@apipass/design-system 4.0.0 → 4.2.1
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/dist/lib/embedded-styles.js +1 -1
- package/dist/lib/json-viewer.index.cjs +1 -1
- package/dist/lib/json-viewer.index.js +4 -2
- package/dist/lib/json-viewer.index.js.map +1 -1
- package/dist/lib/lib.index.cjs +1 -1
- package/dist/lib/lib.index.js +696 -694
- package/dist/lib/lib.index.js.map +1 -1
- package/dist/lib/style.css +1 -1
- package/dist/lib/ui/components/DataTable/DataTable.cjs +1 -1
- package/dist/lib/ui/components/Widget/Widget.cjs +1 -1
- package/dist/lib/ui/components/WidgetGrid/WidgetGrid.cjs +1 -1
- package/dist/lib/ui/primitives/Button/Button.cjs +1 -1
- package/dist/lib/ui/primitives/CodeBlock/CodeBlock.cjs +1 -1
- package/dist/lib/ui/primitives/CodeEditor/CodeEditor.cjs +1 -1
- package/dist/lib/ui/primitives/ComboBox/ComboBox.cjs +1 -1
- package/dist/lib/ui/primitives/ComboBox/ComboBox.cjs.map +1 -1
- package/dist/lib/ui/primitives/ComboBox/ComboBox.js +60 -37
- package/dist/lib/ui/primitives/ComboBox/ComboBox.js.map +1 -1
- package/dist/lib/ui/primitives/DateRangePicker/DateRangePicker.cjs +1 -1
- package/dist/lib/ui/primitives/FileUpload/FileUpload.cjs +1 -1
- package/dist/lib/ui/primitives/FileUpload/FileUpload.js +10 -10
- package/dist/lib/ui/primitives/IconButton/IconButton.cjs +1 -1
- package/dist/lib/ui/primitives/Input/Input.js +2 -2
- package/dist/lib/ui/primitives/JsonViewer/JsonEditor.cjs +2 -0
- package/dist/lib/ui/primitives/JsonViewer/JsonEditor.cjs.map +1 -0
- package/dist/lib/ui/primitives/JsonViewer/JsonEditor.js +95 -0
- package/dist/lib/ui/primitives/JsonViewer/JsonEditor.js.map +1 -0
- package/dist/lib/ui/primitives/JsonViewer/JsonViewer.cjs +1 -1
- package/dist/lib/ui/primitives/JsonViewer/JsonViewer.cjs.map +1 -1
- package/dist/lib/ui/primitives/JsonViewer/JsonViewer.js +37 -88
- package/dist/lib/ui/primitives/JsonViewer/JsonViewer.js.map +1 -1
- package/dist/lib/ui/primitives/JsonViewer/json-code-mirror.cjs +2 -0
- package/dist/lib/ui/primitives/JsonViewer/json-code-mirror.cjs.map +1 -0
- package/dist/lib/ui/primitives/JsonViewer/json-code-mirror.js +64 -0
- package/dist/lib/ui/primitives/JsonViewer/json-code-mirror.js.map +1 -0
- package/dist/lib/ui/primitives/Link/Link.cjs +1 -1
- package/dist/lib/ui/primitives/Link/Link.js +3 -3
- package/dist/lib/ui/primitives/Menu/Menu.cjs +1 -1
- package/dist/lib/ui/primitives/Menu/Menu.cjs.map +1 -1
- package/dist/lib/ui/primitives/Menu/Menu.js +65 -45
- package/dist/lib/ui/primitives/Menu/Menu.js.map +1 -1
- package/dist/lib/ui/primitives/PermissionGate/PermissionGate.cjs.map +1 -1
- package/dist/lib/ui/primitives/PermissionGate/PermissionGate.js.map +1 -1
- package/dist/lib/ui/primitives/Search/Search.cjs +1 -1
- package/dist/lib/ui/primitives/Search/Search.js +8 -8
- package/dist/lib/ui/primitives/Select/MultiSelect.cjs +2 -0
- package/dist/lib/ui/primitives/Select/MultiSelect.cjs.map +1 -0
- package/dist/lib/ui/primitives/Select/MultiSelect.js +113 -0
- package/dist/lib/ui/primitives/Select/MultiSelect.js.map +1 -0
- package/dist/lib/ui/primitives/Select/Select.cjs +1 -1
- package/dist/lib/ui/primitives/Select/Select.cjs.map +1 -1
- package/dist/lib/ui/primitives/Select/Select.js +19 -12
- package/dist/lib/ui/primitives/Select/Select.js.map +1 -1
- package/dist/lib/vendor/@monaco-editor/react/dist/index.cjs +1 -1
- package/dist/lib/vendor/@monaco-editor/react/dist/index.cjs.map +1 -1
- package/dist/lib/vendor/@monaco-editor/react/dist/index.js +21 -21
- package/dist/lib/vendor/@react-aria/interactions/dist/useFocusable.cjs +1 -1
- package/dist/lib/vendor/@react-aria/interactions/dist/useFocusable.js +4 -4
- package/dist/lib/vendor/@react-aria/ssr/dist/SSRProvider.js.map +1 -1
- package/dist/lib/vendor/@react-stately/utils/dist/useControlledState.cjs +1 -1
- package/dist/lib/vendor/react-draggable/build/cjs/Draggable.cjs +2 -2
- package/dist/lib/vendor/react-draggable/build/cjs/Draggable.js +8 -8
- package/dist/lib/vendor/react-grid-layout/build/GridItem.cjs +1 -1
- package/dist/lib/vendor/react-grid-layout/build/ReactGridLayout.cjs +1 -1
- package/dist/lib/vendor/react-grid-layout/build/ReactGridLayout.js +6 -6
- package/dist/lib/vendor/react-grid-layout/build/ReactGridLayout.js.map +1 -1
- package/dist/lib/vendor/react-grid-layout/build/ReactGridLayoutPropTypes.js +2 -2
- package/dist/lib/vendor/react-grid-layout/build/ResponsiveReactGridLayout.cjs +1 -1
- package/dist/lib/vendor/react-grid-layout/build/ResponsiveReactGridLayout.js.map +1 -1
- package/dist/lib/vendor/react-grid-layout/build/components/WidthProvider.cjs +1 -1
- package/dist/lib/vendor/react-grid-layout/build/components/WidthProvider.js +6 -6
- package/dist/lib/vendor/react-grid-layout/build/components/WidthProvider.js.map +1 -1
- package/dist/lib/vendor/react-grid-layout/build/utils.cjs +1 -1
- package/dist/lib/vendor/react-grid-layout/build/utils.js +27 -27
- package/dist/lib/vendor/react-resizable/build/Resizable.cjs +1 -1
- package/dist/lib/vendor/react-resizable/build/Resizable.js +17 -17
- package/dist/lib/vendor/react-resizable/build/Resizable.js.map +1 -1
- package/dist/lib/vendor/react-resizable/build/ResizableBox.cjs +1 -1
- package/dist/lib/vendor/react-resizable/build/ResizableBox.js +5 -5
- package/dist/lib/vendor/react-resizable/build/ResizableBox.js.map +1 -1
- package/dist/lib/vendor/react-resizable/build/utils.cjs +1 -1
- package/dist/lib/vendor/react-resizable/build/utils.cjs.map +1 -1
- package/dist/lib/vendor/react-resizable/build/utils.js +2 -2
- package/dist/lib/vendor/react-toastify/dist/index.cjs +1 -1
- package/dist/lib/vendor/react-toastify/dist/index.js +10 -10
- package/dist/types/json-viewer.index.d.ts +1 -0
- package/dist/types/ui/primitives/JsonViewer/JsonEditor.d.ts +18 -0
- package/dist/types/ui/primitives/JsonViewer/json-code-mirror.d.ts +17 -0
- package/dist/types/ui/primitives/Menu/Menu.d.ts +1 -1
- package/dist/types/ui/primitives/PermissionGate/PermissionGate.d.ts +20 -0
- package/dist/types/ui/primitives/Select/MultiSelect.d.ts +15 -0
- package/dist/types/ui/primitives/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),s=require("react"),R=require("../../../vendor/clsx/dist/clsx.cjs"),x=require("@codemirror/state"),g=require("@codemirror/view"),w=require("@codemirror/language"),o=require("./json-code-mirror.cjs");;/* empty css */const b=require("../../icons/IconChevronDown.cjs"),y=require("../../icons/IconChevronRight.cjs"),j=require("../Button/Button.cjs"),S=220;function f(i,c){c.length>0&&i.dispatch({effects:c.map(r=>w.foldEffect.of(r))})}function z({value:i,expandAllLabel:c,actions:r,className:m,height:E}){const u=s.useRef(null),l=s.useRef(null),[d,h]=s.useState(!1),n=s.useMemo(()=>o.serializeJson(i),[i]),a=s.useMemo(()=>o.computeFirstLevelFoldRanges(n),[n]),p=o.toCssSize(E??S);s.useEffect(()=>{if(!u.current)return;const e=new g.EditorView({parent:u.current,state:x.EditorState.create({doc:n,extensions:[g.EditorView.editable.of(!1),x.EditorState.readOnly.of(!0),o.jsonEditorTheme,...o.jsonEditorExtensions]})});return l.current=e,f(e,a),()=>{e.destroy(),l.current=null}},[]),s.useEffect(()=>{const e=l.current;if(!e)return;const v=e.state.doc.toString();v!==n&&(e.dispatch({changes:{from:0,to:v.length,insert:n}}),f(e,a),h(!1))},[n,a]);const q=()=>{const e=l.current;e&&(d?f(e,a):w.unfoldAll(e),h(!d))};return t.jsxs("div",{className:R.clsx("json-viewer",m),children:[t.jsx(j.Button,{"aria-label":c,variant:"subtle",size:"small",className:"json-viewer-expand-all",onPress:q,children:d?t.jsx(b.IconChevronDown,{size:"14"}):t.jsx(y.IconChevronRight,{size:"14"})}),r&&r.length>0&&t.jsx("div",{className:"json-viewer-actions",children:r.map(e=>t.jsx(j.Button,{"aria-label":e.label,variant:"subtle",size:"small",className:"json-viewer-action",onPress:e.onPress,children:e.icon},e.key))}),t.jsx("div",{ref:u,className:"json-viewer-content",style:{height:p}})]})}exports.JsonViewer=z;
|
|
2
2
|
//# sourceMappingURL=JsonViewer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonViewer.cjs","sources":["../../../../../src/ui/primitives/JsonViewer/JsonViewer.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { EditorState } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { json } from \"@codemirror/lang-json\";\nimport { foldEffect, foldGutter, HighlightStyle, syntaxHighlighting, unfoldAll } from \"@codemirror/language\";\nimport { tags as t } from \"@lezer/highlight\";\nimport { Button } from \"primitives\";\nimport { IconChevronDown, IconChevronRight } from \"icons\";\nimport \"./jsonviewer.css\";\n\nexport interface JsonViewerAction {\n key: string;\n label: string;\n icon: ReactNode;\n onPress: () => void;\n}\n\nexport interface JsonViewerProps {\n value: unknown;\n expandAllLabel: string;\n actions?: JsonViewerAction[];\n className?: string;\n height?: string | number;\n}\n\nconst DEFAULT_HEIGHT = 220;\n\nconst jsonHighlightStyle = HighlightStyle.define([\n { tag: t.propertyName, color: \"var(--json-viewer-color-key)\" },\n { tag: t.string, color: \"var(--json-viewer-color-string)\", fontWeight: 600 },\n { tag: [t.number, t.bool, t.null], color: \"var(--json-viewer-color-scalar)\" },\n { tag: [t.separator, t.squareBracket, t.brace], color: \"var(--json-viewer-color-punctuation)\" },\n]);\n\nconst theme = EditorView.theme({\n \"&\": { backgroundColor: \"transparent\", color: \"var(--json-viewer-color-punctuation)\", fontSize: \"13px\" },\n \"&.cm-focused\": { outline: \"none\" },\n \".cm-content\": { fontFamily: \"var(--sds-typography-family-mono)\", padding: \"45px 124px 12px 4px\" },\n \".cm-gutters\": {\n backgroundColor: \"transparent\",\n border: \"none\",\n color: \"var(--json-viewer-color-caret)\",\n paddingLeft: \"5px\",\n },\n \".cm-scroller\": { overflow: \"auto\" },\n});\n\nconst extensions = [json(), foldGutter(), syntaxHighlighting(jsonHighlightStyle)];\n\nfunction serialize(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2) ?? \"null\";\n } catch {\n return String(value);\n }\n}\n\nfunction toCssSize(size: string | number): string {\n return typeof size === \"number\" ? `${size}px` : size;\n}\n\nfunction applyFoldRanges(view: EditorView, ranges: { from: number; to: number }[]) {\n if (ranges.length > 0) view.dispatch({ effects: ranges.map((range) => foldEffect.of(range)) });\n}\n\n/**\n * Finds the fold range of every direct child (depth 1) of the root object/array\n * by scanning the text itself for matching brackets. This mirrors what\n * CodeMirror's `foldable()` would compute, but doesn't depend on the lezer\n * parser having finished tokenizing the document — which for a multi-MB\n * document is not guaranteed synchronously at mount time.\n */\nfunction computeFirstLevelFoldRanges(text: string): { from: number; to: number }[] {\n const ranges: { from: number; to: number }[] = [];\n const n = text.length;\n let i = 0;\n while (i < n && text[i] !== \"{\" && text[i] !== \"[\") i++;\n if (i >= n) return ranges;\n\n let depth = 0;\n let inString = false;\n let pendingStart = -1;\n for (; i < n; i++) {\n const ch = text[i];\n if (inString) {\n if (ch === \"\\\\\") i++;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === \"{\" || ch === \"[\") {\n depth++;\n if (depth === 2) pendingStart = i + 1;\n continue;\n }\n if (ch === \"}\" || ch === \"]\") {\n if (depth === 2 && pendingStart !== -1) {\n ranges.push({ from: pendingStart, to: i });\n pendingStart = -1;\n }\n depth--;\n }\n }\n return ranges;\n}\n\nexport function JsonViewer({ value, expandAllLabel, actions, className, height }: JsonViewerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const text = useMemo(() => serialize(value), [value]);\n const foldRanges = useMemo(() => computeFirstLevelFoldRanges(text), [text]);\n const editorHeight = toCssSize(height ?? DEFAULT_HEIGHT);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const view = new EditorView({\n parent: containerRef.current,\n state: EditorState.create({\n doc: text,\n extensions: [EditorView.editable.of(false), EditorState.readOnly.of(true), theme, ...extensions],\n }),\n });\n viewRef.current = view;\n applyFoldRanges(view, foldRanges);\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n const view = viewRef.current;\n if (!view) return;\n const currentText = view.state.doc.toString();\n if (currentText !== text) {\n view.dispatch({ changes: { from: 0, to: currentText.length, insert: text } });\n applyFoldRanges(view, foldRanges);\n setIsExpanded(false);\n }\n }, [text, foldRanges]);\n\n const toggleExpandAll = () => {\n const view = viewRef.current;\n if (!view) return;\n if (isExpanded) {\n applyFoldRanges(view, foldRanges);\n } else {\n unfoldAll(view);\n }\n setIsExpanded(!isExpanded);\n };\n\n return (\n <div className={clsx(\"json-viewer\", className)}>\n <Button\n aria-label={expandAllLabel}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-expand-all\"\n onPress={toggleExpandAll}\n >\n {isExpanded ? <IconChevronDown size=\"14\" /> : <IconChevronRight size=\"14\" />}\n </Button>\n {actions && actions.length > 0 && (\n <div className=\"json-viewer-actions\">\n {actions.map((action) => (\n <Button\n key={action.key}\n aria-label={action.label}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-action\"\n onPress={action.onPress}\n >\n {action.icon}\n </Button>\n ))}\n </div>\n )}\n <div ref={containerRef} className=\"json-viewer-content\" style={{ height: editorHeight }} />\n </div>\n );\n}\n"],"names":["DEFAULT_HEIGHT","jsonHighlightStyle","HighlightStyle","t","theme","EditorView","extensions","json","foldGutter","syntaxHighlighting","serialize","value","toCssSize","size","applyFoldRanges","view","ranges","range","foldEffect","computeFirstLevelFoldRanges","text","n","i","depth","inString","pendingStart","ch","JsonViewer","expandAllLabel","actions","className","height","containerRef","useRef","viewRef","isExpanded","setIsExpanded","useState","useMemo","foldRanges","editorHeight","useEffect","EditorState","currentText","toggleExpandAll","unfoldAll","clsx","jsx","Button","IconChevronDown","IconChevronRight","action"],"mappings":"2fA2BMA,EAAiB,IAEjBC,EAAqBC,EAAAA,eAAe,OAAO,CAC/C,CAAE,IAAKC,EAAAA,KAAE,aAAc,MAAO,8BAAA,EAC9B,CAAE,IAAKA,EAAAA,KAAE,OAAQ,MAAO,kCAAmC,WAAY,GAAA,EACvE,CAAE,IAAK,CAACA,OAAE,OAAQA,EAAAA,KAAE,KAAMA,EAAAA,KAAE,IAAI,EAAG,MAAO,iCAAA,EAC1C,CAAE,IAAK,CAACA,EAAAA,KAAE,UAAWA,EAAAA,KAAE,cAAeA,OAAE,KAAK,EAAG,MAAO,sCAAA,CACzD,CAAC,EAEKC,EAAQC,EAAAA,WAAW,MAAM,CAC7B,IAAK,CAAE,gBAAiB,cAAe,MAAO,uCAAwC,SAAU,MAAA,EAChG,eAAgB,CAAE,QAAS,MAAA,EAC3B,cAAe,CAAE,WAAY,oCAAqC,QAAS,qBAAA,EAC3E,cAAe,CACb,gBAAiB,cACjB,OAAQ,OACR,MAAO,iCACP,YAAa,KAAA,EAEf,eAAgB,CAAE,SAAU,MAAA,CAC9B,CAAC,EAEKC,EAAa,CAACC,EAAAA,KAAA,EAAQC,EAAAA,aAAcC,EAAAA,mBAAmBR,CAAkB,CAAC,EAEhF,SAASS,EAAUC,EAAwB,CACzC,GAAI,CACF,OAAO,KAAK,UAAUA,EAAO,KAAM,CAAC,GAAK,MAC3C,MAAQ,CACN,OAAO,OAAOA,CAAK,CACrB,CACF,CAEA,SAASC,EAAUC,EAA+B,CAChD,OAAO,OAAOA,GAAS,SAAW,GAAGA,CAAI,KAAOA,CAClD,CAEA,SAASC,EAAgBC,EAAkBC,EAAwC,CAC7EA,EAAO,OAAS,GAAGD,EAAK,SAAS,CAAE,QAASC,EAAO,IAAKC,GAAUC,EAAAA,WAAW,GAAGD,CAAK,CAAC,EAAG,CAC/F,CASA,SAASE,EAA4BC,EAA8C,CACjF,MAAMJ,EAAyC,CAAA,EACzCK,EAAID,EAAK,OACf,IAAIE,EAAI,EACR,KAAOA,EAAID,GAAKD,EAAKE,CAAC,IAAM,KAAOF,EAAKE,CAAC,IAAM,KAAKA,IACpD,GAAIA,GAAKD,EAAG,OAAOL,EAEnB,IAAIO,EAAQ,EACRC,EAAW,GACXC,EAAe,GACnB,KAAOH,EAAID,EAAGC,IAAK,CACjB,MAAMI,EAAKN,EAAKE,CAAC,EACjB,GAAIE,EAAU,CACRE,IAAO,KAAMJ,IACRI,IAAO,MAAKF,EAAW,IAChC,QACF,CACA,GAAIE,IAAO,IAAK,CACdF,EAAW,GACX,QACF,CACA,GAAIE,IAAO,KAAOA,IAAO,IAAK,CAC5BH,IACIA,IAAU,IAAGE,EAAeH,EAAI,GACpC,QACF,EACII,IAAO,KAAOA,IAAO,OACnBH,IAAU,GAAKE,IAAiB,KAClCT,EAAO,KAAK,CAAE,KAAMS,EAAc,GAAIH,EAAG,EACzCG,EAAe,IAEjBF,IAEJ,CACA,OAAOP,CACT,CAEO,SAASW,EAAW,CAAE,MAAAhB,EAAO,eAAAiB,EAAgB,QAAAC,EAAS,UAAAC,EAAW,OAAAC,GAA2B,CACjG,MAAMC,EAAeC,EAAAA,OAAuB,IAAI,EAC1CC,EAAUD,EAAAA,OAA0B,IAAI,EACxC,CAACE,EAAYC,CAAa,EAAIC,EAAAA,SAAS,EAAK,EAC5CjB,EAAOkB,EAAAA,QAAQ,IAAM5B,EAAUC,CAAK,EAAG,CAACA,CAAK,CAAC,EAC9C4B,EAAaD,EAAAA,QAAQ,IAAMnB,EAA4BC,CAAI,EAAG,CAACA,CAAI,CAAC,EACpEoB,EAAe5B,EAAUmB,GAAU/B,CAAc,EAEvDyC,EAAAA,UAAU,IAAM,CACd,GAAI,CAACT,EAAa,QAAS,OAC3B,MAAMjB,EAAO,IAAIV,aAAW,CAC1B,OAAQ2B,EAAa,QACrB,MAAOU,EAAAA,YAAY,OAAO,CACxB,IAAKtB,EACL,WAAY,CAACf,EAAAA,WAAW,SAAS,GAAG,EAAK,EAAGqC,cAAY,SAAS,GAAG,EAAI,EAAGtC,EAAO,GAAGE,CAAU,CAAA,CAChG,CAAA,CACF,EACD,OAAA4B,EAAQ,QAAUnB,EAClBD,EAAgBC,EAAMwB,CAAU,EACzB,IAAM,CACXxB,EAAK,QAAA,EACLmB,EAAQ,QAAU,IACpB,CAEF,EAAG,CAAA,CAAE,EAELO,EAAAA,UAAU,IAAM,CACd,MAAM1B,EAAOmB,EAAQ,QACrB,GAAI,CAACnB,EAAM,OACX,MAAM4B,EAAc5B,EAAK,MAAM,IAAI,SAAA,EAC/B4B,IAAgBvB,IAClBL,EAAK,SAAS,CAAE,QAAS,CAAE,KAAM,EAAG,GAAI4B,EAAY,OAAQ,OAAQvB,CAAA,CAAK,CAAG,EAC5EN,EAAgBC,EAAMwB,CAAU,EAChCH,EAAc,EAAK,EAEvB,EAAG,CAAChB,EAAMmB,CAAU,CAAC,EAErB,MAAMK,EAAkB,IAAM,CAC5B,MAAM7B,EAAOmB,EAAQ,QAChBnB,IACDoB,EACFrB,EAAgBC,EAAMwB,CAAU,EAEhCM,EAAAA,UAAU9B,CAAI,EAEhBqB,EAAc,CAACD,CAAU,EAC3B,EAEA,cACG,MAAA,CAAI,UAAWW,EAAAA,KAAK,cAAehB,CAAS,EAC3C,SAAA,CAAAiB,EAAAA,IAACC,EAAAA,OAAA,CACC,aAAYpB,EACZ,QAAQ,SACR,KAAK,QACL,UAAU,yBACV,QAASgB,EAER,SAAAT,QAAcc,EAAAA,gBAAA,CAAgB,KAAK,KAAK,EAAKF,EAAAA,IAACG,EAAAA,iBAAA,CAAiB,KAAK,IAAA,CAAK,CAAA,CAAA,EAE3ErB,GAAWA,EAAQ,OAAS,GAC3BkB,EAAAA,IAAC,MAAA,CAAI,UAAU,sBACZ,SAAAlB,EAAQ,IAAKsB,GACZJ,EAAAA,IAACC,EAAAA,OAAA,CAEC,aAAYG,EAAO,MACnB,QAAQ,SACR,KAAK,QACL,UAAU,qBACV,QAASA,EAAO,QAEf,SAAAA,EAAO,IAAA,EAPHA,EAAO,GAAA,CASf,EACH,EAEFJ,EAAAA,IAAC,MAAA,CAAI,IAAKf,EAAc,UAAU,sBAAsB,MAAO,CAAE,OAAQQ,EAAa,CAAG,CAAA,EAC3F,CAEJ"}
|
|
1
|
+
{"version":3,"file":"JsonViewer.cjs","sources":["../../../../../src/ui/primitives/JsonViewer/JsonViewer.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { EditorState } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { foldEffect, unfoldAll } from \"@codemirror/language\";\nimport { Button } from \"primitives\";\nimport { IconChevronDown, IconChevronRight } from \"icons\";\nimport {\n computeFirstLevelFoldRanges,\n jsonEditorExtensions,\n jsonEditorTheme,\n serializeJson,\n toCssSize,\n} from \"./json-code-mirror\";\nimport \"./jsonviewer.css\";\n\nexport interface JsonViewerAction {\n key: string;\n label: string;\n icon: ReactNode;\n onPress: () => void;\n}\n\nexport interface JsonViewerProps {\n value: unknown;\n expandAllLabel: string;\n actions?: JsonViewerAction[];\n className?: string;\n height?: string | number;\n}\n\nconst DEFAULT_HEIGHT = 220;\n\nfunction applyFoldRanges(view: EditorView, ranges: { from: number; to: number }[]) {\n if (ranges.length > 0) view.dispatch({ effects: ranges.map((range) => foldEffect.of(range)) });\n}\n\nexport function JsonViewer({ value, expandAllLabel, actions, className, height }: JsonViewerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const text = useMemo(() => serializeJson(value), [value]);\n const foldRanges = useMemo(() => computeFirstLevelFoldRanges(text), [text]);\n const editorHeight = toCssSize(height ?? DEFAULT_HEIGHT);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const view = new EditorView({\n parent: containerRef.current,\n state: EditorState.create({\n doc: text,\n extensions: [EditorView.editable.of(false), EditorState.readOnly.of(true), jsonEditorTheme, ...jsonEditorExtensions],\n }),\n });\n viewRef.current = view;\n applyFoldRanges(view, foldRanges);\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n const view = viewRef.current;\n if (!view) return;\n const currentText = view.state.doc.toString();\n if (currentText !== text) {\n view.dispatch({ changes: { from: 0, to: currentText.length, insert: text } });\n applyFoldRanges(view, foldRanges);\n setIsExpanded(false);\n }\n }, [text, foldRanges]);\n\n const toggleExpandAll = () => {\n const view = viewRef.current;\n if (!view) return;\n if (isExpanded) {\n applyFoldRanges(view, foldRanges);\n } else {\n unfoldAll(view);\n }\n setIsExpanded(!isExpanded);\n };\n\n return (\n <div className={clsx(\"json-viewer\", className)}>\n <Button\n aria-label={expandAllLabel}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-expand-all\"\n onPress={toggleExpandAll}\n >\n {isExpanded ? <IconChevronDown size=\"14\" /> : <IconChevronRight size=\"14\" />}\n </Button>\n {actions && actions.length > 0 && (\n <div className=\"json-viewer-actions\">\n {actions.map((action) => (\n <Button\n key={action.key}\n aria-label={action.label}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-action\"\n onPress={action.onPress}\n >\n {action.icon}\n </Button>\n ))}\n </div>\n )}\n <div ref={containerRef} className=\"json-viewer-content\" style={{ height: editorHeight }} />\n </div>\n );\n}\n"],"names":["DEFAULT_HEIGHT","applyFoldRanges","view","ranges","range","foldEffect","JsonViewer","value","expandAllLabel","actions","className","height","containerRef","useRef","viewRef","isExpanded","setIsExpanded","useState","text","useMemo","serializeJson","foldRanges","computeFirstLevelFoldRanges","editorHeight","toCssSize","useEffect","EditorView","EditorState","jsonEditorTheme","jsonEditorExtensions","currentText","toggleExpandAll","unfoldAll","clsx","jsx","Button","IconChevronDown","IconChevronRight","action"],"mappings":"8dAgCMA,EAAiB,IAEvB,SAASC,EAAgBC,EAAkBC,EAAwC,CAC7EA,EAAO,OAAS,GAAGD,EAAK,SAAS,CAAE,QAASC,EAAO,IAAKC,GAAUC,EAAAA,WAAW,GAAGD,CAAK,CAAC,EAAG,CAC/F,CAEO,SAASE,EAAW,CAAE,MAAAC,EAAO,eAAAC,EAAgB,QAAAC,EAAS,UAAAC,EAAW,OAAAC,GAA2B,CACjG,MAAMC,EAAeC,EAAAA,OAAuB,IAAI,EAC1CC,EAAUD,EAAAA,OAA0B,IAAI,EACxC,CAACE,EAAYC,CAAa,EAAIC,EAAAA,SAAS,EAAK,EAC5CC,EAAOC,EAAAA,QAAQ,IAAMC,EAAAA,cAAcb,CAAK,EAAG,CAACA,CAAK,CAAC,EAClDc,EAAaF,EAAAA,QAAQ,IAAMG,EAAAA,4BAA4BJ,CAAI,EAAG,CAACA,CAAI,CAAC,EACpEK,EAAeC,EAAAA,UAAUb,GAAUX,CAAc,EAEvDyB,EAAAA,UAAU,IAAM,CACd,GAAI,CAACb,EAAa,QAAS,OAC3B,MAAMV,EAAO,IAAIwB,aAAW,CAC1B,OAAQd,EAAa,QACrB,MAAOe,EAAAA,YAAY,OAAO,CACxB,IAAKT,EACL,WAAY,CAACQ,EAAAA,WAAW,SAAS,GAAG,EAAK,EAAGC,cAAY,SAAS,GAAG,EAAI,EAAGC,EAAAA,gBAAiB,GAAGC,EAAAA,oBAAoB,CAAA,CACpH,CAAA,CACF,EACD,OAAAf,EAAQ,QAAUZ,EAClBD,EAAgBC,EAAMmB,CAAU,EACzB,IAAM,CACXnB,EAAK,QAAA,EACLY,EAAQ,QAAU,IACpB,CAEF,EAAG,CAAA,CAAE,EAELW,EAAAA,UAAU,IAAM,CACd,MAAMvB,EAAOY,EAAQ,QACrB,GAAI,CAACZ,EAAM,OACX,MAAM4B,EAAc5B,EAAK,MAAM,IAAI,SAAA,EAC/B4B,IAAgBZ,IAClBhB,EAAK,SAAS,CAAE,QAAS,CAAE,KAAM,EAAG,GAAI4B,EAAY,OAAQ,OAAQZ,CAAA,CAAK,CAAG,EAC5EjB,EAAgBC,EAAMmB,CAAU,EAChCL,EAAc,EAAK,EAEvB,EAAG,CAACE,EAAMG,CAAU,CAAC,EAErB,MAAMU,EAAkB,IAAM,CAC5B,MAAM7B,EAAOY,EAAQ,QAChBZ,IACDa,EACFd,EAAgBC,EAAMmB,CAAU,EAEhCW,EAAAA,UAAU9B,CAAI,EAEhBc,EAAc,CAACD,CAAU,EAC3B,EAEA,cACG,MAAA,CAAI,UAAWkB,EAAAA,KAAK,cAAevB,CAAS,EAC3C,SAAA,CAAAwB,EAAAA,IAACC,EAAAA,OAAA,CACC,aAAY3B,EACZ,QAAQ,SACR,KAAK,QACL,UAAU,yBACV,QAASuB,EAER,SAAAhB,QAAcqB,EAAAA,gBAAA,CAAgB,KAAK,KAAK,EAAKF,EAAAA,IAACG,EAAAA,iBAAA,CAAiB,KAAK,IAAA,CAAK,CAAA,CAAA,EAE3E5B,GAAWA,EAAQ,OAAS,GAC3ByB,EAAAA,IAAC,MAAA,CAAI,UAAU,sBACZ,SAAAzB,EAAQ,IAAK6B,GACZJ,EAAAA,IAACC,EAAAA,OAAA,CAEC,aAAYG,EAAO,MACnB,QAAQ,SACR,KAAK,QACL,UAAU,qBACV,QAASA,EAAO,QAEf,SAAAA,EAAO,IAAA,EAPHA,EAAO,GAAA,CASf,EACH,EAEFJ,EAAAA,IAAC,MAAA,CAAI,IAAKtB,EAAc,UAAU,sBAAsB,MAAO,CAAE,OAAQW,EAAa,CAAG,CAAA,EAC3F,CAEJ"}
|
|
@@ -1,107 +1,56 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useRef as
|
|
3
|
-
import { clsx as
|
|
4
|
-
import { EditorState as
|
|
5
|
-
import { EditorView as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { tags as l } from "@lezer/highlight";
|
|
1
|
+
import { jsxs as b, jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as u, useState as z, useMemo as p, useEffect as h } from "react";
|
|
3
|
+
import { clsx as y } from "../../../vendor/clsx/dist/clsx.js";
|
|
4
|
+
import { EditorState as v } from "@codemirror/state";
|
|
5
|
+
import { EditorView as w } from "@codemirror/view";
|
|
6
|
+
import { foldEffect as N, unfoldAll as F } from "@codemirror/language";
|
|
7
|
+
import { serializeJson as I, computeFirstLevelFoldRanges as S, jsonEditorTheme as T, jsonEditorExtensions as A, toCssSize as C } from "./json-code-mirror.js";
|
|
9
8
|
/* empty css */
|
|
10
|
-
import { IconChevronDown as
|
|
11
|
-
import { IconChevronRight as
|
|
12
|
-
import { Button as
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{ tag: [l.number, l.bool, l.null], color: "var(--json-viewer-color-scalar)" },
|
|
17
|
-
{ tag: [l.separator, l.squareBracket, l.brace], color: "var(--json-viewer-color-punctuation)" }
|
|
18
|
-
]), B = d.theme({
|
|
19
|
-
"&": { backgroundColor: "transparent", color: "var(--json-viewer-color-punctuation)", fontSize: "13px" },
|
|
20
|
-
"&.cm-focused": { outline: "none" },
|
|
21
|
-
".cm-content": { fontFamily: "var(--sds-typography-family-mono)", padding: "45px 124px 12px 4px" },
|
|
22
|
-
".cm-gutters": {
|
|
23
|
-
backgroundColor: "transparent",
|
|
24
|
-
border: "none",
|
|
25
|
-
color: "var(--json-viewer-color-caret)",
|
|
26
|
-
paddingLeft: "5px"
|
|
27
|
-
},
|
|
28
|
-
".cm-scroller": { overflow: "auto" }
|
|
29
|
-
}), D = [H(), k(), z(T)];
|
|
30
|
-
function G(t) {
|
|
31
|
-
try {
|
|
32
|
-
return JSON.stringify(t, null, 2) ?? "null";
|
|
33
|
-
} catch {
|
|
34
|
-
return String(t);
|
|
35
|
-
}
|
|
9
|
+
import { IconChevronDown as H } from "../../icons/IconChevronDown.js";
|
|
10
|
+
import { IconChevronRight as P } from "../../icons/IconChevronRight.js";
|
|
11
|
+
import { Button as g } from "../Button/Button.js";
|
|
12
|
+
const D = 220;
|
|
13
|
+
function f(s, n) {
|
|
14
|
+
n.length > 0 && s.dispatch({ effects: n.map((o) => N.of(o)) });
|
|
36
15
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
function p(t, s) {
|
|
41
|
-
s.length > 0 && t.dispatch({ effects: s.map((n) => F.of(n)) });
|
|
42
|
-
}
|
|
43
|
-
function O(t) {
|
|
44
|
-
const s = [], n = t.length;
|
|
45
|
-
let r = 0;
|
|
46
|
-
for (; r < n && t[r] !== "{" && t[r] !== "["; ) r++;
|
|
47
|
-
if (r >= n) return s;
|
|
48
|
-
let c = 0, a = !1, i = -1;
|
|
49
|
-
for (; r < n; r++) {
|
|
50
|
-
const o = t[r];
|
|
51
|
-
if (a) {
|
|
52
|
-
o === "\\" ? r++ : o === '"' && (a = !1);
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (o === '"') {
|
|
56
|
-
a = !0;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (o === "{" || o === "[") {
|
|
60
|
-
c++, c === 2 && (i = r + 1);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
(o === "}" || o === "]") && (c === 2 && i !== -1 && (s.push({ from: i, to: r }), i = -1), c--);
|
|
64
|
-
}
|
|
65
|
-
return s;
|
|
66
|
-
}
|
|
67
|
-
function ee({ value: t, expandAllLabel: s, actions: n, className: r, height: c }) {
|
|
68
|
-
const a = v(null), i = v(null), [o, g] = N(!1), f = w(() => G(t), [t]), m = w(() => O(f), [f]), b = J(c ?? P);
|
|
69
|
-
x(() => {
|
|
16
|
+
function K({ value: s, expandAllLabel: n, actions: o, className: x, height: E }) {
|
|
17
|
+
const a = u(null), i = u(null), [c, m] = z(!1), t = p(() => I(s), [s]), l = p(() => S(t), [t]), j = C(E ?? D);
|
|
18
|
+
h(() => {
|
|
70
19
|
if (!a.current) return;
|
|
71
|
-
const e = new
|
|
20
|
+
const e = new w({
|
|
72
21
|
parent: a.current,
|
|
73
|
-
state:
|
|
74
|
-
doc:
|
|
75
|
-
extensions: [
|
|
22
|
+
state: v.create({
|
|
23
|
+
doc: t,
|
|
24
|
+
extensions: [w.editable.of(!1), v.readOnly.of(!0), T, ...A]
|
|
76
25
|
})
|
|
77
26
|
});
|
|
78
|
-
return i.current = e,
|
|
27
|
+
return i.current = e, f(e, l), () => {
|
|
79
28
|
e.destroy(), i.current = null;
|
|
80
29
|
};
|
|
81
|
-
}, []),
|
|
30
|
+
}, []), h(() => {
|
|
82
31
|
const e = i.current;
|
|
83
32
|
if (!e) return;
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
}, [
|
|
87
|
-
const
|
|
33
|
+
const d = e.state.doc.toString();
|
|
34
|
+
d !== t && (e.dispatch({ changes: { from: 0, to: d.length, insert: t } }), f(e, l), m(!1));
|
|
35
|
+
}, [t, l]);
|
|
36
|
+
const R = () => {
|
|
88
37
|
const e = i.current;
|
|
89
|
-
e && (
|
|
38
|
+
e && (c ? f(e, l) : F(e), m(!c));
|
|
90
39
|
};
|
|
91
|
-
return /* @__PURE__ */
|
|
92
|
-
/* @__PURE__ */
|
|
93
|
-
|
|
40
|
+
return /* @__PURE__ */ b("div", { className: y("json-viewer", x), children: [
|
|
41
|
+
/* @__PURE__ */ r(
|
|
42
|
+
g,
|
|
94
43
|
{
|
|
95
|
-
"aria-label":
|
|
44
|
+
"aria-label": n,
|
|
96
45
|
variant: "subtle",
|
|
97
46
|
size: "small",
|
|
98
47
|
className: "json-viewer-expand-all",
|
|
99
|
-
onPress:
|
|
100
|
-
children:
|
|
48
|
+
onPress: R,
|
|
49
|
+
children: c ? /* @__PURE__ */ r(H, { size: "14" }) : /* @__PURE__ */ r(P, { size: "14" })
|
|
101
50
|
}
|
|
102
51
|
),
|
|
103
|
-
|
|
104
|
-
|
|
52
|
+
o && o.length > 0 && /* @__PURE__ */ r("div", { className: "json-viewer-actions", children: o.map((e) => /* @__PURE__ */ r(
|
|
53
|
+
g,
|
|
105
54
|
{
|
|
106
55
|
"aria-label": e.label,
|
|
107
56
|
variant: "subtle",
|
|
@@ -112,10 +61,10 @@ function ee({ value: t, expandAllLabel: s, actions: n, className: r, height: c }
|
|
|
112
61
|
},
|
|
113
62
|
e.key
|
|
114
63
|
)) }),
|
|
115
|
-
/* @__PURE__ */
|
|
64
|
+
/* @__PURE__ */ r("div", { ref: a, className: "json-viewer-content", style: { height: j } })
|
|
116
65
|
] });
|
|
117
66
|
}
|
|
118
67
|
export {
|
|
119
|
-
|
|
68
|
+
K as JsonViewer
|
|
120
69
|
};
|
|
121
70
|
//# sourceMappingURL=JsonViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonViewer.js","sources":["../../../../../src/ui/primitives/JsonViewer/JsonViewer.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { EditorState } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { json } from \"@codemirror/lang-json\";\nimport { foldEffect, foldGutter, HighlightStyle, syntaxHighlighting, unfoldAll } from \"@codemirror/language\";\nimport { tags as t } from \"@lezer/highlight\";\nimport { Button } from \"primitives\";\nimport { IconChevronDown, IconChevronRight } from \"icons\";\nimport \"./jsonviewer.css\";\n\nexport interface JsonViewerAction {\n key: string;\n label: string;\n icon: ReactNode;\n onPress: () => void;\n}\n\nexport interface JsonViewerProps {\n value: unknown;\n expandAllLabel: string;\n actions?: JsonViewerAction[];\n className?: string;\n height?: string | number;\n}\n\nconst DEFAULT_HEIGHT = 220;\n\nconst jsonHighlightStyle = HighlightStyle.define([\n { tag: t.propertyName, color: \"var(--json-viewer-color-key)\" },\n { tag: t.string, color: \"var(--json-viewer-color-string)\", fontWeight: 600 },\n { tag: [t.number, t.bool, t.null], color: \"var(--json-viewer-color-scalar)\" },\n { tag: [t.separator, t.squareBracket, t.brace], color: \"var(--json-viewer-color-punctuation)\" },\n]);\n\nconst theme = EditorView.theme({\n \"&\": { backgroundColor: \"transparent\", color: \"var(--json-viewer-color-punctuation)\", fontSize: \"13px\" },\n \"&.cm-focused\": { outline: \"none\" },\n \".cm-content\": { fontFamily: \"var(--sds-typography-family-mono)\", padding: \"45px 124px 12px 4px\" },\n \".cm-gutters\": {\n backgroundColor: \"transparent\",\n border: \"none\",\n color: \"var(--json-viewer-color-caret)\",\n paddingLeft: \"5px\",\n },\n \".cm-scroller\": { overflow: \"auto\" },\n});\n\nconst extensions = [json(), foldGutter(), syntaxHighlighting(jsonHighlightStyle)];\n\nfunction serialize(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2) ?? \"null\";\n } catch {\n return String(value);\n }\n}\n\nfunction toCssSize(size: string | number): string {\n return typeof size === \"number\" ? `${size}px` : size;\n}\n\nfunction applyFoldRanges(view: EditorView, ranges: { from: number; to: number }[]) {\n if (ranges.length > 0) view.dispatch({ effects: ranges.map((range) => foldEffect.of(range)) });\n}\n\n/**\n * Finds the fold range of every direct child (depth 1) of the root object/array\n * by scanning the text itself for matching brackets. This mirrors what\n * CodeMirror's `foldable()` would compute, but doesn't depend on the lezer\n * parser having finished tokenizing the document — which for a multi-MB\n * document is not guaranteed synchronously at mount time.\n */\nfunction computeFirstLevelFoldRanges(text: string): { from: number; to: number }[] {\n const ranges: { from: number; to: number }[] = [];\n const n = text.length;\n let i = 0;\n while (i < n && text[i] !== \"{\" && text[i] !== \"[\") i++;\n if (i >= n) return ranges;\n\n let depth = 0;\n let inString = false;\n let pendingStart = -1;\n for (; i < n; i++) {\n const ch = text[i];\n if (inString) {\n if (ch === \"\\\\\") i++;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === \"{\" || ch === \"[\") {\n depth++;\n if (depth === 2) pendingStart = i + 1;\n continue;\n }\n if (ch === \"}\" || ch === \"]\") {\n if (depth === 2 && pendingStart !== -1) {\n ranges.push({ from: pendingStart, to: i });\n pendingStart = -1;\n }\n depth--;\n }\n }\n return ranges;\n}\n\nexport function JsonViewer({ value, expandAllLabel, actions, className, height }: JsonViewerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const text = useMemo(() => serialize(value), [value]);\n const foldRanges = useMemo(() => computeFirstLevelFoldRanges(text), [text]);\n const editorHeight = toCssSize(height ?? DEFAULT_HEIGHT);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const view = new EditorView({\n parent: containerRef.current,\n state: EditorState.create({\n doc: text,\n extensions: [EditorView.editable.of(false), EditorState.readOnly.of(true), theme, ...extensions],\n }),\n });\n viewRef.current = view;\n applyFoldRanges(view, foldRanges);\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n const view = viewRef.current;\n if (!view) return;\n const currentText = view.state.doc.toString();\n if (currentText !== text) {\n view.dispatch({ changes: { from: 0, to: currentText.length, insert: text } });\n applyFoldRanges(view, foldRanges);\n setIsExpanded(false);\n }\n }, [text, foldRanges]);\n\n const toggleExpandAll = () => {\n const view = viewRef.current;\n if (!view) return;\n if (isExpanded) {\n applyFoldRanges(view, foldRanges);\n } else {\n unfoldAll(view);\n }\n setIsExpanded(!isExpanded);\n };\n\n return (\n <div className={clsx(\"json-viewer\", className)}>\n <Button\n aria-label={expandAllLabel}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-expand-all\"\n onPress={toggleExpandAll}\n >\n {isExpanded ? <IconChevronDown size=\"14\" /> : <IconChevronRight size=\"14\" />}\n </Button>\n {actions && actions.length > 0 && (\n <div className=\"json-viewer-actions\">\n {actions.map((action) => (\n <Button\n key={action.key}\n aria-label={action.label}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-action\"\n onPress={action.onPress}\n >\n {action.icon}\n </Button>\n ))}\n </div>\n )}\n <div ref={containerRef} className=\"json-viewer-content\" style={{ height: editorHeight }} />\n </div>\n );\n}\n"],"names":["DEFAULT_HEIGHT","jsonHighlightStyle","HighlightStyle","t","theme","EditorView","extensions","json","foldGutter","syntaxHighlighting","serialize","value","toCssSize","size","applyFoldRanges","view","ranges","range","foldEffect","computeFirstLevelFoldRanges","text","i","depth","inString","pendingStart","ch","JsonViewer","expandAllLabel","actions","className","height","containerRef","useRef","viewRef","isExpanded","setIsExpanded","useState","useMemo","foldRanges","editorHeight","useEffect","EditorState","currentText","toggleExpandAll","unfoldAll","clsx","jsx","Button","IconChevronDown","IconChevronRight","action"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JsonViewer.js","sources":["../../../../../src/ui/primitives/JsonViewer/JsonViewer.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { EditorState } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { foldEffect, unfoldAll } from \"@codemirror/language\";\nimport { Button } from \"primitives\";\nimport { IconChevronDown, IconChevronRight } from \"icons\";\nimport {\n computeFirstLevelFoldRanges,\n jsonEditorExtensions,\n jsonEditorTheme,\n serializeJson,\n toCssSize,\n} from \"./json-code-mirror\";\nimport \"./jsonviewer.css\";\n\nexport interface JsonViewerAction {\n key: string;\n label: string;\n icon: ReactNode;\n onPress: () => void;\n}\n\nexport interface JsonViewerProps {\n value: unknown;\n expandAllLabel: string;\n actions?: JsonViewerAction[];\n className?: string;\n height?: string | number;\n}\n\nconst DEFAULT_HEIGHT = 220;\n\nfunction applyFoldRanges(view: EditorView, ranges: { from: number; to: number }[]) {\n if (ranges.length > 0) view.dispatch({ effects: ranges.map((range) => foldEffect.of(range)) });\n}\n\nexport function JsonViewer({ value, expandAllLabel, actions, className, height }: JsonViewerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const text = useMemo(() => serializeJson(value), [value]);\n const foldRanges = useMemo(() => computeFirstLevelFoldRanges(text), [text]);\n const editorHeight = toCssSize(height ?? DEFAULT_HEIGHT);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const view = new EditorView({\n parent: containerRef.current,\n state: EditorState.create({\n doc: text,\n extensions: [EditorView.editable.of(false), EditorState.readOnly.of(true), jsonEditorTheme, ...jsonEditorExtensions],\n }),\n });\n viewRef.current = view;\n applyFoldRanges(view, foldRanges);\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n const view = viewRef.current;\n if (!view) return;\n const currentText = view.state.doc.toString();\n if (currentText !== text) {\n view.dispatch({ changes: { from: 0, to: currentText.length, insert: text } });\n applyFoldRanges(view, foldRanges);\n setIsExpanded(false);\n }\n }, [text, foldRanges]);\n\n const toggleExpandAll = () => {\n const view = viewRef.current;\n if (!view) return;\n if (isExpanded) {\n applyFoldRanges(view, foldRanges);\n } else {\n unfoldAll(view);\n }\n setIsExpanded(!isExpanded);\n };\n\n return (\n <div className={clsx(\"json-viewer\", className)}>\n <Button\n aria-label={expandAllLabel}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-expand-all\"\n onPress={toggleExpandAll}\n >\n {isExpanded ? <IconChevronDown size=\"14\" /> : <IconChevronRight size=\"14\" />}\n </Button>\n {actions && actions.length > 0 && (\n <div className=\"json-viewer-actions\">\n {actions.map((action) => (\n <Button\n key={action.key}\n aria-label={action.label}\n variant=\"subtle\"\n size=\"small\"\n className=\"json-viewer-action\"\n onPress={action.onPress}\n >\n {action.icon}\n </Button>\n ))}\n </div>\n )}\n <div ref={containerRef} className=\"json-viewer-content\" style={{ height: editorHeight }} />\n </div>\n );\n}\n"],"names":["DEFAULT_HEIGHT","applyFoldRanges","view","ranges","range","foldEffect","JsonViewer","value","expandAllLabel","actions","className","height","containerRef","useRef","viewRef","isExpanded","setIsExpanded","useState","text","useMemo","serializeJson","foldRanges","computeFirstLevelFoldRanges","editorHeight","toCssSize","useEffect","EditorView","EditorState","jsonEditorTheme","jsonEditorExtensions","currentText","toggleExpandAll","unfoldAll","clsx","jsx","Button","IconChevronDown","IconChevronRight","action"],"mappings":";;;;;;;;;;;AAgCA,MAAMA,IAAiB;AAEvB,SAASC,EAAgBC,GAAkBC,GAAwC;AACjF,EAAIA,EAAO,SAAS,KAAGD,EAAK,SAAS,EAAE,SAASC,EAAO,IAAI,CAACC,MAAUC,EAAW,GAAGD,CAAK,CAAC,GAAG;AAC/F;AAEO,SAASE,EAAW,EAAE,OAAAC,GAAO,gBAAAC,GAAgB,SAAAC,GAAS,WAAAC,GAAW,QAAAC,KAA2B;AACjG,QAAMC,IAAeC,EAAuB,IAAI,GAC1CC,IAAUD,EAA0B,IAAI,GACxC,CAACE,GAAYC,CAAa,IAAIC,EAAS,EAAK,GAC5CC,IAAOC,EAAQ,MAAMC,EAAcb,CAAK,GAAG,CAACA,CAAK,CAAC,GAClDc,IAAaF,EAAQ,MAAMG,EAA4BJ,CAAI,GAAG,CAACA,CAAI,CAAC,GACpEK,IAAeC,EAAUb,KAAUX,CAAc;AAEvD,EAAAyB,EAAU,MAAM;AACd,QAAI,CAACb,EAAa,QAAS;AAC3B,UAAMV,IAAO,IAAIwB,EAAW;AAAA,MAC1B,QAAQd,EAAa;AAAA,MACrB,OAAOe,EAAY,OAAO;AAAA,QACxB,KAAKT;AAAA,QACL,YAAY,CAACQ,EAAW,SAAS,GAAG,EAAK,GAAGC,EAAY,SAAS,GAAG,EAAI,GAAGC,GAAiB,GAAGC,CAAoB;AAAA,MAAA,CACpH;AAAA,IAAA,CACF;AACD,WAAAf,EAAQ,UAAUZ,GAClBD,EAAgBC,GAAMmB,CAAU,GACzB,MAAM;AACX,MAAAnB,EAAK,QAAA,GACLY,EAAQ,UAAU;AAAA,IACpB;AAAA,EAEF,GAAG,CAAA,CAAE,GAELW,EAAU,MAAM;AACd,UAAMvB,IAAOY,EAAQ;AACrB,QAAI,CAACZ,EAAM;AACX,UAAM4B,IAAc5B,EAAK,MAAM,IAAI,SAAA;AACnC,IAAI4B,MAAgBZ,MAClBhB,EAAK,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI4B,EAAY,QAAQ,QAAQZ,EAAA,EAAK,CAAG,GAC5EjB,EAAgBC,GAAMmB,CAAU,GAChCL,EAAc,EAAK;AAAA,EAEvB,GAAG,CAACE,GAAMG,CAAU,CAAC;AAErB,QAAMU,IAAkB,MAAM;AAC5B,UAAM7B,IAAOY,EAAQ;AACrB,IAAKZ,MACDa,IACFd,EAAgBC,GAAMmB,CAAU,IAEhCW,EAAU9B,CAAI,GAEhBc,EAAc,CAACD,CAAU;AAAA,EAC3B;AAEA,2BACG,OAAA,EAAI,WAAWkB,EAAK,eAAevB,CAAS,GAC3C,UAAA;AAAA,IAAA,gBAAAwB;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,cAAY3B;AAAA,QACZ,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAASuB;AAAA,QAER,UAAAhB,sBAAcqB,GAAA,EAAgB,MAAK,MAAK,IAAK,gBAAAF,EAACG,GAAA,EAAiB,MAAK,KAAA,CAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAE3E5B,KAAWA,EAAQ,SAAS,KAC3B,gBAAAyB,EAAC,OAAA,EAAI,WAAU,uBACZ,UAAAzB,EAAQ,IAAI,CAAC6B,MACZ,gBAAAJ;AAAA,MAACC;AAAA,MAAA;AAAA,QAEC,cAAYG,EAAO;AAAA,QACnB,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAASA,EAAO;AAAA,QAEf,UAAAA,EAAO;AAAA,MAAA;AAAA,MAPHA,EAAO;AAAA,IAAA,CASf,GACH;AAAA,IAEF,gBAAAJ,EAAC,OAAA,EAAI,KAAKtB,GAAc,WAAU,uBAAsB,OAAO,EAAE,QAAQW,IAAa,CAAG;AAAA,EAAA,GAC3F;AAEJ;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("@codemirror/view"),f=require("@codemirror/lang-json"),c=require("@codemirror/language"),e=require("@lezer/highlight"),g=c.HighlightStyle.define([{tag:e.tags.propertyName,color:"var(--json-viewer-color-key)"},{tag:e.tags.string,color:"var(--json-viewer-color-string)",fontWeight:600},{tag:[e.tags.number,e.tags.bool,e.tags.null],color:"var(--json-viewer-color-scalar)"},{tag:[e.tags.separator,e.tags.squareBracket,e.tags.brace],color:"var(--json-viewer-color-punctuation)"}]),p=u.EditorView.theme({"&":{backgroundColor:"transparent",color:"var(--json-viewer-color-punctuation)",fontSize:"13px"},"&.cm-focused":{outline:"none"},".cm-content":{fontFamily:"var(--sds-typography-family-mono)",padding:"45px 124px 12px 4px"},".cm-gutters":{backgroundColor:"transparent",border:"none",color:"var(--json-viewer-color-caret)",paddingLeft:"5px"},".cm-scroller":{overflow:"auto"}}),d=[f.json(),c.foldGutter(),c.syntaxHighlighting(g)];function h(o){try{return JSON.stringify(o,null,2)??"null"}catch{return String(o)}}function m(o){return typeof o=="number"?`${o}px`:o}function v(o){const s=[],a=o.length;let t=0;for(;t<a&&o[t]!=="{"&&o[t]!=="[";)t++;if(t>=a)return s;let r=0,l=!1,i=-1;for(;t<a;t++){const n=o[t];if(l){n==="\\"?t++:n==='"'&&(l=!1);continue}if(n==='"'){l=!0;continue}if(n==="{"||n==="["){r++,r===2&&(i=t+1);continue}(n==="}"||n==="]")&&(r===2&&i!==-1&&(s.push({from:i,to:t}),i=-1),r--)}return s}exports.computeFirstLevelFoldRanges=v;exports.jsonEditorExtensions=d;exports.jsonEditorTheme=p;exports.jsonHighlightStyle=g;exports.serializeJson=h;exports.toCssSize=m;
|
|
2
|
+
//# sourceMappingURL=json-code-mirror.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-code-mirror.cjs","sources":["../../../../../src/ui/primitives/JsonViewer/json-code-mirror.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\nimport { json } from \"@codemirror/lang-json\";\nimport { foldGutter, HighlightStyle, syntaxHighlighting } from \"@codemirror/language\";\nimport { tags as t } from \"@lezer/highlight\";\n\nexport const jsonHighlightStyle = HighlightStyle.define([\n { tag: t.propertyName, color: \"var(--json-viewer-color-key)\" },\n { tag: t.string, color: \"var(--json-viewer-color-string)\", fontWeight: 600 },\n { tag: [t.number, t.bool, t.null], color: \"var(--json-viewer-color-scalar)\" },\n { tag: [t.separator, t.squareBracket, t.brace], color: \"var(--json-viewer-color-punctuation)\" },\n]);\n\nexport const jsonEditorTheme = EditorView.theme({\n \"&\": { backgroundColor: \"transparent\", color: \"var(--json-viewer-color-punctuation)\", fontSize: \"13px\" },\n \"&.cm-focused\": { outline: \"none\" },\n \".cm-content\": { fontFamily: \"var(--sds-typography-family-mono)\", padding: \"45px 124px 12px 4px\" },\n \".cm-gutters\": {\n backgroundColor: \"transparent\",\n border: \"none\",\n color: \"var(--json-viewer-color-caret)\",\n paddingLeft: \"5px\",\n },\n \".cm-scroller\": { overflow: \"auto\" },\n});\n\nexport const jsonEditorExtensions = [json(), foldGutter(), syntaxHighlighting(jsonHighlightStyle)];\n\nexport function serializeJson(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2) ?? \"null\";\n } catch {\n return String(value);\n }\n}\n\nexport function toCssSize(size: string | number): string {\n return typeof size === \"number\" ? `${size}px` : size;\n}\n\n/**\n * Finds the fold range of every direct child (depth 1) of the root object/array\n * by scanning the text itself for matching brackets. This mirrors what\n * CodeMirror's `foldable()` would compute, but doesn't depend on the lezer\n * parser having finished tokenizing the document — which for a multi-MB\n * document is not guaranteed synchronously at mount time.\n */\nexport function computeFirstLevelFoldRanges(text: string): { from: number; to: number }[] {\n const ranges: { from: number; to: number }[] = [];\n const n = text.length;\n let i = 0;\n while (i < n && text[i] !== \"{\" && text[i] !== \"[\") i++;\n if (i >= n) return ranges;\n\n let depth = 0;\n let inString = false;\n let pendingStart = -1;\n for (; i < n; i++) {\n const ch = text[i];\n if (inString) {\n if (ch === \"\\\\\") i++;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === \"{\" || ch === \"[\") {\n depth++;\n if (depth === 2) pendingStart = i + 1;\n continue;\n }\n if (ch === \"}\" || ch === \"]\") {\n if (depth === 2 && pendingStart !== -1) {\n ranges.push({ from: pendingStart, to: i });\n pendingStart = -1;\n }\n depth--;\n }\n }\n return ranges;\n}\n"],"names":["jsonHighlightStyle","HighlightStyle","t","jsonEditorTheme","EditorView","jsonEditorExtensions","json","foldGutter","syntaxHighlighting","serializeJson","value","toCssSize","size","computeFirstLevelFoldRanges","text","ranges","n","i","depth","inString","pendingStart","ch"],"mappings":"uNAKaA,EAAqBC,EAAAA,eAAe,OAAO,CACtD,CAAE,IAAKC,EAAAA,KAAE,aAAc,MAAO,8BAAA,EAC9B,CAAE,IAAKA,EAAAA,KAAE,OAAQ,MAAO,kCAAmC,WAAY,GAAA,EACvE,CAAE,IAAK,CAACA,OAAE,OAAQA,EAAAA,KAAE,KAAMA,EAAAA,KAAE,IAAI,EAAG,MAAO,iCAAA,EAC1C,CAAE,IAAK,CAACA,EAAAA,KAAE,UAAWA,EAAAA,KAAE,cAAeA,OAAE,KAAK,EAAG,MAAO,sCAAA,CACzD,CAAC,EAEYC,EAAkBC,EAAAA,WAAW,MAAM,CAC9C,IAAK,CAAE,gBAAiB,cAAe,MAAO,uCAAwC,SAAU,MAAA,EAChG,eAAgB,CAAE,QAAS,MAAA,EAC3B,cAAe,CAAE,WAAY,oCAAqC,QAAS,qBAAA,EAC3E,cAAe,CACb,gBAAiB,cACjB,OAAQ,OACR,MAAO,iCACP,YAAa,KAAA,EAEf,eAAgB,CAAE,SAAU,MAAA,CAC9B,CAAC,EAEYC,EAAuB,CAACC,EAAAA,KAAA,EAAQC,EAAAA,aAAcC,EAAAA,mBAAmBR,CAAkB,CAAC,EAE1F,SAASS,EAAcC,EAAwB,CACpD,GAAI,CACF,OAAO,KAAK,UAAUA,EAAO,KAAM,CAAC,GAAK,MAC3C,MAAQ,CACN,OAAO,OAAOA,CAAK,CACrB,CACF,CAEO,SAASC,EAAUC,EAA+B,CACvD,OAAO,OAAOA,GAAS,SAAW,GAAGA,CAAI,KAAOA,CAClD,CASO,SAASC,EAA4BC,EAA8C,CACxF,MAAMC,EAAyC,CAAA,EACzCC,EAAIF,EAAK,OACf,IAAIG,EAAI,EACR,KAAOA,EAAID,GAAKF,EAAKG,CAAC,IAAM,KAAOH,EAAKG,CAAC,IAAM,KAAKA,IACpD,GAAIA,GAAKD,EAAG,OAAOD,EAEnB,IAAIG,EAAQ,EACRC,EAAW,GACXC,EAAe,GACnB,KAAOH,EAAID,EAAGC,IAAK,CACjB,MAAMI,EAAKP,EAAKG,CAAC,EACjB,GAAIE,EAAU,CACRE,IAAO,KAAMJ,IACRI,IAAO,MAAKF,EAAW,IAChC,QACF,CACA,GAAIE,IAAO,IAAK,CACdF,EAAW,GACX,QACF,CACA,GAAIE,IAAO,KAAOA,IAAO,IAAK,CAC5BH,IACIA,IAAU,IAAGE,EAAeH,EAAI,GACpC,QACF,EACII,IAAO,KAAOA,IAAO,OACnBH,IAAU,GAAKE,IAAiB,KAClCL,EAAO,KAAK,CAAE,KAAMK,EAAc,GAAIH,EAAG,EACzCG,EAAe,IAEjBF,IAEJ,CACA,OAAOH,CACT"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { EditorView as s } from "@codemirror/view";
|
|
2
|
+
import { json as f } from "@codemirror/lang-json";
|
|
3
|
+
import { foldGutter as u, syntaxHighlighting as g, HighlightStyle as p } from "@codemirror/language";
|
|
4
|
+
import { tags as n } from "@lezer/highlight";
|
|
5
|
+
const m = p.define([
|
|
6
|
+
{ tag: n.propertyName, color: "var(--json-viewer-color-key)" },
|
|
7
|
+
{ tag: n.string, color: "var(--json-viewer-color-string)", fontWeight: 600 },
|
|
8
|
+
{ tag: [n.number, n.bool, n.null], color: "var(--json-viewer-color-scalar)" },
|
|
9
|
+
{ tag: [n.separator, n.squareBracket, n.brace], color: "var(--json-viewer-color-punctuation)" }
|
|
10
|
+
]), j = s.theme({
|
|
11
|
+
"&": { backgroundColor: "transparent", color: "var(--json-viewer-color-punctuation)", fontSize: "13px" },
|
|
12
|
+
"&.cm-focused": { outline: "none" },
|
|
13
|
+
".cm-content": { fontFamily: "var(--sds-typography-family-mono)", padding: "45px 124px 12px 4px" },
|
|
14
|
+
".cm-gutters": {
|
|
15
|
+
backgroundColor: "transparent",
|
|
16
|
+
border: "none",
|
|
17
|
+
color: "var(--json-viewer-color-caret)",
|
|
18
|
+
paddingLeft: "5px"
|
|
19
|
+
},
|
|
20
|
+
".cm-scroller": { overflow: "auto" }
|
|
21
|
+
}), w = [f(), u(), g(m)];
|
|
22
|
+
function S(o) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.stringify(o, null, 2) ?? "null";
|
|
25
|
+
} catch {
|
|
26
|
+
return String(o);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function b(o) {
|
|
30
|
+
return typeof o == "number" ? `${o}px` : o;
|
|
31
|
+
}
|
|
32
|
+
function x(o) {
|
|
33
|
+
const l = [], c = o.length;
|
|
34
|
+
let r = 0;
|
|
35
|
+
for (; r < c && o[r] !== "{" && o[r] !== "["; ) r++;
|
|
36
|
+
if (r >= c) return l;
|
|
37
|
+
let e = 0, a = !1, i = -1;
|
|
38
|
+
for (; r < c; r++) {
|
|
39
|
+
const t = o[r];
|
|
40
|
+
if (a) {
|
|
41
|
+
t === "\\" ? r++ : t === '"' && (a = !1);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (t === '"') {
|
|
45
|
+
a = !0;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (t === "{" || t === "[") {
|
|
49
|
+
e++, e === 2 && (i = r + 1);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
(t === "}" || t === "]") && (e === 2 && i !== -1 && (l.push({ from: i, to: r }), i = -1), e--);
|
|
53
|
+
}
|
|
54
|
+
return l;
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
x as computeFirstLevelFoldRanges,
|
|
58
|
+
w as jsonEditorExtensions,
|
|
59
|
+
j as jsonEditorTheme,
|
|
60
|
+
m as jsonHighlightStyle,
|
|
61
|
+
S as serializeJson,
|
|
62
|
+
b as toCssSize
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=json-code-mirror.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-code-mirror.js","sources":["../../../../../src/ui/primitives/JsonViewer/json-code-mirror.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\nimport { json } from \"@codemirror/lang-json\";\nimport { foldGutter, HighlightStyle, syntaxHighlighting } from \"@codemirror/language\";\nimport { tags as t } from \"@lezer/highlight\";\n\nexport const jsonHighlightStyle = HighlightStyle.define([\n { tag: t.propertyName, color: \"var(--json-viewer-color-key)\" },\n { tag: t.string, color: \"var(--json-viewer-color-string)\", fontWeight: 600 },\n { tag: [t.number, t.bool, t.null], color: \"var(--json-viewer-color-scalar)\" },\n { tag: [t.separator, t.squareBracket, t.brace], color: \"var(--json-viewer-color-punctuation)\" },\n]);\n\nexport const jsonEditorTheme = EditorView.theme({\n \"&\": { backgroundColor: \"transparent\", color: \"var(--json-viewer-color-punctuation)\", fontSize: \"13px\" },\n \"&.cm-focused\": { outline: \"none\" },\n \".cm-content\": { fontFamily: \"var(--sds-typography-family-mono)\", padding: \"45px 124px 12px 4px\" },\n \".cm-gutters\": {\n backgroundColor: \"transparent\",\n border: \"none\",\n color: \"var(--json-viewer-color-caret)\",\n paddingLeft: \"5px\",\n },\n \".cm-scroller\": { overflow: \"auto\" },\n});\n\nexport const jsonEditorExtensions = [json(), foldGutter(), syntaxHighlighting(jsonHighlightStyle)];\n\nexport function serializeJson(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2) ?? \"null\";\n } catch {\n return String(value);\n }\n}\n\nexport function toCssSize(size: string | number): string {\n return typeof size === \"number\" ? `${size}px` : size;\n}\n\n/**\n * Finds the fold range of every direct child (depth 1) of the root object/array\n * by scanning the text itself for matching brackets. This mirrors what\n * CodeMirror's `foldable()` would compute, but doesn't depend on the lezer\n * parser having finished tokenizing the document — which for a multi-MB\n * document is not guaranteed synchronously at mount time.\n */\nexport function computeFirstLevelFoldRanges(text: string): { from: number; to: number }[] {\n const ranges: { from: number; to: number }[] = [];\n const n = text.length;\n let i = 0;\n while (i < n && text[i] !== \"{\" && text[i] !== \"[\") i++;\n if (i >= n) return ranges;\n\n let depth = 0;\n let inString = false;\n let pendingStart = -1;\n for (; i < n; i++) {\n const ch = text[i];\n if (inString) {\n if (ch === \"\\\\\") i++;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') {\n inString = true;\n continue;\n }\n if (ch === \"{\" || ch === \"[\") {\n depth++;\n if (depth === 2) pendingStart = i + 1;\n continue;\n }\n if (ch === \"}\" || ch === \"]\") {\n if (depth === 2 && pendingStart !== -1) {\n ranges.push({ from: pendingStart, to: i });\n pendingStart = -1;\n }\n depth--;\n }\n }\n return ranges;\n}\n"],"names":["jsonHighlightStyle","HighlightStyle","t","jsonEditorTheme","EditorView","jsonEditorExtensions","json","foldGutter","syntaxHighlighting","serializeJson","value","toCssSize","size","computeFirstLevelFoldRanges","text","ranges","n","i","depth","inString","pendingStart","ch"],"mappings":";;;;AAKO,MAAMA,IAAqBC,EAAe,OAAO;AAAA,EACtD,EAAE,KAAKC,EAAE,cAAc,OAAO,+BAAA;AAAA,EAC9B,EAAE,KAAKA,EAAE,QAAQ,OAAO,mCAAmC,YAAY,IAAA;AAAA,EACvE,EAAE,KAAK,CAACA,EAAE,QAAQA,EAAE,MAAMA,EAAE,IAAI,GAAG,OAAO,kCAAA;AAAA,EAC1C,EAAE,KAAK,CAACA,EAAE,WAAWA,EAAE,eAAeA,EAAE,KAAK,GAAG,OAAO,uCAAA;AACzD,CAAC,GAEYC,IAAkBC,EAAW,MAAM;AAAA,EAC9C,KAAK,EAAE,iBAAiB,eAAe,OAAO,wCAAwC,UAAU,OAAA;AAAA,EAChG,gBAAgB,EAAE,SAAS,OAAA;AAAA,EAC3B,eAAe,EAAE,YAAY,qCAAqC,SAAS,sBAAA;AAAA,EAC3E,eAAe;AAAA,IACb,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,EAAA;AAAA,EAEf,gBAAgB,EAAE,UAAU,OAAA;AAC9B,CAAC,GAEYC,IAAuB,CAACC,EAAA,GAAQC,KAAcC,EAAmBR,CAAkB,CAAC;AAE1F,SAASS,EAAcC,GAAwB;AACpD,MAAI;AACF,WAAO,KAAK,UAAUA,GAAO,MAAM,CAAC,KAAK;AAAA,EAC3C,QAAQ;AACN,WAAO,OAAOA,CAAK;AAAA,EACrB;AACF;AAEO,SAASC,EAAUC,GAA+B;AACvD,SAAO,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAClD;AASO,SAASC,EAA4BC,GAA8C;AACxF,QAAMC,IAAyC,CAAA,GACzCC,IAAIF,EAAK;AACf,MAAIG,IAAI;AACR,SAAOA,IAAID,KAAKF,EAAKG,CAAC,MAAM,OAAOH,EAAKG,CAAC,MAAM,MAAK,CAAAA;AACpD,MAAIA,KAAKD,EAAG,QAAOD;AAEnB,MAAIG,IAAQ,GACRC,IAAW,IACXC,IAAe;AACnB,SAAOH,IAAID,GAAGC,KAAK;AACjB,UAAMI,IAAKP,EAAKG,CAAC;AACjB,QAAIE,GAAU;AACZ,MAAIE,MAAO,OAAMJ,MACRI,MAAO,QAAKF,IAAW;AAChC;AAAA,IACF;AACA,QAAIE,MAAO,KAAK;AACd,MAAAF,IAAW;AACX;AAAA,IACF;AACA,QAAIE,MAAO,OAAOA,MAAO,KAAK;AAC5B,MAAAH,KACIA,MAAU,MAAGE,IAAeH,IAAI;AACpC;AAAA,IACF;AACA,KAAII,MAAO,OAAOA,MAAO,SACnBH,MAAU,KAAKE,MAAiB,OAClCL,EAAO,KAAK,EAAE,MAAMK,GAAc,IAAIH,GAAG,GACzCG,IAAe,KAEjBF;AAAA,EAEJ;AACA,SAAOH;AACT;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),t=require("../../../vendor/clsx/dist/clsx.cjs"),c=require("react");;/* empty css */const i=c.forwardRef(function(e,s){const n=t.clsx("link",e.className);return r.jsx("a",{...e,ref:s,className:n})});exports.Link=i;
|
|
2
2
|
//# sourceMappingURL=Link.cjs.map
|
|
@@ -2,9 +2,9 @@ import { jsx as s } from "react/jsx-runtime";
|
|
|
2
2
|
import { clsx as t } from "../../../vendor/clsx/dist/clsx.js";
|
|
3
3
|
import a from "react";
|
|
4
4
|
/* empty css */
|
|
5
|
-
const l = a.forwardRef(function(
|
|
6
|
-
const m = t("link",
|
|
7
|
-
return /* @__PURE__ */ s("a", { ...
|
|
5
|
+
const l = a.forwardRef(function(o, r) {
|
|
6
|
+
const m = t("link", o.className);
|
|
7
|
+
return /* @__PURE__ */ s("a", { ...o, ref: r, className: m });
|
|
8
8
|
});
|
|
9
9
|
export {
|
|
10
10
|
l as Link
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),s=require("../../../vendor/clsx/dist/clsx.cjs"),c=require("react"),j=require("../PermissionGate/PermissionGate.cjs"),u=require("react-aria-components");;/* empty css */const h=require("../../icons/IconChevronDown.cjs"),i=require("../Fieldset/Fieldset.cjs"),g=require("../IconButton/IconButton.cjs"),N=require("../Button/Button.cjs"),v=require("../../hooks/useOverlayPortal.cjs"),q=require("../Text/Text.cjs");let l=!1;function m(n){l||c.Children.forEach(n,e=>{if(c.isValidElement(e)){if(e.type===c.Fragment){m(e.props.children);return}e.type===j.PermissionGate&&(l=!0,console.error("[design-system] Menu: PermissionGate não pode envolver um MenuItem — o react-aria descarta esse item e os seguintes, e o menu abre vazio quando ele é o primeiro. Mova o gate para dentro do MenuItem, em volta do conteúdo do item."))}})}function d({className:n,...e}){return m(typeof e.children=="function"?null:e.children),r.jsx(u.Menu,{className:s.clsx(n,"menu"),...e})}function x({...n}){return r.jsx(u.MenuTrigger,{...n})}function p({label:n,children:e,icon:t,placement:o,variant:a,...f}){return r.jsxs(x,{children:[t?r.jsx(g.IconButton,{variant:a,"aria-label":n,children:t}):r.jsx(N.Button,{variant:a,children:n}),r.jsx(M,{placement:o,children:r.jsx(d,{...f,children:e})})]})}function M({UNSTABLE_portalContainer:n,...e}){const t=v.useOverlayPortalContainer();return r.jsx(u.Popover,{...e,UNSTABLE_portalContainer:n??t})}function I({className:n,...e}){const t=s.clsx(n,"menu-item"),o=e.textValue||(typeof e.children=="string"?e.children:void 0);return r.jsx(u.MenuItem,{...e,className:t,textValue:o,children:({hasSubmenu:a})=>r.jsxs(r.Fragment,{children:[e.children,a&&r.jsx(h.IconChevronDown,{})]})})}function y({className:n,...e}){const t=s.clsx(n,"menu-header");return r.jsx("div",{...e,className:t})}function S({className:n,...e}){const t=s.clsx(n,"menu-section");return r.jsx("div",{...e,className:t})}function b({className:n,...e}){const t=s.clsx(n,"menu-heading");return r.jsx(q.TextHeading,{...e,className:t})}function P({className:n,...e}){const t=s.clsx(n,"menu-separator");return r.jsx(u.Separator,{...e,className:t})}function B({className:n,...e}){const t=s.clsx(n,"menu-label");return r.jsx(i.Label,{...e,className:t})}function C({className:n,...e}){const t=s.clsx(n,"menu-description");return r.jsx(i.Description,{...e,className:t})}function T({children:n,className:e,...t}){const o=s.clsx(e,"menu-shortcut");return r.jsx(i.Keyboard,{...t,className:o,children:n})}exports.Menu=d;exports.MenuButton=p;exports.MenuDescription=C;exports.MenuHeader=y;exports.MenuHeading=b;exports.MenuItem=I;exports.MenuLabel=B;exports.MenuPopover=M;exports.MenuSection=S;exports.MenuSeparator=P;exports.MenuShortcut=T;exports.MenuTrigger=x;
|
|
2
2
|
//# sourceMappingURL=Menu.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.cjs","sources":["../../../../../src/ui/primitives/Menu/Menu.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { useOverlayPortalContainer } from \"hooks\";\nimport { IconChevronDown } from \"icons\";\nimport {\n Button,\n ButtonProps,\n Description,\n DescriptionProps,\n IconButton,\n Keyboard,\n KeyboardProps,\n Label,\n LabelProps,\n TextHeading,\n type TextHeadingProps,\n} from \"primitives\";\nimport type React from \"react\";\nimport {\n Menu as RACMenu,\n MenuItem as RACMenuItem,\n MenuTrigger as RACMenuTrigger,\n Popover as RACPopover,\n Separator as RACSeparator,\n type MenuItemProps as RACMenuItemProps,\n type MenuProps as RACMenuProps,\n type MenuTriggerProps as RACMenuTriggerProps,\n type PopoverProps as RACPopoverProps,\n type SeparatorProps as RACSeparatorProps,\n} from \"react-aria-components\";\nimport \"./menu.css\";\n\nexport type MenuProps<T> = RACMenuProps<T>;\nexport function Menu<T extends object>({ className, ...props }: MenuProps<T>) {\n return <RACMenu className={clsx(className, \"menu\")} {...props} />;\n}\n\nexport type MenuTriggerProps = RACMenuTriggerProps;\nexport function MenuTrigger({ ...props }: MenuTriggerProps) {\n return <RACMenuTrigger {...props} />;\n}\n\nexport interface MenuButtonProps<T>\n extends RACMenuProps<T>,\n Omit<RACMenuTriggerProps, \"children\"> {\n label: string;\n variant?: ButtonProps[\"variant\"];\n placement?: MenuPopoverProps[\"placement\"];\n icon?: React.ReactNode;\n}\nexport function MenuButton<T extends object>({\n label,\n children,\n icon,\n placement,\n variant,\n ...props\n}: MenuButtonProps<T>) {\n return (\n <MenuTrigger>\n {icon ? (\n <IconButton variant={variant} aria-label={label}>\n {icon}\n </IconButton>\n ) : (\n <Button variant={variant}>{label}</Button>\n )}\n <MenuPopover placement={placement}>\n <Menu {...props}>{children}</Menu>\n </MenuPopover>\n </MenuTrigger>\n );\n}\n\nexport type MenuPopoverProps = RACPopoverProps;\nexport function MenuPopover({\n UNSTABLE_portalContainer,\n ...props\n}: MenuPopoverProps) {\n // Sem container explícito o menu faz portal no document.body — fora da shadow\n // root do MFE, sem CSS. Ver ui/hooks/useOverlayPortal.\n const portalContainer = useOverlayPortalContainer();\n return (\n <RACPopover\n {...props}\n UNSTABLE_portalContainer={UNSTABLE_portalContainer ?? portalContainer}\n />\n );\n}\n\nexport type MenuItemProps = RACMenuItemProps;\nexport function MenuItem({ className, ...props }: MenuItemProps) {\n const classNames = clsx(className, \"menu-item\");\n const textValue =\n props.textValue ||\n (typeof props.children === \"string\" ? props.children : undefined);\n return (\n <RACMenuItem {...props} className={classNames} textValue={textValue}>\n {({ hasSubmenu }) => (\n <>\n {props.children}\n {hasSubmenu && <IconChevronDown />}\n </>\n )}\n </RACMenuItem>\n );\n}\n\nexport type MenuHeaderProps = React.ComponentPropsWithoutRef<\"div\">;\nexport function MenuHeader({ className, ...props }: MenuHeaderProps) {\n const classNames = clsx(className, \"menu-header\");\n return <div {...props} className={classNames} />;\n}\n\nexport type MenuSectionProps = React.ComponentPropsWithoutRef<\"div\">;\nexport function MenuSection({ className, ...props }: MenuSectionProps) {\n const classNames = clsx(className, \"menu-section\");\n return <div {...props} className={classNames} />;\n}\n\nexport type MenuHeadingProps = TextHeadingProps;\nexport function MenuHeading({ className, ...props }: MenuHeadingProps) {\n const classNames = clsx(className, \"menu-heading\");\n return <TextHeading {...props} className={classNames} />;\n}\n\nexport type MenuSeparatorProps = RACSeparatorProps;\nexport function MenuSeparator({ className, ...props }: MenuSeparatorProps) {\n const classNames = clsx(className, \"menu-separator\");\n return <RACSeparator {...props} className={classNames} />;\n}\n\nexport type MenuLabelProps = LabelProps;\nexport function MenuLabel({ className, ...props }: MenuLabelProps) {\n const classNames = clsx(className, \"menu-label\");\n return <Label {...props} className={classNames} />;\n}\n\nexport type MenuDescriptionProps = DescriptionProps;\nexport function MenuDescription({ className, ...props }: MenuDescriptionProps) {\n const classNames = clsx(className, \"menu-description\");\n return <Description {...props} className={classNames} />;\n}\n\nexport type MenuShortcutProps = KeyboardProps;\nexport function MenuShortcut({\n children,\n className,\n ...props\n}: MenuShortcutProps) {\n const classNames = clsx(className, \"menu-shortcut\");\n return (\n <Keyboard {...props} className={classNames}>\n {children}\n </Keyboard>\n );\n}\n"],"names":["Menu","className","props","jsx","RACMenu","clsx","MenuTrigger","RACMenuTrigger","MenuButton","label","children","icon","placement","variant","IconButton","Button","MenuPopover","UNSTABLE_portalContainer","portalContainer","useOverlayPortalContainer","RACPopover","MenuItem","classNames","textValue","RACMenuItem","hasSubmenu","jsxs","Fragment","IconChevronDown","MenuHeader","MenuSection","MenuHeading","TextHeading","MenuSeparator","RACSeparator","MenuLabel","Label","MenuDescription","Description","MenuShortcut","Keyboard"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Menu.cjs","sources":["../../../../../src/ui/primitives/Menu/Menu.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { useOverlayPortalContainer } from \"hooks\";\nimport { IconChevronDown } from \"icons\";\nimport {\n Button,\n ButtonProps,\n Description,\n DescriptionProps,\n IconButton,\n Keyboard,\n KeyboardProps,\n Label,\n LabelProps,\n TextHeading,\n type TextHeadingProps,\n} from \"primitives\";\nimport React from \"react\";\nimport { PermissionGate } from \"../PermissionGate/PermissionGate\";\nimport {\n Menu as RACMenu,\n MenuItem as RACMenuItem,\n MenuTrigger as RACMenuTrigger,\n Popover as RACPopover,\n Separator as RACSeparator,\n type MenuItemProps as RACMenuItemProps,\n type MenuProps as RACMenuProps,\n type MenuTriggerProps as RACMenuTriggerProps,\n type PopoverProps as RACPopoverProps,\n type SeparatorProps as RACSeparatorProps,\n} from \"react-aria-components\";\nimport \"./menu.css\";\n\n/**\n * Aviso de desenvolvimento: um `PermissionGate` EM VOLTA de um `MenuItem` quebra\n * o menu. O collection builder do react-aria-components só entende nós de\n * coleção (`MenuItem`, `MenuSeparator`, `MenuSection`); o `<span>` que o gate\n * renderiza no ramo negado entra na coleção com `node` nulo e arrebenta a lista\n * encadeada de chaves — o item envolvido e todos os seguintes desaparecem, e se\n * ele for o primeiro filho o menu abre VAZIO, levando embora também os itens\n * permitidos. Não há erro no console, e a forma errada passa despercebida em QA\n * feito com um usuário que tem todas as permissões, porque o ramo que envolve só\n * é renderizado quando a ação é negada.\n *\n * O gate deve ficar DENTRO do item, em volta do conteúdo — ali é seguro, porque\n * o conteúdo do item é renderizado no DOM real, fora da coleção. Mesmo padrão\n * das ações de linha do `DataTable`.\n *\n * O aviso é incondicional, e não atrás de `process.env.NODE_ENV`: o build da lib\n * (`vite.lib.config.ts`) substitui essa variável pelo literal `\"production\"`, o\n * que transformaria o guard em código morto justamente nos consumidores. Só\n * dispara uma vez por sessão, e só quando já existe um bug na árvore.\n */\nlet hasWarnedAboutGateAroundItem = false;\n\nfunction warnOnGateAroundItem(children: React.ReactNode) {\n if (hasWarnedAboutGateAroundItem) return;\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return;\n if (child.type === React.Fragment) {\n warnOnGateAroundItem(\n (child.props as { children?: React.ReactNode }).children,\n );\n return;\n }\n if (child.type === PermissionGate) {\n hasWarnedAboutGateAroundItem = true;\n console.error(\n \"[design-system] Menu: PermissionGate não pode envolver um MenuItem — \" +\n \"o react-aria descarta esse item e os seguintes, e o menu abre vazio \" +\n \"quando ele é o primeiro. Mova o gate para dentro do MenuItem, em \" +\n \"volta do conteúdo do item.\",\n );\n }\n });\n}\n\nexport type MenuProps<T> = RACMenuProps<T>;\nexport function Menu<T extends object>({ className, ...props }: MenuProps<T>) {\n // children pode ser uma função nas coleções dinâmicas do react-aria.\n warnOnGateAroundItem(\n typeof props.children === \"function\" ? null : props.children,\n );\n return <RACMenu className={clsx(className, \"menu\")} {...props} />;\n}\n\nexport type MenuTriggerProps = RACMenuTriggerProps;\nexport function MenuTrigger({ ...props }: MenuTriggerProps) {\n return <RACMenuTrigger {...props} />;\n}\n\nexport interface MenuButtonProps<T>\n extends RACMenuProps<T>,\n Omit<RACMenuTriggerProps, \"children\"> {\n label: string;\n variant?: ButtonProps[\"variant\"];\n placement?: MenuPopoverProps[\"placement\"];\n icon?: React.ReactNode;\n}\nexport function MenuButton<T extends object>({\n label,\n children,\n icon,\n placement,\n variant,\n ...props\n}: MenuButtonProps<T>) {\n return (\n <MenuTrigger>\n {icon ? (\n <IconButton variant={variant} aria-label={label}>\n {icon}\n </IconButton>\n ) : (\n <Button variant={variant}>{label}</Button>\n )}\n <MenuPopover placement={placement}>\n <Menu {...props}>{children}</Menu>\n </MenuPopover>\n </MenuTrigger>\n );\n}\n\nexport type MenuPopoverProps = RACPopoverProps;\nexport function MenuPopover({\n UNSTABLE_portalContainer,\n ...props\n}: MenuPopoverProps) {\n // Sem container explícito o menu faz portal no document.body — fora da shadow\n // root do MFE, sem CSS. Ver ui/hooks/useOverlayPortal.\n const portalContainer = useOverlayPortalContainer();\n return (\n <RACPopover\n {...props}\n UNSTABLE_portalContainer={UNSTABLE_portalContainer ?? portalContainer}\n />\n );\n}\n\nexport type MenuItemProps = RACMenuItemProps;\nexport function MenuItem({ className, ...props }: MenuItemProps) {\n const classNames = clsx(className, \"menu-item\");\n const textValue =\n props.textValue ||\n (typeof props.children === \"string\" ? props.children : undefined);\n return (\n <RACMenuItem {...props} className={classNames} textValue={textValue}>\n {({ hasSubmenu }) => (\n <>\n {props.children}\n {hasSubmenu && <IconChevronDown />}\n </>\n )}\n </RACMenuItem>\n );\n}\n\nexport type MenuHeaderProps = React.ComponentPropsWithoutRef<\"div\">;\nexport function MenuHeader({ className, ...props }: MenuHeaderProps) {\n const classNames = clsx(className, \"menu-header\");\n return <div {...props} className={classNames} />;\n}\n\nexport type MenuSectionProps = React.ComponentPropsWithoutRef<\"div\">;\nexport function MenuSection({ className, ...props }: MenuSectionProps) {\n const classNames = clsx(className, \"menu-section\");\n return <div {...props} className={classNames} />;\n}\n\nexport type MenuHeadingProps = TextHeadingProps;\nexport function MenuHeading({ className, ...props }: MenuHeadingProps) {\n const classNames = clsx(className, \"menu-heading\");\n return <TextHeading {...props} className={classNames} />;\n}\n\nexport type MenuSeparatorProps = RACSeparatorProps;\nexport function MenuSeparator({ className, ...props }: MenuSeparatorProps) {\n const classNames = clsx(className, \"menu-separator\");\n return <RACSeparator {...props} className={classNames} />;\n}\n\nexport type MenuLabelProps = LabelProps;\nexport function MenuLabel({ className, ...props }: MenuLabelProps) {\n const classNames = clsx(className, \"menu-label\");\n return <Label {...props} className={classNames} />;\n}\n\nexport type MenuDescriptionProps = DescriptionProps;\nexport function MenuDescription({ className, ...props }: MenuDescriptionProps) {\n const classNames = clsx(className, \"menu-description\");\n return <Description {...props} className={classNames} />;\n}\n\nexport type MenuShortcutProps = KeyboardProps;\nexport function MenuShortcut({\n children,\n className,\n ...props\n}: MenuShortcutProps) {\n const classNames = clsx(className, \"menu-shortcut\");\n return (\n <Keyboard {...props} className={classNames}>\n {children}\n </Keyboard>\n );\n}\n"],"names":["hasWarnedAboutGateAroundItem","warnOnGateAroundItem","children","React","child","PermissionGate","Menu","className","props","jsx","RACMenu","clsx","MenuTrigger","RACMenuTrigger","MenuButton","label","icon","placement","variant","IconButton","Button","MenuPopover","UNSTABLE_portalContainer","portalContainer","useOverlayPortalContainer","RACPopover","MenuItem","classNames","textValue","RACMenuItem","hasSubmenu","jsxs","Fragment","IconChevronDown","MenuHeader","MenuSection","MenuHeading","TextHeading","MenuSeparator","RACSeparator","MenuLabel","Label","MenuDescription","Description","MenuShortcut","Keyboard"],"mappings":"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"}
|