diff --git a/packages/web-components/src/components/chat/components/chartElement/src/chartElement.ts b/packages/web-components/src/components/chat/components/chartElement/src/chartElement.ts
index 5846868e..8d475a24 100644
--- a/packages/web-components/src/components/chat/components/chartElement/src/chartElement.ts
+++ b/packages/web-components/src/components/chat/components/chartElement/src/chartElement.ts
@@ -32,6 +32,18 @@ export default class chartElement extends LitElement {
@property({ type: Boolean, attribute: 'debug-mode' })
debugMode = true;
+ /**
+ * selected- highlight if attr is chosen
+ */
+ @property({ type: Boolean, attribute: 'selected' })
+ selected;
+
+ /**
+ * selectable- enable highlight if clicked
+ */
+ @property({ type: Boolean, attribute: 'selectable' })
+ selectable = true;
+
/**
* Event listener to check if parent visibility changed
*/
@@ -270,6 +282,18 @@ export default class chartElement extends LitElement {
@state()
isHovered = false;
+ /**
+ * cellHeight - for multi charts, record max cell size
+ */
+ @state()
+ cellHeight;
+
+ /**
+ * cellWidth - for multi charts, record max cell size
+ */
+ @state()
+ cellWidth;
+
/**
* _latestError - Vega erro message to display
*/
@@ -282,6 +306,12 @@ export default class chartElement extends LitElement {
@state()
_specType;
+ /**
+ * selected - show highlight when chart clicked if selectable enabled
+ */
+ @state()
+ _isSelected = false;
+
/** detect when component is rendered to process visualization specification object
*/
firstUpdated() {
@@ -560,9 +590,10 @@ export default class chartElement extends LitElement {
if (this._specType === 'plain' || this._specType === 'layered') {
chosenSpec.height = 'container';
chosenSpec.width = 'container';
+ } else {
+ chosenSpec.autosize = { resize: false };
}
- chosenSpec.autosize = { resize: false };
if (this.thumbNail) {
chosenSpec.width = 400;
chosenSpec.height = 300;
@@ -1295,6 +1326,8 @@ export default class chartElement extends LitElement {
let plainSpec;
let subChartWidth;
let subChartHeight;
+ this.cellWidth = null;
+ this.cellHeight = null;
if ('layer' in spec) {
this._specType = 'layered';
@@ -1354,9 +1387,9 @@ export default class chartElement extends LitElement {
if (currentContainerWidth) {
let rowCount;
let columnCount;
- const legendHeight = 16 * 3;
+ const legendHeight = 16 + 16 * Math.floor(currentContainerWidth / 130);
const paddingOffset = { vertical: 0, horizontal: 0 };
- const gapSize = 17;
+ const gapSize = 22;
if (spec.repeat) {
if (Array.isArray(repeatedSpec['repeat'])) {
@@ -1414,6 +1447,9 @@ export default class chartElement extends LitElement {
(rowCount + 1) * gapSize) /
rowCount -
42;
+
+ this.cellWidth = subChartWidth;
+ this.cellHeight = subChartHeight;
}
if (spec.repeat) {
@@ -1432,6 +1468,8 @@ export default class chartElement extends LitElement {
if (subChartHeight) {
repeatedSpec['spec']['height'] = subChartHeight;
}
+ this.cellWidth = subChartWidth;
+ this.cellHeight = subChartHeight;
} else if (spec.vconcat || spec.hconcat || spec.concat) {
for (let l = 0; l < repeatedSpec[this._specType].length; l++) {
repeatedSpec[this._specType][l] = this._prepareSpecification(
@@ -1440,7 +1478,9 @@ export default class chartElement extends LitElement {
true,
0
);
- if (subChartWidth) {
+ if (repeatedSpec[this._specType][l].mark?.type === 'text') {
+ repeatedSpec[this._specType][l]['width'] = 40;
+ } else if (subChartWidth) {
repeatedSpec[this._specType][l]['width'] = subChartWidth;
//repeatedSpec[this._specType][l].config.legend.columns =calcColumn;
@@ -1453,6 +1493,8 @@ export default class chartElement extends LitElement {
repeatedSpec['width'] = subChartWidth;
repeatedSpec['height'] = subChartHeight;
}
+ this.cellWidth = subChartWidth;
+ this.cellHeight = subChartHeight;
} else {
this._specType = 'plain';
if (!spec['data']) {
@@ -2005,8 +2047,8 @@ export default class chartElement extends LitElement {
title: null,
symbolType: 'square',
symbolLimit: 30,
- labelLimit: 60,
- columns: { signal: 'floor(width / 70)' },
+ labelLimit: 120,
+ columns: { signal: 'floor(width / 130)' },
orient: 'bottom',
symbolOpacity: 1,
direction: 'horizontal',
@@ -2027,7 +2069,12 @@ export default class chartElement extends LitElement {
},
};
- spec['config'].axis.titleLimit = 100; //Math.min(spec.height,spec.width)
+ if (this.cellHeight && this.cellWidth) {
+ spec['config'].axis.titleLimit = Math.min(
+ this.cellHeight,
+ this.cellWidth
+ );
+ }
}
this._authorizeSingleSelection = false;
@@ -2268,8 +2315,13 @@ export default class chartElement extends LitElement {
}
if (this._authorizeMultiSelection) {
- const brushInteraction: { name: string; select: object } = {
+ const brushInteraction: {
+ name: string;
+ resolve: string;
+ select: object;
+ } = {
name: 'brush',
+ resolve: 'union',
select: { type: 'interval' },
};
params.push(brushInteraction);
diff --git a/packages/web-components/src/components/chat/components/chat/src/chat.template.ts b/packages/web-components/src/components/chat/components/chat/src/chat.template.ts
index 17fa0ef3..feba4396 100644
--- a/packages/web-components/src/components/chat/components/chat/src/chat.template.ts
+++ b/packages/web-components/src/components/chat/components/chat/src/chat.template.ts
@@ -33,6 +33,7 @@ export function chatTemplate(customElementClass) {
agentName,
loading,
closed,
+ forceAutoUpdate,
maxCharacterCount,
disableHeaderMenu,
disableHeaderButtons,
@@ -151,6 +152,7 @@ export function chatTemplate(customElementClass) {
.messages="${messages}"
user-name="${userName}"
agent-name="${agentName}"
+ ?force-scroll-down="${forceAutoUpdate}"
?docking-enabled="${enableDocking}"
?loading="${queryInProgress}"
?stream-responses="${streamResponses}"
diff --git a/packages/web-components/src/components/chat/components/chat/src/chat.ts b/packages/web-components/src/components/chat/components/chat/src/chat.ts
index 658670ed..32895077 100644
--- a/packages/web-components/src/components/chat/components/chat/src/chat.ts
+++ b/packages/web-components/src/components/chat/components/chat/src/chat.ts
@@ -57,6 +57,12 @@ export default class CLABSChat extends LitElement {
@property({ type: Boolean, attribute: 'auto-update', reflect: true })
autoUpdate;
+ /**
+ * force-auto-update - force scroll down no matter what
+ */
+ @property({ type: Boolean, attribute: 'force-auto-update' })
+ forceAutoUpdate;
+
/**
* show launcher when closed
*/
diff --git a/packages/web-components/src/components/chat/components/codeElement/__stories__/codeElement.stories.js b/packages/web-components/src/components/chat/components/codeElement/__stories__/codeElement.stories.js
index 823c6da4..9d3fe1f7 100644
--- a/packages/web-components/src/components/chat/components/codeElement/__stories__/codeElement.stories.js
+++ b/packages/web-components/src/components/chat/components/codeElement/__stories__/codeElement.stories.js
@@ -37,41 +37,190 @@ const defaultPlaygroundArgs = {
disableCopyButton: true,
};
+const frenchLocalized = {
+ 'code-copypaste-button': 'Copier le code',
+ 'code-copypaste-success': 'Copié!',
+ 'code-estimated-warning': '(estimé)',
+ 'code-editing-validation': 'Appliquer',
+ 'code-editing-cancelled': 'Annuler',
+ 'code-line-descriptor': 'lignes',
+};
const codeExamples = {
- 'single command': 'node -v',
- 'npm command': '$ npm install --save carbon-components',
+ cmd: 'node -v',
+ bash: '$ npm install --save carbon-components',
'console multi':
'user@Macbook-Air server % npm run build\nuser@Macbook-Air server % npm run lint:styles --fix\nuser@Macbook-Air server % npm format:write\nuser@Macbook-Air server % python3 server.py',
- 'html example':
- '\n\n\t\n\t\t
This is the title of the webpage\n\t\n\t\n\t\n\t\t
This is an example paragraph. Anything in the body tag will appear on the page, just like this p tag and its contents.
\n\t\n',
+ html: '\n\n\t\n\t\t
This is the title of the webpage\n\t\n\t\n\t\n\t\t
This is an example paragraph. Anything in the body tag will appear on the page, just like this p tag and its contents.
\n\t\n',
+ CSS: `@import url('style.css');\n@media(min-width:760px) {\n\t.box {\n\t\tgrid-template-rows: auto 1fr;\n\t}\nbody {\n\t--main-color: #ff0;\n\tmargin:0;\n\tanimation: spin 3s infinite;\n}\n.container {\n\tcontent:"test";\n\tdisplay: flex;\n\tpadding: 10px;\n}\n.item[data-id="1"]:hover::after {\n\tcontent: attr(data-id);\n\tcolor:red !important;\n}`,
'python code':
'from math import sqrt\n#prime function to check given number prime or not:\ndef Prime(number,itr):\n\t#base condition\n\tif itr == 1:\n\t\treturn True\n\t#if given number divided by itr or not\n\tif number % itr == 0:\n\t\treturn False\n\t#Recursive function Call\n\tif Prime(number,itr-1) == False:\n\t\treturn False\n\treturn True\n',
- 'carbon datatable': `import React from "react";\nimport { DataTable } from "..";\nconst {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableContainer,\n\tTableHead,\n\tTableHeader,\n\tTableRow\n} = DataTable;\nimport mdx from "../DataTable.mdx";\nimport "./datatable-story.scss";\nexport default {\n\ttitle: "Components/DataTable/Basic",\n\tcomponent: DataTable,\n\tsubcomponents: {\n\t\tTableContainer,\n\t\tTable,\n\t\tTableHead,\n\t\tTableRow,\n\t\tTableHeader,\n\t\tTableBody,\n\t\tTableCell\n\t},\n\tparameters: {\n\t\tdocs: {\n\t\t\tpage: mdx\n\t\t}\n\t}\n};\nexport const Default = () => {\n\tconst rows = [{\n\t\tid: "load-balancer-1",\n\t\tname: "Load Balancer 1",\n\t\trule: "Round robin",\n\t\tStatus: "Starting",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-2",\n\t\tname: "Load Balancer 2",\n\t\trule: "DNS delegation",\n\t\tstatus: "Active",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-3",\n\t\tname: "Load Balancer 3",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-4",\n\t\tname: "Load Balancer 4",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-5",\n\t\tname: "Load Balancer 5",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-6",\n\t\tname: "Load Balancer 6",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-7",\n\t\tname: "Load Balancer 7",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}];\n\tconst headers = ["Name", "Rule", "Status", "Other", "Example"];\n\treturn
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t{headers.map(header => )}\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{rows.map(row => \n\t\t\t\t\t\t{Object.keys(row).filter(key => key !== "id").map(key => {\n\t\t\t\t\treturn {row[key]};\n\t\t\t\t})}\n\t\t\t\t\t)}\n\t\t\t\n\t\t
;\n};`,
+ 'C++':
+ '#include
\n#include "llama.cpp/llama.h"\n\nint main() {\n\tllama_model *model = llama_load_model_from_file("path/to/model.bin"); \n\n\tif (model == nullptr) {\n\t\tstd::cerr << "Failed to load model.";\n\t\treturn 1;\n\t}\n\n\tstd::string prompt = "Hello, how are you today?";\n\tllama_context *ctx = llama_new_context_with_model(model, 512); \n\n\tstd::cout << "Prompt: " << prompt << std::endl;\n\tstd::cout << "Response: ";\n\n\tfor (int i = 0; i < 100; ++i) {\n\t\tllama_token token = llama_sample_token(ctx, nullptr);\n\t\tstd::cout << llama_token_to_str(model, token);\n\t}\n\n\tstd::cout << std::endl;\n\n\tllama_free_context(ctx);\n\tllama_free_model(model);\n\n\treturn 0;\n}',
'SQL example': `-- Simple SQL file example\n-- Creating a table named 'employees'\nCREATE TABLE employees (\nid INT PRIMARY KEY,\nfirst_name VARCHAR(50),\nlast_name VARCHAR(50),\nemail VARCHAR(100),\ndepartment_id INT,\nhire_date DATE\n);\n-- Creating a table named 'departments'\nCREATE TABLE departments (\nid INT PRIMARY KEY,\nname VARCHAR(50)\n);\n-- Inserting data into the 'departments' table\nINSERT INTO departments (id, name) VALUES\n(1, 'Human Resources'),\n(2, 'Marketing'),\n(3, 'Sales'),\n(4, 'IT');\n-- Inserting data into the 'employees' table\nINSERT INTO employees (id, first_name, last_name, email, department_id, hire_date) VALUES\n(1, 'John', 'Doe', 'john.doe@example.com', 3, '2020-01-01'),\n(2, 'Jane', 'Doe', 'jane.doe@example.com', 2, '2019-06-15'),\n(3, 'Jim', 'Smith', 'jim.smith@example.com', 3, '2021-02-20');\n`,
COBOL: `IDENTIFICATION DIVISION.\nPROGRAM-ID. VARS.\nDATA DIVISION.\n\t*> working storage defines variables\n\tWORKING-STORAGE SECTION.\n\t*> define a number with a sign, 3 numbers, a decimal, and then\n\t*> two numbers aafter the decimal. by default it should be 0 filled\n\t01 FIRST-VAR PIC S9(3)V9(2).\n\t*> do the same thing as above but actually initialize\n\t*> to a number -123.45\n\t01 SECOND-VAR PIC S9(3)V9(2) VALUE -123.45.\n\t*> defines an alphabetic string and initialize it to abcdef\n\t01 THIRD-VAR PIC A(6) VALUE 'ABCDEF'.\n\t*> define an alphanumeric string and initialize it to a121$\n\t01 FOURTH-VAR PIC X(5) VALUE 'A121$'.\n\t*> create a grouped variable\n\t01 GROUP-VAR.\n\t\t05 SUBVAR-1 PIC 9(3) VALUE 337.\n\t\t*> create 3 alphanumerics, but use less than\n\t\t*> the allocated space for each of them\n\t\t05 SUBVAR-2 PIC X(15) VALUE 'LALALALA'.\n\t\t05 SUBVAR-3 PIC X(15) VALUE 'LALALA'.\n\t\t05 SUBVAR-4 PIC X(15) VALUE 'LALALA'.\n*> print our variables\nPROCEDURE DIVISION.\n\tDISPLAY "1ST VAR :"FIRST-VAR.\n\tDISPLAY "2ND VAR :"SECOND-VAR.\n\tDISPLAY "3RD VAR :"THIRD-VAR.\n\tDISPLAY "4TH VAR :"FOURTH-VAR.\n\tDISPLAY "GROUP VAR :"GROUP-VAR.\n\tSTOP RUN.`,
Java: `public class BinaryConverter {\n\t\n\tpublic static void main(String[] args){\n\t\tfor(int i = -5; i < 33; i++){\n\t\t\tSystem.out.println(i + ": " + toBinary(i));\n\t\t\tSystem.out.println(i);\n\t\t\t//always another way\n\t\t\tSystem.out.println(i + ": " + Integer.toBinaryString(i));\n\t\t}\n\t}\n\t\n\t/*\n\t * pre: none\n\t * post: returns a String with base10Num in base 2\n\t */\n\tpublic static String toBinary(int base10Num){\n\t\tboolean isNeg = base10Num < 0;\n\t\tbase10Num = Math.abs(base10Num);\n\t\tString result = "";\n\t\t\n\t\twhile(base10Num > 1){\n\t\t\tresult = (base10Num % 2) + result;\n\t\t\tbase10Num /= 2;\n\t\t}\n\t\tassert base10Num == 0 || base10Num == 1 : "value is not <= 1: " + base10Num;\n\t\t\n\t\tresult = base10Num + result;\n\t\tassert all0sAnd1s(result);\n\t\t\n\t\tif( isNeg )\n\t\t\tresult = "-" + result;\n\t\treturn result;\n\t}\n\t\n\t/*\n\t * pre: cal != null\n\t * post: return true if val consists only of characters 1 and 0, false otherwise\n\t */\n\tpublic static boolean all0sAnd1s(String val){\n\t\tassert val != null : "Failed precondition all0sAnd1s. parameter cannot be null";\n\t\tboolean all = true;\n\t\tint i = 0;\n\t\tchar c;\n\t\t\n\t\twhile(all && i < val.length()){\n\t\t\tc = val.charAt(i);\n\t\t\tall = c == '0' || c == '1';\n\t\t\ti++;\n\t\t}\n\t\treturn all;\n\t}\n}`,
- 'C++':
- '#include \nusing namespace std;\n\n\nint main() {\n\tint x = 5;\n\tint y = 6;\n\tint sum = x + y;\n\tcout << sum;\n\treturn 0;\n}\n',
JavaScript:
'// A simple JavaScript function to calculate the area of a rectangle\nfunction calculateRectangleArea(length, width) {\n\treturn length * width;\n}\n\n// Example usage:\nlet area = calculateRectangleArea(5, 10);\nconsole.log("Area:", area); // Output: Area: 50',
+ R: `# Fibonacci sequence function in R
+fibonacci <- function(n) {
+ if (n <= 0) {
+ return(NULL)
+ } else if (n == 1) {
+ return(0)
+ } else if (n == 2) {
+ return(1)
+ } else {
+ a <- 0
+ b <- 1
+ for (i in 3:n) {
+ c <- a + b
+ a <- b
+ b <- c
+ }
+ return(b)
+ }
+}
+cat("Fibonacci(10): ", fibonacci(10), "\n")`,
+ Lisp: `; Fibonacci sequence function in Lisp
+(defun fibonacci (n)
+(cond ((< n 1) nil)
+((= n 1) 0)
+((= n 2) 1)
+(t (let ((a 0)
+(b 1))
+(loop for i from 3 to n
+do (let ((c (+ a b)))
+(setf a b)
+(setf b c)))
+b)))))
+(print (fibonacci 10))`,
+ 'C#': `// Fibonacci sequence function in C#
+using System;
+class Program
+{
+ static void Main()
+ {
+ Console.WriteLine("Fibonacci(10): " + Fibonacci(10));
+ }
+ static int Fibonacci(int n)
+ {
+ if (n <= 0)
+ {
+ return -1;
+ }
+ else if (n == 1)
+ {
+ return 0;
+ }
+ else if (n == 2)
+ {
+ return 1;
+ }
+ else
+ {
+ int a = 0;
+ int b = 1;
+ for (int i = 3; i <= n; i++)
+ {
+ int c = a + b;
+ a = b;
+ b = c;
+ }
+ return b;
+ }
+ }
+}`,
+ PHP: `=<;:9876543s+O\n#include "llama.cpp/llama.h"\n\nint main() {\n\tllama_model *model = llama_load_model_from_file("path/to/model.bin"); \n\n\tif (model == nullptr) {\n\t\tstd::cerr << "Failed to load model.";\n\t\treturn 1;\n\t}\n\n\tstd::string prompt = "Hello, how are you today?";\n\tllama_context *ctx = llama_new_context_with_model(model, 512); \n\n\tstd::cout << "Prompt: " << prompt << std::endl;\n\tstd::cout << "Response: ";\n\n\tfor (int i = 0; i < 100; ++i) {\n\t\tllama_token token = llama_sample_token(ctx, nullptr);\n\t\tstd::cout << llama_token_to_str(model, token);\n\t}\n\n\tstd::cout << std::endl;\n\n\tllama_free_context(ctx);\n\tllama_free_model(model);\n\n\treturn 0;\n}',
+ 'carbon datatable': `import React from "react";\nimport { DataTable } from "..";\nconst {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableContainer,\n\tTableHead,\n\tTableHeader,\n\tTableRow\n} = DataTable;\nimport mdx from "../DataTable.mdx";\nimport "./datatable-story.scss";\nexport default {\n\ttitle: "Components/DataTable/Basic",\n\tcomponent: DataTable,\n\tsubcomponents: {\n\t\tTableContainer,\n\t\tTable,\n\t\tTableHead,\n\t\tTableRow,\n\t\tTableHeader,\n\t\tTableBody,\n\t\tTableCell\n\t},\n\tparameters: {\n\t\tdocs: {\n\t\t\tpage: mdx\n\t\t}\n\t}\n};\nexport const Default = () => {\n\tconst rows = [{\n\t\tid: "load-balancer-1",\n\t\tname: "Load Balancer 1",\n\t\trule: "Round robin",\n\t\tStatus: "Starting",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-2",\n\t\tname: "Load Balancer 2",\n\t\trule: "DNS delegation",\n\t\tstatus: "Active",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-3",\n\t\tname: "Load Balancer 3",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-4",\n\t\tname: "Load Balancer 4",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-5",\n\t\tname: "Load Balancer 5",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-6",\n\t\tname: "Load Balancer 6",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}, {\n\t\tid: "load-balancer-7",\n\t\tname: "Load Balancer 7",\n\t\trule: "Round robin",\n\t\tstatus: "Disabled",\n\t\tother: "Test",\n\t\texample: "22"\n\t}];\n\tconst headers = ["Name", "Rule", "Status", "Other", "Example"];\n\treturn \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t{headers.map(header => )}\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{rows.map(row => \n\t\t\t\t\t\t{Object.keys(row).filter(key => key !== "id").map(key => {\n\t\t\t\t\treturn {row[key]};\n\t\t\t\t})}\n\t\t\t\t\t)}\n\t\t\t\n\t\t
;\n};`,
};
-export const Showcase = {
+export const OptionShowcase = {
/**
* Renders the template for Storybook
*
* @returns {TemplateResult<1>}
*/
render: () => html`
- Single line code
+ Single line code without copy
@@ -79,66 +228,193 @@ export const Showcase = {
Single line command with copy
- Multi line command
-
+ Maximum height
+
+ C++ with no height set
+
+
+ C++ with max-height 200px
+
+
+
+ Coloring and Ticks
+
Python example with no coloring or ticks
- SQL example with ticks
+
+ SQL example without ticks
- Python code example with language name
+
+ Info display (language and count)
+
+ Python code example with language name: user language
- C++ example
+ C++ example with guessed language from highlight js
-
+
+
+
+
+ C++ example with line count (no ticks)
+
+
+
- HTML with ticks
-
+ C++ example with both
+
+
- COBOL example
-
+ Tab sizing
+
+ HTML example with default tab-size
- Java example
+
-
+ HTML example with tab-size=6
+
+
+
- JS example
-
- FORTRAN example
-
+ Localization
- Malbolge example
+ HTML example with customLabels in french
-
+
+
`,
};
+/*
+export const ColorTesting = {
+ render: () => html`
+ Top languages
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Web development
+
+
+
+
+
+
+
+
+
+
+
+ Scripting
+
+
+
+
+
+
+
+ Data science
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+ `,
+};*/
+export const ColorTesting = {
+ /**
+ * Renders the template for Storybook
+ *
+ * @returns {TemplateResult<1>}
+ */
+ render: () =>
+ html` ${Object.keys(codeExamples).map(
+ (key) =>
+ html`
+
+
+
+ `
+ )}`,
+};
+
export const Editing = {
/**
* Renders the template for Storybook
@@ -177,13 +453,6 @@ export const Editing = {
content="${codeExamples['SQL example']}">
- C++ example
-
-
-
JS carbon example
- editable |
+ `editable` |
Make every line editable by users |
When a user-input is needed to fix an object |
- streaming |
+ `streaming` |
Rerenders component when content is streamed in |
When streaming is enabled |
- enable-coloring |
- When editable is invoked, remove edit button |
- Disable button to validate edit |
+ `max-height` |
+ Limits total height and scrolls if needed |
+ When code is large or height is limited |
+
+
+ `display-line-count` |
+ Shows line count at top of component |
+ When code length is variable |
+
+
+ `tab-size` |
+ Set tab spacing for new lines |
+ When default spacing of 2 is insufficient |
+
+
+ `enable-language-display` |
+ Show language at top of component |
+ When generation offers multiple options |
+
+
+ `displayed-language` |
+ Force top-level language name |
+ When automatic detection isn't accurate |
+
+
+ `enable-estimated-language` |
+ Show guessed language from coloring |
+ When language is unknown |
+
+
+ `disable-coloring` |
+ Disable auto-coloring on render |
+ When unneeded |
+
+
+ `disable-coloring-char-threshold` |
+ Max character count to auto disable coloring |
+ To optimize performance with large code pieces |
- enable-language-display |
- Shows estimated language at top of component |
- When any type of code can be returned |
+ `disable-coloring-line-threshold` |
+ Max line count to auto disable coloring |
+ To optimize performance with large code pieces |
- disable-auto-compacting |
+ `disable-auto-compacting` |
Stops line-ticks from being removed when space isn't sufficient |
Hide ticks when compacted |
- disable-edit-button |
+ `disable-edit-button` |
When editable is invoked, remove edit button |
Disable button to validate edit |
- disable-line-ticks |
+ `disable-line-ticks` |
Remove line counts on the left side-bar of code |
When showing code such as console commands |
- disable-copy-button |
+ `disable-copy-button` |
Remove copy button from top-right corner |
When displaying code not meant to be replicated |
+
+ `customLabels` |
+ Define all button labels |
+ See below |
+
+### Custom Labels for localization ###
+
+Place `customLabels` with the following object to edit all button tooltip values
+```js
+{
+ 'code-copypaste-button': 'Copy code',
+ 'code-copypaste-success': 'Copied!',
+ 'code-estimated-warning': '(estimated)',
+ 'code-line-descriptor': 'lines',
+ 'code-editing-validation': 'Save edits',
+ 'code-editing-cancelled': 'Revert edits'
+}
+```
+
+### <clabs-chat-code> events
+
+
+
+
+ **Event listener name** |
+ **Trigger condition** |
+
+
+ `on-code-edit-change` |
+ Each edit when in editing mode |
+
+
+ `on-code-edit-validation` |
+ Editing finalized and locked |
+
+
+ `on-code-edit-cancellation` |
+ Last set of edits was undone |
+
+
+ `on-coloring-auto-disabled` |
+ Rendering threshold exceeded |
+
+
+
+### Usage example
+```html
+
+
+```
### Troubleshooting
diff --git a/packages/web-components/src/components/chat/components/codeElement/src/codeElement.scss b/packages/web-components/src/components/chat/components/codeElement/src/codeElement.scss
index 84802322..3bf7147a 100644
--- a/packages/web-components/src/components/chat/components/codeElement/src/codeElement.scss
+++ b/packages/web-components/src/components/chat/components/codeElement/src/codeElement.scss
@@ -29,9 +29,14 @@ $css--plex: true !default;
}
.#{$clabs-prefix}--chat-code-lang {
+ color: $text-secondary;
+ font-size: 14px;
font-style: italic;
- padding-block-start: 16px;
- padding-inline-start: 16px;
+ padding-block: 16px 4px;
+ padding-inline-start: calc(
+ var(--chat-code-tick-width, '0px') + var(--chat-code-inset-start, '13px') +
+ 2px
+ );
}
.#{$clabs-prefix}--chat-code-color-area {
@@ -53,7 +58,7 @@ $css--plex: true !default;
min-block-size: 100%;
padding-block: 16px;
padding-inline-start: 8px;
- tab-size: 3;
+ tab-size: 2;
}
.#{$clabs-prefix}--chat-code-edit-area {
@@ -85,7 +90,7 @@ $css--plex: true !default;
2px
);
resize: none;
- tab-size: 3;
+ tab-size: 2;
word-break: break-word;
}
@@ -97,7 +102,7 @@ $css--plex: true !default;
.#{$clabs-prefix}--chat-code-line-tick {
flex: 0 0 var(--chat-code-tick-width, '13px');
- color: $text-placeholder;
+ color: $text-secondary;
inline-size: var(--chat-code-tick-width, '13px');
padding-inline-end: 0.5em;
text-align: end;
@@ -239,7 +244,7 @@ $css--plex: true !default;
padding-inline-start: var(--chat-code-tick-width, '13px');
resize: none;
- tab-size: 3;
+ tab-size: 2;
word-break: break-word;
}
@@ -283,219 +288,401 @@ $css--plex: true !default;
inset-inline-end: 0;
}
- .hljs {
+ .hljs,
+ .hljs-subst {
color: $text-primary;
}
- .hljs-comment,
- .hljs-quote {
- color: $support-success;
- }
-
.#{$clabs-prefix}--chat-code-white-theme {
- .hljs-literal,
- .hljs-built_in,
- .hljs-builtin-name,
.hljs-selector-tag,
- .hljs-doctag {
+ .hljs-title,
+ .hljs-section,
+ .hljs-function {
color: $purple-60;
}
+ .hljs-literal,
+ .hljs-doctype,
+ .hljs-keyword {
+ color: $blue-60;
+ }
+
+ .hljs-tag .hljs-name {
+ color: $yellow-60;
+ }
+
.hljs-string,
- .hljs-attribute,
- .hljs-template-variable,
- .hljs-template-tag {
+ .hljs-meta .hljs-string {
color: $green-60;
}
- .hljs-keyword,
.hljs-number,
.hljs-symbol,
.hljs-bullet {
- color: $blue-60;
+ color: $teal-60;
}
- .hljs-function .hljs-title,
- .hljs-title,
- .hljs-function {
- color: $cyan-60;
+ .hljs-comment,
+ .hljs-quote {
+ color: $green-60;
}
- .hljs-operator,
- .hljs-punctuation,
- .hljs-subst {
- color: $red-60;
+ .hljs-meta,
+ .hljs-meta .hljs-keyword {
+ color: $purple-60;
}
- .hljs-variable,
- .hljs-property,
- .hljs-params {
- color: $magenta-60;
+ .hljs-built_in,
+ .hljs-builtin-name {
+ color: $cyan-60;
}
- .hljs-attr {
- color: $orange-60;
+ .hljs-attr,
+ .hljs-attribute {
+ color: $teal-60;
}
- .hljs-class .hljs-title,
- .hljs-type,
- .hljs-class {
- color: $teal-60;
+ .hljs-variable,
+ .hljs-template-variable,
+ .hljs-class .hljs-title {
+ color: $yellow-60;
+ }
+
+ .hljs-tag {
+ color: $red-60;
}
.hljs-name,
- .hljs-section,
.hljs-selector-id,
- .hljs-tag,
- .hljs-meta,
.hljs-selector-class {
+ color: $blue-60;
+ }
+
+ .hljs-attribute {
+ color: $teal-60;
+ }
+
+ .hljs-template-tag,
+ .hljs-template-variable {
color: $yellow-60;
}
+ .hljs-selector-tag {
+ color: $blue-60;
+ }
+
+ .hljs-selector-id {
+ color: $purple-60;
+ }
+
+ .hljs-selector-class {
+ color: $blue-60;
+ }
+
+ .hljs-selector-pseudo {
+ color: $cyan-60;
+ }
+
+ .hljs-selector-attr {
+ color: $green-60;
+ }
+
+ .hljs-decorator {
+ color: $magenta-60;
+ }
+
+ .hljs-bullet {
+ color: $orange-60;
+ }
+
+ .hljs-link {
+ color: $blue-60;
+ }
+
.hljs-emphasis {
- font-style: italic;
+ color: $gray-60;
}
.hljs-strong {
- font-weight: bold;
+ color: $gray-60;
+ }
+
+ .hljs-error {
+ color: $red-60;
+ }
+
+ .hljs-addition {
+ color: $green-60;
+ }
+
+ .hljs-params {
+ color: $yellow-60;
+ }
+
+ .hljs-subst {
+ color: $gray-60;
}
}
.#{$clabs-prefix}--chat-code-default-theme {
- .hljs-literal,
- .hljs-built_in,
- .hljs-builtin-name,
.hljs-selector-tag,
- .hljs-doctag {
+ .hljs-title,
+ .hljs-section,
+ .hljs-function {
color: $purple-50;
}
+ .hljs-literal,
+ .hljs-doctype,
+ .hljs-keyword {
+ color: $blue-50;
+ }
+
+ .hljs-tag .hljs-name {
+ color: $yellow-50;
+ }
+
.hljs-string,
- .hljs-attribute,
- .hljs-template-variable,
- .hljs-template-tag {
+ .hljs-meta .hljs-string {
color: $green-50;
}
- .hljs-keyword,
.hljs-number,
.hljs-symbol,
.hljs-bullet {
- color: $blue-50;
+ color: $teal-50;
}
- .hljs-function .hljs-title,
- .hljs-title,
- .hljs-function {
- color: $cyan-50;
+ .hljs-comment,
+ .hljs-quote {
+ color: $green-50;
}
- .hljs-operator,
- .hljs-punctuation,
- .hljs-subst {
- color: $red-50;
+ .hljs-meta,
+ .hljs-meta .hljs-keyword {
+ color: $purple-50;
}
- .hljs-variable,
- .hljs-property,
- .hljs-params {
- color: $magenta-50;
+ .hljs-built_in,
+ .hljs-builtin-name {
+ color: $cyan-50;
}
- .hljs-attr {
- color: $orange-50;
+ .hljs-attr,
+ .hljs-attribute {
+ color: $teal-50;
}
- .hljs-class .hljs-title,
- .hljs-type,
- .hljs-class {
- color: $teal-50;
+ .hljs-variable,
+ .hljs-template-variable,
+ .hljs-class .hljs-title {
+ color: $yellow-50;
+ }
+
+ .hljs-tag {
+ color: $red-50;
}
.hljs-name,
- .hljs-section,
.hljs-selector-id,
- .hljs-tag,
- .hljs-meta,
.hljs-selector-class {
+ color: $blue-50;
+ }
+
+ .hljs-attribute {
+ color: $teal-50;
+ }
+
+ .hljs-template-tag,
+ .hljs-template-variable {
color: $yellow-50;
}
+ .hljs-selector-tag {
+ color: $blue-50;
+ }
+
+ .hljs-selector-id {
+ color: $purple-50;
+ }
+
+ .hljs-selector-class {
+ color: $blue-50;
+ }
+
+ .hljs-selector-pseudo {
+ color: $cyan-50;
+ }
+
+ .hljs-selector-attr {
+ color: $green-50;
+ }
+
+ .hljs-decorator {
+ color: $magenta-50;
+ }
+
+ .hljs-bullet {
+ color: $orange-50;
+ }
+
+ .hljs-link {
+ color: $blue-50;
+ }
+
.hljs-emphasis {
- font-style: italic;
+ color: $gray-50;
}
.hljs-strong {
- font-weight: bold;
+ color: $gray-50;
+ }
+
+ .hljs-error {
+ color: $red-50;
+ }
+
+ .hljs-addition {
+ color: $green-50;
+ }
+
+ .hljs-params {
+ color: $yellow-50;
+ }
+
+ .hljs-subst {
+ color: $gray-50;
}
}
.#{$clabs-prefix}--chat-code-g100-theme {
- .hljs-literal,
- .hljs-built_in,
- .hljs-builtin-name,
.hljs-selector-tag,
- .hljs-doctag {
+ .hljs-title,
+ .hljs-section,
+ .hljs-literal,
+ .hljs-function {
color: $purple-40;
}
+ .hljs-doctype,
+ .hljs-keyword {
+ color: $blue-40;
+ }
+
+ .hljs-tag .hljs-name {
+ color: $yellow-40;
+ }
+
.hljs-string,
- .hljs-attribute,
- .hljs-template-variable,
- .hljs-template-tag {
+ .hljs-meta .hljs-string {
color: $green-40;
}
- .hljs-keyword,
.hljs-number,
.hljs-symbol,
.hljs-bullet {
- color: $blue-40;
+ color: $teal-40;
}
- .hljs-function .hljs-title,
- .hljs-title,
- .hljs-function {
- color: $cyan-40;
+ .hljs-comment,
+ .hljs-quote {
+ color: $green-40;
}
- .hljs-operator,
- .hljs-punctuation,
- .hljs-subst {
- color: $red-40;
+ .hljs-meta,
+ .hljs-meta .hljs-keyword {
+ color: $purple-40;
}
- .hljs-variable,
- .hljs-property,
- .hljs-params {
- color: $magenta-40;
+ .hljs-built_in,
+ .hljs-builtin-name {
+ color: $cyan-40;
}
- .hljs-attr {
- color: $orange-40;
+ .hljs-attr,
+ .hljs-attribute {
+ color: $teal-40;
}
- .hljs-class .hljs-title,
- .hljs-type,
- .hljs-class {
- color: $teal-40;
+ .hljs-variable,
+ .hljs-template-variable,
+ .hljs-class .hljs-title {
+ color: $yellow-40;
+ }
+
+ .hljs-tag {
+ color: $red-40;
}
.hljs-name,
- .hljs-section,
.hljs-selector-id,
- .hljs-tag,
- .hljs-meta,
.hljs-selector-class {
+ color: $blue-40;
+ }
+
+ .hljs-attribute {
+ color: $teal-40;
+ }
+
+ .hljs-template-tag,
+ .hljs-template-variable {
color: $yellow-40;
}
+ .hljs-selector-tag {
+ color: $blue-40;
+ }
+
+ .hljs-selector-id {
+ color: $purple-40;
+ }
+
+ .hljs-selector-class {
+ color: $blue-40;
+ }
+
+ .hljs-selector-pseudo {
+ color: $cyan-40;
+ }
+
+ .hljs-selector-attr {
+ color: $green-40;
+ }
+
+ .hljs-decorator {
+ color: $magenta-40;
+ }
+
+ .hljs-bullet {
+ color: $orange-40;
+ }
+
+ .hljs-link {
+ color: $blue-40;
+ }
+
.hljs-emphasis {
- font-style: italic;
+ color: $gray-40;
}
.hljs-strong {
- font-weight: bold;
+ color: $gray-40;
+ }
+
+ .hljs-error {
+ color: $red-40;
+ }
+
+ .hljs-addition {
+ color: $green-40;
+ }
+
+ .hljs-params {
+ color: $yellow-40;
+ }
+
+ .hljs-subst {
+ color: $gray-40;
}
}
}
diff --git a/packages/web-components/src/components/chat/components/codeElement/src/codeElement.template.ts b/packages/web-components/src/components/chat/components/codeElement/src/codeElement.template.ts
index ff7d5e15..8ea087e1 100644
--- a/packages/web-components/src/components/chat/components/codeElement/src/codeElement.template.ts
+++ b/packages/web-components/src/components/chat/components/codeElement/src/codeElement.template.ts
@@ -30,7 +30,6 @@ import Undo16 from '@carbon/web-components/es/icons/undo/16.js';
export function codeElementTemplate(customElementClass) {
const {
_renderedLines,
- content,
disableLineTicks,
disableCopyButton,
disableEditButton,
@@ -39,10 +38,15 @@ export function codeElementTemplate(customElementClass) {
_handleEditValidation: handleEditValidation,
_handleEditCancellation: handleEditCancellation,
editable,
+ assignedLanguage,
+ autoAssignLanguage,
+ _editedContent: editedContent,
_currentlyEdited: currentlyEdited,
_highlightLine: highlightLine,
enableColoring,
language,
+ lineCount,
+ displayLineCount,
enableLanguageDisplay,
_renderLabel: renderLabel,
_handleScroll: handleScroll,
@@ -52,9 +56,26 @@ export function codeElementTemplate(customElementClass) {
} = customElementClass;
return html`
- ${enableLanguageDisplay
- ? html`
${language}
`
+ ${enableLanguageDisplay || displayLineCount
+ ? html`
+ ${enableLanguageDisplay
+ ? html`
+ ${assignedLanguage
+ ? assignedLanguage
+ : autoAssignLanguage
+ ? language + ' ' + renderLabel('code-estimated-warning')
+ : 'no language detected'}
+ `
+ : ``}
+ ${displayLineCount && lineCount > 1
+ ? (enableLanguageDisplay ? ', ' : '') +
+ lineCount +
+ ' ' +
+ renderLabel('code-line-descriptor')
+ : ''}
+
`
: ``}
+
${!disableEditButton
@@ -77,6 +98,7 @@ export function codeElementTemplate(customElementClass) {
tooltip-alignment="end"
tooltip-position="bottom"
align="left"
+ size="sm"
feedback="${renderLabel('code-copypaste-success')}"
feedback-timeout="2000">
${renderLabel('code-copypaste-button')}
@@ -99,7 +121,7 @@ export function codeElementTemplate(customElementClass) {
class="${clabsPrefix}--chat-code-edit-area ${!editable
? clabsPrefix + '--chat-code-edit-hidden'
: ''}">
-${content}
${Undo16({ slot: 'icon' })}
- Undo edit
+ ${renderLabel('code-editing-cancelled')}
${Checkmark16({ slot: 'icon' })}
- Apply edit
+ ${renderLabel('code-editing-validation')}
`
: html``}
diff --git a/packages/web-components/src/components/chat/components/codeElement/src/codeElement.ts b/packages/web-components/src/components/chat/components/codeElement/src/codeElement.ts
index 34529483..b14de854 100644
--- a/packages/web-components/src/components/chat/components/codeElement/src/codeElement.ts
+++ b/packages/web-components/src/components/chat/components/codeElement/src/codeElement.ts
@@ -37,6 +37,18 @@ export default class codeElement extends LitElement {
@property({ type: Boolean, attribute: 'editable', reflect: true })
editable;
+ /**
+ * character count render limit for coloring performance
+ */
+ @property({ type: Number, attribute: 'disable-coloring-char-threshold' })
+ coloringCharacterThreshold;
+
+ /**
+ * line count render limit for coloring performance
+ */
+ @property({ type: Number, attribute: 'disable-coloring-line-threshold' })
+ coloringLineThreshold;
+
/**
* add coloring with highlightJS
*/
@@ -62,16 +74,34 @@ export default class codeElement extends LitElement {
maxHeight;
/**
- * Set max height for code piece
+ * Set lang name
*/
- @property({ type: String, attribute: 'lang' })
+ @property({ type: String, attribute: 'displayed-language' })
assignedLanguage;
+ /**
+ * Set render language
+ */
+ @property({ type: String, attribute: 'render-language' })
+ renderLanguage;
+
+ /**
+ * Show language guessed by hljs
+ */
+ @property({ type: Boolean, attribute: 'enable-estimated-language' })
+ autoAssignLanguage;
+
+ /**
+ * Show line count
+ */
+ @property({ type: Boolean, attribute: 'display-line-count' })
+ displayLineCount;
+
/**
* Set tab size flag int
*/
@property({ type: Number, attribute: 'tab-size' })
- tabSize = 3;
+ tabSize = 2;
/**
* Editable boolean flag to let users know lines can be changed
@@ -94,8 +124,8 @@ export default class codeElement extends LitElement {
/**
* Editable boolean flag to let users know lines can be changed
*/
- @property({ type: Boolean, attribute: 'disable-auto-compacting' })
- disableAutoCompacting;
+ @property({ type: Boolean, attribute: 'enable-auto-compacting' })
+ enableAutoCompacting = true;
/**
* Source content - save original code text content
@@ -151,6 +181,12 @@ export default class codeElement extends LitElement {
@state()
_preRender = true;
+ /**
+ * line count
+ */
+ @state()
+ lineCount;
+
/**
* Array of lines parsed from content attribute
*/
@@ -202,6 +238,7 @@ export default class codeElement extends LitElement {
if (!this._originalContent) {
this._originalContent = this.content;
}
+
if (this.streaming) {
this._formatCode(false);
} else {
@@ -243,6 +280,11 @@ export default class codeElement extends LitElement {
this.style.setProperty('--chat-code-tick-offset', '0px');
this.style.setProperty('--chat-code-inset-start', '14px');
}
+
+ if (this.enableLanguageDisplay || this.displayLineCount) {
+ this.style.setProperty('--chat-code-info-offset', '46px');
+ }
+
if (this.content !== undefined) {
const codeAnalysis = this._clearCode(this.content);
if (codeAnalysis.language) {
@@ -262,12 +304,11 @@ export default class codeElement extends LitElement {
];
}
//if (!this.disableAutoCompacting) {
- this.resizeObserver = new ResizeObserver(async () => {
- this._handleScroll();
+ this.resizeObserver = new ResizeObserver(async (_event) => {
+ this._handleResize(_event);
});
this.resizeObserver.observe(this);
- //}
}
/** _handleScroll
@@ -285,11 +326,11 @@ export default class codeElement extends LitElement {
this.editable
) {
editArea.scrollTop = textArea.scrollTop;
- setTimeout(() => {
+ /*setTimeout(() => {
if (Math.abs(textArea.scrollHeight - editArea.scrollHeight) > 10) {
this._formatCode(true);
}
- }, 100);
+ }, 100);*/
}
}
@@ -298,8 +339,10 @@ export default class codeElement extends LitElement {
* @param {event} _event - resize event
*/
_handleResize(_event) {
- if (!this.disableLineTicks) {
- this.disableLineTicks = this.clientWidth < 300;
+ if (this.enableAutoCompacting) {
+ if (this.clientWidth < 300) {
+ this.disableLineTicks = true;
+ }
}
this._handleScroll();
}
@@ -469,13 +512,16 @@ export default class codeElement extends LitElement {
});
this.dispatchEvent(codeEditedEvent);
this._currentlyEdited = false;
- this.requestUpdate();
+ this._formatCode(false);
}
/**
* _handleCancellation - button event when user aborts edit of code
*/
_handleEditCancellation() {
+ //this._editedContent = this.content;
+ //this.content=this._originalContent
+ this._editedContent = this.content;
this._editedContent = this._originalContent;
this._currentlyEdited = false;
@@ -490,6 +536,7 @@ export default class codeElement extends LitElement {
});
this.dispatchEvent(codeEditedEvent);
this._formatCode(false);
+ this._handleScroll();
}
/** _highlightLine - run code coloring system
@@ -508,13 +555,16 @@ export default class codeElement extends LitElement {
const formattedText = edited ? this._editedContent : this.content;
const htmlSafeText = formattedText.replace(/```/g, '');
- try {
- if (!this.language) {
- const detection = hljs.highlightAuto(htmlSafeText);
- this.language = detection.language;
+ if (this.coloringCharacterThreshold) {
+ if (formattedText.length > this.coloringCharacterThreshold) {
+ this.disableColoring = true;
}
- } catch (e) {
- this.language = 'javascript';
+ }
+
+ const tabConversion = ' ';
+ let tabHTML = '';
+ if (this.tabSize) {
+ tabHTML = tabConversion.repeat(this.tabSize);
}
const lines = htmlSafeText.trim().split('\n');
@@ -526,6 +576,25 @@ export default class codeElement extends LitElement {
paddingLeft: string;
}[] = [];
+ this.lineCount = lines.length;
+
+ if (!this.disableColoring) {
+ try {
+ if (!this.language) {
+ const detection = hljs.highlightAuto(htmlSafeText);
+ this.language = detection.language;
+ }
+ } catch (e) {
+ this.language = 'javascript';
+ }
+ }
+
+ if (this.coloringLineThreshold) {
+ if (lines.length > this.coloringLineThreshold) {
+ this.disableColoring = true;
+ }
+ }
+
const highlightMode = !this.disableColoring;
if (highlightMode) {
const highlightedCode = hljs.highlightAuto(htmlSafeText).value;
@@ -540,9 +609,7 @@ export default class codeElement extends LitElement {
if (lines) {
for (let k = 0; k < lines.length; k++) {
if (k > 0) {
- codeLines.push(
- currentLine.replace(/\t/g, ' ')
- );
+ codeLines.push(currentLine.replace(/\t/g, tabHTML));
currentLine = '';
}
currentLine += lines[k];
@@ -555,7 +622,7 @@ export default class codeElement extends LitElement {
}
if (currentLine) {
- codeLines.push(currentLine.replace(/\t/g, ' '));
+ codeLines.push(currentLine.replace(/\t/g, tabHTML));
}
textValues = codeLines.map((line) => ({
content: line,
@@ -565,7 +632,7 @@ export default class codeElement extends LitElement {
} else {
for (let i = 0; i < lines.length; i++) {
textValues.push({
- content: lines[i].replace(/\t/g, ' '),
+ content: lines[i].replace(/\t/g, tabHTML),
type: '',
paddingLeft: '0px',
});
@@ -599,7 +666,19 @@ export default class codeElement extends LitElement {
customValue = labels[key] || 'Copy code';
break;
case 'code-copypaste-success':
- customValue = labels[key] || 'Copieddddd!';
+ customValue = labels[key] || 'Copied!';
+ break;
+ case 'code-estimated-warning':
+ customValue = labels[key] || '(estimated)';
+ break;
+ case 'code-editing-validation':
+ customValue = labels[key] || 'Save edits';
+ break;
+ case 'code-editing-cancelled':
+ customValue = labels[key] || 'Revert edits';
+ break;
+ case 'code-line-descriptor':
+ customValue = labels[key] || 'lines';
break;
}
}
diff --git a/packages/web-components/src/components/chat/components/footer/src/footer.ts b/packages/web-components/src/components/chat/components/footer/src/footer.ts
index 942009e6..e992b261 100644
--- a/packages/web-components/src/components/chat/components/footer/src/footer.ts
+++ b/packages/web-components/src/components/chat/components/footer/src/footer.ts
@@ -97,6 +97,12 @@ export default class footer extends LitElement {
@state()
hideContextMessage = false;
+ /**
+ * focus-prompt set focus targeting
+ */
+ @property({ type: Boolean, attribute: 'focus-prompt' })
+ _focusPrompt;
+
/**
* add context meesage above prompt
*/
@@ -210,6 +216,18 @@ export default class footer extends LitElement {
this._checkLimit();
}
}
+
+ if (changedProperties.has('_focusPrompt')) {
+ if (this._focusPrompt) {
+ const textArea = this.shadowRoot?.querySelector(
+ '.' + clabsPrefix + '--chat-search-query'
+ );
+ if (textArea instanceof HTMLElement) {
+ textArea.focus();
+ this._isPromptFocused = true;
+ }
+ }
+ }
if (changedProperties.has('_fullscreenMode')) {
this._checkSize();
}
diff --git a/packages/web-components/src/components/chat/components/formulaElement/src/formulaElement.ts b/packages/web-components/src/components/chat/components/formulaElement/src/formulaElement.ts
index 5dc8f186..5cbe22f1 100644
--- a/packages/web-components/src/components/chat/components/formulaElement/src/formulaElement.ts
+++ b/packages/web-components/src/components/chat/components/formulaElement/src/formulaElement.ts
@@ -33,6 +33,36 @@ export default class formulaElement extends LitElement {
@state()
formula;
+ /**
+ * startMathJax - edit target document for rendering
+ */
+ async startMathJax() {
+ // @ts-ignore
+ /**
+ * getComponents
+ */
+ // @ts-ignore
+ MathJax.startup.getComponents = () => {
+ // @ts-ignore
+ MathJax.startup.document = MathJax.startup.document.constructor({
+ // @ts-ignore
+ options: MathJax.config.options,
+ // @ts-ignore
+ renderActions: MathJax.startup.renderActions,
+ // @ts-ignore
+ inputJax: MathJax.startup.input,
+ // @ts-ignore
+ outputJax: MathJax.startup.output,
+ // @ts-ignore
+ adaptor: MathJax.startup.adaptor,
+ });
+ // @ts-ignore
+ MathJax.startup.document.document = this.shadowRoot;
+ };
+ // @ts-ignore
+ await MathJax.startup.promise;
+ }
+
/** detect when component is rendered to process visualization specification object
*/
firstUpdated() {
@@ -62,6 +92,7 @@ export default class formulaElement extends LitElement {
* Prepare table object for rendering from content string
*/
async _renderFormula() {
+ await this.startMathJax();
const targetDiv = this.shadowRoot?.querySelector(
'.' + clabsPrefix + '--chat-formula-container'
);
diff --git a/packages/web-components/src/components/chat/components/message/src/message.ts b/packages/web-components/src/components/chat/components/message/src/message.ts
index 417c5de6..e2f2f80b 100644
--- a/packages/web-components/src/components/chat/components/message/src/message.ts
+++ b/packages/web-components/src/components/chat/components/message/src/message.ts
@@ -1514,9 +1514,13 @@ export default class message extends LitElement {
const messageDetails = this._prepareEventDetail();
if (this.positiveFeedbackSelected) {
messageDetails['action'] = 'message: user gave feedback to response';
+
+ messageDetails['feedbackRetracted'] = false;
this._focusOnPopup();
} else {
messageDetails['action'] = 'message: user removed feedback to response';
+
+ messageDetails['feedbackRetracted'] = true;
}
messageDetails['type'] = 'positive';
messageDetails['rawTextMessage'] = this.rawText;
@@ -1546,9 +1550,11 @@ export default class message extends LitElement {
const messageDetails = this._prepareEventDetail();
if (this.negativeFeedbackSelected) {
messageDetails['action'] = 'message: user gave feedback to response';
+ messageDetails['feedbackRetracted'] = false;
this._focusOnPopup();
} else {
messageDetails['action'] = 'message: user removed feedback to response';
+ messageDetails['feedbackRetracted'] = true;
}
messageDetails['type'] = 'negative';
messageDetails['rawTextMessage'] = this.rawText;
diff --git a/packages/web-components/src/components/chat/components/messages/src/messages.ts b/packages/web-components/src/components/chat/components/messages/src/messages.ts
index efbfd3dd..e672447d 100644
--- a/packages/web-components/src/components/chat/components/messages/src/messages.ts
+++ b/packages/web-components/src/components/chat/components/messages/src/messages.ts
@@ -36,6 +36,12 @@ export default class messages extends LitElement {
@property({ type: Boolean, attribute: 'loading', reflect: true })
loading;
+ /**
+ * force scroll down on new messages no matter what
+ */
+ @property({ type: Boolean, attribute: 'force-scroll-down' })
+ forceScrollDown;
+
/**
* user-assigned boolean denoting when text content is streamed in token by token
*/
@@ -196,7 +202,11 @@ export default class messages extends LitElement {
}
if (changedProperties.has('_computedMessages')) {
- this._scrollMessage();
+ if (!this.forceScrollDown) {
+ this._scrollMessage();
+ } else {
+ this._scrollToBottom();
+ }
}
if (changedProperties.has('loading')) {
diff --git a/packages/web-components/src/components/chat/components/popupElement/src/popupElement.scss b/packages/web-components/src/components/chat/components/popupElement/src/popupElement.scss
index 1e86f910..b97ab0d4 100644
--- a/packages/web-components/src/components/chat/components/popupElement/src/popupElement.scss
+++ b/packages/web-components/src/components/chat/components/popupElement/src/popupElement.scss
@@ -126,7 +126,7 @@
}
.#{$clabs-prefix}--chat-popup-title {
- padding: 0.5rem;
+ padding: 1rem;
color: $text-primary;
font-size: 18px;
font-weight: 400;
@@ -142,19 +142,19 @@
font-weight: 400;
letter-spacing: 0.32px;
line-height: 16px;
- padding-inline: 0.5rem;
+ padding-inline: 1rem;
text-align: start;
}
.#{$clabs-prefix}--chat-popup-description {
font-size: 14px;
- margin-block-start: 0.5rem;
- padding-inline: 0.5rem;
+ margin-block-start: 1rem;
+ padding-inline: 1rem;
text-align: start;
}
.#{$clabs-prefix}--chat-popup-model-title {
font-size: 14px;
padding-block: 6px;
- padding-inline: 0.5rem;
+ padding-inline: 1rem;
text-align: start;
}
@@ -162,8 +162,8 @@
overflow: hidden;
box-sizing: border-box;
max-inline-size: 100%;
- padding-block: 0.5rem 8px;
- padding-inline: 0.5rem;
+ padding-block: 1rem 8px;
+ padding-inline: 1rem;
}
.#{$clabs-prefix}--chat-popup-feedback-text {
@@ -173,7 +173,7 @@
inline-size: 100%;
inset-block-start: 205.54px;
inset-inline-start: 24px;
- padding-inline: 0.5rem;
+ padding-inline: 1rem;
}
.#{$clabs-prefix}--chat-popup-feedback-text-area {
overflow: hidden;
@@ -188,7 +188,7 @@
letter-spacing: 0.32px;
line-height: 16px;
margin-block: 0.5rem 1.5rem;
- padding-inline: 0.5rem;
+ padding-inline: 1rem;
text-align: start;
}
@@ -203,7 +203,7 @@
.#{$clabs-prefix}--chat-popup-checkbox {
margin-inline-start: -2px;
padding-block-end: 0.5rem;
- padding-inline: 0.5rem;
+ padding-inline: 1rem;
}
.#{$clabs-prefix}--chat-popup-submit {
diff --git a/packages/web-components/src/components/chat/components/popupElement/src/popupElement.template.ts b/packages/web-components/src/components/chat/components/popupElement/src/popupElement.template.ts
index 2eff358d..dc81d688 100644
--- a/packages/web-components/src/components/chat/components/popupElement/src/popupElement.template.ts
+++ b/packages/web-components/src/components/chat/components/popupElement/src/popupElement.template.ts
@@ -128,6 +128,7 @@ export function popupElementTemplate(customElementClass) {