@ngrok/mantle 0.32.0 → 0.32.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.
Files changed (136) hide show
  1. package/dist/accordion.d.ts +143 -2
  2. package/dist/accordion.js +1 -1
  3. package/dist/accordion.js.map +1 -1
  4. package/dist/alert-dialog.d.ts +1 -1
  5. package/dist/alert-dialog.js +1 -1
  6. package/dist/alert-dialog.js.map +1 -1
  7. package/dist/alert.d.ts +5 -2
  8. package/dist/alert.js +1 -1
  9. package/dist/alert.js.map +1 -1
  10. package/dist/anchor.d.ts +1 -1
  11. package/dist/anchor.js +1 -1
  12. package/dist/anchor.js.map +1 -1
  13. package/dist/badge.d.ts +4 -1
  14. package/dist/badge.js +1 -1
  15. package/dist/badge.js.map +1 -1
  16. package/dist/{button-C8eGiHOm.d.ts → button-BvWgeelK.d.ts} +8 -1
  17. package/dist/{button-group-CpDp0fYZ.d.ts → button-group-7oT-O90J.d.ts} +11 -0
  18. package/dist/button.d.ts +3 -3
  19. package/dist/button.js +1 -1
  20. package/dist/calendar.d.ts +17 -0
  21. package/dist/calendar.js +1 -1
  22. package/dist/calendar.js.map +1 -1
  23. package/dist/checkbox.d.ts +1 -1
  24. package/dist/checkbox.js.map +1 -1
  25. package/dist/{chunk-7XIZZ4HQ.js → chunk-3H3EUKI7.js} +1 -1
  26. package/dist/chunk-3H3EUKI7.js.map +1 -0
  27. package/dist/{chunk-ZXLA5BJX.js → chunk-3X4AKTRA.js} +2 -2
  28. package/dist/chunk-3X4AKTRA.js.map +1 -0
  29. package/dist/chunk-6RJ2G2DK.js +34 -0
  30. package/dist/chunk-6RJ2G2DK.js.map +1 -0
  31. package/dist/chunk-I6T6YV2L.js +2 -0
  32. package/dist/chunk-I6T6YV2L.js.map +1 -0
  33. package/dist/chunk-IVXZIYX4.js +2 -0
  34. package/dist/chunk-IVXZIYX4.js.map +1 -0
  35. package/dist/chunk-J6ZF5J72.js +2 -0
  36. package/dist/chunk-J6ZF5J72.js.map +1 -0
  37. package/dist/chunk-JIRNFNH5.js +2 -0
  38. package/dist/{chunk-72UMV3YP.js.map → chunk-JIRNFNH5.js.map} +1 -1
  39. package/dist/chunk-NPTDRQT5.js +2 -0
  40. package/dist/chunk-NPTDRQT5.js.map +1 -0
  41. package/dist/chunk-NRMIFYYG.js +2 -0
  42. package/dist/chunk-NRMIFYYG.js.map +1 -0
  43. package/dist/{chunk-VTCWSFFJ.js → chunk-PANPBV3Q.js} +2 -2
  44. package/dist/{chunk-VTCWSFFJ.js.map → chunk-PANPBV3Q.js.map} +1 -1
  45. package/dist/{chunk-BK4P33ZH.js → chunk-RTXWW6ND.js} +2 -2
  46. package/dist/{chunk-BK4P33ZH.js.map → chunk-RTXWW6ND.js.map} +1 -1
  47. package/dist/{chunk-3MDQ3LC2.js → chunk-W2YQRWR5.js} +2 -2
  48. package/dist/{chunk-3MDQ3LC2.js.map → chunk-W2YQRWR5.js.map} +1 -1
  49. package/dist/code-block.d.ts +3 -0
  50. package/dist/code-block.js +3 -3
  51. package/dist/code-block.js.map +1 -1
  52. package/dist/combobox.d.ts +4 -1
  53. package/dist/combobox.js +1 -1
  54. package/dist/combobox.js.map +1 -1
  55. package/dist/data-table.d.ts +41 -12
  56. package/dist/data-table.js +1 -1
  57. package/dist/data-table.js.map +1 -1
  58. package/dist/dialog.d.ts +256 -3
  59. package/dist/dialog.js +1 -1
  60. package/dist/dialog.js.map +1 -1
  61. package/dist/dropdown-menu.d.ts +80 -0
  62. package/dist/dropdown-menu.js +1 -1
  63. package/dist/dropdown-menu.js.map +1 -1
  64. package/dist/flag.d.ts +4 -1
  65. package/dist/flag.js +1 -1
  66. package/dist/flag.js.map +1 -1
  67. package/dist/hover-card.d.ts +58 -0
  68. package/dist/hover-card.js +1 -1
  69. package/dist/hover-card.js.map +1 -1
  70. package/dist/{icon-Cu-iYUjr.d.ts → icon-CkvpQ4BK.d.ts} +1 -7
  71. package/dist/{icon-button-D41yiI7H.d.ts → icon-button-D4BTvC7F.d.ts} +12 -1
  72. package/dist/icon.d.ts +2 -2
  73. package/dist/icon.js +1 -1
  74. package/dist/icons.d.ts +9 -0
  75. package/dist/icons.js +1 -1
  76. package/dist/icons.js.map +1 -1
  77. package/dist/inline-code.d.ts +10 -1
  78. package/dist/inline-code.js.map +1 -1
  79. package/dist/input.d.ts +39 -1
  80. package/dist/input.js +1 -1
  81. package/dist/input.js.map +1 -1
  82. package/dist/label.d.ts +1 -1
  83. package/dist/label.js.map +1 -1
  84. package/dist/pagination.d.ts +51 -1
  85. package/dist/pagination.js +1 -1
  86. package/dist/pagination.js.map +1 -1
  87. package/dist/popover.d.ts +77 -17
  88. package/dist/popover.js.map +1 -1
  89. package/dist/{primitive-hud69IM9.d.ts → primitive-BUbUB7RS.d.ts} +3 -0
  90. package/dist/progress.d.ts +14 -2
  91. package/dist/progress.js +1 -1
  92. package/dist/progress.js.map +1 -1
  93. package/dist/radio-group.d.ts +51 -3
  94. package/dist/radio-group.js +1 -1
  95. package/dist/radio-group.js.map +1 -1
  96. package/dist/sandboxed-on-click.d.ts +0 -3
  97. package/dist/sandboxed-on-click.js.map +1 -1
  98. package/dist/select.d.ts +8 -4
  99. package/dist/select.js +1 -1
  100. package/dist/separator.d.ts +4 -1
  101. package/dist/separator.js +1 -1
  102. package/dist/sheet.d.ts +18 -6
  103. package/dist/sheet.js +1 -1
  104. package/dist/sheet.js.map +1 -1
  105. package/dist/{svg-only-CS2INnEL.d.ts → svg-only-Bj2yffO4.d.ts} +7 -7
  106. package/dist/switch.d.ts +2 -2
  107. package/dist/switch.js.map +1 -1
  108. package/dist/table.js +1 -1
  109. package/dist/tabs.d.ts +104 -1
  110. package/dist/tabs.js +1 -1
  111. package/dist/tabs.js.map +1 -1
  112. package/dist/text-area.d.ts +2 -1
  113. package/dist/text-area.js.map +1 -1
  114. package/dist/theme-provider.d.ts +29 -5
  115. package/dist/theme-provider.js +1 -1
  116. package/dist/toast.d.ts +70 -2
  117. package/dist/toast.js +1 -1
  118. package/dist/tooltip.d.ts +53 -13
  119. package/dist/tooltip.js +1 -1
  120. package/dist/tooltip.js.map +1 -1
  121. package/package.json +1 -1
  122. package/dist/chunk-3XX7M573.js +0 -34
  123. package/dist/chunk-3XX7M573.js.map +0 -1
  124. package/dist/chunk-72UMV3YP.js +0 -2
  125. package/dist/chunk-7XIZZ4HQ.js.map +0 -1
  126. package/dist/chunk-BGY3DO4G.js +0 -2
  127. package/dist/chunk-BGY3DO4G.js.map +0 -1
  128. package/dist/chunk-HDPLH5HC.js +0 -2
  129. package/dist/chunk-HDPLH5HC.js.map +0 -1
  130. package/dist/chunk-HVMKFNT3.js +0 -2
  131. package/dist/chunk-HVMKFNT3.js.map +0 -1
  132. package/dist/chunk-UXH22BMO.js +0 -2
  133. package/dist/chunk-UXH22BMO.js.map +0 -1
  134. package/dist/chunk-XQVVOOLT.js +0 -2
  135. package/dist/chunk-XQVVOOLT.js.map +0 -1
  136. package/dist/chunk-ZXLA5BJX.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/code-block/code-block.tsx","../src/components/code-block/escape-html.ts","../src/components/code-block/highlighter.ts","../src/components/code-block/indentation.ts","../src/components/code-block/normalize.ts","../src/components/code-block/supported-languages.ts","../src/components/code-block/fmt-code.ts","../src/components/code-block/parse-metastring.ts"],"sourcesContent":["\"use client\";\n\nimport { CaretDownIcon } from \"@phosphor-icons/react/CaretDown\";\nimport { CheckIcon } from \"@phosphor-icons/react/Check\";\nimport { CopyIcon } from \"@phosphor-icons/react/Copy\";\nimport { FileTextIcon } from \"@phosphor-icons/react/FileText\";\nimport { TerminalIcon } from \"@phosphor-icons/react/Terminal\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport clsx from \"clsx\";\nimport type {\n\tComponentProps,\n\tComponentRef,\n\tDispatch,\n\tHTMLAttributes,\n\tReactNode,\n\tSetStateAction,\n} from \"react\";\nimport {\n\tcreateContext,\n\tforwardRef,\n\tuseContext,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport assert from \"tiny-invariant\";\nimport { useCopyToClipboard } from \"../../hooks/use-copy-to-clipboard.js\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Icon } from \"../icon/icon.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { TrafficPolicyFileIcon } from \"../icons/traffic-policy-file.js\";\nimport { escapeHtml } from \"./escape-html.js\";\nimport { Highlighter } from \"./highlighter.js\";\nimport { type Indentation, inferIndentation } from \"./indentation.js\";\nimport type { LineRange } from \"./line-numbers.js\";\nimport { normalizeIndentation } from \"./normalize.js\";\nimport type { Mode } from \"./parse-metastring.js\";\nimport type { SupportedLanguage } from \"./supported-languages.js\";\nimport {\n\tformatLanguageClassName,\n\tsupportedLanguages,\n} from \"./supported-languages.js\";\n\n/**\n * TODO(cody):\n * - fix line numbers, maybe try grid instead of :before and flex?\n * - fix line hightlighting\n * - fix line wrapping? horizontal scrolling has problems w/ line highlighting :(\n */\n\ntype CodeBlockContextType = {\n\tcodeId: string | undefined;\n\tcopyText: string;\n\thasCodeExpander: boolean;\n\tisCodeExpanded: boolean;\n\tregisterCodeId: (id: string) => void;\n\tsetCopyText: (newCopyText: string) => void;\n\tsetHasCodeExpander: (value: boolean) => void;\n\tsetIsCodeExpanded: Dispatch<SetStateAction<boolean>>;\n\tunregisterCodeId: (id: string) => void;\n};\n\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n\tcodeId: undefined,\n\tcopyText: \"\",\n\thasCodeExpander: false,\n\tisCodeExpanded: false,\n\tregisterCodeId: () => {},\n\tsetCopyText: () => {},\n\tsetHasCodeExpander: () => {},\n\tsetIsCodeExpanded: () => {},\n\tunregisterCodeId: () => {},\n});\n\n/**\n * Code blocks render and apply syntax highlighting to blocks of code.\n * This is the root component for all code block components.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlock = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentProps<\"div\"> & WithAsChild\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst [copyText, setCopyText] = useState(\"\");\n\tconst [hasCodeExpander, setHasCodeExpander] = useState(false);\n\tconst [isCodeExpanded, setIsCodeExpanded] = useState(false);\n\tconst [codeId, setCodeId] = useState<string | undefined>(undefined);\n\n\tconst context: CodeBlockContextType = useMemo(\n\t\t() =>\n\t\t\t({\n\t\t\t\tcodeId,\n\t\t\t\tcopyText,\n\t\t\t\thasCodeExpander,\n\t\t\t\tisCodeExpanded,\n\t\t\t\tregisterCodeId: (id) => {\n\t\t\t\t\tsetCodeId((old) => {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\told == null,\n\t\t\t\t\t\t\t\"You can only render a single CodeBlockCode within a CodeBlock.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn id;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tsetCopyText,\n\t\t\t\tsetHasCodeExpander,\n\t\t\t\tsetIsCodeExpanded,\n\t\t\t\tunregisterCodeId: (id) => {\n\t\t\t\t\tsetCodeId((old) => {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\told === id,\n\t\t\t\t\t\t\t\"You can only render a single CodeBlockCode within a CodeBlock.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t}) as const,\n\t\t[codeId, copyText, hasCodeExpander, isCodeExpanded],\n\t);\n\n\tconst Component = asChild ? Slot : \"div\";\n\n\treturn (\n\t\t<CodeBlockContext.Provider value={context}>\n\t\t\t<Component\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"text-size-mono overflow-hidden rounded-md border border-gray-300 bg-gray-50 font-mono\",\n\t\t\t\t\t\"[&_svg]:shrink-0\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</CodeBlockContext.Provider>\n\t);\n});\nCodeBlock.displayName = \"CodeBlock\";\n\n/**\n * The body of the `CodeBlock`. This is where the `CodeBlockCode` and optional\n * `CodeBlockCopyButton` is rendered.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-body\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockBody = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentProps<\"div\"> & WithAsChild\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst Component = asChild ? Slot : \"div\";\n\n\treturn (\n\t\t<Component className={cx(\"relative\", className)} ref={ref} {...props} />\n\t);\n});\nCodeBlockBody.displayName = \"CodeBlockBody\";\n\ntype CodeBlockCodeProps = Omit<ComponentProps<\"pre\">, \"children\"> & {\n\t/**\n\t * The code to display in the code block. Should be code formatted as a string. This code will be passed to our syntax highlighter.\n\t */\n\tvalue: string;\n\t/**\n\t * @todo not implemented yet\n\t */\n\thighlightLines?: (LineRange | number)[];\n\t/**\n\t * The type of indentation to use. Can be either \"tabs\" or \"spaces\".\n\t * @default inferred from the given language, fallback to `spaces`\n\t */\n\tindentation?: Indentation;\n\t/**\n\t * The language of the code block. This will be used to determine how to syntax highlight the code.\n\t * @default `\"text\"`.\n\t */\n\tlanguage?: SupportedLanguage;\n\t/**\n\t * @todo not implemented yet\n\t */\n\tshowLineNumbers?: boolean;\n};\n\n/**\n * The `CodeBlock` content. This is where the code is rendered and syntax highlighted.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-code\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode\n * language=\"sh\"\n * value={fmtCode`ffmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4`}\n * />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockCode = forwardRef<ComponentRef<\"pre\">, CodeBlockCodeProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\thighlightLines: _unusedHighlightLines, // not implemented yet\n\t\t\tindentation: propIndentation,\n\t\t\tlanguage = \"text\",\n\t\t\tshowLineNumbers: _unusedShowLineNumbers, // not implemented yet\n\t\t\tstyle,\n\t\t\ttabIndex,\n\t\t\tvalue,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst id = useId();\n\t\tconst {\n\t\t\thasCodeExpander,\n\t\t\tisCodeExpanded,\n\t\t\tregisterCodeId,\n\t\t\tsetCopyText,\n\t\t\tunregisterCodeId,\n\t\t} = useContext(CodeBlockContext);\n\t\tconst indentation = inferIndentation(language, propIndentation);\n\n\t\t// trim any leading and trailing whitespace/empty lines, convert leading tabs to spaces\n\t\tconst normalizedAndTrimmedValue = useMemo(\n\t\t\t() => normalizeIndentation(value, { indentation }),\n\t\t\t[value, indentation],\n\t\t);\n\t\tconst [highlightedCodeInnerHtml, setHighlightedCodeInnerHtml] = useState(\n\t\t\t// initialize the <code> inner html with escaped HTML since we are using\n\t\t\t// dangerouslySetInnerHTML to set the inner html of the <code> element\n\t\t\t// and use Prism.js to \"highlight\" the code in a useEffect (client-side only)\n\t\t\tescapeHtml(normalizeIndentation(value, { indentation })),\n\t\t);\n\n\t\tuseEffect(() => {\n\t\t\tconst grammar = Highlighter.languages[language];\n\t\t\tassert(\n\t\t\t\tgrammar,\n\t\t\t\t`CodeBlock does not support the language \"${language}\". The syntax highlighter does not have a grammar for this language. The supported languages are: ${supportedLanguages.join(\", \")}.`,\n\t\t\t);\n\t\t\tconst newHighlightedCodeInnerHtml = Highlighter.highlight(\n\t\t\t\tnormalizedAndTrimmedValue,\n\t\t\t\tgrammar,\n\t\t\t\tlanguage,\n\t\t\t);\n\t\t\tsetHighlightedCodeInnerHtml(newHighlightedCodeInnerHtml);\n\t\t}, [normalizedAndTrimmedValue, language]);\n\n\t\tuseEffect(() => {\n\t\t\tsetCopyText(normalizedAndTrimmedValue);\n\t\t}, [normalizedAndTrimmedValue, setCopyText]);\n\n\t\tuseEffect(() => {\n\t\t\tregisterCodeId(id);\n\n\t\t\treturn () => {\n\t\t\t\tunregisterCodeId(id);\n\t\t\t};\n\t\t}, [id, registerCodeId, unregisterCodeId]);\n\n\t\tconst languageClassName = formatLanguageClassName(language);\n\n\t\treturn (\n\t\t\t<pre\n\t\t\t\taria-expanded={hasCodeExpander ? isCodeExpanded : undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"scrollbar firefox:after:mr-[3.375rem] firefox:after:inline-block firefox:after:content-[''] overflow-x-auto overflow-y-hidden p-4 pr-14\",\n\t\t\t\t\t\"text-size-inherit text-size-mono m-0 font-mono\",\n\t\t\t\t\t\"aria-collapsed:max-h-[13.6rem]\",\n\t\t\t\t\tlanguageClassName, // place it last because prism does weird stuff client side, causes hydration mismatches\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-lang={language}\n\t\t\t\tid={id}\n\t\t\t\tref={ref}\n\t\t\t\tstyle={{\n\t\t\t\t\t...style,\n\t\t\t\t\ttabSize: 2,\n\t\t\t\t\tMozTabSize: 2,\n\t\t\t\t}}\n\t\t\t\t// prism.js adds a tabindex of 0 to the pre element by default (unless it's set)\n\t\t\t\t// this is unnecessary, we do not want this automatic behavior!\n\t\t\t\ttabIndex={tabIndex ?? -1}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<code\n\t\t\t\t\tclassName={clsx(\"text-size-inherit\", languageClassName)}\n\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t__html: highlightedCodeInnerHtml,\n\t\t\t\t\t}}\n\t\t\t\t\t// we need to suppress the hydration warning because we are setting the innerHTML of the code block\n\t\t\t\t\t// and using Prism.js to \"highlight\" the code in a useEffect (client-side only), which does different things on the client and server\n\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t/>\n\t\t\t</pre>\n\t\t);\n\t},\n);\nCodeBlockCode.displayName = \"CodeBlockCode\";\n\n/**\n * The (optional) header slot of the `CodeBlock`. This is where things like the\n * `CodeBlockIcon` and `CodeBlockTitle` are rendered.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-header\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockHeader = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentProps<\"div\"> & WithAsChild\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst Component = asChild ? Slot : \"div\";\n\n\treturn (\n\t\t<Component\n\t\t\tclassName={cx(\n\t\t\t\t\"flex items-center gap-1 border-b border-gray-300 bg-gray-100 px-4 py-2 text-gray-700\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nCodeBlockHeader.displayName = \"CodeBlockHeader\";\n\n/**\n * The (optional) title of the `CodeBlock`. Default renders as an h3 element,\n * use asChild to render something else.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-title\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockTitle = forwardRef<\n\tHTMLHeadingElement,\n\tHTMLAttributes<HTMLHeadingElement> & { asChild?: boolean }\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst Component = asChild ? Slot : \"h3\";\n\n\treturn (\n\t\t<Component\n\t\t\tref={ref}\n\t\t\tclassName={cx(\"text-size-mono m-0 font-mono font-normal\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nCodeBlockTitle.displayName = \"CodeBlockTitle\";\n\ntype CodeBlockCopyButtonProps = Omit<\n\tComponentProps<\"button\">,\n\t\"children\" | \"type\"\n> &\n\tWithAsChild & {\n\t\t/**\n\t\t * Callback fired when the copy button is clicked, passes the copied text as an argument.\n\t\t */\n\t\tonCopy?: (value: string) => void;\n\t\t/**\n\t\t * Callback fired when an error occurs during copying.\n\t\t */\n\t\tonCopyError?: (error: unknown) => void;\n\t};\n\n/**\n * The (optional) copy button of the `CodeBlock`. Render this as a child of the\n * `CodeBlockBody` to allow users to copy the code block contents to their\n * clipboard.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-copy-button\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockCopyButton = forwardRef<\n\tComponentRef<\"button\">,\n\tCodeBlockCopyButtonProps\n>(\n\t(\n\t\t{ asChild = false, className, onCopy, onCopyError, onClick, ...props },\n\t\tref,\n\t) => {\n\t\tconst { copyText } = useContext(CodeBlockContext);\n\t\tconst [, copyToClipboard] = useCopyToClipboard();\n\t\tconst [wasCopied, setWasCopied] = useState(false);\n\t\tconst timeoutHandle = useRef<number>(0);\n\n\t\tconst Component = asChild ? Slot : \"button\";\n\n\t\treturn (\n\t\t\t<Component\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"focus-visible:border-accent-600 focus-visible:ring-focus-accent absolute right-2.5 top-2.5 z-10 flex size-7 items-center justify-center rounded border border-gray-300 bg-gray-50 shadow-[-1rem_0_0.75rem_-0.375rem_hsl(var(--gray-50)),1rem_0_0_-0.25rem_hsl(var(--gray-50))] hover:border-gray-400 hover:bg-gray-200 focus-visible:outline-none focus-visible:ring-4\",\n\t\t\t\t\twasCopied &&\n\t\t\t\t\t\t\"bg-filled-success text-on-filled hover:bg-filled-success focus:bg-filled-success focus-visible:border-success-600 focus-visible:ring-focus-success w-auto gap-1 border-transparent pl-2 pr-1.5 hover:border-transparent\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\tonClick={async (event) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tonClick?.(event);\n\t\t\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\t\t\t// Clear any existing timeout\n\t\t\t\t\t\t\twindow.clearTimeout(timeoutHandle.current);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait copyToClipboard(copyText);\n\t\t\t\t\t\tonCopy?.(copyText);\n\t\t\t\t\t\tsetWasCopied(true);\n\n\t\t\t\t\t\t// Clear any existing timeout\n\t\t\t\t\t\twindow.clearTimeout(timeoutHandle.current);\n\n\t\t\t\t\t\t// Reset the copied state after a short delay\n\t\t\t\t\t\ttimeoutHandle.current = window.setTimeout(() => {\n\t\t\t\t\t\t\tsetWasCopied(false);\n\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tonCopyError?.(error);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<span className=\"sr-only\">Copy code</span>\n\t\t\t\t{wasCopied ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\tCopied\n\t\t\t\t\t\t<Icon svg={<CheckIcon weight=\"bold\" />} className=\"size-4\" />\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<Icon svg={<CopyIcon />} className=\"-ml-px\" />\n\t\t\t\t)}\n\t\t\t</Component>\n\t\t);\n\t},\n);\nCodeBlockCopyButton.displayName = \"CodeBlockCopyButton\";\n\ntype CodeBlockExpanderButtonProps = Omit<\n\tComponentProps<\"button\">,\n\t\"children\" | \"aria-controls\" | \"aria-expanded\"\n> &\n\tWithAsChild;\n\n/**\n * The (optional) expander button of the `CodeBlock`. Render this as a child of the\n * `CodeBlockBody` to allow users to expand/collapse the code block contents.\n *\n * @note If this component is preset, the `CodeBlock` will automatically know\n * that it should be collapsible. Don't use this component if you don't want\n * the code block to be collapsible.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-expander-button\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockExpanderButton = forwardRef<\n\tComponentRef<\"button\">,\n\tCodeBlockExpanderButtonProps\n>(({ asChild = false, className, onClick, ...props }, ref) => {\n\tconst { codeId, isCodeExpanded, setIsCodeExpanded, setHasCodeExpander } =\n\t\tuseContext(CodeBlockContext);\n\n\tuseEffect(() => {\n\t\tsetHasCodeExpander(true);\n\n\t\treturn () => {\n\t\t\tsetHasCodeExpander(false);\n\t\t};\n\t}, [setHasCodeExpander]);\n\n\tconst Component = asChild ? Slot : \"button\";\n\n\treturn (\n\t\t<Component\n\t\t\t{...props}\n\t\t\taria-controls={codeId}\n\t\t\taria-expanded={isCodeExpanded}\n\t\t\tclassName={cx(\n\t\t\t\t\"flex w-full items-center justify-center gap-0.5 border-t border-gray-300 bg-gray-50 px-4 py-2 font-sans text-gray-700 hover:bg-gray-100\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\ttype=\"button\"\n\t\t\tonClick={(event) => {\n\t\t\t\tsetIsCodeExpanded((prev) => !prev);\n\t\t\t\tonClick?.(event);\n\t\t\t}}\n\t\t>\n\t\t\t{isCodeExpanded ? \"Show less\" : \"Show more\"}{\" \"}\n\t\t\t<Icon\n\t\t\t\tsvg={<CaretDownIcon weight=\"bold\" />}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"size-4\",\n\t\t\t\t\tisCodeExpanded && \"rotate-180\",\n\t\t\t\t\t\"transition-all duration-150\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</Component>\n\t);\n});\nCodeBlockExpanderButton.displayName = \"CodeBlockExpanderButton\";\n\ntype CodeBlockIconProps = Omit<SvgAttributes, \"children\"> &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * A custom icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tsvg: ReactNode;\n\t\t\t\t/**\n\t\t\t\t * A preset icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tpreset?: undefined | never;\n\t\t }\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * A custom icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tsvg?: undefined | never;\n\t\t\t\t/**\n\t\t\t\t * A preset icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tpreset: Mode;\n\t\t }\n\t);\n\n/**\n * A small icon that represents the type of code block being displayed,\n * rendered as an SVG next to the code block title in the code block header.\n *\n * You can pass in a custom SVG component or use one of the presets\n * (pass only one of `svg` or `preset`).\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-icon\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nfunction CodeBlockIcon({\n\tclassName,\n\tpreset,\n\tsvg: _svgProp,\n\t...props\n}: CodeBlockIconProps) {\n\tlet svg = _svgProp;\n\tif (preset != null) {\n\t\tswitch (preset) {\n\t\t\tcase \"file\":\n\t\t\t\tsvg = <FileTextIcon weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"cli\":\n\t\t\t\tsvg = <TerminalIcon weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"traffic-policy\":\n\t\t\t\tsvg = <TrafficPolicyFileIcon />;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn <Icon className={className} svg={svg} {...props} />;\n}\n\nexport {\n\tCodeBlock,\n\tCodeBlockBody,\n\tCodeBlockCode,\n\tCodeBlockCopyButton,\n\tCodeBlockExpanderButton,\n\tCodeBlockHeader,\n\tCodeBlockIcon,\n\tCodeBlockTitle,\n};\n","/**\n * Escapes special HTML characters in a string to their corresponding\n * HTML entities, preventing issues like unintended HTML rendering or\n * cross-site scripting (XSS) when injecting raw strings into the DOM\n * using `dangerouslySetInnerHTML`.\n *\n * Characters escaped:\n * - \\& => `&amp`;\n * - \\< => `&lt`;\n * - \\> => `&gt`;\n * - \\\" => `&quot`;\n * - \\' => `&#39`;\n *\n * @param {string} value The raw string to be escaped.\n *\n * @example\n * escapeHtml('<div>Hello & \"world\"</div>');\n * // Returns: '&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;'\n */\nfunction escapeHtml(value: string): string {\n\tlet escaped = \"\";\n\tfor (const character of value) {\n\t\tswitch (character) {\n\t\t\tcase \"&\":\n\t\t\t\tescaped += \"&amp;\";\n\t\t\t\tbreak;\n\t\t\tcase \"<\":\n\t\t\t\tescaped += \"&lt;\";\n\t\t\t\tbreak;\n\t\t\tcase \">\":\n\t\t\t\tescaped += \"&gt;\";\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\tescaped += \"&quot;\";\n\t\t\t\tbreak;\n\t\t\tcase \"'\":\n\t\t\t\tescaped += \"&#39;\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tescaped += character;\n\t\t}\n\t}\n\treturn escaped;\n}\n\nexport {\n\t//,\n\tescapeHtml,\n};\n","import Prism from \"prismjs\";\nimport \"prismjs/components/prism-bash.js\";\nimport \"prismjs/components/prism-csharp.js\";\nimport \"prismjs/components/prism-css.js\";\nimport \"prismjs/components/prism-go.js\";\nimport \"prismjs/components/prism-java.js\";\nimport \"prismjs/components/prism-javascript.js\";\nimport \"prismjs/components/prism-json.js\";\nimport \"prismjs/components/prism-jsx.js\";\nimport \"prismjs/components/prism-markup.js\";\nimport \"prismjs/components/prism-python.js\";\nimport \"prismjs/components/prism-ruby.js\";\nimport \"prismjs/components/prism-rust.js\";\nimport \"prismjs/components/prism-tsx.js\";\nimport \"prismjs/components/prism-typescript.js\";\nimport \"prismjs/components/prism-yaml.js\";\n\nexport {\n\t//,\n\tPrism as Highlighter,\n};\n","import type { SupportedLanguage } from \"./supported-languages.js\";\n\nconst indentations = [\"tabs\", \"spaces\"] as const;\ntype Indentation = (typeof indentations)[number];\n\n/**\n * Type Predicate: checks if the given value is a valid indentation type.\n */\nfunction isIndentation(input: unknown): input is Indentation {\n\treturn indentations.includes(input as Indentation);\n}\n\n/**\n * Infers the indentation type based on the language and preferred indentation.\n *\n * @param language - The language to check.\n * @param preferredIndentation - The preferred indentation type (overrides what is detected).\n */\nfunction inferIndentation(\n\tlanguage: SupportedLanguage,\n\tpreferredIndentation: Indentation | undefined,\n) {\n\t// if the user has a preferred indentation, use that regardless of the language\n\tif (preferredIndentation) {\n\t\treturn preferredIndentation;\n\t}\n\n\tif (isTabIndentedLanguage(language)) {\n\t\treturn \"tabs\";\n\t}\n\n\tif (isSpaceIndentedLanguage(language)) {\n\t\treturn \"spaces\";\n\t}\n\n\treturn \"spaces\";\n}\n\nexport {\n\t//,\n\tindentations,\n\tinferIndentation,\n\tisIndentation,\n};\n\nexport type {\n\t//,\n\tIndentation,\n};\n\n/**\n * Languages that require or strongly prefer tabs\n */\nconst tabIndentedLanguages = [\n\t\"csharp\",\n\t\"css\",\n\t\"go\",\n\t\"html\",\n\t\"java\",\n\t\"javascript\",\n\t\"js\",\n\t\"jsx\",\n\t\"ts\",\n\t\"tsx\",\n\t\"typescript\",\n\t\"xml\",\n] as const satisfies SupportedLanguage[];\n\n/**\n * Languages that require or strongly prefer spaces\n */\nconst spaceIndentedLanguages = [\n\t\"python\",\n\t\"py\",\n\t\"yaml\",\n\t\"yml\",\n\t\"ruby\",\n\t\"rb\",\n] as const satisfies SupportedLanguage[];\n\ntype TabIndentedLanguage = (typeof tabIndentedLanguages)[number];\ntype SpaceIndentedLanguage = (typeof spaceIndentedLanguages)[number];\n\n/**\n * Type Predicate: checks if the given value is a required/preferred tab-indented language.\n */\nfunction isTabIndentedLanguage(\n\tvalue: SupportedLanguage,\n): value is TabIndentedLanguage {\n\treturn tabIndentedLanguages.includes(value as TabIndentedLanguage);\n}\n\n/**\n * Type Predicate: checks if the given value is a required/preferred space-indented language.\n */\nfunction isSpaceIndentedLanguage(\n\tvalue: SupportedLanguage,\n): value is SpaceIndentedLanguage {\n\treturn spaceIndentedLanguages.includes(value as SpaceIndentedLanguage);\n}\n","import type { Indentation } from \"./indentation.js\";\n\ntype Options = {\n\t/**\n\t * The indentation type to use. Can be either \"tabs\" or \"spaces\".\n\t * @default \"spaces\"\n\t */\n\tindentation?: Indentation;\n};\n\n/**\n * Trim any leading and trailing whitespace/empty lines, convert leading\n * indentation to the given options.indentation\n */\nfunction normalizeIndentation(value: string, options?: Options): string {\n\tconst { indentation = \"spaces\" } = options || {};\n\n\treturn value.trim().replace(/^[ \\t]*(?=\\S)/gm, (match) => {\n\t\t// 1 tab === 2 spaces\n\t\t// convert tabs to spaces and spaces to tabs\n\t\tif (indentation === \"spaces\") {\n\t\t\treturn match.replace(/\\t/g, \" \");\n\t\t}\n\t\treturn match.replace(/ {2}/g, \"\\t\");\n\t});\n}\n\nexport {\n\t//,\n\tnormalizeIndentation,\n};\n","/**\n * List of supported languages for syntax highlighting.\n * @private\n */\nexport const supportedLanguages = [\n\t\"bash\",\n\t\"cs\",\n\t\"csharp\",\n\t\"css\",\n\t\"dotnet\",\n\t\"go\",\n\t\"html\",\n\t\"java\",\n\t\"javascript\",\n\t\"js\",\n\t\"json\",\n\t\"jsx\",\n\t\"markup\",\n\t\"plain\",\n\t\"plaintext\",\n\t\"py\",\n\t\"python\",\n\t\"rb\",\n\t\"ruby\",\n\t\"rust\",\n\t\"sh\",\n\t\"shell\",\n\t\"text\",\n\t\"ts\",\n\t\"tsx\",\n\t\"txt\",\n\t\"typescript\",\n\t\"xml\",\n\t\"yaml\",\n\t\"yml\",\n] as const;\n\n/**\n * Supported languages for syntax highlighting.\n */\ntype SupportedLanguage = (typeof supportedLanguages)[number];\n\n/**\n * Parses a markdown code block (```) language class into a SupportedLanguage.\n * Defaults to \"sh\" if no supported language is found.\n */\nfunction parseLanguage(\n\tvalue: `language-${string}` | `lang-${string}` | (string & {}) | undefined,\n): SupportedLanguage {\n\tif (!value) {\n\t\treturn \"sh\";\n\t}\n\n\t// remove leading \"language-\" and \"lang-\" prefixes\n\t// find first '-' and slice from there\n\tconst maybeLanguage = value.trim().slice(value.indexOf(\"-\") + 1);\n\n\treturn isSupportedLanguage(maybeLanguage) ? maybeLanguage : \"sh\";\n}\n\n/**\n * Type Predicate: checks if an arbitrary value is a supported syntax highlighting language.\n */\nconst isSupportedLanguage = (value: unknown): value is SupportedLanguage => {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tsupportedLanguages.includes(value as SupportedLanguage)\n\t);\n};\n\n/**\n * A class name for a language that Prism.js can understand.\n */\ntype LanguageClass = `language-${SupportedLanguage}`;\n\n/**\n * Formats a language name into a class name that Prism.js can understand.\n * @default \"language-sh\"\n */\nfunction formatLanguageClassName(\n\tlanguage: SupportedLanguage | undefined = \"sh\",\n) {\n\tconst lang = language ?? \"sh\";\n\tconst className: LanguageClass = `language-${lang}`;\n\treturn className;\n}\n\nexport { isSupportedLanguage, parseLanguage, formatLanguageClassName };\nexport type { SupportedLanguage };\n","type Primitive = string | number | boolean | undefined | null;\n\n/**\n * Tagged template literal to format code blocks and normalize leading indentation\n */\nfunction fmtCode(\n\tstrings: TemplateStringsArray,\n\t...values: Primitive[]\n): string {\n\tif (!isTemplateStringsArray(strings) || !Array.isArray(values)) {\n\t\tthrow new Error(\n\t\t\t\"It looks like you tried to call `fmtCode` as a function. Make sure to use it as a tagged template.\\n\\tExample: fmtCode`SELECT * FROM users`, not fmtCode('SELECT * FROM users')\",\n\t\t);\n\t}\n\n\tconst text = String.raw({ raw: strings }, ...values);\n\n\t// fine the minimum indentation of the code block\n\tconst minIndent = findMinIndent(text);\n\tconst lines = text.trim().split(\"\\n\");\n\n\treturn lines\n\t\t.map((line) => {\n\t\t\t// remove nothing if the line doesn't start with indentation\n\t\t\tif (/^\\S+/.test(line)) {\n\t\t\t\treturn line;\n\t\t\t}\n\t\t\treturn line.slice(minIndent);\n\t\t})\n\t\t.join(\"\\n\");\n}\n\nexport {\n\t//,\n\tfmtCode,\n};\n\n/**\n * Find the shortest indentation of a multiline string\n */\nfunction findMinIndent(value: string): number {\n\tconst match = value.match(/^[ \\t]*(?=\\S)/gm);\n\n\tif (!match) {\n\t\treturn 0;\n\t}\n\n\treturn match.reduce(\n\t\t(acc, curr) => Math.min(acc, curr.length),\n\t\tNumber.POSITIVE_INFINITY,\n\t);\n}\n\n/**\n * Type guard to check if a value is a `TemplateStringsArray`\n */\nfunction isTemplateStringsArray(\n\tstrings: unknown,\n): strings is TemplateStringsArray {\n\treturn (\n\t\tArray.isArray(strings) && \"raw\" in strings && Array.isArray(strings.raw)\n\t);\n}\n","import { parseBooleanish } from \"../../types/booleanish.js\";\nimport { type Indentation, isIndentation } from \"./indentation.js\";\n\nconst modes = [\n\t//,\n\t\"cli\",\n\t\"file\",\n\t\"traffic-policy\",\n] as const;\ntype Mode = (typeof modes)[number];\n\ntype MetaInput = {\n\tcollapsible?: boolean | undefined;\n\tdisableCopy?: boolean | undefined;\n\tindentation?: Indentation | undefined;\n\tmode?: Mode | undefined;\n\ttitle?: string | undefined;\n};\n\ntype Meta = {\n\tcollapsible: boolean;\n\tdisableCopy: boolean;\n\tindentation?: Indentation | undefined;\n\tmode?: Mode | undefined;\n\ttitle?: string | undefined;\n};\n\nconst defaultMeta = {\n\tcollapsible: false,\n\tdisableCopy: false,\n\tindentation: undefined,\n\tmode: undefined,\n\ttitle: undefined,\n} as const satisfies Meta;\n\ntype DefaultMeta = typeof defaultMeta;\n\n/**\n * Parses a markdown code block (```) metastring into a meta object.\n * Defaults to DefaultMeta if no metastring given or if metastring is invalid.\n * Useful for parsing the metastring from a markdown code block to pass into the\n * CodeBlock components as props.\n */\nfunction parseMetastring(input: string | undefined): Meta {\n\tconst metastring = input?.trim() ?? \"\";\n\tif (!metastring) {\n\t\treturn defaultMeta;\n\t}\n\n\tconst metaJson = tokenizeMetastring(metastring).reduce<\n\t\tRecord<string, unknown>\n\t>((acc, token) => {\n\t\tconst [key, value] = token.split(\"=\");\n\t\tif (!key) {\n\t\t\treturn acc;\n\t\t}\n\t\tconst normalizedValue = normalizeValue(value);\n\t\tacc[key] = normalizedValue ?? true;\n\t\treturn acc;\n\t}, {});\n\n\ttry {\n\t\tconst parsed = parseMetaJson(metaJson);\n\n\t\t// return the parsed meta object, with default values filled in\n\t\treturn {\n\t\t\t...defaultMeta,\n\t\t\t...parsed,\n\t\t};\n\t} catch (_) {\n\t\treturn defaultMeta;\n\t}\n}\n\nexport {\n\t//,\n\tdefaultMeta,\n\tparseMetastring,\n};\nexport type {\n\t//,\n\tMeta,\n\tMetaInput,\n\tMode,\n\tDefaultMeta,\n};\n\n/**\n * Remove leading and trailing `\"` quotes around value\n * @private\n */\nexport function normalizeValue(value: string | undefined) {\n\treturn value?.trim().replace(/^\"(.*)\"$/, \"$1\");\n}\n\n/**\n * Splits a metastring into an array of tokens that can be parsed into a meta object.\n * Should allow for quotes and spaces in tokens\n * @private\n */\nexport function tokenizeMetastring(value: string | undefined): string[] {\n\tconst input = value?.trim() ?? \"\";\n\tconst result: string[] = [];\n\n\tlet currentString = \"\";\n\tlet inQuotes = false;\n\n\tfor (const char of input) {\n\t\tif (char === \" \" && !inQuotes) {\n\t\t\tif (currentString) {\n\t\t\t\tresult.push(currentString);\n\t\t\t\tcurrentString = \"\";\n\t\t\t}\n\t\t} else if (char === '\"') {\n\t\t\tinQuotes = !inQuotes;\n\t\t\tcurrentString += char;\n\t\t} else {\n\t\t\tcurrentString += char;\n\t\t}\n\t}\n\n\tif (currentString) {\n\t\tresult.push(currentString);\n\t}\n\n\treturn result;\n}\n\n/**\n * Type Predicate: checks if the given value is a valid mode.\n * @private\n */\nfunction isMode(input: unknown): input is Mode {\n\treturn modes.includes(input as Mode);\n}\n\n/**\n * Parses a meta JSON object into a Meta object.\n * @private\n */\nfunction parseMetaJson(input: Record<string, unknown>): Meta {\n\tconst {\n\t\tcollapsible = defaultMeta.collapsible,\n\t\tdisableCopy = defaultMeta.disableCopy,\n\t\tindentation = defaultMeta.indentation,\n\t\tmode = defaultMeta.mode,\n\t\ttitle = defaultMeta.title,\n\t} = input;\n\n\treturn {\n\t\tcollapsible:\n\t\t\ttypeof collapsible === \"string\" || typeof collapsible === \"boolean\"\n\t\t\t\t? parseBooleanish(collapsible)\n\t\t\t\t: defaultMeta.collapsible,\n\t\tdisableCopy:\n\t\t\ttypeof disableCopy === \"string\" || typeof disableCopy === \"boolean\"\n\t\t\t\t? parseBooleanish(disableCopy)\n\t\t\t\t: defaultMeta.disableCopy,\n\t\tindentation: isIndentation(indentation)\n\t\t\t? indentation\n\t\t\t: defaultMeta.indentation,\n\t\tmode: isMode(mode) ? mode : defaultMeta.mode,\n\t\ttitle: typeof title === \"string\" ? title.trim() : defaultMeta.title,\n\t};\n}\n"],"mappings":"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","names":["CaretDownIcon","CheckIcon","CopyIcon","FileTextIcon","TerminalIcon","Slot","clsx","createContext","forwardRef","useContext","useEffect","useId","useMemo","useRef","useState","assert","escapeHtml","value","escaped","character","Prism","indentations","isIndentation","input","inferIndentation","language","preferredIndentation","isTabIndentedLanguage","isSpaceIndentedLanguage","tabIndentedLanguages","spaceIndentedLanguages","isTabIndentedLanguage","value","isSpaceIndentedLanguage","normalizeIndentation","value","options","indentation","match","supportedLanguages","parseLanguage","value","maybeLanguage","isSupportedLanguage","formatLanguageClassName","language","Fragment","jsx","jsxs","CodeBlockContext","createContext","CodeBlock","forwardRef","asChild","className","props","ref","copyText","setCopyText","useState","hasCodeExpander","setHasCodeExpander","isCodeExpanded","setIsCodeExpanded","codeId","setCodeId","context","useMemo","id","old","assert","Component","Slot","cx","CodeBlockBody","CodeBlockCode","_unusedHighlightLines","propIndentation","language","_unusedShowLineNumbers","style","tabIndex","value","useId","registerCodeId","unregisterCodeId","useContext","indentation","inferIndentation","normalizedAndTrimmedValue","normalizeIndentation","highlightedCodeInnerHtml","setHighlightedCodeInnerHtml","escapeHtml","useEffect","grammar","Prism","supportedLanguages","newHighlightedCodeInnerHtml","languageClassName","formatLanguageClassName","clsx","CodeBlockHeader","CodeBlockTitle","CodeBlockCopyButton","onCopy","onCopyError","onClick","copyToClipboard","useCopyToClipboard","wasCopied","setWasCopied","timeoutHandle","useRef","event","error","Icon","CheckIcon","CopyIcon","CodeBlockExpanderButton","prev","CaretDownIcon","CodeBlockIcon","preset","_svgProp","svg","FileTextIcon","TerminalIcon","TrafficPolicyFileIcon","fmtCode","strings","values","isTemplateStringsArray","text","minIndent","findMinIndent","line","findMinIndent","value","match","acc","curr","isTemplateStringsArray","strings","modes","defaultMeta","parseMetastring","input","metastring","metaJson","tokenizeMetastring","acc","token","key","value","normalizedValue","normalizeValue","parsed","parseMetaJson","normalizeValue","value","tokenizeMetastring","input","result","currentString","inQuotes","char","isMode","modes","parseMetaJson","collapsible","defaultMeta","disableCopy","indentation","mode","title","parseBooleanish","isIndentation"]}
1
+ {"version":3,"sources":["../src/components/code-block/code-block.tsx","../src/components/code-block/escape-html.ts","../src/components/code-block/highlighter.ts","../src/components/code-block/indentation.ts","../src/components/code-block/normalize.ts","../src/components/code-block/supported-languages.ts","../src/components/code-block/fmt-code.ts","../src/components/code-block/parse-metastring.ts"],"sourcesContent":["\"use client\";\n\nimport { CaretDownIcon } from \"@phosphor-icons/react/CaretDown\";\nimport { CheckIcon } from \"@phosphor-icons/react/Check\";\nimport { CopyIcon } from \"@phosphor-icons/react/Copy\";\nimport { FileTextIcon } from \"@phosphor-icons/react/FileText\";\nimport { TerminalIcon } from \"@phosphor-icons/react/Terminal\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport clsx from \"clsx\";\nimport type {\n\tComponentProps,\n\tComponentRef,\n\tDispatch,\n\tHTMLAttributes,\n\tReactNode,\n\tSetStateAction,\n} from \"react\";\nimport {\n\tcreateContext,\n\tforwardRef,\n\tuseContext,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport assert from \"tiny-invariant\";\nimport { useCopyToClipboard } from \"../../hooks/use-copy-to-clipboard.js\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Icon } from \"../icon/icon.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { TrafficPolicyFileIcon } from \"../icons/traffic-policy-file.js\";\nimport { escapeHtml } from \"./escape-html.js\";\nimport { Highlighter } from \"./highlighter.js\";\nimport { type Indentation, inferIndentation } from \"./indentation.js\";\nimport type { LineRange } from \"./line-numbers.js\";\nimport { normalizeIndentation } from \"./normalize.js\";\nimport type { Mode } from \"./parse-metastring.js\";\nimport type { SupportedLanguage } from \"./supported-languages.js\";\nimport {\n\tformatLanguageClassName,\n\tsupportedLanguages,\n} from \"./supported-languages.js\";\n\n/**\n * TODO(cody):\n * - fix line numbers, maybe try grid instead of :before and flex?\n * - fix line hightlighting\n * - fix line wrapping? horizontal scrolling has problems w/ line highlighting :(\n */\n\ntype CodeBlockContextType = {\n\tcodeId: string | undefined;\n\tcopyText: string;\n\thasCodeExpander: boolean;\n\tisCodeExpanded: boolean;\n\tregisterCodeId: (id: string) => void;\n\tsetCopyText: (newCopyText: string) => void;\n\tsetHasCodeExpander: (value: boolean) => void;\n\tsetIsCodeExpanded: Dispatch<SetStateAction<boolean>>;\n\tunregisterCodeId: (id: string) => void;\n};\n\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n\tcodeId: undefined,\n\tcopyText: \"\",\n\thasCodeExpander: false,\n\tisCodeExpanded: false,\n\tregisterCodeId: () => {},\n\tsetCopyText: () => {},\n\tsetHasCodeExpander: () => {},\n\tsetIsCodeExpanded: () => {},\n\tunregisterCodeId: () => {},\n});\n\n/**\n * Code blocks render and apply syntax highlighting to blocks of code.\n * This is the root component for all code block components.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlock = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentProps<\"div\"> & WithAsChild\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst [copyText, setCopyText] = useState(\"\");\n\tconst [hasCodeExpander, setHasCodeExpander] = useState(false);\n\tconst [isCodeExpanded, setIsCodeExpanded] = useState(false);\n\tconst [codeId, setCodeId] = useState<string | undefined>(undefined);\n\n\tconst context: CodeBlockContextType = useMemo(\n\t\t() =>\n\t\t\t({\n\t\t\t\tcodeId,\n\t\t\t\tcopyText,\n\t\t\t\thasCodeExpander,\n\t\t\t\tisCodeExpanded,\n\t\t\t\tregisterCodeId: (id) => {\n\t\t\t\t\tsetCodeId((old) => {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\told == null,\n\t\t\t\t\t\t\t\"You can only render a single CodeBlockCode within a CodeBlock.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn id;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tsetCopyText,\n\t\t\t\tsetHasCodeExpander,\n\t\t\t\tsetIsCodeExpanded,\n\t\t\t\tunregisterCodeId: (id) => {\n\t\t\t\t\tsetCodeId((old) => {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\told === id,\n\t\t\t\t\t\t\t\"You can only render a single CodeBlockCode within a CodeBlock.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t}) as const,\n\t\t[codeId, copyText, hasCodeExpander, isCodeExpanded],\n\t);\n\n\tconst Component = asChild ? Slot : \"div\";\n\n\treturn (\n\t\t<CodeBlockContext.Provider value={context}>\n\t\t\t<Component\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"text-size-mono overflow-hidden rounded-md border border-gray-300 bg-gray-50 font-mono\",\n\t\t\t\t\t\"[&_svg]:shrink-0\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</CodeBlockContext.Provider>\n\t);\n});\nCodeBlock.displayName = \"CodeBlock\";\n\n/**\n * The body of the `CodeBlock`. This is where the `CodeBlockCode` and optional\n * `CodeBlockCopyButton` is rendered.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-body\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockBody = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentProps<\"div\"> & WithAsChild\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst Component = asChild ? Slot : \"div\";\n\n\treturn (\n\t\t<Component className={cx(\"relative\", className)} ref={ref} {...props} />\n\t);\n});\nCodeBlockBody.displayName = \"CodeBlockBody\";\n\ntype CodeBlockCodeProps = Omit<ComponentProps<\"pre\">, \"children\"> & {\n\t/**\n\t * The code to display in the code block. Should be code formatted as a string. This code will be passed to our syntax highlighter.\n\t */\n\tvalue: string;\n\t/**\n\t * @todo not implemented yet\n\t */\n\thighlightLines?: (LineRange | number)[];\n\t/**\n\t * The type of indentation to use. Can be either \"tabs\" or \"spaces\".\n\t * @default inferred from the given language, fallback to `spaces`\n\t */\n\tindentation?: Indentation;\n\t/**\n\t * The language of the code block. This will be used to determine how to syntax highlight the code.\n\t * @default `\"text\"`.\n\t */\n\tlanguage?: SupportedLanguage;\n\t/**\n\t * @todo not implemented yet\n\t */\n\tshowLineNumbers?: boolean;\n};\n\n/**\n * The `CodeBlock` content. This is where the code is rendered and syntax highlighted.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-code\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode\n * language=\"sh\"\n * value={fmtCode`ffmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4`}\n * />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockCode = forwardRef<ComponentRef<\"pre\">, CodeBlockCodeProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\thighlightLines: _unusedHighlightLines, // not implemented yet\n\t\t\tindentation: propIndentation,\n\t\t\tlanguage = \"text\",\n\t\t\tshowLineNumbers: _unusedShowLineNumbers, // not implemented yet\n\t\t\tstyle,\n\t\t\ttabIndex,\n\t\t\tvalue,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst id = useId();\n\t\tconst {\n\t\t\thasCodeExpander,\n\t\t\tisCodeExpanded,\n\t\t\tregisterCodeId,\n\t\t\tsetCopyText,\n\t\t\tunregisterCodeId,\n\t\t} = useContext(CodeBlockContext);\n\t\tconst indentation = inferIndentation(language, propIndentation);\n\n\t\t// trim any leading and trailing whitespace/empty lines, convert leading tabs to spaces\n\t\tconst normalizedAndTrimmedValue = useMemo(\n\t\t\t() => normalizeIndentation(value, { indentation }),\n\t\t\t[value, indentation],\n\t\t);\n\t\tconst [highlightedCodeInnerHtml, setHighlightedCodeInnerHtml] = useState(\n\t\t\t// initialize the <code> inner html with escaped HTML since we are using\n\t\t\t// dangerouslySetInnerHTML to set the inner html of the <code> element\n\t\t\t// and use Prism.js to \"highlight\" the code in a useEffect (client-side only)\n\t\t\tescapeHtml(normalizeIndentation(value, { indentation })),\n\t\t);\n\n\t\tuseEffect(() => {\n\t\t\tconst grammar = Highlighter.languages[language];\n\t\t\tassert(\n\t\t\t\tgrammar,\n\t\t\t\t`CodeBlock does not support the language \"${language}\". The syntax highlighter does not have a grammar for this language. The supported languages are: ${supportedLanguages.join(\", \")}.`,\n\t\t\t);\n\t\t\tconst newHighlightedCodeInnerHtml = Highlighter.highlight(\n\t\t\t\tnormalizedAndTrimmedValue,\n\t\t\t\tgrammar,\n\t\t\t\tlanguage,\n\t\t\t);\n\t\t\tsetHighlightedCodeInnerHtml(newHighlightedCodeInnerHtml);\n\t\t}, [normalizedAndTrimmedValue, language]);\n\n\t\tuseEffect(() => {\n\t\t\tsetCopyText(normalizedAndTrimmedValue);\n\t\t}, [normalizedAndTrimmedValue, setCopyText]);\n\n\t\tuseEffect(() => {\n\t\t\tregisterCodeId(id);\n\n\t\t\treturn () => {\n\t\t\t\tunregisterCodeId(id);\n\t\t\t};\n\t\t}, [id, registerCodeId, unregisterCodeId]);\n\n\t\tconst languageClassName = formatLanguageClassName(language);\n\n\t\treturn (\n\t\t\t<pre\n\t\t\t\taria-expanded={hasCodeExpander ? isCodeExpanded : undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"scrollbar firefox:after:mr-[3.375rem] firefox:after:inline-block firefox:after:content-[''] overflow-x-auto overflow-y-hidden p-4 pr-14\",\n\t\t\t\t\t\"text-size-inherit text-size-mono m-0 font-mono\",\n\t\t\t\t\t\"aria-collapsed:max-h-[13.6rem]\",\n\t\t\t\t\tlanguageClassName, // place it last because prism does weird stuff client side, causes hydration mismatches\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-lang={language}\n\t\t\t\tid={id}\n\t\t\t\tref={ref}\n\t\t\t\tstyle={{\n\t\t\t\t\t...style,\n\t\t\t\t\ttabSize: 2,\n\t\t\t\t\tMozTabSize: 2,\n\t\t\t\t}}\n\t\t\t\t// prism.js adds a tabindex of 0 to the pre element by default (unless it's set)\n\t\t\t\t// this is unnecessary, we do not want this automatic behavior!\n\t\t\t\ttabIndex={tabIndex ?? -1}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<code\n\t\t\t\t\tclassName={clsx(\"text-size-inherit\", languageClassName)}\n\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t__html: highlightedCodeInnerHtml,\n\t\t\t\t\t}}\n\t\t\t\t\t// we need to suppress the hydration warning because we are setting the innerHTML of the code block\n\t\t\t\t\t// and using Prism.js to \"highlight\" the code in a useEffect (client-side only), which does different things on the client and server\n\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t/>\n\t\t\t</pre>\n\t\t);\n\t},\n);\nCodeBlockCode.displayName = \"CodeBlockCode\";\n\n/**\n * The (optional) header slot of the `CodeBlock`. This is where things like the\n * `CodeBlockIcon` and `CodeBlockTitle` are rendered.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-header\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockHeader = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentProps<\"div\"> & WithAsChild\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst Component = asChild ? Slot : \"div\";\n\n\treturn (\n\t\t<Component\n\t\t\tclassName={cx(\n\t\t\t\t\"flex items-center gap-1 border-b border-gray-300 bg-gray-100 px-4 py-2 text-gray-700\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nCodeBlockHeader.displayName = \"CodeBlockHeader\";\n\n/**\n * The (optional) title of the `CodeBlock`. Default renders as an h3 element,\n * use asChild to render something else.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-title\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockTitle = forwardRef<\n\tHTMLHeadingElement,\n\tHTMLAttributes<HTMLHeadingElement> & { asChild?: boolean }\n>(({ asChild = false, className, ...props }, ref) => {\n\tconst Component = asChild ? Slot : \"h3\";\n\n\treturn (\n\t\t<Component\n\t\t\tref={ref}\n\t\t\tclassName={cx(\"text-size-mono m-0 font-mono font-normal\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nCodeBlockTitle.displayName = \"CodeBlockTitle\";\n\ntype CodeBlockCopyButtonProps = Omit<\n\tComponentProps<\"button\">,\n\t\"children\" | \"type\"\n> &\n\tWithAsChild & {\n\t\t/**\n\t\t * Callback fired when the copy button is clicked, passes the copied text as an argument.\n\t\t */\n\t\tonCopy?: (value: string) => void;\n\t\t/**\n\t\t * Callback fired when an error occurs during copying.\n\t\t */\n\t\tonCopyError?: (error: unknown) => void;\n\t};\n\n/**\n * The (optional) copy button of the `CodeBlock`. Render this as a child of the\n * `CodeBlockBody` to allow users to copy the code block contents to their\n * clipboard.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-copy-button\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockCopyButton = forwardRef<\n\tComponentRef<\"button\">,\n\tCodeBlockCopyButtonProps\n>(\n\t(\n\t\t{ asChild = false, className, onCopy, onCopyError, onClick, ...props },\n\t\tref,\n\t) => {\n\t\tconst { copyText } = useContext(CodeBlockContext);\n\t\tconst [, copyToClipboard] = useCopyToClipboard();\n\t\tconst [wasCopied, setWasCopied] = useState(false);\n\t\tconst timeoutHandle = useRef<number>(0);\n\n\t\tconst Component = asChild ? Slot : \"button\";\n\n\t\treturn (\n\t\t\t<Component\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"focus-visible:border-accent-600 focus-visible:ring-focus-accent absolute right-2.5 top-2.5 z-10 flex size-7 items-center justify-center rounded border border-gray-300 bg-gray-50 shadow-[-1rem_0_0.75rem_-0.375rem_hsl(var(--gray-50)),1rem_0_0_-0.25rem_hsl(var(--gray-50))] hover:border-gray-400 hover:bg-gray-200 focus-visible:outline-none focus-visible:ring-4\",\n\t\t\t\t\twasCopied &&\n\t\t\t\t\t\t\"bg-filled-success text-on-filled hover:bg-filled-success focus:bg-filled-success focus-visible:border-success-600 focus-visible:ring-focus-success w-auto gap-1 border-transparent pl-2 pr-1.5 hover:border-transparent\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\tonClick={async (event) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tonClick?.(event);\n\t\t\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\t\t\t// Clear any existing timeout\n\t\t\t\t\t\t\twindow.clearTimeout(timeoutHandle.current);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait copyToClipboard(copyText);\n\t\t\t\t\t\tonCopy?.(copyText);\n\t\t\t\t\t\tsetWasCopied(true);\n\n\t\t\t\t\t\t// Clear any existing timeout\n\t\t\t\t\t\twindow.clearTimeout(timeoutHandle.current);\n\n\t\t\t\t\t\t// Reset the copied state after a short delay\n\t\t\t\t\t\ttimeoutHandle.current = window.setTimeout(() => {\n\t\t\t\t\t\t\tsetWasCopied(false);\n\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tonCopyError?.(error);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<span className=\"sr-only\">Copy code</span>\n\t\t\t\t{wasCopied ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\tCopied\n\t\t\t\t\t\t<Icon svg={<CheckIcon weight=\"bold\" />} className=\"size-4\" />\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<Icon svg={<CopyIcon />} className=\"-ml-px\" />\n\t\t\t\t)}\n\t\t\t</Component>\n\t\t);\n\t},\n);\nCodeBlockCopyButton.displayName = \"CodeBlockCopyButton\";\n\ntype CodeBlockExpanderButtonProps = Omit<\n\tComponentProps<\"button\">,\n\t\"children\" | \"aria-controls\" | \"aria-expanded\"\n> &\n\tWithAsChild;\n\n/**\n * The (optional) expander button of the `CodeBlock`. Render this as a child of the\n * `CodeBlockBody` to allow users to expand/collapse the code block contents.\n *\n * @note If this component is preset, the `CodeBlock` will automatically know\n * that it should be collapsible. Don't use this component if you don't want\n * the code block to be collapsible.\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-expander-button\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nconst CodeBlockExpanderButton = forwardRef<\n\tComponentRef<\"button\">,\n\tCodeBlockExpanderButtonProps\n>(({ asChild = false, className, onClick, ...props }, ref) => {\n\tconst { codeId, isCodeExpanded, setIsCodeExpanded, setHasCodeExpander } =\n\t\tuseContext(CodeBlockContext);\n\n\tuseEffect(() => {\n\t\tsetHasCodeExpander(true);\n\n\t\treturn () => {\n\t\t\tsetHasCodeExpander(false);\n\t\t};\n\t}, [setHasCodeExpander]);\n\n\tconst Component = asChild ? Slot : \"button\";\n\n\treturn (\n\t\t<Component\n\t\t\t{...props}\n\t\t\taria-controls={codeId}\n\t\t\taria-expanded={isCodeExpanded}\n\t\t\tclassName={cx(\n\t\t\t\t\"flex w-full items-center justify-center gap-0.5 border-t border-gray-300 bg-gray-50 px-4 py-2 font-sans text-gray-700 hover:bg-gray-100\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\ttype=\"button\"\n\t\t\tonClick={(event) => {\n\t\t\t\tsetIsCodeExpanded((prev) => !prev);\n\t\t\t\tonClick?.(event);\n\t\t\t}}\n\t\t>\n\t\t\t{isCodeExpanded ? \"Show less\" : \"Show more\"}{\" \"}\n\t\t\t<Icon\n\t\t\t\tsvg={<CaretDownIcon weight=\"bold\" />}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"size-4\",\n\t\t\t\t\tisCodeExpanded && \"rotate-180\",\n\t\t\t\t\t\"transition-all duration-150\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</Component>\n\t);\n});\nCodeBlockExpanderButton.displayName = \"CodeBlockExpanderButton\";\n\ntype CodeBlockIconProps = Omit<SvgAttributes, \"children\"> &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * A custom icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tsvg: ReactNode;\n\t\t\t\t/**\n\t\t\t\t * A preset icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tpreset?: undefined | never;\n\t\t }\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * A custom icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tsvg?: undefined | never;\n\t\t\t\t/**\n\t\t\t\t * A preset icon to display in the code block header.\n\t\t\t\t * (Pass only one of `svg` or `preset`.)\n\t\t\t\t */\n\t\t\t\tpreset: Mode;\n\t\t }\n\t);\n\n/**\n * A small icon that represents the type of code block being displayed,\n * rendered as an SVG next to the code block title in the code block header.\n *\n * You can pass in a custom SVG component or use one of the presets\n * (pass only one of `svg` or `preset`).\n *\n * @see https://mantle.ngrok.com/components/code-block#api-code-block-icon\n *\n * @example\n * ```tsx\n * <CodeBlock>\n * <CodeBlockHeader>\n * <CodeBlockIcon preset=\"file\" />\n * <CodeBlockTitle>…</CodeBlockTitle>\n * </CodeBlockHeader>\n * <CodeBlockBody>\n * <CodeBlockCopyButton />\n * <CodeBlockCode language=\"…\" value={fmtCode\\`…\\`} />\n * </CodeBlockBody>\n * <CodeBlockExpanderButton />\n * </CodeBlock>\n * ```\n */\nfunction CodeBlockIcon({\n\tclassName,\n\tpreset,\n\tsvg: _svgProp,\n\t...props\n}: CodeBlockIconProps) {\n\tlet svg = _svgProp;\n\tif (preset != null) {\n\t\tswitch (preset) {\n\t\t\tcase \"file\":\n\t\t\t\tsvg = <FileTextIcon weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"cli\":\n\t\t\t\tsvg = <TerminalIcon weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"traffic-policy\":\n\t\t\t\tsvg = <TrafficPolicyFileIcon />;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn <Icon className={className} svg={svg} {...props} />;\n}\nCodeBlockIcon.displayName = \"CodeBlockIcon\";\n\nexport {\n\tCodeBlock,\n\tCodeBlockBody,\n\tCodeBlockCode,\n\tCodeBlockCopyButton,\n\tCodeBlockExpanderButton,\n\tCodeBlockHeader,\n\tCodeBlockIcon,\n\tCodeBlockTitle,\n};\n","/**\n * Escapes special HTML characters in a string to their corresponding\n * HTML entities, preventing issues like unintended HTML rendering or\n * cross-site scripting (XSS) when injecting raw strings into the DOM\n * using `dangerouslySetInnerHTML`.\n *\n * Characters escaped:\n * - \\& => `&amp`;\n * - \\< => `&lt`;\n * - \\> => `&gt`;\n * - \\\" => `&quot`;\n * - \\' => `&#39`;\n *\n * @param {string} value The raw string to be escaped.\n *\n * @example\n * escapeHtml('<div>Hello & \"world\"</div>');\n * // Returns: '&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;'\n */\nfunction escapeHtml(value: string): string {\n\tlet escaped = \"\";\n\tfor (const character of value) {\n\t\tswitch (character) {\n\t\t\tcase \"&\":\n\t\t\t\tescaped += \"&amp;\";\n\t\t\t\tbreak;\n\t\t\tcase \"<\":\n\t\t\t\tescaped += \"&lt;\";\n\t\t\t\tbreak;\n\t\t\tcase \">\":\n\t\t\t\tescaped += \"&gt;\";\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\tescaped += \"&quot;\";\n\t\t\t\tbreak;\n\t\t\tcase \"'\":\n\t\t\t\tescaped += \"&#39;\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tescaped += character;\n\t\t}\n\t}\n\treturn escaped;\n}\n\nexport {\n\t//,\n\tescapeHtml,\n};\n","import Prism from \"prismjs\";\nimport \"prismjs/components/prism-bash.js\";\nimport \"prismjs/components/prism-csharp.js\";\nimport \"prismjs/components/prism-css.js\";\nimport \"prismjs/components/prism-go.js\";\nimport \"prismjs/components/prism-java.js\";\nimport \"prismjs/components/prism-javascript.js\";\nimport \"prismjs/components/prism-json.js\";\nimport \"prismjs/components/prism-jsx.js\";\nimport \"prismjs/components/prism-markup.js\";\nimport \"prismjs/components/prism-python.js\";\nimport \"prismjs/components/prism-ruby.js\";\nimport \"prismjs/components/prism-rust.js\";\nimport \"prismjs/components/prism-tsx.js\";\nimport \"prismjs/components/prism-typescript.js\";\nimport \"prismjs/components/prism-yaml.js\";\n\nexport {\n\t//,\n\tPrism as Highlighter,\n};\n","import type { SupportedLanguage } from \"./supported-languages.js\";\n\nconst indentations = [\"tabs\", \"spaces\"] as const;\ntype Indentation = (typeof indentations)[number];\n\n/**\n * Type Predicate: checks if the given value is a valid indentation type.\n */\nfunction isIndentation(input: unknown): input is Indentation {\n\treturn indentations.includes(input as Indentation);\n}\n\n/**\n * Infers the indentation type based on the language and preferred indentation.\n *\n * @param language - The language to check.\n * @param preferredIndentation - The preferred indentation type (overrides what is detected).\n */\nfunction inferIndentation(\n\tlanguage: SupportedLanguage,\n\tpreferredIndentation: Indentation | undefined,\n) {\n\t// if the user has a preferred indentation, use that regardless of the language\n\tif (preferredIndentation) {\n\t\treturn preferredIndentation;\n\t}\n\n\tif (isTabIndentedLanguage(language)) {\n\t\treturn \"tabs\";\n\t}\n\n\tif (isSpaceIndentedLanguage(language)) {\n\t\treturn \"spaces\";\n\t}\n\n\treturn \"spaces\";\n}\n\nexport {\n\t//,\n\tindentations,\n\tinferIndentation,\n\tisIndentation,\n};\n\nexport type {\n\t//,\n\tIndentation,\n};\n\n/**\n * Languages that require or strongly prefer tabs\n */\nconst tabIndentedLanguages = [\n\t\"csharp\",\n\t\"css\",\n\t\"go\",\n\t\"html\",\n\t\"java\",\n\t\"javascript\",\n\t\"js\",\n\t\"jsx\",\n\t\"ts\",\n\t\"tsx\",\n\t\"typescript\",\n\t\"xml\",\n] as const satisfies SupportedLanguage[];\n\n/**\n * Languages that require or strongly prefer spaces\n */\nconst spaceIndentedLanguages = [\n\t\"python\",\n\t\"py\",\n\t\"yaml\",\n\t\"yml\",\n\t\"ruby\",\n\t\"rb\",\n] as const satisfies SupportedLanguage[];\n\ntype TabIndentedLanguage = (typeof tabIndentedLanguages)[number];\ntype SpaceIndentedLanguage = (typeof spaceIndentedLanguages)[number];\n\n/**\n * Type Predicate: checks if the given value is a required/preferred tab-indented language.\n */\nfunction isTabIndentedLanguage(\n\tvalue: SupportedLanguage,\n): value is TabIndentedLanguage {\n\treturn tabIndentedLanguages.includes(value as TabIndentedLanguage);\n}\n\n/**\n * Type Predicate: checks if the given value is a required/preferred space-indented language.\n */\nfunction isSpaceIndentedLanguage(\n\tvalue: SupportedLanguage,\n): value is SpaceIndentedLanguage {\n\treturn spaceIndentedLanguages.includes(value as SpaceIndentedLanguage);\n}\n","import type { Indentation } from \"./indentation.js\";\n\ntype Options = {\n\t/**\n\t * The indentation type to use. Can be either \"tabs\" or \"spaces\".\n\t * @default \"spaces\"\n\t */\n\tindentation?: Indentation;\n};\n\n/**\n * Trim any leading and trailing whitespace/empty lines, convert leading\n * indentation to the given options.indentation\n */\nfunction normalizeIndentation(value: string, options?: Options): string {\n\tconst { indentation = \"spaces\" } = options || {};\n\n\treturn value.trim().replace(/^[ \\t]*(?=\\S)/gm, (match) => {\n\t\t// 1 tab === 2 spaces\n\t\t// convert tabs to spaces and spaces to tabs\n\t\tif (indentation === \"spaces\") {\n\t\t\treturn match.replace(/\\t/g, \" \");\n\t\t}\n\t\treturn match.replace(/ {2}/g, \"\\t\");\n\t});\n}\n\nexport {\n\t//,\n\tnormalizeIndentation,\n};\n","/**\n * List of supported languages for syntax highlighting.\n * @private\n */\nexport const supportedLanguages = [\n\t\"bash\",\n\t\"cs\",\n\t\"csharp\",\n\t\"css\",\n\t\"dotnet\",\n\t\"go\",\n\t\"html\",\n\t\"java\",\n\t\"javascript\",\n\t\"js\",\n\t\"json\",\n\t\"jsx\",\n\t\"markup\",\n\t\"plain\",\n\t\"plaintext\",\n\t\"py\",\n\t\"python\",\n\t\"rb\",\n\t\"ruby\",\n\t\"rust\",\n\t\"sh\",\n\t\"shell\",\n\t\"text\",\n\t\"ts\",\n\t\"tsx\",\n\t\"txt\",\n\t\"typescript\",\n\t\"xml\",\n\t\"yaml\",\n\t\"yml\",\n] as const;\n\n/**\n * Supported languages for syntax highlighting.\n */\ntype SupportedLanguage = (typeof supportedLanguages)[number];\n\n/**\n * Parses a markdown code block (```) language class into a SupportedLanguage.\n * Defaults to \"sh\" if no supported language is found.\n */\nfunction parseLanguage(\n\tvalue: `language-${string}` | `lang-${string}` | (string & {}) | undefined,\n): SupportedLanguage {\n\tif (!value) {\n\t\treturn \"sh\";\n\t}\n\n\t// remove leading \"language-\" and \"lang-\" prefixes\n\t// find first '-' and slice from there\n\tconst maybeLanguage = value.trim().slice(value.indexOf(\"-\") + 1);\n\n\treturn isSupportedLanguage(maybeLanguage) ? maybeLanguage : \"sh\";\n}\n\n/**\n * Type Predicate: checks if an arbitrary value is a supported syntax highlighting language.\n */\nconst isSupportedLanguage = (value: unknown): value is SupportedLanguage => {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tsupportedLanguages.includes(value as SupportedLanguage)\n\t);\n};\n\n/**\n * A class name for a language that Prism.js can understand.\n */\ntype LanguageClass = `language-${SupportedLanguage}`;\n\n/**\n * Formats a language name into a class name that Prism.js can understand.\n * @default \"language-sh\"\n */\nfunction formatLanguageClassName(\n\tlanguage: SupportedLanguage | undefined = \"sh\",\n) {\n\tconst lang = language ?? \"sh\";\n\tconst className: LanguageClass = `language-${lang}`;\n\treturn className;\n}\n\nexport { isSupportedLanguage, parseLanguage, formatLanguageClassName };\nexport type { SupportedLanguage };\n","type Primitive = string | number | boolean | undefined | null;\n\n/**\n * Tagged template literal to format code blocks and normalize leading indentation\n */\nfunction fmtCode(\n\tstrings: TemplateStringsArray,\n\t...values: Primitive[]\n): string {\n\tif (!isTemplateStringsArray(strings) || !Array.isArray(values)) {\n\t\tthrow new Error(\n\t\t\t\"It looks like you tried to call `fmtCode` as a function. Make sure to use it as a tagged template.\\n\\tExample: fmtCode`SELECT * FROM users`, not fmtCode('SELECT * FROM users')\",\n\t\t);\n\t}\n\n\tconst text = String.raw({ raw: strings }, ...values);\n\n\t// fine the minimum indentation of the code block\n\tconst minIndent = findMinIndent(text);\n\tconst lines = text.trim().split(\"\\n\");\n\n\treturn lines\n\t\t.map((line) => {\n\t\t\t// remove nothing if the line doesn't start with indentation\n\t\t\tif (/^\\S+/.test(line)) {\n\t\t\t\treturn line;\n\t\t\t}\n\t\t\treturn line.slice(minIndent);\n\t\t})\n\t\t.join(\"\\n\");\n}\n\nexport {\n\t//,\n\tfmtCode,\n};\n\n/**\n * Find the shortest indentation of a multiline string\n */\nfunction findMinIndent(value: string): number {\n\tconst match = value.match(/^[ \\t]*(?=\\S)/gm);\n\n\tif (!match) {\n\t\treturn 0;\n\t}\n\n\treturn match.reduce(\n\t\t(acc, curr) => Math.min(acc, curr.length),\n\t\tNumber.POSITIVE_INFINITY,\n\t);\n}\n\n/**\n * Type guard to check if a value is a `TemplateStringsArray`\n */\nfunction isTemplateStringsArray(\n\tstrings: unknown,\n): strings is TemplateStringsArray {\n\treturn (\n\t\tArray.isArray(strings) && \"raw\" in strings && Array.isArray(strings.raw)\n\t);\n}\n","import { parseBooleanish } from \"../../types/booleanish.js\";\nimport { type Indentation, isIndentation } from \"./indentation.js\";\n\nconst modes = [\n\t//,\n\t\"cli\",\n\t\"file\",\n\t\"traffic-policy\",\n] as const;\ntype Mode = (typeof modes)[number];\n\ntype MetaInput = {\n\tcollapsible?: boolean | undefined;\n\tdisableCopy?: boolean | undefined;\n\tindentation?: Indentation | undefined;\n\tmode?: Mode | undefined;\n\ttitle?: string | undefined;\n};\n\ntype Meta = {\n\tcollapsible: boolean;\n\tdisableCopy: boolean;\n\tindentation?: Indentation | undefined;\n\tmode?: Mode | undefined;\n\ttitle?: string | undefined;\n};\n\nconst defaultMeta = {\n\tcollapsible: false,\n\tdisableCopy: false,\n\tindentation: undefined,\n\tmode: undefined,\n\ttitle: undefined,\n} as const satisfies Meta;\n\ntype DefaultMeta = typeof defaultMeta;\n\n/**\n * Parses a markdown code block (```) metastring into a meta object.\n * Defaults to DefaultMeta if no metastring given or if metastring is invalid.\n * Useful for parsing the metastring from a markdown code block to pass into the\n * CodeBlock components as props.\n */\nfunction parseMetastring(input: string | undefined): Meta {\n\tconst metastring = input?.trim() ?? \"\";\n\tif (!metastring) {\n\t\treturn defaultMeta;\n\t}\n\n\tconst metaJson = tokenizeMetastring(metastring).reduce<\n\t\tRecord<string, unknown>\n\t>((acc, token) => {\n\t\tconst [key, value] = token.split(\"=\");\n\t\tif (!key) {\n\t\t\treturn acc;\n\t\t}\n\t\tconst normalizedValue = normalizeValue(value);\n\t\tacc[key] = normalizedValue ?? true;\n\t\treturn acc;\n\t}, {});\n\n\ttry {\n\t\tconst parsed = parseMetaJson(metaJson);\n\n\t\t// return the parsed meta object, with default values filled in\n\t\treturn {\n\t\t\t...defaultMeta,\n\t\t\t...parsed,\n\t\t};\n\t} catch (_) {\n\t\treturn defaultMeta;\n\t}\n}\n\nexport {\n\t//,\n\tdefaultMeta,\n\tparseMetastring,\n};\nexport type {\n\t//,\n\tMeta,\n\tMetaInput,\n\tMode,\n\tDefaultMeta,\n};\n\n/**\n * Remove leading and trailing `\"` quotes around value\n * @private\n */\nexport function normalizeValue(value: string | undefined) {\n\treturn value?.trim().replace(/^\"(.*)\"$/, \"$1\");\n}\n\n/**\n * Splits a metastring into an array of tokens that can be parsed into a meta object.\n * Should allow for quotes and spaces in tokens\n * @private\n */\nexport function tokenizeMetastring(value: string | undefined): string[] {\n\tconst input = value?.trim() ?? \"\";\n\tconst result: string[] = [];\n\n\tlet currentString = \"\";\n\tlet inQuotes = false;\n\n\tfor (const char of input) {\n\t\tif (char === \" \" && !inQuotes) {\n\t\t\tif (currentString) {\n\t\t\t\tresult.push(currentString);\n\t\t\t\tcurrentString = \"\";\n\t\t\t}\n\t\t} else if (char === '\"') {\n\t\t\tinQuotes = !inQuotes;\n\t\t\tcurrentString += char;\n\t\t} else {\n\t\t\tcurrentString += char;\n\t\t}\n\t}\n\n\tif (currentString) {\n\t\tresult.push(currentString);\n\t}\n\n\treturn result;\n}\n\n/**\n * Type Predicate: checks if the given value is a valid mode.\n * @private\n */\nfunction isMode(input: unknown): input is Mode {\n\treturn modes.includes(input as Mode);\n}\n\n/**\n * Parses a meta JSON object into a Meta object.\n * @private\n */\nfunction parseMetaJson(input: Record<string, unknown>): Meta {\n\tconst {\n\t\tcollapsible = defaultMeta.collapsible,\n\t\tdisableCopy = defaultMeta.disableCopy,\n\t\tindentation = defaultMeta.indentation,\n\t\tmode = defaultMeta.mode,\n\t\ttitle = defaultMeta.title,\n\t} = input;\n\n\treturn {\n\t\tcollapsible:\n\t\t\ttypeof collapsible === \"string\" || typeof collapsible === \"boolean\"\n\t\t\t\t? parseBooleanish(collapsible)\n\t\t\t\t: defaultMeta.collapsible,\n\t\tdisableCopy:\n\t\t\ttypeof disableCopy === \"string\" || typeof disableCopy === \"boolean\"\n\t\t\t\t? parseBooleanish(disableCopy)\n\t\t\t\t: defaultMeta.disableCopy,\n\t\tindentation: isIndentation(indentation)\n\t\t\t? indentation\n\t\t\t: defaultMeta.indentation,\n\t\tmode: isMode(mode) ? mode : defaultMeta.mode,\n\t\ttitle: typeof title === \"string\" ? title.trim() : defaultMeta.title,\n\t};\n}\n"],"mappings":"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","names":["CaretDownIcon","CheckIcon","CopyIcon","FileTextIcon","TerminalIcon","Slot","clsx","createContext","forwardRef","useContext","useEffect","useId","useMemo","useRef","useState","assert","escapeHtml","value","escaped","character","Prism","indentations","isIndentation","input","inferIndentation","language","preferredIndentation","isTabIndentedLanguage","isSpaceIndentedLanguage","tabIndentedLanguages","spaceIndentedLanguages","isTabIndentedLanguage","value","isSpaceIndentedLanguage","normalizeIndentation","value","options","indentation","match","supportedLanguages","parseLanguage","value","maybeLanguage","isSupportedLanguage","formatLanguageClassName","language","Fragment","jsx","jsxs","CodeBlockContext","createContext","CodeBlock","forwardRef","asChild","className","props","ref","copyText","setCopyText","useState","hasCodeExpander","setHasCodeExpander","isCodeExpanded","setIsCodeExpanded","codeId","setCodeId","context","useMemo","id","old","assert","Component","Slot","cx","CodeBlockBody","CodeBlockCode","_unusedHighlightLines","propIndentation","language","_unusedShowLineNumbers","style","tabIndex","value","useId","registerCodeId","unregisterCodeId","useContext","indentation","inferIndentation","normalizedAndTrimmedValue","normalizeIndentation","highlightedCodeInnerHtml","setHighlightedCodeInnerHtml","escapeHtml","useEffect","grammar","Prism","supportedLanguages","newHighlightedCodeInnerHtml","languageClassName","formatLanguageClassName","clsx","CodeBlockHeader","CodeBlockTitle","CodeBlockCopyButton","onCopy","onCopyError","onClick","copyToClipboard","useCopyToClipboard","wasCopied","setWasCopied","timeoutHandle","useRef","event","error","Icon","CheckIcon","CopyIcon","CodeBlockExpanderButton","prev","CaretDownIcon","CodeBlockIcon","preset","_svgProp","svg","FileTextIcon","TerminalIcon","TrafficPolicyFileIcon","fmtCode","strings","values","isTemplateStringsArray","text","minIndent","findMinIndent","line","findMinIndent","value","match","acc","curr","isTemplateStringsArray","strings","modes","defaultMeta","parseMetastring","input","metastring","metaJson","tokenizeMetastring","acc","token","key","value","normalizedValue","normalizeValue","parsed","parseMetaJson","normalizeValue","value","tokenizeMetastring","input","result","currentString","inQuotes","char","isMode","modes","parseMetaJson","collapsible","defaultMeta","disableCopy","indentation","mode","title","parseBooleanish","isIndentation"]}
@@ -17,7 +17,10 @@ type ComboboxProps = Primitive.ComboboxProviderProps;
17
17
  * </ComboboxContent>
18
18
  * </Combobox>
19
19
  */
20
- declare const Combobox: ({ children, ...props }: ComboboxProps) => react_jsx_runtime.JSX.Element;
20
+ declare const Combobox: {
21
+ ({ children, ...props }: ComboboxProps): react_jsx_runtime.JSX.Element;
22
+ displayName: string;
23
+ };
21
24
  type ComboboxInputProps = Omit<Primitive.ComboboxProps, "render"> & WithValidation;
22
25
  /**
23
26
  * Renders a combobox input element that can be used to filter a list of items.
package/dist/combobox.js CHANGED
@@ -1,2 +1,2 @@
1
- import{b as x}from"./chunk-UXH22BMO.js";import{a as d}from"./chunk-AZ56JGNY.js";import*as i from"@ariakit/react";import{Slot as l}from"@radix-ui/react-slot";import{createContext as g,forwardRef as s}from"react";import{jsx as t}from"react/jsx-runtime";var h=({children:o,...e})=>t(i.ComboboxProvider,{...e,children:o}),f=s(({"aria-invalid":o,autoComplete:e="list",autoSelect:a="always",className:n,validation:r,...m},b)=>{let p=o!=null&&o!=="false"?"error":typeof r=="function"?r():r;return t(i.Combobox,{"aria-invalid":o??p==="error",autoComplete:e,autoSelect:a,className:d("pointer-coarse:text-base h-9 text-sm","bg-form relative block w-full rounded-md border px-3 py-2 border-form text-strong","placeholder:text-placeholder","aria-disabled:opacity-50","hover:border-neutral-400","focus:outline-none focus:ring-4 aria-expanded:ring-4","focus:border-accent-600 focus:ring-focus-accent aria-expanded:border-accent-600 aria-expanded:ring-focus-accent","data-validation-success:border-success-600 data-validation-success:focus:border-success-600 data-validation-success:focus:ring-focus-success data-validation-success:aria-expanded:border-success-600 data-validation-success:aria-expanded:ring-focus-success","data-validation-warning:border-warning-600 data-validation-warning:focus:border-warning-600 data-validation-warning:focus:ring-focus-warning data-validation-warning:aria-expanded:border-warning-600 data-validation-warning:aria-expanded:ring-focus-warning","data-validation-error:border-danger-600 data-validation-error:focus:border-danger-600 data-validation-error:focus:ring-focus-danger data-validation-error:aria-expanded:border-danger-600 data-validation-error:aria-expanded:ring-focus-danger","autofill:shadow-[inset_0_0_0px_1000px_hsl(var(--blue-50))] autofill:bg-blue-50 autofill:[-webkit-text-fill-color:hsl(var(--text-strong))]",n),"data-validation":p||void 0,ref:b,...m})});f.displayName="ComboboxInput";var C=s(({asChild:o=!1,children:e,className:a,sameWidth:n=!0,unmountOnHide:r=!0,...m},b)=>t(i.ComboboxPopover,{className:d("border-popover bg-popover relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md p-1 my-1",a),ref:b,render:o?({ref:u,...p})=>t(l,{ref:u,...p}):void 0,sameWidth:n,unmountOnHide:r,...m,children:e}));C.displayName="ComboboxContent";var I=g(void 0),c=s(({asChild:o=!1,children:e,className:a,focusOnHover:n=!0,value:r,...m},b)=>t(I.Provider,{value:r,children:t(i.ComboboxItem,{className:d("cursor-pointer rounded px-2 py-1.5 text-sm flex min-w-0 gap-2 items-center","data-active-item:bg-popover-hover","aria-disabled:opacity-50",a),focusOnHover:n,ref:b,render:o?({ref:u,...p})=>t(l,{ref:u,...p}):void 0,value:r,...m,children:e})}));c.displayName="ComboboxItem";var v=s(({asChild:o=!1,children:e,className:a,...n},r)=>t(i.ComboboxGroup,{className:d("",a),ref:r,render:o?({ref:m,...b})=>t(l,{ref:m,...b}):void 0,...n,children:e}));v.displayName="ComboboxGroup";var P=s(({asChild:o=!1,children:e,className:a,...n},r)=>t(i.ComboboxGroupLabel,{className:d("text-muted px-2 py-1 text-xs font-medium",a),ref:r,render:o?({ref:m,...b})=>t(l,{ref:m,...b}):void 0,...n,children:e}));P.displayName="ComboboxGroupLabel";var w=s(({asChild:o=!1,className:e,...a},n)=>t(i.ComboboxItemValue,{className:d("data-[user-value]:*:font-bold flex-1 shrink-0 text-strong font-normal",e),ref:n,render:o?({ref:r,...m})=>t(l,{ref:r,...m}):void 0,...a})),y=s(({className:o,...e},a)=>t(x,{ref:a,className:d("-mx-1.25 my-1 w-auto",o),...e}));y.displayName="ComboboxSeparator";export{h as Combobox,C as ComboboxContent,v as ComboboxGroup,P as ComboboxGroupLabel,f as ComboboxInput,c as ComboboxItem,w as ComboboxItemValue,y as ComboboxSeparator};
1
+ import{b as x}from"./chunk-J6ZF5J72.js";import{a as d}from"./chunk-AZ56JGNY.js";import*as i from"@ariakit/react";import{Slot as l}from"@radix-ui/react-slot";import{createContext as I,forwardRef as s}from"react";import{jsx as t}from"react/jsx-runtime";var f=({children:o,...e})=>t(i.ComboboxProvider,{...e,children:o});f.displayName="Combobox";var C=s(({"aria-invalid":o,autoComplete:e="list",autoSelect:a="always",className:n,validation:r,...m},b)=>{let p=o!=null&&o!=="false"?"error":typeof r=="function"?r():r;return t(i.Combobox,{"aria-invalid":o??p==="error",autoComplete:e,autoSelect:a,className:d("pointer-coarse:text-base h-9 text-sm","bg-form relative block w-full rounded-md border px-3 py-2 border-form text-strong","placeholder:text-placeholder","aria-disabled:opacity-50","hover:border-neutral-400","focus:outline-none focus:ring-4 aria-expanded:ring-4","focus:border-accent-600 focus:ring-focus-accent aria-expanded:border-accent-600 aria-expanded:ring-focus-accent","data-validation-success:border-success-600 data-validation-success:focus:border-success-600 data-validation-success:focus:ring-focus-success data-validation-success:aria-expanded:border-success-600 data-validation-success:aria-expanded:ring-focus-success","data-validation-warning:border-warning-600 data-validation-warning:focus:border-warning-600 data-validation-warning:focus:ring-focus-warning data-validation-warning:aria-expanded:border-warning-600 data-validation-warning:aria-expanded:ring-focus-warning","data-validation-error:border-danger-600 data-validation-error:focus:border-danger-600 data-validation-error:focus:ring-focus-danger data-validation-error:aria-expanded:border-danger-600 data-validation-error:aria-expanded:ring-focus-danger","autofill:shadow-[inset_0_0_0px_1000px_hsl(var(--blue-50))] autofill:bg-blue-50 autofill:[-webkit-text-fill-color:hsl(var(--text-strong))]",n),"data-validation":p||void 0,ref:b,...m})});C.displayName="ComboboxInput";var c=s(({asChild:o=!1,children:e,className:a,sameWidth:n=!0,unmountOnHide:r=!0,...m},b)=>t(i.ComboboxPopover,{className:d("border-popover bg-popover relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md p-1 my-1",a),ref:b,render:o?({ref:u,...p})=>t(l,{ref:u,...p}):void 0,sameWidth:n,unmountOnHide:r,...m,children:e}));c.displayName="ComboboxContent";var w=I(void 0),v=s(({asChild:o=!1,children:e,className:a,focusOnHover:n=!0,value:r,...m},b)=>t(w.Provider,{value:r,children:t(i.ComboboxItem,{className:d("cursor-pointer rounded px-2 py-1.5 text-sm flex min-w-0 gap-2 items-center","data-active-item:bg-popover-hover","aria-disabled:opacity-50",a),focusOnHover:n,ref:b,render:o?({ref:u,...p})=>t(l,{ref:u,...p}):void 0,value:r,...m,children:e})}));v.displayName="ComboboxItem";var P=s(({asChild:o=!1,children:e,className:a,...n},r)=>t(i.ComboboxGroup,{className:d("",a),ref:r,render:o?({ref:m,...b})=>t(l,{ref:m,...b}):void 0,...n,children:e}));P.displayName="ComboboxGroup";var y=s(({asChild:o=!1,children:e,className:a,...n},r)=>t(i.ComboboxGroupLabel,{className:d("text-muted px-2 py-1 text-xs font-medium",a),ref:r,render:o?({ref:m,...b})=>t(l,{ref:m,...b}):void 0,...n,children:e}));y.displayName="ComboboxGroupLabel";var g=s(({asChild:o=!1,className:e,...a},n)=>t(i.ComboboxItemValue,{className:d("data-[user-value]:*:font-bold flex-1 shrink-0 text-strong font-normal",e),ref:n,render:o?({ref:r,...m})=>t(l,{ref:r,...m}):void 0,...a}));g.displayName="ComboboxItemValue";var h=s(({className:o,...e},a)=>t(x,{ref:a,className:d("-mx-1.25 my-1 w-auto",o),...e}));h.displayName="ComboboxSeparator";export{f as Combobox,c as ComboboxContent,P as ComboboxGroup,y as ComboboxGroupLabel,C as ComboboxInput,v as ComboboxItem,g as ComboboxItemValue,h as ComboboxSeparator};
2
2
  //# sourceMappingURL=combobox.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/combobox/combobox.tsx"],"sourcesContent":["\"use client\";\n\nimport * as Primitive from \"@ariakit/react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n\ttype ComponentPropsWithoutRef,\n\ttype ComponentRef,\n\ttype ElementRef,\n\tcreateContext,\n\tforwardRef,\n} from \"react\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport type { WithValidation } from \"../input/types.js\";\nimport { Separator } from \"../separator/separator.js\";\n\ntype ComboboxProps = Primitive.ComboboxProviderProps;\n\n/**\n * Root component for a combobox. Provides a combobox store that controls the state of Combobox components.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst Combobox = ({ children, ...props }: ComboboxProps) => {\n\treturn (\n\t\t<Primitive.ComboboxProvider {...props}>\n\t\t\t{children}\n\t\t</Primitive.ComboboxProvider>\n\t);\n};\n\ntype ComboboxInputProps = Omit<\n\tPrimitive.ComboboxProps,\n\t\"render\" // we don't support a render prop for the combobox input\n> &\n\tWithValidation;\n\n/**\n * Renders a combobox input element that can be used to filter a list of items.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxInput = forwardRef<ComponentRef<\"input\">, ComboboxInputProps>(\n\t(\n\t\t{\n\t\t\t\"aria-invalid\": _ariaInvalid,\n\t\t\tautoComplete = \"list\",\n\t\t\tautoSelect = \"always\",\n\t\t\tclassName,\n\t\t\tvalidation: _validation,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isInvalid = _ariaInvalid != null && _ariaInvalid !== \"false\";\n\t\tconst validation = isInvalid\n\t\t\t? \"error\"\n\t\t\t: typeof _validation === \"function\"\n\t\t\t\t? _validation()\n\t\t\t\t: _validation;\n\t\tconst ariaInvalid = _ariaInvalid ?? validation === \"error\";\n\n\t\treturn (\n\t\t\t<Primitive.Combobox\n\t\t\t\taria-invalid={ariaInvalid}\n\t\t\t\tautoComplete={autoComplete}\n\t\t\t\tautoSelect={autoSelect}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"pointer-coarse:text-base h-9 text-sm\",\n\t\t\t\t\t\"bg-form relative block w-full rounded-md border px-3 py-2 border-form text-strong\",\n\t\t\t\t\t\"placeholder:text-placeholder\",\n\t\t\t\t\t\"aria-disabled:opacity-50\",\n\t\t\t\t\t\"hover:border-neutral-400\",\n\t\t\t\t\t\"focus:outline-none focus:ring-4 aria-expanded:ring-4\",\n\t\t\t\t\t\"focus:border-accent-600 focus:ring-focus-accent aria-expanded:border-accent-600 aria-expanded:ring-focus-accent\",\n\t\t\t\t\t\"data-validation-success:border-success-600 data-validation-success:focus:border-success-600 data-validation-success:focus:ring-focus-success data-validation-success:aria-expanded:border-success-600 data-validation-success:aria-expanded:ring-focus-success\",\n\t\t\t\t\t\"data-validation-warning:border-warning-600 data-validation-warning:focus:border-warning-600 data-validation-warning:focus:ring-focus-warning data-validation-warning:aria-expanded:border-warning-600 data-validation-warning:aria-expanded:ring-focus-warning\",\n\t\t\t\t\t\"data-validation-error:border-danger-600 data-validation-error:focus:border-danger-600 data-validation-error:focus:ring-focus-danger data-validation-error:aria-expanded:border-danger-600 data-validation-error:aria-expanded:ring-focus-danger\",\n\t\t\t\t\t\"autofill:shadow-[inset_0_0_0px_1000px_hsl(var(--blue-50))] autofill:bg-blue-50 autofill:[-webkit-text-fill-color:hsl(var(--text-strong))]\", // Autofill styling on the input itself and any children with autofill styling\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-validation={validation || undefined}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nComboboxInput.displayName = \"ComboboxInput\";\n\ntype ComboboxContentProps = Omit<Primitive.ComboboxPopoverProps, \"render\"> &\n\tWithAsChild;\n\n/**\n * Renders a popover that contains combobox content, e.g. ComboboxItems, ComboboxGroups, and ComboboxSeparators.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxContent = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxPopover>,\n\tComboboxContentProps\n>(\n\t(\n\t\t{\n\t\t\tasChild = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tsameWidth = true,\n\t\t\tunmountOnHide = true,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\treturn (\n\t\t\t<Primitive.ComboboxPopover\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"border-popover bg-popover relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md p-1 my-1\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild\n\t\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tsameWidth={sameWidth}\n\t\t\t\tunmountOnHide={unmountOnHide}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxPopover>\n\t\t);\n\t},\n);\nComboboxContent.displayName = \"ComboboxContent\";\n\ntype ComboboxItemProps = Omit<Primitive.ComboboxItemProps, \"render\"> &\n\tWithAsChild;\n\nconst ComboboxItemValueContext = createContext<string | undefined>(undefined);\n\n/**\n * Renders a combobox item inside a ComboboxContent component.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * <ComboboxItem value=\"Orange\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxItem = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxItem>,\n\tComboboxItemProps\n>(\n\t(\n\t\t{\n\t\t\tasChild = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tfocusOnHover = true,\n\t\t\tvalue,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\treturn (\n\t\t\t<ComboboxItemValueContext.Provider value={value}>\n\t\t\t\t<Primitive.ComboboxItem\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"cursor-pointer rounded px-2 py-1.5 text-sm flex min-w-0 gap-2 items-center\",\n\t\t\t\t\t\t\"data-active-item:bg-popover-hover\",\n\t\t\t\t\t\t\"aria-disabled:opacity-50\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\tfocusOnHover={focusOnHover}\n\t\t\t\t\tref={ref}\n\t\t\t\t\trender={\n\t\t\t\t\t\tasChild\n\t\t\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\t{...props}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</Primitive.ComboboxItem>\n\t\t\t</ComboboxItemValueContext.Provider>\n\t\t);\n\t},\n);\nComboboxItem.displayName = \"ComboboxItem\";\n\ntype ComboboxGroupProps = Omit<Primitive.ComboboxGroupProps, \"render\"> &\n\tWithAsChild;\n\n/**\n * Renders a group for ComboboxItem elements.\n *\n * Optionally, a ComboboxGroupLabel can be rendered as a child to provide a label for the group.\n *\n * You should only reach for this component when it semantically makes sense to group items together, such as when a label is needed.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxGroup>\n * <ComboboxGroupLabel>Fruits</ComboboxGroupLabel>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxGroup>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxGroup = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxGroup>,\n\tComboboxGroupProps\n>(({ asChild = false, children, className, ...props }, ref) => {\n\treturn (\n\t\t<Primitive.ComboboxGroup\n\t\t\tclassName={cx(\"\", className)}\n\t\t\tref={ref}\n\t\t\trender={\n\t\t\t\tasChild\n\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Primitive.ComboboxGroup>\n\t);\n});\nComboboxGroup.displayName = \"ComboboxGroup\";\n\ntype ComboboxGroupLabelProps = Omit<\n\tPrimitive.ComboboxGroupLabelProps,\n\t\"render\"\n> &\n\tWithAsChild;\n\n/**\n * Renders a label in a combobox group.\n *\n * This component should be wrapped with ComboboxGroup so the aria-labelledby is correctly set on the group element.\n *\n * You should only reach for this component when it semantically makes sense to group items together, such as when a label is needed.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxGroup>\n * <ComboboxGroupLabel>Fruits</ComboboxGroupLabel>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxGroup>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxGroupLabel = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxGroupLabel>,\n\tComboboxGroupLabelProps\n>(({ asChild = false, children, className, ...props }, ref) => {\n\treturn (\n\t\t<Primitive.ComboboxGroupLabel\n\t\t\tclassName={cx(\"text-muted px-2 py-1 text-xs font-medium\", className)}\n\t\t\tref={ref}\n\t\t\trender={\n\t\t\t\tasChild\n\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Primitive.ComboboxGroupLabel>\n\t);\n});\nComboboxGroupLabel.displayName = \"ComboboxGroupLabel\";\n\ntype ComboboxItemValueProps = Omit<\n\tPrimitive.ComboboxItemValueProps<\"span\">,\n\t\"render\"\n> &\n\tWithAsChild;\n\n/**\n * Highlights the match between the current ComboboxInput value (userValue) and parent ComboboxItem value.\n *\n * Renders a span element with the combobox item value as children.\n * The value is split into span elements.\n * Portions of the value matching the user input will have a data-user-value attribute, while the rest will have a data-autocomplete-value attribute.\n *\n * Should only be used as a child of ComboboxItem.\n * The item value is automatically set to the value of the closest ComboboxItem component's value prop.\n * The user input value is automatically set to the combobox store's value state.\n * Both values can be overridden by providing the value and userValue props, respectively.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\">\n * 🍎\n * <ComboboxItemValue />\n * </ComboboxItem>\n * <ComboboxItem value=\"Banana\">\n * 🍌\n * <ComboboxItemValue />\n * </ComboboxItem>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxItemValue = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxItemValue>,\n\tComboboxItemValueProps\n>(({ asChild = false, className, ...props }, ref) => {\n\treturn (\n\t\t<Primitive.ComboboxItemValue\n\t\t\tclassName={cx(\n\t\t\t\t\"data-[user-value]:*:font-bold flex-1 shrink-0 text-strong font-normal\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\trender={\n\t\t\t\tasChild\n\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\n\n/**\n * Renders a separator between ComboboxItems or ComboboxGroups.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxGroup>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxGroup>\n * <ComboboxSeparator />\n * <ComboboxItem>\n * Click me!\n * </ComboboxItem>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxSeparator = forwardRef<\n\tElementRef<typeof Separator>,\n\tComponentPropsWithoutRef<typeof Separator>\n>(({ className, ...props }, ref) => (\n\t<Separator\n\t\tref={ref}\n\t\tclassName={cx(\"-mx-1.25 my-1 w-auto\", className)}\n\t\t{...props}\n\t/>\n));\nComboboxSeparator.displayName = \"ComboboxSeparator\";\n\nexport {\n\t//,\n\tCombobox,\n\tComboboxContent,\n\tComboboxGroup,\n\tComboboxGroupLabel,\n\tComboboxInput,\n\tComboboxItem,\n\tComboboxItemValue,\n\tComboboxSeparator,\n};\n"],"mappings":"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","names":["Primitive","Slot","createContext","forwardRef","jsx","Combobox","children","props","ComboboxInput","forwardRef","_ariaInvalid","autoComplete","autoSelect","className","_validation","ref","validation","cx","ComboboxContent","asChild","sameWidth","unmountOnHide","childProps","Slot","ComboboxItemValueContext","createContext","ComboboxItem","focusOnHover","value","ComboboxGroup","ComboboxGroupLabel","ComboboxItemValue","ComboboxSeparator","Separator"]}
1
+ {"version":3,"sources":["../src/components/combobox/combobox.tsx"],"sourcesContent":["\"use client\";\n\nimport * as Primitive from \"@ariakit/react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n\ttype ComponentPropsWithoutRef,\n\ttype ComponentRef,\n\ttype ElementRef,\n\tcreateContext,\n\tforwardRef,\n} from \"react\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport type { WithValidation } from \"../input/types.js\";\nimport { Separator } from \"../separator/separator.js\";\n\ntype ComboboxProps = Primitive.ComboboxProviderProps;\n\n/**\n * Root component for a combobox. Provides a combobox store that controls the state of Combobox components.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst Combobox = ({ children, ...props }: ComboboxProps) => {\n\treturn (\n\t\t<Primitive.ComboboxProvider {...props}>\n\t\t\t{children}\n\t\t</Primitive.ComboboxProvider>\n\t);\n};\nCombobox.displayName = \"Combobox\";\n\ntype ComboboxInputProps = Omit<\n\tPrimitive.ComboboxProps,\n\t\"render\" // we don't support a render prop for the combobox input\n> &\n\tWithValidation;\n\n/**\n * Renders a combobox input element that can be used to filter a list of items.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxInput = forwardRef<ComponentRef<\"input\">, ComboboxInputProps>(\n\t(\n\t\t{\n\t\t\t\"aria-invalid\": _ariaInvalid,\n\t\t\tautoComplete = \"list\",\n\t\t\tautoSelect = \"always\",\n\t\t\tclassName,\n\t\t\tvalidation: _validation,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isInvalid = _ariaInvalid != null && _ariaInvalid !== \"false\";\n\t\tconst validation = isInvalid\n\t\t\t? \"error\"\n\t\t\t: typeof _validation === \"function\"\n\t\t\t\t? _validation()\n\t\t\t\t: _validation;\n\t\tconst ariaInvalid = _ariaInvalid ?? validation === \"error\";\n\n\t\treturn (\n\t\t\t<Primitive.Combobox\n\t\t\t\taria-invalid={ariaInvalid}\n\t\t\t\tautoComplete={autoComplete}\n\t\t\t\tautoSelect={autoSelect}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"pointer-coarse:text-base h-9 text-sm\",\n\t\t\t\t\t\"bg-form relative block w-full rounded-md border px-3 py-2 border-form text-strong\",\n\t\t\t\t\t\"placeholder:text-placeholder\",\n\t\t\t\t\t\"aria-disabled:opacity-50\",\n\t\t\t\t\t\"hover:border-neutral-400\",\n\t\t\t\t\t\"focus:outline-none focus:ring-4 aria-expanded:ring-4\",\n\t\t\t\t\t\"focus:border-accent-600 focus:ring-focus-accent aria-expanded:border-accent-600 aria-expanded:ring-focus-accent\",\n\t\t\t\t\t\"data-validation-success:border-success-600 data-validation-success:focus:border-success-600 data-validation-success:focus:ring-focus-success data-validation-success:aria-expanded:border-success-600 data-validation-success:aria-expanded:ring-focus-success\",\n\t\t\t\t\t\"data-validation-warning:border-warning-600 data-validation-warning:focus:border-warning-600 data-validation-warning:focus:ring-focus-warning data-validation-warning:aria-expanded:border-warning-600 data-validation-warning:aria-expanded:ring-focus-warning\",\n\t\t\t\t\t\"data-validation-error:border-danger-600 data-validation-error:focus:border-danger-600 data-validation-error:focus:ring-focus-danger data-validation-error:aria-expanded:border-danger-600 data-validation-error:aria-expanded:ring-focus-danger\",\n\t\t\t\t\t\"autofill:shadow-[inset_0_0_0px_1000px_hsl(var(--blue-50))] autofill:bg-blue-50 autofill:[-webkit-text-fill-color:hsl(var(--text-strong))]\", // Autofill styling on the input itself and any children with autofill styling\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-validation={validation || undefined}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nComboboxInput.displayName = \"ComboboxInput\";\n\ntype ComboboxContentProps = Omit<Primitive.ComboboxPopoverProps, \"render\"> &\n\tWithAsChild;\n\n/**\n * Renders a popover that contains combobox content, e.g. ComboboxItems, ComboboxGroups, and ComboboxSeparators.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxContent = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxPopover>,\n\tComboboxContentProps\n>(\n\t(\n\t\t{\n\t\t\tasChild = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tsameWidth = true,\n\t\t\tunmountOnHide = true,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\treturn (\n\t\t\t<Primitive.ComboboxPopover\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"border-popover bg-popover relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md p-1 my-1\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild\n\t\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tsameWidth={sameWidth}\n\t\t\t\tunmountOnHide={unmountOnHide}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxPopover>\n\t\t);\n\t},\n);\nComboboxContent.displayName = \"ComboboxContent\";\n\ntype ComboboxItemProps = Omit<Primitive.ComboboxItemProps, \"render\"> &\n\tWithAsChild;\n\nconst ComboboxItemValueContext = createContext<string | undefined>(undefined);\n\n/**\n * Renders a combobox item inside a ComboboxContent component.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * <ComboboxItem value=\"Orange\" />\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxItem = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxItem>,\n\tComboboxItemProps\n>(\n\t(\n\t\t{\n\t\t\tasChild = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tfocusOnHover = true,\n\t\t\tvalue,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\treturn (\n\t\t\t<ComboboxItemValueContext.Provider value={value}>\n\t\t\t\t<Primitive.ComboboxItem\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"cursor-pointer rounded px-2 py-1.5 text-sm flex min-w-0 gap-2 items-center\",\n\t\t\t\t\t\t\"data-active-item:bg-popover-hover\",\n\t\t\t\t\t\t\"aria-disabled:opacity-50\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\tfocusOnHover={focusOnHover}\n\t\t\t\t\tref={ref}\n\t\t\t\t\trender={\n\t\t\t\t\t\tasChild\n\t\t\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\t{...props}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</Primitive.ComboboxItem>\n\t\t\t</ComboboxItemValueContext.Provider>\n\t\t);\n\t},\n);\nComboboxItem.displayName = \"ComboboxItem\";\n\ntype ComboboxGroupProps = Omit<Primitive.ComboboxGroupProps, \"render\"> &\n\tWithAsChild;\n\n/**\n * Renders a group for ComboboxItem elements.\n *\n * Optionally, a ComboboxGroupLabel can be rendered as a child to provide a label for the group.\n *\n * You should only reach for this component when it semantically makes sense to group items together, such as when a label is needed.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxGroup>\n * <ComboboxGroupLabel>Fruits</ComboboxGroupLabel>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxGroup>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxGroup = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxGroup>,\n\tComboboxGroupProps\n>(({ asChild = false, children, className, ...props }, ref) => {\n\treturn (\n\t\t<Primitive.ComboboxGroup\n\t\t\tclassName={cx(\"\", className)}\n\t\t\tref={ref}\n\t\t\trender={\n\t\t\t\tasChild\n\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Primitive.ComboboxGroup>\n\t);\n});\nComboboxGroup.displayName = \"ComboboxGroup\";\n\ntype ComboboxGroupLabelProps = Omit<\n\tPrimitive.ComboboxGroupLabelProps,\n\t\"render\"\n> &\n\tWithAsChild;\n\n/**\n * Renders a label in a combobox group.\n *\n * This component should be wrapped with ComboboxGroup so the aria-labelledby is correctly set on the group element.\n *\n * You should only reach for this component when it semantically makes sense to group items together, such as when a label is needed.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxGroup>\n * <ComboboxGroupLabel>Fruits</ComboboxGroupLabel>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxGroup>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxGroupLabel = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxGroupLabel>,\n\tComboboxGroupLabelProps\n>(({ asChild = false, children, className, ...props }, ref) => {\n\treturn (\n\t\t<Primitive.ComboboxGroupLabel\n\t\t\tclassName={cx(\"text-muted px-2 py-1 text-xs font-medium\", className)}\n\t\t\tref={ref}\n\t\t\trender={\n\t\t\t\tasChild\n\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Primitive.ComboboxGroupLabel>\n\t);\n});\nComboboxGroupLabel.displayName = \"ComboboxGroupLabel\";\n\ntype ComboboxItemValueProps = Omit<\n\tPrimitive.ComboboxItemValueProps<\"span\">,\n\t\"render\"\n> &\n\tWithAsChild;\n\n/**\n * Highlights the match between the current ComboboxInput value (userValue) and parent ComboboxItem value.\n *\n * Renders a span element with the combobox item value as children.\n * The value is split into span elements.\n * Portions of the value matching the user input will have a data-user-value attribute, while the rest will have a data-autocomplete-value attribute.\n *\n * Should only be used as a child of ComboboxItem.\n * The item value is automatically set to the value of the closest ComboboxItem component's value prop.\n * The user input value is automatically set to the combobox store's value state.\n * Both values can be overridden by providing the value and userValue props, respectively.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxItem value=\"Apple\">\n * 🍎\n * <ComboboxItemValue />\n * </ComboboxItem>\n * <ComboboxItem value=\"Banana\">\n * 🍌\n * <ComboboxItemValue />\n * </ComboboxItem>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxItemValue = forwardRef<\n\tComponentRef<typeof Primitive.ComboboxItemValue>,\n\tComboboxItemValueProps\n>(({ asChild = false, className, ...props }, ref) => {\n\treturn (\n\t\t<Primitive.ComboboxItemValue\n\t\t\tclassName={cx(\n\t\t\t\t\"data-[user-value]:*:font-bold flex-1 shrink-0 text-strong font-normal\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\trender={\n\t\t\t\tasChild\n\t\t\t\t\t? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} />\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nComboboxItemValue.displayName = \"ComboboxItemValue\";\n\n/**\n * Renders a separator between ComboboxItems or ComboboxGroups.\n *\n * @example\n * <Combobox>\n * <ComboboxInput />\n * <ComboboxContent>\n * <ComboboxGroup>\n * <ComboboxItem value=\"Apple\" />\n * <ComboboxItem value=\"Banana\" />\n * </ComboboxGroup>\n * <ComboboxSeparator />\n * <ComboboxItem>\n * Click me!\n * </ComboboxItem>\n * </ComboboxContent>\n * </Combobox>\n */\nconst ComboboxSeparator = forwardRef<\n\tElementRef<typeof Separator>,\n\tComponentPropsWithoutRef<typeof Separator>\n>(({ className, ...props }, ref) => (\n\t<Separator\n\t\tref={ref}\n\t\tclassName={cx(\"-mx-1.25 my-1 w-auto\", className)}\n\t\t{...props}\n\t/>\n));\nComboboxSeparator.displayName = \"ComboboxSeparator\";\n\nexport {\n\t//,\n\tCombobox,\n\tComboboxContent,\n\tComboboxGroup,\n\tComboboxGroupLabel,\n\tComboboxInput,\n\tComboboxItem,\n\tComboboxItemValue,\n\tComboboxSeparator,\n};\n"],"mappings":"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","names":["Primitive","Slot","createContext","forwardRef","jsx","Combobox","children","props","ComboboxInput","forwardRef","_ariaInvalid","autoComplete","autoSelect","className","_validation","ref","validation","cx","ComboboxContent","asChild","sameWidth","unmountOnHide","childProps","Slot","ComboboxItemValueContext","createContext","ComboboxItem","focusOnHover","value","ComboboxGroup","ComboboxGroupLabel","ComboboxItemValue","ComboboxSeparator","Separator"]}
@@ -4,7 +4,7 @@ import * as react from 'react';
4
4
  import { ComponentProps, ReactNode } from 'react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { k as SortingMode } from './direction-veAOo2is.js';
7
- import { B as Button } from './button-C8eGiHOm.js';
7
+ import { B as Button } from './button-BvWgeelK.js';
8
8
  import { TableRoot, TableCell, TableRow, TableHead, TableHeader } from './table.js';
9
9
  import './deep-non-nullable-SmpSvoSd.js';
10
10
  import 'class-variance-authority';
@@ -17,6 +17,22 @@ type SortDirection = (typeof sortDirections)[number];
17
17
  type DataTableProps<TData> = ComponentProps<typeof TableRoot> & {
18
18
  table: Table<TData>;
19
19
  };
20
+ /**
21
+ * A data table component that provides sorting and other data table functionality.
22
+ * Built on top of TanStack Table for advanced table features.
23
+ *
24
+ * @see https://mantle.ngrok.com/components/data-table#api-data-table
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * <DataTable table={table}>
29
+ * <DataTableHead />
30
+ * <DataTableBody>
31
+ * <DataTableRows />
32
+ * </DataTableBody>
33
+ * </DataTable>
34
+ * ```
35
+ */
20
36
  declare function DataTable<TData>({ children, table, ...props }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
21
37
  type DataTableHeaderSortButtonProps<TData, TValue> = Omit<ComponentProps<typeof Button>, "icon"> & Pick<HeaderContext<TData, TValue>, "column"> & ({
22
38
  /**
@@ -51,25 +67,38 @@ type DataTableHeaderSortButtonProps<TData, TValue> = Omit<ComponentProps<typeof
51
67
  * If the column is sortable, clicking the button will toggle the sorting
52
68
  * direction.
53
69
  *
54
- * @example
55
- * ```md
56
- * Each click cycles through...
57
- *
58
- * For alphanumeric sorting:
59
- * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...
70
+ * @see https://mantle.ngrok.com/components/data-table#api-data-table-header-sort-button
60
71
  *
61
- * For time sorting:
62
- * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...
63
- *
64
- * this is equivalent to the inverse of alphanumeric sorting, or
65
- * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...
72
+ * @example
73
+ * ```tsx
74
+ * <DataTableHeaderSortButton
75
+ * column={column}
76
+ * sortingMode="alphanumeric"
77
+ * >
78
+ * Column Title
79
+ * </DataTableHeaderSortButton>
66
80
  * ```
81
+ *
82
+ * Each click cycles through:
83
+ * - For alphanumeric sorting: unsorted ➡️ ascending ➡️ descending ➡️ unsorted
84
+ * - For time sorting: unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted
67
85
  */
68
86
  declare function DataTableHeaderSortButton<TData, TValue>({ children, className, column, disableSorting, iconPlacement, sortingMode, sortIcon: propSortIcon, onClick, ...props }: DataTableHeaderSortButtonProps<TData, TValue>): react_jsx_runtime.JSX.Element;
69
87
  type DataTableHeaderProps = ComponentProps<typeof TableHeader>;
70
88
  /**
71
89
  * A header for a data table.
72
90
  * This is typically used to wrap the `DataTableHeaderSortButton` component.
91
+ *
92
+ * @see https://mantle.ngrok.com/components/data-table#api-data-table-header
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * <DataTableHeader>
97
+ * <DataTableHeaderSortButton column={column} sortingMode="alphanumeric">
98
+ * Column Title
99
+ * </DataTableHeaderSortButton>
100
+ * </DataTableHeader>
101
+ * ```
73
102
  */
74
103
  declare function DataTableHeader<TData, TValue>({ children, className, ...props }: DataTableHeaderProps): react_jsx_runtime.JSX.Element;
75
104
  declare const DataTableBody: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>, "ref"> & react.RefAttributes<HTMLTableSectionElement>>;
@@ -1,2 +1,2 @@
1
- import{a as g,b as S,c as x,d as C,f as c,g as d,h as T}from"./chunk-72UMV3YP.js";import{a as y}from"./chunk-2PHWBRBD.js";import{m as f}from"./chunk-GYPSB3OK.js";import"./chunk-MF2QITTY.js";import{b as m}from"./chunk-VTCWSFFJ.js";import"./chunk-4LSFAAZW.js";import"./chunk-72TJUKMV.js";import"./chunk-3C5O3AQA.js";import"./chunk-XQVVOOLT.js";import"./chunk-HDPLH5HC.js";import{a as s}from"./chunk-AZ56JGNY.js";export*from"@tanstack/react-table";import{flexRender as R}from"@tanstack/react-table";import{Fragment as h,createContext as M,useContext as j,useMemo as E}from"react";import F from"tiny-invariant";var O=["unsorted","asc","desc"],V=["unsorted","desc","asc"];function P(t,a){return A(a==="alphanumeric"?O:V,t)??"unsorted"}function A(t,a,e){if(t.length===0)return e;let n=t.findIndex(r=>r===a);if(n===-1)return e;let l=(n+1)%t.length;return t.at(l)??e}import{Fragment as W,jsx as o,jsxs as w}from"react/jsx-runtime";var H=M(null);function u(){let t=j(H);return F(t,"useDataTableContext should only be used within a DataTable child component"),t}function z({children:t,table:a,...e}){let n=E(()=>({table:a}),[a]);return o(H.Provider,{value:n,children:o(g,{...e,children:o(S,{children:t})})})}function L({children:t,className:a,column:e,disableSorting:n=!1,iconPlacement:l="end",sortingMode:r,sortIcon:B,onClick:v,..._}){let D=e.getIsSorted(),p=!n&&e.getCanSort(),i=p&&typeof D=="string"?D:"unsorted",k=B?.(i)??o(Q,{mode:r,direction:i});return w(m,{appearance:"ghost",className:s("flex justify-start w-full h-full rounded-none",a),"data-sort-direction":i,"data-table-header-action":!0,icon:k,iconPlacement:l,onClick:b=>{v?.(b),!b.defaultPrevented&&(!p||n||typeof r>"u"||U(e,r))},priority:"neutral",type:"button",..._,children:[p&&i!=="unsorted"&&w("span",{className:"sr-only",children:["Column sorted in"," ",r==="alphanumeric"?i==="asc"?"ascending":"descending":f(i)," ","order"]}),t]})}function $({children:t,className:a,...e}){return o(d,{className:s("has-[[data-table-header-action]]:px-0",a),...e,children:t})}var I=C;I.displayName="DataTableBody";function q(t){let{table:a}=u();return o(x,{...t,children:a.getHeaderGroups().map(e=>o(c,{children:e.headers.map(n=>o(h,{children:n.isPlaceholder?o(d,{},n.id):R(n.column.columnDef.header,n.getContext())},n.id))},e.id))})}function G(){let{table:t}=u(),a=t.getRowModel().rows;return o(W,{children:a.map(e=>o(N,{row:e},e.id))})}function N({row:t,...a}){return o(c,{...a,children:t.getVisibleCells().map(e=>o(h,{children:R(e.column.columnDef.cell,e.getContext())},e.id))})}function J({children:t,...a}){let{table:e}=u(),n=e.getAllColumns().length;return o(c,{...a,children:o(T,{colSpan:n,children:t})})}function K({children:t,className:a,...e}){return o(T,{className:s("sticky z-10 right-0 top-px -bottom-px group-data-[sticky-active]/table:[box-shadow:inset_10px_0_8px_-8px_hsl(0deg_0%_0%_/_15%)]",a),...e,children:o("div",{className:"flex justify-end",children:t})})}function Q({direction:t,mode:a,...e}){return t==="unsorted"||!a||!t?o("svg",{"aria-hidden":!0,...e}):o(y,{mode:a,direction:t,...e})}function U(t,a){if(!t.getCanSort())return;let e=t.getIsSorted();switch(P(typeof e=="string"?e:"unsorted",a)){case"unsorted":t.clearSorting();return;case"asc":t.toggleSorting(!1);return;case"desc":t.toggleSorting(!0);return;default:return}}export{z as DataTable,K as DataTableActionCell,I as DataTableBody,J as DataTableEmptyRow,q as DataTableHead,$ as DataTableHeader,L as DataTableHeaderSortButton,N as DataTableRow,G as DataTableRows};
1
+ import{a as g,b as S,c as x,d as C,f as c,g as d,h as T}from"./chunk-JIRNFNH5.js";import{a as y}from"./chunk-2PHWBRBD.js";import{m as f}from"./chunk-GYPSB3OK.js";import"./chunk-MF2QITTY.js";import{b as m}from"./chunk-PANPBV3Q.js";import"./chunk-4LSFAAZW.js";import"./chunk-72TJUKMV.js";import"./chunk-3C5O3AQA.js";import"./chunk-I6T6YV2L.js";import"./chunk-NPTDRQT5.js";import{a as s}from"./chunk-AZ56JGNY.js";export*from"@tanstack/react-table";import{flexRender as R}from"@tanstack/react-table";import{Fragment as h,createContext as M,useContext as j,useMemo as E}from"react";import F from"tiny-invariant";var O=["unsorted","asc","desc"],V=["unsorted","desc","asc"];function P(t,a){return A(a==="alphanumeric"?O:V,t)??"unsorted"}function A(t,a,e){if(t.length===0)return e;let n=t.findIndex(r=>r===a);if(n===-1)return e;let l=(n+1)%t.length;return t.at(l)??e}import{Fragment as W,jsx as o,jsxs as w}from"react/jsx-runtime";var H=M(null);function u(){let t=j(H);return F(t,"useDataTableContext should only be used within a DataTable child component"),t}function z({children:t,table:a,...e}){let n=E(()=>({table:a}),[a]);return o(H.Provider,{value:n,children:o(g,{...e,children:o(S,{children:t})})})}function L({children:t,className:a,column:e,disableSorting:n=!1,iconPlacement:l="end",sortingMode:r,sortIcon:B,onClick:v,..._}){let D=e.getIsSorted(),p=!n&&e.getCanSort(),i=p&&typeof D=="string"?D:"unsorted",k=B?.(i)??o(Q,{mode:r,direction:i});return w(m,{appearance:"ghost",className:s("flex justify-start w-full h-full rounded-none",a),"data-sort-direction":i,"data-table-header-action":!0,icon:k,iconPlacement:l,onClick:b=>{v?.(b),!b.defaultPrevented&&(!p||n||typeof r>"u"||U(e,r))},priority:"neutral",type:"button",..._,children:[p&&i!=="unsorted"&&w("span",{className:"sr-only",children:["Column sorted in"," ",r==="alphanumeric"?i==="asc"?"ascending":"descending":f(i)," ","order"]}),t]})}function $({children:t,className:a,...e}){return o(d,{className:s("has-[[data-table-header-action]]:px-0",a),...e,children:t})}var I=C;I.displayName="DataTableBody";function q(t){let{table:a}=u();return o(x,{...t,children:a.getHeaderGroups().map(e=>o(c,{children:e.headers.map(n=>o(h,{children:n.isPlaceholder?o(d,{},n.id):R(n.column.columnDef.header,n.getContext())},n.id))},e.id))})}function G(){let{table:t}=u(),a=t.getRowModel().rows;return o(W,{children:a.map(e=>o(N,{row:e},e.id))})}function N({row:t,...a}){return o(c,{...a,children:t.getVisibleCells().map(e=>o(h,{children:R(e.column.columnDef.cell,e.getContext())},e.id))})}function J({children:t,...a}){let{table:e}=u(),n=e.getAllColumns().length;return o(c,{...a,children:o(T,{colSpan:n,children:t})})}function K({children:t,className:a,...e}){return o(T,{className:s("sticky z-10 right-0 top-px -bottom-px group-data-[sticky-active]/table:[box-shadow:inset_10px_0_8px_-8px_hsl(0deg_0%_0%_/_15%)]",a),...e,children:o("div",{className:"flex justify-end",children:t})})}function Q({direction:t,mode:a,...e}){return t==="unsorted"||!a||!t?o("svg",{"aria-hidden":!0,...e}):o(y,{mode:a,direction:t,...e})}function U(t,a){if(!t.getCanSort())return;let e=t.getIsSorted();switch(P(typeof e=="string"?e:"unsorted",a)){case"unsorted":t.clearSorting();return;case"asc":t.toggleSorting(!1);return;case"desc":t.toggleSorting(!0);return;default:return}}export{z as DataTable,K as DataTableActionCell,I as DataTableBody,J as DataTableEmptyRow,q as DataTableHead,$ as DataTableHeader,L as DataTableHeaderSortButton,N as DataTableRow,G as DataTableRows};
2
2
  //# sourceMappingURL=data-table.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/data-table/index.ts","../src/components/data-table/data-table.tsx","../src/components/data-table/helpers.ts"],"sourcesContent":["export * from \"@tanstack/react-table\";\n\nexport {\n\t//,\n\tDataTable,\n\tDataTableActionCell,\n\tDataTableBody,\n\tDataTableEmptyRow,\n\tDataTableHead,\n\tDataTableHeader,\n\tDataTableHeaderSortButton,\n\tDataTableRow,\n\tDataTableRows,\n} from \"./data-table.js\";\n","import {\n\ttype Column,\n\ttype HeaderContext,\n\ttype Row,\n\ttype Table as TableInstance,\n\tflexRender,\n} from \"@tanstack/react-table\";\nimport {\n\ttype ComponentProps,\n\tFragment,\n\ttype ReactNode,\n\tcreateContext,\n\tuseContext,\n\tuseMemo,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport {\n\t$timeSortingDirection,\n\ttype SortingMode,\n} from \"../../utils/sorting/direction.js\";\nimport { Button } from \"../button/button.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { SortIcon } from \"../icons/sort.js\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRoot,\n\tTableRow,\n} from \"../table/table.js\";\nimport { getNextSortDirection } from \"./helpers.js\";\nimport type { SortDirection } from \"./types.js\";\n\ntype DataTableContextShape<TData = unknown> = {\n\ttable: TableInstance<TData>;\n};\n\nconst DataTableContext = createContext<DataTableContextShape<any> | null>(null);\n\n/**\n * @private\n */\nfunction useDataTableContext<TData>() {\n\tconst context = useContext(DataTableContext);\n\n\tinvariant(\n\t\tcontext,\n\t\t\"useDataTableContext should only be used within a DataTable child component\",\n\t);\n\n\treturn context as DataTableContextShape<TData>;\n}\n\ntype DataTableProps<TData> = ComponentProps<typeof TableRoot> & {\n\ttable: TableInstance<TData>;\n};\n\nfunction DataTable<TData>({\n\tchildren,\n\ttable,\n\t...props\n}: DataTableProps<TData>) {\n\tconst context: DataTableContextShape<TData> = useMemo(\n\t\t() => ({ table }),\n\t\t[table],\n\t);\n\n\treturn (\n\t\t<DataTableContext.Provider value={context}>\n\t\t\t<TableRoot {...props}>\n\t\t\t\t<Table>{children}</Table>\n\t\t\t</TableRoot>\n\t\t</DataTableContext.Provider>\n\t);\n}\n\ntype DataTableHeaderSortButtonProps<TData, TValue> = Omit<\n\tComponentProps<typeof Button>,\n\t\"icon\"\n> &\n\tPick<HeaderContext<TData, TValue>, \"column\"> &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * Disable sorting for this column.\n\t\t\t\t * It will prevent the sorting direction from being toggled and any icon\n\t\t\t\t * from being shown.\n\t\t\t\t */\n\t\t\t\tdisableSorting: true;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: undefined;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode?: undefined;\n\t\t }\n\t\t| {\n\t\t\t\tdisableSorting?: false;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: (sortDirection: SortDirection) => ReactNode;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode: SortingMode;\n\t\t }\n\t);\n\n/**\n * A sortable button toggle for a column header in a data table.\n * If the column is sortable, clicking the button will toggle the sorting\n * direction.\n *\n * @example\n * ```md\n * Each click cycles through...\n *\n * For alphanumeric sorting:\n * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...\n *\n * For time sorting:\n * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...\n *\n * this is equivalent to the inverse of alphanumeric sorting, or\n * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...\n * ```\n */\nfunction DataTableHeaderSortButton<TData, TValue>({\n\tchildren,\n\tclassName,\n\tcolumn,\n\tdisableSorting = false,\n\ticonPlacement = \"end\",\n\tsortingMode,\n\tsortIcon: propSortIcon,\n\tonClick,\n\t...props\n}: DataTableHeaderSortButtonProps<TData, TValue>) {\n\tconst _sortDirection = column.getIsSorted();\n\tconst canSort = !disableSorting && column.getCanSort();\n\n\tconst sortDirection: SortDirection =\n\t\tcanSort && typeof _sortDirection === \"string\" ? _sortDirection : \"unsorted\";\n\n\tconst sortIcon = propSortIcon?.(sortDirection) ?? (\n\t\t<DefaultSortIcon mode={sortingMode} direction={sortDirection} />\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tappearance=\"ghost\"\n\t\t\tclassName={cx(\"flex justify-start w-full h-full rounded-none\", className)}\n\t\t\tdata-sort-direction={sortDirection}\n\t\t\tdata-table-header-action\n\t\t\ticon={sortIcon}\n\t\t\ticonPlacement={iconPlacement}\n\t\t\tonClick={(event) => {\n\t\t\t\tonClick?.(event);\n\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!canSort || disableSorting || typeof sortingMode === \"undefined\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttoggleNextSortingDirection(column, sortingMode);\n\t\t\t}}\n\t\t\tpriority=\"neutral\"\n\t\t\ttype=\"button\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{canSort && sortDirection !== \"unsorted\" && (\n\t\t\t\t<span className=\"sr-only\">\n\t\t\t\t\tColumn sorted in{\" \"}\n\t\t\t\t\t{sortingMode === \"alphanumeric\"\n\t\t\t\t\t\t? sortDirection === \"asc\"\n\t\t\t\t\t\t\t? \"ascending\"\n\t\t\t\t\t\t\t: \"descending\"\n\t\t\t\t\t\t: $timeSortingDirection(sortDirection)}{\" \"}\n\t\t\t\t\torder\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t{children}\n\t\t</Button>\n\t);\n}\n\ntype DataTableHeaderProps = ComponentProps<typeof TableHeader>;\n\n/**\n * A header for a data table.\n * This is typically used to wrap the `DataTableHeaderSortButton` component.\n */\nfunction DataTableHeader<TData, TValue>({\n\tchildren,\n\tclassName,\n\t...props\n}: DataTableHeaderProps) {\n\treturn (\n\t\t<TableHeader\n\t\t\tclassName={cx(\"has-[[data-table-header-action]]:px-0\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</TableHeader>\n\t);\n}\n\nconst DataTableBody = TableBody;\nDataTableBody.displayName = \"DataTableBody\";\n\ntype DataTableHeadProps = Omit<ComponentProps<typeof TableHead>, \"children\">;\n\nfunction DataTableHead<TData>(props: DataTableHeadProps) {\n\tconst { table } = useDataTableContext<TData>();\n\n\treturn (\n\t\t<TableHead {...props}>\n\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t<TableRow key={headerGroup.id}>\n\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t<Fragment key={header.id}>\n\t\t\t\t\t\t\t{header.isPlaceholder ? (\n\t\t\t\t\t\t\t\t<TableHeader key={header.id} />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tflexRender(header.column.columnDef.header, header.getContext())\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t))}\n\t\t\t\t</TableRow>\n\t\t\t))}\n\t\t</TableHead>\n\t);\n}\n\nfunction DataTableRows<TData>() {\n\tconst { table } = useDataTableContext<TData>();\n\tconst rows = table.getRowModel().rows;\n\n\treturn (\n\t\t<>\n\t\t\t{rows.map((row) => (\n\t\t\t\t<DataTableRow key={row.id} row={row} />\n\t\t\t))}\n\t\t</>\n\t);\n}\n\ntype DataTableRowProps<TData> = Omit<\n\tComponentProps<typeof TableRow>,\n\t\"children\"\n> & {\n\trow: Row<TData>;\n};\n\nfunction DataTableRow<TData>({ row, ...props }: DataTableRowProps<TData>) {\n\treturn (\n\t\t<TableRow {...props}>\n\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t<Fragment key={cell.id}>\n\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t</Fragment>\n\t\t\t))}\n\t\t</TableRow>\n\t);\n}\n\ntype DataTableEmptyRowProps = ComponentProps<typeof TableRow>;\n\nfunction DataTableEmptyRow<TData>({\n\tchildren,\n\t...props\n}: DataTableEmptyRowProps) {\n\tconst { table } = useDataTableContext<TData>();\n\tconst numberOfColumns = table.getAllColumns().length;\n\n\treturn (\n\t\t<TableRow {...props}>\n\t\t\t<TableCell colSpan={numberOfColumns}>{children}</TableCell>\n\t\t</TableRow>\n\t);\n}\n\ntype DataTableActionCellProps = ComponentProps<typeof TableCell>;\n\nfunction DataTableActionCell({\n\tchildren,\n\tclassName,\n\t...props\n}: DataTableActionCellProps) {\n\treturn (\n\t\t<TableCell\n\t\t\tclassName={cx(\n\t\t\t\t\"sticky z-10 right-0 top-px -bottom-px group-data-[sticky-active]/table:[box-shadow:inset_10px_0_8px_-8px_hsl(0deg_0%_0%_/_15%)]\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex justify-end\">{children}</div>\n\t\t</TableCell>\n\t);\n}\n\nexport {\n\t//,\n\tDataTable,\n\tDataTableActionCell,\n\tDataTableBody,\n\tDataTableEmptyRow,\n\tDataTableHead,\n\tDataTableHeader,\n\tDataTableHeaderSortButton,\n\tDataTableRow,\n\tDataTableRows,\n};\n\ntype DefaultSortIconProps = SvgAttributes & {\n\tdirection: SortDirection | undefined;\n\tmode: SortingMode | undefined;\n};\n\nfunction DefaultSortIcon({ direction, mode, ...props }: DefaultSortIconProps) {\n\tif (direction === \"unsorted\" || !mode || !direction) {\n\t\treturn <svg aria-hidden {...props} />;\n\t}\n\n\treturn <SortIcon mode={mode} direction={direction} {...props} />;\n}\n\n/**\n * Toggle the sorting direction of a column.\n * This ordering is typically toggled by clicking the column header.\n *\n * @example\n * ```md\n * Each click cycles through...\n *\n * For alphanumeric sorting:\n * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...\n *\n * For time sorting:\n * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...\n *\n * this is equivalent to the inverse of alphanumeric sorting, or\n * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...\n * ```\n */\nfunction toggleNextSortingDirection<TData, TValue>(\n\tcolumn: Column<TData, TValue>,\n\tsortingMode: SortingMode,\n) {\n\tif (!column.getCanSort()) {\n\t\treturn;\n\t}\n\n\tconst sortDirection = column.getIsSorted();\n\tconst currentSortDirection: SortDirection =\n\t\ttypeof sortDirection === \"string\" ? sortDirection : \"unsorted\";\n\n\tconst nextSortDirection = getNextSortDirection(\n\t\tcurrentSortDirection,\n\t\tsortingMode,\n\t);\n\n\tswitch (nextSortDirection) {\n\t\tcase \"unsorted\":\n\t\t\tcolumn.clearSorting();\n\t\t\treturn;\n\t\tcase \"asc\":\n\t\t\tcolumn.toggleSorting(false);\n\t\t\treturn;\n\t\tcase \"desc\":\n\t\t\tcolumn.toggleSorting(true);\n\t\t\treturn;\n\t\tdefault:\n\t\t\treturn;\n\t}\n}\n","import type { SortingMode } from \"../../utils/sorting/direction.js\";\nimport type { SortDirection } from \"./types.js\";\n\nconst alphanumericSortingOrder = [\n\t\"unsorted\",\n\t\"asc\",\n\t\"desc\",\n] as const satisfies SortDirection[];\n\nconst timeSortingOrder = [\n\t\"unsorted\",\n\t\"desc\",\n\t\"asc\",\n] as const satisfies SortDirection[];\n\n/**\n * Get the next sort direction based on the current sort direction and sorting mode.\n */\nfunction getNextSortDirection(\n\tcurrentSortDirection: SortDirection,\n\tsortingMode: SortingMode,\n) {\n\tconst sortOrder =\n\t\tsortingMode === \"alphanumeric\"\n\t\t\t? alphanumericSortingOrder\n\t\t\t: timeSortingOrder;\n\n\treturn getNextInCircularList(sortOrder, currentSortDirection) ?? \"unsorted\";\n}\n\n/**\n * Get the next item in a circular list.\n * If the current item is not found in the list (or it's empty), return the fallback value.\n */\nfunction getNextInCircularList<T>(\n\tlist: T[],\n\tcurrentItem: T,\n\tfallback?: T | undefined,\n) {\n\tif (list.length === 0) {\n\t\treturn fallback;\n\t}\n\n\tconst currentItemIndex = list.findIndex((item) => item === currentItem);\n\tif (currentItemIndex === -1) {\n\t\treturn fallback;\n\t}\n\n\tconst nextIndex = (currentItemIndex + 1) % list.length;\n\treturn list.at(nextIndex) ?? fallback;\n}\n\nexport {\n\t//,\n\tgetNextSortDirection,\n\tgetNextInCircularList,\n};\n"],"mappings":"0ZAAA,WAAc,wBCAd,OAKC,cAAAA,MACM,wBACP,OAEC,YAAAC,EAEA,iBAAAC,EACA,cAAAC,EACA,WAAAC,MACM,QACP,OAAOC,MAAe,iBCZtB,IAAMC,EAA2B,CAChC,WACA,MACA,MACD,EAEMC,EAAmB,CACxB,WACA,OACA,KACD,EAKA,SAASC,EACRC,EACAC,EACC,CAMD,OAAOC,EAJND,IAAgB,eACbJ,EACAC,EAEoCE,CAAoB,GAAK,UAClE,CAMA,SAASE,EACRC,EACAC,EACAC,EACC,CACD,GAAIF,EAAK,SAAW,EACnB,OAAOE,EAGR,IAAMC,EAAmBH,EAAK,UAAWI,GAASA,IAASH,CAAW,EACtE,GAAIE,IAAqB,GACxB,OAAOD,EAGR,IAAMG,GAAaF,EAAmB,GAAKH,EAAK,OAChD,OAAOA,EAAK,GAAGK,CAAS,GAAKH,CAC9B,CDuBI,OA8KF,YAAAI,EA9KE,OAAAC,EA0GA,QAAAC,MA1GA,oBAjCJ,IAAMC,EAAmBC,EAAiD,IAAI,EAK9E,SAASC,GAA6B,CACrC,IAAMC,EAAUC,EAAWJ,CAAgB,EAE3C,OAAAK,EACCF,EACA,4EACD,EAEOA,CACR,CAMA,SAASG,EAAiB,CACzB,SAAAC,EACA,MAAAC,EACA,GAAGC,CACJ,EAA0B,CACzB,IAAMN,EAAwCO,EAC7C,KAAO,CAAE,MAAAF,CAAM,GACf,CAACA,CAAK,CACP,EAEA,OACCV,EAACE,EAAiB,SAAjB,CAA0B,MAAOG,EACjC,SAAAL,EAACa,EAAA,CAAW,GAAGF,EACd,SAAAX,EAACc,EAAA,CAAO,SAAAL,EAAS,EAClB,EACD,CAEF,CA0DA,SAASM,EAAyC,CACjD,SAAAN,EACA,UAAAO,EACA,OAAAC,EACA,eAAAC,EAAiB,GACjB,cAAAC,EAAgB,MAChB,YAAAC,EACA,SAAUC,EACV,QAAAC,EACA,GAAGX,CACJ,EAAkD,CACjD,IAAMY,EAAiBN,EAAO,YAAY,EACpCO,EAAU,CAACN,GAAkBD,EAAO,WAAW,EAE/CQ,EACLD,GAAW,OAAOD,GAAmB,SAAWA,EAAiB,WAE5DG,EAAWL,IAAeI,CAAa,GAC5CzB,EAAC2B,EAAA,CAAgB,KAAMP,EAAa,UAAWK,EAAe,EAG/D,OACCxB,EAAC2B,EAAA,CACA,WAAW,QACX,UAAWC,EAAG,gDAAiDb,CAAS,EACxE,sBAAqBS,EACrB,2BAAwB,GACxB,KAAMC,EACN,cAAeP,EACf,QAAUW,GAAU,CACnBR,IAAUQ,CAAK,EACX,CAAAA,EAAM,mBAGN,CAACN,GAAWN,GAAkB,OAAOE,EAAgB,KAGzDW,EAA2Bd,EAAQG,CAAW,EAC/C,EACA,SAAS,UACT,KAAK,SACJ,GAAGT,EAEH,UAAAa,GAAWC,IAAkB,YAC7BxB,EAAC,QAAK,UAAU,UAAU,6BACR,IAChBmB,IAAgB,eACdK,IAAkB,MACjB,YACA,aACDO,EAAsBP,CAAa,EAAG,IAAI,SAE9C,EAEAhB,GACF,CAEF,CAQA,SAASwB,EAA+B,CACvC,SAAAxB,EACA,UAAAO,EACA,GAAGL,CACJ,EAAyB,CACxB,OACCX,EAACkC,EAAA,CACA,UAAWL,EAAG,wCAAyCb,CAAS,EAC/D,GAAGL,EAEH,SAAAF,EACF,CAEF,CAEA,IAAM0B,EAAgBC,EACtBD,EAAc,YAAc,gBAI5B,SAASE,EAAqB1B,EAA2B,CACxD,GAAM,CAAE,MAAAD,CAAM,EAAIN,EAA2B,EAE7C,OACCJ,EAACsC,EAAA,CAAW,GAAG3B,EACb,SAAAD,EAAM,gBAAgB,EAAE,IAAK6B,GAC7BvC,EAACwC,EAAA,CACC,SAAAD,EAAY,QAAQ,IAAKE,GACzBzC,EAACD,EAAA,CACC,SAAA0C,EAAO,cACPzC,EAACkC,EAAA,GAAiBO,EAAO,EAAI,EAE7BC,EAAWD,EAAO,OAAO,UAAU,OAAQA,EAAO,WAAW,CAAC,GAJjDA,EAAO,EAMtB,CACA,GATaF,EAAY,EAU3B,CACA,EACF,CAEF,CAEA,SAASI,GAAuB,CAC/B,GAAM,CAAE,MAAAjC,CAAM,EAAIN,EAA2B,EACvCwC,EAAOlC,EAAM,YAAY,EAAE,KAEjC,OACCV,EAAAD,EAAA,CACE,SAAA6C,EAAK,IAAKC,GACV7C,EAAC8C,EAAA,CAA0B,IAAKD,GAAbA,EAAI,EAAc,CACrC,EACF,CAEF,CASA,SAASC,EAAoB,CAAE,IAAAD,EAAK,GAAGlC,CAAM,EAA6B,CACzE,OACCX,EAACwC,EAAA,CAAU,GAAG7B,EACZ,SAAAkC,EAAI,gBAAgB,EAAE,IAAKE,GAC3B/C,EAACD,EAAA,CACC,SAAA2C,EAAWK,EAAK,OAAO,UAAU,KAAMA,EAAK,WAAW,CAAC,GAD3CA,EAAK,EAEpB,CACA,EACF,CAEF,CAIA,SAASC,EAAyB,CACjC,SAAAvC,EACA,GAAGE,CACJ,EAA2B,CAC1B,GAAM,CAAE,MAAAD,CAAM,EAAIN,EAA2B,EACvC6C,EAAkBvC,EAAM,cAAc,EAAE,OAE9C,OACCV,EAACwC,EAAA,CAAU,GAAG7B,EACb,SAAAX,EAACkD,EAAA,CAAU,QAASD,EAAkB,SAAAxC,EAAS,EAChD,CAEF,CAIA,SAAS0C,EAAoB,CAC5B,SAAA1C,EACA,UAAAO,EACA,GAAGL,CACJ,EAA6B,CAC5B,OACCX,EAACkD,EAAA,CACA,UAAWrB,EACV,kIACAb,CACD,EACC,GAAGL,EAEJ,SAAAX,EAAC,OAAI,UAAU,mBAAoB,SAAAS,EAAS,EAC7C,CAEF,CAoBA,SAAS2C,EAAgB,CAAE,UAAAC,EAAW,KAAAC,EAAM,GAAGC,CAAM,EAAyB,CAC7E,OAAIF,IAAc,YAAc,CAACC,GAAQ,CAACD,EAClCG,EAAC,OAAI,cAAW,GAAE,GAAGD,EAAO,EAG7BC,EAACC,EAAA,CAAS,KAAMH,EAAM,UAAWD,EAAY,GAAGE,EAAO,CAC/D,CAoBA,SAASG,EACRC,EACAC,EACC,CACD,GAAI,CAACD,EAAO,WAAW,EACtB,OAGD,IAAME,EAAgBF,EAAO,YAAY,EASzC,OAL0BG,EAFzB,OAAOD,GAAkB,SAAWA,EAAgB,WAIpDD,CACD,EAE2B,CAC1B,IAAK,WACJD,EAAO,aAAa,EACpB,OACD,IAAK,MACJA,EAAO,cAAc,EAAK,EAC1B,OACD,IAAK,OACJA,EAAO,cAAc,EAAI,EACzB,OACD,QACC,MACF,CACD","names":["flexRender","Fragment","createContext","useContext","useMemo","invariant","alphanumericSortingOrder","timeSortingOrder","getNextSortDirection","currentSortDirection","sortingMode","getNextInCircularList","list","currentItem","fallback","currentItemIndex","item","nextIndex","Fragment","jsx","jsxs","DataTableContext","createContext","useDataTableContext","context","useContext","invariant","DataTable","children","table","props","useMemo","TableRoot","Table","DataTableHeaderSortButton","className","column","disableSorting","iconPlacement","sortingMode","propSortIcon","onClick","_sortDirection","canSort","sortDirection","sortIcon","DefaultSortIcon","Button","cx","event","toggleNextSortingDirection","$timeSortingDirection","DataTableHeader","TableHeader","DataTableBody","TableBody","DataTableHead","TableHead","headerGroup","TableRow","header","flexRender","DataTableRows","rows","row","DataTableRow","cell","DataTableEmptyRow","numberOfColumns","TableCell","DataTableActionCell","DefaultSortIcon","direction","mode","props","jsx","SortIcon","toggleNextSortingDirection","column","sortingMode","sortDirection","getNextSortDirection"]}
1
+ {"version":3,"sources":["../src/components/data-table/index.ts","../src/components/data-table/data-table.tsx","../src/components/data-table/helpers.ts"],"sourcesContent":["export * from \"@tanstack/react-table\";\n\nexport {\n\t//,\n\tDataTable,\n\tDataTableActionCell,\n\tDataTableBody,\n\tDataTableEmptyRow,\n\tDataTableHead,\n\tDataTableHeader,\n\tDataTableHeaderSortButton,\n\tDataTableRow,\n\tDataTableRows,\n} from \"./data-table.js\";\n","import {\n\ttype Column,\n\ttype HeaderContext,\n\ttype Row,\n\ttype Table as TableInstance,\n\tflexRender,\n} from \"@tanstack/react-table\";\nimport {\n\ttype ComponentProps,\n\tFragment,\n\ttype ReactNode,\n\tcreateContext,\n\tuseContext,\n\tuseMemo,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport {\n\t$timeSortingDirection,\n\ttype SortingMode,\n} from \"../../utils/sorting/direction.js\";\nimport { Button } from \"../button/button.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { SortIcon } from \"../icons/sort.js\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRoot,\n\tTableRow,\n} from \"../table/table.js\";\nimport { getNextSortDirection } from \"./helpers.js\";\nimport type { SortDirection } from \"./types.js\";\n\ntype DataTableContextShape<TData = unknown> = {\n\ttable: TableInstance<TData>;\n};\n\nconst DataTableContext = createContext<DataTableContextShape<any> | null>(null);\n\n/**\n * @private\n */\nfunction useDataTableContext<TData>() {\n\tconst context = useContext(DataTableContext);\n\n\tinvariant(\n\t\tcontext,\n\t\t\"useDataTableContext should only be used within a DataTable child component\",\n\t);\n\n\treturn context as DataTableContextShape<TData>;\n}\n\ntype DataTableProps<TData> = ComponentProps<typeof TableRoot> & {\n\ttable: TableInstance<TData>;\n};\n\n/**\n * A data table component that provides sorting and other data table functionality.\n * Built on top of TanStack Table for advanced table features.\n *\n * @see https://mantle.ngrok.com/components/data-table#api-data-table\n *\n * @example\n * ```tsx\n * <DataTable table={table}>\n * <DataTableHead />\n * <DataTableBody>\n * <DataTableRows />\n * </DataTableBody>\n * </DataTable>\n * ```\n */\nfunction DataTable<TData>({\n\tchildren,\n\ttable,\n\t...props\n}: DataTableProps<TData>) {\n\tconst context: DataTableContextShape<TData> = useMemo(\n\t\t() => ({ table }),\n\t\t[table],\n\t);\n\n\treturn (\n\t\t<DataTableContext.Provider value={context}>\n\t\t\t<TableRoot {...props}>\n\t\t\t\t<Table>{children}</Table>\n\t\t\t</TableRoot>\n\t\t</DataTableContext.Provider>\n\t);\n}\n\ntype DataTableHeaderSortButtonProps<TData, TValue> = Omit<\n\tComponentProps<typeof Button>,\n\t\"icon\"\n> &\n\tPick<HeaderContext<TData, TValue>, \"column\"> &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * Disable sorting for this column.\n\t\t\t\t * It will prevent the sorting direction from being toggled and any icon\n\t\t\t\t * from being shown.\n\t\t\t\t */\n\t\t\t\tdisableSorting: true;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: undefined;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode?: undefined;\n\t\t }\n\t\t| {\n\t\t\t\tdisableSorting?: false;\n\t\t\t\t/**\n\t\t\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t\t\t * and you want to override the default sort icon\n\t\t\t\t */\n\t\t\t\tsortIcon?: (sortDirection: SortDirection) => ReactNode;\n\t\t\t\t/**\n\t\t\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t\t\t */\n\t\t\t\tsortingMode: SortingMode;\n\t\t }\n\t);\n\n/**\n * A sortable button toggle for a column header in a data table.\n * If the column is sortable, clicking the button will toggle the sorting\n * direction.\n *\n * @see https://mantle.ngrok.com/components/data-table#api-data-table-header-sort-button\n *\n * @example\n * ```tsx\n * <DataTableHeaderSortButton\n * column={column}\n * sortingMode=\"alphanumeric\"\n * >\n * Column Title\n * </DataTableHeaderSortButton>\n * ```\n *\n * Each click cycles through:\n * - For alphanumeric sorting: unsorted ➡️ ascending ➡️ descending ➡️ unsorted\n * - For time sorting: unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted\n */\nfunction DataTableHeaderSortButton<TData, TValue>({\n\tchildren,\n\tclassName,\n\tcolumn,\n\tdisableSorting = false,\n\ticonPlacement = \"end\",\n\tsortingMode,\n\tsortIcon: propSortIcon,\n\tonClick,\n\t...props\n}: DataTableHeaderSortButtonProps<TData, TValue>) {\n\tconst _sortDirection = column.getIsSorted();\n\tconst canSort = !disableSorting && column.getCanSort();\n\n\tconst sortDirection: SortDirection =\n\t\tcanSort && typeof _sortDirection === \"string\" ? _sortDirection : \"unsorted\";\n\n\tconst sortIcon = propSortIcon?.(sortDirection) ?? (\n\t\t<DefaultSortIcon mode={sortingMode} direction={sortDirection} />\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tappearance=\"ghost\"\n\t\t\tclassName={cx(\"flex justify-start w-full h-full rounded-none\", className)}\n\t\t\tdata-sort-direction={sortDirection}\n\t\t\tdata-table-header-action\n\t\t\ticon={sortIcon}\n\t\t\ticonPlacement={iconPlacement}\n\t\t\tonClick={(event) => {\n\t\t\t\tonClick?.(event);\n\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!canSort || disableSorting || typeof sortingMode === \"undefined\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttoggleNextSortingDirection(column, sortingMode);\n\t\t\t}}\n\t\t\tpriority=\"neutral\"\n\t\t\ttype=\"button\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{canSort && sortDirection !== \"unsorted\" && (\n\t\t\t\t<span className=\"sr-only\">\n\t\t\t\t\tColumn sorted in{\" \"}\n\t\t\t\t\t{sortingMode === \"alphanumeric\"\n\t\t\t\t\t\t? sortDirection === \"asc\"\n\t\t\t\t\t\t\t? \"ascending\"\n\t\t\t\t\t\t\t: \"descending\"\n\t\t\t\t\t\t: $timeSortingDirection(sortDirection)}{\" \"}\n\t\t\t\t\torder\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t{children}\n\t\t</Button>\n\t);\n}\n\ntype DataTableHeaderProps = ComponentProps<typeof TableHeader>;\n\n/**\n * A header for a data table.\n * This is typically used to wrap the `DataTableHeaderSortButton` component.\n *\n * @see https://mantle.ngrok.com/components/data-table#api-data-table-header\n *\n * @example\n * ```tsx\n * <DataTableHeader>\n * <DataTableHeaderSortButton column={column} sortingMode=\"alphanumeric\">\n * Column Title\n * </DataTableHeaderSortButton>\n * </DataTableHeader>\n * ```\n */\nfunction DataTableHeader<TData, TValue>({\n\tchildren,\n\tclassName,\n\t...props\n}: DataTableHeaderProps) {\n\treturn (\n\t\t<TableHeader\n\t\t\tclassName={cx(\"has-[[data-table-header-action]]:px-0\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</TableHeader>\n\t);\n}\n\nconst DataTableBody = TableBody;\nDataTableBody.displayName = \"DataTableBody\";\n\ntype DataTableHeadProps = Omit<ComponentProps<typeof TableHead>, \"children\">;\n\nfunction DataTableHead<TData>(props: DataTableHeadProps) {\n\tconst { table } = useDataTableContext<TData>();\n\n\treturn (\n\t\t<TableHead {...props}>\n\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t<TableRow key={headerGroup.id}>\n\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t<Fragment key={header.id}>\n\t\t\t\t\t\t\t{header.isPlaceholder ? (\n\t\t\t\t\t\t\t\t<TableHeader key={header.id} />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tflexRender(header.column.columnDef.header, header.getContext())\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t))}\n\t\t\t\t</TableRow>\n\t\t\t))}\n\t\t</TableHead>\n\t);\n}\n\nfunction DataTableRows<TData>() {\n\tconst { table } = useDataTableContext<TData>();\n\tconst rows = table.getRowModel().rows;\n\n\treturn (\n\t\t<>\n\t\t\t{rows.map((row) => (\n\t\t\t\t<DataTableRow key={row.id} row={row} />\n\t\t\t))}\n\t\t</>\n\t);\n}\n\ntype DataTableRowProps<TData> = Omit<\n\tComponentProps<typeof TableRow>,\n\t\"children\"\n> & {\n\trow: Row<TData>;\n};\n\nfunction DataTableRow<TData>({ row, ...props }: DataTableRowProps<TData>) {\n\treturn (\n\t\t<TableRow {...props}>\n\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t<Fragment key={cell.id}>\n\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t</Fragment>\n\t\t\t))}\n\t\t</TableRow>\n\t);\n}\n\ntype DataTableEmptyRowProps = ComponentProps<typeof TableRow>;\n\nfunction DataTableEmptyRow<TData>({\n\tchildren,\n\t...props\n}: DataTableEmptyRowProps) {\n\tconst { table } = useDataTableContext<TData>();\n\tconst numberOfColumns = table.getAllColumns().length;\n\n\treturn (\n\t\t<TableRow {...props}>\n\t\t\t<TableCell colSpan={numberOfColumns}>{children}</TableCell>\n\t\t</TableRow>\n\t);\n}\n\ntype DataTableActionCellProps = ComponentProps<typeof TableCell>;\n\nfunction DataTableActionCell({\n\tchildren,\n\tclassName,\n\t...props\n}: DataTableActionCellProps) {\n\treturn (\n\t\t<TableCell\n\t\t\tclassName={cx(\n\t\t\t\t\"sticky z-10 right-0 top-px -bottom-px group-data-[sticky-active]/table:[box-shadow:inset_10px_0_8px_-8px_hsl(0deg_0%_0%_/_15%)]\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex justify-end\">{children}</div>\n\t\t</TableCell>\n\t);\n}\n\nexport {\n\t//,\n\tDataTable,\n\tDataTableActionCell,\n\tDataTableBody,\n\tDataTableEmptyRow,\n\tDataTableHead,\n\tDataTableHeader,\n\tDataTableHeaderSortButton,\n\tDataTableRow,\n\tDataTableRows,\n};\n\ntype DefaultSortIconProps = SvgAttributes & {\n\tdirection: SortDirection | undefined;\n\tmode: SortingMode | undefined;\n};\n\nfunction DefaultSortIcon({ direction, mode, ...props }: DefaultSortIconProps) {\n\tif (direction === \"unsorted\" || !mode || !direction) {\n\t\treturn <svg aria-hidden {...props} />;\n\t}\n\n\treturn <SortIcon mode={mode} direction={direction} {...props} />;\n}\n\n/**\n * Toggle the sorting direction of a column.\n * This ordering is typically toggled by clicking the column header.\n *\n * @example\n * ```md\n * Each click cycles through...\n *\n * For alphanumeric sorting:\n * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...\n *\n * For time sorting:\n * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...\n *\n * this is equivalent to the inverse of alphanumeric sorting, or\n * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...\n * ```\n */\nfunction toggleNextSortingDirection<TData, TValue>(\n\tcolumn: Column<TData, TValue>,\n\tsortingMode: SortingMode,\n) {\n\tif (!column.getCanSort()) {\n\t\treturn;\n\t}\n\n\tconst sortDirection = column.getIsSorted();\n\tconst currentSortDirection: SortDirection =\n\t\ttypeof sortDirection === \"string\" ? sortDirection : \"unsorted\";\n\n\tconst nextSortDirection = getNextSortDirection(\n\t\tcurrentSortDirection,\n\t\tsortingMode,\n\t);\n\n\tswitch (nextSortDirection) {\n\t\tcase \"unsorted\":\n\t\t\tcolumn.clearSorting();\n\t\t\treturn;\n\t\tcase \"asc\":\n\t\t\tcolumn.toggleSorting(false);\n\t\t\treturn;\n\t\tcase \"desc\":\n\t\t\tcolumn.toggleSorting(true);\n\t\t\treturn;\n\t\tdefault:\n\t\t\treturn;\n\t}\n}\n","import type { SortingMode } from \"../../utils/sorting/direction.js\";\nimport type { SortDirection } from \"./types.js\";\n\nconst alphanumericSortingOrder = [\n\t\"unsorted\",\n\t\"asc\",\n\t\"desc\",\n] as const satisfies SortDirection[];\n\nconst timeSortingOrder = [\n\t\"unsorted\",\n\t\"desc\",\n\t\"asc\",\n] as const satisfies SortDirection[];\n\n/**\n * Get the next sort direction based on the current sort direction and sorting mode.\n */\nfunction getNextSortDirection(\n\tcurrentSortDirection: SortDirection,\n\tsortingMode: SortingMode,\n) {\n\tconst sortOrder =\n\t\tsortingMode === \"alphanumeric\"\n\t\t\t? alphanumericSortingOrder\n\t\t\t: timeSortingOrder;\n\n\treturn getNextInCircularList(sortOrder, currentSortDirection) ?? \"unsorted\";\n}\n\n/**\n * Get the next item in a circular list.\n * If the current item is not found in the list (or it's empty), return the fallback value.\n */\nfunction getNextInCircularList<T>(\n\tlist: T[],\n\tcurrentItem: T,\n\tfallback?: T | undefined,\n) {\n\tif (list.length === 0) {\n\t\treturn fallback;\n\t}\n\n\tconst currentItemIndex = list.findIndex((item) => item === currentItem);\n\tif (currentItemIndex === -1) {\n\t\treturn fallback;\n\t}\n\n\tconst nextIndex = (currentItemIndex + 1) % list.length;\n\treturn list.at(nextIndex) ?? fallback;\n}\n\nexport {\n\t//,\n\tgetNextSortDirection,\n\tgetNextInCircularList,\n};\n"],"mappings":"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","names":["flexRender","Fragment","createContext","useContext","useMemo","invariant","alphanumericSortingOrder","timeSortingOrder","getNextSortDirection","currentSortDirection","sortingMode","getNextInCircularList","list","currentItem","fallback","currentItemIndex","item","nextIndex","Fragment","jsx","jsxs","DataTableContext","createContext","useDataTableContext","context","useContext","invariant","DataTable","children","table","props","useMemo","TableRoot","Table","DataTableHeaderSortButton","className","column","disableSorting","iconPlacement","sortingMode","propSortIcon","onClick","_sortDirection","canSort","sortDirection","sortIcon","DefaultSortIcon","Button","cx","event","toggleNextSortingDirection","$timeSortingDirection","DataTableHeader","TableHeader","DataTableBody","TableBody","DataTableHead","TableHead","headerGroup","TableRow","header","flexRender","DataTableRows","rows","row","DataTableRow","cell","DataTableEmptyRow","numberOfColumns","TableCell","DataTableActionCell","DefaultSortIcon","direction","mode","props","jsx","SortIcon","toggleNextSortingDirection","column","sortingMode","sortDirection","getNextSortDirection"]}