@ably/ui 17.13.2-dev.44eaafa0f2 → 17.13.2-dev.aa83caf92f

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/README.md CHANGED
@@ -269,25 +269,22 @@ After the above, you should have:
269
269
  To deploy a review app with your in-progress code, you can use the `pre-release` script:
270
270
 
271
271
  ```bash
272
- # in packages/ui directory
273
- ./scripts/pre-release.sh
272
+ # in root
273
+ scripts/pre-release.sh
274
274
  ```
275
275
 
276
- This script automates the following steps:
276
+ This script is a combination of two scripts:
277
277
 
278
278
  1. Pre-Release:
279
279
 
280
- - Updates local dependencies for ably-ui and runs a production build
281
- - Releases an NPM package with the version built from your current SemVer but adding a pre-release tag based on a short SHA of your HEAD commit
282
- - Waits for the package to be available on the NPM registry (handles propagation delay)
283
- - Automatically updates both `apps/website` and `apps/voltaire` with the new dev version
280
+ - update your local dependencies for ably-ui and run a production build
281
+ - release an NPM package with the version built from your current SemVer but adding a pre-release tag based on a short SHA of your HEAD commit
284
282
 
285
283
  2. Update Pre-Release Version:
286
284
 
287
- - Commits all changes (UI package.json, app package.json files, and lockfiles) in a single atomic commit
288
- - Pushes the commit and tag to origin
285
+ - commit all the above and push to origin
289
286
 
290
- This will trigger a build of the review app with the pre-release version installed in both consuming apps.
287
+ This will trigger a build of the review app.
291
288
 
292
289
  ### Components
293
290
 
@@ -342,13 +339,13 @@ We use [Semantic Versioning 2.0.0](https://semver.org/) to version different lib
342
339
 
343
340
  Packages are published to the [GitHub private registry](https://github.com/features/packages).
344
341
 
345
- Publishing is done by tagging a release in GitHub. This triggers a GitHub action that pushes to the NPM registry as well as deploying Storybook to the [ably/ably-ui](https://github.com/ably/ably-ui) repository, with the version taken from the tag of the GitHub release.
342
+ Publishing is done by tagging a release in GitHub. This triggers a GitHub action that pushes to the private NPM registry as well as publishing new artefacts in the CDN, with the version taken from the tag of the GitHub release.
346
343
 
347
- After publishing, you can manually trigger the `update-ably-ui` workflow to create a single draft PR that updates both [Voltaire](http://github.com/ably/voltaire) and [Website](http://github.com/ably/website) with the new ably-ui version.
344
+ This will trigger GitHub actions in supported apps (currently [Voltaire](http://github.com/ably/voltaire) & [Website](http://github.com/ably/website)) to create a PR with an ably-ui version update.
348
345
 
349
346
  **To trigger a release:**
350
347
 
351
- - Make sure you have run the pre-release script `./scripts/pre-release.sh` (This updates the npm package version for ably-ui in `package.json` and updates both consuming apps).
348
+ - Make sure you have run pre-release script `./pre-release.sh` (This updates the npm package version for ably-ui in `package.json`).
352
349
  - Merge your PR into `main` after it has been approved.
353
350
  - On the Github [Ably-UI](http://github.com/ably/ably-ui) repo, [create a new release](https://github.com/ably/ably-ui/releases/new) tag.
354
351
  - Create a new tag with the new version number for the release.
@@ -357,10 +354,9 @@ After publishing, you can manually trigger the `update-ably-ui` workflow to crea
357
354
  - Click on the Autogenerate release notes button.
358
355
  - Publish Release.
359
356
  - Check the Github `Actions` tab in the repo to make sure the release is green.
360
- - Upon successful release, a compiled version of the Storybook site will be deployed to the [ably/ably-ui](https://github.com/ably/ably-ui) repository's gh-pages branch.
361
- - Manually trigger the `update-ably-ui` workflow from the Actions tab to create a draft PR updating both apps.
357
+ - Upon successful release, a compiled version of the Storybook site will be deployed to Github Pages.
362
358
 
363
- This will publish the package to NPM and deploy a new Storybook site to [https://ably.github.io/ably-ui/](https://ably.github.io/ably-ui/). To update the consuming apps, manually trigger the workflow, which will create a single draft PR for both Voltaire and Website that requires review before merging.
359
+ This will release the packages and update library and create & push the commit & tag, and also create corresponding PRs in Voltaire & Website. It will also deploy a new Storybook site to [https://ably.github.io/ably-ui/](https://ably.github.io/ably-ui/).
364
360
 
365
361
  ### Tagging Convention (Monorepo)
366
362
 
@@ -0,0 +1,2 @@
1
+ import React from"react";import{describe,expect,it,vi,afterEach}from"vitest";import{render,screen,within,cleanup}from"@testing-library/react";import CodeSnippet from"../CodeSnippet";afterEach(cleanup);vi.mock("../Code",()=>({default:({snippet,language})=>React.createElement("div",{"data-testid":"code-block","data-language":language},snippet)}));vi.mock("../Icon",()=>({default:({name})=>React.createElement("span",{"data-testid":"icon","data-icon":name})}));vi.mock("../SegmentedControl",()=>({default:({children,onClick,active})=>React.createElement("button",{"data-testid":"sdk-toggle","data-active":active,onClick:onClick},children)}));vi.mock("./LanguageSelector",()=>({default:({languages,activeLanguage,onLanguageChange})=>React.createElement("div",{"data-testid":"language-selector","data-active":activeLanguage},languages.map(lang=>React.createElement("button",{key:lang,"data-testid":`lang-${lang}`,onClick:()=>onLanguageChange(lang)},lang)))}));vi.mock("./CopyButton",()=>({default:()=>React.createElement("button",{"data-testid":"copy-button"},"Copy")}));vi.mock("./ApiKeySelector",()=>({default:()=>React.createElement("div",{"data-testid":"api-key-selector"})}));vi.mock("./PlainCodeView",()=>({default:({content,language})=>React.createElement("div",{"data-testid":"plain-code-view","data-language":language},content)}));const makeSnippet=(lang,content)=>React.createElement("pre",null,React.createElement("code",{className:`language-${lang}`},content));describe("CodeSnippet",()=>{describe("basic rendering",()=>{it("renders a single language snippet",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},makeSnippet("javascript","console.log('hello')")));expect(screen.getByTestId("code-block").textContent).toBe("console.log('hello')")});it("renders a language label for a single non-fixed language",()=>{const{container}=render(React.createElement(CodeSnippet,{lang:"javascript"},makeSnippet("javascript","const x = 1;")));const labelSpans=container.querySelectorAll(".ui-text-label4");const labels=Array.from(labelSpans).map(el=>el.textContent);expect(labels).toContain("JavaScript")});it("renders the language selector when multiple languages are available",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},makeSnippet("javascript","const x = 1;"),makeSnippet("python","x = 1")));expect(screen.getByTestId("language-selector")).toBeTruthy()})});describe("realtime/rest SDK types",()=>{it("shows SDK selector for realtime/rest prefixed languages",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime"},makeSnippet("realtime_javascript","// realtime code"),makeSnippet("rest_javascript","// rest code")));const toggles=screen.getAllByTestId("sdk-toggle");expect(toggles).toHaveLength(2);expect(toggles[0].textContent).toBe("Realtime");expect(toggles[1].textContent).toBe("REST")});it("shows single SDK label when only one SDK type present",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime"},makeSnippet("realtime_javascript","// realtime only")));const toggles=screen.getAllByTestId("sdk-toggle");expect(toggles[0].textContent).toBe("Realtime")});it("resolves to the correct SDK when only one type is available",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime"},makeSnippet("rest_javascript","// rest only")));expect(screen.getByTestId("code-block").textContent).toBe("// rest only")})});describe("client/agent SDK types",()=>{it("does not show SDK selector for client/agent prefixed languages",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"client",fixed:true},makeSnippet("client_javascript","// client code"),makeSnippet("agent_python","// agent code")));expect(screen.queryAllByTestId("sdk-toggle")).toHaveLength(0)});it("renders client_ prefixed snippet with fixed mode and sdk=client",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"client",fixed:true},makeSnippet("client_javascript","// client JS"),makeSnippet("agent_python","// agent python")));expect(screen.getByTestId("code-block").textContent).toBe("// client JS")});it("renders agent_ prefixed snippet with fixed mode and sdk=agent",()=>{render(React.createElement(CodeSnippet,{lang:"python",sdk:"agent",fixed:true},makeSnippet("client_javascript","// client JS"),makeSnippet("agent_python","// agent python")));expect(screen.getByTestId("code-block").textContent).toBe("// agent python")});it("falls back to first language with matching prefix when exact match not found",()=>{render(React.createElement(CodeSnippet,{lang:"ruby",sdk:"client",fixed:true},makeSnippet("client_javascript","// client JS"),makeSnippet("client_typescript","// client TS")));expect(screen.getByTestId("code-block").textContent).toBe("// client JS")})});describe("fixed mode",()=>{it("shows a read-only language label in fixed mode",()=>{const{container}=render(React.createElement(CodeSnippet,{lang:"javascript",fixed:true},makeSnippet("javascript","const x = 1;")));const labelSpans=container.querySelectorAll(".ui-text-label4");const labels=Array.from(labelSpans).map(el=>el.textContent);expect(labels).toContain("JavaScript");expect(screen.queryByTestId("language-selector")).toBeNull()});it("shows correct label for client_ prefixed language in fixed mode",()=>{const{container}=render(React.createElement(CodeSnippet,{lang:"python",sdk:"client",fixed:true},makeSnippet("client_python","# client python")));const labelSpans=container.querySelectorAll(".ui-text-label4");const labels=Array.from(labelSpans).map(el=>el.textContent);expect(labels).toContain("Python")});it("hides language selector in fixed mode even with multiple languages",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",fixed:true},makeSnippet("javascript","const x = 1;"),makeSnippet("python","x = 1")));expect(screen.queryByTestId("language-selector")).toBeNull()})});describe("header row",()=>{it("renders a header row when headerRow is true",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",headerRow:true,title:"My Code"},makeSnippet("javascript","const x = 1;")));expect(screen.getByText("My Code")).toBeTruthy()})});describe("plain command mode",()=>{it("renders shell commands in plain mode",()=>{render(React.createElement(CodeSnippet,{lang:"shell"},makeSnippet("shell","npm install")));expect(screen.getByTestId("plain-code-view").textContent).toBe("npm install")});it("renders text commands in plain mode",()=>{render(React.createElement(CodeSnippet,{lang:"text"},makeSnippet("text","Hello world")));expect(screen.getByTestId("plain-code-view").textContent).toBe("Hello world")})});describe("onChange callback",()=>{it("passes stripped language and sdk type on language change",()=>{const onChange=vi.fn();render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime",onChange:onChange},makeSnippet("realtime_javascript","// js code"),makeSnippet("realtime_python","# python code")));const pyButton=screen.getByTestId("lang-realtime_python");pyButton.click();expect(onChange).toHaveBeenCalledWith("python","realtime")});it("passes undefined sdk when no SDK type",()=>{const onChange=vi.fn();render(React.createElement(CodeSnippet,{lang:"javascript",onChange:onChange},makeSnippet("javascript","// js"),makeSnippet("python","# py")));const pyButton=screen.getByTestId("lang-python");pyButton.click();expect(onChange).toHaveBeenCalledWith("python",undefined)})});describe("missing language snippet",()=>{it("shows a message when active language has no snippet",()=>{render(React.createElement(CodeSnippet,{lang:"ruby"},makeSnippet("javascript","const x = 1;"),makeSnippet("python","x = 1")));expect(screen.getByText(/currently viewing the Ruby docs/)).toBeTruthy()})});describe("JSON-only snippets",()=>{it("always shows JSON content regardless of selected language",()=>{render(React.createElement(CodeSnippet,{lang:"ruby"},makeSnippet("json",'{"key": "value"}')));expect(screen.getByTestId("code-block").textContent).toBe('{"key": "value"}')})});describe("language ordering",()=>{it("respects custom language ordering",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",languageOrdering:["python","typescript","javascript"]},makeSnippet("javascript","// js"),makeSnippet("typescript","// ts"),makeSnippet("python","# py")));const selector=screen.getByTestId("language-selector");const buttons=within(selector).getAllByRole("button");expect(buttons[0].textContent).toBe("python");expect(buttons[1].textContent).toBe("typescript");expect(buttons[2].textContent).toBe("javascript")})})});
2
+ //# sourceMappingURL=CodeSnippet.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/CodeSnippet.test.tsx"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\n\nimport React from \"react\";\nimport { describe, expect, it, vi, afterEach } from \"vitest\";\nimport { render, screen, within, cleanup } from \"@testing-library/react\";\n\nimport CodeSnippet from \"../CodeSnippet\";\n\nafterEach(cleanup);\n\n// Mock child components to avoid complex rendering dependencies\nvi.mock(\"../Code\", () => ({\n default: ({ snippet, language }: { snippet: string; language: string }) => (\n <div data-testid=\"code-block\" data-language={language}>\n {snippet}\n </div>\n ),\n}));\n\nvi.mock(\"../Icon\", () => ({\n default: ({ name }: { name: string }) => (\n <span data-testid=\"icon\" data-icon={name} />\n ),\n}));\n\nvi.mock(\"../SegmentedControl\", () => ({\n default: ({\n children,\n onClick,\n active,\n }: {\n children: React.ReactNode;\n onClick: () => void;\n active: boolean;\n }) => (\n <button data-testid=\"sdk-toggle\" data-active={active} onClick={onClick}>\n {children}\n </button>\n ),\n}));\n\nvi.mock(\"./LanguageSelector\", () => ({\n default: ({\n languages,\n activeLanguage,\n onLanguageChange,\n }: {\n languages: string[];\n activeLanguage: string;\n onLanguageChange: (lang: string) => void;\n }) => (\n <div data-testid=\"language-selector\" data-active={activeLanguage}>\n {languages.map((lang) => (\n <button\n key={lang}\n data-testid={`lang-${lang}`}\n onClick={() => onLanguageChange(lang)}\n >\n {lang}\n </button>\n ))}\n </div>\n ),\n}));\n\nvi.mock(\"./CopyButton\", () => ({\n default: () => <button data-testid=\"copy-button\">Copy</button>,\n}));\n\nvi.mock(\"./ApiKeySelector\", () => ({\n default: () => <div data-testid=\"api-key-selector\" />,\n}));\n\nvi.mock(\"./PlainCodeView\", () => ({\n default: ({ content, language }: { content: string; language: string }) => (\n <div data-testid=\"plain-code-view\" data-language={language}>\n {content}\n </div>\n ),\n}));\n\nconst makeSnippet = (lang: string, content: string) => (\n <pre>\n <code className={`language-${lang}`}>{content}</code>\n </pre>\n);\n\ndescribe(\"CodeSnippet\", () => {\n describe(\"basic rendering\", () => {\n it(\"renders a single language snippet\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n {makeSnippet(\"javascript\", \"console.log('hello')\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n \"console.log('hello')\",\n );\n });\n\n it(\"renders a language label for a single non-fixed language\", () => {\n const { container } = render(\n <CodeSnippet lang=\"javascript\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n </CodeSnippet>,\n );\n const labelSpans = container.querySelectorAll(\".ui-text-label4\");\n const labels = Array.from(labelSpans).map((el) => el.textContent);\n expect(labels).toContain(\"JavaScript\");\n });\n\n it(\"renders the language selector when multiple languages are available\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n {makeSnippet(\"python\", \"x = 1\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"language-selector\")).toBeTruthy();\n });\n });\n\n describe(\"realtime/rest SDK types\", () => {\n it(\"shows SDK selector for realtime/rest prefixed languages\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\">\n {makeSnippet(\"realtime_javascript\", \"// realtime code\")}\n {makeSnippet(\"rest_javascript\", \"// rest code\")}\n </CodeSnippet>,\n );\n const toggles = screen.getAllByTestId(\"sdk-toggle\");\n expect(toggles).toHaveLength(2);\n expect(toggles[0].textContent).toBe(\"Realtime\");\n expect(toggles[1].textContent).toBe(\"REST\");\n });\n\n it(\"shows single SDK label when only one SDK type present\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\">\n {makeSnippet(\"realtime_javascript\", \"// realtime only\")}\n </CodeSnippet>,\n );\n const toggles = screen.getAllByTestId(\"sdk-toggle\");\n expect(toggles[0].textContent).toBe(\"Realtime\");\n });\n\n it(\"resolves to the correct SDK when only one type is available\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\">\n {makeSnippet(\"rest_javascript\", \"// rest only\")}\n </CodeSnippet>,\n );\n // Should fall back to rest since that's the only type available\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// rest only\");\n });\n });\n\n describe(\"client/agent SDK types\", () => {\n it(\"does not show SDK selector for client/agent prefixed languages\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"client\" fixed>\n {makeSnippet(\"client_javascript\", \"// client code\")}\n {makeSnippet(\"agent_python\", \"// agent code\")}\n </CodeSnippet>,\n );\n expect(screen.queryAllByTestId(\"sdk-toggle\")).toHaveLength(0);\n });\n\n it(\"renders client_ prefixed snippet with fixed mode and sdk=client\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"client\" fixed>\n {makeSnippet(\"client_javascript\", \"// client JS\")}\n {makeSnippet(\"agent_python\", \"// agent python\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// client JS\");\n });\n\n it(\"renders agent_ prefixed snippet with fixed mode and sdk=agent\", () => {\n render(\n <CodeSnippet lang=\"python\" sdk=\"agent\" fixed>\n {makeSnippet(\"client_javascript\", \"// client JS\")}\n {makeSnippet(\"agent_python\", \"// agent python\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n \"// agent python\",\n );\n });\n\n it(\"falls back to first language with matching prefix when exact match not found\", () => {\n render(\n <CodeSnippet lang=\"ruby\" sdk=\"client\" fixed>\n {makeSnippet(\"client_javascript\", \"// client JS\")}\n {makeSnippet(\"client_typescript\", \"// client TS\")}\n </CodeSnippet>,\n );\n // Ruby doesn't exist with client_ prefix, should fall back to first client_ language\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// client JS\");\n });\n });\n\n describe(\"fixed mode\", () => {\n it(\"shows a read-only language label in fixed mode\", () => {\n const { container } = render(\n <CodeSnippet lang=\"javascript\" fixed>\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n </CodeSnippet>,\n );\n const labelSpans = container.querySelectorAll(\".ui-text-label4\");\n const labels = Array.from(labelSpans).map((el) => el.textContent);\n expect(labels).toContain(\"JavaScript\");\n expect(screen.queryByTestId(\"language-selector\")).toBeNull();\n });\n\n it(\"shows correct label for client_ prefixed language in fixed mode\", () => {\n const { container } = render(\n <CodeSnippet lang=\"python\" sdk=\"client\" fixed>\n {makeSnippet(\"client_python\", \"# client python\")}\n </CodeSnippet>,\n );\n const labelSpans = container.querySelectorAll(\".ui-text-label4\");\n const labels = Array.from(labelSpans).map((el) => el.textContent);\n expect(labels).toContain(\"Python\");\n });\n\n it(\"hides language selector in fixed mode even with multiple languages\", () => {\n render(\n <CodeSnippet lang=\"javascript\" fixed>\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n {makeSnippet(\"python\", \"x = 1\")}\n </CodeSnippet>,\n );\n expect(screen.queryByTestId(\"language-selector\")).toBeNull();\n });\n });\n\n describe(\"header row\", () => {\n it(\"renders a header row when headerRow is true\", () => {\n render(\n <CodeSnippet lang=\"javascript\" headerRow title=\"My Code\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n </CodeSnippet>,\n );\n expect(screen.getByText(\"My Code\")).toBeTruthy();\n });\n });\n\n describe(\"plain command mode\", () => {\n it(\"renders shell commands in plain mode\", () => {\n render(\n <CodeSnippet lang=\"shell\">\n {makeSnippet(\"shell\", \"npm install\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"plain-code-view\").textContent).toBe(\n \"npm install\",\n );\n });\n\n it(\"renders text commands in plain mode\", () => {\n render(\n <CodeSnippet lang=\"text\">\n {makeSnippet(\"text\", \"Hello world\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"plain-code-view\").textContent).toBe(\n \"Hello world\",\n );\n });\n });\n\n describe(\"onChange callback\", () => {\n it(\"passes stripped language and sdk type on language change\", () => {\n const onChange = vi.fn();\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\" onChange={onChange}>\n {makeSnippet(\"realtime_javascript\", \"// js code\")}\n {makeSnippet(\"realtime_python\", \"# python code\")}\n </CodeSnippet>,\n );\n const pyButton = screen.getByTestId(\"lang-realtime_python\");\n pyButton.click();\n expect(onChange).toHaveBeenCalledWith(\"python\", \"realtime\");\n });\n\n it(\"passes undefined sdk when no SDK type\", () => {\n const onChange = vi.fn();\n render(\n <CodeSnippet lang=\"javascript\" onChange={onChange}>\n {makeSnippet(\"javascript\", \"// js\")}\n {makeSnippet(\"python\", \"# py\")}\n </CodeSnippet>,\n );\n const pyButton = screen.getByTestId(\"lang-python\");\n pyButton.click();\n expect(onChange).toHaveBeenCalledWith(\"python\", undefined);\n });\n });\n\n describe(\"missing language snippet\", () => {\n it(\"shows a message when active language has no snippet\", () => {\n render(\n <CodeSnippet lang=\"ruby\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n {makeSnippet(\"python\", \"x = 1\")}\n </CodeSnippet>,\n );\n expect(screen.getByText(/currently viewing the Ruby docs/)).toBeTruthy();\n });\n });\n\n describe(\"JSON-only snippets\", () => {\n it(\"always shows JSON content regardless of selected language\", () => {\n render(\n <CodeSnippet lang=\"ruby\">\n {makeSnippet(\"json\", '{\"key\": \"value\"}')}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n '{\"key\": \"value\"}',\n );\n });\n });\n\n describe(\"language ordering\", () => {\n it(\"respects custom language ordering\", () => {\n render(\n <CodeSnippet\n lang=\"javascript\"\n languageOrdering={[\"python\", \"typescript\", \"javascript\"]}\n >\n {makeSnippet(\"javascript\", \"// js\")}\n {makeSnippet(\"typescript\", \"// ts\")}\n {makeSnippet(\"python\", \"# py\")}\n </CodeSnippet>,\n );\n const selector = screen.getByTestId(\"language-selector\");\n const buttons = within(selector).getAllByRole(\"button\");\n expect(buttons[0].textContent).toBe(\"python\");\n expect(buttons[1].textContent).toBe(\"typescript\");\n expect(buttons[2].textContent).toBe(\"javascript\");\n });\n });\n});\n"],"names":["React","describe","expect","it","vi","afterEach","render","screen","within","cleanup","CodeSnippet","mock","default","snippet","language","div","data-testid","data-language","name","span","data-icon","children","onClick","active","button","data-active","languages","activeLanguage","onLanguageChange","map","lang","key","content","makeSnippet","pre","code","className","getByTestId","textContent","toBe","container","labelSpans","querySelectorAll","labels","Array","from","el","toContain","toBeTruthy","sdk","toggles","getAllByTestId","toHaveLength","fixed","queryAllByTestId","queryByTestId","toBeNull","headerRow","title","getByText","onChange","fn","pyButton","click","toHaveBeenCalledWith","undefined","languageOrdering","selector","buttons","getAllByRole"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const languages={javascript:{label:"JavaScript",icon:"icon-tech-javascript",syntaxHighlighterKey:"javascript"},typescript:{label:"TypeScript",icon:"icon-tech-typescript",syntaxHighlighterKey:"typescript"},java:{label:"Java",icon:"icon-tech-java",syntaxHighlighterKey:"java"},kotlin:{label:"Kotlin",icon:"icon-tech-kotlin",syntaxHighlighterKey:"kotlin"},python:{label:"Python",icon:"icon-tech-python",syntaxHighlighterKey:"python"},csharp:{label:"C#",icon:"icon-tech-csharp",syntaxHighlighterKey:"csharp"},go:{label:"Go",icon:"icon-tech-go",syntaxHighlighterKey:"go"},ruby:{label:"Ruby",icon:"icon-tech-ruby",syntaxHighlighterKey:"ruby"},php:{label:"PHP",icon:"icon-tech-php",syntaxHighlighterKey:"php"},nodejs:{label:"Node.js",icon:"icon-tech-nodejs",syntaxHighlighterKey:"javascript"},react:{label:"React",icon:"icon-tech-react",syntaxHighlighterKey:"javascript"},html:{label:"HTML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},shell:{label:"Shell",icon:"icon-tech-web",syntaxHighlighterKey:"bash"},json:{label:"JSON",icon:"icon-tech-json",syntaxHighlighterKey:"json"},laravel:{label:"Laravel",icon:"icon-tech-laravel-broadcast",syntaxHighlighterKey:"php"},xml:{label:"XML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},sql:{label:"SQL",icon:"icon-tech-postgres",syntaxHighlighterKey:"sql"},swift:{label:"Swift",icon:"icon-tech-swift",syntaxHighlighterKey:"swift"},cpp:{label:"C++",icon:"icon-tech-web",syntaxHighlighterKey:"cpp"},dart:{label:"Dart",icon:"icon-tech-web",syntaxHighlighterKey:"dart"},objc:{label:"Objective-C",icon:"icon-tech-objectivec",syntaxHighlighterKey:"objc"},android:{label:"Android",icon:"icon-tech-android-head",syntaxHighlighterKey:"java"},flutter:{label:"Flutter",icon:"icon-tech-flutter",syntaxHighlighterKey:"dart"},jetpack:{label:"Jetpack Compose",icon:"icon-tech-jetpack",syntaxHighlighterKey:"kotlin"}};export const stripSdkType=lang=>{if(lang.startsWith("realtime_")||lang.startsWith("rest_")){return lang.split("_").slice(1).join("_")}return lang};export const getLanguageInfo=langKey=>{const key=stripSdkType(langKey).toLowerCase();if(languages[key]){return languages[key]}return{label:langKey,icon:"icon-tech-web",syntaxHighlighterKey:langKey}};export default languages;
1
+ export const SDK_PREFIXES=["realtime","rest","client","agent"];const languages={javascript:{label:"JavaScript",icon:"icon-tech-javascript",syntaxHighlighterKey:"javascript"},typescript:{label:"TypeScript",icon:"icon-tech-typescript",syntaxHighlighterKey:"typescript"},java:{label:"Java",icon:"icon-tech-java",syntaxHighlighterKey:"java"},kotlin:{label:"Kotlin",icon:"icon-tech-kotlin",syntaxHighlighterKey:"kotlin"},python:{label:"Python",icon:"icon-tech-python",syntaxHighlighterKey:"python"},csharp:{label:"C#",icon:"icon-tech-csharp",syntaxHighlighterKey:"csharp"},go:{label:"Go",icon:"icon-tech-go",syntaxHighlighterKey:"go"},ruby:{label:"Ruby",icon:"icon-tech-ruby",syntaxHighlighterKey:"ruby"},php:{label:"PHP",icon:"icon-tech-php",syntaxHighlighterKey:"php"},nodejs:{label:"Node.js",icon:"icon-tech-nodejs",syntaxHighlighterKey:"javascript"},react:{label:"React",icon:"icon-tech-react",syntaxHighlighterKey:"javascript"},html:{label:"HTML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},shell:{label:"Shell",icon:"icon-tech-web",syntaxHighlighterKey:"bash"},json:{label:"JSON",icon:"icon-tech-json",syntaxHighlighterKey:"json"},laravel:{label:"Laravel",icon:"icon-tech-laravel-broadcast",syntaxHighlighterKey:"php"},xml:{label:"XML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},sql:{label:"SQL",icon:"icon-tech-postgres",syntaxHighlighterKey:"sql"},swift:{label:"Swift",icon:"icon-tech-swift",syntaxHighlighterKey:"swift"},cpp:{label:"C++",icon:"icon-tech-web",syntaxHighlighterKey:"cpp"},dart:{label:"Dart",icon:"icon-tech-web",syntaxHighlighterKey:"dart"},objc:{label:"Objective-C",icon:"icon-tech-objectivec",syntaxHighlighterKey:"objc"},android:{label:"Android",icon:"icon-tech-android-head",syntaxHighlighterKey:"java"},flutter:{label:"Flutter",icon:"icon-tech-flutter",syntaxHighlighterKey:"dart"},jetpack:{label:"Jetpack Compose",icon:"icon-tech-jetpack",syntaxHighlighterKey:"kotlin"}};export const stripSdkType=lang=>{for(const prefix of SDK_PREFIXES){const withUnderscore=`${prefix}_`;if(lang.startsWith(withUnderscore)){return lang.slice(withUnderscore.length)}}return lang};export const getLanguageInfo=langKey=>{const key=stripSdkType(langKey).toLowerCase();if(languages[key]){return languages[key]}return{label:langKey,icon:"icon-tech-web",syntaxHighlighterKey:langKey}};export default languages;
2
2
  //# sourceMappingURL=languages.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/languages.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport interface LanguageInfo {\n label: string;\n icon: IconName;\n syntaxHighlighterKey?: string;\n}\n\nexport type LanguageMap = Record<string, LanguageInfo>;\n\nconst languages: LanguageMap = {\n javascript: {\n label: \"JavaScript\",\n icon: \"icon-tech-javascript\",\n syntaxHighlighterKey: \"javascript\",\n },\n typescript: {\n label: \"TypeScript\",\n icon: \"icon-tech-typescript\",\n syntaxHighlighterKey: \"typescript\",\n },\n java: {\n label: \"Java\",\n icon: \"icon-tech-java\",\n syntaxHighlighterKey: \"java\",\n },\n kotlin: {\n label: \"Kotlin\",\n icon: \"icon-tech-kotlin\",\n syntaxHighlighterKey: \"kotlin\",\n },\n python: {\n label: \"Python\",\n icon: \"icon-tech-python\",\n syntaxHighlighterKey: \"python\",\n },\n csharp: {\n label: \"C#\",\n icon: \"icon-tech-csharp\",\n syntaxHighlighterKey: \"csharp\",\n },\n go: {\n label: \"Go\",\n icon: \"icon-tech-go\",\n syntaxHighlighterKey: \"go\",\n },\n ruby: {\n label: \"Ruby\",\n icon: \"icon-tech-ruby\",\n syntaxHighlighterKey: \"ruby\",\n },\n php: {\n label: \"PHP\",\n icon: \"icon-tech-php\",\n syntaxHighlighterKey: \"php\",\n },\n nodejs: {\n label: \"Node.js\",\n icon: \"icon-tech-nodejs\",\n syntaxHighlighterKey: \"javascript\",\n },\n react: {\n label: \"React\",\n icon: \"icon-tech-react\",\n syntaxHighlighterKey: \"javascript\",\n },\n html: {\n label: \"HTML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n shell: {\n label: \"Shell\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"bash\",\n },\n json: {\n label: \"JSON\",\n icon: \"icon-tech-json\",\n syntaxHighlighterKey: \"json\",\n },\n laravel: {\n label: \"Laravel\",\n icon: \"icon-tech-laravel-broadcast\",\n syntaxHighlighterKey: \"php\",\n },\n xml: {\n label: \"XML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n sql: {\n label: \"SQL\",\n icon: \"icon-tech-postgres\",\n syntaxHighlighterKey: \"sql\",\n },\n swift: {\n label: \"Swift\",\n icon: \"icon-tech-swift\",\n syntaxHighlighterKey: \"swift\",\n },\n // New entries from languageInfo.ts\n cpp: {\n label: \"C++\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"cpp\",\n },\n dart: {\n label: \"Dart\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"dart\",\n },\n objc: {\n label: \"Objective-C\",\n icon: \"icon-tech-objectivec\",\n syntaxHighlighterKey: \"objc\",\n },\n android: {\n label: \"Android\",\n icon: \"icon-tech-android-head\",\n syntaxHighlighterKey: \"java\",\n },\n flutter: {\n label: \"Flutter\",\n icon: \"icon-tech-flutter\",\n syntaxHighlighterKey: \"dart\",\n },\n jetpack: {\n label: \"Jetpack Compose\",\n icon: \"icon-tech-jetpack\",\n syntaxHighlighterKey: \"kotlin\",\n },\n};\n\nexport const stripSdkType = (lang: string) => {\n if (lang.startsWith(\"realtime_\") || lang.startsWith(\"rest_\")) {\n return lang.split(\"_\").slice(1).join(\"_\");\n }\n return lang;\n};\n\n// Fallback function to handle languages not in the map\nexport const getLanguageInfo = (langKey: string): LanguageInfo => {\n const key = stripSdkType(langKey).toLowerCase();\n\n if (languages[key]) {\n return languages[key];\n }\n\n // Fallback for unknown languages\n return {\n label: langKey,\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: langKey,\n };\n};\n\nexport default languages;\n"],"names":["languages","javascript","label","icon","syntaxHighlighterKey","typescript","java","kotlin","python","csharp","go","ruby","php","nodejs","react","html","shell","json","laravel","xml","sql","swift","cpp","dart","objc","android","flutter","jetpack","stripSdkType","lang","startsWith","split","slice","join","getLanguageInfo","langKey","key","toLowerCase"],"mappings":"AAUA,MAAMA,UAAyB,CAC7BC,WAAY,CACVC,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAC,WAAY,CACVH,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAE,KAAM,CACJJ,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAG,OAAQ,CACNL,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAI,OAAQ,CACNN,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAK,OAAQ,CACNP,MAAO,KACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAM,GAAI,CACFR,MAAO,KACPC,KAAM,eACNC,qBAAsB,IACxB,EACAO,KAAM,CACJT,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAQ,IAAK,CACHV,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAS,OAAQ,CACNX,MAAO,UACPC,KAAM,mBACNC,qBAAsB,YACxB,EACAU,MAAO,CACLZ,MAAO,QACPC,KAAM,kBACNC,qBAAsB,YACxB,EACAW,KAAM,CACJb,MAAO,OACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAY,MAAO,CACLd,MAAO,QACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAa,KAAM,CACJf,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAc,QAAS,CACPhB,MAAO,UACPC,KAAM,8BACNC,qBAAsB,KACxB,EACAe,IAAK,CACHjB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAgB,IAAK,CACHlB,MAAO,MACPC,KAAM,qBACNC,qBAAsB,KACxB,EACAiB,MAAO,CACLnB,MAAO,QACPC,KAAM,kBACNC,qBAAsB,OACxB,EAEAkB,IAAK,CACHpB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAmB,KAAM,CACJrB,MAAO,OACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAoB,KAAM,CACJtB,MAAO,cACPC,KAAM,uBACNC,qBAAsB,MACxB,EACAqB,QAAS,CACPvB,MAAO,UACPC,KAAM,yBACNC,qBAAsB,MACxB,EACAsB,QAAS,CACPxB,MAAO,UACPC,KAAM,oBACNC,qBAAsB,MACxB,EACAuB,QAAS,CACPzB,MAAO,kBACPC,KAAM,oBACNC,qBAAsB,QACxB,CACF,CAEA,QAAO,MAAMwB,aAAe,AAACC,OAC3B,GAAIA,KAAKC,UAAU,CAAC,cAAgBD,KAAKC,UAAU,CAAC,SAAU,CAC5D,OAAOD,KAAKE,KAAK,CAAC,KAAKC,KAAK,CAAC,GAAGC,IAAI,CAAC,IACvC,CACA,OAAOJ,IACT,CAAE,AAGF,QAAO,MAAMK,gBAAkB,AAACC,UAC9B,MAAMC,IAAMR,aAAaO,SAASE,WAAW,GAE7C,GAAIrC,SAAS,CAACoC,IAAI,CAAE,CAClB,OAAOpC,SAAS,CAACoC,IAAI,AACvB,CAGA,MAAO,CACLlC,MAAOiC,QACPhC,KAAM,gBACNC,qBAAsB+B,OACxB,CACF,CAAE,AAEF,gBAAenC,SAAU"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/languages.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport interface LanguageInfo {\n label: string;\n icon: IconName;\n syntaxHighlighterKey?: string;\n}\n\nexport type LanguageMap = Record<string, LanguageInfo>;\n\nexport const SDK_PREFIXES = [\"realtime\", \"rest\", \"client\", \"agent\"] as const;\nexport type SDKType = (typeof SDK_PREFIXES)[number];\n\nconst languages: LanguageMap = {\n javascript: {\n label: \"JavaScript\",\n icon: \"icon-tech-javascript\",\n syntaxHighlighterKey: \"javascript\",\n },\n typescript: {\n label: \"TypeScript\",\n icon: \"icon-tech-typescript\",\n syntaxHighlighterKey: \"typescript\",\n },\n java: {\n label: \"Java\",\n icon: \"icon-tech-java\",\n syntaxHighlighterKey: \"java\",\n },\n kotlin: {\n label: \"Kotlin\",\n icon: \"icon-tech-kotlin\",\n syntaxHighlighterKey: \"kotlin\",\n },\n python: {\n label: \"Python\",\n icon: \"icon-tech-python\",\n syntaxHighlighterKey: \"python\",\n },\n csharp: {\n label: \"C#\",\n icon: \"icon-tech-csharp\",\n syntaxHighlighterKey: \"csharp\",\n },\n go: {\n label: \"Go\",\n icon: \"icon-tech-go\",\n syntaxHighlighterKey: \"go\",\n },\n ruby: {\n label: \"Ruby\",\n icon: \"icon-tech-ruby\",\n syntaxHighlighterKey: \"ruby\",\n },\n php: {\n label: \"PHP\",\n icon: \"icon-tech-php\",\n syntaxHighlighterKey: \"php\",\n },\n nodejs: {\n label: \"Node.js\",\n icon: \"icon-tech-nodejs\",\n syntaxHighlighterKey: \"javascript\",\n },\n react: {\n label: \"React\",\n icon: \"icon-tech-react\",\n syntaxHighlighterKey: \"javascript\",\n },\n html: {\n label: \"HTML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n shell: {\n label: \"Shell\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"bash\",\n },\n json: {\n label: \"JSON\",\n icon: \"icon-tech-json\",\n syntaxHighlighterKey: \"json\",\n },\n laravel: {\n label: \"Laravel\",\n icon: \"icon-tech-laravel-broadcast\",\n syntaxHighlighterKey: \"php\",\n },\n xml: {\n label: \"XML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n sql: {\n label: \"SQL\",\n icon: \"icon-tech-postgres\",\n syntaxHighlighterKey: \"sql\",\n },\n swift: {\n label: \"Swift\",\n icon: \"icon-tech-swift\",\n syntaxHighlighterKey: \"swift\",\n },\n // New entries from languageInfo.ts\n cpp: {\n label: \"C++\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"cpp\",\n },\n dart: {\n label: \"Dart\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"dart\",\n },\n objc: {\n label: \"Objective-C\",\n icon: \"icon-tech-objectivec\",\n syntaxHighlighterKey: \"objc\",\n },\n android: {\n label: \"Android\",\n icon: \"icon-tech-android-head\",\n syntaxHighlighterKey: \"java\",\n },\n flutter: {\n label: \"Flutter\",\n icon: \"icon-tech-flutter\",\n syntaxHighlighterKey: \"dart\",\n },\n jetpack: {\n label: \"Jetpack Compose\",\n icon: \"icon-tech-jetpack\",\n syntaxHighlighterKey: \"kotlin\",\n },\n};\n\nexport const stripSdkType = (lang: string) => {\n for (const prefix of SDK_PREFIXES) {\n const withUnderscore = `${prefix}_`;\n if (lang.startsWith(withUnderscore)) {\n return lang.slice(withUnderscore.length);\n }\n }\n return lang;\n};\n\n// Fallback function to handle languages not in the map\nexport const getLanguageInfo = (langKey: string): LanguageInfo => {\n const key = stripSdkType(langKey).toLowerCase();\n\n if (languages[key]) {\n return languages[key];\n }\n\n // Fallback for unknown languages\n return {\n label: langKey,\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: langKey,\n };\n};\n\nexport default languages;\n"],"names":["SDK_PREFIXES","languages","javascript","label","icon","syntaxHighlighterKey","typescript","java","kotlin","python","csharp","go","ruby","php","nodejs","react","html","shell","json","laravel","xml","sql","swift","cpp","dart","objc","android","flutter","jetpack","stripSdkType","lang","prefix","withUnderscore","startsWith","slice","length","getLanguageInfo","langKey","key","toLowerCase"],"mappings":"AAUA,OAAO,MAAMA,aAAe,CAAC,WAAY,OAAQ,SAAU,QAAQ,AAAU,CAG7E,MAAMC,UAAyB,CAC7BC,WAAY,CACVC,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAC,WAAY,CACVH,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAE,KAAM,CACJJ,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAG,OAAQ,CACNL,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAI,OAAQ,CACNN,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAK,OAAQ,CACNP,MAAO,KACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAM,GAAI,CACFR,MAAO,KACPC,KAAM,eACNC,qBAAsB,IACxB,EACAO,KAAM,CACJT,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAQ,IAAK,CACHV,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAS,OAAQ,CACNX,MAAO,UACPC,KAAM,mBACNC,qBAAsB,YACxB,EACAU,MAAO,CACLZ,MAAO,QACPC,KAAM,kBACNC,qBAAsB,YACxB,EACAW,KAAM,CACJb,MAAO,OACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAY,MAAO,CACLd,MAAO,QACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAa,KAAM,CACJf,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAc,QAAS,CACPhB,MAAO,UACPC,KAAM,8BACNC,qBAAsB,KACxB,EACAe,IAAK,CACHjB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAgB,IAAK,CACHlB,MAAO,MACPC,KAAM,qBACNC,qBAAsB,KACxB,EACAiB,MAAO,CACLnB,MAAO,QACPC,KAAM,kBACNC,qBAAsB,OACxB,EAEAkB,IAAK,CACHpB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAmB,KAAM,CACJrB,MAAO,OACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAoB,KAAM,CACJtB,MAAO,cACPC,KAAM,uBACNC,qBAAsB,MACxB,EACAqB,QAAS,CACPvB,MAAO,UACPC,KAAM,yBACNC,qBAAsB,MACxB,EACAsB,QAAS,CACPxB,MAAO,UACPC,KAAM,oBACNC,qBAAsB,MACxB,EACAuB,QAAS,CACPzB,MAAO,kBACPC,KAAM,oBACNC,qBAAsB,QACxB,CACF,CAEA,QAAO,MAAMwB,aAAe,AAACC,OAC3B,IAAK,MAAMC,UAAU/B,aAAc,CACjC,MAAMgC,eAAiB,CAAC,EAAED,OAAO,CAAC,CAAC,CACnC,GAAID,KAAKG,UAAU,CAACD,gBAAiB,CACnC,OAAOF,KAAKI,KAAK,CAACF,eAAeG,MAAM,CACzC,CACF,CACA,OAAOL,IACT,CAAE,AAGF,QAAO,MAAMM,gBAAkB,AAACC,UAC9B,MAAMC,IAAMT,aAAaQ,SAASE,WAAW,GAE7C,GAAItC,SAAS,CAACqC,IAAI,CAAE,CAClB,OAAOrC,SAAS,CAACqC,IAAI,AACvB,CAGA,MAAO,CACLnC,MAAOkC,QACPjC,KAAM,gBACNC,qBAAsBgC,OACxB,CACF,CAAE,AAEF,gBAAepC,SAAU"}
@@ -0,0 +1,2 @@
1
+ import{describe,expect,it}from"vitest";import{stripSdkType,getLanguageInfo,SDK_PREFIXES}from"./languages";describe("SDK_PREFIXES",()=>{it("contains the expected SDK types",()=>{expect(SDK_PREFIXES).toEqual(["realtime","rest","client","agent"])});it("derives SDKType correctly",()=>{const types=[...SDK_PREFIXES];expect(types).toHaveLength(4)})});describe("stripSdkType",()=>{it("strips realtime_ prefix",()=>{expect(stripSdkType("realtime_javascript")).toBe("javascript")});it("strips rest_ prefix",()=>{expect(stripSdkType("rest_python")).toBe("python")});it("strips client_ prefix",()=>{expect(stripSdkType("client_javascript")).toBe("javascript")});it("strips agent_ prefix",()=>{expect(stripSdkType("agent_python")).toBe("python")});it("returns the language unchanged when no prefix",()=>{expect(stripSdkType("javascript")).toBe("javascript")});it("handles languages with underscores after the prefix",()=>{expect(stripSdkType("client_objective_c")).toBe("objective_c")});it("does not strip unknown prefixes",()=>{expect(stripSdkType("unknown_javascript")).toBe("unknown_javascript")});it("handles empty string",()=>{expect(stripSdkType("")).toBe("")});it("does not strip prefix without underscore",()=>{expect(stripSdkType("realtimejavascript")).toBe("realtimejavascript")})});describe("getLanguageInfo",()=>{it("returns info for known languages",()=>{const info=getLanguageInfo("javascript");expect(info.label).toBe("JavaScript");expect(info.icon).toBe("icon-tech-javascript");expect(info.syntaxHighlighterKey).toBe("javascript")});it("returns info for prefixed languages by stripping prefix first",()=>{const info=getLanguageInfo("realtime_javascript");expect(info.label).toBe("JavaScript");expect(info.icon).toBe("icon-tech-javascript")});it("returns info for client_ prefixed languages",()=>{const info=getLanguageInfo("client_python");expect(info.label).toBe("Python");expect(info.icon).toBe("icon-tech-python")});it("returns info for agent_ prefixed languages",()=>{const info=getLanguageInfo("agent_nodejs");expect(info.label).toBe("Node.js");expect(info.icon).toBe("icon-tech-nodejs")});it("handles case-insensitive lookup",()=>{const info=getLanguageInfo("JavaScript");expect(info.label).toBe("JavaScript")});it("returns fallback for unknown languages",()=>{const info=getLanguageInfo("brainfuck");expect(info.label).toBe("brainfuck");expect(info.icon).toBe("icon-tech-web");expect(info.syntaxHighlighterKey).toBe("brainfuck")});it("returns correct info for new language entries",()=>{expect(getLanguageInfo("cpp").label).toBe("C++");expect(getLanguageInfo("dart").label).toBe("Dart");expect(getLanguageInfo("objc").label).toBe("Objective-C");expect(getLanguageInfo("android").label).toBe("Android");expect(getLanguageInfo("flutter").label).toBe("Flutter");expect(getLanguageInfo("jetpack").label).toBe("Jetpack Compose")});it("maps languages to correct syntax highlighter keys",()=>{expect(getLanguageInfo("nodejs").syntaxHighlighterKey).toBe("javascript");expect(getLanguageInfo("react").syntaxHighlighterKey).toBe("javascript");expect(getLanguageInfo("flutter").syntaxHighlighterKey).toBe("dart");expect(getLanguageInfo("jetpack").syntaxHighlighterKey).toBe("kotlin");expect(getLanguageInfo("android").syntaxHighlighterKey).toBe("java");expect(getLanguageInfo("laravel").syntaxHighlighterKey).toBe("php")})});
2
+ //# sourceMappingURL=languages.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/languages.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport {\n stripSdkType,\n getLanguageInfo,\n SDK_PREFIXES,\n SDKType,\n} from \"./languages\";\n\ndescribe(\"SDK_PREFIXES\", () => {\n it(\"contains the expected SDK types\", () => {\n expect(SDK_PREFIXES).toEqual([\"realtime\", \"rest\", \"client\", \"agent\"]);\n });\n\n it(\"derives SDKType correctly\", () => {\n // Verify the type system works by assigning each prefix\n const types: SDKType[] = [...SDK_PREFIXES];\n expect(types).toHaveLength(4);\n });\n});\n\ndescribe(\"stripSdkType\", () => {\n it(\"strips realtime_ prefix\", () => {\n expect(stripSdkType(\"realtime_javascript\")).toBe(\"javascript\");\n });\n\n it(\"strips rest_ prefix\", () => {\n expect(stripSdkType(\"rest_python\")).toBe(\"python\");\n });\n\n it(\"strips client_ prefix\", () => {\n expect(stripSdkType(\"client_javascript\")).toBe(\"javascript\");\n });\n\n it(\"strips agent_ prefix\", () => {\n expect(stripSdkType(\"agent_python\")).toBe(\"python\");\n });\n\n it(\"returns the language unchanged when no prefix\", () => {\n expect(stripSdkType(\"javascript\")).toBe(\"javascript\");\n });\n\n it(\"handles languages with underscores after the prefix\", () => {\n expect(stripSdkType(\"client_objective_c\")).toBe(\"objective_c\");\n });\n\n it(\"does not strip unknown prefixes\", () => {\n expect(stripSdkType(\"unknown_javascript\")).toBe(\"unknown_javascript\");\n });\n\n it(\"handles empty string\", () => {\n expect(stripSdkType(\"\")).toBe(\"\");\n });\n\n it(\"does not strip prefix without underscore\", () => {\n expect(stripSdkType(\"realtimejavascript\")).toBe(\"realtimejavascript\");\n });\n});\n\ndescribe(\"getLanguageInfo\", () => {\n it(\"returns info for known languages\", () => {\n const info = getLanguageInfo(\"javascript\");\n expect(info.label).toBe(\"JavaScript\");\n expect(info.icon).toBe(\"icon-tech-javascript\");\n expect(info.syntaxHighlighterKey).toBe(\"javascript\");\n });\n\n it(\"returns info for prefixed languages by stripping prefix first\", () => {\n const info = getLanguageInfo(\"realtime_javascript\");\n expect(info.label).toBe(\"JavaScript\");\n expect(info.icon).toBe(\"icon-tech-javascript\");\n });\n\n it(\"returns info for client_ prefixed languages\", () => {\n const info = getLanguageInfo(\"client_python\");\n expect(info.label).toBe(\"Python\");\n expect(info.icon).toBe(\"icon-tech-python\");\n });\n\n it(\"returns info for agent_ prefixed languages\", () => {\n const info = getLanguageInfo(\"agent_nodejs\");\n expect(info.label).toBe(\"Node.js\");\n expect(info.icon).toBe(\"icon-tech-nodejs\");\n });\n\n it(\"handles case-insensitive lookup\", () => {\n const info = getLanguageInfo(\"JavaScript\");\n expect(info.label).toBe(\"JavaScript\");\n });\n\n it(\"returns fallback for unknown languages\", () => {\n const info = getLanguageInfo(\"brainfuck\");\n expect(info.label).toBe(\"brainfuck\");\n expect(info.icon).toBe(\"icon-tech-web\");\n expect(info.syntaxHighlighterKey).toBe(\"brainfuck\");\n });\n\n it(\"returns correct info for new language entries\", () => {\n expect(getLanguageInfo(\"cpp\").label).toBe(\"C++\");\n expect(getLanguageInfo(\"dart\").label).toBe(\"Dart\");\n expect(getLanguageInfo(\"objc\").label).toBe(\"Objective-C\");\n expect(getLanguageInfo(\"android\").label).toBe(\"Android\");\n expect(getLanguageInfo(\"flutter\").label).toBe(\"Flutter\");\n expect(getLanguageInfo(\"jetpack\").label).toBe(\"Jetpack Compose\");\n });\n\n it(\"maps languages to correct syntax highlighter keys\", () => {\n expect(getLanguageInfo(\"nodejs\").syntaxHighlighterKey).toBe(\"javascript\");\n expect(getLanguageInfo(\"react\").syntaxHighlighterKey).toBe(\"javascript\");\n expect(getLanguageInfo(\"flutter\").syntaxHighlighterKey).toBe(\"dart\");\n expect(getLanguageInfo(\"jetpack\").syntaxHighlighterKey).toBe(\"kotlin\");\n expect(getLanguageInfo(\"android\").syntaxHighlighterKey).toBe(\"java\");\n expect(getLanguageInfo(\"laravel\").syntaxHighlighterKey).toBe(\"php\");\n });\n});\n"],"names":["describe","expect","it","stripSdkType","getLanguageInfo","SDK_PREFIXES","toEqual","types","toHaveLength","toBe","info","label","icon","syntaxHighlighterKey"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import React,{useState,useEffect,Children,isValidElement,useRef,useCallback,useMemo}from"react";import Code from"./Code";import cn from"./utils/cn";import Icon from"./Icon";import{getLanguageInfo,stripSdkType}from"./CodeSnippet/languages";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import PlainCodeView from"./CodeSnippet/PlainCodeView";import CopyButton from"./CodeSnippet/CopyButton";import SegmentedControl from"./SegmentedControl";const substituteApiKey=(content,apiKey,mask=true)=>{return content.replace(/\{\{API_KEY\}\}/g,mask?`${apiKey.split(":")[0]}:*****`:apiKey)};const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk,showCodeLines=true,languageOrdering,wrapCode=false})=>{const codeRef=useRef(null);const[selectedApiKey,setSelectedApiKey]=useState(()=>apiKeys?.[0]?.keys?.[0]?.key??"");useEffect(()=>{if(!selectedApiKey&&apiKeys&&apiKeys.length>0){setSelectedApiKey(apiKeys[0].keys?.[0]?.key)}},[apiKeys]);useEffect(()=>{const element=codeRef.current;if(!element)return;const unmaskRenderedApiKey=(content,apiKey)=>{return content.replace(/(['"]?)([^:'"]+):\*{5}\1/g,`$1${apiKey}$1`)};const handleCopy=event=>{const selection=window.getSelection();if(!selection||selection.rangeCount===0)return;const selectedText=selection.toString();if(!selectedText)return;const range=selection.getRangeAt(0);if(!element.contains(range.commonAncestorContainer))return;const modifiedText=unmaskRenderedApiKey(selectedText,selectedApiKey);event.clipboardData?.setData("text/plain",modifiedText);event.preventDefault()};document.addEventListener("copy",handleCopy);return()=>{document.removeEventListener("copy",handleCopy)}},[selectedApiKey]);const extractLanguageFromCode=useCallback(codeElement=>{if(!codeElement||!codeElement.props.className)return null;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return null;return langClass.substring(9)},[]);const{codeData,languages,sdkTypes,isSinglePlainCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const codeData=[];const isSinglePlainCommand=childrenArray.length===1&&["language-shell","language-text"].some(lang=>isValidElement(childrenArray[0])&&isValidElement(childrenArray[0].props.children)&&childrenArray[0].props.children.props.className?.includes(lang));childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement)return;const codeLanguage=extractLanguageFromCode(codeElement);if(!codeLanguage)return;if(codeLanguage.startsWith("realtime_")){sdkTypes.add("realtime")}else if(codeLanguage.startsWith("rest_")){sdkTypes.add("rest")}if(!languages.includes(codeLanguage)){languages.push(codeLanguage)}const codeContent=codeElement.props.children;codeData.push({language:codeLanguage,content:codeContent})});return{codeData,languages,sdkTypes,isSinglePlainCommand}},[children,extractLanguageFromCode]);const resolvedSdk=useMemo(()=>{if(sdkTypes.size===1&&sdk&&!sdkTypes.has(sdk)){return Array.from(sdkTypes)[0]}return sdk??null},[sdk,sdkTypes]);const showSDKSelector=sdkTypes.size>0;const filteredLanguages=useMemo(()=>{const filtered=!resolvedSdk||!showSDKSelector?[...languages]:languages.filter(lang=>lang.startsWith(`${resolvedSdk}_`));if(languageOrdering&&languageOrdering.length>0){filtered.sort((a,b)=>{const aBase=stripSdkType(a);const bBase=stripSdkType(b);const aIndex=languageOrdering.indexOf(aBase);const bIndex=languageOrdering.indexOf(bBase);if(aIndex!==-1&&bIndex!==-1)return aIndex-bIndex;if(aIndex!==-1)return-1;if(bIndex!==-1)return 1;return 0})}return filtered},[resolvedSdk,showSDKSelector,languages,languageOrdering]);const activeLanguage=useMemo(()=>{if(resolvedSdk&&sdkTypes.has(resolvedSdk)){return`${resolvedSdk}_${lang}`}if(lang)return lang;if(filteredLanguages.length>0)return filteredLanguages[0];return languages[0]},[resolvedSdk,sdkTypes,lang,filteredLanguages,languages]);const requiresApiKeySubstitution=useMemo(()=>{const containsPlaceholder=codeData.some(code=>code?.content.includes("{{API_KEY}}"));return containsPlaceholder&&!!apiKeys&&apiKeys.length>0&&!!selectedApiKey},[codeData,apiKeys,selectedApiKey]);const[isHovering,setIsHovering]=useState(false);const hasOnlyJsonSnippet=useMemo(()=>languages.length===1&&languages[0]==="json",[languages]);const processedChildren=useMemo(()=>{if(!activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":activeLanguage;return codeData.filter(code=>{return code?.language===targetLanguage}).map(code=>{if(!code)return null;const cleanLang=hasOnlyJsonSnippet?"json":code.language;const langInfo=getLanguageInfo(cleanLang??"");if(typeof code.content==="string"||typeof code.content==="number"||typeof code.content==="boolean"){let processedContent=String(code.content);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}if(!langInfo.syntaxHighlighterKey||!cleanLang)return null;return React.createElement(Code,{key:code.language,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:processedContent,additionalCSS:"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4",showLines:showCodeLines,wrap:wrapCode})}return null})},[activeLanguage,hasOnlyJsonSnippet,codeData,requiresApiKeySubstitution,showCodeLines,wrapCode,selectedApiKey]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return codeData.some(code=>{return code?.language===activeLanguage})},[activeLanguage,hasOnlyJsonSnippet,codeData]);const handleSDKTypeChange=useCallback(type=>{const nextLang=stripSdkType(languages.find(l=>l===`${type}_${stripSdkType(activeLanguage)}`)??languages.find(l=>l.startsWith(`${type}_`))??activeLanguage);if(onChange&&nextLang){onChange(stripSdkType(activeLanguage),type)}},[activeLanguage,languages,onChange]);const handleLanguageChange=useCallback(language=>{if(onChange){onChange(stripSdkType(language),resolvedSdk)}},[onChange,resolvedSdk]);const noSnippetMessage=useMemo(()=>{if(!activeLanguage)return null;const activeLanguageInfo=getLanguageInfo(activeLanguage);return React.createElement("div",{className:"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center"},React.createElement(Icon,{name:"icon-gui-exclamation-triangle-outline",color:"text-yellow-600 dark:text-yellow-400",size:"24px"}),React.createElement("p",{className:"ui-text-p3 text-neutral-700 dark:text-neutral-600"},"You're currently viewing the ",activeLanguageInfo.label," docs. There either isn't a ",activeLanguageInfo.label," code sample for this example, or this feature isn't supported in"," ",activeLanguageInfo.label,". Switch language to view this example in a different language, or check which SDKs support this feature."))},[activeLanguage]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const renderContent=useMemo(()=>{if(!activeLanguage)return null;if(hasSnippetForActiveLanguage){return processedChildren}return noSnippetMessage},[activeLanguage,hasSnippetForActiveLanguage,processedChildren,noSnippetMessage]);if(isSinglePlainCommand){const plainChild=codeData[0];if(plainChild){const codeContent=plainChild.content;const language=plainChild.language;if(!language||!codeContent)return null;let processedContent=String(codeContent);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(PlainCodeView,{content:processedContent,className:className,language:language,icon:language==="shell"?"icon-gui-command-line-outline":null})}}return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]",className)},headerRow&&React.createElement("div",{className:"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg"},React.createElement("div",{className:"flex space-x-1.5"},React.createElement("div",{className:"w-3 h-3 rounded-full bg-orange-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-green-500"})),React.createElement("div",{className:"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000"},title),React.createElement("div",{className:"w-12"})),showSDKSelector&&React.createElement("div",{className:cn("p-2 border-b border-neutral-300 dark:border-neutral-1000",sdkTypes.size===1&&"p-1",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-1 justify-start"},["realtime","rest"].map(type=>sdkTypes.has(type)&&React.createElement(SegmentedControl,{key:type,onClick:()=>handleSDKTypeChange(type),size:"xs",active:resolvedSdk===type,className:cn("text-[11px] font-semibold px-2 py-1 h-auto",sdkTypes.size===1&&"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500",sdkTypes.size>1&&resolvedSdk!==type&&"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900",sdkTypes.size>1&&resolvedSdk===type&&"bg-neutral-000 dark:bg-neutral-1100")},type==="realtime"?"Realtime":"REST")))),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:activeLanguage,onLanguageChange:handleLanguageChange}):React.createElement("div",{className:cn("border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full",{"rounded-t-lg":!headerRow})},filteredLanguages.length>0&&React.createElement("div",{className:cn("inline-flex items-center",{"cursor-pointer":filteredLanguages.length>0}),...filteredLanguages.length>0&&{onClick:()=>handleLanguageChange(filteredLanguages[0])}},React.createElement(Icon,{name:getLanguageInfo(filteredLanguages[0]).icon,size:"16px",additionalCSS:"mr-2"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none"},getLanguageInfo(filteredLanguages[0]).label)))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false)},renderContent,isHovering&&activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=codeData.find(code=>code.language===activeLanguage)?.content;if(text)navigator.clipboard.writeText(substituteApiKey(text,selectedApiKey,false))}})),requiresApiKeySubstitution&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:selectedApiKey,onApiKeyChange:setSelectedApiKey}))};export default CodeSnippet;
1
+ import React,{useState,useEffect,Children,isValidElement,useRef,useCallback,useMemo}from"react";import Code from"./Code";import cn from"./utils/cn";import Icon from"./Icon";import{getLanguageInfo,stripSdkType,SDK_PREFIXES}from"./CodeSnippet/languages";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import PlainCodeView from"./CodeSnippet/PlainCodeView";import CopyButton from"./CodeSnippet/CopyButton";import SegmentedControl from"./SegmentedControl";const substituteApiKey=(content,apiKey,mask=true)=>{return content.replace(/\{\{API_KEY\}\}/g,mask?`${apiKey.split(":")[0]}:*****`:apiKey)};const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk,showCodeLines=true,languageOrdering,wrapCode=false})=>{const codeRef=useRef(null);const[selectedApiKey,setSelectedApiKey]=useState(()=>apiKeys?.[0]?.keys?.[0]?.key??"");useEffect(()=>{if(!selectedApiKey&&apiKeys&&apiKeys.length>0){setSelectedApiKey(apiKeys[0].keys?.[0]?.key)}},[apiKeys]);useEffect(()=>{const element=codeRef.current;if(!element)return;const unmaskRenderedApiKey=(content,apiKey)=>{return content.replace(/(['"]?)([^:'"]+):\*{5}\1/g,`$1${apiKey}$1`)};const handleCopy=event=>{const selection=window.getSelection();if(!selection||selection.rangeCount===0)return;const selectedText=selection.toString();if(!selectedText)return;const range=selection.getRangeAt(0);if(!element.contains(range.commonAncestorContainer))return;const modifiedText=unmaskRenderedApiKey(selectedText,selectedApiKey);event.clipboardData?.setData("text/plain",modifiedText);event.preventDefault()};document.addEventListener("copy",handleCopy);return()=>{document.removeEventListener("copy",handleCopy)}},[selectedApiKey]);const extractLanguageFromCode=useCallback(codeElement=>{if(!codeElement||!codeElement.props.className)return null;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return null;return langClass.substring(9)},[]);const findCodeElement=useCallback(preChildren=>{if(isValidElement(preChildren)){return preChildren}if(Array.isArray(preChildren)){const codeEl=preChildren.find(c=>isValidElement(c));return codeEl&&isValidElement(codeEl)?codeEl:null}return null},[]);const{codeData,languages,sdkTypes,isSinglePlainCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const codeData=[];const isSinglePlainCommand=childrenArray.length===1&&["language-shell","language-text"].some(lang=>{if(!isValidElement(childrenArray[0]))return false;const codeEl=findCodeElement(childrenArray[0].props.children);return codeEl?.props.className?.includes(lang)});childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=findCodeElement(preElement.props.children);if(!codeElement)return;const codeLanguage=extractLanguageFromCode(codeElement);if(!codeLanguage)return;for(const prefix of SDK_PREFIXES){if(codeLanguage.startsWith(`${prefix}_`)){sdkTypes.add(prefix);break}}if(!languages.includes(codeLanguage)){languages.push(codeLanguage)}const codeContent=codeElement.props.children;codeData.push({language:codeLanguage,content:codeContent})});return{codeData,languages,sdkTypes,isSinglePlainCommand}},[children,extractLanguageFromCode,findCodeElement]);const resolvedSdk=useMemo(()=>{if(sdkTypes.size===1&&sdk&&!sdkTypes.has(sdk)){return Array.from(sdkTypes)[0]}return sdk},[sdk,sdkTypes]);const showSDKSelector=sdkTypes.has("realtime")||sdkTypes.has("rest");const filteredLanguages=useMemo(()=>{const filtered=!resolvedSdk||!showSDKSelector?[...languages]:languages.filter(lang=>lang.startsWith(`${resolvedSdk}_`));if(languageOrdering&&languageOrdering.length>0){filtered.sort((a,b)=>{const aBase=stripSdkType(a);const bBase=stripSdkType(b);const aIndex=languageOrdering.indexOf(aBase);const bIndex=languageOrdering.indexOf(bBase);if(aIndex!==-1&&bIndex!==-1)return aIndex-bIndex;if(aIndex!==-1)return-1;if(bIndex!==-1)return 1;return 0})}return filtered},[resolvedSdk,showSDKSelector,languages,languageOrdering]);const activeLanguage=useMemo(()=>{if(resolvedSdk==="client"||resolvedSdk==="agent"){const fullLang=`${resolvedSdk}_${lang}`;if(languages.includes(fullLang)){return fullLang}const prefixMatch=languages.find(l=>l.startsWith(`${resolvedSdk}_`));if(prefixMatch)return prefixMatch}if(resolvedSdk&&sdkTypes.has(resolvedSdk)){return`${resolvedSdk}_${lang}`}if(lang)return lang;if(filteredLanguages.length>0)return filteredLanguages[0];return languages[0]},[resolvedSdk,sdkTypes,lang,filteredLanguages,languages]);const requiresApiKeySubstitution=useMemo(()=>{const containsPlaceholder=codeData.some(code=>code?.content.includes("{{API_KEY}}"));return containsPlaceholder&&!!apiKeys&&apiKeys.length>0&&!!selectedApiKey},[codeData,apiKeys,selectedApiKey]);const[isHovering,setIsHovering]=useState(false);const hasOnlyJsonSnippet=useMemo(()=>languages.length===1&&languages[0]==="json",[languages]);const processedChildren=useMemo(()=>{if(!activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":activeLanguage;return codeData.filter(code=>{return code?.language===targetLanguage}).map(code=>{if(!code)return null;const cleanLang=hasOnlyJsonSnippet?"json":code.language;const langInfo=getLanguageInfo(cleanLang??"");if(typeof code.content==="string"||typeof code.content==="number"||typeof code.content==="boolean"){let processedContent=String(code.content);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}if(!langInfo.syntaxHighlighterKey||!cleanLang)return null;return React.createElement(Code,{key:code.language,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:processedContent,additionalCSS:"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4",showLines:showCodeLines,wrap:wrapCode})}return null})},[activeLanguage,hasOnlyJsonSnippet,codeData,requiresApiKeySubstitution,showCodeLines,wrapCode,selectedApiKey]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return codeData.some(code=>{return code?.language===activeLanguage})},[activeLanguage,hasOnlyJsonSnippet,codeData]);const handleSDKTypeChange=useCallback(type=>{const nextLang=stripSdkType(languages.find(l=>l===`${type}_${stripSdkType(activeLanguage)}`)??languages.find(l=>l.startsWith(`${type}_`))??activeLanguage);if(onChange&&nextLang){onChange(stripSdkType(activeLanguage),type)}},[activeLanguage,languages,onChange]);const handleLanguageChange=useCallback(language=>{if(onChange){onChange(stripSdkType(language),resolvedSdk)}},[onChange,resolvedSdk]);const noSnippetMessage=useMemo(()=>{if(!activeLanguage)return null;const activeLanguageInfo=getLanguageInfo(activeLanguage);return React.createElement("div",{className:"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center"},React.createElement(Icon,{name:"icon-gui-exclamation-triangle-outline",color:"text-yellow-600 dark:text-yellow-400",size:"24px"}),React.createElement("p",{className:"ui-text-p3 text-neutral-700 dark:text-neutral-600"},"You're currently viewing the ",activeLanguageInfo.label," docs. There either isn't a ",activeLanguageInfo.label," code sample for this example, or this feature isn't supported in"," ",activeLanguageInfo.label,". Switch language to view this example in a different language, or check which SDKs support this feature."))},[activeLanguage]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const showFixedLanguageLabel=fixed&&activeLanguage;const renderLanguageLabel=(langKey,onClick)=>React.createElement("div",{className:cn("border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full",{"rounded-t-lg":!headerRow})},React.createElement("div",{className:cn("inline-flex items-center",onClick&&"cursor-pointer"),...onClick&&{onClick}},React.createElement(Icon,{name:getLanguageInfo(langKey).icon,size:"16px",additionalCSS:"mr-2"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none"},getLanguageInfo(langKey).label)));const renderContent=useMemo(()=>{if(!activeLanguage)return null;if(hasSnippetForActiveLanguage){return processedChildren}return noSnippetMessage},[activeLanguage,hasSnippetForActiveLanguage,processedChildren,noSnippetMessage]);if(isSinglePlainCommand){const plainChild=codeData[0];if(plainChild){const codeContent=plainChild.content;const language=plainChild.language;if(!language||!codeContent)return null;let processedContent=String(codeContent);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(PlainCodeView,{content:processedContent,className:className,language:language,icon:language==="shell"?"icon-gui-command-line-outline":null})}}return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]",className)},headerRow&&React.createElement("div",{className:"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg"},React.createElement("div",{className:"flex space-x-1.5"},React.createElement("div",{className:"w-3 h-3 rounded-full bg-orange-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-green-500"})),React.createElement("div",{className:"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000"},title),React.createElement("div",{className:"w-12"})),showSDKSelector&&React.createElement("div",{className:cn("p-2 border-b border-neutral-300 dark:border-neutral-1000",sdkTypes.size===1&&"p-1",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-1 justify-start"},["realtime","rest"].map(type=>sdkTypes.has(type)&&React.createElement(SegmentedControl,{key:type,onClick:()=>handleSDKTypeChange(type),size:"xs",active:resolvedSdk===type,className:cn("text-[11px] font-semibold px-2 py-1 h-auto",sdkTypes.size===1&&"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500",sdkTypes.size>1&&resolvedSdk!==type&&"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900",sdkTypes.size>1&&resolvedSdk===type&&"bg-neutral-000 dark:bg-neutral-1100")},type==="realtime"?"Realtime":"REST")))),showFixedLanguageLabel&&renderLanguageLabel(activeLanguage),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:activeLanguage,onLanguageChange:handleLanguageChange}):renderLanguageLabel(filteredLanguages[0],()=>handleLanguageChange(filteredLanguages[0]))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false)},renderContent,isHovering&&activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=codeData.find(code=>code.language===activeLanguage)?.content;if(text)navigator.clipboard.writeText(substituteApiKey(text,selectedApiKey,false))}})),requiresApiKeySubstitution&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:selectedApiKey,onApiKeyChange:setSelectedApiKey}))};export default CodeSnippet;
2
2
  //# sourceMappingURL=CodeSnippet.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/CodeSnippet.tsx"],"sourcesContent":["import React, {\n useState,\n useEffect,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport { getLanguageInfo, stripSdkType } from \"./CodeSnippet/languages\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport PlainCodeView from \"./CodeSnippet/PlainCodeView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport SegmentedControl from \"./SegmentedControl\";\n\n// Define SDK type\nexport type SDKType = \"realtime\" | \"rest\" | null;\n\n// Define API key types\nexport type ApiKeysItem = {\n app: string;\n keys: { name: string; key: string }[];\n};\n\nexport type CodeSnippetProps = {\n /**\n * If true, hides the language selector row completely\n */\n fixed?: boolean;\n /**\n * If true, renders a macOS-style window header with buttons and title\n */\n headerRow?: boolean;\n /**\n * Title to display in the header row (when headerRow is true)\n */\n title?: string;\n /**\n * Children elements with lang attribute\n */\n children: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Default language to display. If not found in available languages, first available is used.\n * If found in languages but no matching snippet exists, a message is displayed.\n */\n lang: string | null;\n /**\n * Callback fired when the active language changes\n */\n onChange?: (language: string, sdk?: SDKType) => void;\n /**\n * List of API keys to display in a dropdown\n */\n apiKeys?: ApiKeysItem[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\n /**\n * Whether to show line numbers in code snippets\n */\n showCodeLines?: boolean;\n /**\n * Defines the order in which languages should be displayed.\n * Languages not in this array will be shown after those that are included.\n */\n languageOrdering?: string[];\n /**\n * Whether to wrap code content instead of scrolling\n */\n wrapCode?: boolean;\n};\n\n// Substitution function for API key placeholders\nconst substituteApiKey = (\n content: string,\n apiKey: string,\n mask = true,\n): string => {\n return content.replace(\n /\\{\\{API_KEY\\}\\}/g,\n mask ? `${apiKey.split(\":\")[0]}:*****` : apiKey,\n );\n};\n\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n wrapCode = false,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n\n const [selectedApiKey, setSelectedApiKey] = useState<string>(\n () => apiKeys?.[0]?.keys?.[0]?.key ?? \"\",\n );\n\n useEffect(() => {\n if (!selectedApiKey && apiKeys && apiKeys.length > 0) {\n setSelectedApiKey(apiKeys[0].keys?.[0]?.key);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiKeys]);\n\n useEffect(() => {\n const element = codeRef.current;\n if (!element) return;\n\n // Detects the key masking via substituteApiKey (i.e. \"abcde:*****\") and replaces it with the actual API key\n const unmaskRenderedApiKey = (content: string, apiKey: string): string => {\n return content.replace(/(['\"]?)([^:'\"]+):\\*{5}\\1/g, `$1${apiKey}$1`);\n };\n\n const handleCopy = (event: ClipboardEvent) => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n\n const selectedText = selection.toString();\n if (!selectedText) return;\n\n // Check if the selection is within our element\n const range = selection.getRangeAt(0);\n if (!element.contains(range.commonAncestorContainer)) return;\n\n const modifiedText = unmaskRenderedApiKey(selectedText, selectedApiKey);\n\n event.clipboardData?.setData(\"text/plain\", modifiedText);\n event.preventDefault();\n };\n\n document.addEventListener(\"copy\", handleCopy);\n\n return () => {\n document.removeEventListener(\"copy\", handleCopy);\n };\n }, [selectedApiKey]);\n\n const extractLanguageFromCode = useCallback(\n (codeElement: React.ReactElement | null): string | null => {\n if (!codeElement || !codeElement.props.className) return null;\n\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return null;\n\n return langClass.substring(9); // Remove \"language-\" prefix\n },\n [],\n );\n\n const { codeData, languages, sdkTypes, isSinglePlainCommand } =\n useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const codeData: { language: string; content: string }[] = [];\n\n const isSinglePlainCommand =\n childrenArray.length === 1 &&\n [\"language-shell\", \"language-text\"].some(\n (lang) =>\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(lang),\n );\n\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n if (!codeElement) return;\n\n const codeLanguage = extractLanguageFromCode(codeElement);\n\n if (!codeLanguage) return;\n\n if (codeLanguage.startsWith(\"realtime_\")) {\n sdkTypes.add(\"realtime\");\n } else if (codeLanguage.startsWith(\"rest_\")) {\n sdkTypes.add(\"rest\");\n }\n\n if (!languages.includes(codeLanguage)) {\n languages.push(codeLanguage);\n }\n\n const codeContent = codeElement.props.children;\n codeData.push({ language: codeLanguage, content: codeContent });\n });\n\n return {\n codeData,\n languages,\n sdkTypes,\n isSinglePlainCommand,\n };\n }, [children, extractLanguageFromCode]);\n\n const resolvedSdk: SDKType = useMemo(() => {\n if (sdkTypes.size === 1 && sdk && !sdkTypes.has(sdk)) {\n return Array.from(sdkTypes)[0];\n }\n return sdk ?? null;\n }, [sdk, sdkTypes]);\n\n const showSDKSelector = sdkTypes.size > 0;\n\n const filteredLanguages = useMemo(() => {\n const filtered =\n !resolvedSdk || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${resolvedSdk}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = stripSdkType(a);\n const bBase = stripSdkType(b);\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [resolvedSdk, showSDKSelector, languages, languageOrdering]);\n\n const activeLanguage = useMemo(() => {\n if (resolvedSdk && sdkTypes.has(resolvedSdk)) {\n return `${resolvedSdk}_${lang}`;\n }\n\n if (lang) return lang;\n\n if (filteredLanguages.length > 0) return filteredLanguages[0];\n\n return languages[0];\n }, [resolvedSdk, sdkTypes, lang, filteredLanguages, languages]);\n\n const requiresApiKeySubstitution = useMemo(() => {\n const containsPlaceholder = codeData.some((code) =>\n code?.content.includes(\"{{API_KEY}}\"),\n );\n\n return (\n containsPlaceholder && !!apiKeys && apiKeys.length > 0 && !!selectedApiKey\n );\n }, [codeData, apiKeys, selectedApiKey]);\n\n const [isHovering, setIsHovering] = useState(false);\n\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return codeData\n .filter((code) => {\n return code?.language === targetLanguage;\n })\n .map((code) => {\n if (!code) return null;\n\n const cleanLang = hasOnlyJsonSnippet ? \"json\" : code.language;\n const langInfo = getLanguageInfo(cleanLang ?? \"\");\n\n if (\n typeof code.content === \"string\" ||\n typeof code.content === \"number\" ||\n typeof code.content === \"boolean\"\n ) {\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(code.content);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(\n processedContent,\n selectedApiKey,\n );\n }\n\n if (!langInfo.syntaxHighlighterKey || !cleanLang) return null;\n\n return (\n <Code\n key={code.language}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={processedContent}\n additionalCSS=\"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n wrap={wrapCode}\n />\n );\n }\n\n return null;\n });\n }, [\n activeLanguage,\n hasOnlyJsonSnippet,\n codeData,\n requiresApiKeySubstitution,\n showCodeLines,\n wrapCode,\n selectedApiKey,\n ]);\n\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return codeData.some((code) => {\n return code?.language === activeLanguage;\n });\n }, [activeLanguage, hasOnlyJsonSnippet, codeData]);\n\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n const nextLang = stripSdkType(\n languages.find(\n (l) => l === `${type}_${stripSdkType(activeLanguage)}`,\n ) ??\n languages.find((l) => l.startsWith(`${type}_`)) ??\n activeLanguage,\n );\n\n if (onChange && nextLang) {\n onChange(stripSdkType(activeLanguage), type);\n }\n },\n [activeLanguage, languages, onChange],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n if (onChange) {\n onChange(stripSdkType(language), resolvedSdk);\n }\n },\n [onChange, resolvedSdk],\n );\n\n const noSnippetMessage = useMemo(() => {\n if (!activeLanguage) return null;\n\n const activeLanguageInfo = getLanguageInfo(activeLanguage);\n\n return (\n <div className=\"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You&apos;re currently viewing the {activeLanguageInfo.label} docs.\n There either isn&apos;t a {activeLanguageInfo.label} code sample for\n this example, or this feature isn&apos;t supported in{\" \"}\n {activeLanguageInfo.label}. Switch language to view this example in a\n different language, or check which SDKs support this feature.\n </p>\n </div>\n );\n }, [activeLanguage]);\n\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n return noSnippetMessage;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n noSnippetMessage,\n ]);\n\n // Render special case for plain commands (shell or text)\n if (isSinglePlainCommand) {\n const plainChild = codeData[0];\n if (plainChild) {\n const codeContent = plainChild.content;\n const language = plainChild.language;\n\n if (!language || !codeContent) return null;\n\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(processedContent, selectedApiKey);\n }\n\n return (\n <PlainCodeView\n content={processedContent}\n className={className}\n language={language}\n icon={language === \"shell\" ? \"icon-gui-command-line-outline\" : null}\n />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg\">\n <div className=\"flex space-x-1.5\">\n <div className=\"w-3 h-3 rounded-full bg-orange-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-green-500\"></div>\n </div>\n\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n <div className=\"w-12\"></div>\n </div>\n )}\n\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-300 dark:border-neutral-1000\",\n sdkTypes.size === 1 && \"p-1\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-1 justify-start\">\n {[\"realtime\", \"rest\"].map(\n (type) =>\n sdkTypes.has(type as SDKType) && (\n <SegmentedControl\n key={type}\n onClick={() => handleSDKTypeChange(type as SDKType)}\n size=\"xs\"\n active={resolvedSdk === type}\n className={cn(\n \"text-[11px] font-semibold px-2 py-1 h-auto\",\n sdkTypes.size === 1 &&\n \"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500\",\n sdkTypes.size > 1 &&\n resolvedSdk !== type &&\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900\",\n sdkTypes.size > 1 &&\n resolvedSdk === type &&\n \"bg-neutral-000 dark:bg-neutral-1100\",\n )}\n >\n {type === \"realtime\" ? \"Realtime\" : \"REST\"}\n </SegmentedControl>\n ),\n )}\n </div>\n </div>\n )}\n\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full\",\n { \"rounded-t-lg\": !headerRow },\n )}\n >\n {filteredLanguages.length > 0 && (\n <div\n className={cn(\"inline-flex items-center\", {\n \"cursor-pointer\": filteredLanguages.length > 0,\n })}\n {...(filteredLanguages.length > 0 && {\n onClick: () => handleLanguageChange(filteredLanguages[0]),\n })}\n >\n <Icon\n name={getLanguageInfo(filteredLanguages[0]).icon}\n size=\"16px\"\n additionalCSS=\"mr-2\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageInfo(filteredLanguages[0]).label}\n </span>\n </div>\n )}\n </div>\n ))}\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n >\n {renderContent}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = codeData.find(\n (code) => code.language === activeLanguage,\n )?.content;\n if (text)\n navigator.clipboard.writeText(\n substituteApiKey(text, selectedApiKey, false),\n );\n }}\n />\n )}\n </div>\n {requiresApiKeySubstitution && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={setSelectedApiKey}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","Icon","getLanguageInfo","stripSdkType","LanguageSelector","ApiKeySelector","PlainCodeView","CopyButton","SegmentedControl","substituteApiKey","content","apiKey","mask","replace","split","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","wrapCode","codeRef","selectedApiKey","setSelectedApiKey","keys","key","length","element","current","unmaskRenderedApiKey","handleCopy","event","selection","window","getSelection","rangeCount","selectedText","toString","range","getRangeAt","contains","commonAncestorContainer","modifiedText","clipboardData","setData","preventDefault","document","addEventListener","removeEventListener","extractLanguageFromCode","codeElement","props","classNames","langClass","find","cls","startsWith","substring","codeData","languages","sdkTypes","isSinglePlainCommand","childrenArray","toArray","Set","some","includes","forEach","child","preElement","codeLanguage","add","push","codeContent","language","resolvedSdk","size","has","Array","from","showSDKSelector","filteredLanguages","filtered","filter","sort","a","b","aBase","bBase","aIndex","indexOf","bIndex","activeLanguage","requiresApiKeySubstitution","containsPlaceholder","code","isHovering","setIsHovering","hasOnlyJsonSnippet","processedChildren","targetLanguage","map","cleanLang","langInfo","processedContent","String","syntaxHighlighterKey","snippet","additionalCSS","showLines","wrap","hasSnippetForActiveLanguage","handleSDKTypeChange","type","nextLang","l","handleLanguageChange","noSnippetMessage","activeLanguageInfo","div","name","color","p","label","showLanguageSelector","showFullSelector","renderContent","plainChild","icon","onClick","active","onLanguageChange","span","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","onCopy","text","navigator","clipboard","writeText","onApiKeyChange"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/CodeSnippet.tsx"],"sourcesContent":["import React, {\n useState,\n useEffect,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport {\n getLanguageInfo,\n stripSdkType,\n SDK_PREFIXES,\n SDKType,\n} from \"./CodeSnippet/languages\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport PlainCodeView from \"./CodeSnippet/PlainCodeView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport SegmentedControl from \"./SegmentedControl\";\n\n// Re-export SDKType for consumers\nexport type { SDKType };\n\n// Define API key types\nexport type ApiKeysItem = {\n app: string;\n keys: { name: string; key: string }[];\n};\n\nexport type CodeSnippetProps = {\n /**\n * If true, hides the language selector row completely\n */\n fixed?: boolean;\n /**\n * If true, renders a macOS-style window header with buttons and title\n */\n headerRow?: boolean;\n /**\n * Title to display in the header row (when headerRow is true)\n */\n title?: string;\n /**\n * Children elements with lang attribute\n */\n children: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Default language to display. If not found in available languages, first available is used.\n * If found in languages but no matching snippet exists, a message is displayed.\n */\n lang: string | null;\n /**\n * Callback fired when the active language changes\n */\n onChange?: (language: string, sdk?: SDKType) => void;\n /**\n * List of API keys to display in a dropdown\n */\n apiKeys?: ApiKeysItem[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\n /**\n * Whether to show line numbers in code snippets\n */\n showCodeLines?: boolean;\n /**\n * Defines the order in which languages should be displayed.\n * Languages not in this array will be shown after those that are included.\n */\n languageOrdering?: string[];\n /**\n * Whether to wrap code content instead of scrolling\n */\n wrapCode?: boolean;\n};\n\n// Substitution function for API key placeholders\nconst substituteApiKey = (\n content: string,\n apiKey: string,\n mask = true,\n): string => {\n return content.replace(\n /\\{\\{API_KEY\\}\\}/g,\n mask ? `${apiKey.split(\":\")[0]}:*****` : apiKey,\n );\n};\n\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n wrapCode = false,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n\n const [selectedApiKey, setSelectedApiKey] = useState<string>(\n () => apiKeys?.[0]?.keys?.[0]?.key ?? \"\",\n );\n\n useEffect(() => {\n if (!selectedApiKey && apiKeys && apiKeys.length > 0) {\n setSelectedApiKey(apiKeys[0].keys?.[0]?.key);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiKeys]);\n\n useEffect(() => {\n const element = codeRef.current;\n if (!element) return;\n\n // Detects the key masking via substituteApiKey (i.e. \"abcde:*****\") and replaces it with the actual API key\n const unmaskRenderedApiKey = (content: string, apiKey: string): string => {\n return content.replace(/(['\"]?)([^:'\"]+):\\*{5}\\1/g, `$1${apiKey}$1`);\n };\n\n const handleCopy = (event: ClipboardEvent) => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n\n const selectedText = selection.toString();\n if (!selectedText) return;\n\n // Check if the selection is within our element\n const range = selection.getRangeAt(0);\n if (!element.contains(range.commonAncestorContainer)) return;\n\n const modifiedText = unmaskRenderedApiKey(selectedText, selectedApiKey);\n\n event.clipboardData?.setData(\"text/plain\", modifiedText);\n event.preventDefault();\n };\n\n document.addEventListener(\"copy\", handleCopy);\n\n return () => {\n document.removeEventListener(\"copy\", handleCopy);\n };\n }, [selectedApiKey]);\n\n const extractLanguageFromCode = useCallback(\n (codeElement: React.ReactElement | null): string | null => {\n if (!codeElement || !codeElement.props.className) return null;\n\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return null;\n\n return langClass.substring(9); // Remove \"language-\" prefix\n },\n [],\n );\n\n // Helper to find the code element within pre's children (handles both single element and array)\n const findCodeElement = useCallback(\n (preChildren: React.ReactNode): React.ReactElement | null => {\n if (isValidElement(preChildren)) {\n return preChildren;\n }\n if (Array.isArray(preChildren)) {\n const codeEl = preChildren.find((c) => isValidElement(c));\n return codeEl && isValidElement(codeEl) ? codeEl : null;\n }\n return null;\n },\n [],\n );\n\n const { codeData, languages, sdkTypes, isSinglePlainCommand } =\n useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const codeData: { language: string; content: string }[] = [];\n\n const isSinglePlainCommand =\n childrenArray.length === 1 &&\n [\"language-shell\", \"language-text\"].some((lang) => {\n if (!isValidElement(childrenArray[0])) return false;\n const codeEl = findCodeElement(childrenArray[0].props.children);\n return codeEl?.props.className?.includes(lang);\n });\n\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = findCodeElement(preElement.props.children);\n\n if (!codeElement) return;\n\n const codeLanguage = extractLanguageFromCode(codeElement);\n\n if (!codeLanguage) return;\n\n for (const prefix of SDK_PREFIXES) {\n if (codeLanguage.startsWith(`${prefix}_`)) {\n sdkTypes.add(prefix);\n break;\n }\n }\n\n if (!languages.includes(codeLanguage)) {\n languages.push(codeLanguage);\n }\n\n const codeContent = codeElement.props.children;\n codeData.push({ language: codeLanguage, content: codeContent });\n });\n\n return {\n codeData,\n languages,\n sdkTypes,\n isSinglePlainCommand,\n };\n }, [children, extractLanguageFromCode, findCodeElement]);\n\n const resolvedSdk: SDKType | undefined = useMemo(() => {\n if (sdkTypes.size === 1 && sdk && !sdkTypes.has(sdk)) {\n return Array.from(sdkTypes)[0];\n }\n return sdk;\n }, [sdk, sdkTypes]);\n\n // Only show SDK selector for realtime/rest types, not for client/agent (which are controlled by page-level selector)\n const showSDKSelector = sdkTypes.has(\"realtime\") || sdkTypes.has(\"rest\");\n\n const filteredLanguages = useMemo(() => {\n const filtered =\n !resolvedSdk || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${resolvedSdk}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = stripSdkType(a);\n const bBase = stripSdkType(b);\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [resolvedSdk, showSDKSelector, languages, languageOrdering]);\n\n const activeLanguage = useMemo(() => {\n // For client/agent SDK types (controlled by page-level selector), construct the full language\n if (resolvedSdk === \"client\" || resolvedSdk === \"agent\") {\n const fullLang = `${resolvedSdk}_${lang}`;\n // Verify this language exists in available languages\n if (languages.includes(fullLang)) {\n return fullLang;\n }\n // Fall back to first language with this prefix\n const prefixMatch = languages.find((l) =>\n l.startsWith(`${resolvedSdk}_`),\n );\n if (prefixMatch) return prefixMatch;\n }\n\n // For realtime/rest SDK types\n if (resolvedSdk && sdkTypes.has(resolvedSdk)) {\n return `${resolvedSdk}_${lang}`;\n }\n\n if (lang) return lang;\n\n if (filteredLanguages.length > 0) return filteredLanguages[0];\n\n return languages[0];\n }, [resolvedSdk, sdkTypes, lang, filteredLanguages, languages]);\n\n const requiresApiKeySubstitution = useMemo(() => {\n const containsPlaceholder = codeData.some((code) =>\n code?.content.includes(\"{{API_KEY}}\"),\n );\n\n return (\n containsPlaceholder && !!apiKeys && apiKeys.length > 0 && !!selectedApiKey\n );\n }, [codeData, apiKeys, selectedApiKey]);\n\n const [isHovering, setIsHovering] = useState(false);\n\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return codeData\n .filter((code) => {\n return code?.language === targetLanguage;\n })\n .map((code) => {\n if (!code) return null;\n\n const cleanLang = hasOnlyJsonSnippet ? \"json\" : code.language;\n const langInfo = getLanguageInfo(cleanLang ?? \"\");\n\n if (\n typeof code.content === \"string\" ||\n typeof code.content === \"number\" ||\n typeof code.content === \"boolean\"\n ) {\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(code.content);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(\n processedContent,\n selectedApiKey,\n );\n }\n\n if (!langInfo.syntaxHighlighterKey || !cleanLang) return null;\n\n return (\n <Code\n key={code.language}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={processedContent}\n additionalCSS=\"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n wrap={wrapCode}\n />\n );\n }\n\n return null;\n });\n }, [\n activeLanguage,\n hasOnlyJsonSnippet,\n codeData,\n requiresApiKeySubstitution,\n showCodeLines,\n wrapCode,\n selectedApiKey,\n ]);\n\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return codeData.some((code) => {\n return code?.language === activeLanguage;\n });\n }, [activeLanguage, hasOnlyJsonSnippet, codeData]);\n\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n const nextLang = stripSdkType(\n languages.find(\n (l) => l === `${type}_${stripSdkType(activeLanguage)}`,\n ) ??\n languages.find((l) => l.startsWith(`${type}_`)) ??\n activeLanguage,\n );\n\n if (onChange && nextLang) {\n onChange(stripSdkType(activeLanguage), type);\n }\n },\n [activeLanguage, languages, onChange],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n if (onChange) {\n onChange(stripSdkType(language), resolvedSdk);\n }\n },\n [onChange, resolvedSdk],\n );\n\n const noSnippetMessage = useMemo(() => {\n if (!activeLanguage) return null;\n\n const activeLanguageInfo = getLanguageInfo(activeLanguage);\n\n return (\n <div className=\"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You&apos;re currently viewing the {activeLanguageInfo.label} docs.\n There either isn&apos;t a {activeLanguageInfo.label} code sample for\n this example, or this feature isn&apos;t supported in{\" \"}\n {activeLanguageInfo.label}. Switch language to view this example in a\n different language, or check which SDKs support this feature.\n </p>\n </div>\n );\n }, [activeLanguage]);\n\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n // Show a read-only language label when fixed (controlled by external selector)\n const showFixedLanguageLabel = fixed && activeLanguage;\n\n const renderLanguageLabel = (langKey: string, onClick?: () => void) => (\n <div\n className={cn(\n \"border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full\",\n { \"rounded-t-lg\": !headerRow },\n )}\n >\n <div\n className={cn(\"inline-flex items-center\", onClick && \"cursor-pointer\")}\n {...(onClick && { onClick })}\n >\n <Icon\n name={getLanguageInfo(langKey).icon}\n size=\"16px\"\n additionalCSS=\"mr-2\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageInfo(langKey).label}\n </span>\n </div>\n </div>\n );\n\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n return noSnippetMessage;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n noSnippetMessage,\n ]);\n\n // Render special case for plain commands (shell or text)\n if (isSinglePlainCommand) {\n const plainChild = codeData[0];\n if (plainChild) {\n const codeContent = plainChild.content;\n const language = plainChild.language;\n\n if (!language || !codeContent) return null;\n\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(processedContent, selectedApiKey);\n }\n\n return (\n <PlainCodeView\n content={processedContent}\n className={className}\n language={language}\n icon={language === \"shell\" ? \"icon-gui-command-line-outline\" : null}\n />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg\">\n <div className=\"flex space-x-1.5\">\n <div className=\"w-3 h-3 rounded-full bg-orange-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-green-500\"></div>\n </div>\n\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n <div className=\"w-12\"></div>\n </div>\n )}\n\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-300 dark:border-neutral-1000\",\n sdkTypes.size === 1 && \"p-1\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-1 justify-start\">\n {[\"realtime\", \"rest\"].map(\n (type) =>\n sdkTypes.has(type as SDKType) && (\n <SegmentedControl\n key={type}\n onClick={() => handleSDKTypeChange(type as SDKType)}\n size=\"xs\"\n active={resolvedSdk === type}\n className={cn(\n \"text-[11px] font-semibold px-2 py-1 h-auto\",\n sdkTypes.size === 1 &&\n \"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500\",\n sdkTypes.size > 1 &&\n resolvedSdk !== type &&\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900\",\n sdkTypes.size > 1 &&\n resolvedSdk === type &&\n \"bg-neutral-000 dark:bg-neutral-1100\",\n )}\n >\n {type === \"realtime\" ? \"Realtime\" : \"REST\"}\n </SegmentedControl>\n ),\n )}\n </div>\n </div>\n )}\n\n {showFixedLanguageLabel && renderLanguageLabel(activeLanguage)}\n\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n />\n ) : (\n renderLanguageLabel(filteredLanguages[0], () =>\n handleLanguageChange(filteredLanguages[0]),\n )\n ))}\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n >\n {renderContent}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = codeData.find(\n (code) => code.language === activeLanguage,\n )?.content;\n if (text)\n navigator.clipboard.writeText(\n substituteApiKey(text, selectedApiKey, false),\n );\n }}\n />\n )}\n </div>\n {requiresApiKeySubstitution && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={setSelectedApiKey}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","Icon","getLanguageInfo","stripSdkType","SDK_PREFIXES","LanguageSelector","ApiKeySelector","PlainCodeView","CopyButton","SegmentedControl","substituteApiKey","content","apiKey","mask","replace","split","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","wrapCode","codeRef","selectedApiKey","setSelectedApiKey","keys","key","length","element","current","unmaskRenderedApiKey","handleCopy","event","selection","window","getSelection","rangeCount","selectedText","toString","range","getRangeAt","contains","commonAncestorContainer","modifiedText","clipboardData","setData","preventDefault","document","addEventListener","removeEventListener","extractLanguageFromCode","codeElement","props","classNames","langClass","find","cls","startsWith","substring","findCodeElement","preChildren","Array","isArray","codeEl","c","codeData","languages","sdkTypes","isSinglePlainCommand","childrenArray","toArray","Set","some","includes","forEach","child","preElement","codeLanguage","prefix","add","push","codeContent","language","resolvedSdk","size","has","from","showSDKSelector","filteredLanguages","filtered","filter","sort","a","b","aBase","bBase","aIndex","indexOf","bIndex","activeLanguage","fullLang","prefixMatch","l","requiresApiKeySubstitution","containsPlaceholder","code","isHovering","setIsHovering","hasOnlyJsonSnippet","processedChildren","targetLanguage","map","cleanLang","langInfo","processedContent","String","syntaxHighlighterKey","snippet","additionalCSS","showLines","wrap","hasSnippetForActiveLanguage","handleSDKTypeChange","type","nextLang","handleLanguageChange","noSnippetMessage","activeLanguageInfo","div","name","color","p","label","showLanguageSelector","showFullSelector","showFixedLanguageLabel","renderLanguageLabel","langKey","onClick","icon","span","renderContent","plainChild","active","onLanguageChange","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","onCopy","text","navigator","clipboard","writeText","onApiKeyChange"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/remote-blogs-posts.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst fetchBlogPosts = async (store, blogUrl) => {\n try {\n if (!blogUrl) {\n console.log(\n `Skipping fetching blog posts, invalid blogUrl: \"${blogUrl}\"`,\n );\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(blogUrl, options);\n\n if (isJsonResponse(res.headers.get(\"content-type\"))) {\n const payload = await res.json();\n store.dispatch({ type: \"blog/loaded\", payload });\n } else {\n throw new Error(\"Blog posts url is not serving json\");\n }\n } catch (e) {\n console.warn(\"Could not fetch blog posts due to error:\", e);\n }\n};\n\nconst initialState = { recent: null };\n\nconst REDUCER_KEY = \"blogPosts\";\n\nconst reducerBlogPosts = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"blog/loaded\":\n return { ...state, recent: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectRecentBlogPosts = (store) => store.getState()[REDUCER_KEY]?.recent;\n\nexport { fetchBlogPosts, reducerBlogPosts, selectRecentBlogPosts };\n"],"names":["isJsonResponse","fetchBlogPosts","store","blogUrl","console","log","options","headers","accept","cache","credentials","res","fetch","get","payload","json","dispatch","type","Error","e","warn","initialState","recent","REDUCER_KEY","reducerBlogPosts","state","action","selectRecentBlogPosts","getState"],"mappings":"AAEA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,eAAiB,MAAOC,MAAOC,WACnC,GAAI,CACF,GAAI,CAACA,QAAS,CACZC,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEF,QAAQ,CAAC,CAAC,EAE/D,MACF,CAEA,MAAMG,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,SAAuC,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMT,QAASG,SAEjC,GAAIN,eAAeW,IAAIJ,OAAO,CAACM,GAAG,CAAC,iBAAkB,CACnD,MAAMC,QAAU,MAAMH,IAAII,IAAI,GAC9Bb,MAAMc,QAAQ,CAAC,CAAEC,KAAM,cAAeH,OAAQ,EAChD,KAAO,CACL,MAAM,IAAII,MAAM,qCAClB,CACF,CAAE,MAAOC,EAAG,CACVf,QAAQgB,IAAI,CAAC,2CAA4CD,EAC3D,CACF,EAEA,MAAME,aAAe,CAAEC,OAAQ,IAAK,EAEpC,MAAMC,YAAc,YAEpB,MAAMC,iBAAmB,CACvB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOT,IAAI,EACjB,IAAK,cACH,MAAO,CAAE,GAAGQ,KAAK,CAAEH,OAAQI,OAAOZ,OAAO,AAAC,CAC5C,SACE,OAAOW,KACX,CACF,CACF,EAEA,MAAME,sBAAwB,AAACzB,OAAUA,MAAM0B,QAAQ,EAAE,CAACL,YAAY,EAAED,MAExE,QAASrB,cAAc,CAAEuB,gBAAgB,CAAEG,qBAAqB,CAAG"}
1
+ {"version":3,"sources":["../../src/core/remote-blogs-posts.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst fetchBlogPosts = async (store, blogUrl) => {\n try {\n if (!blogUrl) {\n console.log(\n `Skipping fetching blog posts, invalid blogUrl: \"${blogUrl}\"`,\n );\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(blogUrl, options);\n\n if (isJsonResponse(res.headers.get(\"content-type\"))) {\n const payload = await res.json();\n store.dispatch({ type: \"blog/loaded\", payload });\n } else {\n throw new Error(\"Blog posts url is not serving json\");\n }\n } catch (e) {\n console.warn(\"Could not fetch blog posts due to error:\", e);\n }\n};\n\nconst initialState = { recent: null };\n\nconst REDUCER_KEY = \"blogPosts\";\n\nconst reducerBlogPosts = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"blog/loaded\":\n return { ...state, recent: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectRecentBlogPosts = (store) => store.getState()[REDUCER_KEY]?.recent;\n\nexport { fetchBlogPosts, reducerBlogPosts, selectRecentBlogPosts };\n"],"names":["isJsonResponse","fetchBlogPosts","store","blogUrl","console","log","options","headers","accept","cache","credentials","res","fetch","get","payload","json","dispatch","type","Error","e","warn","initialState","recent","REDUCER_KEY","reducerBlogPosts","state","action","selectRecentBlogPosts","getState"],"mappings":"AAEA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,eAAiB,MAAOC,MAAOC,WACnC,GAAI,CACF,GAAI,CAACA,QAAS,CACZC,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEF,QAAQ,CAAC,CAAC,EAE/D,MACF,CAEA,MAAMG,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,GAWJ,MAX2C,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMT,QAASG,SAEjC,GAAIN,eAAeW,IAAIJ,OAAO,CAACM,GAAG,CAAC,iBAAkB,CACnD,MAAMC,QAAU,MAAMH,IAAII,IAAI,GAC9Bb,MAAMc,QAAQ,CAAC,CAAEC,KAAM,cAAeH,OAAQ,EAChD,KAAO,CACL,MAAM,IAAII,MAAM,qCAClB,CACF,CAAE,MAAOC,EAAG,CACVf,QAAQgB,IAAI,CAAC,2CAA4CD,EAC3D,CACF,EAEA,MAAME,aAAe,CAAEC,OAAQ,IAAK,EAEpC,MAAMC,YAAc,YAEpB,MAAMC,iBAAmB,CACvB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOT,IAAI,EACjB,IAAK,cACH,MAAO,CAAE,GAAGQ,KAAK,CAAEH,OAAQI,OAAOZ,OAAO,AAAC,CAC5C,SACE,OAAOW,KACX,CACF,CACF,EAEA,MAAME,sBAAwB,AAACzB,OAAUA,MAAM0B,QAAQ,EAAE,CAACL,YAAY,EAAED,MAExE,QAASrB,cAAc,CAAEuB,gBAAgB,CAAEG,qBAAqB,CAAG"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/remote-session-data.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\n// Fetches current users session data\n// Assumes an authenticated session, so will only work when used on ably.com/ably.io\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst NOT_FOUND_ERROR_CODE = \"not-found\";\n\nconst fetchSessionData = async (store, sessionUrl) => {\n const sessionLoaded = (payload = {}) =>\n store.dispatch({ type: \"session/loaded\", payload });\n\n try {\n if (!sessionUrl) {\n console.log(\n `Skipping fetching session, invalid sessionUrl: \"${sessionUrl}\"`,\n );\n sessionLoaded();\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(sessionUrl, options);\n const jsonResponse = isJsonResponse(res.headers.get(\"content-type\"));\n\n if (!jsonResponse) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const payload = await res.json();\n\n if (payload.error === NOT_FOUND_ERROR_CODE) {\n sessionLoaded();\n } else {\n sessionLoaded(payload);\n }\n } catch (e) {\n sessionLoaded();\n console.warn(\"Could not fetch session data due to error:\", e);\n }\n};\n\nconst initialState = { data: null };\n\nconst REDUCER_KEY = \"session\";\n\nconst reducerSessionData = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"session/loaded\":\n return { ...state, data: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectSessionData = (store) => store.getState()[REDUCER_KEY]?.data;\n\nexport { fetchSessionData, reducerSessionData, selectSessionData };\n"],"names":["isJsonResponse","NOT_FOUND_ERROR_CODE","fetchSessionData","store","sessionUrl","sessionLoaded","payload","dispatch","type","console","log","options","headers","accept","cache","credentials","res","fetch","jsonResponse","get","Error","json","error","e","warn","initialState","data","REDUCER_KEY","reducerSessionData","state","action","selectSessionData","getState"],"mappings":"AAKA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,qBAAuB,YAE7B,MAAMC,iBAAmB,MAAOC,MAAOC,cACrC,MAAMC,cAAgB,CAACC,QAAU,CAAC,CAAC,GACjCH,MAAMI,QAAQ,CAAC,CAAEC,KAAM,iBAAkBF,OAAQ,GAEnD,GAAI,CACF,GAAI,CAACF,WAAY,CACfK,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEN,WAAW,CAAC,CAAC,EAElEC,gBACA,MACF,CAEA,MAAMM,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,SAAuC,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMb,WAAYO,SACpC,MAAMO,aAAelB,eAAegB,IAAIJ,OAAO,CAACO,GAAG,CAAC,iBAEpD,GAAI,CAACD,aAAc,CACjB,MAAM,IAAIE,MAAM,uCAClB,CAEA,MAAMd,QAAU,MAAMU,IAAIK,IAAI,GAE9B,GAAIf,QAAQgB,KAAK,GAAKrB,qBAAsB,CAC1CI,eACF,KAAO,CACLA,cAAcC,QAChB,CACF,CAAE,MAAOiB,EAAG,CACVlB,gBACAI,QAAQe,IAAI,CAAC,6CAA8CD,EAC7D,CACF,EAEA,MAAME,aAAe,CAAEC,KAAM,IAAK,EAElC,MAAMC,YAAc,UAEpB,MAAMC,mBAAqB,CACzB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOtB,IAAI,EACjB,IAAK,iBACH,MAAO,CAAE,GAAGqB,KAAK,CAAEH,KAAMI,OAAOxB,OAAO,AAAC,CAC1C,SACE,OAAOuB,KACX,CACF,CACF,EAEA,MAAME,kBAAoB,AAAC5B,OAAUA,MAAM6B,QAAQ,EAAE,CAACL,YAAY,EAAED,IAEpE,QAASxB,gBAAgB,CAAE0B,kBAAkB,CAAEG,iBAAiB,CAAG"}
1
+ {"version":3,"sources":["../../src/core/remote-session-data.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\n// Fetches current users session data\n// Assumes an authenticated session, so will only work when used on ably.com/ably.io\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst NOT_FOUND_ERROR_CODE = \"not-found\";\n\nconst fetchSessionData = async (store, sessionUrl) => {\n const sessionLoaded = (payload = {}) =>\n store.dispatch({ type: \"session/loaded\", payload });\n\n try {\n if (!sessionUrl) {\n console.log(\n `Skipping fetching session, invalid sessionUrl: \"${sessionUrl}\"`,\n );\n sessionLoaded();\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(sessionUrl, options);\n const jsonResponse = isJsonResponse(res.headers.get(\"content-type\"));\n\n if (!jsonResponse) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const payload = await res.json();\n\n if (payload.error === NOT_FOUND_ERROR_CODE) {\n sessionLoaded();\n } else {\n sessionLoaded(payload);\n }\n } catch (e) {\n sessionLoaded();\n console.warn(\"Could not fetch session data due to error:\", e);\n }\n};\n\nconst initialState = { data: null };\n\nconst REDUCER_KEY = \"session\";\n\nconst reducerSessionData = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"session/loaded\":\n return { ...state, data: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectSessionData = (store) => store.getState()[REDUCER_KEY]?.data;\n\nexport { fetchSessionData, reducerSessionData, selectSessionData };\n"],"names":["isJsonResponse","NOT_FOUND_ERROR_CODE","fetchSessionData","store","sessionUrl","sessionLoaded","payload","dispatch","type","console","log","options","headers","accept","cache","credentials","res","fetch","jsonResponse","get","Error","json","error","e","warn","initialState","data","REDUCER_KEY","reducerSessionData","state","action","selectSessionData","getState"],"mappings":"AAKA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,qBAAuB,YAE7B,MAAMC,iBAAmB,MAAOC,MAAOC,cACrC,MAAMC,cAAgB,CAACC,QAAU,CAAC,CAAC,GACjCH,MAAMI,QAAQ,CAAC,CAAEC,KAAM,iBAAkBF,OAAQ,GAEnD,GAAI,CACF,GAAI,CAACF,WAAY,CACfK,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEN,WAAW,CAAC,CAAC,EAElEC,gBACA,MACF,CAEA,MAAMM,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,GACkB,MADqB,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMb,WAAYO,SACpC,MAAMO,aAAelB,eAAegB,IAAIJ,OAAO,CAACO,GAAG,CAAC,iBAEpD,GAAI,CAACD,aAAc,CACjB,MAAM,IAAIE,MAAM,uCAClB,CAEA,MAAMd,QAAU,MAAMU,IAAIK,IAAI,GAE9B,GAAIf,QAAQgB,KAAK,GAAKrB,qBAAsB,CAC1CI,eACF,KAAO,CACLA,cAAcC,QAChB,CACF,CAAE,MAAOiB,EAAG,CACVlB,gBACAI,QAAQe,IAAI,CAAC,6CAA8CD,EAC7D,CACF,EAEA,MAAME,aAAe,CAAEC,KAAM,IAAK,EAElC,MAAMC,YAAc,UAEpB,MAAMC,mBAAqB,CACzB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOtB,IAAI,EACjB,IAAK,iBACH,MAAO,CAAE,GAAGqB,KAAK,CAAEH,KAAMI,OAAOxB,OAAO,AAAC,CAC1C,SACE,OAAOuB,KACX,CACF,CACF,EAEA,MAAME,kBAAoB,AAAC5B,OAAUA,MAAM6B,QAAQ,EAAE,CAACL,YAAY,EAAED,IAEpE,QAASxB,gBAAgB,CAAE0B,kBAAkB,CAAEG,iBAAiB,CAAG"}
package/index.d.ts CHANGED
@@ -338,6 +338,14 @@ export default ApiKeySelector;
338
338
  //# sourceMappingURL=ApiKeySelector.d.ts.map
339
339
  }
340
340
 
341
+ declare module '@ably/ui/core/CodeSnippet/CodeSnippet.test' {
342
+ /**
343
+ * @vitest-environment jsdom
344
+ */
345
+ export {};
346
+ //# sourceMappingURL=CodeSnippet.test.d.ts.map
347
+ }
348
+
341
349
  declare module '@ably/ui/core/CodeSnippet/CopyButton' {
342
350
  type CopyButtonProps = {
343
351
  onCopy: () => void;
@@ -403,6 +411,8 @@ export interface LanguageInfo {
403
411
  syntaxHighlighterKey?: string;
404
412
  }
405
413
  export type LanguageMap = Record<string, LanguageInfo>;
414
+ export const SDK_PREFIXES: readonly ["realtime", "rest", "client", "agent"];
415
+ export type SDKType = (typeof SDK_PREFIXES)[number];
406
416
  const languages: LanguageMap;
407
417
  export const stripSdkType: (lang: string) => string;
408
418
  export const getLanguageInfo: (langKey: string) => LanguageInfo;
@@ -410,9 +420,15 @@ export default languages;
410
420
  //# sourceMappingURL=languages.d.ts.map
411
421
  }
412
422
 
423
+ declare module '@ably/ui/core/CodeSnippet/languages.test' {
424
+ export {};
425
+ //# sourceMappingURL=languages.test.d.ts.map
426
+ }
427
+
413
428
  declare module '@ably/ui/core/CodeSnippet' {
414
429
  import React from "react";
415
- export type SDKType = "realtime" | "rest" | null;
430
+ import { SDKType } from "@ably/ui/core/CodeSnippet/languages";
431
+ export type { SDKType };
416
432
  export type ApiKeysItem = {
417
433
  app: string;
418
434
  keys: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ably/ui",
3
- "version": "17.13.2-dev.44eaafa0f2",
3
+ "version": "17.13.2-dev.aa83caf92f",
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",