@upbound/monarch-blocks 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cel-filter-bar.js +2 -31
- package/dist/cel-filter-bar.js.map +1 -1
- package/dist/chart.js +1 -31
- package/dist/chart.js.map +1 -1
- package/dist/chat-interface.js +1 -31
- package/dist/chat-interface.js.map +1 -1
- package/dist/code-block.js +1 -31
- package/dist/code-block.js.map +1 -1
- package/dist/data-table.d.ts +10 -1
- package/dist/data-table.js +7 -34
- package/dist/data-table.js.map +1 -1
- package/dist/filter-bar.js +2 -31
- package/dist/filter-bar.js.map +1 -1
- package/dist/floating-widget.js +1 -31
- package/dist/floating-widget.js.map +1 -1
- package/dist/graph.js +2 -31
- package/dist/graph.js.map +1 -1
- package/dist/index.js +7 -34
- package/dist/index.js.map +1 -1
- package/dist/page-header.js +1 -31
- package/dist/page-header.js.map +1 -1
- package/dist/relative-time.js +1 -31
- package/dist/relative-time.js.map +1 -1
- package/dist/section-header.js +1 -31
- package/dist/section-header.js.map +1 -1
- package/dist/section-nav.js +1 -31
- package/dist/section-nav.js.map +1 -1
- package/dist/timeline.js +1 -31
- package/dist/timeline.js.map +1 -1
- package/package.json +3 -5
package/dist/code-block.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/code-block.tsx","../src/lib/utils.ts","../src/lib/highlight.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Icon } from '@upbound/monarch-core';\n\nimport { cn } from '@/lib/utils';\nimport {\n Card,\n CardContent,\n CardFooter,\n CardHeader,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@upbound/monarch-core';\nimport { highlightCode, type CodeBlockLanguage } from './lib/highlight';\n\nexport type { CodeBlockLanguage } from './lib/highlight';\n\ntype CodeBlockCodeBase = {\n /** Raw code string — used for clipboard copy, download, and as the rendered text. */\n content: string;\n /** Numbers each line in the gutter. */\n lineNumbers?: boolean;\n};\n\nexport type CodeBlockCode =\n | (CodeBlockCodeBase & {\n /** Syntax-highlighted with Shiki inside CodeBlockBody — no highlighting step needed on your end. */\n type: 'parsed';\n language: CodeBlockLanguage;\n })\n | (CodeBlockCodeBase & {\n /** Rendered as plain, unhighlighted text. */\n type: 'raw';\n });\n\nfunction CodeBlock({\n className,\n variant = 'default',\n size = 'default',\n ...props\n}: React.ComponentProps<'div'> & {\n variant?: 'default' | 'terminal';\n size?: 'default' | 'sm';\n}) {\n return (\n <Card\n data-slot=\"code-block\"\n data-variant={variant}\n data-size={size}\n role=\"region\"\n className={cn(\n 'group/code-block gap-0 overflow-hidden py-0',\n size === 'default' && 'text-[13px]',\n size === 'sm' && 'text-body-sm',\n variant === 'terminal' && 'border-terminal-border bg-terminal-bg text-terminal-fg ring-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CodeBlockHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <CardHeader\n className={cn(\n 'group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-bg group-data-[variant=terminal]/code-block:text-terminal-muted flex flex-row items-center gap-2 border-b bg-[color-mix(in_oklch,var(--muted)_50%,var(--card))] py-4',\n className,\n )}\n {...props}\n />\n );\n}\n\nconst LINE_NUMBER_GUTTER = cn(\n '[&_code]:[counter-reset:line]',\n '[&_.line]:before:[counter-increment:line]',\n '[&_.line]:before:content-[counter(line)]',\n '[&_.line]:before:inline-block',\n '[&_.line]:before:w-6',\n '[&_.line]:before:mr-3',\n '[&_.line]:before:text-right',\n '[&_.line]:before:text-muted-foreground',\n '[&_.line]:before:text-[0.75rem]',\n '[&_.line]:before:select-none',\n);\n\nfunction CodeBlockBody({\n className,\n code,\n maxHeight,\n copyButton,\n downloadButton,\n ...props\n}: Omit<React.ComponentProps<'div'>, 'children'> & {\n code: CodeBlockCode;\n maxHeight?: string;\n copyButton?: React.ReactNode;\n downloadButton?: React.ReactNode;\n}) {\n const { content, lineNumbers } = code;\n const [html, setHtml] = useState<string | null>(null);\n const language = code.type === 'parsed' ? code.language : null;\n\n useEffect(() => {\n if (!language) {\n setHtml(null);\n return;\n }\n\n let cancelled = false;\n highlightCode(content, language).then(result => {\n if (!cancelled) setHtml(result);\n });\n\n return () => {\n cancelled = true;\n };\n }, [content, language]);\n\n // Layout note: the copy/download buttons must stay anchored to the\n // top-right of the visible code area when the content scrolls\n // horizontally. To make that work the relative containing block\n // (CardContent) must NOT be the scrollable element — otherwise\n // `right`-positioning is computed against the scrolled content edge and\n // the buttons move with the scroll. So the overflow lives on an inner\n // wrapper and the absolute button group is its sibling under CardContent.\n return (\n <CardContent data-line-numbers={lineNumbers || undefined} className={cn('relative p-0!', className)} {...props}>\n {(copyButton || downloadButton) && (\n <div className=\"absolute top-2 right-2 z-10 flex items-center gap-1 opacity-0 transition-opacity group-hover/code-block:opacity-100\">\n {copyButton}\n {downloadButton}\n </div>\n )}\n <div\n className={cn('overflow-x-auto', maxHeight && 'overflow-y-auto')}\n style={maxHeight ? { maxHeight } : undefined}\n >\n <div\n className={cn(\n '[&_code]:font-mono [&_pre]:m-0 [&_pre]:p-4 group-data-[size=sm]/code-block:[&_pre]:p-3',\n html && '[&_pre]:bg-transparent!',\n lineNumbers && LINE_NUMBER_GUTTER,\n )}\n >\n {html ? (\n <div dangerouslySetInnerHTML={{ __html: html }} />\n ) : (\n <pre>\n <code className={lineNumbers ? undefined : 'whitespace-pre'}>\n {lineNumbers\n ? content.split('\\n').map((line, i) => (\n <span key={i} className=\"line\">\n {line}\n {'\\n'}\n </span>\n ))\n : content}\n </code>\n </pre>\n )}\n </div>\n </div>\n </CardContent>\n );\n}\n\nfunction CodeBlockFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <CardFooter\n className={cn(\n 'text-body-sm group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-footer-bg group-data-[variant=terminal]/code-block:text-terminal-muted',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CodeBlockCopyButton({\n code,\n className,\n ...props\n}: Omit<React.ComponentProps<'button'>, 'children'> & {\n code: string;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n data-slot=\"code-block-copy-button\"\n onClick={handleCopy}\n className={cn(\n 'border-border bg-background inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border motion-safe:transition-colors',\n 'text-muted-foreground hover:bg-accent hover:text-foreground',\n 'focus-visible:ring-ring/30 focus-visible:ring-2 focus-visible:outline-none',\n 'group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-bg group-data-[variant=terminal]/code-block:text-terminal-muted group-data-[variant=terminal]/code-block:hover:bg-terminal-muted-hover-bg group-data-[variant=terminal]/code-block:hover:text-terminal-muted-hover-fg',\n className,\n )}\n aria-label={copied ? 'Copied' : 'Copy code'}\n {...props}\n >\n {copied ? <Icon name=\"check\" size=\"sm\" className=\"text-green-500\" /> : <Icon name=\"copy\" size=\"sm\" />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{copied ? 'Copied' : 'Copy'}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction CodeBlockDownloadButton({\n code,\n fileName,\n mimeType = 'text/plain',\n className,\n ...props\n}: Omit<React.ComponentProps<'button'>, 'children'> & {\n code: string;\n fileName: string;\n mimeType?: string;\n}) {\n const [downloaded, setDownloaded] = useState(false);\n\n const handleDownload = () => {\n const blob = new Blob([code], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n setDownloaded(true);\n setTimeout(() => setDownloaded(false), 2000);\n };\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n data-slot=\"code-block-download-button\"\n onClick={handleDownload}\n className={cn(\n 'border-border bg-background inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border motion-safe:transition-colors',\n 'text-muted-foreground hover:bg-accent hover:text-foreground',\n 'focus-visible:ring-ring/30 focus-visible:ring-2 focus-visible:outline-none',\n 'group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-bg group-data-[variant=terminal]/code-block:text-terminal-muted group-data-[variant=terminal]/code-block:hover:bg-terminal-muted-hover-bg group-data-[variant=terminal]/code-block:hover:text-terminal-muted-hover-fg',\n className,\n )}\n aria-label={downloaded ? 'Downloaded' : 'Download code'}\n {...props}\n >\n {downloaded ? <Icon name=\"check\" size=\"sm\" className=\"text-green-500\" /> : <Icon name=\"download\" size=\"sm\" />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{downloaded ? 'Downloaded' : 'Download'}</TooltipContent>\n </Tooltip>\n );\n}\n\nexport { CodeBlock, CodeBlockHeader, CodeBlockBody, CodeBlockFooter, CodeBlockCopyButton, CodeBlockDownloadButton };\n","import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [\n {\n text: [\n 'display-hero',\n 'display-kpi-sm',\n 'display-kpi',\n 'display-kpi-lg',\n 'display-feature',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'body-lg',\n 'body',\n 'body-sm',\n 'caption',\n 'eyebrow',\n ],\n },\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function sortBy<T>(items: T[], getKey: (item: T) => string): T[] {\n return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));\n}\n","import { createHighlighter, type Highlighter } from 'shiki';\n\nexport const CODE_BLOCK_LANGUAGES = ['tsx', 'typescript', 'bash', 'shell', 'json', 'css', 'yaml'] as const;\n\nexport type CodeBlockLanguage = (typeof CODE_BLOCK_LANGUAGES)[number];\n\nconst HIGHLIGHTER_KEY = '__monarch_shiki_highlighter__';\n\ntype HighlighterGlobal = typeof globalThis & {\n [HIGHLIGHTER_KEY]?: Promise<Highlighter>;\n};\n\n/**\n * Cache the in-flight Promise, not the resolved instance. `createHighlighter`\n * is async — storing only after `await` lets every concurrent CodeBlockBody\n * start a new highlighter (Shiki warns at 10/20/30 instances). `globalThis`\n * keeps the same promise across HMR module re-evals in the same realm.\n */\nfunction getHighlighter(): Promise<Highlighter> {\n const g = globalThis as HighlighterGlobal;\n if (!g[HIGHLIGHTER_KEY]) {\n g[HIGHLIGHTER_KEY] = createHighlighter({\n themes: ['github-light-high-contrast', 'github-dark-dimmed'],\n langs: [...CODE_BLOCK_LANGUAGES],\n }).catch(error => {\n delete g[HIGHLIGHTER_KEY];\n throw error;\n });\n }\n return g[HIGHLIGHTER_KEY];\n}\n\n/**\n * Highlight a code string with Shiki dual themes. Returns raw HTML safe to\n * render via dangerouslySetInnerHTML.\n *\n * Light theme renders as inline `color:` / `background-color:`.\n * Dark theme renders as CSS variables `--shiki-dark` / `--shiki-dark-bg`.\n */\nexport async function highlightCode(code: string, lang: CodeBlockLanguage): Promise<string> {\n const hl = await getHighlighter();\n return hl.codeToHtml(code, {\n lang,\n themes: {\n light: 'github-light-high-contrast',\n dark: 'github-dark-dimmed',\n },\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/code-block.tsx","../src/lib/utils.ts","../src/lib/highlight.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Icon } from '@upbound/monarch-core';\n\nimport { cn } from '@/lib/utils';\nimport {\n Card,\n CardContent,\n CardFooter,\n CardHeader,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@upbound/monarch-core';\nimport { highlightCode, type CodeBlockLanguage } from './lib/highlight';\n\nexport type { CodeBlockLanguage } from './lib/highlight';\n\ntype CodeBlockCodeBase = {\n /** Raw code string — used for clipboard copy, download, and as the rendered text. */\n content: string;\n /** Numbers each line in the gutter. */\n lineNumbers?: boolean;\n};\n\nexport type CodeBlockCode =\n | (CodeBlockCodeBase & {\n /** Syntax-highlighted with Shiki inside CodeBlockBody — no highlighting step needed on your end. */\n type: 'parsed';\n language: CodeBlockLanguage;\n })\n | (CodeBlockCodeBase & {\n /** Rendered as plain, unhighlighted text. */\n type: 'raw';\n });\n\nfunction CodeBlock({\n className,\n variant = 'default',\n size = 'default',\n ...props\n}: React.ComponentProps<'div'> & {\n variant?: 'default' | 'terminal';\n size?: 'default' | 'sm';\n}) {\n return (\n <Card\n data-slot=\"code-block\"\n data-variant={variant}\n data-size={size}\n role=\"region\"\n className={cn(\n 'group/code-block gap-0 overflow-hidden py-0',\n size === 'default' && 'text-[13px]',\n size === 'sm' && 'text-body-sm',\n variant === 'terminal' && 'border-terminal-border bg-terminal-bg text-terminal-fg ring-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CodeBlockHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <CardHeader\n className={cn(\n 'group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-bg group-data-[variant=terminal]/code-block:text-terminal-muted flex flex-row items-center gap-2 border-b bg-[color-mix(in_oklch,var(--muted)_50%,var(--card))] py-4',\n className,\n )}\n {...props}\n />\n );\n}\n\nconst LINE_NUMBER_GUTTER = cn(\n '[&_code]:[counter-reset:line]',\n '[&_.line]:before:[counter-increment:line]',\n '[&_.line]:before:content-[counter(line)]',\n '[&_.line]:before:inline-block',\n '[&_.line]:before:w-6',\n '[&_.line]:before:mr-3',\n '[&_.line]:before:text-right',\n '[&_.line]:before:text-muted-foreground',\n '[&_.line]:before:text-[0.75rem]',\n '[&_.line]:before:select-none',\n);\n\nfunction CodeBlockBody({\n className,\n code,\n maxHeight,\n copyButton,\n downloadButton,\n ...props\n}: Omit<React.ComponentProps<'div'>, 'children'> & {\n code: CodeBlockCode;\n maxHeight?: string;\n copyButton?: React.ReactNode;\n downloadButton?: React.ReactNode;\n}) {\n const { content, lineNumbers } = code;\n const [html, setHtml] = useState<string | null>(null);\n const language = code.type === 'parsed' ? code.language : null;\n\n useEffect(() => {\n if (!language) {\n setHtml(null);\n return;\n }\n\n let cancelled = false;\n highlightCode(content, language).then(result => {\n if (!cancelled) setHtml(result);\n });\n\n return () => {\n cancelled = true;\n };\n }, [content, language]);\n\n // Layout note: the copy/download buttons must stay anchored to the\n // top-right of the visible code area when the content scrolls\n // horizontally. To make that work the relative containing block\n // (CardContent) must NOT be the scrollable element — otherwise\n // `right`-positioning is computed against the scrolled content edge and\n // the buttons move with the scroll. So the overflow lives on an inner\n // wrapper and the absolute button group is its sibling under CardContent.\n return (\n <CardContent data-line-numbers={lineNumbers || undefined} className={cn('relative p-0!', className)} {...props}>\n {(copyButton || downloadButton) && (\n <div className=\"absolute top-2 right-2 z-10 flex items-center gap-1 opacity-0 transition-opacity group-hover/code-block:opacity-100\">\n {copyButton}\n {downloadButton}\n </div>\n )}\n <div\n className={cn('overflow-x-auto', maxHeight && 'overflow-y-auto')}\n style={maxHeight ? { maxHeight } : undefined}\n >\n <div\n className={cn(\n '[&_code]:font-mono [&_pre]:m-0 [&_pre]:p-4 group-data-[size=sm]/code-block:[&_pre]:p-3',\n html && '[&_pre]:bg-transparent!',\n lineNumbers && LINE_NUMBER_GUTTER,\n )}\n >\n {html ? (\n <div dangerouslySetInnerHTML={{ __html: html }} />\n ) : (\n <pre>\n <code className={lineNumbers ? undefined : 'whitespace-pre'}>\n {lineNumbers\n ? content.split('\\n').map((line, i) => (\n <span key={i} className=\"line\">\n {line}\n {'\\n'}\n </span>\n ))\n : content}\n </code>\n </pre>\n )}\n </div>\n </div>\n </CardContent>\n );\n}\n\nfunction CodeBlockFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <CardFooter\n className={cn(\n 'text-body-sm group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-footer-bg group-data-[variant=terminal]/code-block:text-terminal-muted',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CodeBlockCopyButton({\n code,\n className,\n ...props\n}: Omit<React.ComponentProps<'button'>, 'children'> & {\n code: string;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n data-slot=\"code-block-copy-button\"\n onClick={handleCopy}\n className={cn(\n 'border-border bg-background inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border motion-safe:transition-colors',\n 'text-muted-foreground hover:bg-accent hover:text-foreground',\n 'focus-visible:ring-ring/30 focus-visible:ring-2 focus-visible:outline-none',\n 'group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-bg group-data-[variant=terminal]/code-block:text-terminal-muted group-data-[variant=terminal]/code-block:hover:bg-terminal-muted-hover-bg group-data-[variant=terminal]/code-block:hover:text-terminal-muted-hover-fg',\n className,\n )}\n aria-label={copied ? 'Copied' : 'Copy code'}\n {...props}\n >\n {copied ? <Icon name=\"check\" size=\"sm\" className=\"text-green-500\" /> : <Icon name=\"copy\" size=\"sm\" />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{copied ? 'Copied' : 'Copy'}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction CodeBlockDownloadButton({\n code,\n fileName,\n mimeType = 'text/plain',\n className,\n ...props\n}: Omit<React.ComponentProps<'button'>, 'children'> & {\n code: string;\n fileName: string;\n mimeType?: string;\n}) {\n const [downloaded, setDownloaded] = useState(false);\n\n const handleDownload = () => {\n const blob = new Blob([code], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n setDownloaded(true);\n setTimeout(() => setDownloaded(false), 2000);\n };\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n data-slot=\"code-block-download-button\"\n onClick={handleDownload}\n className={cn(\n 'border-border bg-background inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border motion-safe:transition-colors',\n 'text-muted-foreground hover:bg-accent hover:text-foreground',\n 'focus-visible:ring-ring/30 focus-visible:ring-2 focus-visible:outline-none',\n 'group-data-[variant=terminal]/code-block:border-terminal-border group-data-[variant=terminal]/code-block:bg-terminal-bg group-data-[variant=terminal]/code-block:text-terminal-muted group-data-[variant=terminal]/code-block:hover:bg-terminal-muted-hover-bg group-data-[variant=terminal]/code-block:hover:text-terminal-muted-hover-fg',\n className,\n )}\n aria-label={downloaded ? 'Downloaded' : 'Download code'}\n {...props}\n >\n {downloaded ? <Icon name=\"check\" size=\"sm\" className=\"text-green-500\" /> : <Icon name=\"download\" size=\"sm\" />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{downloaded ? 'Downloaded' : 'Download'}</TooltipContent>\n </Tooltip>\n );\n}\n\nexport { CodeBlock, CodeBlockHeader, CodeBlockBody, CodeBlockFooter, CodeBlockCopyButton, CodeBlockDownloadButton };\n","export { cn } from '@upbound/monarch-core/utils';\n\nexport function sortBy<T>(items: T[], getKey: (item: T) => string): T[] {\n return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));\n}\n","import { createHighlighter, type Highlighter } from 'shiki';\n\nexport const CODE_BLOCK_LANGUAGES = ['tsx', 'typescript', 'bash', 'shell', 'json', 'css', 'yaml'] as const;\n\nexport type CodeBlockLanguage = (typeof CODE_BLOCK_LANGUAGES)[number];\n\nconst HIGHLIGHTER_KEY = '__monarch_shiki_highlighter__';\n\ntype HighlighterGlobal = typeof globalThis & {\n [HIGHLIGHTER_KEY]?: Promise<Highlighter>;\n};\n\n/**\n * Cache the in-flight Promise, not the resolved instance. `createHighlighter`\n * is async — storing only after `await` lets every concurrent CodeBlockBody\n * start a new highlighter (Shiki warns at 10/20/30 instances). `globalThis`\n * keeps the same promise across HMR module re-evals in the same realm.\n */\nfunction getHighlighter(): Promise<Highlighter> {\n const g = globalThis as HighlighterGlobal;\n if (!g[HIGHLIGHTER_KEY]) {\n g[HIGHLIGHTER_KEY] = createHighlighter({\n themes: ['github-light-high-contrast', 'github-dark-dimmed'],\n langs: [...CODE_BLOCK_LANGUAGES],\n }).catch(error => {\n delete g[HIGHLIGHTER_KEY];\n throw error;\n });\n }\n return g[HIGHLIGHTER_KEY];\n}\n\n/**\n * Highlight a code string with Shiki dual themes. Returns raw HTML safe to\n * render via dangerouslySetInnerHTML.\n *\n * Light theme renders as inline `color:` / `background-color:`.\n * Dark theme renders as CSS variables `--shiki-dark` / `--shiki-dark-bg`.\n */\nexport async function highlightCode(code: string, lang: CodeBlockLanguage): Promise<string> {\n const hl = await getHighlighter();\n return hl.codeToHtml(code, {\n lang,\n themes: {\n light: 'github-light-high-contrast',\n dark: 'github-dark-dimmed',\n },\n });\n}\n"],"mappings":"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","names":[]}
|
package/dist/data-table.d.ts
CHANGED
|
@@ -256,7 +256,12 @@ interface DataTableProps<TData extends RowData> {
|
|
|
256
256
|
className?: string;
|
|
257
257
|
/** Table layout mode. 'auto' uses native HTML table layout, 'grid' uses CSS Grid with div elements. @default 'auto' */
|
|
258
258
|
layout?: TableLayout;
|
|
259
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* When true, table height fits content instead of using viewport-based height constraints.
|
|
261
|
+
* The row scroll area then grows with the rows, so `stickyHeader` has no effect — a sticky
|
|
262
|
+
* header needs a scroll area that is shorter than its content to stick against.
|
|
263
|
+
* @default false
|
|
264
|
+
*/
|
|
260
265
|
fitContent?: boolean;
|
|
261
266
|
serverSidePagination?: boolean;
|
|
262
267
|
onRowRender?(row: TData): DataTableRowProps;
|
|
@@ -312,6 +317,10 @@ interface DataTableProps<TData extends RowData> {
|
|
|
312
317
|
/**
|
|
313
318
|
* Enable sticky column headers within the table scroll area.
|
|
314
319
|
* Pass `true` for defaults, or an object to customise offset / row height.
|
|
320
|
+
*
|
|
321
|
+
* This caps the scroll area at a viewport-relative height so the rows scroll under the
|
|
322
|
+
* header. `fitContent` removes that cap, so the two props do not work together: with
|
|
323
|
+
* `fitContent` the table grows to its content and the header does not stick.
|
|
315
324
|
*/
|
|
316
325
|
stickyHeader?: StickyHeaderConfig;
|
|
317
326
|
/** When set, renders the CEL filter builder in the filter row instead of column filters. */
|
package/dist/data-table.js
CHANGED
|
@@ -129,37 +129,7 @@ import {
|
|
|
129
129
|
import { Icon } from "@upbound/monarch-core";
|
|
130
130
|
|
|
131
131
|
// src/lib/utils.ts
|
|
132
|
-
import {
|
|
133
|
-
import { extendTailwindMerge } from "tailwind-merge";
|
|
134
|
-
var twMerge = extendTailwindMerge({
|
|
135
|
-
extend: {
|
|
136
|
-
classGroups: {
|
|
137
|
-
"font-size": [
|
|
138
|
-
{
|
|
139
|
-
text: [
|
|
140
|
-
"display-hero",
|
|
141
|
-
"display-kpi-sm",
|
|
142
|
-
"display-kpi",
|
|
143
|
-
"display-kpi-lg",
|
|
144
|
-
"display-feature",
|
|
145
|
-
"h1",
|
|
146
|
-
"h2",
|
|
147
|
-
"h3",
|
|
148
|
-
"h4",
|
|
149
|
-
"body-lg",
|
|
150
|
-
"body",
|
|
151
|
-
"body-sm",
|
|
152
|
-
"caption",
|
|
153
|
-
"eyebrow"
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
function cn(...inputs) {
|
|
161
|
-
return twMerge(clsx(inputs));
|
|
162
|
-
}
|
|
132
|
+
import { cn } from "@upbound/monarch-core/utils";
|
|
163
133
|
function sortBy(items, getKey) {
|
|
164
134
|
return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));
|
|
165
135
|
}
|
|
@@ -167,10 +137,9 @@ function sortBy(items, getKey) {
|
|
|
167
137
|
// src/lib/data-table/utils.ts
|
|
168
138
|
var TO_EACH_SIDE = 2;
|
|
169
139
|
function normalizeColumnOrdering(columnOrdering, allColumnIds) {
|
|
170
|
-
const validIds = new Set(allColumnIds);
|
|
171
140
|
const seenIds = /* @__PURE__ */ new Set();
|
|
172
141
|
const trackedColumnIds = columnOrdering.filter((columnId) => {
|
|
173
|
-
if (
|
|
142
|
+
if (seenIds.has(columnId)) return false;
|
|
174
143
|
seenIds.add(columnId);
|
|
175
144
|
return true;
|
|
176
145
|
});
|
|
@@ -1825,6 +1794,7 @@ function CelAddFilterButton({
|
|
|
1825
1794
|
items: groups,
|
|
1826
1795
|
itemToStringValue: (item) => item.title,
|
|
1827
1796
|
itemToStringLabel: (item) => item.title,
|
|
1797
|
+
value: null,
|
|
1828
1798
|
onValueChange: (column) => {
|
|
1829
1799
|
if (column) onSelect(column.id);
|
|
1830
1800
|
},
|
|
@@ -3874,6 +3844,7 @@ function FilterBar(_a) {
|
|
|
3874
3844
|
items: availableFilters,
|
|
3875
3845
|
itemToStringValue: (item) => item.label,
|
|
3876
3846
|
itemToStringLabel: (item) => item.label,
|
|
3847
|
+
value: null,
|
|
3877
3848
|
onValueChange: (filter) => {
|
|
3878
3849
|
if (filter) handleAddFilter(filter.key);
|
|
3879
3850
|
},
|
|
@@ -4434,6 +4405,7 @@ function SectionHeaderDescription(_a) {
|
|
|
4434
4405
|
// src/data-table/data-table.tsx
|
|
4435
4406
|
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4436
4407
|
var DEFAULT_PAGE_SIZE = 20;
|
|
4408
|
+
var STICKY_HEADER_MAX_HEIGHT_CLASS = "max-h-[calc(100svh-250px)]";
|
|
4437
4409
|
function DataTable({
|
|
4438
4410
|
id,
|
|
4439
4411
|
config,
|
|
@@ -4771,9 +4743,10 @@ function DataTable({
|
|
|
4771
4743
|
"div",
|
|
4772
4744
|
{
|
|
4773
4745
|
ref: tableBodyScrollRef,
|
|
4746
|
+
"data-testid": "table-scroll-container",
|
|
4774
4747
|
className: cn(
|
|
4775
4748
|
"min-h-0 flex-1 overflow-auto rounded-lg border **:data-[slot=table-container]:overflow-visible",
|
|
4776
|
-
!!stickyHeader &&
|
|
4749
|
+
!!stickyHeader && !fitContent && STICKY_HEADER_MAX_HEIGHT_CLASS
|
|
4777
4750
|
),
|
|
4778
4751
|
children: /* @__PURE__ */ jsxs10(
|
|
4779
4752
|
DataTableRoot,
|