@ably/ui 17.14.0-dev.a396678b99 → 17.14.0-dev.dff5348de8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/Code/Code.test.js +2 -0
- package/core/Code/Code.test.js.map +1 -0
- package/core/Code.js +1 -1
- package/core/Code.js.map +1 -1
- package/core/utils/syntax-highlighter.js +1 -1
- package/core/utils/syntax-highlighter.js.map +1 -1
- package/core/utils/syntax-highlighter.test.js +2 -0
- package/core/utils/syntax-highlighter.test.js.map +1 -0
- package/index.d.ts +13 -0
- package/package.json +1 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import React from"react";import{describe,expect,it}from"vitest";import{render}from"@testing-library/react";import Code from"../Code";describe("Code",()=>{it("renders a single <code> element when no highlights are present",()=>{const{container}=render(React.createElement(Code,{language:"javascript",snippet:'var x = "hello";'}));const codeElements=container.querySelectorAll("code");expect(codeElements.length).toBe(1)});it("uses <span> (not <code>) for per-line content when highlights are present",()=>{const{container}=render(React.createElement(Code,{language:"javascript",snippet:'var x = "hello";\nvar y = "world";',lineHighlights:{1:"addition"}}));const pre=container.querySelector("pre");const innerCodeElements=pre?.querySelectorAll("code");expect(innerCodeElements?.length??0).toBe(0);const lineSpans=pre?.querySelectorAll("span.ui-text-code");expect(lineSpans?.length).toBeGreaterThan(0)});it("applies highlight classes to the correct lines",()=>{const{container}=render(React.createElement(Code,{language:"javascript",snippet:"line1\nline2\nline3",lineHighlights:{1:"addition",3:"removal"}}));const lineWrappers=container.querySelectorAll("pre > span");expect(lineWrappers.length).toBe(3);expect(lineWrappers[0].classList.contains("code-line-addition")).toBe(true);expect(lineWrappers[1].classList.contains("code-line-addition")).toBe(false);expect(lineWrappers[2].classList.contains("code-line-removal")).toBe(true)})});
|
|
2
|
+
//# sourceMappingURL=Code.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Code/Code.test.tsx"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\n\nimport React from \"react\";\nimport { describe, expect, it } from \"vitest\";\nimport { render } from \"@testing-library/react\";\n\nimport Code from \"../Code\";\n\ndescribe(\"Code\", () => {\n it(\"renders a single <code> element when no highlights are present\", () => {\n const { container } = render(\n <Code language=\"javascript\" snippet={'var x = \"hello\";'} />,\n );\n const codeElements = container.querySelectorAll(\"code\");\n expect(codeElements.length).toBe(1);\n });\n\n it(\"uses <span> (not <code>) for per-line content when highlights are present\", () => {\n const { container } = render(\n <Code\n language=\"javascript\"\n snippet={'var x = \"hello\";\\nvar y = \"world\";'}\n lineHighlights={{ 1: \"addition\" }}\n />,\n );\n\n // The highlighted path should not produce inner <code> elements\n const pre = container.querySelector(\"pre\");\n const innerCodeElements = pre?.querySelectorAll(\"code\");\n expect(innerCodeElements?.length ?? 0).toBe(0);\n\n // It should use <span> elements with the text-size class for line content\n const lineSpans = pre?.querySelectorAll(\"span.ui-text-code\");\n expect(lineSpans?.length).toBeGreaterThan(0);\n });\n\n it(\"applies highlight classes to the correct lines\", () => {\n const { container } = render(\n <Code\n language=\"javascript\"\n snippet={\"line1\\nline2\\nline3\"}\n lineHighlights={{ 1: \"addition\", 3: \"removal\" }}\n />,\n );\n\n const lineWrappers = container.querySelectorAll(\"pre > span\");\n expect(lineWrappers.length).toBe(3);\n expect(lineWrappers[0].classList.contains(\"code-line-addition\")).toBe(true);\n expect(lineWrappers[1].classList.contains(\"code-line-addition\")).toBe(\n false,\n );\n expect(lineWrappers[2].classList.contains(\"code-line-removal\")).toBe(true);\n });\n});\n"],"names":["React","describe","expect","it","render","Code","container","language","snippet","codeElements","querySelectorAll","length","toBe","lineHighlights","pre","querySelector","innerCodeElements","lineSpans","toBeGreaterThan","lineWrappers","classList","contains"],"mappings":"AAIA,OAAOA,UAAW,OAAQ,AAC1B,QAASC,QAAQ,CAAEC,MAAM,CAAEC,EAAE,KAAQ,QAAS,AAC9C,QAASC,MAAM,KAAQ,wBAAyB,AAEhD,QAAOC,SAAU,SAAU,CAE3BJ,SAAS,OAAQ,KACfE,GAAG,iEAAkE,KACnE,KAAM,CAAEG,SAAS,CAAE,CAAGF,OACpB,oBAACC,MAAKE,SAAS,aAAaC,QAAS,sBAEvC,MAAMC,aAAeH,UAAUI,gBAAgB,CAAC,QAChDR,OAAOO,aAAaE,MAAM,EAAEC,IAAI,CAAC,EACnC,GAEAT,GAAG,4EAA6E,KAC9E,KAAM,CAAEG,SAAS,CAAE,CAAGF,OACpB,oBAACC,MACCE,SAAS,aACTC,QAAS,qCACTK,eAAgB,CAAE,EAAG,UAAW,KAKpC,MAAMC,IAAMR,UAAUS,aAAa,CAAC,OACpC,MAAMC,kBAAoBF,KAAKJ,iBAAiB,QAChDR,OAAOc,mBAAmBL,QAAU,GAAGC,IAAI,CAAC,GAG5C,MAAMK,UAAYH,KAAKJ,iBAAiB,qBACxCR,OAAOe,WAAWN,QAAQO,eAAe,CAAC,EAC5C,GAEAf,GAAG,iDAAkD,KACnD,KAAM,CAAEG,SAAS,CAAE,CAAGF,OACpB,oBAACC,MACCE,SAAS,aACTC,QAAS,sBACTK,eAAgB,CAAE,EAAG,WAAY,EAAG,SAAU,KAIlD,MAAMM,aAAeb,UAAUI,gBAAgB,CAAC,cAChDR,OAAOiB,aAAaR,MAAM,EAAEC,IAAI,CAAC,GACjCV,OAAOiB,YAAY,CAAC,EAAE,CAACC,SAAS,CAACC,QAAQ,CAAC,uBAAuBT,IAAI,CAAC,MACtEV,OAAOiB,YAAY,CAAC,EAAE,CAACC,SAAS,CAACC,QAAQ,CAAC,uBAAuBT,IAAI,CACnE,OAEFV,OAAOiB,YAAY,CAAC,EAAE,CAACC,SAAS,CAACC,QAAQ,CAAC,sBAAsBT,IAAI,CAAC,KACvE,EACF"}
|
package/core/Code.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import{highlightSnippet,LINE_HIGHLIGHT_CLASSES,registerDefaultLanguages,splitHtmlLines}from"./utils/syntax-highlighter";import languagesRegistry from"./utils/syntax-highlighter-registry";import cn from"./utils/cn";registerDefaultLanguages(languagesRegistry);const Code=({language,snippet,textSize="ui-text-code",padding="p-8",additionalCSS="",showLines,lineCSS,wrap=false,lineHighlights})=>{const trimmedSnippet=snippet.trimEnd();const HTMLraw=highlightSnippet(language,trimmedSnippet)??"";const className=`language-${language} ${textSize}`;const lines=trimmedSnippet.split(/\r\n|\r|\n/);const lineCount=lines.length;const hasHighlights=lineHighlights&&Object.keys(lineHighlights).length>0;if(hasHighlights){const htmlLines=splitHtmlLines(HTMLraw);return React.createElement("div",{className:cn("hljs overflow-y-auto",padding,additionalCSS),"data-id":"code"},React.createElement("pre",{lang:language,className:cn("h-full flex-1 text-p4 leading-normal",wrap?"whitespace-pre-wrap break-words":"overflow-x-auto")},htmlLines.map((lineHtml,i)=>{const lineNum=i+1;const highlightType=lineHighlights[lineNum];const highlightClass=highlightType?LINE_HIGHLIGHT_CLASSES[highlightType]:undefined;return React.createElement("span",{key:i,className:cn("flex min-w-full",highlightClass)},showLines&&React.createElement("span",{className:cn("mr-4 font-mono text-right text-neutral-800 select-none shrink-0 inline-block",lineCSS),style:{minWidth:`${String(lineCount).length}ch`}},lineNum),React.createElement("
|
|
1
|
+
import React from"react";import{highlightSnippet,LINE_HIGHLIGHT_CLASSES,registerDefaultLanguages,splitHtmlLines}from"./utils/syntax-highlighter";import languagesRegistry from"./utils/syntax-highlighter-registry";import cn from"./utils/cn";registerDefaultLanguages(languagesRegistry);const Code=({language,snippet,textSize="ui-text-code",padding="p-8",additionalCSS="",showLines,lineCSS,wrap=false,lineHighlights})=>{const trimmedSnippet=snippet.trimEnd();const HTMLraw=highlightSnippet(language,trimmedSnippet)??"";const className=`language-${language} ${textSize}`;const lines=trimmedSnippet.split(/\r\n|\r|\n/);const lineCount=lines.length;const hasHighlights=lineHighlights&&Object.keys(lineHighlights).length>0;if(hasHighlights){const htmlLines=splitHtmlLines(HTMLraw);return React.createElement("div",{className:cn("hljs overflow-y-auto",padding,additionalCSS),"data-id":"code"},React.createElement("pre",{lang:language,className:cn("h-full flex-1 text-p4 leading-normal",wrap?"whitespace-pre-wrap break-words":"overflow-x-auto")},htmlLines.map((lineHtml,i)=>{const lineNum=i+1;const highlightType=lineHighlights[lineNum];const highlightClass=highlightType?LINE_HIGHLIGHT_CLASSES[highlightType]:undefined;return React.createElement("span",{key:i,className:cn("flex min-w-full",highlightClass)},showLines&&React.createElement("span",{className:cn("mr-4 font-mono text-right text-neutral-800 select-none shrink-0 inline-block",lineCSS),style:{minWidth:`${String(lineCount).length}ch`}},lineNum),React.createElement("span",{className:cn(className,"flex-1 !leading-normal"),dangerouslySetInnerHTML:{__html:lineHtml||" "}}))})))}return React.createElement("div",{className:cn("hljs overflow-y-auto flex",padding,additionalCSS),"data-id":"code"},showLines?React.createElement("div",{className:"text-p4 leading-normal pt-px"},[...Array(lineCount)].map((_,i)=>React.createElement("p",{className:cn("mr-4 font-mono text-right text-neutral-800",lineCSS),key:i},i+1))):null,React.createElement("pre",{lang:language,className:cn("h-full flex-1 text-p4 leading-normal",wrap?"whitespace-pre-wrap break-words":"overflow-x-auto")},React.createElement("code",{className:className,dangerouslySetInnerHTML:{__html:HTMLraw}})))};export default Code;
|
|
2
2
|
//# sourceMappingURL=Code.js.map
|
package/core/Code.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Code.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n highlightSnippet,\n LINE_HIGHLIGHT_CLASSES,\n registerDefaultLanguages,\n splitHtmlLines,\n} from \"./utils/syntax-highlighter\";\nimport languagesRegistry from \"./utils/syntax-highlighter-registry\";\nimport cn from \"./utils/cn\";\n\nregisterDefaultLanguages(languagesRegistry);\n\nexport type LineHighlightType = \"addition\" | \"removal\" | \"highlight\";\n\ntype CodeProps = {\n language: string;\n snippet: string;\n textSize?: string;\n padding?: string;\n additionalCSS?: string;\n showLines?: boolean;\n lineCSS?: string;\n wrap?: boolean;\n lineHighlights?: Record<number, LineHighlightType>;\n};\n\nconst Code = ({\n language,\n snippet,\n textSize = \"ui-text-code\",\n padding = \"p-8\",\n additionalCSS = \"\",\n showLines,\n lineCSS,\n wrap = false,\n lineHighlights,\n}: CodeProps) => {\n // Trim the snippet and remove trailing empty lines\n const trimmedSnippet = snippet.trimEnd();\n const HTMLraw = highlightSnippet(language, trimmedSnippet) ?? \"\";\n const className = `language-${language} ${textSize}`;\n\n // Calculate line count after removing trailing empty lines\n const lines = trimmedSnippet.split(/\\r\\n|\\r|\\n/);\n const lineCount = lines.length;\n\n const hasHighlights =\n lineHighlights && Object.keys(lineHighlights).length > 0;\n\n // Per-line rendering when highlights are present\n if (hasHighlights) {\n const htmlLines = splitHtmlLines(HTMLraw);\n\n return (\n <div\n className={cn(\"hljs overflow-y-auto\", padding, additionalCSS)}\n data-id=\"code\"\n >\n <pre\n lang={language}\n className={cn(\n \"h-full flex-1 text-p4 leading-normal\",\n wrap ? \"whitespace-pre-wrap break-words\" : \"overflow-x-auto\",\n )}\n >\n {htmlLines.map((lineHtml, i) => {\n const lineNum = i + 1;\n const highlightType = lineHighlights[lineNum];\n const highlightClass = highlightType\n ? LINE_HIGHLIGHT_CLASSES[highlightType]\n : undefined;\n\n return (\n <span key={i} className={cn(\"flex min-w-full\", highlightClass)}>\n {showLines && (\n <span\n className={cn(\n \"mr-4 font-mono text-right text-neutral-800 select-none shrink-0 inline-block\",\n lineCSS,\n )}\n style={{ minWidth: `${String(lineCount).length}ch` }}\n >\n {lineNum}\n </span>\n )}\n <
|
|
1
|
+
{"version":3,"sources":["../../src/core/Code.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n highlightSnippet,\n LINE_HIGHLIGHT_CLASSES,\n registerDefaultLanguages,\n splitHtmlLines,\n} from \"./utils/syntax-highlighter\";\nimport languagesRegistry from \"./utils/syntax-highlighter-registry\";\nimport cn from \"./utils/cn\";\n\nregisterDefaultLanguages(languagesRegistry);\n\nexport type LineHighlightType = \"addition\" | \"removal\" | \"highlight\";\n\ntype CodeProps = {\n language: string;\n snippet: string;\n textSize?: string;\n padding?: string;\n additionalCSS?: string;\n showLines?: boolean;\n lineCSS?: string;\n wrap?: boolean;\n lineHighlights?: Record<number, LineHighlightType>;\n};\n\nconst Code = ({\n language,\n snippet,\n textSize = \"ui-text-code\",\n padding = \"p-8\",\n additionalCSS = \"\",\n showLines,\n lineCSS,\n wrap = false,\n lineHighlights,\n}: CodeProps) => {\n // Trim the snippet and remove trailing empty lines\n const trimmedSnippet = snippet.trimEnd();\n const HTMLraw = highlightSnippet(language, trimmedSnippet) ?? \"\";\n const className = `language-${language} ${textSize}`;\n\n // Calculate line count after removing trailing empty lines\n const lines = trimmedSnippet.split(/\\r\\n|\\r|\\n/);\n const lineCount = lines.length;\n\n const hasHighlights =\n lineHighlights && Object.keys(lineHighlights).length > 0;\n\n // Per-line rendering when highlights are present\n if (hasHighlights) {\n const htmlLines = splitHtmlLines(HTMLraw);\n\n return (\n <div\n className={cn(\"hljs overflow-y-auto\", padding, additionalCSS)}\n data-id=\"code\"\n >\n <pre\n lang={language}\n className={cn(\n \"h-full flex-1 text-p4 leading-normal\",\n wrap ? \"whitespace-pre-wrap break-words\" : \"overflow-x-auto\",\n )}\n >\n {htmlLines.map((lineHtml, i) => {\n const lineNum = i + 1;\n const highlightType = lineHighlights[lineNum];\n const highlightClass = highlightType\n ? LINE_HIGHLIGHT_CLASSES[highlightType]\n : undefined;\n\n return (\n <span key={i} className={cn(\"flex min-w-full\", highlightClass)}>\n {showLines && (\n <span\n className={cn(\n \"mr-4 font-mono text-right text-neutral-800 select-none shrink-0 inline-block\",\n lineCSS,\n )}\n style={{ minWidth: `${String(lineCount).length}ch` }}\n >\n {lineNum}\n </span>\n )}\n <span\n className={cn(className, \"flex-1 !leading-normal\")}\n dangerouslySetInnerHTML={{\n __html: lineHtml || \" \",\n }}\n />\n </span>\n );\n })}\n </pre>\n </div>\n );\n }\n\n // Default: single-block rendering (no highlights)\n return (\n <div\n className={cn(\"hljs overflow-y-auto flex\", padding, additionalCSS)}\n data-id=\"code\"\n >\n {showLines ? (\n <div className=\"text-p4 leading-normal pt-px\">\n {[...Array(lineCount)].map((_, i) => (\n <p\n className={cn(\n \"mr-4 font-mono text-right text-neutral-800\",\n lineCSS,\n )}\n key={i}\n >\n {i + 1}\n </p>\n ))}\n </div>\n ) : null}\n <pre\n lang={language}\n className={cn(\n \"h-full flex-1 text-p4 leading-normal\",\n wrap ? \"whitespace-pre-wrap break-words\" : \"overflow-x-auto\",\n )}\n >\n <code\n className={className}\n dangerouslySetInnerHTML={{ __html: HTMLraw }}\n />\n </pre>\n </div>\n );\n};\n\nexport default Code;\n"],"names":["React","highlightSnippet","LINE_HIGHLIGHT_CLASSES","registerDefaultLanguages","splitHtmlLines","languagesRegistry","cn","Code","language","snippet","textSize","padding","additionalCSS","showLines","lineCSS","wrap","lineHighlights","trimmedSnippet","trimEnd","HTMLraw","className","lines","split","lineCount","length","hasHighlights","Object","keys","htmlLines","div","data-id","pre","lang","map","lineHtml","i","lineNum","highlightType","highlightClass","undefined","span","key","style","minWidth","String","dangerouslySetInnerHTML","__html","Array","_","p","code"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QACEC,gBAAgB,CAChBC,sBAAsB,CACtBC,wBAAwB,CACxBC,cAAc,KACT,4BAA6B,AACpC,QAAOC,sBAAuB,qCAAsC,AACpE,QAAOC,OAAQ,YAAa,CAE5BH,yBAAyBE,mBAgBzB,MAAME,KAAO,CAAC,CACZC,QAAQ,CACRC,OAAO,CACPC,SAAW,cAAc,CACzBC,QAAU,KAAK,CACfC,cAAgB,EAAE,CAClBC,SAAS,CACTC,OAAO,CACPC,KAAO,KAAK,CACZC,cAAc,CACJ,IAEV,MAAMC,eAAiBR,QAAQS,OAAO,GACtC,MAAMC,QAAUlB,iBAAiBO,SAAUS,iBAAmB,GAC9D,MAAMG,UAAY,CAAC,SAAS,EAAEZ,SAAS,CAAC,EAAEE,SAAS,CAAC,CAGpD,MAAMW,MAAQJ,eAAeK,KAAK,CAAC,cACnC,MAAMC,UAAYF,MAAMG,MAAM,CAE9B,MAAMC,cACJT,gBAAkBU,OAAOC,IAAI,CAACX,gBAAgBQ,MAAM,CAAG,EAGzD,GAAIC,cAAe,CACjB,MAAMG,UAAYxB,eAAee,SAEjC,OACE,oBAACU,OACCT,UAAWd,GAAG,uBAAwBK,QAASC,eAC/CkB,UAAQ,QAER,oBAACC,OACCC,KAAMxB,SACNY,UAAWd,GACT,uCACAS,KAAO,kCAAoC,oBAG5Ca,UAAUK,GAAG,CAAC,CAACC,SAAUC,KACxB,MAAMC,QAAUD,EAAI,EACpB,MAAME,cAAgBrB,cAAc,CAACoB,QAAQ,CAC7C,MAAME,eAAiBD,cACnBnC,sBAAsB,CAACmC,cAAc,CACrCE,UAEJ,OACE,oBAACC,QAAKC,IAAKN,EAAGf,UAAWd,GAAG,kBAAmBgC,iBAC5CzB,WACC,oBAAC2B,QACCpB,UAAWd,GACT,+EACAQ,SAEF4B,MAAO,CAAEC,SAAU,CAAC,EAAEC,OAAOrB,WAAWC,MAAM,CAAC,EAAE,CAAC,AAAC,GAElDY,SAGL,oBAACI,QACCpB,UAAWd,GAAGc,UAAW,0BACzByB,wBAAyB,CACvBC,OAAQZ,UAAY,QACtB,IAIR,IAIR,CAGA,OACE,oBAACL,OACCT,UAAWd,GAAG,4BAA6BK,QAASC,eACpDkB,UAAQ,QAEPjB,UACC,oBAACgB,OAAIT,UAAU,gCACZ,IAAI2B,MAAMxB,WAAW,CAACU,GAAG,CAAC,CAACe,EAAGb,IAC7B,oBAACc,KACC7B,UAAWd,GACT,6CACAQ,SAEF2B,IAAKN,GAEJA,EAAI,KAIT,KACJ,oBAACJ,OACCC,KAAMxB,SACNY,UAAWd,GACT,uCACAS,KAAO,kCAAoC,oBAG7C,oBAACmC,QACC9B,UAAWA,UACXyB,wBAAyB,CAAEC,OAAQ3B,OAAQ,KAKrD,CAEA,gBAAeZ,IAAK"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import hljs from"highlight.js/lib/core";const languageToHighlightKey=lang=>{let id;if(!lang){lang="text"}switch(lang.toLowerCase()){case"android":id="java";break;case".net":case"net":case"dotnet":case"csharp":case"c#":id="cs";break;case"objc":case"objective c":id="objectivec";break;case"laravel":id="php";break;case"flutter":id="dart";break;case"node.js":case"js":id="javascript";break;case"ts":id="typescript";break;case"kotlin":case"kt":id="kotlin";break;case"shell":case"fh":case"sh":id="bash";break;case"https":case"http":case"txt":case"plaintext":id="text";break;case"cmd":case"bat":id="dos";break;case"yml":id="yaml";break;case"erl":id="erlang";break;case"patch":id="diff";break;case"svg":id="xml";break;default:break}return id||lang};const registerDefaultLanguages=register=>{register.forEach(({key,module})=>hljs.registerLanguage(key,module))};const highlightSnippet=(languageKeyword,snippet)=>{const language=languageToHighlightKey(languageKeyword);if(typeof snippet!=="string"||!snippet||!language)return;return hljs.highlight(snippet,{language}).value};const parseLineHighlights=(languageString,meta)=>{if(!meta){return{lang:languageString,highlights:{}}}const match=meta.match(/highlight=["']?([^"']+)["']?/);if(!match){return{lang:languageString,highlights:{}}}const spec=match[1];const highlights={};const tokens=spec.split(",");for(const token of tokens){const trimmed=token.trim();if(!trimmed)continue;let type="highlight";let rangePart=trimmed;if(trimmed.startsWith("+")){type="addition";rangePart=trimmed.slice(1)}else if(trimmed.startsWith("-")){type="removal";rangePart=trimmed.slice(1)}const rangeMatch=rangePart.match(/^(\d+)(?:-(\d+))?$/);if(!rangeMatch)continue;const start=parseInt(rangeMatch[1],10);const end=rangeMatch[2]?parseInt(rangeMatch[2],10):start;for(let i=start;i<=end;i++){highlights[i]=type}}return{lang:languageString,highlights}};const splitHtmlLines=html=>{const rawLines=html.split("\n");const result=[];let openTags=[];for(const rawLine of rawLines){let line=openTags.join("")+rawLine;const
|
|
1
|
+
import hljs from"highlight.js/lib/core";const languageToHighlightKey=lang=>{let id;if(!lang){lang="text"}switch(lang.toLowerCase()){case"android":id="java";break;case".net":case"net":case"dotnet":case"csharp":case"c#":id="cs";break;case"objc":case"objective c":id="objectivec";break;case"laravel":id="php";break;case"flutter":id="dart";break;case"node.js":case"js":id="javascript";break;case"ts":id="typescript";break;case"kotlin":case"kt":id="kotlin";break;case"shell":case"fh":case"sh":id="bash";break;case"https":case"http":case"txt":case"plaintext":id="text";break;case"cmd":case"bat":id="dos";break;case"yml":id="yaml";break;case"erl":id="erlang";break;case"patch":id="diff";break;case"svg":id="xml";break;default:break}return id||lang};const registerDefaultLanguages=register=>{register.forEach(({key,module})=>hljs.registerLanguage(key,module))};const highlightSnippet=(languageKeyword,snippet)=>{const language=languageToHighlightKey(languageKeyword);if(typeof snippet!=="string"||!snippet||!language)return;return hljs.highlight(snippet,{language}).value};const parseLineHighlights=(languageString,meta)=>{if(!meta){return{lang:languageString,highlights:{}}}const match=meta.match(/highlight=["']?([^"']+)["']?/);if(!match){return{lang:languageString,highlights:{}}}const spec=match[1];const highlights={};const tokens=spec.split(",");for(const token of tokens){const trimmed=token.trim();if(!trimmed)continue;let type="highlight";let rangePart=trimmed;if(trimmed.startsWith("+")){type="addition";rangePart=trimmed.slice(1)}else if(trimmed.startsWith("-")){type="removal";rangePart=trimmed.slice(1)}const rangeMatch=rangePart.match(/^(\d+)(?:-(\d+))?$/);if(!rangeMatch)continue;const start=parseInt(rangeMatch[1],10);const end=rangeMatch[2]?parseInt(rangeMatch[2],10):start;for(let i=start;i<=end;i++){highlights[i]=type}}return{lang:languageString,highlights}};const splitHtmlLines=html=>{const rawLines=html.split("\n");const result=[];let openTags=[];for(const rawLine of rawLines){let line=openTags.join("")+rawLine;const tagPattern=/<(\/?)span([^>]*)>/g;let m;while((m=tagPattern.exec(rawLine))!==null){if(m[1]==="/"){openTags.pop()}else{openTags.push(m[0])}}for(let i=0;i<openTags.length;i++){line+="</span>"}result.push(line)}return result};const LINE_HIGHLIGHT_CLASSES={addition:"code-line-addition",removal:"code-line-removal",highlight:"code-line-highlight"};export{highlightSnippet,languageToHighlightKey,LINE_HIGHLIGHT_CLASSES,parseLineHighlights,registerDefaultLanguages,splitHtmlLines};
|
|
2
2
|
//# sourceMappingURL=syntax-highlighter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/utils/syntax-highlighter.js"],"sourcesContent":["import hljs from \"highlight.js/lib/core\";\n\n// Map certain frameworks, protocols etc to available langauage packs\nconst languageToHighlightKey = (lang) => {\n let id;\n\n if (!lang) {\n lang = \"text\";\n }\n\n switch (lang.toLowerCase()) {\n case \"android\":\n id = \"java\";\n break;\n\n case \".net\":\n case \"net\":\n case \"dotnet\":\n case \"csharp\":\n case \"c#\":\n id = \"cs\";\n break;\n\n case \"objc\":\n case \"objective c\":\n id = \"objectivec\";\n break;\n\n case \"laravel\":\n id = \"php\";\n break;\n\n case \"flutter\":\n id = \"dart\";\n break;\n\n case \"node.js\":\n case \"js\":\n id = \"javascript\";\n break;\n\n case \"ts\":\n id = \"typescript\";\n break;\n\n case \"kotlin\":\n case \"kt\":\n id = \"kotlin\";\n break;\n\n case \"shell\":\n case \"fh\":\n case \"sh\":\n id = \"bash\";\n break;\n\n case \"https\":\n case \"http\":\n case \"txt\":\n case \"plaintext\":\n id = \"text\";\n break;\n\n case \"cmd\":\n case \"bat\":\n id = \"dos\";\n break;\n\n case \"yml\":\n id = \"yaml\";\n break;\n\n case \"erl\":\n id = \"erlang\";\n break;\n\n case \"patch\":\n id = \"diff\";\n break;\n\n case \"svg\":\n id = \"xml\";\n break;\n\n default:\n break;\n }\n\n return id || lang;\n};\n\nconst registerDefaultLanguages = (register) => {\n register.forEach(({ key, module }) => hljs.registerLanguage(key, module));\n};\n\nconst highlightSnippet = (languageKeyword, snippet) => {\n const language = languageToHighlightKey(languageKeyword);\n if (typeof snippet !== \"string\" || !snippet || !language) return;\n\n return hljs.highlight(snippet, { language }).value;\n};\n\n/**\n * Parse line highlight specifications from the code fence meta string.\n *\n * A remark plugin preserves the meta as a `data-meta` attribute on the <code>\n * element. Components read it and pass it here as the `meta` parameter.\n *\n * Syntax (in meta string): `highlight=\"+1-3,-5,7\"`\n * - `+` prefix: addition (green)\n * - `-` prefix: removal (red)\n * - no prefix: neutral highlight (blue)\n * - `N-M`: inclusive line range\n * - comma-separated for multiple specs\n *\n * @param {string} languageString - the language, e.g. \"javascript\"\n * @param {string} [meta] - the code fence meta string, e.g. 'highlight=\"+1-3,-5,7\"'\n * @returns {{ lang: string, highlights: Record<number, 'addition' | 'removal' | 'highlight'> }}\n */\nconst parseLineHighlights = (languageString, meta) => {\n if (!meta) {\n return { lang: languageString, highlights: {} };\n }\n\n const match = meta.match(/highlight=[\"']?([^\"']+)[\"']?/);\n if (!match) {\n return { lang: languageString, highlights: {} };\n }\n\n const spec = match[1];\n const highlights = {};\n\n const tokens = spec.split(\",\");\n for (const token of tokens) {\n const trimmed = token.trim();\n if (!trimmed) continue;\n\n let type = \"highlight\";\n let rangePart = trimmed;\n\n if (trimmed.startsWith(\"+\")) {\n type = \"addition\";\n rangePart = trimmed.slice(1);\n } else if (trimmed.startsWith(\"-\")) {\n type = \"removal\";\n rangePart = trimmed.slice(1);\n }\n\n const rangeMatch = rangePart.match(/^(\\d+)(?:-(\\d+))?$/);\n if (!rangeMatch) continue;\n\n const start = parseInt(rangeMatch[1], 10);\n const end = rangeMatch[2] ? parseInt(rangeMatch[2], 10) : start;\n\n for (let i = start; i <= end; i++) {\n highlights[i] = type;\n }\n }\n\n return { lang: languageString, highlights };\n};\n\n/**\n * Split highlighted HTML by newlines, repairing any spans that cross\n * line boundaries so each line fragment is valid HTML.\n *\n * @param {string} html - HTML string produced by highlight.js\n * @returns {string[]} one HTML fragment per source line\n */\nconst splitHtmlLines = (html) => {\n const rawLines = html.split(\"\\n\");\n const result = [];\n let openTags = [];\n\n for (const rawLine of rawLines) {\n let line = openTags.join(\"\") + rawLine;\n\n const
|
|
1
|
+
{"version":3,"sources":["../../../src/core/utils/syntax-highlighter.js"],"sourcesContent":["import hljs from \"highlight.js/lib/core\";\n\n// Map certain frameworks, protocols etc to available langauage packs\nconst languageToHighlightKey = (lang) => {\n let id;\n\n if (!lang) {\n lang = \"text\";\n }\n\n switch (lang.toLowerCase()) {\n case \"android\":\n id = \"java\";\n break;\n\n case \".net\":\n case \"net\":\n case \"dotnet\":\n case \"csharp\":\n case \"c#\":\n id = \"cs\";\n break;\n\n case \"objc\":\n case \"objective c\":\n id = \"objectivec\";\n break;\n\n case \"laravel\":\n id = \"php\";\n break;\n\n case \"flutter\":\n id = \"dart\";\n break;\n\n case \"node.js\":\n case \"js\":\n id = \"javascript\";\n break;\n\n case \"ts\":\n id = \"typescript\";\n break;\n\n case \"kotlin\":\n case \"kt\":\n id = \"kotlin\";\n break;\n\n case \"shell\":\n case \"fh\":\n case \"sh\":\n id = \"bash\";\n break;\n\n case \"https\":\n case \"http\":\n case \"txt\":\n case \"plaintext\":\n id = \"text\";\n break;\n\n case \"cmd\":\n case \"bat\":\n id = \"dos\";\n break;\n\n case \"yml\":\n id = \"yaml\";\n break;\n\n case \"erl\":\n id = \"erlang\";\n break;\n\n case \"patch\":\n id = \"diff\";\n break;\n\n case \"svg\":\n id = \"xml\";\n break;\n\n default:\n break;\n }\n\n return id || lang;\n};\n\nconst registerDefaultLanguages = (register) => {\n register.forEach(({ key, module }) => hljs.registerLanguage(key, module));\n};\n\nconst highlightSnippet = (languageKeyword, snippet) => {\n const language = languageToHighlightKey(languageKeyword);\n if (typeof snippet !== \"string\" || !snippet || !language) return;\n\n return hljs.highlight(snippet, { language }).value;\n};\n\n/**\n * Parse line highlight specifications from the code fence meta string.\n *\n * A remark plugin preserves the meta as a `data-meta` attribute on the <code>\n * element. Components read it and pass it here as the `meta` parameter.\n *\n * Syntax (in meta string): `highlight=\"+1-3,-5,7\"`\n * - `+` prefix: addition (green)\n * - `-` prefix: removal (red)\n * - no prefix: neutral highlight (blue)\n * - `N-M`: inclusive line range\n * - comma-separated for multiple specs\n *\n * @param {string} languageString - the language, e.g. \"javascript\"\n * @param {string} [meta] - the code fence meta string, e.g. 'highlight=\"+1-3,-5,7\"'\n * @returns {{ lang: string, highlights: Record<number, 'addition' | 'removal' | 'highlight'> }}\n */\nconst parseLineHighlights = (languageString, meta) => {\n if (!meta) {\n return { lang: languageString, highlights: {} };\n }\n\n const match = meta.match(/highlight=[\"']?([^\"']+)[\"']?/);\n if (!match) {\n return { lang: languageString, highlights: {} };\n }\n\n const spec = match[1];\n const highlights = {};\n\n const tokens = spec.split(\",\");\n for (const token of tokens) {\n const trimmed = token.trim();\n if (!trimmed) continue;\n\n let type = \"highlight\";\n let rangePart = trimmed;\n\n if (trimmed.startsWith(\"+\")) {\n type = \"addition\";\n rangePart = trimmed.slice(1);\n } else if (trimmed.startsWith(\"-\")) {\n type = \"removal\";\n rangePart = trimmed.slice(1);\n }\n\n const rangeMatch = rangePart.match(/^(\\d+)(?:-(\\d+))?$/);\n if (!rangeMatch) continue;\n\n const start = parseInt(rangeMatch[1], 10);\n const end = rangeMatch[2] ? parseInt(rangeMatch[2], 10) : start;\n\n for (let i = start; i <= end; i++) {\n highlights[i] = type;\n }\n }\n\n return { lang: languageString, highlights };\n};\n\n/**\n * Split highlighted HTML by newlines, repairing any spans that cross\n * line boundaries so each line fragment is valid HTML.\n *\n * @param {string} html - HTML string produced by highlight.js\n * @returns {string[]} one HTML fragment per source line\n */\nconst splitHtmlLines = (html) => {\n const rawLines = html.split(\"\\n\");\n const result = [];\n let openTags = [];\n\n for (const rawLine of rawLines) {\n let line = openTags.join(\"\") + rawLine;\n\n // Process open/close tags in document order\n const tagPattern = /<(\\/?)span([^>]*)>/g;\n let m;\n while ((m = tagPattern.exec(rawLine)) !== null) {\n if (m[1] === \"/\") {\n openTags.pop();\n } else {\n openTags.push(m[0]);\n }\n }\n\n // Close any tags still open so this line is valid HTML\n for (let i = 0; i < openTags.length; i++) {\n line += \"</span>\";\n }\n\n result.push(line);\n }\n\n return result;\n};\n\nconst LINE_HIGHLIGHT_CLASSES = {\n addition: \"code-line-addition\",\n removal: \"code-line-removal\",\n highlight: \"code-line-highlight\",\n};\n\nexport {\n highlightSnippet,\n languageToHighlightKey,\n LINE_HIGHLIGHT_CLASSES,\n parseLineHighlights,\n registerDefaultLanguages,\n splitHtmlLines,\n};\n"],"names":["hljs","languageToHighlightKey","lang","id","toLowerCase","registerDefaultLanguages","register","forEach","key","module","registerLanguage","highlightSnippet","languageKeyword","snippet","language","highlight","value","parseLineHighlights","languageString","meta","highlights","match","spec","tokens","split","token","trimmed","trim","type","rangePart","startsWith","slice","rangeMatch","start","parseInt","end","i","splitHtmlLines","html","rawLines","result","openTags","rawLine","line","join","tagPattern","m","exec","pop","push","length","LINE_HIGHLIGHT_CLASSES","addition","removal"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{describe,expect,it}from"vitest";import{splitHtmlLines,parseLineHighlights}from"./syntax-highlighter";describe("splitHtmlLines",()=>{it("splits plain text with no spans",()=>{expect(splitHtmlLines("hello\nworld")).toEqual(["hello","world"])});it("repairs a span crossing a line boundary",()=>{const html='<span class="a">hello\nworld</span>';expect(splitHtmlLines(html)).toEqual(['<span class="a">hello</span>','<span class="a">world</span>'])});it("handles close then open on the same line",()=>{const html='<span class="a">first\n</span><span class="b">second\nthird</span>';const result=splitHtmlLines(html);expect(result[0]).toBe('<span class="a">first</span>');expect(result[1]).toBe('<span class="a"></span><span class="b">second</span>');expect(result[2]).toBe('<span class="b">third</span>')});it("re-opens nested spans crossing lines",()=>{const html='<span class="a"><span class="b">text\nmore</span></span>';const result=splitHtmlLines(html);expect(result[0]).toBe('<span class="a"><span class="b">text</span></span>');expect(result[1]).toBe('<span class="a"><span class="b">more</span></span>')});it("preserves empty lines",()=>{expect(splitHtmlLines("line1\n\nline3")).toEqual(["line1","","line3"])});it("does not carry forward complete spans on one line",()=>{const html='<span class="a">x</span><span class="b">y</span>\nnext';expect(splitHtmlLines(html)).toEqual(['<span class="a">x</span><span class="b">y</span>',"next"])});it("handles a single line with no newlines",()=>{expect(splitHtmlLines('<span class="a">hello</span>')).toEqual(['<span class="a">hello</span>'])})});describe("parseLineHighlights",()=>{it("returns empty highlights when no meta is provided",()=>{expect(parseLineHighlights("javascript")).toEqual({lang:"javascript",highlights:{}})});it("parses addition ranges",()=>{const result=parseLineHighlights("js",'highlight="+1-3"');expect(result.highlights).toEqual({1:"addition",2:"addition",3:"addition"})});it("parses removal lines",()=>{const result=parseLineHighlights("js",'highlight="-5"');expect(result.highlights).toEqual({5:"removal"})});it("parses neutral highlight lines",()=>{const result=parseLineHighlights("js",'highlight="7"');expect(result.highlights).toEqual({7:"highlight"})});it("parses mixed specs",()=>{const result=parseLineHighlights("js",'highlight="+1-3,-5,7"');expect(result.highlights).toEqual({1:"addition",2:"addition",3:"addition",5:"removal",7:"highlight"})})});
|
|
2
|
+
//# sourceMappingURL=syntax-highlighter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/utils/syntax-highlighter.test.js"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\n\nimport { splitHtmlLines, parseLineHighlights } from \"./syntax-highlighter\";\n\ndescribe(\"splitHtmlLines\", () => {\n it(\"splits plain text with no spans\", () => {\n expect(splitHtmlLines(\"hello\\nworld\")).toEqual([\"hello\", \"world\"]);\n });\n\n it(\"repairs a span crossing a line boundary\", () => {\n const html = '<span class=\"a\">hello\\nworld</span>';\n expect(splitHtmlLines(html)).toEqual([\n '<span class=\"a\">hello</span>',\n '<span class=\"a\">world</span>',\n ]);\n });\n\n it(\"handles close then open on the same line\", () => {\n const html =\n '<span class=\"a\">first\\n</span><span class=\"b\">second\\nthird</span>';\n const result = splitHtmlLines(html);\n\n // Line 1: carries nothing, opens \"a\" → \"first\" with closing tag\n expect(result[0]).toBe('<span class=\"a\">first</span>');\n // Line 2: carries \"a\", raw line closes \"a\" then opens \"b\" → only \"b\" open\n expect(result[1]).toBe(\n '<span class=\"a\"></span><span class=\"b\">second</span>',\n );\n // Line 3: carries only \"b\"\n expect(result[2]).toBe('<span class=\"b\">third</span>');\n });\n\n it(\"re-opens nested spans crossing lines\", () => {\n const html = '<span class=\"a\"><span class=\"b\">text\\nmore</span></span>';\n const result = splitHtmlLines(html);\n expect(result[0]).toBe(\n '<span class=\"a\"><span class=\"b\">text</span></span>',\n );\n expect(result[1]).toBe(\n '<span class=\"a\"><span class=\"b\">more</span></span>',\n );\n });\n\n it(\"preserves empty lines\", () => {\n expect(splitHtmlLines(\"line1\\n\\nline3\")).toEqual([\"line1\", \"\", \"line3\"]);\n });\n\n it(\"does not carry forward complete spans on one line\", () => {\n const html = '<span class=\"a\">x</span><span class=\"b\">y</span>\\nnext';\n expect(splitHtmlLines(html)).toEqual([\n '<span class=\"a\">x</span><span class=\"b\">y</span>',\n \"next\",\n ]);\n });\n\n it(\"handles a single line with no newlines\", () => {\n expect(splitHtmlLines('<span class=\"a\">hello</span>')).toEqual([\n '<span class=\"a\">hello</span>',\n ]);\n });\n});\n\ndescribe(\"parseLineHighlights\", () => {\n it(\"returns empty highlights when no meta is provided\", () => {\n expect(parseLineHighlights(\"javascript\")).toEqual({\n lang: \"javascript\",\n highlights: {},\n });\n });\n\n it(\"parses addition ranges\", () => {\n const result = parseLineHighlights(\"js\", 'highlight=\"+1-3\"');\n expect(result.highlights).toEqual({\n 1: \"addition\",\n 2: \"addition\",\n 3: \"addition\",\n });\n });\n\n it(\"parses removal lines\", () => {\n const result = parseLineHighlights(\"js\", 'highlight=\"-5\"');\n expect(result.highlights).toEqual({ 5: \"removal\" });\n });\n\n it(\"parses neutral highlight lines\", () => {\n const result = parseLineHighlights(\"js\", 'highlight=\"7\"');\n expect(result.highlights).toEqual({ 7: \"highlight\" });\n });\n\n it(\"parses mixed specs\", () => {\n const result = parseLineHighlights(\"js\", 'highlight=\"+1-3,-5,7\"');\n expect(result.highlights).toEqual({\n 1: \"addition\",\n 2: \"addition\",\n 3: \"addition\",\n 5: \"removal\",\n 7: \"highlight\",\n });\n });\n});\n"],"names":["describe","expect","it","splitHtmlLines","parseLineHighlights","toEqual","html","result","toBe","lang","highlights"],"mappings":"AAAA,OAASA,QAAQ,CAAEC,MAAM,CAAEC,EAAE,KAAQ,QAAS,AAE9C,QAASC,cAAc,CAAEC,mBAAmB,KAAQ,sBAAuB,CAE3EJ,SAAS,iBAAkB,KACzBE,GAAG,kCAAmC,KACpCD,OAAOE,eAAe,iBAAiBE,OAAO,CAAC,CAAC,QAAS,QAAQ,CACnE,GAEAH,GAAG,0CAA2C,KAC5C,MAAMI,KAAO,sCACbL,OAAOE,eAAeG,OAAOD,OAAO,CAAC,CACnC,+BACA,+BACD,CACH,GAEAH,GAAG,2CAA4C,KAC7C,MAAMI,KACJ,qEACF,MAAMC,OAASJ,eAAeG,MAG9BL,OAAOM,MAAM,CAAC,EAAE,EAAEC,IAAI,CAAC,gCAEvBP,OAAOM,MAAM,CAAC,EAAE,EAAEC,IAAI,CACpB,wDAGFP,OAAOM,MAAM,CAAC,EAAE,EAAEC,IAAI,CAAC,+BACzB,GAEAN,GAAG,uCAAwC,KACzC,MAAMI,KAAO,2DACb,MAAMC,OAASJ,eAAeG,MAC9BL,OAAOM,MAAM,CAAC,EAAE,EAAEC,IAAI,CACpB,sDAEFP,OAAOM,MAAM,CAAC,EAAE,EAAEC,IAAI,CACpB,qDAEJ,GAEAN,GAAG,wBAAyB,KAC1BD,OAAOE,eAAe,mBAAmBE,OAAO,CAAC,CAAC,QAAS,GAAI,QAAQ,CACzE,GAEAH,GAAG,oDAAqD,KACtD,MAAMI,KAAO,yDACbL,OAAOE,eAAeG,OAAOD,OAAO,CAAC,CACnC,mDACA,OACD,CACH,GAEAH,GAAG,yCAA0C,KAC3CD,OAAOE,eAAe,iCAAiCE,OAAO,CAAC,CAC7D,+BACD,CACH,EACF,GAEAL,SAAS,sBAAuB,KAC9BE,GAAG,oDAAqD,KACtDD,OAAOG,oBAAoB,eAAeC,OAAO,CAAC,CAChDI,KAAM,aACNC,WAAY,CAAC,CACf,EACF,GAEAR,GAAG,yBAA0B,KAC3B,MAAMK,OAASH,oBAAoB,KAAM,oBACzCH,OAAOM,OAAOG,UAAU,EAAEL,OAAO,CAAC,CAChC,EAAG,WACH,EAAG,WACH,EAAG,UACL,EACF,GAEAH,GAAG,uBAAwB,KACzB,MAAMK,OAASH,oBAAoB,KAAM,kBACzCH,OAAOM,OAAOG,UAAU,EAAEL,OAAO,CAAC,CAAE,EAAG,SAAU,EACnD,GAEAH,GAAG,iCAAkC,KACnC,MAAMK,OAASH,oBAAoB,KAAM,iBACzCH,OAAOM,OAAOG,UAAU,EAAEL,OAAO,CAAC,CAAE,EAAG,WAAY,EACrD,GAEAH,GAAG,qBAAsB,KACvB,MAAMK,OAASH,oBAAoB,KAAM,yBACzCH,OAAOM,OAAOG,UAAU,EAAEL,OAAO,CAAC,CAChC,EAAG,WACH,EAAG,WACH,EAAG,WACH,EAAG,UACH,EAAG,WACL,EACF,EACF"}
|
package/index.d.ts
CHANGED
|
@@ -304,6 +304,14 @@ export default Button;
|
|
|
304
304
|
//# sourceMappingURL=Button.d.ts.map
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
declare module '@ably/ui/core/Code/Code.test' {
|
|
308
|
+
/**
|
|
309
|
+
* @vitest-environment jsdom
|
|
310
|
+
*/
|
|
311
|
+
export {};
|
|
312
|
+
//# sourceMappingURL=Code.test.d.ts.map
|
|
313
|
+
}
|
|
314
|
+
|
|
307
315
|
declare module '@ably/ui/core/Code/component' {
|
|
308
316
|
export default highlightEl;
|
|
309
317
|
function highlightEl(el: any): void;
|
|
@@ -6633,6 +6641,11 @@ export function splitHtmlLines(html: string): string[];
|
|
|
6633
6641
|
//# sourceMappingURL=syntax-highlighter.d.ts.map
|
|
6634
6642
|
}
|
|
6635
6643
|
|
|
6644
|
+
declare module '@ably/ui/core/utils/syntax-highlighter.test' {
|
|
6645
|
+
export {};
|
|
6646
|
+
//# sourceMappingURL=syntax-highlighter.test.d.ts.map
|
|
6647
|
+
}
|
|
6648
|
+
|
|
6636
6649
|
declare module '@ably/ui/reset/scripts' {
|
|
6637
6650
|
export {};
|
|
6638
6651
|
//# sourceMappingURL=scripts.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ably/ui",
|
|
3
|
-
"version": "17.14.0-dev.
|
|
3
|
+
"version": "17.14.0-dev.dff5348de8",
|
|
4
4
|
"description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|