@humain/ui 2.2.6 → 2.2.9
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/index101.js +2 -2
- package/dist/index101.js.map +1 -1
- package/dist/index103.js +3 -3
- package/dist/index103.js.map +1 -1
- package/dist/index108.js +1 -1
- package/dist/index108.js.map +1 -1
- package/dist/index117.js +1 -1
- package/dist/index117.js.map +1 -1
- package/dist/index122.js +6 -6
- package/dist/index122.js.map +1 -1
- package/dist/index126.js +1 -1
- package/dist/index126.js.map +1 -1
- package/dist/index130.js +2 -2
- package/dist/index130.js.map +1 -1
- package/dist/index146.js +4 -4
- package/dist/index146.js.map +1 -1
- package/dist/index152.js +1 -1
- package/dist/index152.js.map +1 -1
- package/dist/index154.js +2 -2
- package/dist/index154.js.map +1 -1
- package/dist/index166.js +1 -1
- package/dist/index166.js.map +1 -1
- package/dist/index168.js +1 -1
- package/dist/index168.js.map +1 -1
- package/dist/index169.js +1 -1
- package/dist/index169.js.map +1 -1
- package/dist/index173.js +2 -2
- package/dist/index173.js.map +1 -1
- package/dist/index175.js +4 -4
- package/dist/index175.js.map +1 -1
- package/dist/index176.js +2 -2
- package/dist/index176.js.map +1 -1
- package/dist/index177.js +2 -2
- package/dist/index177.js.map +1 -1
- package/dist/index184.js +1 -1
- package/dist/index184.js.map +1 -1
- package/dist/index191.js +3 -3
- package/dist/index191.js.map +1 -1
- package/dist/index192.js +2 -2
- package/dist/index192.js.map +1 -1
- package/dist/index201.js +2 -2
- package/dist/index201.js.map +1 -1
- package/dist/index204.js +4 -4
- package/dist/index204.js.map +1 -1
- package/dist/index228.js +1 -1
- package/dist/index228.js.map +1 -1
- package/dist/index229.js +1 -1
- package/dist/index229.js.map +1 -1
- package/dist/index24.js +2 -2
- package/dist/index24.js.map +1 -1
- package/dist/index5.js +1 -1
- package/dist/index5.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/wc/AICodeBlock.js +41 -41
- package/dist/wc/AICodeBlock.js.map +1 -1
- package/dist/wc/AIMermaidDiagram.js +7 -7
- package/dist/wc/AIMermaidDiagram.js.map +1 -1
- package/dist/wc/AIMessage.js +6 -6
- package/dist/wc/AIMessage.js.map +1 -1
- package/dist/wc/AISource.js +2 -2
- package/dist/wc/AISource.js.map +1 -1
- package/dist/wc/AIToolCall.js +1 -1
- package/dist/wc/AIToolCall.js.map +1 -1
- package/dist/wc/Breadcrumb.js +43 -43
- package/dist/wc/Breadcrumb.js.map +1 -1
- package/dist/wc/DropdownMenu.js +9 -9
- package/dist/wc/DropdownMenu.js.map +1 -1
- package/dist/wc/Kbd.js +22 -22
- package/dist/wc/Kbd.js.map +1 -1
- package/dist/wc/button.js +7 -7
- package/dist/wc/button.js.map +1 -1
- package/dist/wc/close-button.js +19 -19
- package/dist/wc/close-button.js.map +1 -1
- package/dist/wc/hf-ai-prompt-suggestion.js +14 -14
- package/dist/wc/hf-ai-prompt-suggestion.js.map +1 -1
- package/dist/wc/hf-ai-reasoning-block.js +13 -13
- package/dist/wc/hf-ai-reasoning-block.js.map +1 -1
- package/dist/wc/hf-ai-steps.js +53 -53
- package/dist/wc/hf-ai-steps.js.map +1 -1
- package/dist/wc/hf-ai-system-message.js +26 -26
- package/dist/wc/hf-ai-system-message.js.map +1 -1
- package/dist/wc/hf-code-snippet.js +35 -35
- package/dist/wc/hf-code-snippet.js.map +1 -1
- package/dist/wc/hf-command-menu.js +39 -39
- package/dist/wc/hf-command-menu.js.map +1 -1
- package/dist/wc/hf-data-table.js +3 -3
- package/dist/wc/hf-data-table.js.map +1 -1
- package/dist/wc/hf-display-value.js +50 -50
- package/dist/wc/hf-display-value.js.map +1 -1
- package/dist/wc/hf-nav-account-menu.js +5 -5
- package/dist/wc/hf-nav-account-menu.js.map +1 -1
- package/dist/wc/hf-rich-textarea.js +1 -1
- package/dist/wc/hf-rich-textarea.js.map +1 -1
- package/dist/wc/hf-steps.js +8 -8
- package/dist/wc/hf-steps.js.map +1 -1
- package/dist/wc/markdown-renderer.js +1 -1
- package/dist/wc/markdown-renderer.js.map +1 -1
- package/dist/wc/selection-group.js +26 -26
- package/dist/wc/selection-group.js.map +1 -1
- package/dist/wc/syntax-highlight.js +4 -4
- package/dist/wc/syntax-highlight.js.map +1 -1
- package/dist/wc/workflow-step-renderer.js +51 -51
- package/dist/wc/workflow-step-renderer.js.map +1 -1
- package/dist/wc-react/AICodeBlock.js +17 -17
- package/dist/wc-react/AICodeBlock.js.map +1 -1
- package/dist/wc-react/AIMermaidDiagram.js +16 -16
- package/dist/wc-react/AIMermaidDiagram.js.map +1 -1
- package/dist/wc-react/AIMessage.js +7 -7
- package/dist/wc-react/AIMessage.js.map +1 -1
- package/dist/wc-react/AISource.js +41 -41
- package/dist/wc-react/AISource.js.map +1 -1
- package/dist/wc-react/AIToolCall.js +6 -6
- package/dist/wc-react/AIToolCall.js.map +1 -1
- package/dist/wc-react/Breadcrumb.js +18 -18
- package/dist/wc-react/Breadcrumb.js.map +1 -1
- package/dist/wc-react/DropdownMenu.js +27 -27
- package/dist/wc-react/DropdownMenu.js.map +1 -1
- package/dist/wc-react/Kbd.js +17 -17
- package/dist/wc-react/Kbd.js.map +1 -1
- package/dist/wc-react/button.js +12 -12
- package/dist/wc-react/button.js.map +1 -1
- package/dist/wc-react/close-button.js +19 -19
- package/dist/wc-react/close-button.js.map +1 -1
- package/dist/wc-react/hf-ai-prompt-suggestion.js +1 -1
- package/dist/wc-react/hf-ai-prompt-suggestion.js.map +1 -1
- package/dist/wc-react/hf-ai-reasoning-block.js +1 -1
- package/dist/wc-react/hf-ai-reasoning-block.js.map +1 -1
- package/dist/wc-react/hf-ai-steps.js +33 -33
- package/dist/wc-react/hf-ai-steps.js.map +1 -1
- package/dist/wc-react/hf-ai-system-message.js +9 -9
- package/dist/wc-react/hf-ai-system-message.js.map +1 -1
- package/dist/wc-react/hf-code-snippet.js +3 -3
- package/dist/wc-react/hf-code-snippet.js.map +1 -1
- package/dist/wc-react/hf-command-menu.js +56 -56
- package/dist/wc-react/hf-command-menu.js.map +1 -1
- package/dist/wc-react/hf-data-table.js +3 -3
- package/dist/wc-react/hf-data-table.js.map +1 -1
- package/dist/wc-react/hf-display-value.js +58 -58
- package/dist/wc-react/hf-display-value.js.map +1 -1
- package/dist/wc-react/hf-nav-account-menu.js +7 -7
- package/dist/wc-react/hf-nav-account-menu.js.map +1 -1
- package/dist/wc-react/hf-rich-textarea.js +5 -5
- package/dist/wc-react/hf-rich-textarea.js.map +1 -1
- package/dist/wc-react/hf-steps.js +2 -2
- package/dist/wc-react/hf-steps.js.map +1 -1
- package/dist/wc-react/markdown-renderer.js +1 -1
- package/dist/wc-react/markdown-renderer.js.map +1 -1
- package/dist/wc-react/selection-group.js +7 -7
- package/dist/wc-react/selection-group.js.map +1 -1
- package/dist/wc-react/syntax-highlight.js +4 -4
- package/dist/wc-react/syntax-highlight.js.map +1 -1
- package/dist/wc-react/workflow-step-renderer.js +44 -44
- package/dist/wc-react/workflow-step-renderer.js.map +1 -1
- package/package.json +1 -1
- package/skills/humain-ui/SKILL.md +1 -1
- package/skills/humain-ui-wc/SKILL.md +1 -1
- package/skills/humain-ui-wc.skill +0 -0
- package/skills/humain-ui.skill +0 -0
- package/src/tokens.css +4 -0
package/dist/index101.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
var SUGAR_HIGH_STYLE = {
|
|
3
3
|
"--sh-class": "var(--blue-700)",
|
|
4
4
|
"--sh-identifier": "var(--foreground)",
|
|
5
|
-
"--sh-sign": "var(--
|
|
5
|
+
"--sh-sign": "var(--secondary-foreground)",
|
|
6
6
|
"--sh-property": "var(--pink-600)",
|
|
7
7
|
"--sh-entity": "var(--purple-700)",
|
|
8
8
|
"--sh-jsxliterals": "var(--cyan-700)",
|
|
9
9
|
"--sh-string": "var(--green-700)",
|
|
10
10
|
"--sh-keyword": "var(--indigo-700)",
|
|
11
|
-
"--sh-comment": "var(--
|
|
11
|
+
"--sh-comment": "var(--secondary-foreground)"
|
|
12
12
|
};
|
|
13
13
|
var INVERTED_SUGAR_HIGH_STYLE = {
|
|
14
14
|
"--sh-class": "var(--blue-200)",
|
package/dist/index101.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index101.js","names":[],"sources":["../src/lib/syntax-highlight.ts"],"sourcesContent":["import type * as React from 'react';\n\nexport const SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-700)',\n '--sh-identifier': 'var(--foreground)',\n '--sh-sign': 'var(--
|
|
1
|
+
{"version":3,"file":"index101.js","names":[],"sources":["../src/lib/syntax-highlight.ts"],"sourcesContent":["import type * as React from 'react';\n\nexport const SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-700)',\n '--sh-identifier': 'var(--foreground)',\n '--sh-sign': 'var(--secondary-foreground)',\n '--sh-property': 'var(--pink-600)',\n '--sh-entity': 'var(--purple-700)',\n '--sh-jsxliterals': 'var(--cyan-700)',\n '--sh-string': 'var(--green-700)',\n '--sh-keyword': 'var(--indigo-700)',\n '--sh-comment': 'var(--secondary-foreground)',\n} as React.CSSProperties;\n\nexport const INVERTED_SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-200)',\n '--sh-identifier': 'var(--primary-foreground)',\n '--sh-sign': 'var(--primary-foreground)',\n '--sh-property': 'var(--pink-300)',\n '--sh-entity': 'var(--purple-300)',\n '--sh-jsxliterals': 'var(--cyan-300)',\n '--sh-string': 'var(--green-300)',\n '--sh-keyword': 'var(--indigo-300)',\n '--sh-comment': 'var(--primary-foreground)',\n} as React.CSSProperties;\n"],"mappings":";AAEA,IAAa,mBAAmB;CAC9B,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;AAClB;AAEA,IAAa,4BAA4B;CACvC,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;AAClB"}
|
package/dist/index103.js
CHANGED
|
@@ -16,7 +16,7 @@ var codeSnippetVariants = cva("overflow-hidden rounded-xl bg-background", {
|
|
|
16
16
|
} },
|
|
17
17
|
defaultVariants: { size: "md" }
|
|
18
18
|
});
|
|
19
|
-
var lineNumberVariants = cva("select-none font-mono font-bold leading-normal text-
|
|
19
|
+
var lineNumberVariants = cva("select-none font-mono font-bold leading-normal text-secondary-foreground", {
|
|
20
20
|
variants: { size: {
|
|
21
21
|
sm: "text-xs",
|
|
22
22
|
md: "text-base",
|
|
@@ -88,7 +88,7 @@ var CodeSnippet = React$1.forwardRef(({ code, language, showLineNumbers = true,
|
|
|
88
88
|
(language || showCopyButton) && /* @__PURE__ */ jsxs("div", {
|
|
89
89
|
className: "absolute top-2 end-2 flex items-center gap-2 z-10",
|
|
90
90
|
children: [language && /* @__PURE__ */ jsx("span", {
|
|
91
|
-
className: "text-xs font-medium text-
|
|
91
|
+
className: "text-xs font-medium text-secondary-foreground uppercase select-none",
|
|
92
92
|
children: language
|
|
93
93
|
}), showCopyButton && /* @__PURE__ */ jsx(Button, {
|
|
94
94
|
appearance: "ghost",
|
|
@@ -96,7 +96,7 @@ var CodeSnippet = React$1.forwardRef(({ code, language, showLineNumbers = true,
|
|
|
96
96
|
size: "sm",
|
|
97
97
|
onClick: handleCopy,
|
|
98
98
|
"aria-label": copied ? "Copied to clipboard" : "Copy code to clipboard",
|
|
99
|
-
className: "h-7 px-2 text-
|
|
99
|
+
className: "h-7 px-2 text-secondary-foreground hover:text-foreground transition-colors duration-150 ease-out",
|
|
100
100
|
children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-success" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" })
|
|
101
101
|
})]
|
|
102
102
|
}),
|
package/dist/index103.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index103.js","names":[],"sources":["../src/components/molecules/data/CodeSnippet/CodeSnippet.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, Copy } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { SUGAR_HIGH_STYLE } from '@/lib/syntax-highlight';\nimport { renderHighlightedCode } from '@/lib/syntax-highlight-react';\nimport { cn } from '@/lib/utils';\n\nconst codeSnippetVariants = cva('overflow-hidden rounded-xl bg-background', {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nconst lineNumberVariants = cva(\n 'select-none font-mono font-bold leading-normal text-
|
|
1
|
+
{"version":3,"file":"index103.js","names":[],"sources":["../src/components/molecules/data/CodeSnippet/CodeSnippet.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, Copy } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { SUGAR_HIGH_STYLE } from '@/lib/syntax-highlight';\nimport { renderHighlightedCode } from '@/lib/syntax-highlight-react';\nimport { cn } from '@/lib/utils';\n\nconst codeSnippetVariants = cva('overflow-hidden rounded-xl bg-background', {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nconst lineNumberVariants = cva(\n 'select-none font-mono font-bold leading-normal text-secondary-foreground',\n {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nexport interface CodeSnippetProps\n extends VariantProps<typeof codeSnippetVariants> {\n /** Code content to display */\n code: string;\n /** Programming language label shown in the top-right corner */\n language?: string;\n /** Whether to show line numbers */\n showLineNumbers?: boolean;\n /** Starting line number */\n startLineNumber?: number;\n /** Whether to show a copy-to-clipboard button */\n showCopyButton?: boolean;\n /** Additional class name */\n className?: string;\n /** Responsive breakpoint for compact mode */\n breakpoint?: 'desktop' | 'mobile';\n}\n\ninterface LineNumbersProps {\n count: number;\n startLine: number;\n size?: 'sm' | 'md' | 'lg' | null;\n}\n\ninterface CopyFeedbackState {\n copied: boolean;\n resetKey: number;\n}\n\nfunction copyFeedbackReducer(\n state: CopyFeedbackState,\n copied: boolean,\n): CopyFeedbackState {\n return copied\n ? { copied: true, resetKey: state.resetKey + 1 }\n : { ...state, copied: false };\n}\n\nfunction getStartLineNumber(startLineNumber: number): number {\n return Number.isFinite(startLineNumber) ? Math.floor(startLineNumber) : 1;\n}\n\nfunction LineNumbers({ count, startLine, size }: LineNumbersProps) {\n return (\n <div aria-hidden=\"true\" className={cn(lineNumberVariants({ size }))}>\n {Array.from({ length: count }, (_, i) => (\n <span key={i} className=\"block mb-px last:mb-0\">\n {startLine + i}\n </span>\n ))}\n </div>\n );\n}\n\nconst CodeSnippet = React.forwardRef<HTMLElement, CodeSnippetProps>(\n (\n {\n code,\n language,\n showLineNumbers = true,\n startLineNumber = 1,\n showCopyButton = false,\n size,\n className,\n breakpoint = 'desktop',\n },\n ref,\n ) => {\n const highlightedContent = React.useMemo(\n () => renderHighlightedCode(code),\n [code],\n );\n const lineCount = React.useMemo(() => code.split('\\n').length, [code]);\n const safeStartLineNumber = getStartLineNumber(startLineNumber);\n\n const [copyFeedback, setCopyFeedback] = React.useReducer(\n copyFeedbackReducer,\n { copied: false, resetKey: 0 },\n );\n const { copied } = copyFeedback;\n const rootRef = React.useRef<HTMLElement>(null);\n\n // Merge forwarded ref with local ref\n React.useImperativeHandle(ref, () => rootRef.current as HTMLElement);\n\n React.useEffect(() => {\n if (!copyFeedback.copied) return;\n\n const copyResetTimer = setTimeout(() => {\n setCopyFeedback(false);\n }, 2000);\n\n return () => {\n clearTimeout(copyResetTimer);\n };\n }, [copyFeedback]);\n\n const handleCopy = React.useCallback(async () => {\n try {\n const win = rootRef.current?.ownerDocument.defaultView;\n if (!win) return;\n await win.navigator.clipboard.writeText(code);\n setCopyFeedback(true);\n } catch (err) {\n console.error('Failed to copy code:', err);\n }\n }, [code]);\n\n const containerPadding = breakpoint === 'mobile' ? 'p-4' : 'p-6';\n const contentPadding =\n breakpoint === 'mobile' ? 'py-4 px-4 pb-6' : 'py-6 px-6 pb-8';\n\n return (\n <section\n ref={rootRef}\n data-slot=\"code-snippet\"\n aria-label=\"Code snippet\"\n className={cn(\n codeSnippetVariants({ size }),\n 'relative flex items-start justify-center',\n className,\n )}\n style={SUGAR_HIGH_STYLE}\n >\n {/* Language badge & copy button */}\n {(language || showCopyButton) && (\n <div className=\"absolute top-2 end-2 flex items-center gap-2 z-10\">\n {language && (\n <span className=\"text-xs font-medium text-secondary-foreground uppercase select-none\">\n {language}\n </span>\n )}\n {showCopyButton && (\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleCopy}\n aria-label={\n copied ? 'Copied to clipboard' : 'Copy code to clipboard'\n }\n className=\"h-7 px-2 text-secondary-foreground hover:text-foreground transition-colors duration-150 ease-out\"\n >\n {copied ? (\n <Check className=\"size-3.5 text-success\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n </Button>\n )}\n </div>\n )}\n\n {/* Line Numbers Sidebar */}\n {showLineNumbers && (\n <div\n className={cn(\n 'shrink-0 self-stretch bg-muted border-e border-border',\n containerPadding,\n )}\n >\n <LineNumbers\n count={lineCount}\n startLine={safeStartLineNumber}\n size={size}\n />\n </div>\n )}\n\n {/* Code Content */}\n <section\n className={cn(\n 'grow min-w-0 overflow-x-auto focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n contentPadding,\n )}\n // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable scroll region satisfies axe scrollable-region-focusable.\n tabIndex={0}\n aria-label=\"Code content\"\n >\n <pre\n className={cn(\n 'font-mono font-medium leading-normal !bg-transparent !p-0 !m-0 !border-0 !rounded-none',\n '[&_.sh__line]:block [&_.sh__line]:leading-normal [&_.sh__line]:mb-px [&_.sh__line:last-child]:mb-0',\n )}\n >\n {highlightedContent}\n </pre>\n </section>\n </section>\n );\n },\n);\n\nCodeSnippet.displayName = 'CodeSnippet';\n\nexport { CodeSnippet, codeSnippetVariants, lineNumberVariants };\n"],"mappings":"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"}
|
package/dist/index108.js
CHANGED
|
@@ -12,7 +12,7 @@ var kbdVariants = cva("pointer-events-none inline-flex items-center justify-cent
|
|
|
12
12
|
outline: "bg-transparent border border-border text-muted-foreground rounded-sm shadow-[var(--shadow-kbd-outline)]",
|
|
13
13
|
solid: "bg-card/60 border border-border text-muted-foreground rounded shadow-[var(--shadow-kbd-default)]",
|
|
14
14
|
tooltip: "bg-background/20 text-background dark:bg-background/10 rounded-sm",
|
|
15
|
-
footer: "bg-background border border-border text-
|
|
15
|
+
footer: "bg-background border border-border text-secondary-foreground rounded-md shadow-[var(--shadow-kbd-footer)]"
|
|
16
16
|
},
|
|
17
17
|
size: {
|
|
18
18
|
xs: "h-4 min-w-4 px-0.5 text-[10px]",
|
package/dist/index108.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index108.js","names":[],"sources":["../src/components/molecules/data/Kbd/Kbd.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// ============================================\n// Variants\n// ============================================\n\nexport const kbdVariants = cva(\n 'pointer-events-none inline-flex items-center justify-center select-none font-sans font-medium',\n {\n variants: {\n variant: {\n default:\n 'bg-muted text-muted-foreground border border-border rounded-sm shadow-[var(--shadow-kbd-default)]',\n ghost: 'bg-transparent text-muted-foreground',\n outline:\n 'bg-transparent border border-border text-muted-foreground rounded-sm shadow-[var(--shadow-kbd-outline)]',\n solid:\n 'bg-card/60 border border-border text-muted-foreground rounded shadow-[var(--shadow-kbd-default)]',\n tooltip:\n 'bg-background/20 text-background dark:bg-background/10 rounded-sm',\n footer:\n 'bg-background border border-border text-
|
|
1
|
+
{"version":3,"file":"index108.js","names":[],"sources":["../src/components/molecules/data/Kbd/Kbd.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// ============================================\n// Variants\n// ============================================\n\nexport const kbdVariants = cva(\n 'pointer-events-none inline-flex items-center justify-center select-none font-sans font-medium',\n {\n variants: {\n variant: {\n default:\n 'bg-muted text-muted-foreground border border-border rounded-sm shadow-[var(--shadow-kbd-default)]',\n ghost: 'bg-transparent text-muted-foreground',\n outline:\n 'bg-transparent border border-border text-muted-foreground rounded-sm shadow-[var(--shadow-kbd-outline)]',\n solid:\n 'bg-card/60 border border-border text-muted-foreground rounded shadow-[var(--shadow-kbd-default)]',\n tooltip:\n 'bg-background/20 text-background dark:bg-background/10 rounded-sm',\n footer:\n 'bg-background border border-border text-secondary-foreground rounded-md shadow-[var(--shadow-kbd-footer)]',\n },\n size: {\n xs: 'h-4 min-w-4 px-0.5 text-[10px]',\n sm: 'h-5 min-w-5 px-1 text-xs',\n md: 'h-6 min-w-6 px-1.5 text-sm',\n lg: 'h-7 min-w-7 px-2 text-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'sm',\n },\n },\n);\n\nexport const kbdGroupVariants = cva('inline-flex items-center', {\n variants: {\n gap: {\n none: 'gap-0',\n xs: 'gap-0.5',\n sm: 'gap-1',\n md: 'gap-1.5',\n lg: 'gap-2',\n },\n },\n defaultVariants: {\n gap: 'sm',\n },\n});\n\n// ============================================\n// Types\n// ============================================\n\nexport interface KbdProps\n extends React.ComponentProps<'kbd'>,\n VariantProps<typeof kbdVariants> {\n /** Icon to display before the key */\n icon?: React.ReactNode;\n /** Icon to display after the key */\n iconAfter?: React.ReactNode;\n}\n\nexport interface KbdGroupProps\n extends React.ComponentProps<'span'>,\n VariantProps<typeof kbdGroupVariants> {}\n\n// ============================================\n// Kbd Component\n// ============================================\n\n/**\n * Keyboard key indicator component for displaying keyboard shortcuts.\n *\n * @example\n * // Basic usage\n * <Kbd>⌘K</Kbd>\n *\n * @example\n * // With variant and size\n * <Kbd variant=\"solid\" size=\"md\">⌘</Kbd>\n *\n * @example\n * // With icon\n * <Kbd icon={<ArrowUp />} />\n */\nconst Kbd = React.forwardRef<HTMLElement, KbdProps>(\n ({ className, variant, size, icon, iconAfter, children, ...props }, ref) => {\n return (\n <kbd\n ref={ref}\n data-slot=\"kbd\"\n className={cn(kbdVariants({ variant, size }), className)}\n {...props}\n >\n {icon && (\n <span\n aria-hidden=\"true\"\n className=\"shrink-0 [&_svg:not([class*='size-'])]:size-3\"\n >\n {icon}\n </span>\n )}\n {children}\n {iconAfter && (\n <span\n aria-hidden=\"true\"\n className=\"shrink-0 [&_svg:not([class*='size-'])]:size-3\"\n >\n {iconAfter}\n </span>\n )}\n </kbd>\n );\n },\n);\nKbd.displayName = 'Kbd';\n\n// ============================================\n// KbdGroup Component\n// ============================================\n\n/**\n * Group multiple Kbd components together with consistent spacing.\n *\n * @example\n * <KbdGroup>\n * <Kbd>⌘</Kbd>\n * <Kbd>K</Kbd>\n * </KbdGroup>\n */\nconst KbdGroup = React.forwardRef<HTMLSpanElement, KbdGroupProps>(\n ({ className, gap, ...props }, ref) => {\n return (\n <span\n ref={ref}\n data-slot=\"kbd-group\"\n className={cn(kbdGroupVariants({ gap }), className)}\n {...props}\n />\n );\n },\n);\nKbdGroup.displayName = 'KbdGroup';\n\n// ============================================\n// Shortcut Component (convenience wrapper)\n// ============================================\n\nexport interface ShortcutProps extends Omit<KbdProps, 'children'> {\n /** Array of keys to display (e.g., ['⌘', 'K']) */\n keys: (string | React.ReactNode)[];\n /** Separator between keys (defaults to none, keys are grouped) */\n separator?: React.ReactNode;\n}\n\nfunction getShortcutPartKey(\n key: string | React.ReactNode,\n position: number,\n): string {\n return `${position}:${typeof key === 'string' ? key : 'node'}`;\n}\n\n/**\n * Convenience component for displaying keyboard shortcuts with multiple keys.\n *\n * @example\n * // Simple shortcut\n * <Shortcut keys={['⌘', 'K']} />\n *\n * @example\n * // With separator\n * <Shortcut keys={['⌘', 'Shift', 'P']} separator=\"+\" />\n */\nconst Shortcut = React.forwardRef<HTMLSpanElement, ShortcutProps>(\n ({ keys, separator, className, variant, size, ...props }, ref) => {\n if (separator) {\n return (\n <KbdGroup ref={ref} gap=\"xs\" className={className}>\n {keys.map((key, position) => (\n <React.Fragment key={getShortcutPartKey(key, position)}>\n <Kbd variant={variant} size={size} {...props}>\n {key}\n </Kbd>\n {position < keys.length - 1 && (\n <span className=\"text-muted-foreground text-xs\">\n {separator}\n </span>\n )}\n </React.Fragment>\n ))}\n </KbdGroup>\n );\n }\n\n return (\n <KbdGroup ref={ref} gap=\"xs\" className={className}>\n {keys.map((key, position) => (\n <Kbd\n key={getShortcutPartKey(key, position)}\n variant={variant}\n size={size}\n {...props}\n >\n {key}\n </Kbd>\n ))}\n </KbdGroup>\n );\n },\n);\nShortcut.displayName = 'Shortcut';\n\n// ============================================\n// Platform-aware helpers\n// ============================================\n\n/**\n * Common keyboard key symbols for macOS\n */\nexport const MAC_KEYS = {\n cmd: '⌘',\n command: '⌘',\n ctrl: '⌃',\n control: '⌃',\n alt: '⌥',\n option: '⌥',\n shift: '⇧',\n enter: '↵',\n return: '↵',\n backspace: '⌫',\n delete: '⌦',\n tab: '⇥',\n esc: 'esc',\n escape: 'esc',\n up: '↑',\n down: '↓',\n left: '←',\n right: '→',\n space: '␣',\n} as const;\n\n/**\n * Common keyboard key symbols for Windows/Linux\n */\nexport const WIN_KEYS = {\n cmd: 'Ctrl',\n command: 'Ctrl',\n ctrl: 'Ctrl',\n control: 'Ctrl',\n alt: 'Alt',\n option: 'Alt',\n shift: 'Shift',\n enter: 'Enter',\n return: 'Enter',\n backspace: 'Backspace',\n delete: 'Delete',\n tab: 'Tab',\n esc: 'Esc',\n escape: 'Esc',\n up: '↑',\n down: '↓',\n left: '←',\n right: '→',\n space: 'Space',\n} as const;\n\n// ============================================\n// Exports\n// ============================================\n\nexport { Kbd, KbdGroup, Shortcut };\n"],"mappings":";;;;;;AAWA,IAAa,cAAc,IACzB,iGACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,OAAO;GACP,SACE;GACF,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,IAAa,mBAAmB,IAAI,4BAA4B;CAC9D,UAAU,EACR,KAAK;EACH,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,KAAK,KACP;AACF,CAAC;;;;;;;;;;;;;;;;AAsCD,IAAM,MAAM,QAAM,YACf,EAAE,WAAW,SAAS,MAAM,MAAM,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1E,OACE,qBAAC,OAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,YAAY;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EACvD,GAAI;YAJN;GAMG,QACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAET;GACG,CAAA;GAEP;GACA,aACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAET;GACG,CAAA;EAEL;;AAET,CACF;AACA,IAAI,cAAc;;;;;;;;;;AAelB,IAAM,WAAW,QAAM,YACpB,EAAE,WAAW,KAAK,GAAG,SAAS,QAAQ;CACrC,OACE,oBAAC,QAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,iBAAiB,EAAE,IAAI,CAAC,GAAG,SAAS;EAClD,GAAI;CACL,CAAA;AAEL,CACF;AACA,SAAS,cAAc;AAavB,SAAS,mBACP,KACA,UACQ;CACR,OAAO,GAAG,SAAS,GAAG,OAAO,QAAQ,WAAW,MAAM;AACxD;;;;;;;;;;;;AAaA,IAAM,WAAW,QAAM,YACpB,EAAE,MAAM,WAAW,WAAW,SAAS,MAAM,GAAG,SAAS,QAAQ;CAChE,IAAI,WACF,OACE,oBAAC,UAAD;EAAe;EAAK,KAAI;EAAgB;YACrC,KAAK,KAAK,KAAK,aACd,qBAAC,QAAM,UAAP,EAAA,UAAA,CACE,oBAAC,KAAD;GAAc;GAAe;GAAM,GAAI;aACpC;EACE,CAAA,GACJ,WAAW,KAAK,SAAS,KACxB,oBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,CAEM,EAAA,GATK,mBAAmB,KAAK,QAAQ,CASrC,CACjB;CACO,CAAA;CAId,OACE,oBAAC,UAAD;EAAe;EAAK,KAAI;EAAgB;YACrC,KAAK,KAAK,KAAK,aACd,oBAAC,KAAD;GAEW;GACH;GACN,GAAI;aAEH;EACE,GANE,mBAAmB,KAAK,QAAQ,CAMlC,CACN;CACO,CAAA;AAEd,CACF;AACA,SAAS,cAAc;;;;AASvB,IAAa,WAAW;CACtB,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACT,KAAK;CACL,QAAQ;CACR,OAAO;CACP,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT;;;;AAKA,IAAa,WAAW;CACtB,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACT,KAAK;CACL,QAAQ;CACR,OAAO;CACP,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT"}
|
package/dist/index117.js
CHANGED
|
@@ -43,7 +43,7 @@ CloseButton.displayName = "CloseButton";
|
|
|
43
43
|
* RemoveButton - for inline remove buttons (tags, list items, chips)
|
|
44
44
|
* Lightweight button with smaller footprint
|
|
45
45
|
*/
|
|
46
|
-
var removeButtonVariants = cva("flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-
|
|
46
|
+
var removeButtonVariants = cva("flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-secondary-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", {
|
|
47
47
|
variants: { size: {
|
|
48
48
|
sm: "[&>svg]:size-2.5",
|
|
49
49
|
md: "[&>svg]:size-3",
|
package/dist/index117.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index117.js","names":[],"sources":["../src/components/ui/close-button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\n/**\n * CloseButton - for modal/overlay close buttons (dialogs, sheets, drawers)\n * Uses Button component with ghost variant, positioned by consumer\n */\nconst closeButtonVariants = cva('', {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n});\n\nconst buttonSizeMap = {\n sm: 'icon-sm',\n md: 'icon',\n lg: 'icon-lg',\n} as const;\n\nexport interface CloseButtonProps\n extends Omit<\n React.ComponentProps<typeof Button>,\n 'variant' | 'size' | 'children'\n >,\n VariantProps<typeof closeButtonVariants> {\n /** Accessible label for the close button */\n 'aria-label'?: string;\n}\n\nconst CloseButton = React.forwardRef<HTMLButtonElement, CloseButtonProps>(\n (\n { className, size = 'sm', 'aria-label': ariaLabel = 'Close', ...props },\n ref,\n ) => {\n return (\n <Button\n ref={ref}\n data-slot=\"close-button\"\n appearance=\"ghost\"\n variant=\"secondary\"\n size={buttonSizeMap[size ?? 'sm']}\n className={cn(closeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n <span className=\"sr-only\">{ariaLabel}</span>\n </Button>\n );\n },\n);\n\nCloseButton.displayName = 'CloseButton';\n\n/**\n * RemoveButton - for inline remove buttons (tags, list items, chips)\n * Lightweight button with smaller footprint\n */\nconst removeButtonVariants = cva(\n 'flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-
|
|
1
|
+
{"version":3,"file":"index117.js","names":[],"sources":["../src/components/ui/close-button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\n/**\n * CloseButton - for modal/overlay close buttons (dialogs, sheets, drawers)\n * Uses Button component with ghost variant, positioned by consumer\n */\nconst closeButtonVariants = cva('', {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n});\n\nconst buttonSizeMap = {\n sm: 'icon-sm',\n md: 'icon',\n lg: 'icon-lg',\n} as const;\n\nexport interface CloseButtonProps\n extends Omit<\n React.ComponentProps<typeof Button>,\n 'variant' | 'size' | 'children'\n >,\n VariantProps<typeof closeButtonVariants> {\n /** Accessible label for the close button */\n 'aria-label'?: string;\n}\n\nconst CloseButton = React.forwardRef<HTMLButtonElement, CloseButtonProps>(\n (\n { className, size = 'sm', 'aria-label': ariaLabel = 'Close', ...props },\n ref,\n ) => {\n return (\n <Button\n ref={ref}\n data-slot=\"close-button\"\n appearance=\"ghost\"\n variant=\"secondary\"\n size={buttonSizeMap[size ?? 'sm']}\n className={cn(closeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n <span className=\"sr-only\">{ariaLabel}</span>\n </Button>\n );\n },\n);\n\nCloseButton.displayName = 'CloseButton';\n\n/**\n * RemoveButton - for inline remove buttons (tags, list items, chips)\n * Lightweight button with smaller footprint\n */\nconst removeButtonVariants = cva(\n 'flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-secondary-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n {\n variants: {\n size: {\n sm: '[&>svg]:size-2.5',\n md: '[&>svg]:size-3',\n lg: '[&>svg]:size-3.5',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nexport interface RemoveButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof removeButtonVariants> {\n /** Accessible label for the remove button */\n 'aria-label'?: string;\n}\n\nconst RemoveButton = React.forwardRef<HTMLButtonElement, RemoveButtonProps>(\n (\n { className, size = 'md', 'aria-label': ariaLabel = 'Remove', ...props },\n ref,\n ) => {\n return (\n <button\n ref={ref}\n type=\"button\"\n data-slot=\"remove-button\"\n className={cn(removeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n </button>\n );\n },\n);\n\nRemoveButton.displayName = 'RemoveButton';\n\nexport { CloseButton, closeButtonVariants, RemoveButton, removeButtonVariants };\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,sBAAsB,IAAI,IAAI;CAClC,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC;AAED,IAAM,gBAAgB;CACpB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAYA,IAAM,cAAc,QAAM,YAEtB,EAAE,WAAW,OAAO,MAAM,cAAc,YAAY,SAAS,GAAG,SAChE,QACG;CACH,OACE,qBAAC,QAAD;EACO;EACL,aAAU;EACV,YAAW;EACX,SAAQ;EACR,MAAM,cAAc,QAAQ;EAC5B,WAAW,GAAG,oBAAoB,EAAE,KAAK,CAAC,GAAG,SAAS;EACtD,cAAY;EACZ,GAAI;YARN,CAUE,oBAAC,GAAD,CAAI,CAAA,GACJ,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAgB,CAAA,CACrC;;AAEZ,CACF;AAEA,YAAY,cAAc;;;;;AAM1B,IAAM,uBAAuB,IAC3B,oOACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AASA,IAAM,eAAe,QAAM,YAEvB,EAAE,WAAW,OAAO,MAAM,cAAc,YAAY,UAAU,GAAG,SACjE,QACG;CACH,OACE,oBAAC,UAAD;EACO;EACL,MAAK;EACL,aAAU;EACV,WAAW,GAAG,qBAAqB,EAAE,KAAK,CAAC,GAAG,SAAS;EACvD,cAAY;EACZ,GAAI;YAEJ,oBAAC,GAAD,CAAI,CAAA;CACE,CAAA;AAEZ,CACF;AAEA,aAAa,cAAc"}
|
package/dist/index122.js
CHANGED
|
@@ -30,11 +30,11 @@ function DisplayValueLabel({ label, helpIcon, helpTooltip }) {
|
|
|
30
30
|
return /* @__PURE__ */ jsxs("div", {
|
|
31
31
|
className: "flex items-center gap-0.5",
|
|
32
32
|
children: [/* @__PURE__ */ jsx("span", {
|
|
33
|
-
className: "text-sm font-medium leading-5 text-secondary-foreground
|
|
33
|
+
className: "text-sm font-medium leading-5 text-secondary-foreground",
|
|
34
34
|
children: label
|
|
35
35
|
}), helpIcon && /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx("button", {
|
|
36
36
|
type: "button",
|
|
37
|
-
className: "text-muted-foreground hover:text-
|
|
37
|
+
className: "text-muted-foreground hover:text-secondary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none",
|
|
38
38
|
"aria-label": helpTooltip || `Help for ${label}`,
|
|
39
39
|
children: /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" })
|
|
40
40
|
}) }), /* @__PURE__ */ jsx(TooltipPopup, { children: helpTooltip || label })] })]
|
|
@@ -52,7 +52,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
|
|
|
52
52
|
case "icon-leading": return /* @__PURE__ */ jsxs("div", {
|
|
53
53
|
className: "flex items-center gap-2 flex-1 min-w-0",
|
|
54
54
|
children: [icon && /* @__PURE__ */ jsx("span", {
|
|
55
|
-
className: "shrink-0 text-
|
|
55
|
+
className: "shrink-0 text-muted-foreground [&>svg]:size-5",
|
|
56
56
|
children: icon
|
|
57
57
|
}), /* @__PURE__ */ jsx("span", {
|
|
58
58
|
className: "text-base font-normal leading-6 text-foreground dark:text-foreground truncate",
|
|
@@ -64,7 +64,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
|
|
|
64
64
|
children: [leadingText && /* @__PURE__ */ jsx("div", {
|
|
65
65
|
className: cn("flex items-center gap-1 overflow-hidden", displayPaddingY),
|
|
66
66
|
children: /* @__PURE__ */ jsx("span", {
|
|
67
|
-
className: "text-base font-normal leading-6 text-secondary-foreground
|
|
67
|
+
className: "text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap",
|
|
68
68
|
children: leadingText
|
|
69
69
|
})
|
|
70
70
|
}), /* @__PURE__ */ jsx("div", {
|
|
@@ -86,7 +86,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
|
|
|
86
86
|
}), trailingText && /* @__PURE__ */ jsx("div", {
|
|
87
87
|
className: cn("flex items-center gap-1 overflow-hidden px-3", displayPaddingY),
|
|
88
88
|
children: /* @__PURE__ */ jsx("span", {
|
|
89
|
-
className: "text-base font-normal leading-6 text-secondary-foreground
|
|
89
|
+
className: "text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap",
|
|
90
90
|
children: trailingText
|
|
91
91
|
})
|
|
92
92
|
})]
|
|
@@ -138,7 +138,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
|
|
|
138
138
|
children: /* @__PURE__ */ jsx("span", {
|
|
139
139
|
className: "text-base font-normal leading-6 text-foreground dark:text-foreground truncate",
|
|
140
140
|
children: value ?? children ?? /* @__PURE__ */ jsx("span", {
|
|
141
|
-
className: "text-
|
|
141
|
+
className: "text-secondary-foreground italic",
|
|
142
142
|
children: "—"
|
|
143
143
|
})
|
|
144
144
|
})
|
package/dist/index122.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index122.js","names":[],"sources":["../src/components/molecules/forms/DisplayValue/DisplayValue.tsx"],"sourcesContent":["import { HelpCircle } from 'lucide-react';\nimport * as React from 'react';\nimport { Badge, type BadgeProps } from '@/components/atoms/display/Badge';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\nexport type DisplayValueType =\n | 'default'\n | 'icon-leading'\n | 'trailing-text'\n | 'link'\n | 'tags'\n | 'leading-text'\n | 'avatar'\n | 'badge';\n\nexport interface DisplayValueTag\n extends Omit<BadgeProps, 'avatar' | 'children'> {\n label: string;\n avatar?: string;\n avatarAlt?: string;\n}\n\nexport interface DisplayValueProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Label text displayed above the field */\n label?: string;\n /** The main value to display */\n value?: React.ReactNode;\n /** Hint text displayed below the field */\n hint?: string;\n /** Show help icon with tooltip */\n helpIcon?: boolean;\n /** Tooltip content for help icon */\n helpTooltip?: string;\n /** Leading icon for icon-leading type */\n icon?: React.ReactNode;\n /** Size variant */\n size?: 'sm' | 'md';\n /** Display type */\n type?: DisplayValueType;\n /** RTL layout support */\n rtl?: boolean;\n /** Leading text (for leading-text type) */\n leadingText?: string;\n /** Trailing text (for trailing-text type) */\n trailingText?: string;\n /** Link URL (for link type) */\n linkHref?: string;\n /** Avatar props (for avatar type) */\n avatarProps?: AvatarProps;\n /** Supporting text for avatar */\n avatarSupportingText?: string;\n /** Badge props (for badge type) */\n badgeProps?: Omit<BadgeProps, 'children'>;\n /** Badge label (for badge type) */\n badgeLabel?: string;\n /** Tags data (for tags type) */\n tags?: DisplayValueTag[];\n}\n\ntype DisplayTag = NonNullable<DisplayValueProps['tags']>[number];\n\nfunction getDisplayTagKey(tag: DisplayTag): React.Key {\n return tag.id ?? `${tag.label}:${tag.avatarAlt ?? 'no-avatar'}`;\n}\n\nfunction DisplayValueBadge({ label, avatar, avatarAlt, ...props }: DisplayTag) {\n return (\n <Badge\n variant=\"outline\"\n shape=\"rounded\"\n size=\"md\"\n avatar={\n avatar ? (\n <Avatar\n src={avatar}\n alt={avatarAlt ?? ''}\n fallback={label}\n size=\"sm\"\n shape=\"circle\"\n />\n ) : undefined\n }\n {...props}\n >\n {label}\n </Badge>\n );\n}\n\ninterface DisplayValueLabelProps {\n label?: string;\n helpIcon: boolean;\n helpTooltip?: string;\n}\n\nfunction DisplayValueLabel({\n label,\n helpIcon,\n helpTooltip,\n}: DisplayValueLabelProps) {\n if (!label) return null;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <span className=\"text-sm font-medium leading-5 text-secondary-foreground dark:text-text-quaternary\">\n {label}\n </span>\n {helpIcon && (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-text-quaternary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none\"\n aria-label={helpTooltip || `Help for ${label}`}\n >\n <HelpCircle className=\"size-4\" />\n </button>\n }\n />\n <TooltipPopup>{helpTooltip || label}</TooltipPopup>\n </Tooltip>\n )}\n </div>\n );\n}\n\nfunction DisplayValueHint({ hint }: { hint?: string }) {\n if (!hint) return null;\n\n return (\n <p className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground w-full\">\n {hint}\n </p>\n );\n}\n\ninterface DisplayValueContentProps {\n type: DisplayValueType;\n icon?: React.ReactNode;\n value?: React.ReactNode;\n children?: React.ReactNode;\n leadingText?: string;\n trailingText?: string;\n displayPaddingY: string;\n linkHref?: string;\n tags?: DisplayValueProps['tags'];\n avatarProps?: AvatarProps;\n avatarSupportingText?: string;\n badgeProps?: Omit<BadgeProps, 'children'>;\n badgeLabel?: string;\n}\n\nfunction DisplayValueContent({\n type,\n icon,\n value,\n children,\n leadingText,\n trailingText,\n displayPaddingY,\n linkHref,\n tags,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n}: DisplayValueContentProps) {\n switch (type) {\n case 'icon-leading':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {icon && (\n <span className=\"shrink-0 text-text-quaternary [&>svg]:size-5\">\n {icon}\n </span>\n )}\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n );\n\n case 'leading-text':\n return (\n <div className=\"flex items-start w-full\">\n {leadingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground dark:text-text-quaternary whitespace-nowrap\">\n {leadingText}\n </span>\n </div>\n )}\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n 'ps-3',\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n </div>\n );\n\n case 'trailing-text':\n return (\n <div className=\"flex items-start w-full\">\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n {trailingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden px-3',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground dark:text-text-quaternary whitespace-nowrap\">\n {trailingText}\n </span>\n </div>\n )}\n </div>\n );\n\n case 'link':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {linkHref ? (\n <a\n href={linkHref}\n className=\"text-sm font-normal leading-5 text-primary hover:text-primary dark:text-primary dark:hover:text-primary truncate transition-colors duration-200 ease-smooth motion-reduce:transition-none hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {value ?? children ?? linkHref}\n </a>\n ) : (\n <span className=\"text-sm font-normal leading-5 text-primary dark:text-primary truncate\">\n {value ?? children}\n </span>\n )}\n </div>\n );\n\n case 'tags':\n return (\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n {tags?.map((tag) => (\n <DisplayValueBadge key={getDisplayTagKey(tag)} {...tag} />\n ))}\n {children}\n </div>\n );\n\n case 'avatar':\n return (\n <div className=\"flex items-center gap-2\">\n <Avatar size=\"lg\" {...avatarProps} />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold leading-5 text-foreground dark:text-foreground\">\n {value ?? children ?? avatarProps?.fallback}\n </span>\n {avatarSupportingText && (\n <span className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground\">\n {avatarSupportingText}\n </span>\n )}\n </div>\n </div>\n );\n\n case 'badge':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Badge variant=\"dot\" color=\"success\" {...badgeProps}>\n {badgeLabel ?? value ?? children}\n </Badge>\n </div>\n );\n\n default:\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children ?? (\n <span className=\"text-muted-foreground dark:text-text-quaternary italic\">\n —\n </span>\n )}\n </span>\n </div>\n );\n }\n}\n\nconst DisplayValue = React.forwardRef<HTMLDivElement, DisplayValueProps>(\n (\n {\n className,\n label,\n value,\n hint,\n helpIcon = false,\n helpTooltip,\n icon,\n size = 'sm',\n type = 'default',\n rtl = false,\n leadingText,\n trailingText,\n linkHref,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n tags,\n children,\n ...props\n },\n ref,\n ) => {\n const isRTL = rtl;\n\n // Size-based padding for display area\n const displayPaddingY = size === 'md' ? 'py-2.5' : 'py-2';\n\n // Determine container width based on type\n const containerWidth =\n type === 'tags' || type === 'avatar' || type === 'badge'\n ? 'w-[400px]'\n : 'w-[320px]';\n\n return (\n <div\n ref={ref}\n data-slot=\"display-value\"\n dir={isRTL ? 'rtl' : undefined}\n className={cn('flex flex-col gap-1.5', containerWidth, className)}\n {...props}\n >\n {/* Label section */}\n <DisplayValueLabel\n label={label}\n helpIcon={helpIcon}\n helpTooltip={helpTooltip}\n />\n\n {/* Display section */}\n <div\n data-slot=\"display-value-content\"\n className={cn(\n 'flex items-center gap-2 w-full rounded-md',\n // Only add vertical padding for non-special types\n type !== 'leading-text' &&\n type !== 'trailing-text' &&\n displayPaddingY,\n )}\n >\n <DisplayValueContent\n type={type}\n icon={icon}\n value={value}\n leadingText={leadingText}\n trailingText={trailingText}\n displayPaddingY={displayPaddingY}\n linkHref={linkHref}\n tags={tags}\n avatarProps={avatarProps}\n avatarSupportingText={avatarSupportingText}\n badgeProps={badgeProps}\n badgeLabel={badgeLabel}\n >\n {children}\n </DisplayValueContent>\n </div>\n\n {/* Hint section */}\n <DisplayValueHint hint={hint} />\n </div>\n );\n },\n);\n\nDisplayValue.displayName = 'DisplayValue';\n\nexport { DisplayValue };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index122.js","names":[],"sources":["../src/components/molecules/forms/DisplayValue/DisplayValue.tsx"],"sourcesContent":["import { HelpCircle } from 'lucide-react';\nimport * as React from 'react';\nimport { Badge, type BadgeProps } from '@/components/atoms/display/Badge';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\nexport type DisplayValueType =\n | 'default'\n | 'icon-leading'\n | 'trailing-text'\n | 'link'\n | 'tags'\n | 'leading-text'\n | 'avatar'\n | 'badge';\n\nexport interface DisplayValueTag\n extends Omit<BadgeProps, 'avatar' | 'children'> {\n label: string;\n avatar?: string;\n avatarAlt?: string;\n}\n\nexport interface DisplayValueProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Label text displayed above the field */\n label?: string;\n /** The main value to display */\n value?: React.ReactNode;\n /** Hint text displayed below the field */\n hint?: string;\n /** Show help icon with tooltip */\n helpIcon?: boolean;\n /** Tooltip content for help icon */\n helpTooltip?: string;\n /** Leading icon for icon-leading type */\n icon?: React.ReactNode;\n /** Size variant */\n size?: 'sm' | 'md';\n /** Display type */\n type?: DisplayValueType;\n /** RTL layout support */\n rtl?: boolean;\n /** Leading text (for leading-text type) */\n leadingText?: string;\n /** Trailing text (for trailing-text type) */\n trailingText?: string;\n /** Link URL (for link type) */\n linkHref?: string;\n /** Avatar props (for avatar type) */\n avatarProps?: AvatarProps;\n /** Supporting text for avatar */\n avatarSupportingText?: string;\n /** Badge props (for badge type) */\n badgeProps?: Omit<BadgeProps, 'children'>;\n /** Badge label (for badge type) */\n badgeLabel?: string;\n /** Tags data (for tags type) */\n tags?: DisplayValueTag[];\n}\n\ntype DisplayTag = NonNullable<DisplayValueProps['tags']>[number];\n\nfunction getDisplayTagKey(tag: DisplayTag): React.Key {\n return tag.id ?? `${tag.label}:${tag.avatarAlt ?? 'no-avatar'}`;\n}\n\nfunction DisplayValueBadge({ label, avatar, avatarAlt, ...props }: DisplayTag) {\n return (\n <Badge\n variant=\"outline\"\n shape=\"rounded\"\n size=\"md\"\n avatar={\n avatar ? (\n <Avatar\n src={avatar}\n alt={avatarAlt ?? ''}\n fallback={label}\n size=\"sm\"\n shape=\"circle\"\n />\n ) : undefined\n }\n {...props}\n >\n {label}\n </Badge>\n );\n}\n\ninterface DisplayValueLabelProps {\n label?: string;\n helpIcon: boolean;\n helpTooltip?: string;\n}\n\nfunction DisplayValueLabel({\n label,\n helpIcon,\n helpTooltip,\n}: DisplayValueLabelProps) {\n if (!label) return null;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <span className=\"text-sm font-medium leading-5 text-secondary-foreground\">\n {label}\n </span>\n {helpIcon && (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-secondary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none\"\n aria-label={helpTooltip || `Help for ${label}`}\n >\n <HelpCircle className=\"size-4\" />\n </button>\n }\n />\n <TooltipPopup>{helpTooltip || label}</TooltipPopup>\n </Tooltip>\n )}\n </div>\n );\n}\n\nfunction DisplayValueHint({ hint }: { hint?: string }) {\n if (!hint) return null;\n\n return (\n <p className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground w-full\">\n {hint}\n </p>\n );\n}\n\ninterface DisplayValueContentProps {\n type: DisplayValueType;\n icon?: React.ReactNode;\n value?: React.ReactNode;\n children?: React.ReactNode;\n leadingText?: string;\n trailingText?: string;\n displayPaddingY: string;\n linkHref?: string;\n tags?: DisplayValueProps['tags'];\n avatarProps?: AvatarProps;\n avatarSupportingText?: string;\n badgeProps?: Omit<BadgeProps, 'children'>;\n badgeLabel?: string;\n}\n\nfunction DisplayValueContent({\n type,\n icon,\n value,\n children,\n leadingText,\n trailingText,\n displayPaddingY,\n linkHref,\n tags,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n}: DisplayValueContentProps) {\n switch (type) {\n case 'icon-leading':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {icon && (\n <span className=\"shrink-0 text-muted-foreground [&>svg]:size-5\">\n {icon}\n </span>\n )}\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n );\n\n case 'leading-text':\n return (\n <div className=\"flex items-start w-full\">\n {leadingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap\">\n {leadingText}\n </span>\n </div>\n )}\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n 'ps-3',\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n </div>\n );\n\n case 'trailing-text':\n return (\n <div className=\"flex items-start w-full\">\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n {trailingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden px-3',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap\">\n {trailingText}\n </span>\n </div>\n )}\n </div>\n );\n\n case 'link':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {linkHref ? (\n <a\n href={linkHref}\n className=\"text-sm font-normal leading-5 text-primary hover:text-primary dark:text-primary dark:hover:text-primary truncate transition-colors duration-200 ease-smooth motion-reduce:transition-none hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {value ?? children ?? linkHref}\n </a>\n ) : (\n <span className=\"text-sm font-normal leading-5 text-primary dark:text-primary truncate\">\n {value ?? children}\n </span>\n )}\n </div>\n );\n\n case 'tags':\n return (\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n {tags?.map((tag) => (\n <DisplayValueBadge key={getDisplayTagKey(tag)} {...tag} />\n ))}\n {children}\n </div>\n );\n\n case 'avatar':\n return (\n <div className=\"flex items-center gap-2\">\n <Avatar size=\"lg\" {...avatarProps} />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold leading-5 text-foreground dark:text-foreground\">\n {value ?? children ?? avatarProps?.fallback}\n </span>\n {avatarSupportingText && (\n <span className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground\">\n {avatarSupportingText}\n </span>\n )}\n </div>\n </div>\n );\n\n case 'badge':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Badge variant=\"dot\" color=\"success\" {...badgeProps}>\n {badgeLabel ?? value ?? children}\n </Badge>\n </div>\n );\n\n default:\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children ?? (\n <span className=\"text-secondary-foreground italic\">—</span>\n )}\n </span>\n </div>\n );\n }\n}\n\nconst DisplayValue = React.forwardRef<HTMLDivElement, DisplayValueProps>(\n (\n {\n className,\n label,\n value,\n hint,\n helpIcon = false,\n helpTooltip,\n icon,\n size = 'sm',\n type = 'default',\n rtl = false,\n leadingText,\n trailingText,\n linkHref,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n tags,\n children,\n ...props\n },\n ref,\n ) => {\n const isRTL = rtl;\n\n // Size-based padding for display area\n const displayPaddingY = size === 'md' ? 'py-2.5' : 'py-2';\n\n // Determine container width based on type\n const containerWidth =\n type === 'tags' || type === 'avatar' || type === 'badge'\n ? 'w-[400px]'\n : 'w-[320px]';\n\n return (\n <div\n ref={ref}\n data-slot=\"display-value\"\n dir={isRTL ? 'rtl' : undefined}\n className={cn('flex flex-col gap-1.5', containerWidth, className)}\n {...props}\n >\n {/* Label section */}\n <DisplayValueLabel\n label={label}\n helpIcon={helpIcon}\n helpTooltip={helpTooltip}\n />\n\n {/* Display section */}\n <div\n data-slot=\"display-value-content\"\n className={cn(\n 'flex items-center gap-2 w-full rounded-md',\n // Only add vertical padding for non-special types\n type !== 'leading-text' &&\n type !== 'trailing-text' &&\n displayPaddingY,\n )}\n >\n <DisplayValueContent\n type={type}\n icon={icon}\n value={value}\n leadingText={leadingText}\n trailingText={trailingText}\n displayPaddingY={displayPaddingY}\n linkHref={linkHref}\n tags={tags}\n avatarProps={avatarProps}\n avatarSupportingText={avatarSupportingText}\n badgeProps={badgeProps}\n badgeLabel={badgeLabel}\n >\n {children}\n </DisplayValueContent>\n </div>\n\n {/* Hint section */}\n <DisplayValueHint hint={hint} />\n </div>\n );\n },\n);\n\nDisplayValue.displayName = 'DisplayValue';\n\nexport { DisplayValue };\n"],"mappings":";;;;;;;;AAgEA,SAAS,iBAAiB,KAA4B;CACpD,OAAO,IAAI,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,aAAa;AACpD;AAEA,SAAS,kBAAkB,EAAE,OAAO,QAAQ,WAAW,GAAG,SAAqB;CAC7E,OACE,oBAAC,OAAD;EACE,SAAQ;EACR,OAAM;EACN,MAAK;EACL,QACE,SACE,oBAAC,QAAD;GACE,KAAK;GACL,KAAK,aAAa;GAClB,UAAU;GACV,MAAK;GACL,OAAM;EACP,CAAA,IACC,KAAA;EAEN,GAAI;YAEH;CACI,CAAA;AAEX;AAQA,SAAS,kBAAkB,EACzB,OACA,UACA,eACyB;CACzB,IAAI,CAAC,OAAO,OAAO;CAEnB,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,GACL,YACC,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,gBAAD,EACE,QACE,oBAAC,UAAD;GACE,MAAK;GACL,WAAU;GACV,cAAY,eAAe,YAAY;aAEvC,oBAAC,YAAD,EAAY,WAAU,SAAU,CAAA;EAC1B,CAAA,EAEX,CAAA,GACD,oBAAC,cAAD,EAAA,UAAe,eAAe,MAAoB,CAAA,CAC3C,EAAA,CAAA,CAER;;AAET;AAEA,SAAS,iBAAiB,EAAE,QAA2B;CACrD,IAAI,CAAC,MAAM,OAAO;CAElB,OACE,oBAAC,KAAD;EAAG,WAAU;YACV;CACA,CAAA;AAEP;AAkBA,SAAS,oBAAoB,EAC3B,MACA,MACA,OACA,UACA,aACA,cACA,iBACA,UACA,MACA,aACA,sBACA,YACA,cAC2B;CAC3B,QAAQ,MAAR;EACE,KAAK,gBACH,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QACC,oBAAC,QAAD;IAAM,WAAU;cACb;GACG,CAAA,GAER,oBAAC,QAAD;IAAM,WAAU;cACb,SAAS;GACN,CAAA,CACH;;EAGT,KAAK,gBACH,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,eACC,oBAAC,OAAD;IACE,WAAW,GACT,2CACA,eACF;cAEA,oBAAC,QAAD;KAAM,WAAU;eACb;IACG,CAAA;GACH,CAAA,GAEP,oBAAC,OAAD;IACE,WAAW,GACT,0CACA,iBACA,MACF;cAEA,oBAAC,QAAD;KAAM,WAAU;eACb,SAAS;IACN,CAAA;GACH,CAAA,CACF;;EAGT,KAAK,iBACH,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,OAAD;IACE,WAAW,GACT,0CACA,eACF;cAEA,oBAAC,QAAD;KAAM,WAAU;eACb,SAAS;IACN,CAAA;GACH,CAAA,GACJ,gBACC,oBAAC,OAAD;IACE,WAAW,GACT,gDACA,eACF;cAEA,oBAAC,QAAD;KAAM,WAAU;eACb;IACG,CAAA;GACH,CAAA,CAEJ;;EAGT,KAAK,QACH,OACE,oBAAC,OAAD;GAAK,WAAU;aACZ,WACC,oBAAC,KAAD;IACE,MAAM;IACN,WAAU;IACV,QAAO;IACP,KAAI;cAEH,SAAS,YAAY;GACrB,CAAA,IAEH,oBAAC,QAAD;IAAM,WAAU;cACb,SAAS;GACN,CAAA;EAEL,CAAA;EAGT,KAAK,QACH,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,MAAM,KAAK,QACV,oBAAC,mBAAD,EAA+C,GAAI,IAAM,GAAjC,iBAAiB,GAAG,CAAa,CAC1D,GACA,QACE;;EAGT,KAAK,UACH,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,QAAD;IAAQ,MAAK;IAAK,GAAI;GAAc,CAAA,GACpC,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,QAAD;KAAM,WAAU;eACb,SAAS,YAAY,aAAa;IAC/B,CAAA,GACL,wBACC,oBAAC,QAAD;KAAM,WAAU;eACb;IACG,CAAA,CAEL;KACF;;EAGT,KAAK,SACH,OACE,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,OAAD;IAAO,SAAQ;IAAM,OAAM;IAAU,GAAI;cACtC,cAAc,SAAS;GACnB,CAAA;EACJ,CAAA;EAGT,SACE,OACE,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,QAAD;IAAM,WAAU;cACb,SAAS,YACR,oBAAC,QAAD;KAAM,WAAU;eAAmC;IAAO,CAAA;GAExD,CAAA;EACH,CAAA;CAEX;AACF;AAEA,IAAM,eAAe,QAAM,YAEvB,EACE,WACA,OACA,OACA,MACA,WAAW,OACX,aACA,MACA,OAAO,MACP,OAAO,WACP,MAAM,OACN,aACA,cACA,UACA,aACA,sBACA,YACA,YACA,MACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,QAAQ;CAGd,MAAM,kBAAkB,SAAS,OAAO,WAAW;CAQnD,OACE,qBAAC,OAAD;EACO;EACL,aAAU;EACV,KAAK,QAAQ,QAAQ,KAAA;EACrB,WAAW,GAAG,yBAThB,SAAS,UAAU,SAAS,YAAY,SAAS,UAC7C,cACA,aAOqD,SAAS;EAChE,GAAI;YALN;GAQE,oBAAC,mBAAD;IACS;IACG;IACG;GACd,CAAA;GAGD,oBAAC,OAAD;IACE,aAAU;IACV,WAAW,GACT,6CAEA,SAAS,kBACP,SAAS,mBACT,eACJ;cAEA,oBAAC,qBAAD;KACQ;KACA;KACC;KACM;KACC;KACG;KACP;KACJ;KACO;KACS;KACV;KACA;KAEX;IACkB,CAAA;GAClB,CAAA;GAGL,oBAAC,kBAAD,EAAwB,KAAO,CAAA;EAC5B;;AAET,CACF;AAEA,aAAa,cAAc"}
|
package/dist/index126.js
CHANGED
|
@@ -193,7 +193,7 @@ var RichTextarea = React$1.forwardRef(({ label, hint, error, required, showHelpI
|
|
|
193
193
|
showHelpIcon && /* @__PURE__ */ jsx("button", {
|
|
194
194
|
type: "button",
|
|
195
195
|
onClick: onHelpClick,
|
|
196
|
-
className: "text-muted-foreground hover:text-
|
|
196
|
+
className: "text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full",
|
|
197
197
|
"aria-label": "Help",
|
|
198
198
|
children: /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" })
|
|
199
199
|
})
|
package/dist/index126.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index126.js","names":[],"sources":["../src/components/molecules/forms/RichTextarea/RichTextarea.tsx"],"sourcesContent":["import {\n Bold,\n ChevronDown,\n Expand,\n HelpCircle,\n Italic,\n Link,\n List,\n MoreHorizontal,\n Paperclip,\n Redo2,\n Sparkles,\n Table,\n Type,\n Underline,\n Undo2,\n} from 'lucide-react';\nimport * as React from 'react';\nimport { Label } from '@/components/ui/label';\nimport { Separator } from '@/components/ui/separator';\nimport { Textarea as TextareaBase } from '@/components/ui/textarea';\nimport { Toggle } from '@/components/ui/toggle';\nimport { cn } from '@/lib/utils';\n\nconst DEFAULT_MAX_LENGTH = 3000;\n\nfunction getMaxLength(maxLength: number): number {\n return Number.isFinite(maxLength) && maxLength >= 0\n ? Math.floor(maxLength)\n : DEFAULT_MAX_LENGTH;\n}\n\nfunction getCharCount(charCount: number | undefined, fallback: number): number {\n return typeof charCount === 'number' &&\n Number.isFinite(charCount) &&\n charCount >= 0\n ? Math.floor(charCount)\n : fallback;\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Button\n// ---------------------------------------------------------------------------\n\ninterface ToolbarButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {\n icon: React.ReactNode;\n pressed?: boolean;\n hasDropdown?: boolean;\n}\n\nconst ToolbarButton = React.forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, pressed, hasDropdown, className, ...props }, ref) => {\n if (hasDropdown) {\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-haspopup=\"true\"\n className={cn(\n 'group/dropdown inline-flex h-8 items-center justify-center gap-1 rounded px-1.5 py-1 text-foreground transition-[color,background-color,transform] duration-200 ease-smooth motion-reduce:transition-none',\n 'hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'active:scale-95 motion-reduce:active:scale-100',\n 'disabled:pointer-events-none disabled:opacity-50',\n pressed && 'bg-muted',\n className,\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-4\">{icon}</span>\n <ChevronDown className=\"size-4 text-muted-foreground transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/dropdown:translate-y-0.5\" />\n </button>\n );\n }\n\n return (\n <Toggle\n ref={ref}\n pressed={pressed}\n size=\"sm\"\n className={className}\n disabled={props.disabled}\n onClick={props.onClick}\n aria-label={props['aria-label']}\n >\n <span className=\"[&>svg]:size-5\">{icon}</span>\n </Toggle>\n );\n },\n);\n\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Divider\n// ---------------------------------------------------------------------------\n\nfunction ToolbarDivider() {\n return (\n <Separator\n orientation=\"vertical\"\n className=\"mx-0.5 h-5 w-px bg-surface-2\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaToolbarProps {\n className?: string;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand/fullscreen button is clicked */\n onExpand?: () => void;\n /** Show AI assist button */\n showAiAssist?: boolean;\n /** Show expand button */\n showExpand?: boolean;\n /** Disabled state */\n disabled?: boolean;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nfunction RichTextareaToolbar({\n className,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n showAiAssist = true,\n showExpand = true,\n disabled,\n rtl,\n formatting = {},\n onFormatChange,\n}: RichTextareaToolbarProps) {\n return (\n <div\n data-slot=\"rich-textarea-toolbar\"\n role=\"toolbar\"\n aria-label=\"Formatting toolbar\"\n className={cn(\n 'flex flex-wrap items-center gap-2 rounded-t-xl border border-input border-b-0 bg-muted/30 p-2 transition-[border-color] duration-200 ease-smooth motion-reduce:transition-none group-has-[:focus-visible]/editor:border-ring group-has-[[aria-invalid=true]]/editor:border-destructive',\n rtl && 'flex-row-reverse',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* AI Assist */}\n {showAiAssist && (\n <>\n <ToolbarButton\n icon={\n <Sparkles className=\"size-5 text-primary transition-transform duration-300 ease-smooth motion-reduce:transition-none group-hover/toggle:rotate-12\" />\n }\n onClick={onAiAssist}\n disabled={disabled}\n aria-label=\"AI Assist\"\n />\n <ToolbarDivider />\n </>\n )}\n\n {/* Undo/Redo */}\n <div className=\"flex items-center gap-2\">\n <ToolbarButton\n icon={<Undo2 />}\n onClick={onUndo}\n disabled={disabled}\n aria-label=\"Undo\"\n />\n <ToolbarButton\n icon={<Redo2 />}\n onClick={onRedo}\n disabled={disabled}\n aria-label=\"Redo\"\n />\n </div>\n\n <ToolbarDivider />\n\n {/* Text formatting dropdown */}\n <ToolbarButton\n icon={<Type />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Text formatting\"\n />\n\n {/* Text color dropdown */}\n <ToolbarButton\n icon={\n <span className=\"relative\">\n <span className=\"text-sm font-bold\">A</span>\n <span className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-foreground\" />\n </span>\n }\n hasDropdown\n disabled={disabled}\n aria-label=\"Text color\"\n />\n\n {/* Bold/Italic/Underline */}\n <ToolbarButton\n icon={<Bold />}\n pressed={formatting.bold}\n onClick={() => onFormatChange?.('bold')}\n disabled={disabled}\n aria-label=\"Bold\"\n />\n <ToolbarButton\n icon={<Italic />}\n pressed={formatting.italic}\n onClick={() => onFormatChange?.('italic')}\n disabled={disabled}\n aria-label=\"Italic\"\n />\n <ToolbarButton\n icon={<Underline />}\n pressed={formatting.underline}\n onClick={() => onFormatChange?.('underline')}\n disabled={disabled}\n aria-label=\"Underline\"\n />\n\n {/* List dropdown */}\n <ToolbarButton\n icon={<List />}\n hasDropdown\n disabled={disabled}\n aria-label=\"List options\"\n />\n\n <ToolbarDivider />\n\n {/* Link */}\n <ToolbarButton\n icon={<Link />}\n disabled={disabled}\n aria-label=\"Insert link\"\n />\n\n {/* Table dropdown */}\n <ToolbarButton\n icon={<Table />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Table options\"\n />\n\n {/* Attachment */}\n <ToolbarButton\n icon={<Paperclip />}\n disabled={disabled}\n aria-label=\"Attach file\"\n />\n\n {/* More options */}\n <ToolbarButton\n icon={<MoreHorizontal />}\n disabled={disabled}\n aria-label=\"More options\"\n />\n\n {/* Expand */}\n {showExpand && (\n <ToolbarButton\n icon={\n <Expand className=\"transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/toggle:scale-110\" />\n }\n onClick={onExpand}\n disabled={disabled}\n aria-label=\"Expand\"\n className=\"ms-auto\"\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Component\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaProps\n extends Omit<React.ComponentProps<typeof TextareaBase>, 'children'> {\n /** Label text displayed above the editor */\n label?: string;\n /** Hint text displayed below the editor */\n hint?: string;\n /** Error message displayed below the editor */\n error?: string;\n /** Show required indicator */\n required?: boolean;\n /** Show help icon next to label */\n showHelpIcon?: boolean;\n /** Callback when help icon is clicked */\n onHelpClick?: () => void;\n /** Show character count */\n showCharCount?: boolean;\n /** Maximum character count */\n maxLength?: number;\n /** Current character count (controlled) */\n charCount?: number;\n /** Show resize handle */\n showResizeHandle?: boolean;\n /** Show AI assist button in toolbar */\n showAiAssist?: boolean;\n /** Show expand button in toolbar */\n showExpand?: boolean;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand button is clicked */\n onExpand?: () => void;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nconst RichTextarea = React.forwardRef<HTMLTextAreaElement, RichTextareaProps>(\n (\n {\n label,\n hint,\n error,\n required,\n showHelpIcon,\n onHelpClick,\n showCharCount,\n maxLength = DEFAULT_MAX_LENGTH,\n charCount,\n showResizeHandle = true,\n showAiAssist = true,\n showExpand = true,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n rtl,\n formatting,\n onFormatChange,\n className,\n disabled,\n id,\n value,\n defaultValue,\n onChange,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const textareaId = id || generatedId;\n const hintId = `${textareaId}-hint`;\n const errorId = `${textareaId}-error`;\n\n // Track character count internally if not controlled\n const [internalValue, setInternalValue] = React.useState(\n defaultValue?.toString() || '',\n );\n const currentValue = value !== undefined ? value.toString() : internalValue;\n const safeMaxLength = getMaxLength(maxLength);\n const currentCharCount = getCharCount(charCount, currentValue.length);\n const isNearLimit = currentCharCount >= safeMaxLength * 0.9;\n const isApproachingLimit = currentCharCount >= safeMaxLength * 0.75;\n let describedById: string | undefined;\n if (error) {\n describedById = errorId;\n } else if (hint) {\n describedById = hintId;\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (value === undefined) {\n setInternalValue(e.target.value);\n }\n onChange?.(e);\n };\n\n const isDestructive = !!error;\n\n return (\n <div\n data-slot=\"rich-textarea\"\n className={cn('flex flex-col gap-1.5 w-full', rtl && 'text-right')}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* Label */}\n {label && (\n <div\n className={cn(\n 'flex items-center gap-0.5',\n rtl && 'flex-row-reverse',\n )}\n >\n <Label\n htmlFor={textareaId}\n className=\"text-sm font-medium leading-5 text-secondary-foreground\"\n >\n {label}\n </Label>\n {required && (\n <span\n className=\"text-sm font-medium leading-5 text-destructive\"\n aria-hidden=\"true\"\n >\n *\n </span>\n )}\n {showHelpIcon && (\n <button\n type=\"button\"\n onClick={onHelpClick}\n className=\"text-muted-foreground hover:text-text-quaternary transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full\"\n aria-label=\"Help\"\n >\n <HelpCircle className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n\n {/* Toolbar + Textarea (gapless for connected borders) */}\n <div data-slot=\"rich-textarea-control\" className=\"group/editor\">\n <RichTextareaToolbar\n onAiAssist={onAiAssist}\n onUndo={onUndo}\n onRedo={onRedo}\n onExpand={onExpand}\n showAiAssist={showAiAssist}\n showExpand={showExpand}\n disabled={disabled}\n rtl={rtl}\n formatting={formatting}\n onFormatChange={onFormatChange}\n />\n\n <TextareaBase\n ref={ref}\n data-slot=\"rich-textarea-editor\"\n id={textareaId}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n disabled={disabled}\n aria-invalid={isDestructive}\n aria-required={required || undefined}\n aria-describedby={describedById}\n maxLength={safeMaxLength}\n className={cn(\n 'min-h-30 rounded-t-none border-t-0',\n isDestructive &&\n 'border-destructive focus-visible:border-destructive focus-visible:ring-destructive/20',\n !showResizeHandle && 'resize-none',\n rtl && 'text-right',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n {...props}\n />\n </div>\n\n {/* Hint/Error and Character Count */}\n <div\n className={cn(\n 'flex items-start gap-4 text-sm leading-5',\n rtl ? 'flex-row-reverse' : 'justify-between',\n )}\n >\n {/* Hint or error */}\n <div className=\"flex-1\">\n {error ? (\n <p\n id={errorId}\n className=\"text-destructive animate-in fade-in-0 slide-in-from-top-1 duration-200 motion-reduce:animate-none\"\n >\n {error}\n </p>\n ) : hint ? (\n <p id={hintId} className=\"text-muted-foreground\">\n {hint}\n </p>\n ) : null}\n </div>\n\n {/* Character count — only announces via aria-live when near the limit (≥90%) */}\n {showCharCount && (\n <span\n role={isNearLimit ? 'status' : undefined}\n aria-live={isNearLimit ? 'polite' : 'off'}\n className={cn(\n 'whitespace-nowrap transition-colors duration-300 ease-out motion-reduce:transition-none',\n isNearLimit\n ? 'text-destructive font-medium'\n : isApproachingLimit\n ? 'text-secondary-foreground'\n : 'text-muted-foreground',\n rtl && 'text-start',\n )}\n >\n {currentCharCount}/{safeMaxLength}\n </span>\n )}\n </div>\n </div>\n );\n },\n);\n\nRichTextarea.displayName = 'RichTextarea';\n\nexport { RichTextarea, RichTextareaToolbar, ToolbarButton, ToolbarDivider };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index126.js","names":[],"sources":["../src/components/molecules/forms/RichTextarea/RichTextarea.tsx"],"sourcesContent":["import {\n Bold,\n ChevronDown,\n Expand,\n HelpCircle,\n Italic,\n Link,\n List,\n MoreHorizontal,\n Paperclip,\n Redo2,\n Sparkles,\n Table,\n Type,\n Underline,\n Undo2,\n} from 'lucide-react';\nimport * as React from 'react';\nimport { Label } from '@/components/ui/label';\nimport { Separator } from '@/components/ui/separator';\nimport { Textarea as TextareaBase } from '@/components/ui/textarea';\nimport { Toggle } from '@/components/ui/toggle';\nimport { cn } from '@/lib/utils';\n\nconst DEFAULT_MAX_LENGTH = 3000;\n\nfunction getMaxLength(maxLength: number): number {\n return Number.isFinite(maxLength) && maxLength >= 0\n ? Math.floor(maxLength)\n : DEFAULT_MAX_LENGTH;\n}\n\nfunction getCharCount(charCount: number | undefined, fallback: number): number {\n return typeof charCount === 'number' &&\n Number.isFinite(charCount) &&\n charCount >= 0\n ? Math.floor(charCount)\n : fallback;\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Button\n// ---------------------------------------------------------------------------\n\ninterface ToolbarButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {\n icon: React.ReactNode;\n pressed?: boolean;\n hasDropdown?: boolean;\n}\n\nconst ToolbarButton = React.forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, pressed, hasDropdown, className, ...props }, ref) => {\n if (hasDropdown) {\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-haspopup=\"true\"\n className={cn(\n 'group/dropdown inline-flex h-8 items-center justify-center gap-1 rounded px-1.5 py-1 text-foreground transition-[color,background-color,transform] duration-200 ease-smooth motion-reduce:transition-none',\n 'hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'active:scale-95 motion-reduce:active:scale-100',\n 'disabled:pointer-events-none disabled:opacity-50',\n pressed && 'bg-muted',\n className,\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-4\">{icon}</span>\n <ChevronDown className=\"size-4 text-muted-foreground transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/dropdown:translate-y-0.5\" />\n </button>\n );\n }\n\n return (\n <Toggle\n ref={ref}\n pressed={pressed}\n size=\"sm\"\n className={className}\n disabled={props.disabled}\n onClick={props.onClick}\n aria-label={props['aria-label']}\n >\n <span className=\"[&>svg]:size-5\">{icon}</span>\n </Toggle>\n );\n },\n);\n\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Divider\n// ---------------------------------------------------------------------------\n\nfunction ToolbarDivider() {\n return (\n <Separator\n orientation=\"vertical\"\n className=\"mx-0.5 h-5 w-px bg-surface-2\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaToolbarProps {\n className?: string;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand/fullscreen button is clicked */\n onExpand?: () => void;\n /** Show AI assist button */\n showAiAssist?: boolean;\n /** Show expand button */\n showExpand?: boolean;\n /** Disabled state */\n disabled?: boolean;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nfunction RichTextareaToolbar({\n className,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n showAiAssist = true,\n showExpand = true,\n disabled,\n rtl,\n formatting = {},\n onFormatChange,\n}: RichTextareaToolbarProps) {\n return (\n <div\n data-slot=\"rich-textarea-toolbar\"\n role=\"toolbar\"\n aria-label=\"Formatting toolbar\"\n className={cn(\n 'flex flex-wrap items-center gap-2 rounded-t-xl border border-input border-b-0 bg-muted/30 p-2 transition-[border-color] duration-200 ease-smooth motion-reduce:transition-none group-has-[:focus-visible]/editor:border-ring group-has-[[aria-invalid=true]]/editor:border-destructive',\n rtl && 'flex-row-reverse',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* AI Assist */}\n {showAiAssist && (\n <>\n <ToolbarButton\n icon={\n <Sparkles className=\"size-5 text-primary transition-transform duration-300 ease-smooth motion-reduce:transition-none group-hover/toggle:rotate-12\" />\n }\n onClick={onAiAssist}\n disabled={disabled}\n aria-label=\"AI Assist\"\n />\n <ToolbarDivider />\n </>\n )}\n\n {/* Undo/Redo */}\n <div className=\"flex items-center gap-2\">\n <ToolbarButton\n icon={<Undo2 />}\n onClick={onUndo}\n disabled={disabled}\n aria-label=\"Undo\"\n />\n <ToolbarButton\n icon={<Redo2 />}\n onClick={onRedo}\n disabled={disabled}\n aria-label=\"Redo\"\n />\n </div>\n\n <ToolbarDivider />\n\n {/* Text formatting dropdown */}\n <ToolbarButton\n icon={<Type />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Text formatting\"\n />\n\n {/* Text color dropdown */}\n <ToolbarButton\n icon={\n <span className=\"relative\">\n <span className=\"text-sm font-bold\">A</span>\n <span className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-foreground\" />\n </span>\n }\n hasDropdown\n disabled={disabled}\n aria-label=\"Text color\"\n />\n\n {/* Bold/Italic/Underline */}\n <ToolbarButton\n icon={<Bold />}\n pressed={formatting.bold}\n onClick={() => onFormatChange?.('bold')}\n disabled={disabled}\n aria-label=\"Bold\"\n />\n <ToolbarButton\n icon={<Italic />}\n pressed={formatting.italic}\n onClick={() => onFormatChange?.('italic')}\n disabled={disabled}\n aria-label=\"Italic\"\n />\n <ToolbarButton\n icon={<Underline />}\n pressed={formatting.underline}\n onClick={() => onFormatChange?.('underline')}\n disabled={disabled}\n aria-label=\"Underline\"\n />\n\n {/* List dropdown */}\n <ToolbarButton\n icon={<List />}\n hasDropdown\n disabled={disabled}\n aria-label=\"List options\"\n />\n\n <ToolbarDivider />\n\n {/* Link */}\n <ToolbarButton\n icon={<Link />}\n disabled={disabled}\n aria-label=\"Insert link\"\n />\n\n {/* Table dropdown */}\n <ToolbarButton\n icon={<Table />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Table options\"\n />\n\n {/* Attachment */}\n <ToolbarButton\n icon={<Paperclip />}\n disabled={disabled}\n aria-label=\"Attach file\"\n />\n\n {/* More options */}\n <ToolbarButton\n icon={<MoreHorizontal />}\n disabled={disabled}\n aria-label=\"More options\"\n />\n\n {/* Expand */}\n {showExpand && (\n <ToolbarButton\n icon={\n <Expand className=\"transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/toggle:scale-110\" />\n }\n onClick={onExpand}\n disabled={disabled}\n aria-label=\"Expand\"\n className=\"ms-auto\"\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Component\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaProps\n extends Omit<React.ComponentProps<typeof TextareaBase>, 'children'> {\n /** Label text displayed above the editor */\n label?: string;\n /** Hint text displayed below the editor */\n hint?: string;\n /** Error message displayed below the editor */\n error?: string;\n /** Show required indicator */\n required?: boolean;\n /** Show help icon next to label */\n showHelpIcon?: boolean;\n /** Callback when help icon is clicked */\n onHelpClick?: () => void;\n /** Show character count */\n showCharCount?: boolean;\n /** Maximum character count */\n maxLength?: number;\n /** Current character count (controlled) */\n charCount?: number;\n /** Show resize handle */\n showResizeHandle?: boolean;\n /** Show AI assist button in toolbar */\n showAiAssist?: boolean;\n /** Show expand button in toolbar */\n showExpand?: boolean;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand button is clicked */\n onExpand?: () => void;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nconst RichTextarea = React.forwardRef<HTMLTextAreaElement, RichTextareaProps>(\n (\n {\n label,\n hint,\n error,\n required,\n showHelpIcon,\n onHelpClick,\n showCharCount,\n maxLength = DEFAULT_MAX_LENGTH,\n charCount,\n showResizeHandle = true,\n showAiAssist = true,\n showExpand = true,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n rtl,\n formatting,\n onFormatChange,\n className,\n disabled,\n id,\n value,\n defaultValue,\n onChange,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const textareaId = id || generatedId;\n const hintId = `${textareaId}-hint`;\n const errorId = `${textareaId}-error`;\n\n // Track character count internally if not controlled\n const [internalValue, setInternalValue] = React.useState(\n defaultValue?.toString() || '',\n );\n const currentValue = value !== undefined ? value.toString() : internalValue;\n const safeMaxLength = getMaxLength(maxLength);\n const currentCharCount = getCharCount(charCount, currentValue.length);\n const isNearLimit = currentCharCount >= safeMaxLength * 0.9;\n const isApproachingLimit = currentCharCount >= safeMaxLength * 0.75;\n let describedById: string | undefined;\n if (error) {\n describedById = errorId;\n } else if (hint) {\n describedById = hintId;\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (value === undefined) {\n setInternalValue(e.target.value);\n }\n onChange?.(e);\n };\n\n const isDestructive = !!error;\n\n return (\n <div\n data-slot=\"rich-textarea\"\n className={cn('flex flex-col gap-1.5 w-full', rtl && 'text-right')}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* Label */}\n {label && (\n <div\n className={cn(\n 'flex items-center gap-0.5',\n rtl && 'flex-row-reverse',\n )}\n >\n <Label\n htmlFor={textareaId}\n className=\"text-sm font-medium leading-5 text-secondary-foreground\"\n >\n {label}\n </Label>\n {required && (\n <span\n className=\"text-sm font-medium leading-5 text-destructive\"\n aria-hidden=\"true\"\n >\n *\n </span>\n )}\n {showHelpIcon && (\n <button\n type=\"button\"\n onClick={onHelpClick}\n className=\"text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full\"\n aria-label=\"Help\"\n >\n <HelpCircle className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n\n {/* Toolbar + Textarea (gapless for connected borders) */}\n <div data-slot=\"rich-textarea-control\" className=\"group/editor\">\n <RichTextareaToolbar\n onAiAssist={onAiAssist}\n onUndo={onUndo}\n onRedo={onRedo}\n onExpand={onExpand}\n showAiAssist={showAiAssist}\n showExpand={showExpand}\n disabled={disabled}\n rtl={rtl}\n formatting={formatting}\n onFormatChange={onFormatChange}\n />\n\n <TextareaBase\n ref={ref}\n data-slot=\"rich-textarea-editor\"\n id={textareaId}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n disabled={disabled}\n aria-invalid={isDestructive}\n aria-required={required || undefined}\n aria-describedby={describedById}\n maxLength={safeMaxLength}\n className={cn(\n 'min-h-30 rounded-t-none border-t-0',\n isDestructive &&\n 'border-destructive focus-visible:border-destructive focus-visible:ring-destructive/20',\n !showResizeHandle && 'resize-none',\n rtl && 'text-right',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n {...props}\n />\n </div>\n\n {/* Hint/Error and Character Count */}\n <div\n className={cn(\n 'flex items-start gap-4 text-sm leading-5',\n rtl ? 'flex-row-reverse' : 'justify-between',\n )}\n >\n {/* Hint or error */}\n <div className=\"flex-1\">\n {error ? (\n <p\n id={errorId}\n className=\"text-destructive animate-in fade-in-0 slide-in-from-top-1 duration-200 motion-reduce:animate-none\"\n >\n {error}\n </p>\n ) : hint ? (\n <p id={hintId} className=\"text-muted-foreground\">\n {hint}\n </p>\n ) : null}\n </div>\n\n {/* Character count — only announces via aria-live when near the limit (≥90%) */}\n {showCharCount && (\n <span\n role={isNearLimit ? 'status' : undefined}\n aria-live={isNearLimit ? 'polite' : 'off'}\n className={cn(\n 'whitespace-nowrap transition-colors duration-300 ease-out motion-reduce:transition-none',\n isNearLimit\n ? 'text-destructive font-medium'\n : isApproachingLimit\n ? 'text-secondary-foreground'\n : 'text-muted-foreground',\n rtl && 'text-start',\n )}\n >\n {currentCharCount}/{safeMaxLength}\n </span>\n )}\n </div>\n </div>\n );\n },\n);\n\nRichTextarea.displayName = 'RichTextarea';\n\nexport { RichTextarea, RichTextareaToolbar, ToolbarButton, ToolbarDivider };\n"],"mappings":"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"}
|
package/dist/index130.js
CHANGED
|
@@ -104,7 +104,7 @@ function BreadcrumbSeparator({ className, type, ...props }) {
|
|
|
104
104
|
const { separator } = useBreadcrumbContext();
|
|
105
105
|
const separatorType = type ?? separator;
|
|
106
106
|
return /* @__PURE__ */ jsx(BreadcrumbSeparator$1, {
|
|
107
|
-
className: cn("[&>svg]:size-3.5 text-
|
|
107
|
+
className: cn("[&>svg]:size-3.5 text-muted-foreground transition-opacity duration-200 ease-out motion-reduce:transition-none", className),
|
|
108
108
|
...props,
|
|
109
109
|
children: separatorType === "slash" ? /* @__PURE__ */ jsx(Slash, {}) : /* @__PURE__ */ jsx(ChevronRight, { className: "rtl:rotate-180" })
|
|
110
110
|
});
|
|
@@ -124,7 +124,7 @@ function BreadcrumbEllipsis({ className, variant = "text", ...props }) {
|
|
|
124
124
|
}
|
|
125
125
|
function BreadcrumbHomeLink({ className, variant = "text", srLabel = "Home", ...props }) {
|
|
126
126
|
return /* @__PURE__ */ jsxs(BreadcrumbLink$1, {
|
|
127
|
-
className: cn(`group inline-flex items-center text-
|
|
127
|
+
className: cn(`group inline-flex items-center text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`, variant === "soft-badge" && "rounded-full px-1.5 py-0.5 bg-primary/10 text-primary", variant === "outline-badge" && "rounded-full px-1.5 py-0.5 border border-muted-foreground/50", className),
|
|
128
128
|
...props,
|
|
129
129
|
children: [/* @__PURE__ */ jsx(Home, { className: "size-3.5 transition-transform duration-200 ease-out group-hover:scale-110 motion-reduce:transition-none" }), /* @__PURE__ */ jsx("span", {
|
|
130
130
|
className: "sr-only",
|
package/dist/index130.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index130.js","names":[],"sources":["../src/components/molecules/navigation/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["/** biome-ignore-all lint/a11y/useFocusableInteractive: BreadcrumbPage intentionally uses aria-disabled=\"true\" for current page, removing it from tab order */\n/** biome-ignore-all lint/a11y/useSemanticElements: BreadcrumbPage uses span with role=\"link\" for non-interactive current page indicator per WAI-ARIA breadcrumb pattern */\nimport { cva } from 'class-variance-authority';\nimport { ChevronRight, Home, Slash } from 'lucide-react';\nimport * as React from 'react';\nimport {\n Breadcrumb as BreadcrumbBase,\n BreadcrumbItem as BreadcrumbItemBase,\n BreadcrumbLink as BreadcrumbLinkBase,\n BreadcrumbList as BreadcrumbListBase,\n BreadcrumbPage as BreadcrumbPageBase,\n BreadcrumbSeparator as BreadcrumbSeparatorBase,\n} from '@/components/ui/breadcrumb';\nimport { cn } from '@/lib/utils';\n\nconst FOCUS_RING =\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-sm';\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Variants\n * -------------------------------------------------------------------------- */\n\nconst breadcrumbItemVariants = cva(\n 'inline-flex items-center transition-[color,opacity,background-color,border-color,text-decoration-color] duration-200 ease-out whitespace-nowrap relative before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:min-h-11 before:content-[\"\"] sm:before:content-none motion-reduce:transition-none',\n {\n variants: {\n variant: {\n text: 'text-sm font-normal text-muted-foreground hover:text-foreground underline decoration-transparent underline-offset-4 hover:decoration-current/30',\n 'soft-badge':\n 'text-xs font-normal text-primary rounded-full px-2 py-0.5 bg-primary/10 hover:bg-primary/15',\n 'outline-badge':\n 'text-xs font-normal text-foreground rounded-full px-2 py-0.5 border border-muted-foreground/50 hover:border-muted-foreground',\n },\n isCurrent: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n {\n variant: 'text',\n isCurrent: true,\n className: 'text-foreground no-underline',\n },\n {\n variant: 'text',\n isCurrent: false,\n className: 'text-muted-foreground',\n },\n {\n variant: 'soft-badge',\n isCurrent: true,\n className: 'bg-primary/10',\n },\n {\n variant: 'soft-badge',\n isCurrent: false,\n className: 'bg-primary/10 opacity-50',\n },\n {\n variant: 'outline-badge',\n isCurrent: true,\n className: 'border-primary text-foreground',\n },\n {\n variant: 'outline-badge',\n isCurrent: false,\n className: 'border-muted-foreground/50 opacity-50',\n },\n ],\n defaultVariants: {\n variant: 'text',\n isCurrent: false,\n },\n },\n);\n\n/* -----------------------------------------------------------------------------\n * Context for sharing separator type\n * -------------------------------------------------------------------------- */\n\ntype SeparatorType = 'chevron' | 'slash';\n\ntype BreadcrumbContextValue = {\n separator: SeparatorType;\n};\n\nconst BreadcrumbContext = React.createContext<BreadcrumbContextValue>({\n separator: 'chevron',\n});\n\nconst useBreadcrumbContext = () => React.useContext(BreadcrumbContext);\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbProps\n extends React.ComponentProps<typeof BreadcrumbBase> {\n separator?: SeparatorType;\n ring?: boolean;\n}\n\nfunction Breadcrumb({\n className,\n separator = 'chevron',\n ring = false,\n children,\n ...props\n}: BreadcrumbProps) {\n const contextValue = React.useMemo(() => ({ separator }), [separator]);\n\n return (\n <BreadcrumbContext.Provider value={contextValue}>\n <BreadcrumbBase\n className={cn(\n ring &&\n 'inline-flex border border-ring/50 rounded-full px-2.5 py-0.5',\n className,\n )}\n {...props}\n >\n {children}\n </BreadcrumbBase>\n </BreadcrumbContext.Provider>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbList Component\n * -------------------------------------------------------------------------- */\n\nexport type BreadcrumbListProps = React.ComponentProps<\n typeof BreadcrumbListBase\n>;\n\nfunction BreadcrumbList({ className, ...props }: BreadcrumbListProps) {\n return (\n <BreadcrumbListBase\n className={cn('flex-nowrap gap-1', className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbItem Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbItemProps\n extends Omit<React.ComponentProps<typeof BreadcrumbItemBase>, 'className'> {\n className?: string;\n}\n\nfunction BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {\n return <BreadcrumbItemBase className={cn('gap-1', className)} {...props} />;\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbLink Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbLinkProps\n extends React.ComponentProps<typeof BreadcrumbLinkBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n isCurrent?: boolean;\n}\n\nfunction BreadcrumbLink({\n className,\n variant = 'text',\n isCurrent = false,\n ...props\n}: BreadcrumbLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(breadcrumbItemVariants({ variant, isCurrent }), className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbPage Component (Current Page)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbPageProps\n extends React.ComponentProps<typeof BreadcrumbPageBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbPage({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbPageProps) {\n return (\n <BreadcrumbPageBase\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: true }),\n className,\n )}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbSeparator Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbSeparatorProps\n extends Omit<\n React.ComponentProps<typeof BreadcrumbSeparatorBase>,\n 'children'\n > {\n type?: SeparatorType;\n}\n\nfunction BreadcrumbSeparator({\n className,\n type,\n ...props\n}: BreadcrumbSeparatorProps) {\n const { separator } = useBreadcrumbContext();\n const separatorType = type ?? separator;\n\n return (\n <BreadcrumbSeparatorBase\n className={cn(\n '[&>svg]:size-3.5 text-text-quaternary transition-opacity duration-200 ease-out motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {separatorType === 'slash' ? (\n <Slash />\n ) : (\n <ChevronRight className=\"rtl:rotate-180\" />\n )}\n </BreadcrumbSeparatorBase>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbEllipsis Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbEllipsisProps\n extends React.ComponentProps<'button'> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbEllipsis({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbEllipsisProps) {\n return (\n <button\n type=\"button\"\n data-slot=\"breadcrumb-ellipsis\"\n aria-label=\"Show more breadcrumb items\"\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: false }),\n `cursor-pointer hover:text-foreground ${FOCUS_RING}`,\n className,\n )}\n {...props}\n >\n …\n </button>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbHomeLink Component (Home Icon)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbHomeLinkProps\n extends Omit<BreadcrumbLinkProps, 'children'> {\n srLabel?: string;\n}\n\nfunction BreadcrumbHomeLink({\n className,\n variant = 'text',\n srLabel = 'Home',\n ...props\n}: BreadcrumbHomeLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(\n `group inline-flex items-center text-text-quaternary hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`,\n variant === 'soft-badge' &&\n 'rounded-full px-1.5 py-0.5 bg-primary/10 text-primary',\n variant === 'outline-badge' &&\n 'rounded-full px-1.5 py-0.5 border border-muted-foreground/50',\n className,\n )}\n {...props}\n >\n <Home className=\"size-3.5 transition-transform duration-200 ease-out group-hover:scale-110 motion-reduce:transition-none\" />\n <span className=\"sr-only\">{srLabel}</span>\n </BreadcrumbLinkBase>\n );\n}\n\nBreadcrumb.displayName = 'Breadcrumb';\nBreadcrumbList.displayName = 'BreadcrumbList';\nBreadcrumbItem.displayName = 'BreadcrumbItem';\nBreadcrumbLink.displayName = 'BreadcrumbLink';\nBreadcrumbPage.displayName = 'BreadcrumbPage';\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\nBreadcrumbHomeLink.displayName = 'BreadcrumbHomeLink';\n\n/**\n * Breadcrumb component with dot notation for compound parts.\n *\n * @example\n * ```tsx\n * <Breadcrumb>\n * <Breadcrumb.List>\n * <Breadcrumb.Item>\n * <Breadcrumb.Link href=\"/\">Home</Breadcrumb.Link>\n * </Breadcrumb.Item>\n * <Breadcrumb.Separator />\n * <Breadcrumb.Item>\n * <Breadcrumb.Page>Current</Breadcrumb.Page>\n * </Breadcrumb.Item>\n * </Breadcrumb.List>\n * </Breadcrumb>\n * ```\n */\nconst BreadcrumbCompound = Object.assign(Breadcrumb, {\n Root: Breadcrumb,\n List: BreadcrumbList,\n Item: BreadcrumbItem,\n Link: BreadcrumbLink,\n Page: BreadcrumbPage,\n Separator: BreadcrumbSeparator,\n Ellipsis: BreadcrumbEllipsis,\n HomeLink: BreadcrumbHomeLink,\n});\n\nexport {\n BreadcrumbCompound as Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbHomeLink,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n breadcrumbItemVariants,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index130.js","names":[],"sources":["../src/components/molecules/navigation/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["/** biome-ignore-all lint/a11y/useFocusableInteractive: BreadcrumbPage intentionally uses aria-disabled=\"true\" for current page, removing it from tab order */\n/** biome-ignore-all lint/a11y/useSemanticElements: BreadcrumbPage uses span with role=\"link\" for non-interactive current page indicator per WAI-ARIA breadcrumb pattern */\nimport { cva } from 'class-variance-authority';\nimport { ChevronRight, Home, Slash } from 'lucide-react';\nimport * as React from 'react';\nimport {\n Breadcrumb as BreadcrumbBase,\n BreadcrumbItem as BreadcrumbItemBase,\n BreadcrumbLink as BreadcrumbLinkBase,\n BreadcrumbList as BreadcrumbListBase,\n BreadcrumbPage as BreadcrumbPageBase,\n BreadcrumbSeparator as BreadcrumbSeparatorBase,\n} from '@/components/ui/breadcrumb';\nimport { cn } from '@/lib/utils';\n\nconst FOCUS_RING =\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-sm';\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Variants\n * -------------------------------------------------------------------------- */\n\nconst breadcrumbItemVariants = cva(\n 'inline-flex items-center transition-[color,opacity,background-color,border-color,text-decoration-color] duration-200 ease-out whitespace-nowrap relative before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:min-h-11 before:content-[\"\"] sm:before:content-none motion-reduce:transition-none',\n {\n variants: {\n variant: {\n text: 'text-sm font-normal text-muted-foreground hover:text-foreground underline decoration-transparent underline-offset-4 hover:decoration-current/30',\n 'soft-badge':\n 'text-xs font-normal text-primary rounded-full px-2 py-0.5 bg-primary/10 hover:bg-primary/15',\n 'outline-badge':\n 'text-xs font-normal text-foreground rounded-full px-2 py-0.5 border border-muted-foreground/50 hover:border-muted-foreground',\n },\n isCurrent: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n {\n variant: 'text',\n isCurrent: true,\n className: 'text-foreground no-underline',\n },\n {\n variant: 'text',\n isCurrent: false,\n className: 'text-muted-foreground',\n },\n {\n variant: 'soft-badge',\n isCurrent: true,\n className: 'bg-primary/10',\n },\n {\n variant: 'soft-badge',\n isCurrent: false,\n className: 'bg-primary/10 opacity-50',\n },\n {\n variant: 'outline-badge',\n isCurrent: true,\n className: 'border-primary text-foreground',\n },\n {\n variant: 'outline-badge',\n isCurrent: false,\n className: 'border-muted-foreground/50 opacity-50',\n },\n ],\n defaultVariants: {\n variant: 'text',\n isCurrent: false,\n },\n },\n);\n\n/* -----------------------------------------------------------------------------\n * Context for sharing separator type\n * -------------------------------------------------------------------------- */\n\ntype SeparatorType = 'chevron' | 'slash';\n\ntype BreadcrumbContextValue = {\n separator: SeparatorType;\n};\n\nconst BreadcrumbContext = React.createContext<BreadcrumbContextValue>({\n separator: 'chevron',\n});\n\nconst useBreadcrumbContext = () => React.useContext(BreadcrumbContext);\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbProps\n extends React.ComponentProps<typeof BreadcrumbBase> {\n separator?: SeparatorType;\n ring?: boolean;\n}\n\nfunction Breadcrumb({\n className,\n separator = 'chevron',\n ring = false,\n children,\n ...props\n}: BreadcrumbProps) {\n const contextValue = React.useMemo(() => ({ separator }), [separator]);\n\n return (\n <BreadcrumbContext.Provider value={contextValue}>\n <BreadcrumbBase\n className={cn(\n ring &&\n 'inline-flex border border-ring/50 rounded-full px-2.5 py-0.5',\n className,\n )}\n {...props}\n >\n {children}\n </BreadcrumbBase>\n </BreadcrumbContext.Provider>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbList Component\n * -------------------------------------------------------------------------- */\n\nexport type BreadcrumbListProps = React.ComponentProps<\n typeof BreadcrumbListBase\n>;\n\nfunction BreadcrumbList({ className, ...props }: BreadcrumbListProps) {\n return (\n <BreadcrumbListBase\n className={cn('flex-nowrap gap-1', className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbItem Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbItemProps\n extends Omit<React.ComponentProps<typeof BreadcrumbItemBase>, 'className'> {\n className?: string;\n}\n\nfunction BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {\n return <BreadcrumbItemBase className={cn('gap-1', className)} {...props} />;\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbLink Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbLinkProps\n extends React.ComponentProps<typeof BreadcrumbLinkBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n isCurrent?: boolean;\n}\n\nfunction BreadcrumbLink({\n className,\n variant = 'text',\n isCurrent = false,\n ...props\n}: BreadcrumbLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(breadcrumbItemVariants({ variant, isCurrent }), className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbPage Component (Current Page)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbPageProps\n extends React.ComponentProps<typeof BreadcrumbPageBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbPage({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbPageProps) {\n return (\n <BreadcrumbPageBase\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: true }),\n className,\n )}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbSeparator Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbSeparatorProps\n extends Omit<\n React.ComponentProps<typeof BreadcrumbSeparatorBase>,\n 'children'\n > {\n type?: SeparatorType;\n}\n\nfunction BreadcrumbSeparator({\n className,\n type,\n ...props\n}: BreadcrumbSeparatorProps) {\n const { separator } = useBreadcrumbContext();\n const separatorType = type ?? separator;\n\n return (\n <BreadcrumbSeparatorBase\n className={cn(\n '[&>svg]:size-3.5 text-muted-foreground transition-opacity duration-200 ease-out motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {separatorType === 'slash' ? (\n <Slash />\n ) : (\n <ChevronRight className=\"rtl:rotate-180\" />\n )}\n </BreadcrumbSeparatorBase>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbEllipsis Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbEllipsisProps\n extends React.ComponentProps<'button'> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbEllipsis({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbEllipsisProps) {\n return (\n <button\n type=\"button\"\n data-slot=\"breadcrumb-ellipsis\"\n aria-label=\"Show more breadcrumb items\"\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: false }),\n `cursor-pointer hover:text-foreground ${FOCUS_RING}`,\n className,\n )}\n {...props}\n >\n …\n </button>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbHomeLink Component (Home Icon)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbHomeLinkProps\n extends Omit<BreadcrumbLinkProps, 'children'> {\n srLabel?: string;\n}\n\nfunction BreadcrumbHomeLink({\n className,\n variant = 'text',\n srLabel = 'Home',\n ...props\n}: BreadcrumbHomeLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(\n `group inline-flex items-center text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`,\n variant === 'soft-badge' &&\n 'rounded-full px-1.5 py-0.5 bg-primary/10 text-primary',\n variant === 'outline-badge' &&\n 'rounded-full px-1.5 py-0.5 border border-muted-foreground/50',\n className,\n )}\n {...props}\n >\n <Home className=\"size-3.5 transition-transform duration-200 ease-out group-hover:scale-110 motion-reduce:transition-none\" />\n <span className=\"sr-only\">{srLabel}</span>\n </BreadcrumbLinkBase>\n );\n}\n\nBreadcrumb.displayName = 'Breadcrumb';\nBreadcrumbList.displayName = 'BreadcrumbList';\nBreadcrumbItem.displayName = 'BreadcrumbItem';\nBreadcrumbLink.displayName = 'BreadcrumbLink';\nBreadcrumbPage.displayName = 'BreadcrumbPage';\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\nBreadcrumbHomeLink.displayName = 'BreadcrumbHomeLink';\n\n/**\n * Breadcrumb component with dot notation for compound parts.\n *\n * @example\n * ```tsx\n * <Breadcrumb>\n * <Breadcrumb.List>\n * <Breadcrumb.Item>\n * <Breadcrumb.Link href=\"/\">Home</Breadcrumb.Link>\n * </Breadcrumb.Item>\n * <Breadcrumb.Separator />\n * <Breadcrumb.Item>\n * <Breadcrumb.Page>Current</Breadcrumb.Page>\n * </Breadcrumb.Item>\n * </Breadcrumb.List>\n * </Breadcrumb>\n * ```\n */\nconst BreadcrumbCompound = Object.assign(Breadcrumb, {\n Root: Breadcrumb,\n List: BreadcrumbList,\n Item: BreadcrumbItem,\n Link: BreadcrumbLink,\n Page: BreadcrumbPage,\n Separator: BreadcrumbSeparator,\n Ellipsis: BreadcrumbEllipsis,\n HomeLink: BreadcrumbHomeLink,\n});\n\nexport {\n BreadcrumbCompound as Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbHomeLink,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n breadcrumbItemVariants,\n};\n"],"mappings":"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"}
|
package/dist/index146.js
CHANGED
|
@@ -34,7 +34,7 @@ function AICodeBlockHeader({ language, fileName, showCopyButton = true, onCopy,
|
|
|
34
34
|
className: "text-sm font-medium text-secondary-foreground",
|
|
35
35
|
children: fileName
|
|
36
36
|
}), language && !fileName && /* @__PURE__ */ jsx("span", {
|
|
37
|
-
className: "text-xs font-medium text-
|
|
37
|
+
className: "text-xs font-medium text-secondary-foreground uppercase",
|
|
38
38
|
children: language
|
|
39
39
|
})]
|
|
40
40
|
}), /* @__PURE__ */ jsxs("div", {
|
|
@@ -45,7 +45,7 @@ function AICodeBlockHeader({ language, fileName, showCopyButton = true, onCopy,
|
|
|
45
45
|
size: "sm",
|
|
46
46
|
onClick: onCopy,
|
|
47
47
|
"aria-label": copied ? "Copied to clipboard" : "Copy code to clipboard",
|
|
48
|
-
className: "h-7 px-2 text-
|
|
48
|
+
className: "h-7 px-2 text-secondary-foreground hover:text-foreground transition-colors duration-150 ease-out",
|
|
49
49
|
children: [copied ? /* @__PURE__ */ jsx(Check, { className: "size-4 text-success delight-bounce-in motion-reduce:animate-none" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
|
|
50
50
|
className: "ms-1.5 text-xs",
|
|
51
51
|
children: copied ? "Copied!" : "Copy"
|
|
@@ -61,7 +61,7 @@ function AICodeBlockContentBody({ children, showLineNumbers, startLineNumber })
|
|
|
61
61
|
children: [/* @__PURE__ */ jsx("div", {
|
|
62
62
|
className: "flex flex-col items-end pe-4 select-none border-e border-border me-4",
|
|
63
63
|
children: children.split("\n").map((_, index) => /* @__PURE__ */ jsx("span", {
|
|
64
|
-
className: "text-
|
|
64
|
+
className: "text-secondary-foreground leading-relaxed",
|
|
65
65
|
children: startLineNumber + index
|
|
66
66
|
}, index))
|
|
67
67
|
}), /* @__PURE__ */ jsx("section", {
|
|
@@ -136,7 +136,7 @@ function AICodeBlock({ code, language = "plaintext", fileName, showHeader = true
|
|
|
136
136
|
copied,
|
|
137
137
|
actions: headerActions
|
|
138
138
|
}), /* @__PURE__ */ jsx("section", {
|
|
139
|
-
className: cn("p-4 overflow-x-auto font-mono leading-relaxed [overflow-wrap:normal] !bg-transparent !m-0 !border-0 !rounded-none", "[&_.sh__line]:block [&_.sh__line]:leading-relaxed", showLineNumbers && ["[&_.sh__line]:[counter-increment:sh-line]", "[&_.sh__line]:before:[content:counter(sh-line)] [&_.sh__line]:before:inline-block [&_.sh__line]:before:w-8 [&_.sh__line]:before:me-4 [&_.sh__line]:before:text-end [&_.sh__line]:before:text-
|
|
139
|
+
className: cn("p-4 overflow-x-auto font-mono leading-relaxed [overflow-wrap:normal] !bg-transparent !m-0 !border-0 !rounded-none", "[&_.sh__line]:block [&_.sh__line]:leading-relaxed", showLineNumbers && ["[&_.sh__line]:[counter-increment:sh-line]", "[&_.sh__line]:before:[content:counter(sh-line)] [&_.sh__line]:before:inline-block [&_.sh__line]:before:w-8 [&_.sh__line]:before:me-4 [&_.sh__line]:before:text-end [&_.sh__line]:before:text-secondary-foreground [&_.sh__line]:before:select-none"]),
|
|
140
140
|
style: showLineNumbers ? { counterReset: `sh-line ${startLineNumber - 1}` } : void 0,
|
|
141
141
|
"aria-label": "Code content",
|
|
142
142
|
tabIndex: 0,
|