@ngrok/mantle 0.25.2 → 0.27.0

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 (45) hide show
  1. package/dist/alert-dialog.js +1 -1
  2. package/dist/chunk-DDMTW6XB.js +2 -0
  3. package/dist/chunk-DDMTW6XB.js.map +1 -0
  4. package/dist/chunk-FHW7SSNY.js +2 -0
  5. package/dist/chunk-FHW7SSNY.js.map +1 -0
  6. package/dist/chunk-GOXG4BVJ.js +2 -0
  7. package/dist/chunk-GOXG4BVJ.js.map +1 -0
  8. package/dist/chunk-GYPSB3OK.js +2 -0
  9. package/dist/chunk-GYPSB3OK.js.map +1 -0
  10. package/dist/chunk-WGF5NYWL.js +2 -0
  11. package/dist/chunk-WGF5NYWL.js.map +1 -0
  12. package/dist/chunk-YAT4IMMN.js +2 -0
  13. package/dist/chunk-YAT4IMMN.js.map +1 -0
  14. package/dist/code-block.js +3 -3
  15. package/dist/code-block.js.map +1 -1
  16. package/dist/data-table.d.ts +42 -0
  17. package/dist/data-table.js +1 -1
  18. package/dist/data-table.js.map +1 -1
  19. package/dist/dialog.js +1 -1
  20. package/dist/direction-veAOo2is.d.ts +143 -0
  21. package/dist/icons.d.ts +37 -0
  22. package/dist/icons.js +2 -0
  23. package/dist/icons.js.map +1 -0
  24. package/dist/pagination.js +1 -1
  25. package/dist/select.d.ts +22 -6
  26. package/dist/select.js +1 -1
  27. package/dist/sheet.js +1 -1
  28. package/dist/sorting.d.ts +18 -0
  29. package/dist/sorting.js +2 -0
  30. package/dist/sorting.js.map +1 -0
  31. package/dist/table.d.ts +375 -10
  32. package/dist/table.js +1 -1
  33. package/dist/table.js.map +1 -1
  34. package/dist/tailwind-preset.cjs +1 -1
  35. package/dist/tailwind-preset.cjs.map +1 -1
  36. package/dist/tailwind-preset.d.cts +1 -1
  37. package/dist/tailwind-preset.d.ts +1 -1
  38. package/dist/tailwind-preset.js +1 -1
  39. package/dist/tailwind-preset.js.map +1 -1
  40. package/dist/toast.js +1 -1
  41. package/package.json +25 -15
  42. package/dist/chunk-7FIV4E5C.js +0 -2
  43. package/dist/chunk-7FIV4E5C.js.map +0 -1
  44. package/dist/chunk-ATNIDU3M.js +0 -2
  45. package/dist/chunk-ATNIDU3M.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":["import { CaretDown } from \"@phosphor-icons/react/CaretDown\";\nimport { Check } from \"@phosphor-icons/react/Check\";\nimport { Copy } from \"@phosphor-icons/react/Copy\";\nimport { FileText } from \"@phosphor-icons/react/FileText\";\nimport { Terminal } 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 { 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-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-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-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<Check className=\"size-4 shrink-0\" weight=\"bold\" />\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<Copy className=\"-ml-px size-5 shrink-0\" />\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<CaretDown\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"size-4 shrink-0\",\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\tweight=\"bold\"\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 = <FileText weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"cli\":\n\t\t\t\tsvg = <Terminal 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\nfunction TrafficPolicyFileIcon(props: SvgAttributes) {\n\treturn (\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\twidth=\"1em\"\n\t\t\theight=\"1em\"\n\t\t\tfill=\"currentColor\"\n\t\t\tviewBox=\"0 0 256 256\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path fill=\"none\" d=\"M0 0h256v256H0z\" />\n\t\t\t<path d=\"m213.7 82.3-56-56c-1.5-1.5-3.5-2.3-5.7-2.3H56c-8.8 0-16 7.2-16 16v88c0 4.4 3.6 8 8 8s8-3.6 8-8V40h88v48c0 4.4 3.6 8 8 8h48v120h-40c-4.4 0-8 3.6-8 8s3.6 8 8 8h40c8.8 0 16-7.2 16-16V88c0-2.1-.8-4.2-2.3-5.7zm-53.7-31L188.7 80H160V51.3z\" />\n\t\t\t<path d=\"M124.6 194.5h-6.8v-27.3h6.8c1.9 0 3.4-1.5 3.4-3.4s-1.5-3.4-3.4-3.4h-6.8v-10.2c0-3.8-3.1-6.8-6.8-6.8H63.3c-3.8 0-6.8 3.1-6.8 6.8v10.2h-6.8c-1.9 0-3.4 1.5-3.4 3.4s1.5 3.4 3.4 3.4h6.8v27.3h-6.8c-1.9 0-3.4 1.5-3.4 3.4s1.5 3.4 3.4 3.4h6.8v23.9c0 3.8 3.1 6.8 6.8 6.8H111c3.8 0 6.8-3.1 6.8-6.8v-23.9h6.8c1.9 0 3.4-1.5 3.4-3.4s-1.5-3.4-3.4-3.4zm-37.5-11.9c-6.6 0-11.9-5.3-11.9-11.9s5.3-11.9 11.9-11.9S99 164.1 99 170.7s-5.3 11.9-11.9 11.9zm0 10.2c6.6 0 11.9 5.3 11.9 11.9s-5.3 11.9-11.9 11.9-11.9-5.3-11.9-11.9 5.3-11.9 11.9-11.9z\" />\n\t\t</svg>\n\t);\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 * 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};\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 { z } from \"zod\";\nimport { indentations } 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\nconst metaSchema = z.object({\n\tcollapsible: z.boolean().default(false),\n\tdisableCopy: z.boolean().default(false),\n\tmode: z.enum(modes).optional(),\n\ttitle: z.string().trim().optional(),\n\tindentation: z.enum(indentations).optional(),\n});\n\ntype MetaInput = z.input<typeof metaSchema>;\n\ntype Meta = z.infer<typeof metaSchema>;\n\nconst defaultMeta = {\n\tcollapsible: false,\n\tdisableCopy: false,\n\tmode: undefined,\n\ttitle: undefined,\n\tindentation: 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(value: string | undefined): Meta {\n\tconst metastring = value?.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 value = normalizeValue(_value);\n\t\tacc[key] = value ?? true;\n\t\treturn acc;\n\t}, {});\n\n\ttry {\n\t\tconst parsed = metaSchema.parse(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"],"mappings":"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","names":["CaretDown","Check","Copy","FileText","Terminal","Slot","clsx","createContext","forwardRef","useContext","useEffect","useId","useMemo","useRef","useState","assert","escapeHtml","value","escaped","character","Prism","indentations","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","Check","Copy","CodeBlockExpanderButton","prev","CaretDown","CodeBlockIcon","preset","_svgProp","svg","FileText","Terminal","TrafficPolicyFileIcon","Icon","TrafficPolicyFileIcon","props","jsxs","jsx","fmtCode","strings","values","isTemplateStringsArray","text","minIndent","findMinIndent","line","findMinIndent","value","match","acc","curr","isTemplateStringsArray","strings","z","modes","metaSchema","z","indentations","defaultMeta","parseMetastring","value","metastring","metaJson","tokenizeMetastring","acc","token","key","_value","normalizeValue","parsed","normalizeValue","value","tokenizeMetastring","input","result","currentString","inQuotes","char"]}
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":["import { CaretDown } from \"@phosphor-icons/react/CaretDown\";\nimport { Check } from \"@phosphor-icons/react/Check\";\nimport { Copy } from \"@phosphor-icons/react/Copy\";\nimport { FileText } from \"@phosphor-icons/react/FileText\";\nimport { Terminal } 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 { TrafficPolicyFile } 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<Check className=\"size-4 shrink-0\" weight=\"bold\" />\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<Copy className=\"-ml-px size-5 shrink-0\" />\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<CaretDown\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"size-4 shrink-0\",\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\tweight=\"bold\"\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 = <FileText weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"cli\":\n\t\t\t\tsvg = <Terminal weight=\"fill\" />;\n\t\t\t\tbreak;\n\t\t\tcase \"traffic-policy\":\n\t\t\t\tsvg = <TrafficPolicyFile />;\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 * 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};\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 { z } from \"zod\";\nimport { indentations } 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\nconst metaSchema = z.object({\n\tcollapsible: z.boolean().default(false),\n\tdisableCopy: z.boolean().default(false),\n\tmode: z.enum(modes).optional(),\n\ttitle: z.string().trim().optional(),\n\tindentation: z.enum(indentations).optional(),\n});\n\ntype MetaInput = z.input<typeof metaSchema>;\n\ntype Meta = z.infer<typeof metaSchema>;\n\nconst defaultMeta = {\n\tcollapsible: false,\n\tdisableCopy: false,\n\tmode: undefined,\n\ttitle: undefined,\n\tindentation: 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(value: string | undefined): Meta {\n\tconst metastring = value?.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 value = normalizeValue(_value);\n\t\tacc[key] = value ?? true;\n\t\treturn acc;\n\t}, {});\n\n\ttry {\n\t\tconst parsed = metaSchema.parse(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"],"mappings":"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","names":["CaretDown","Check","Copy","FileText","Terminal","Slot","clsx","createContext","forwardRef","useContext","useEffect","useId","useMemo","useRef","useState","assert","escapeHtml","value","escaped","character","Prism","indentations","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","Check","Copy","CodeBlockExpanderButton","prev","CaretDown","CodeBlockIcon","preset","_svgProp","svg","FileText","Terminal","TrafficPolicyFile","Icon","fmtCode","strings","values","isTemplateStringsArray","text","minIndent","findMinIndent","line","findMinIndent","value","match","acc","curr","isTemplateStringsArray","strings","z","modes","metaSchema","z","indentations","defaultMeta","parseMetastring","value","metastring","metaJson","tokenizeMetastring","acc","token","key","_value","normalizeValue","parsed","normalizeValue","value","tokenizeMetastring","input","result","currentString","inQuotes","char"]}
@@ -1 +1,43 @@
1
+ import { HeaderContext } from '@tanstack/react-table';
1
2
  export * from '@tanstack/react-table';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { ComponentProps, ReactNode } from 'react';
5
+ import { k as SortingMode } from './direction-veAOo2is.js';
6
+ import { TableHeader } from './table.js';
7
+
8
+ declare const sortDirections: readonly ["asc", "desc", "unsorted"];
9
+ type SortDirection = (typeof sortDirections)[number];
10
+
11
+ type DataTableColumnHeaderProps<TData, TValue> = ComponentProps<typeof TableHeader> & Pick<HeaderContext<TData, TValue>, "column"> & {
12
+ /**
13
+ * Use this to render a custom sort icon for the column if it is sortable
14
+ * and you want to override the default sort icon
15
+ */
16
+ sortIcon?: (sortDirection: SortDirection) => ReactNode;
17
+ /**
18
+ * The sorting mode of the column, whether it is alphanumeric or time based.
19
+ */
20
+ sortingMode: SortingMode;
21
+ };
22
+ /**
23
+ * The header for a column in a data table.
24
+ * If the column is sortable, clicking the header will toggle the sorting
25
+ * direction.
26
+ *
27
+ * @example
28
+ * ```md
29
+ * Each click cycles through...
30
+ *
31
+ * For alphanumeric sorting:
32
+ * unsorted ➡️ ascending ➡️ descending ➡️ unsorted ➡️ ...
33
+ *
34
+ * For time sorting:
35
+ * unsorted ➡️ newest-to-oldest ➡️ oldest-to-newest ➡️ unsorted ➡️ ...
36
+ *
37
+ * this is equivalent to the inverse of alphanumeric sorting, or
38
+ * unsorted ➡️ descending ➡️ ascending ➡️ unsorted ➡️ ...
39
+ * ```
40
+ */
41
+ declare function DataTableHeader<TData, TValue>({ children, className, column, sortIcon: propsSortIcon, sortingMode, ...props }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime.JSX.Element;
42
+
43
+ export { DataTableHeader };
@@ -1,2 +1,2 @@
1
- export*from"@tanstack/react-table";
1
+ import{f}from"./chunk-YAT4IMMN.js";import{a as S}from"./chunk-FHW7SSNY.js";import"./chunk-GYPSB3OK.js";import{b as p}from"./chunk-J3NVDJIE.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a as u}from"./chunk-AZ56JGNY.js";export*from"@tanstack/react-table";var D=["unsorted","asc","desc"],T=["unsorted","desc","asc"];function g(t,r){return y(r==="alphanumeric"?D:T,t)??"unsorted"}function y(t,r,e){if(t.length===0)return e;let o=t.findIndex(s=>s===r);if(o===-1)return e;let n=(o+1)%t.length;return t.at(n)??e}import{jsx as a,jsxs as m}from"react/jsx-runtime";function x({children:t,className:r,column:e,sortIcon:o,sortingMode:n,...s}){let c=e.getIsSorted(),d=e.getCanSort(),i=d&&typeof c=="string"?c:"unsorted",l=o?.(i)??a(I,{mode:n,direction:i});return a(f,{className:u("px-0",r),...s,children:m(p,{className:"flex justify-start w-full h-full rounded-none",type:"button",appearance:"ghost",priority:"neutral",iconPlacement:"end","data-sort-direction":i,icon:l,onClick:()=>{d&&C(e,n)},children:[i!=="unsorted"&&m("span",{className:"sr-only",children:["Sorted in ",i==="asc"?"ascending":"descending"," ","order"]}),t]})})}function I({direction:t,mode:r,...e}){return t==="unsorted"?null:a(S,{mode:r,direction:t,...e})}function C(t,r){if(!t.getCanSort())return;let e=t.getIsSorted();switch(g(typeof e=="string"?e:"unsorted",r)){case"unsorted":t.clearSorting();return;case"asc":t.toggleSorting(!1);return;case"desc":t.toggleSorting(!0);return;default:return}}export{x as DataTableHeader};
2
2
  //# sourceMappingURL=data-table.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/data-table/index.ts"],"sourcesContent":["export * from \"@tanstack/react-table\";\n"],"mappings":"AAAA,WAAc","names":[]}
1
+ {"version":3,"sources":["../src/components/data-table/index.ts","../src/components/data-table/helpers.ts","../src/components/data-table/data-table.tsx"],"sourcesContent":["export * from \"@tanstack/react-table\";\n\nexport {\n\t//,\n\tDataTableHeader,\n} from \"./data-table.js\";\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","import type { Column, HeaderContext } from \"@tanstack/react-table\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport {\n\ttype SortingMode,\n\tsortingDirections as baseSortingDirections,\n} from \"../../utils/sorting/direction.js\";\nimport { Button } from \"../button/button.js\";\nimport type { SvgAttributes } from \"../icon/types.js\";\nimport { Sort } from \"../icons/sort.js\";\nimport { TableHeader } from \"../table/table.js\";\nimport { getNextSortDirection } from \"./helpers.js\";\nimport type { SortDirection } from \"./types.js\";\n\ntype DataTableColumnHeaderProps<TData, TValue> = ComponentProps<\n\ttypeof TableHeader\n> &\n\tPick<HeaderContext<TData, TValue>, \"column\"> & {\n\t\t/**\n\t\t * Use this to render a custom sort icon for the column if it is sortable\n\t\t * and you want to override the default sort icon\n\t\t */\n\t\tsortIcon?: (sortDirection: SortDirection) => ReactNode;\n\t\t/**\n\t\t * The sorting mode of the column, whether it is alphanumeric or time based.\n\t\t */\n\t\tsortingMode: SortingMode;\n\t};\n\n/**\n * The header for a column in a data table.\n * If the column is sortable, clicking the header 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 DataTableHeader<TData, TValue>({\n\tchildren,\n\tclassName,\n\tcolumn,\n\tsortIcon: propsSortIcon,\n\tsortingMode,\n\t...props\n}: DataTableColumnHeaderProps<TData, TValue>) {\n\tconst _sortDirection = column.getIsSorted();\n\tconst canSort = column.getCanSort();\n\n\tconst sortDirection: SortDirection =\n\t\tcanSort && typeof _sortDirection === \"string\" ? _sortDirection : \"unsorted\";\n\n\tconst sortIcon = propsSortIcon?.(sortDirection) ?? (\n\t\t<DefaultSortIcon mode={sortingMode} direction={sortDirection} />\n\t);\n\n\treturn (\n\t\t<TableHeader className={cx(\"px-0\", className)} {...props}>\n\t\t\t<Button\n\t\t\t\tclassName=\"flex justify-start w-full h-full rounded-none\"\n\t\t\t\ttype=\"button\"\n\t\t\t\tappearance=\"ghost\"\n\t\t\t\tpriority=\"neutral\"\n\t\t\t\ticonPlacement=\"end\"\n\t\t\t\tdata-sort-direction={sortDirection}\n\t\t\t\ticon={sortIcon}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tif (!canSort) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ttoggleNextSortingDirection(column, sortingMode);\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{sortDirection !== \"unsorted\" && (\n\t\t\t\t\t<span className=\"sr-only\">\n\t\t\t\t\t\tSorted in {sortDirection === \"asc\" ? \"ascending\" : \"descending\"}{\" \"}\n\t\t\t\t\t\torder\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t{children}\n\t\t\t</Button>\n\t\t</TableHeader>\n\t);\n}\n\nexport {\n\t//,\n\tDataTableHeader,\n};\n\ntype DefaultSortIconProps = SvgAttributes & {\n\tdirection: SortDirection;\n\tmode: SortingMode;\n};\n\nfunction DefaultSortIcon({ direction, mode, ...props }: DefaultSortIconProps) {\n\tif (direction === \"unsorted\") {\n\t\treturn null;\n\t}\n\n\treturn <Sort 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"],"mappings":"mUAAA,WAAc,wBCGd,IAAMA,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,CCaE,cAAAI,EAqBG,QAAAC,MArBH,oBAfF,SAASC,EAA+B,CACvC,SAAAC,EACA,UAAAC,EACA,OAAAC,EACA,SAAUC,EACV,YAAAC,EACA,GAAGC,CACJ,EAA8C,CAC7C,IAAMC,EAAiBJ,EAAO,YAAY,EACpCK,EAAUL,EAAO,WAAW,EAE5BM,EACLD,GAAW,OAAOD,GAAmB,SAAWA,EAAiB,WAE5DG,EAAWN,IAAgBK,CAAa,GAC7CX,EAACa,EAAA,CAAgB,KAAMN,EAAa,UAAWI,EAAe,EAG/D,OACCX,EAACc,EAAA,CAAY,UAAWC,EAAG,OAAQX,CAAS,EAAI,GAAGI,EAClD,SAAAP,EAACe,EAAA,CACA,UAAU,gDACV,KAAK,SACL,WAAW,QACX,SAAS,UACT,cAAc,MACd,sBAAqBL,EACrB,KAAMC,EACN,QAAS,IAAM,CACTF,GAGLO,EAA2BZ,EAAQE,CAAW,CAC/C,EAEC,UAAAI,IAAkB,YAClBV,EAAC,QAAK,UAAU,UAAU,uBACdU,IAAkB,MAAQ,YAAc,aAAc,IAAI,SAEtE,EAEAR,GACF,EACD,CAEF,CAYA,SAASe,EAAgB,CAAE,UAAAC,EAAW,KAAAC,EAAM,GAAGC,CAAM,EAAyB,CAC7E,OAAIF,IAAc,WACV,KAGDG,EAACC,EAAA,CAAK,KAAMH,EAAM,UAAWD,EAAY,GAAGE,EAAO,CAC3D,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":["alphanumericSortingOrder","timeSortingOrder","getNextSortDirection","currentSortDirection","sortingMode","getNextInCircularList","list","currentItem","fallback","currentItemIndex","item","nextIndex","jsx","jsxs","DataTableHeader","children","className","column","propsSortIcon","sortingMode","props","_sortDirection","canSort","sortDirection","sortIcon","DefaultSortIcon","TableHeader","cx","Button","toggleNextSortingDirection","DefaultSortIcon","direction","mode","props","jsx","Sort","toggleNextSortingDirection","column","sortingMode","sortDirection","getNextSortDirection"]}
package/dist/dialog.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as P,b as v,c as u,d as m,e as p,f as d,g,h as D}from"./chunk-PBARMKNJ.js";import{g as c}from"./chunk-ATNIDU3M.js";import"./chunk-DOTYPWKO.js";import"./chunk-D3XF6J5A.js";import{a as y}from"./chunk-XBVAQ3DV.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a}from"./chunk-AZ56JGNY.js";import{X as O}from"@phosphor-icons/react/X";import{forwardRef as r}from"react";import{jsx as e,jsxs as F}from"react/jsx-runtime";var T=P,W=v,C=u,z=m,f=r(({className:o,...t},i)=>e(p,{ref:i,className:a("bg-overlay data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:animate-in data-state-open:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm",o),...t}));f.displayName=p.displayName;var x=r(({children:o,className:t,onInteractOutside:i,onPointerDownOutside:n,preferredWidth:s="max-w-lg",...B},I)=>F(C,{children:[e(f,{}),e("div",{className:"fixed inset-4 z-50 flex items-center justify-center",children:e(d,{className:a("flex max-h-full w-full flex-1 flex-col","outline-none focus-within:outline-none","border-dialog bg-dialog rounded-xl border shadow-lg transition-transform duration-200","data-state-closed:animate-out data-state-closed:fade-out-0 data-state-closed:zoom-out-95 data-state-open:animate-in data-state-open:fade-in-0 data-state-open:zoom-in-95",s,t),onInteractOutside:l=>{c(l),i?.(l)},onPointerDownOutside:l=>{c(l),n?.(l)},ref:I,...B,children:o})})]}));x.displayName=d.displayName;var N=({className:o,children:t,...i})=>e("div",{className:a("border-dialog-muted text-strong relative flex shrink-0 items-center justify-between gap-2 border-b px-6 py-4","has-[.icon-button]:pr-4",o),...i,children:t});N.displayName="DialogHeader";var k=({size:o="md",type:t="button",label:i="Close Dialog",appearance:n="ghost",...s})=>e(m,{asChild:!0,children:e(y,{appearance:n,icon:e(O,{}),label:i,size:o,type:t,...s})}),b=({className:o,...t})=>e("div",{className:a("scrollbar text-body flex-1 overflow-y-auto p-6",o),...t});b.displayName="DialogBody";var h=({className:o,...t})=>e("div",{className:a("border-dialog-muted flex shrink-0 flex-row-reverse gap-2 border-t px-6 py-4",o),...t});h.displayName="DialogFooter";var R=r(({className:o,...t},i)=>e(g,{ref:i,className:a("text-strong truncate text-lg font-medium",o),...t}));R.displayName=g.displayName;var w=r(({className:o,...t},i)=>e(D,{ref:i,className:a("text-muted",o),...t}));w.displayName=D.displayName;export{T as Dialog,b as DialogBody,z as DialogClose,k as DialogCloseIconButton,x as DialogContent,w as DialogDescription,h as DialogFooter,N as DialogHeader,f as DialogOverlay,C as DialogPortal,R as DialogTitle,W as DialogTrigger};
1
+ import{a as P,b as v,c as u,d as m,e as p,f as d,g,h as D}from"./chunk-PBARMKNJ.js";import{g as c}from"./chunk-DDMTW6XB.js";import"./chunk-DOTYPWKO.js";import"./chunk-D3XF6J5A.js";import{a as y}from"./chunk-XBVAQ3DV.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a}from"./chunk-AZ56JGNY.js";import{X as O}from"@phosphor-icons/react/X";import{forwardRef as r}from"react";import{jsx as e,jsxs as F}from"react/jsx-runtime";var T=P,W=v,C=u,z=m,f=r(({className:o,...t},i)=>e(p,{ref:i,className:a("bg-overlay data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:animate-in data-state-open:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm",o),...t}));f.displayName=p.displayName;var x=r(({children:o,className:t,onInteractOutside:i,onPointerDownOutside:n,preferredWidth:s="max-w-lg",...B},I)=>F(C,{children:[e(f,{}),e("div",{className:"fixed inset-4 z-50 flex items-center justify-center",children:e(d,{className:a("flex max-h-full w-full flex-1 flex-col","outline-none focus-within:outline-none","border-dialog bg-dialog rounded-xl border shadow-lg transition-transform duration-200","data-state-closed:animate-out data-state-closed:fade-out-0 data-state-closed:zoom-out-95 data-state-open:animate-in data-state-open:fade-in-0 data-state-open:zoom-in-95",s,t),onInteractOutside:l=>{c(l),i?.(l)},onPointerDownOutside:l=>{c(l),n?.(l)},ref:I,...B,children:o})})]}));x.displayName=d.displayName;var N=({className:o,children:t,...i})=>e("div",{className:a("border-dialog-muted text-strong relative flex shrink-0 items-center justify-between gap-2 border-b px-6 py-4","has-[.icon-button]:pr-4",o),...i,children:t});N.displayName="DialogHeader";var k=({size:o="md",type:t="button",label:i="Close Dialog",appearance:n="ghost",...s})=>e(m,{asChild:!0,children:e(y,{appearance:n,icon:e(O,{}),label:i,size:o,type:t,...s})}),b=({className:o,...t})=>e("div",{className:a("scrollbar text-body flex-1 overflow-y-auto p-6",o),...t});b.displayName="DialogBody";var h=({className:o,...t})=>e("div",{className:a("border-dialog-muted flex shrink-0 flex-row-reverse gap-2 border-t px-6 py-4",o),...t});h.displayName="DialogFooter";var R=r(({className:o,...t},i)=>e(g,{ref:i,className:a("text-strong truncate text-lg font-medium",o),...t}));R.displayName=g.displayName;var w=r(({className:o,...t},i)=>e(D,{ref:i,className:a("text-muted",o),...t}));w.displayName=D.displayName;export{T as Dialog,b as DialogBody,z as DialogClose,k as DialogCloseIconButton,x as DialogContent,w as DialogDescription,h as DialogFooter,N as DialogHeader,f as DialogOverlay,C as DialogPortal,R as DialogTitle,W as DialogTrigger};
2
2
  //# sourceMappingURL=dialog.js.map
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Sorting modes
3
+ * - alphanumeric: Sort by alphanumeric order (A-Z, 0-9, Z-A, 9-0)
4
+ * - time: Sort by time (newest-to-oldest, oldest-to-newest)
5
+ */
6
+ declare const sortingModes: readonly ["alphanumeric", "time"];
7
+ /**
8
+ * Sorting modes
9
+ * - alphanumeric: Sort by alphanumeric order (A-Z, 0-9, Z-A, 9-0)
10
+ * - time: Sort by time (newest-to-oldest, oldest-to-newest)
11
+ */
12
+ type SortingMode = (typeof sortingModes)[number];
13
+ /**
14
+ * Type guard for sorting modes
15
+ * - alphanumeric: Sort by alphanumeric order (A-Z, 0-9, Z-A, 9-0)
16
+ * - time: Sort by time (newest-to-oldest, oldest-to-newest)
17
+ *
18
+ * @example isSortingMode("alphanumeric") // true
19
+ * @example isSortingMode("time") // true
20
+ * @example isSortingMode("foo") // false
21
+ */
22
+ declare const isSortingMode: (value: unknown) => value is SortingMode;
23
+ /**
24
+ * Runtime type-to-value helper for sorting modes
25
+ * - alphanumeric: Sort by alphanumeric order (A-Z, 0-9, Z-A, 9-0)
26
+ * - time: Sort by time (newest-to-oldest, oldest-to-newest)
27
+ *
28
+ * @example $sortingMode("alphanumeric") // "alphanumeric"
29
+ * @example $sortingMode("time") // "time"
30
+ */
31
+ declare const $sortingMode: <T extends SortingMode = SortingMode>(value: T) => T;
32
+ /**
33
+ * Sorting directions
34
+ * - asc: Ascending order (alphanumeric: A-Z, 0-9; time: oldest-to-newest)
35
+ * - desc: Descending order (alphanumeric: Z-A, 9-0; time: newest-to-oldest)
36
+ */
37
+ declare const sortingDirections: readonly ["asc", "desc"];
38
+ /**
39
+ * Sorting directions
40
+ * - asc: Ascending order (alphanumeric: A-Z, 0-9; time: oldest-to-newest)
41
+ * - desc: Descending order (alphanumeric: Z-A, 9-0; time: newest-to-oldest)
42
+ */
43
+ type SortingDirection = (typeof sortingDirections)[number];
44
+ /**
45
+ * Type guard for sorting directions
46
+ * - asc: Ascending order (alphanumeric: A-Z, 0-9; time: oldest-to-newest)
47
+ * - desc: Descending order (alphanumeric: Z-A, 9-0; time: newest-to-oldest)
48
+ *
49
+ * @example isSortingDirection("asc") // true
50
+ * @example isSortingDirection("desc") // true
51
+ * @example isSortingDirection("foo") // false
52
+ */
53
+ declare const isSortingDirection: (value: unknown) => value is SortingDirection;
54
+ /**
55
+ * Runtime type-to-value helper for sorting directions
56
+ * - asc: Ascending order (alphanumeric: A-Z, 0-9; time: oldest-to-newest)
57
+ * - desc: Descending order (alphanumeric: Z-A, 9-0; time: newest-to-oldest)
58
+ *
59
+ * @example $sortingDirection("asc") // "asc"
60
+ * @example $sortingDirection("desc") // "desc"
61
+ */
62
+ declare const $sortingDirection: <T extends SortingDirection = SortingDirection>(value: T) => T;
63
+ /**
64
+ * Alphanumeric sorting directions
65
+ * - asc: Ascending order (A-Z, 0-9)
66
+ * - desc: Descending order (Z-A, 9-0)
67
+ */
68
+ declare const alphanumericSortingDirections: readonly ["asc", "desc"];
69
+ /**
70
+ * Alphanumeric sorting directions
71
+ * - asc: Ascending order (A-Z, 0-9)
72
+ * - desc: Descending order (Z-A, 9-0)
73
+ */
74
+ type AlphanumericSortingDirection = (typeof alphanumericSortingDirections)[number];
75
+ /**
76
+ * Type guard for alphanumeric sorting directions
77
+ * - asc: Ascending order (A-Z, 0-9)
78
+ * - desc: Descending order (Z-A, 9-0)
79
+ *
80
+ * @example isAlphanumericSortingDirection("asc") // true
81
+ * @example isAlphanumericSortingDirection("desc") // true
82
+ * @example isAlphanumericSortingDirection("foo") // false
83
+ */
84
+ declare const isAlphanumericSortingDirection: (value: unknown) => value is AlphanumericSortingDirection;
85
+ /**
86
+ * Runtime type-to-value helper for alphanumeric sorting directions
87
+ * - asc: Ascending order (A-Z, 0-9)
88
+ * - desc: Descending order (Z-A, 9-0)
89
+ *
90
+ * @example $alphanumericSortingDirection("asc") // "asc"
91
+ * @example $alphanumericSortingDirection("desc") // "desc"
92
+ */
93
+ declare const $alphanumericSortingDirection: <T extends AlphanumericSortingDirection = AlphanumericSortingDirection>(value: T) => T;
94
+ /**
95
+ * Time sorting directions
96
+ * - newest-to-oldest: Descending order (newest first, oldest last)
97
+ * - oldest-to-newest: Ascending order (oldest first, newest last)
98
+ */
99
+ declare const timeSortingDirections: readonly ["newest-to-oldest", "oldest-to-newest"];
100
+ /**
101
+ * Time sorting directions
102
+ * - newest-to-oldest: Descending order (newest first, oldest last)
103
+ * - oldest-to-newest: Ascending order (oldest first, newest last)
104
+ */
105
+ type TimeSortingDirection = (typeof timeSortingDirections)[number];
106
+ /**
107
+ * Type guard for time sorting directions
108
+ * - newest-to-oldest: Descending order (newest first, oldest last)
109
+ * - oldest-to-newest: Ascending order (oldest first, newest last)
110
+ *
111
+ * @example isTimeSortingDirection("newest-to-oldest") // true
112
+ * @example isTimeSortingDirection("oldest-to-newest") // true
113
+ * @example isTimeSortingDirection("foo") // false
114
+ * @example isTimeSortingDirection("asc") // false
115
+ * @example isTimeSortingDirection("desc") // false
116
+ */
117
+ declare const isTimeSortingDirection: (value: unknown) => value is TimeSortingDirection;
118
+ /**
119
+ * Converts a sorting direction to a time sorting direction
120
+ * - asc -> oldest-to-newest
121
+ * - desc -> newest-to-oldest
122
+ */
123
+ declare const timeSortingByDirection: {
124
+ readonly asc: "oldest-to-newest";
125
+ readonly desc: "newest-to-oldest";
126
+ };
127
+ /**
128
+ * Runtime type-to-value helper for time sorting directions.
129
+ * If given a sorting direction, it will convert it to a time sorting direction.
130
+ * - newest-to-oldest: Descending order (desc; newest first, oldest last)
131
+ * - oldest-to-newest: Ascending order (asc; oldest first, newest last)
132
+ *
133
+ * @example $timeSortingDirection("asc") // "oldest-to-newest"
134
+ * @example $timeSortingDirection("desc") // "newest-to-oldest"
135
+ * @example $timeSortingDirection("oldest-to-newest") // "oldest-to-newest"
136
+ * @example $timeSortingDirection("newest-to-oldest") // "newest-to-oldest"
137
+ */
138
+ declare function $timeSortingDirection<T extends TimeSortingDirection | SortingDirection>(value: T): {
139
+ readonly asc: "oldest-to-newest";
140
+ readonly desc: "newest-to-oldest";
141
+ }[(T & "asc") | (T & "desc")] | (T & "newest-to-oldest") | (T & "oldest-to-newest");
142
+
143
+ export { $alphanumericSortingDirection as $, type AlphanumericSortingDirection as A, type SortingDirection as S, type TimeSortingDirection as T, $sortingDirection as a, $sortingMode as b, $timeSortingDirection as c, alphanumericSortingDirections as d, isSortingDirection as e, isSortingMode as f, isTimeSortingDirection as g, sortingModes as h, isAlphanumericSortingDirection as i, timeSortingDirections as j, type SortingMode as k, sortingDirections as s, timeSortingByDirection as t };
@@ -0,0 +1,37 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { k as SortingMode, A as AlphanumericSortingDirection, T as TimeSortingDirection, S as SortingDirection } from './direction-veAOo2is.js';
3
+ import { S as SvgAttributes } from './types-BuKAGhC-.js';
4
+ import 'react';
5
+
6
+ type Props = SvgAttributes & ({
7
+ mode: Extract<SortingMode, "alphanumeric">;
8
+ /**
9
+ * Sort by alphanumeric order in "ascending" (asc) or "descending" (desc) order.
10
+ * @example "asc" for A-Z, 0-9
11
+ * @example "desc" for Z-A, 0-9
12
+ */
13
+ direction: AlphanumericSortingDirection;
14
+ } | {
15
+ mode: Extract<SortingMode, "time">;
16
+ /**
17
+ * Sort by time in "newest-to-oldest" (descending, desc) or "oldest-to-newest" (ascending, asc) order.
18
+ * @example "newest-to-oldest" for newest first (aka descending, desc)
19
+ * @example "oldest-to-newest" for oldest first (aka ascending, asc)
20
+ */
21
+ direction: TimeSortingDirection | SortingDirection;
22
+ });
23
+ /**
24
+ * A sorting icon that can be used to indicate the sorting direction of a table column or list.
25
+ * It is aware of the sorting mode (alphanumeric or time) and the sorting direction (ascending or descending).
26
+ */
27
+ declare const Sort: {
28
+ ({ mode, direction, ...props }: Props): react_jsx_runtime.JSX.Element;
29
+ displayName: string;
30
+ };
31
+
32
+ /**
33
+ * An icon representing a traffic policy file.
34
+ */
35
+ declare function TrafficPolicyFile(props: SvgAttributes): react_jsx_runtime.JSX.Element;
36
+
37
+ export { Sort, TrafficPolicyFile };
package/dist/icons.js ADDED
@@ -0,0 +1,2 @@
1
+ import{a as o}from"./chunk-GOXG4BVJ.js";import{a as r}from"./chunk-FHW7SSNY.js";import"./chunk-GYPSB3OK.js";export{r as Sort,o as TrafficPolicyFile};
2
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,2 +1,2 @@
1
- import{a as b,c as v,d as x,e as y,g as h}from"./chunk-7FIV4E5C.js";import"./chunk-MF2QITTY.js";import{b as z}from"./chunk-UXH22BMO.js";import{a as d}from"./chunk-7XIZZ4HQ.js";import{a as l}from"./chunk-XBVAQ3DV.js";import"./chunk-J3NVDJIE.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a as p}from"./chunk-AZ56JGNY.js";import{CaretLeft as k}from"@phosphor-icons/react/CaretLeft";import{CaretRight as A}from"@phosphor-icons/react/CaretRight";import{Slot as E}from"@radix-ui/react-slot";import{createContext as F,forwardRef as m,useContext as N,useState as W}from"react";import P from"tiny-invariant";import{jsx as s,jsxs as f}from"react/jsx-runtime";var c=F(void 0),O=m(({className:n,children:e,defaultPageSize:a,...t},i)=>{let[o,r]=W(a);return s(c.Provider,{value:{defaultPageSize:a,pageSize:o,setPageSize:r},children:s("div",{className:p("inline-flex items-center justify-between gap-2",n),ref:i,...t,children:e})})});O.displayName="CursorPagination";var T=m(({hasNextPage:n,hasPreviousPage:e,onNextPage:a,onPreviousPage:t,...i},o)=>f(d,{appearance:"panel",ref:o,...i,children:[s(l,{appearance:"ghost",disabled:!e,icon:s(k,{}),label:"Previous page",onClick:t,size:"sm",type:"button"}),s(z,{orientation:"vertical",className:"min-h-5"}),s(l,{appearance:"ghost",disabled:!n,icon:s(A,{}),label:"Next page",onClick:a,size:"sm",type:"button"})]}));T.displayName="CursorButtons";var $=[5,10,20,50,100],B=m(({className:n,pageSizes:e=$,onChangePageSize:a,...t},i)=>{let o=N(c);return P(o,"CursorPageSizeSelect must be used as a child of a CursorPagination component"),P(e.includes(o.defaultPageSize),"CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes"),P(e.includes(o.pageSize),"CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes"),f(b,{defaultValue:`${o.pageSize}`,onChange:r=>{let g=Number.parseInt(r,10);Number.isNaN(g)&&(g=o.defaultPageSize),o.setPageSize(g),a?.(g)},children:[s(x,{ref:i,className:p("w-auto min-w-36",n),value:o.pageSize,...t,children:s(v,{})}),s(y,{width:"trigger",children:e.map(r=>f(h,{value:`${r}`,children:[r," per page"]},r))})]})});B.displayName="CursorPageSizeSelect";function D({asChild:n=!1,className:e,...a}){let t=N(c);return P(t,"CursorPageSizeValue must be used as a child of a CursorPagination component"),f(n?E:"span",{className:p("text-muted text-sm font-normal",e),...a,children:[t.pageSize," per page"]})}import{useEffect as V,useState as w}from"react";function H({listSize:n,pageSize:e}){let[a,t]=w(1),[i,o]=w(e);V(()=>{o(e),t(1)},[e]),V(()=>{t(1)},[n]);let r=Math.ceil(n/i),g=(a-1)*i,S=a>1,C=a<r;function M(u){let j=Math.max(1,Math.min(u,r));t(j)}function R(){C&&t(u=>Math.min(u+1,r))}function G(){S&&t(u=>Math.max(u-1,1))}function I(u){o(u),t(1)}function L(){t(r)}function U(){t(1)}return{currentPage:a,goToFirstPage:U,goToLastPage:L,goToPage:M,hasNextPage:C,hasPreviousPage:S,nextPage:R,offset:g,pageSize:i,previousPage:G,setPageSize:I,totalPages:r}}function q(n,e){return n.slice(e.offset,e.offset+e.pageSize)}export{T as CursorButtons,B as CursorPageSizeSelect,D as CursorPageSizeValue,O as CursorPagination,q as getOffsetPaginatedSlice,H as useOffsetPagination};
1
+ import{a as b,c as v,d as x,e as y,g as h}from"./chunk-WGF5NYWL.js";import"./chunk-MF2QITTY.js";import{b as z}from"./chunk-UXH22BMO.js";import{a as d}from"./chunk-7XIZZ4HQ.js";import{a as l}from"./chunk-XBVAQ3DV.js";import"./chunk-J3NVDJIE.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a as p}from"./chunk-AZ56JGNY.js";import{CaretLeft as k}from"@phosphor-icons/react/CaretLeft";import{CaretRight as A}from"@phosphor-icons/react/CaretRight";import{Slot as E}from"@radix-ui/react-slot";import{createContext as F,forwardRef as m,useContext as N,useState as W}from"react";import P from"tiny-invariant";import{jsx as s,jsxs as f}from"react/jsx-runtime";var c=F(void 0),O=m(({className:n,children:e,defaultPageSize:a,...t},i)=>{let[o,r]=W(a);return s(c.Provider,{value:{defaultPageSize:a,pageSize:o,setPageSize:r},children:s("div",{className:p("inline-flex items-center justify-between gap-2",n),ref:i,...t,children:e})})});O.displayName="CursorPagination";var T=m(({hasNextPage:n,hasPreviousPage:e,onNextPage:a,onPreviousPage:t,...i},o)=>f(d,{appearance:"panel",ref:o,...i,children:[s(l,{appearance:"ghost",disabled:!e,icon:s(k,{}),label:"Previous page",onClick:t,size:"sm",type:"button"}),s(z,{orientation:"vertical",className:"min-h-5"}),s(l,{appearance:"ghost",disabled:!n,icon:s(A,{}),label:"Next page",onClick:a,size:"sm",type:"button"})]}));T.displayName="CursorButtons";var $=[5,10,20,50,100],B=m(({className:n,pageSizes:e=$,onChangePageSize:a,...t},i)=>{let o=N(c);return P(o,"CursorPageSizeSelect must be used as a child of a CursorPagination component"),P(e.includes(o.defaultPageSize),"CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes"),P(e.includes(o.pageSize),"CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes"),f(b,{defaultValue:`${o.pageSize}`,onChange:r=>{let g=Number.parseInt(r,10);Number.isNaN(g)&&(g=o.defaultPageSize),o.setPageSize(g),a?.(g)},children:[s(x,{ref:i,className:p("w-auto min-w-36",n),value:o.pageSize,...t,children:s(v,{})}),s(y,{width:"trigger",children:e.map(r=>f(h,{value:`${r}`,children:[r," per page"]},r))})]})});B.displayName="CursorPageSizeSelect";function D({asChild:n=!1,className:e,...a}){let t=N(c);return P(t,"CursorPageSizeValue must be used as a child of a CursorPagination component"),f(n?E:"span",{className:p("text-muted text-sm font-normal",e),...a,children:[t.pageSize," per page"]})}import{useEffect as V,useState as w}from"react";function H({listSize:n,pageSize:e}){let[a,t]=w(1),[i,o]=w(e);V(()=>{o(e),t(1)},[e]),V(()=>{t(1)},[n]);let r=Math.ceil(n/i),g=(a-1)*i,S=a>1,C=a<r;function M(u){let j=Math.max(1,Math.min(u,r));t(j)}function R(){C&&t(u=>Math.min(u+1,r))}function G(){S&&t(u=>Math.max(u-1,1))}function I(u){o(u),t(1)}function L(){t(r)}function U(){t(1)}return{currentPage:a,goToFirstPage:U,goToLastPage:L,goToPage:M,hasNextPage:C,hasPreviousPage:S,nextPage:R,offset:g,pageSize:i,previousPage:G,setPageSize:I,totalPages:r}}function q(n,e){return n.slice(e.offset,e.offset+e.pageSize)}export{T as CursorButtons,B as CursorPageSizeSelect,D as CursorPageSizeValue,O as CursorPagination,q as getOffsetPaginatedSlice,H as useOffsetPagination};
2
2
  //# sourceMappingURL=pagination.js.map
package/dist/select.d.ts CHANGED
@@ -31,17 +31,33 @@ type WithAriaInvalid = Pick<SelectHTMLAttributes<HTMLSelectElement>, "aria-inval
31
31
  *
32
32
  * @see https://mantle.ngrok.com/components/select#api-select
33
33
  */
34
- declare const Select: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectProps, "onValueChange"> & WithValidation & WithAriaInvalid & {
35
- /**
36
- * Event handler called when the value changes.
37
- */
38
- onChange?: (value: string) => void;
34
+ declare const Select: react.ForwardRefExoticComponent<{
35
+ children?: react.ReactNode | undefined;
36
+ } & {
37
+ autoComplete?: string;
38
+ defaultOpen?: boolean;
39
+ defaultValue?: string;
40
+ dir?: "ltr" | "rtl";
41
+ disabled?: boolean;
42
+ form?: string;
43
+ id?: string;
44
+ name?: string;
39
45
  /**
40
46
  * Event handler called when Select blurs.
41
47
  * @note this is a no-op for now until we can guarantee that it works identically to a native select onBlur
42
48
  */
43
49
  onBlur?: (event: FocusEvent<HTMLButtonElement>) => void;
44
- } & Pick<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "id"> & react.RefAttributes<HTMLButtonElement>>;
50
+ /**
51
+ * Event handler called when the value changes.
52
+ * @deprecated Use `onValueChange` instead.
53
+ */
54
+ onChange?: (value: string) => void;
55
+ onOpenChange?(open: boolean): void;
56
+ onValueChange?(value: string): void;
57
+ open?: boolean;
58
+ required?: boolean;
59
+ value?: string;
60
+ } & WithValidation & WithAriaInvalid & react.RefAttributes<HTMLButtonElement>>;
45
61
  /**
46
62
  * A group of related options within a select menu. Similar to an html `<optgroup>` element.
47
63
  * Use in conjunction with SelectLabel to ensure good accessibility via automatic labelling.
package/dist/select.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as e,b as t,c as l,d as S,e as c,f as r,g as o,h as a}from"./chunk-7FIV4E5C.js";import"./chunk-MF2QITTY.js";import"./chunk-UXH22BMO.js";import"./chunk-AZ56JGNY.js";export{e as Select,c as SelectContent,t as SelectGroup,o as SelectItem,r as SelectLabel,a as SelectSeparator,S as SelectTrigger,l as SelectValue};
1
+ import{a as e,b as t,c as l,d as S,e as c,f as r,g as o,h as a}from"./chunk-WGF5NYWL.js";import"./chunk-MF2QITTY.js";import"./chunk-UXH22BMO.js";import"./chunk-AZ56JGNY.js";export{e as Select,c as SelectContent,t as SelectGroup,o as SelectItem,r as SelectLabel,a as SelectSeparator,S as SelectTrigger,l as SelectValue};
2
2
  //# sourceMappingURL=select.js.map
package/dist/sheet.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as S,b as u,c as v,d as m,e as p,f as d,g as h,h as f}from"./chunk-PBARMKNJ.js";import{g as c}from"./chunk-ATNIDU3M.js";import"./chunk-DOTYPWKO.js";import"./chunk-D3XF6J5A.js";import{a as P}from"./chunk-XBVAQ3DV.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a as r}from"./chunk-AZ56JGNY.js";import{X as D}from"@phosphor-icons/react/X";import{cva as L}from"class-variance-authority";import{forwardRef as n}from"react";import{jsx as i,jsxs as k}from"react/jsx-runtime";var M=S,w=u,A=m,B=v,y=n(({className:e,...t},o)=>i(p,{className:r("bg-overlay data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:animate-in data-state-open:fade-in-0 fixed inset-0 z-40 backdrop-blur-sm",e),...t,ref:o}));y.displayName=p.displayName;var I=L("bg-dialog border-dialog inset-y-0 h-full w-full fixed z-40 flex flex-col shadow-lg outline-none transition ease-in-out focus-within:outline-none data-state-closed:duration-100 data-state-closed:animate-out data-state-open:duration-100 data-state-open:animate-in",{variants:{side:{left:"data-state-closed:slide-out-to-left data-state-open:slide-in-from-left left-0 border-r",right:"data-state-closed:slide-out-to-right data-state-open:slide-in-from-right right-0 border-l"}},defaultVariants:{side:"right"}}),C=n(({children:e,className:t,onInteractOutside:o,onPointerDownOutside:a,preferredWidth:l="sm:max-w-[30rem]",side:N="right",...R},H)=>k(B,{children:[i(y,{}),i(d,{className:r(I({side:N}),l,t),onInteractOutside:s=>{c(s),o?.(s)},onPointerDownOutside:s=>{c(s),a?.(s)},ref:H,...R,children:e})]}));C.displayName=d.displayName;var O=({size:e="md",type:t="button",label:o="Close Sheet",appearance:a="ghost",...l})=>i(m,{asChild:!0,children:i(P,{appearance:a,icon:i(D,{}),label:o,size:e,type:t,...l})}),W=({className:e,...t})=>i("div",{className:r("scrollbar text-body flex-1 overflow-y-auto p-6",e),...t}),E=({className:e,...t})=>i("div",{className:r("border-dialog-muted flex shrink-0 flex-col gap-2 border-b py-4 pl-6 pr-4","has-[.icon-button]:pr-4",e),...t}),V=({className:e,...t})=>i("div",{className:r("border-dialog-muted flex shrink-0 justify-end gap-2 border-t px-6 py-2.5",e),...t}),g=n(({className:e,...t},o)=>i(h,{ref:o,className:r("text-strong flex-1 truncate text-lg font-medium",e),...t}));g.displayName=h.displayName;var b=n(({children:e,className:t,...o},a)=>i("div",{className:r("flex items-center justify-between gap-2",t),...o,ref:a,children:e}));b.displayName="SheetTitleGroup";var T=n(({className:e,...t},o)=>i(f,{ref:o,className:r("text-body text-sm",e),...t}));T.displayName=f.displayName;var x=n(({children:e,className:t,...o},a)=>i("div",{className:r("flex h-full items-center gap-2",t),...o,ref:a,children:e}));x.displayName="SheetActions";export{M as Sheet,x as SheetActions,W as SheetBody,A as SheetClose,O as SheetCloseIconButton,C as SheetContent,T as SheetDescription,V as SheetFooter,E as SheetHeader,g as SheetTitle,b as SheetTitleGroup,w as SheetTrigger};
1
+ import{a as S,b as u,c as v,d as m,e as p,f as d,g as h,h as f}from"./chunk-PBARMKNJ.js";import{g as c}from"./chunk-DDMTW6XB.js";import"./chunk-DOTYPWKO.js";import"./chunk-D3XF6J5A.js";import{a as P}from"./chunk-XBVAQ3DV.js";import"./chunk-4LSFAAZW.js";import"./chunk-3C5O3AQA.js";import"./chunk-72TJUKMV.js";import"./chunk-7O36LG52.js";import"./chunk-HDPLH5HC.js";import{a as r}from"./chunk-AZ56JGNY.js";import{X as D}from"@phosphor-icons/react/X";import{cva as L}from"class-variance-authority";import{forwardRef as n}from"react";import{jsx as i,jsxs as k}from"react/jsx-runtime";var M=S,w=u,A=m,B=v,y=n(({className:e,...t},o)=>i(p,{className:r("bg-overlay data-state-closed:animate-out data-state-closed:fade-out-0 data-state-open:animate-in data-state-open:fade-in-0 fixed inset-0 z-40 backdrop-blur-sm",e),...t,ref:o}));y.displayName=p.displayName;var I=L("bg-dialog border-dialog inset-y-0 h-full w-full fixed z-40 flex flex-col shadow-lg outline-none transition ease-in-out focus-within:outline-none data-state-closed:duration-100 data-state-closed:animate-out data-state-open:duration-100 data-state-open:animate-in",{variants:{side:{left:"data-state-closed:slide-out-to-left data-state-open:slide-in-from-left left-0 border-r",right:"data-state-closed:slide-out-to-right data-state-open:slide-in-from-right right-0 border-l"}},defaultVariants:{side:"right"}}),C=n(({children:e,className:t,onInteractOutside:o,onPointerDownOutside:a,preferredWidth:l="sm:max-w-[30rem]",side:N="right",...R},H)=>k(B,{children:[i(y,{}),i(d,{className:r(I({side:N}),l,t),onInteractOutside:s=>{c(s),o?.(s)},onPointerDownOutside:s=>{c(s),a?.(s)},ref:H,...R,children:e})]}));C.displayName=d.displayName;var O=({size:e="md",type:t="button",label:o="Close Sheet",appearance:a="ghost",...l})=>i(m,{asChild:!0,children:i(P,{appearance:a,icon:i(D,{}),label:o,size:e,type:t,...l})}),W=({className:e,...t})=>i("div",{className:r("scrollbar text-body flex-1 overflow-y-auto p-6",e),...t}),E=({className:e,...t})=>i("div",{className:r("border-dialog-muted flex shrink-0 flex-col gap-2 border-b py-4 pl-6 pr-4","has-[.icon-button]:pr-4",e),...t}),V=({className:e,...t})=>i("div",{className:r("border-dialog-muted flex shrink-0 justify-end gap-2 border-t px-6 py-2.5",e),...t}),g=n(({className:e,...t},o)=>i(h,{ref:o,className:r("text-strong flex-1 truncate text-lg font-medium",e),...t}));g.displayName=h.displayName;var b=n(({children:e,className:t,...o},a)=>i("div",{className:r("flex items-center justify-between gap-2",t),...o,ref:a,children:e}));b.displayName="SheetTitleGroup";var T=n(({className:e,...t},o)=>i(f,{ref:o,className:r("text-body text-sm",e),...t}));T.displayName=f.displayName;var x=n(({children:e,className:t,...o},a)=>i("div",{className:r("flex h-full items-center gap-2",t),...o,ref:a,children:e}));x.displayName="SheetActions";export{M as Sheet,x as SheetActions,W as SheetBody,A as SheetClose,O as SheetCloseIconButton,C as SheetContent,T as SheetDescription,V as SheetFooter,E as SheetHeader,g as SheetTitle,b as SheetTitleGroup,w as SheetTrigger};
2
2
  //# sourceMappingURL=sheet.js.map