@particle-academy/react-fancy 5.49.0 → 5.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/button.cjs +4 -4
- package/dist/button.js +2 -2
- package/dist/{chunk-WBJRFWZE.cjs → chunk-2KZINS6D.cjs} +4 -4
- package/dist/{chunk-WBJRFWZE.cjs.map → chunk-2KZINS6D.cjs.map} +1 -1
- package/dist/chunk-6TBRBN7H.js +212 -0
- package/dist/chunk-6TBRBN7H.js.map +1 -0
- package/dist/{chunk-VM5BNL4L.js → chunk-7MJ7VEKE.js} +3 -3
- package/dist/{chunk-VM5BNL4L.js.map → chunk-7MJ7VEKE.js.map} +1 -1
- package/dist/{chunk-XOWWNG7D.js → chunk-ASS6EWNI.js} +3 -3
- package/dist/{chunk-XOWWNG7D.js.map → chunk-ASS6EWNI.js.map} +1 -1
- package/dist/{chunk-JHDO6CRT.js → chunk-FU6R6BZ4.js} +3 -3
- package/dist/{chunk-JHDO6CRT.js.map → chunk-FU6R6BZ4.js.map} +1 -1
- package/dist/{chunk-3XJKJQSY.cjs → chunk-FWA4PCW7.cjs} +4 -4
- package/dist/{chunk-3XJKJQSY.cjs.map → chunk-FWA4PCW7.cjs.map} +1 -1
- package/dist/{chunk-EEKXWXYO.cjs → chunk-GCWIZNN2.cjs} +4 -4
- package/dist/{chunk-EEKXWXYO.cjs.map → chunk-GCWIZNN2.cjs.map} +1 -1
- package/dist/{chunk-TKDUT7ZA.cjs → chunk-IPBEVSSC.cjs} +6 -6
- package/dist/{chunk-TKDUT7ZA.cjs.map → chunk-IPBEVSSC.cjs.map} +1 -1
- package/dist/{chunk-LP3HMRQT.cjs → chunk-IYVV4RD3.cjs} +4 -4
- package/dist/{chunk-LP3HMRQT.cjs.map → chunk-IYVV4RD3.cjs.map} +1 -1
- package/dist/{chunk-GMNMJLZO.js → chunk-K6EJLBBQ.js} +12 -6
- package/dist/chunk-K6EJLBBQ.js.map +1 -0
- package/dist/{chunk-ZLYOMQ2J.js → chunk-KODD54GT.js} +3 -3
- package/dist/{chunk-ZLYOMQ2J.js.map → chunk-KODD54GT.js.map} +1 -1
- package/dist/{chunk-ODAPI4QJ.cjs → chunk-M52IS5SO.cjs} +11 -11
- package/dist/{chunk-ODAPI4QJ.cjs.map → chunk-M52IS5SO.cjs.map} +1 -1
- package/dist/{chunk-FNYUUVOK.cjs → chunk-MFQ5NBSV.cjs} +14 -7
- package/dist/chunk-MFQ5NBSV.cjs.map +1 -0
- package/dist/{chunk-I6XHZ3S2.cjs → chunk-NAQJF3G6.cjs} +4 -4
- package/dist/{chunk-I6XHZ3S2.cjs.map → chunk-NAQJF3G6.cjs.map} +1 -1
- package/dist/{chunk-KST6GW2B.cjs → chunk-NCXH5O4I.cjs} +6 -6
- package/dist/{chunk-KST6GW2B.cjs.map → chunk-NCXH5O4I.cjs.map} +1 -1
- package/dist/{chunk-K74R6IEB.js → chunk-PCTZNK2Z.js} +4 -4
- package/dist/{chunk-K74R6IEB.js.map → chunk-PCTZNK2Z.js.map} +1 -1
- package/dist/{chunk-DUOZSOSB.cjs → chunk-RU6ZTA4M.cjs} +3 -3
- package/dist/chunk-RU6ZTA4M.cjs.map +1 -0
- package/dist/{chunk-62WPAKFS.js → chunk-UDEEPMQ4.js} +3 -3
- package/dist/{chunk-62WPAKFS.js.map → chunk-UDEEPMQ4.js.map} +1 -1
- package/dist/{chunk-VKRQHLM5.js → chunk-VB3QJ6QE.js} +3 -3
- package/dist/{chunk-VKRQHLM5.js.map → chunk-VB3QJ6QE.js.map} +1 -1
- package/dist/{chunk-RLC2BE3D.cjs → chunk-VWBKFQQN.cjs} +15 -15
- package/dist/{chunk-RLC2BE3D.cjs.map → chunk-VWBKFQQN.cjs.map} +1 -1
- package/dist/chunk-X2FC7ODX.cjs +215 -0
- package/dist/chunk-X2FC7ODX.cjs.map +1 -0
- package/dist/{chunk-SK4AEUO4.js → chunk-XBC3M4BL.js} +3 -3
- package/dist/{chunk-SK4AEUO4.js.map → chunk-XBC3M4BL.js.map} +1 -1
- package/dist/{chunk-XWXV6HSK.js → chunk-XZUGREDI.js} +3 -3
- package/dist/chunk-XZUGREDI.js.map +1 -0
- package/dist/{chunk-MQEV7XEG.js → chunk-YOTCZUNW.js} +4 -4
- package/dist/{chunk-MQEV7XEG.js.map → chunk-YOTCZUNW.js.map} +1 -1
- package/dist/content-renderer.cjs +5 -5
- package/dist/content-renderer.js +2 -2
- package/dist/editor.cjs +5 -5
- package/dist/editor.js +3 -3
- package/dist/faux-client.cjs +2 -2
- package/dist/faux-client.js +1 -1
- package/dist/image-viewer.cjs +3 -3
- package/dist/image-viewer.js +2 -2
- package/dist/index.cjs +48 -44
- package/dist/index.d.cts +74 -7
- package/dist/index.d.ts +74 -7
- package/dist/index.js +12 -12
- package/dist/json-editor.cjs +14 -14
- package/dist/json-editor.js +3 -3
- package/dist/magic-wand.cjs +4 -4
- package/dist/magic-wand.js +3 -3
- package/dist/media-viewer.cjs +5 -5
- package/dist/media-viewer.js +4 -4
- package/dist/pdf-viewer.cjs +3 -3
- package/dist/pdf-viewer.js +2 -2
- package/dist/prompt-input.cjs +4 -4
- package/dist/prompt-input.js +3 -3
- package/dist/reason-tag.cjs +4 -4
- package/dist/reason-tag.js +3 -3
- package/docs/ContentRenderer.md +36 -0
- package/package.json +1 -1
- package/dist/chunk-DUOZSOSB.cjs.map +0 -1
- package/dist/chunk-FNYUUVOK.cjs.map +0 -1
- package/dist/chunk-GMNMJLZO.js.map +0 -1
- package/dist/chunk-LRNWD26Z.cjs +0 -82
- package/dist/chunk-LRNWD26Z.cjs.map +0 -1
- package/dist/chunk-QXYO76NZ.js +0 -79
- package/dist/chunk-QXYO76NZ.js.map +0 -1
- package/dist/chunk-XWXV6HSK.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FauxClient } from './chunk-
|
|
1
|
+
import { FauxClient } from './chunk-XZUGREDI.js';
|
|
2
2
|
import { usePanZoom } from './chunk-CPY7NHXM.js';
|
|
3
3
|
import { cn } from './chunk-MMW2JGKZ.js';
|
|
4
4
|
import { forwardRef, useRef, useState, useCallback } from 'react';
|
|
@@ -214,5 +214,5 @@ var ImageViewer = forwardRef(
|
|
|
214
214
|
ImageViewer.displayName = "ImageViewer";
|
|
215
215
|
|
|
216
216
|
export { ImageViewer };
|
|
217
|
-
//# sourceMappingURL=chunk-
|
|
218
|
-
//# sourceMappingURL=chunk-
|
|
217
|
+
//# sourceMappingURL=chunk-ASS6EWNI.js.map
|
|
218
|
+
//# sourceMappingURL=chunk-ASS6EWNI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ImageViewer/ImageViewer.tsx"],"names":[],"mappings":"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","file":"chunk-XOWWNG7D.js","sourcesContent":["import { FauxClient } from \"../FauxClient\";\nimport {\n forwardRef,\n useCallback,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { usePanZoom } from \"../../hooks/use-pan-zoom\";\nimport type { ImageViewerProps, ImageViewerViewport } from \"./ImageViewer.types\";\n\nconst DEFAULT_VIEWPORT: ImageViewerViewport = { panX: 0, panY: 0, zoom: 1 };\n\nconst fitClasses: Record<NonNullable<ImageViewerProps[\"fit\"]>, string> = {\n contain: \"h-full w-full object-contain\",\n cover: \"h-full w-full object-cover\",\n none: \"max-w-none object-none\",\n};\n\nfunction clamp(n: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, n));\n}\n\n/**\n * A standalone image viewer: fits the image to its container, with optional\n * Ctrl/⌘+wheel zoom, click-drag panning, and a transparency checkerboard. Works\n * anywhere on its own and is also what `<MediaViewer>` renders for images.\n *\n * The pan/zoom viewport is controllable (`viewport` + `onViewportChange`) so an\n * agent bridge can drive it; it's uncontrolled by default.\n *\n * ```tsx\n * <ImageViewer src=\"/logo.png\" alt=\"logo.png\" style={{ height: 320 }} />\n * ```\n */\nexport const ImageViewer = forwardRef<HTMLDivElement, ImageViewerProps>(\n (\n {\n src,\n alt = \"\",\n fit = \"contain\",\n zoomable = true,\n pannable = true,\n controls,\n minZoom = 0.25,\n maxZoom = 8,\n checkerboard = true,\n viewport,\n defaultViewport,\n onViewportChange,\n onLoad,\n onError,\n className,\n style,\n frame = false,\n frameProps,\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [status, setStatus] = useState<\"loading\" | \"loaded\" | \"error\">(\"loading\");\n\n // Controllable viewport supporting functional updates (usePanZoom needs them).\n const isControlled = viewport !== undefined;\n const [internal, setInternal] = useState<ImageViewerViewport>(\n defaultViewport ?? DEFAULT_VIEWPORT,\n );\n const current = isControlled ? viewport! : internal;\n const currentRef = useRef(current);\n currentRef.current = current;\n\n const setViewport = useCallback(\n (\n next:\n | ImageViewerViewport\n | ((prev: ImageViewerViewport) => ImageViewerViewport),\n ) => {\n const resolved =\n typeof next === \"function\" ? next(currentRef.current) : next;\n if (!isControlled) setInternal(resolved);\n onViewportChange?.(resolved);\n },\n [isControlled, onViewportChange],\n );\n\n const interactive = status === \"loaded\";\n const { containerProps, isPanning } = usePanZoom({\n viewport: current,\n setViewport,\n minZoom,\n maxZoom,\n pannable: pannable && interactive,\n zoomable: zoomable && interactive,\n containerRef,\n });\n\n // Zoom about the container centre — used by the +/− buttons.\n const zoomBy = useCallback(\n (factor: number) => {\n const el = containerRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n setViewport((prev) => {\n const newZoom = clamp(prev.zoom * factor, minZoom, maxZoom);\n const ratio = newZoom / prev.zoom;\n return {\n zoom: newZoom,\n panX: cx - (cx - prev.panX) * ratio,\n panY: cy - (cy - prev.panY) * ratio,\n };\n });\n },\n [setViewport, minZoom, maxZoom],\n );\n\n const reset = useCallback(() => setViewport(DEFAULT_VIEWPORT), [setViewport]);\n\n const showControls = !frame && (controls ?? zoomable) && interactive;\n const transform = `translate(${current.panX}px, ${current.panY}px) scale(${current.zoom})`;\n\n const viewer = (\n <div\n ref={ref}\n data-react-fancy-image-viewer=\"\"\n className={cn(\n \"relative isolate overflow-hidden rounded-md select-none\",\n // In the frame it fills the frame's body; standalone, the caller sizes it.\n frame && \"h-full w-full rounded-none\",\n checkerboard\n ? \"fancy-checkerboard\"\n : \"bg-zinc-100 dark:bg-zinc-900\",\n className,\n )}\n style={style}\n >\n <div\n ref={containerRef}\n data-canvas-bg=\"\"\n className={cn(\n \"absolute inset-0 flex items-center justify-center\",\n isPanning\n ? \"cursor-grabbing\"\n : pannable && interactive\n ? \"cursor-grab\"\n : \"\",\n )}\n style={\n {\n transform,\n transformOrigin: \"0 0\",\n willChange: \"transform\",\n touchAction: zoomable || pannable ? \"none\" : undefined,\n } as CSSProperties\n }\n onDoubleClick={zoomable ? reset : undefined}\n {...containerProps}\n >\n <img\n src={src}\n alt={alt}\n draggable={false}\n onLoad={() => {\n setStatus(\"loaded\");\n onLoad?.();\n }}\n onError={() => {\n setStatus(\"error\");\n onError?.();\n }}\n className={cn(\n \"pointer-events-none block\",\n status === \"error\" && \"hidden\",\n fitClasses[fit],\n )}\n />\n </div>\n\n {status === \"error\" && (\n <div\n data-react-fancy-image-viewer-error=\"\"\n className=\"absolute inset-0 flex flex-col items-center justify-center gap-1 p-4 text-center text-sm text-zinc-500 dark:text-zinc-400\"\n >\n <span className=\"font-medium\">Couldn't load image</span>\n <span className=\"max-w-full truncate text-xs opacity-70\">{alt || src}</span>\n </div>\n )}\n\n {showControls && (\n <div\n data-react-fancy-image-viewer-controls=\"\"\n className=\"absolute bottom-2 right-2 flex items-center gap-0.5 rounded-md border border-zinc-200 bg-white/90 p-0.5 text-zinc-700 shadow-sm backdrop-blur dark:border-zinc-700 dark:bg-zinc-900/90 dark:text-zinc-200\"\n >\n <button\n type=\"button\"\n aria-label=\"Zoom out\"\n onClick={() => zoomBy(1 / 1.25)}\n className=\"flex h-6 w-6 items-center justify-center rounded text-base leading-none hover:bg-zinc-100 dark:hover:bg-zinc-800\"\n >\n −\n </button>\n <button\n type=\"button\"\n aria-label=\"Reset zoom\"\n onClick={reset}\n className=\"min-w-[3rem] rounded px-1 text-center text-xs tabular-nums hover:bg-zinc-100 dark:hover:bg-zinc-800\"\n >\n {Math.round(current.zoom * 100)}%\n </button>\n <button\n type=\"button\"\n aria-label=\"Zoom in\"\n onClick={() => zoomBy(1.25)}\n className=\"flex h-6 w-6 items-center justify-center rounded text-base leading-none hover:bg-zinc-100 dark:hover:bg-zinc-800\"\n >\n +\n </button>\n </div>\n )}\n </div>\n );\n\n if (!frame) return viewer;\n\n // The frame's bar drives the image's own zoom (about the centre), and the\n // image's boxed bar steps aside: one set of controls, revealed on hover.\n return (\n <FauxClient\n variant=\"device\"\n controls\n fill\n applyZoom={false}\n zoom={current.zoom}\n onZoomChange={(z) => (z === 1 ? reset() : zoomBy(z / current.zoom))}\n minZoom={minZoom}\n maxZoom={maxZoom}\n {...frameProps}\n >\n {viewer}\n </FauxClient>\n );\n },\n);\n\nImageViewer.displayName = \"ImageViewer\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ImageViewer/ImageViewer.tsx"],"names":[],"mappings":"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","file":"chunk-ASS6EWNI.js","sourcesContent":["import { FauxClient } from \"../FauxClient\";\nimport {\n forwardRef,\n useCallback,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { usePanZoom } from \"../../hooks/use-pan-zoom\";\nimport type { ImageViewerProps, ImageViewerViewport } from \"./ImageViewer.types\";\n\nconst DEFAULT_VIEWPORT: ImageViewerViewport = { panX: 0, panY: 0, zoom: 1 };\n\nconst fitClasses: Record<NonNullable<ImageViewerProps[\"fit\"]>, string> = {\n contain: \"h-full w-full object-contain\",\n cover: \"h-full w-full object-cover\",\n none: \"max-w-none object-none\",\n};\n\nfunction clamp(n: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, n));\n}\n\n/**\n * A standalone image viewer: fits the image to its container, with optional\n * Ctrl/⌘+wheel zoom, click-drag panning, and a transparency checkerboard. Works\n * anywhere on its own and is also what `<MediaViewer>` renders for images.\n *\n * The pan/zoom viewport is controllable (`viewport` + `onViewportChange`) so an\n * agent bridge can drive it; it's uncontrolled by default.\n *\n * ```tsx\n * <ImageViewer src=\"/logo.png\" alt=\"logo.png\" style={{ height: 320 }} />\n * ```\n */\nexport const ImageViewer = forwardRef<HTMLDivElement, ImageViewerProps>(\n (\n {\n src,\n alt = \"\",\n fit = \"contain\",\n zoomable = true,\n pannable = true,\n controls,\n minZoom = 0.25,\n maxZoom = 8,\n checkerboard = true,\n viewport,\n defaultViewport,\n onViewportChange,\n onLoad,\n onError,\n className,\n style,\n frame = false,\n frameProps,\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [status, setStatus] = useState<\"loading\" | \"loaded\" | \"error\">(\"loading\");\n\n // Controllable viewport supporting functional updates (usePanZoom needs them).\n const isControlled = viewport !== undefined;\n const [internal, setInternal] = useState<ImageViewerViewport>(\n defaultViewport ?? DEFAULT_VIEWPORT,\n );\n const current = isControlled ? viewport! : internal;\n const currentRef = useRef(current);\n currentRef.current = current;\n\n const setViewport = useCallback(\n (\n next:\n | ImageViewerViewport\n | ((prev: ImageViewerViewport) => ImageViewerViewport),\n ) => {\n const resolved =\n typeof next === \"function\" ? next(currentRef.current) : next;\n if (!isControlled) setInternal(resolved);\n onViewportChange?.(resolved);\n },\n [isControlled, onViewportChange],\n );\n\n const interactive = status === \"loaded\";\n const { containerProps, isPanning } = usePanZoom({\n viewport: current,\n setViewport,\n minZoom,\n maxZoom,\n pannable: pannable && interactive,\n zoomable: zoomable && interactive,\n containerRef,\n });\n\n // Zoom about the container centre — used by the +/− buttons.\n const zoomBy = useCallback(\n (factor: number) => {\n const el = containerRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n setViewport((prev) => {\n const newZoom = clamp(prev.zoom * factor, minZoom, maxZoom);\n const ratio = newZoom / prev.zoom;\n return {\n zoom: newZoom,\n panX: cx - (cx - prev.panX) * ratio,\n panY: cy - (cy - prev.panY) * ratio,\n };\n });\n },\n [setViewport, minZoom, maxZoom],\n );\n\n const reset = useCallback(() => setViewport(DEFAULT_VIEWPORT), [setViewport]);\n\n const showControls = !frame && (controls ?? zoomable) && interactive;\n const transform = `translate(${current.panX}px, ${current.panY}px) scale(${current.zoom})`;\n\n const viewer = (\n <div\n ref={ref}\n data-react-fancy-image-viewer=\"\"\n className={cn(\n \"relative isolate overflow-hidden rounded-md select-none\",\n // In the frame it fills the frame's body; standalone, the caller sizes it.\n frame && \"h-full w-full rounded-none\",\n checkerboard\n ? \"fancy-checkerboard\"\n : \"bg-zinc-100 dark:bg-zinc-900\",\n className,\n )}\n style={style}\n >\n <div\n ref={containerRef}\n data-canvas-bg=\"\"\n className={cn(\n \"absolute inset-0 flex items-center justify-center\",\n isPanning\n ? \"cursor-grabbing\"\n : pannable && interactive\n ? \"cursor-grab\"\n : \"\",\n )}\n style={\n {\n transform,\n transformOrigin: \"0 0\",\n willChange: \"transform\",\n touchAction: zoomable || pannable ? \"none\" : undefined,\n } as CSSProperties\n }\n onDoubleClick={zoomable ? reset : undefined}\n {...containerProps}\n >\n <img\n src={src}\n alt={alt}\n draggable={false}\n onLoad={() => {\n setStatus(\"loaded\");\n onLoad?.();\n }}\n onError={() => {\n setStatus(\"error\");\n onError?.();\n }}\n className={cn(\n \"pointer-events-none block\",\n status === \"error\" && \"hidden\",\n fitClasses[fit],\n )}\n />\n </div>\n\n {status === \"error\" && (\n <div\n data-react-fancy-image-viewer-error=\"\"\n className=\"absolute inset-0 flex flex-col items-center justify-center gap-1 p-4 text-center text-sm text-zinc-500 dark:text-zinc-400\"\n >\n <span className=\"font-medium\">Couldn't load image</span>\n <span className=\"max-w-full truncate text-xs opacity-70\">{alt || src}</span>\n </div>\n )}\n\n {showControls && (\n <div\n data-react-fancy-image-viewer-controls=\"\"\n className=\"absolute bottom-2 right-2 flex items-center gap-0.5 rounded-md border border-zinc-200 bg-white/90 p-0.5 text-zinc-700 shadow-sm backdrop-blur dark:border-zinc-700 dark:bg-zinc-900/90 dark:text-zinc-200\"\n >\n <button\n type=\"button\"\n aria-label=\"Zoom out\"\n onClick={() => zoomBy(1 / 1.25)}\n className=\"flex h-6 w-6 items-center justify-center rounded text-base leading-none hover:bg-zinc-100 dark:hover:bg-zinc-800\"\n >\n −\n </button>\n <button\n type=\"button\"\n aria-label=\"Reset zoom\"\n onClick={reset}\n className=\"min-w-[3rem] rounded px-1 text-center text-xs tabular-nums hover:bg-zinc-100 dark:hover:bg-zinc-800\"\n >\n {Math.round(current.zoom * 100)}%\n </button>\n <button\n type=\"button\"\n aria-label=\"Zoom in\"\n onClick={() => zoomBy(1.25)}\n className=\"flex h-6 w-6 items-center justify-center rounded text-base leading-none hover:bg-zinc-100 dark:hover:bg-zinc-800\"\n >\n +\n </button>\n </div>\n )}\n </div>\n );\n\n if (!frame) return viewer;\n\n // The frame's bar drives the image's own zoom (about the centre), and the\n // image's boxed bar steps aside: one set of controls, revealed on hover.\n return (\n <FauxClient\n variant=\"device\"\n controls\n fill\n applyZoom={false}\n zoom={current.zoom}\n onZoomChange={(z) => (z === 1 ? reset() : zoomBy(z / current.zoom))}\n minZoom={minZoom}\n maxZoom={maxZoom}\n {...frameProps}\n >\n {viewer}\n </FauxClient>\n );\n },\n);\n\nImageViewer.displayName = \"ImageViewer\";\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Textarea } from './chunk-DEFGT75G.js';
|
|
2
2
|
import { Badge } from './chunk-6FCQD2KQ.js';
|
|
3
|
-
import { Button } from './chunk-
|
|
3
|
+
import { Button } from './chunk-KODD54GT.js';
|
|
4
4
|
import { useRef, useState, useCallback, useEffect } from 'react';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -198,5 +198,5 @@ function caretRect(ta, start, end) {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
export { MagicWand };
|
|
201
|
-
//# sourceMappingURL=chunk-
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
201
|
+
//# sourceMappingURL=chunk-FU6R6BZ4.js.map
|
|
202
|
+
//# sourceMappingURL=chunk-FU6R6BZ4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/MagicWand/MagicWand.tsx"],"names":[],"mappings":"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","file":"chunk-JHDO6CRT.js","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Button } from \"../Button\";\nimport { Badge } from \"../Badge\";\nimport { Textarea } from \"../inputs/Textarea/Textarea\";\n\n/**\n * MagicWand — selection-anchored floating toolbar for text inputs.\n *\n * When the user highlights text inside the wrapped <Textarea>, a small\n * pill of AI quick-actions floats above the selection. Clicking an\n * action invokes the host callback with the selected substring + range;\n * the host returns a replacement string and MagicWand swaps it in-place.\n *\n * <MagicWand\n * value={body}\n * onValueChange={setBody}\n * actions={[\n * { id: \"rephrase\", label: \"Rephrase\", hint: \"same meaning, different words\",\n * run: async (s) => await ai.rephrase(s) },\n * …\n * ]}\n * />\n *\n * Two appearances: `\"floating\"` (default — full labels) and `\"pill\"`\n * (icon-only, compact). Auto-hides on click-away or scroll by default.\n */\nexport type MagicWandSelection = { start: number; end: number; text: string };\n\nexport type MagicWandAction = {\n /** Stable id, also shown as the busy-state key. */\n id: string;\n /** Display label (first character used in `pill` mode). */\n label: string;\n /** Tooltip body. */\n hint?: string;\n /** Optional kind chip rendered next to the label. */\n tag?: string;\n /** Returns the replacement text for the selection. */\n run: (selection: string, range: MagicWandSelection) => Promise<string> | string;\n};\n\nexport type MagicWandAppearance = \"pill\" | \"floating\";\n\nexport interface MagicWandProps {\n /** Controlled textarea value. */\n value: string;\n /** Called on every edit. */\n onValueChange: (v: string) => void;\n /** Action list. */\n actions: MagicWandAction[];\n /** Visual treatment. Defaults to \"floating\". */\n appearance?: MagicWandAppearance;\n /** Auto-hide the wand on click-away or scroll. Defaults to true. */\n autoHide?: boolean;\n /** Textarea rows. */\n rows?: number;\n /** Placeholder. */\n placeholder?: string;\n /** Called after an action runs successfully. */\n onAction?: (action: MagicWandAction, selection: MagicWandSelection, replacement: string) => void;\n}\n\nexport function MagicWand({\n value,\n onValueChange,\n actions,\n appearance = \"floating\",\n autoHide = true,\n rows = 6,\n placeholder,\n onAction,\n}: MagicWandProps) {\n const taRef = useRef<HTMLTextAreaElement>(null);\n const wandRef = useRef<HTMLDivElement>(null);\n const [sel, setSel] = useState<MagicWandSelection | null>(null);\n const [pos, setPos] = useState<{ x: number; y: number } | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n\n const measureSelection = useCallback(() => {\n const ta = taRef.current;\n if (!ta) return;\n const start = ta.selectionStart ?? 0;\n const end = ta.selectionEnd ?? 0;\n if (start === end) {\n setSel(null);\n setPos(null);\n return;\n }\n const text = ta.value.slice(start, end);\n setSel({ start, end, text });\n const rect = caretRect(ta, start, end);\n if (rect) setPos({ x: rect.x, y: rect.y });\n }, []);\n\n useEffect(() => {\n if (!autoHide) return;\n const onScroll = () => {\n setSel(null);\n setPos(null);\n };\n window.addEventListener(\"scroll\", onScroll, true);\n return () => window.removeEventListener(\"scroll\", onScroll, true);\n }, [autoHide]);\n\n useEffect(() => {\n if (!autoHide) return;\n const onDocMouseDown = (e: MouseEvent) => {\n if (wandRef.current?.contains(e.target as Node)) return;\n if (taRef.current?.contains(e.target as Node)) return;\n setSel(null);\n setPos(null);\n };\n document.addEventListener(\"mousedown\", onDocMouseDown);\n return () => document.removeEventListener(\"mousedown\", onDocMouseDown);\n }, [autoHide]);\n\n const handleAction = async (action: MagicWandAction) => {\n if (!sel) return;\n setBusy(action.id);\n try {\n const replacement = await action.run(sel.text, sel);\n const next = value.slice(0, sel.start) + replacement + value.slice(sel.end);\n onValueChange(next);\n onAction?.(action, sel, replacement);\n } finally {\n setBusy(null);\n setSel(null);\n setPos(null);\n }\n };\n\n return (\n <div className=\"relative\">\n <Textarea\n ref={taRef as unknown as React.Ref<HTMLTextAreaElement>}\n value={value}\n onValueChange={onValueChange}\n onSelect={measureSelection}\n onKeyUp={measureSelection}\n onMouseUp={measureSelection}\n rows={rows}\n placeholder={placeholder}\n />\n {sel && pos && (\n <Wand\n ref={wandRef}\n pos={pos}\n actions={actions}\n appearance={appearance}\n busy={busy}\n onAction={handleAction}\n selectionLength={sel.text.length}\n />\n )}\n </div>\n );\n}\n\nfunction Wand({\n ref,\n pos,\n actions,\n appearance,\n busy,\n onAction,\n selectionLength,\n}: {\n ref: React.RefObject<HTMLDivElement | null>;\n pos: { x: number; y: number };\n actions: MagicWandAction[];\n appearance: MagicWandAppearance;\n busy: string | null;\n onAction: (a: MagicWandAction) => void;\n selectionLength: number;\n}) {\n return (\n <div\n ref={ref}\n className=\"absolute z-20 -translate-x-1/2 -translate-y-full\"\n style={{ left: pos.x, top: pos.y - 6 }}\n >\n <div className=\"flex items-center gap-1 rounded-full border border-violet-300 bg-white px-1.5 py-1 shadow-lg ring-1 ring-violet-200 dark:border-violet-700 dark:bg-zinc-900 dark:ring-violet-900\">\n <span className=\"ml-1 mr-0.5 inline-flex items-center gap-1 text-[10px] font-medium text-violet-700 dark:text-violet-300\">\n <span aria-hidden>✦</span>\n {appearance === \"floating\" && (\n <Badge color=\"violet\">{selectionLength} chars</Badge>\n )}\n </span>\n {actions.map((a) => (\n <Button\n key={a.id}\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => onAction(a)}\n disabled={busy !== null}\n title={a.hint}\n >\n {busy === a.id ? \"…\" : appearance === \"pill\" ? a.label[0] : a.label}\n {appearance === \"floating\" && a.tag && (\n <span className=\"ml-1 rounded-full bg-zinc-100 px-1 text-[9px] font-medium text-zinc-500 dark:bg-zinc-800\">\n {a.tag}\n </span>\n )}\n </Button>\n ))}\n </div>\n <div className=\"absolute left-1/2 top-full -translate-x-1/2 -translate-y-px\">\n <div className=\"h-2 w-2 rotate-45 border-b border-r border-violet-300 bg-white dark:border-violet-700 dark:bg-zinc-900\" />\n </div>\n </div>\n );\n}\n\n/**\n * Caret/selection geometry: mirror the textarea into a hidden div and\n * measure the selected substring's bounding rect. Not perfect for\n * resized textareas, but works for typical chat composers.\n */\nfunction caretRect(\n ta: HTMLTextAreaElement,\n start: number,\n end: number,\n): { x: number; y: number } | null {\n const div = document.createElement(\"div\");\n const style = getComputedStyle(ta);\n const props = [\n \"boxSizing\",\n \"width\",\n \"height\",\n \"overflowX\",\n \"overflowY\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontWeight\",\n \"fontStretch\",\n \"fontSize\",\n \"fontSizeAdjust\",\n \"lineHeight\",\n \"fontFamily\",\n \"textAlign\",\n \"textTransform\",\n \"textIndent\",\n \"letterSpacing\",\n \"wordSpacing\",\n \"tabSize\",\n ] as const;\n for (const p of props) (div.style as any)[p] = (style as any)[p];\n div.style.position = \"absolute\";\n div.style.top = \"-9999px\";\n div.style.left = \"-9999px\";\n div.style.whiteSpace = \"pre-wrap\";\n div.style.wordWrap = \"break-word\";\n\n const value = ta.value;\n div.textContent = value.substring(0, start);\n const startSpan = document.createElement(\"span\");\n startSpan.textContent = value.substring(start, end) || \".\";\n div.appendChild(startSpan);\n\n document.body.appendChild(div);\n const taRect = ta.getBoundingClientRect();\n const parentRect =\n (ta.offsetParent as HTMLElement | null)?.getBoundingClientRect() ?? taRect;\n const spanRect = startSpan.getBoundingClientRect();\n const divRect = div.getBoundingClientRect();\n const offsetX = spanRect.left - divRect.left;\n const offsetY = spanRect.top - divRect.top;\n document.body.removeChild(div);\n\n const x = taRect.left - parentRect.left + offsetX + spanRect.width / 2;\n const y = taRect.top - parentRect.top + offsetY - ta.scrollTop;\n return { x, y };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/MagicWand/MagicWand.tsx"],"names":[],"mappings":"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","file":"chunk-FU6R6BZ4.js","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Button } from \"../Button\";\nimport { Badge } from \"../Badge\";\nimport { Textarea } from \"../inputs/Textarea/Textarea\";\n\n/**\n * MagicWand — selection-anchored floating toolbar for text inputs.\n *\n * When the user highlights text inside the wrapped <Textarea>, a small\n * pill of AI quick-actions floats above the selection. Clicking an\n * action invokes the host callback with the selected substring + range;\n * the host returns a replacement string and MagicWand swaps it in-place.\n *\n * <MagicWand\n * value={body}\n * onValueChange={setBody}\n * actions={[\n * { id: \"rephrase\", label: \"Rephrase\", hint: \"same meaning, different words\",\n * run: async (s) => await ai.rephrase(s) },\n * …\n * ]}\n * />\n *\n * Two appearances: `\"floating\"` (default — full labels) and `\"pill\"`\n * (icon-only, compact). Auto-hides on click-away or scroll by default.\n */\nexport type MagicWandSelection = { start: number; end: number; text: string };\n\nexport type MagicWandAction = {\n /** Stable id, also shown as the busy-state key. */\n id: string;\n /** Display label (first character used in `pill` mode). */\n label: string;\n /** Tooltip body. */\n hint?: string;\n /** Optional kind chip rendered next to the label. */\n tag?: string;\n /** Returns the replacement text for the selection. */\n run: (selection: string, range: MagicWandSelection) => Promise<string> | string;\n};\n\nexport type MagicWandAppearance = \"pill\" | \"floating\";\n\nexport interface MagicWandProps {\n /** Controlled textarea value. */\n value: string;\n /** Called on every edit. */\n onValueChange: (v: string) => void;\n /** Action list. */\n actions: MagicWandAction[];\n /** Visual treatment. Defaults to \"floating\". */\n appearance?: MagicWandAppearance;\n /** Auto-hide the wand on click-away or scroll. Defaults to true. */\n autoHide?: boolean;\n /** Textarea rows. */\n rows?: number;\n /** Placeholder. */\n placeholder?: string;\n /** Called after an action runs successfully. */\n onAction?: (action: MagicWandAction, selection: MagicWandSelection, replacement: string) => void;\n}\n\nexport function MagicWand({\n value,\n onValueChange,\n actions,\n appearance = \"floating\",\n autoHide = true,\n rows = 6,\n placeholder,\n onAction,\n}: MagicWandProps) {\n const taRef = useRef<HTMLTextAreaElement>(null);\n const wandRef = useRef<HTMLDivElement>(null);\n const [sel, setSel] = useState<MagicWandSelection | null>(null);\n const [pos, setPos] = useState<{ x: number; y: number } | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n\n const measureSelection = useCallback(() => {\n const ta = taRef.current;\n if (!ta) return;\n const start = ta.selectionStart ?? 0;\n const end = ta.selectionEnd ?? 0;\n if (start === end) {\n setSel(null);\n setPos(null);\n return;\n }\n const text = ta.value.slice(start, end);\n setSel({ start, end, text });\n const rect = caretRect(ta, start, end);\n if (rect) setPos({ x: rect.x, y: rect.y });\n }, []);\n\n useEffect(() => {\n if (!autoHide) return;\n const onScroll = () => {\n setSel(null);\n setPos(null);\n };\n window.addEventListener(\"scroll\", onScroll, true);\n return () => window.removeEventListener(\"scroll\", onScroll, true);\n }, [autoHide]);\n\n useEffect(() => {\n if (!autoHide) return;\n const onDocMouseDown = (e: MouseEvent) => {\n if (wandRef.current?.contains(e.target as Node)) return;\n if (taRef.current?.contains(e.target as Node)) return;\n setSel(null);\n setPos(null);\n };\n document.addEventListener(\"mousedown\", onDocMouseDown);\n return () => document.removeEventListener(\"mousedown\", onDocMouseDown);\n }, [autoHide]);\n\n const handleAction = async (action: MagicWandAction) => {\n if (!sel) return;\n setBusy(action.id);\n try {\n const replacement = await action.run(sel.text, sel);\n const next = value.slice(0, sel.start) + replacement + value.slice(sel.end);\n onValueChange(next);\n onAction?.(action, sel, replacement);\n } finally {\n setBusy(null);\n setSel(null);\n setPos(null);\n }\n };\n\n return (\n <div className=\"relative\">\n <Textarea\n ref={taRef as unknown as React.Ref<HTMLTextAreaElement>}\n value={value}\n onValueChange={onValueChange}\n onSelect={measureSelection}\n onKeyUp={measureSelection}\n onMouseUp={measureSelection}\n rows={rows}\n placeholder={placeholder}\n />\n {sel && pos && (\n <Wand\n ref={wandRef}\n pos={pos}\n actions={actions}\n appearance={appearance}\n busy={busy}\n onAction={handleAction}\n selectionLength={sel.text.length}\n />\n )}\n </div>\n );\n}\n\nfunction Wand({\n ref,\n pos,\n actions,\n appearance,\n busy,\n onAction,\n selectionLength,\n}: {\n ref: React.RefObject<HTMLDivElement | null>;\n pos: { x: number; y: number };\n actions: MagicWandAction[];\n appearance: MagicWandAppearance;\n busy: string | null;\n onAction: (a: MagicWandAction) => void;\n selectionLength: number;\n}) {\n return (\n <div\n ref={ref}\n className=\"absolute z-20 -translate-x-1/2 -translate-y-full\"\n style={{ left: pos.x, top: pos.y - 6 }}\n >\n <div className=\"flex items-center gap-1 rounded-full border border-violet-300 bg-white px-1.5 py-1 shadow-lg ring-1 ring-violet-200 dark:border-violet-700 dark:bg-zinc-900 dark:ring-violet-900\">\n <span className=\"ml-1 mr-0.5 inline-flex items-center gap-1 text-[10px] font-medium text-violet-700 dark:text-violet-300\">\n <span aria-hidden>✦</span>\n {appearance === \"floating\" && (\n <Badge color=\"violet\">{selectionLength} chars</Badge>\n )}\n </span>\n {actions.map((a) => (\n <Button\n key={a.id}\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => onAction(a)}\n disabled={busy !== null}\n title={a.hint}\n >\n {busy === a.id ? \"…\" : appearance === \"pill\" ? a.label[0] : a.label}\n {appearance === \"floating\" && a.tag && (\n <span className=\"ml-1 rounded-full bg-zinc-100 px-1 text-[9px] font-medium text-zinc-500 dark:bg-zinc-800\">\n {a.tag}\n </span>\n )}\n </Button>\n ))}\n </div>\n <div className=\"absolute left-1/2 top-full -translate-x-1/2 -translate-y-px\">\n <div className=\"h-2 w-2 rotate-45 border-b border-r border-violet-300 bg-white dark:border-violet-700 dark:bg-zinc-900\" />\n </div>\n </div>\n );\n}\n\n/**\n * Caret/selection geometry: mirror the textarea into a hidden div and\n * measure the selected substring's bounding rect. Not perfect for\n * resized textareas, but works for typical chat composers.\n */\nfunction caretRect(\n ta: HTMLTextAreaElement,\n start: number,\n end: number,\n): { x: number; y: number } | null {\n const div = document.createElement(\"div\");\n const style = getComputedStyle(ta);\n const props = [\n \"boxSizing\",\n \"width\",\n \"height\",\n \"overflowX\",\n \"overflowY\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontWeight\",\n \"fontStretch\",\n \"fontSize\",\n \"fontSizeAdjust\",\n \"lineHeight\",\n \"fontFamily\",\n \"textAlign\",\n \"textTransform\",\n \"textIndent\",\n \"letterSpacing\",\n \"wordSpacing\",\n \"tabSize\",\n ] as const;\n for (const p of props) (div.style as any)[p] = (style as any)[p];\n div.style.position = \"absolute\";\n div.style.top = \"-9999px\";\n div.style.left = \"-9999px\";\n div.style.whiteSpace = \"pre-wrap\";\n div.style.wordWrap = \"break-word\";\n\n const value = ta.value;\n div.textContent = value.substring(0, start);\n const startSpan = document.createElement(\"span\");\n startSpan.textContent = value.substring(start, end) || \".\";\n div.appendChild(startSpan);\n\n document.body.appendChild(div);\n const taRect = ta.getBoundingClientRect();\n const parentRect =\n (ta.offsetParent as HTMLElement | null)?.getBoundingClientRect() ?? taRect;\n const spanRect = startSpan.getBoundingClientRect();\n const divRect = div.getBoundingClientRect();\n const offsetX = spanRect.left - divRect.left;\n const offsetY = spanRect.top - divRect.top;\n document.body.removeChild(div);\n\n const x = taRect.left - parentRect.left + offsetX + spanRect.width / 2;\n const y = taRect.top - parentRect.top + offsetY - ta.scrollTop;\n return { x, y };\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkX2FC7ODX_cjs = require('./chunk-X2FC7ODX.cjs');
|
|
4
4
|
var chunkXCZZVRBY_cjs = require('./chunk-XCZZVRBY.cjs');
|
|
5
5
|
var chunkQKFOJKVE_cjs = require('./chunk-QKFOJKVE.cjs');
|
|
6
6
|
var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
|
|
@@ -364,7 +364,7 @@ var Button = react.forwardRef(
|
|
|
364
364
|
),
|
|
365
365
|
trailingElements
|
|
366
366
|
] });
|
|
367
|
-
const safeHref =
|
|
367
|
+
const safeHref = chunkX2FC7ODX_cjs.sanitizeHref(href);
|
|
368
368
|
const Anchor = As ?? "a";
|
|
369
369
|
const buttonEl = safeHref && !disabled ? (
|
|
370
370
|
// Anchor mode forwards the same rest props as the <button> branch so
|
|
@@ -456,5 +456,5 @@ var Action = Button;
|
|
|
456
456
|
|
|
457
457
|
exports.Action = Action;
|
|
458
458
|
exports.Button = Button;
|
|
459
|
-
//# sourceMappingURL=chunk-
|
|
460
|
-
//# sourceMappingURL=chunk-
|
|
459
|
+
//# sourceMappingURL=chunk-FWA4PCW7.cjs.map
|
|
460
|
+
//# sourceMappingURL=chunk-FWA4PCW7.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Button/Button.colors.ts","../src/components/Button/Button.tsx"],"names":["forwardRef","resolve","jsx","cn","Icon","jsxs","Fragment","sanitizeHref"],"mappings":"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","file":"chunk-3XJKJQSY.cjs","sourcesContent":["// AUTO-GENERATED by scripts/gen-button-colors — do not edit by hand.\n// Literal Tailwind class strings for every color in the v4 palette so the\n// scanner can detect them in the published dist (template-built names are\n// invisible to Tailwind's JIT). Regenerate after changing the palette.\nimport type { Color } from \"../../utils/types\";\n\nexport const buttonColorClasses: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-brand text-brand-contrast border border-brand hover:bg-brand-hover\",\n slate: \"bg-slate-500 text-white border border-slate-600 hover:bg-slate-600 dark:bg-slate-600 dark:border-slate-500 dark:hover:bg-slate-500\",\n gray: \"bg-gray-500 text-white border border-gray-600 hover:bg-gray-600 dark:bg-gray-600 dark:border-gray-500 dark:hover:bg-gray-500\",\n zinc: \"bg-zinc-500 text-white border border-zinc-600 hover:bg-zinc-600 dark:bg-zinc-600 dark:border-zinc-500 dark:hover:bg-zinc-500\",\n neutral: \"bg-neutral-500 text-white border border-neutral-600 hover:bg-neutral-600 dark:bg-neutral-600 dark:border-neutral-500 dark:hover:bg-neutral-500\",\n stone: \"bg-stone-500 text-white border border-stone-600 hover:bg-stone-600 dark:bg-stone-600 dark:border-stone-500 dark:hover:bg-stone-500\",\n red: \"bg-red-500 text-white border border-red-600 hover:bg-red-600 dark:bg-red-600 dark:border-red-500 dark:hover:bg-red-500\",\n orange: \"bg-orange-500 text-white border border-orange-600 hover:bg-orange-600 dark:bg-orange-600 dark:border-orange-500 dark:hover:bg-orange-500\",\n amber: \"bg-amber-400 text-amber-950 border border-amber-500 hover:bg-amber-500 dark:bg-amber-300 dark:text-amber-950 dark:border-amber-400 dark:hover:bg-amber-400\",\n yellow: \"bg-yellow-400 text-yellow-950 border border-yellow-500 hover:bg-yellow-500 dark:bg-yellow-300 dark:text-yellow-950 dark:border-yellow-400 dark:hover:bg-yellow-400\",\n lime: \"bg-lime-400 text-lime-950 border border-lime-500 hover:bg-lime-500 dark:bg-lime-300 dark:text-lime-950 dark:border-lime-400 dark:hover:bg-lime-400\",\n green: \"bg-green-500 text-white border border-green-600 hover:bg-green-600 dark:bg-green-600 dark:border-green-500 dark:hover:bg-green-500\",\n emerald: \"bg-emerald-500 text-white border border-emerald-600 hover:bg-emerald-600 dark:bg-emerald-600 dark:border-emerald-500 dark:hover:bg-emerald-500\",\n teal: \"bg-teal-500 text-white border border-teal-600 hover:bg-teal-600 dark:bg-teal-600 dark:border-teal-500 dark:hover:bg-teal-500\",\n cyan: \"bg-cyan-500 text-white border border-cyan-600 hover:bg-cyan-600 dark:bg-cyan-600 dark:border-cyan-500 dark:hover:bg-cyan-500\",\n sky: \"bg-sky-500 text-white border border-sky-600 hover:bg-sky-600 dark:bg-sky-600 dark:border-sky-500 dark:hover:bg-sky-500\",\n blue: \"bg-blue-500 text-white border border-blue-600 hover:bg-blue-600 dark:bg-blue-600 dark:border-blue-500 dark:hover:bg-blue-500\",\n indigo: \"bg-indigo-500 text-white border border-indigo-600 hover:bg-indigo-600 dark:bg-indigo-600 dark:border-indigo-500 dark:hover:bg-indigo-500\",\n violet: \"bg-violet-500 text-white border border-violet-600 hover:bg-violet-600 dark:bg-violet-600 dark:border-violet-500 dark:hover:bg-violet-500\",\n purple: \"bg-purple-500 text-white border border-purple-600 hover:bg-purple-600 dark:bg-purple-600 dark:border-purple-500 dark:hover:bg-purple-500\",\n fuchsia: \"bg-fuchsia-500 text-white border border-fuchsia-600 hover:bg-fuchsia-600 dark:bg-fuchsia-600 dark:border-fuchsia-500 dark:hover:bg-fuchsia-500\",\n pink: \"bg-pink-500 text-white border border-pink-600 hover:bg-pink-600 dark:bg-pink-600 dark:border-pink-500 dark:hover:bg-pink-500\",\n rose: \"bg-rose-500 text-white border border-rose-600 hover:bg-rose-600 dark:bg-rose-600 dark:border-rose-500 dark:hover:bg-rose-500\",\n};\n\nexport const buttonGhostClasses: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-transparent text-brand hover:bg-brand/10\",\n slate: \"bg-transparent text-slate-600 hover:bg-slate-50 dark:text-slate-400 dark:hover:bg-slate-950/50\",\n gray: \"bg-transparent text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-950/50\",\n zinc: \"bg-transparent text-zinc-600 hover:bg-zinc-50 dark:text-zinc-400 dark:hover:bg-zinc-950/50\",\n neutral: \"bg-transparent text-neutral-600 hover:bg-neutral-50 dark:text-neutral-400 dark:hover:bg-neutral-950/50\",\n stone: \"bg-transparent text-stone-600 hover:bg-stone-50 dark:text-stone-400 dark:hover:bg-stone-950/50\",\n red: \"bg-transparent text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/50\",\n orange: \"bg-transparent text-orange-600 hover:bg-orange-50 dark:text-orange-400 dark:hover:bg-orange-950/50\",\n amber: \"bg-transparent text-amber-600 hover:bg-amber-50 dark:text-amber-400 dark:hover:bg-amber-950/50\",\n yellow: \"bg-transparent text-yellow-600 hover:bg-yellow-50 dark:text-yellow-400 dark:hover:bg-yellow-950/50\",\n lime: \"bg-transparent text-lime-600 hover:bg-lime-50 dark:text-lime-400 dark:hover:bg-lime-950/50\",\n green: \"bg-transparent text-green-600 hover:bg-green-50 dark:text-green-400 dark:hover:bg-green-950/50\",\n emerald: \"bg-transparent text-emerald-600 hover:bg-emerald-50 dark:text-emerald-400 dark:hover:bg-emerald-950/50\",\n teal: \"bg-transparent text-teal-600 hover:bg-teal-50 dark:text-teal-400 dark:hover:bg-teal-950/50\",\n cyan: \"bg-transparent text-cyan-600 hover:bg-cyan-50 dark:text-cyan-400 dark:hover:bg-cyan-950/50\",\n sky: \"bg-transparent text-sky-600 hover:bg-sky-50 dark:text-sky-400 dark:hover:bg-sky-950/50\",\n blue: \"bg-transparent text-blue-600 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-950/50\",\n indigo: \"bg-transparent text-indigo-600 hover:bg-indigo-50 dark:text-indigo-400 dark:hover:bg-indigo-950/50\",\n violet: \"bg-transparent text-violet-600 hover:bg-violet-50 dark:text-violet-400 dark:hover:bg-violet-950/50\",\n purple: \"bg-transparent text-purple-600 hover:bg-purple-50 dark:text-purple-400 dark:hover:bg-purple-950/50\",\n fuchsia: \"bg-transparent text-fuchsia-600 hover:bg-fuchsia-50 dark:text-fuchsia-400 dark:hover:bg-fuchsia-950/50\",\n pink: \"bg-transparent text-pink-600 hover:bg-pink-50 dark:text-pink-400 dark:hover:bg-pink-950/50\",\n rose: \"bg-transparent text-rose-600 hover:bg-rose-50 dark:text-rose-400 dark:hover:bg-rose-950/50\",\n};\n","import { forwardRef, type AnchorHTMLAttributes, type ElementType, type ForwardedRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { sanitizeHref } from \"../../utils/sanitize\";\nimport { resolve } from \"../../data/emoji-utils\";\nimport { Icon } from \"../Icon/Icon\";\nimport type { ButtonProps } from \"./Button.types\";\nimport type { ButtonColor, Size } from \"../../utils/types\";\nimport {\n buttonColorClasses as colorClasses,\n buttonGhostClasses as ghostColorClasses,\n} from \"./Button.colors\";\n\nconst iconSizeMap: Record<Size, \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"sm\",\n lg: \"md\",\n xl: \"lg\",\n};\n\nconst alertIconSizeMap: Record<Size, \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"xs\",\n lg: \"sm\",\n xl: \"sm\",\n};\n\n// ---------------------------------------------------------------------------\n// Color classes\n//\n// Solid + ghost color maps live in ./Button.colors (AUTO-GENERATED, all 22\n// Tailwind v4 hues as literal strings). The state-color classes below\n// (default/active/checked/warn) branch on flags, not specific colors.\n// ---------------------------------------------------------------------------\n\nconst defaultClasses =\n \"bg-white text-zinc-700 border border-zinc-200 hover:bg-zinc-50 hover:border-zinc-300 dark:bg-zinc-800 dark:text-zinc-300 dark:border-zinc-700 dark:hover:bg-zinc-700\";\n\nconst activeClasses =\n \"bg-blue-500 text-white border border-blue-600 hover:bg-blue-600 dark:bg-blue-600 dark:border-blue-500 dark:hover:bg-blue-500\";\n\nconst checkedClasses =\n \"bg-emerald-500 text-white border border-emerald-600 hover:bg-emerald-600 dark:bg-emerald-600 dark:border-emerald-500 dark:hover:bg-emerald-500\";\n\nconst warnClasses =\n \"bg-amber-50 text-amber-700 border border-amber-200 hover:bg-amber-100 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-700 dark:hover:bg-amber-900/50\";\n\nconst ghostDefaultClasses =\n \"bg-transparent text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800\";\n\nconst ghostActiveClasses =\n \"bg-blue-50 text-blue-700 hover:bg-blue-100 dark:bg-blue-950/50 dark:text-blue-300 dark:hover:bg-blue-950\";\n\nconst ghostCheckedClasses =\n \"bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:bg-emerald-950/50 dark:text-emerald-300 dark:hover:bg-emerald-950\";\n\nconst ghostWarnClasses =\n \"bg-transparent text-amber-700 hover:bg-amber-50 dark:text-amber-300 dark:hover:bg-amber-950/50\";\n\n// ---------------------------------------------------------------------------\n// Size helpers\n// ---------------------------------------------------------------------------\n\nconst horizontalSize: Record<Size, string> = {\n xs: \"px-2 py-1 text-xs\",\n sm: \"px-2 py-1 text-xs\",\n md: \"px-3 py-1.5 text-sm\",\n lg: \"px-4 py-2.5 text-base\",\n xl: \"px-5 py-3 text-lg\",\n};\n\nconst circleSize: Record<Size, string> = {\n xs: \"w-7 h-7 text-xs\",\n sm: \"w-8 h-8 text-xs\",\n md: \"w-10 h-10 text-sm\",\n lg: \"w-12 h-12 text-base\",\n xl: \"w-14 h-14 text-lg\",\n};\n\nconst iconSize: Record<Size, string> = {\n xs: \"w-3 h-3\",\n sm: \"w-3 h-3\",\n md: \"w-4 h-4\",\n lg: \"w-5 h-5\",\n xl: \"w-6 h-6\",\n};\n\nconst avatarSize: Record<Size, string> = {\n xs: \"w-4 h-4\",\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\",\n xl: \"w-7 h-7\",\n};\n\nconst alertIconSize: Record<Size, string> = {\n xs: \"w-2 h-2\",\n sm: \"w-2.5 h-2.5\",\n md: \"w-3 h-3\",\n lg: \"w-4 h-4\",\n xl: \"w-4 h-4\",\n};\n\nconst badgeSize: Record<Size, string> = {\n xs: \"text-[10px] px-1 min-w-[14px] h-3.5\",\n sm: \"text-[10px] px-1.5 min-w-[16px] h-4\",\n md: \"text-[11px] px-1.5 min-w-[18px] h-[18px]\",\n lg: \"text-xs px-2 min-w-[22px] h-5\",\n xl: \"text-xs px-2 min-w-[24px] h-5\",\n};\n\nconst externalIconOffset: Record<Size, string> = {\n xs: \"0.75rem\",\n sm: \"0.75rem\",\n md: \"1rem\",\n lg: \"1.25rem\",\n xl: \"1.5rem\",\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isColored(color?: ButtonColor, active?: boolean, checked?: boolean): boolean {\n return !!(color || active || checked);\n}\n\nfunction getColorClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n if (color) return ghostColorClasses[color];\n if (checked) return ghostCheckedClasses;\n if (active) return ghostActiveClasses;\n if (warn) return ghostWarnClasses;\n return ghostDefaultClasses;\n }\n if (color) return colorClasses[color];\n if (checked) return checkedClasses;\n if (active) return activeClasses;\n if (warn) return warnClasses;\n return defaultClasses;\n}\n\nfunction getIconColorClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n // Ghost variant: icon inherits currentColor from the button text\n return \"text-current\";\n }\n // A filled button's icon takes the label's colour — whatever that colour class\n // says, including a host's per-mode `text-brand-contrast` and the dark labels on\n // amber / yellow / lime. Hard-coded white was invisible on any light fill.\n if (color || active || checked) return \"text-current\";\n if (warn) return \"text-amber-600 dark:text-amber-400\";\n return \"text-zinc-500 dark:text-zinc-400\";\n}\n\nfunction getBadgeClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n return \"bg-current/10 text-current\";\n }\n // Tinted with the label's own colour, for the same reason as the icon.\n if (isColored(color, active, checked)) return \"bg-current/20 text-current\";\n if (warn) return \"bg-amber-200 text-amber-800 dark:bg-amber-800 dark:text-amber-200\";\n return \"bg-zinc-200 text-zinc-700 dark:bg-zinc-600 dark:text-zinc-200\";\n}\n\n// ---------------------------------------------------------------------------\n// Placement parsing\n// ---------------------------------------------------------------------------\n\ntype PlacementAxis = \"left\" | \"right\" | \"top\" | \"bottom\";\n\nfunction parsePlacement(iconPlace: string): { primary: PlacementAxis; secondary?: PlacementAxis } {\n const parts = iconPlace.split(\" \") as PlacementAxis[];\n return { primary: parts[0], secondary: parts[1] };\n}\n\nfunction isVerticalPrimary(primary: PlacementAxis): boolean {\n return primary === \"top\" || primary === \"bottom\";\n}\n\n// ---------------------------------------------------------------------------\n// Sort parsing\n// ---------------------------------------------------------------------------\n\ntype ElementKey = \"e\" | \"i\" | \"a\" | \"b\";\nconst DEFAULT_SORT = \"eiab\";\n\nfunction parseSortOrder(sort?: string): ElementKey[] {\n const chars = (sort ?? DEFAULT_SORT).split(\"\") as ElementKey[];\n const valid: ElementKey[] = [];\n const seen = new Set<string>();\n for (const c of chars) {\n if (\"eiab\".includes(c) && !seen.has(c)) {\n valid.push(c);\n seen.add(c);\n }\n }\n // Add missing keys in default order\n for (const c of DEFAULT_SORT.split(\"\") as ElementKey[]) {\n if (!seen.has(c)) valid.push(c);\n }\n return valid;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n className,\n variant = \"default\",\n color,\n size = \"md\",\n active,\n checked,\n warn,\n alert: alertProp,\n icon,\n iconTrailing,\n iconPlace = \"left\",\n alertIcon,\n alertIconTrailing,\n emoji,\n emojiTrailing,\n avatar,\n avatarTrailing,\n badge,\n badgeTrailing,\n sort,\n loading = false,\n disabled,\n href,\n as: As,\n responsive,\n labelClassName,\n ...props\n },\n ref,\n ) => {\n const isCircle = variant === \"circle\";\n const isGhost = variant === \"ghost\";\n const { primary, secondary } = parsePlacement(iconPlace);\n const isVertical = isVerticalPrimary(primary);\n const isCompound = !!secondary;\n const needsWrapper = isVertical || isCompound;\n const isReversed = iconPlace === \"right\";\n\n // -----------------------------------------------------------------------\n // Sizing — always use horizontalSize for the button itself\n // -----------------------------------------------------------------------\n const sizeClass = isCircle ? circleSize[size] : horizontalSize[size];\n\n // -----------------------------------------------------------------------\n // Build decorative elements\n // -----------------------------------------------------------------------\n const iconColorCls = getIconColorClasses(color, active, checked, warn, isGhost);\n\n const buildElement = (key: ElementKey, trailing: boolean): ReactNode => {\n switch (key) {\n case \"e\": {\n const slug = trailing ? emojiTrailing : emoji;\n if (!slug) return null;\n const char = resolve(slug);\n if (!char) return null;\n return (\n <span key={`emoji-${trailing ? \"t\" : \"l\"}`} data-action-emoji>\n {char}\n </span>\n );\n }\n case \"i\": {\n if (loading && !trailing) {\n return (\n <span\n key=\"spinner\"\n className={cn(\"animate-spin border-2 border-current border-t-transparent rounded-full\", iconSize[size])}\n />\n );\n }\n const iconSlug = trailing ? iconTrailing : icon;\n if (!iconSlug) return null;\n // For vertical/compound placements, icons render outside the button — not inside\n if (needsWrapper) return null;\n return (\n <span\n key={`icon-${trailing ? \"t\" : \"l\"}`}\n data-action-icon={trailing ? \"trailing\" : \"leading\"}\n className={cn(\"inline-flex items-center flex-shrink-0\", iconColorCls)}\n >\n <Icon name={iconSlug} size={iconSizeMap[size]} />\n </span>\n );\n }\n case \"a\": {\n if (!avatar) return null;\n const isTrailing = avatarTrailing ?? false;\n if (isTrailing !== trailing) return null;\n return (\n <img\n key=\"avatar\"\n src={avatar}\n alt=\"\"\n className={cn(avatarSize[size], \"rounded-full object-cover flex-shrink-0\")}\n data-action-avatar\n />\n );\n }\n case \"b\": {\n if (!badge) return null;\n const isTrailing = badgeTrailing ?? false;\n if (isTrailing !== trailing) return null;\n return (\n <span\n key=\"badge\"\n className={cn(\n \"inline-flex items-center justify-center font-medium rounded-full\",\n badgeSize[size],\n getBadgeClasses(color, active, checked, warn, isGhost),\n )}\n data-action-badge\n >\n {badge}\n </span>\n );\n }\n default:\n return null;\n }\n };\n\n // Alert icon element\n const renderAlertIcon = (trailing: boolean): ReactNode => {\n if (!alertIcon) return null;\n const isTrailing = alertIconTrailing ?? false;\n if (isTrailing !== trailing) return null;\n const alertIconEl = <Icon name={alertIcon} size={alertIconSizeMap[size]} />;\n return (\n <span\n key=\"alert-icon\"\n className=\"relative inline-flex flex-shrink-0\"\n data-action-alert\n >\n <span className=\"text-red-500 dark:text-red-400 animate-pulse\">\n {alertIconEl}\n </span>\n <span className=\"absolute inset-0 flex items-center justify-center text-red-400 dark:text-red-300 animate-ping opacity-75\">\n {alertIconEl}\n </span>\n </span>\n );\n };\n\n const sortOrder = parseSortOrder(sort);\n\n const leadingElements: ReactNode[] = [];\n const trailingElements: ReactNode[] = [];\n\n for (const key of sortOrder) {\n const leading = buildElement(key, false);\n if (leading) leadingElements.push(leading);\n const trailing = buildElement(key, true);\n if (trailing) trailingElements.push(trailing);\n }\n\n // Insert alert icon\n const leadingAlert = renderAlertIcon(false);\n if (leadingAlert) leadingElements.push(leadingAlert);\n const trailingAlert = renderAlertIcon(true);\n if (trailingAlert) trailingElements.push(trailingAlert);\n\n // -----------------------------------------------------------------------\n // Classes\n // -----------------------------------------------------------------------\n const classes = cn(\n // `text-left` overrides the UA <button> center default so a wrapped,\n // width-constrained multi-word label stacks left-aligned. Overridable —\n // twMerge lets a `text-center` / `text-right` in `className` win.\n \"inline-flex items-center justify-center text-left font-medium transition-all duration-200\",\n \"focus:outline-none focus:ring-2 focus:ring-offset-1\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n isCircle ? \"rounded-full\" : \"rounded-lg\",\n sizeClass,\n getColorClasses(color, active, checked, warn, isGhost),\n !isCircle && !needsWrapper && \"gap-2\",\n !isCircle && needsWrapper && \"gap-2\",\n isReversed && !needsWrapper && \"flex-row-reverse\",\n alertProp && \"animate-pulse\",\n className,\n );\n\n // -----------------------------------------------------------------------\n // Content\n // -----------------------------------------------------------------------\n const content = isCircle ? (\n <>\n {loading ? (\n <span\n className={cn(\n \"animate-spin border-2 border-current border-t-transparent rounded-full\",\n iconSize[size],\n )}\n />\n ) : (\n icon ? <Icon name={icon} size={iconSizeMap[size]} /> : children\n )}\n </>\n ) : (\n <>\n {leadingElements}\n {children != null && (\n <span\n data-react-fancy-button-label=\"\"\n className={cn(\n // A button label must stay on one line. When a host flex layout\n // squeezes the button, `whitespace-nowrap` keeps the label and any\n // trailing icon/arrow together instead of wrapping and stacking the\n // icon below it (the classic \"send\" over \"→\" break). `min-w-0` keeps\n // the span shrinkable so `truncate`/ellipsis still works; multi-line\n // wrapping is opt-in via `labelClassName` (\"whitespace-normal\") or\n // the `responsive` prop.\n \"min-w-0 whitespace-nowrap\",\n // `responsive` collapses to icon-only when squeezed, while keeping\n // the label readable to screen readers.\n responsive && \"sr-only sm:not-sr-only\",\n labelClassName,\n )}\n >\n {children}\n </span>\n )}\n {trailingElements}\n </>\n );\n\n // -----------------------------------------------------------------------\n // Build the button element\n // -----------------------------------------------------------------------\n const safeHref = sanitizeHref(href);\n // Anchor mode renders `as` when provided (e.g. a router's <Link> for\n // client-side navigation — Inertia, React Router, Next). Previously `as`\n // fell through ...props onto the <a> where React silently DROPS a\n // function-valued unknown attribute — so `<Button as={Link}>` looked fine\n // but did a full page load. `as` only applies in anchor mode; without an\n // href (or when disabled) the plain <button> renders as always.\n const Anchor = (As ?? \"a\") as ElementType;\n const buttonEl = safeHref && !disabled ? (\n // Anchor mode forwards the same rest props as the <button> branch so\n // onClick / target / rel / ref / ARIA / data-* reach the <a> (issue #7).\n <Anchor\n ref={ref as ForwardedRef<HTMLAnchorElement>}\n href={safeHref}\n className={classes}\n data-react-fancy-button=\"\"\n data-react-fancy-action=\"\"\n {...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {content}\n </Anchor>\n ) : (\n <button\n ref={ref}\n className={classes}\n disabled={disabled || loading}\n data-react-fancy-button=\"\"\n data-react-fancy-action=\"\"\n {...props}\n >\n {content}\n </button>\n );\n\n // -----------------------------------------------------------------------\n // Wrap for vertical/compound icon placement\n // The icon is absolutely positioned so it never shifts the button.\n // -----------------------------------------------------------------------\n if (needsWrapper && (icon || iconTrailing)) {\n const iconSlug = icon ?? iconTrailing;\n const offset = externalIconOffset[size];\n\n // Determine position styles for the icon\n const posStyle: React.CSSProperties = { position: \"absolute\" };\n\n // Primary axis: which side of the button\n if (primary === \"top\") {\n posStyle.bottom = \"100%\";\n posStyle.marginBottom = \"0.125rem\";\n } else if (primary === \"bottom\") {\n posStyle.top = \"100%\";\n posStyle.marginTop = \"0.125rem\";\n } else if (primary === \"left\") {\n posStyle.right = \"100%\";\n posStyle.marginRight = \"0.125rem\";\n } else if (primary === \"right\") {\n posStyle.left = \"100%\";\n posStyle.marginLeft = \"0.125rem\";\n }\n\n // Secondary axis: cross-axis alignment\n if (isVerticalPrimary(primary)) {\n // Vertical primary → secondary controls horizontal position\n if (secondary === \"left\") {\n posStyle.left = \"0\";\n } else if (secondary === \"right\") {\n posStyle.right = \"0\";\n } else {\n // center (default)\n posStyle.left = \"50%\";\n posStyle.transform = \"translateX(-50%)\";\n }\n } else {\n // Horizontal primary → secondary controls vertical position\n if (secondary === \"top\") {\n posStyle.top = \"0\";\n } else if (secondary === \"bottom\") {\n posStyle.bottom = \"0\";\n } else {\n // center (default)\n posStyle.top = \"50%\";\n posStyle.transform = \"translateY(-50%)\";\n }\n }\n\n const externalIcon = (\n <span\n className={cn(\"absolute flex-shrink-0\", iconColorCls)}\n style={posStyle}\n >\n <Icon name={iconSlug!} size={iconSizeMap[size]} />\n </span>\n );\n\n return (\n <span\n data-react-fancy-action-group=\"\"\n className=\"relative inline-flex\"\n >\n {buttonEl}\n {externalIcon}\n </span>\n );\n }\n\n return buttonEl;\n },\n);\n\nButton.displayName = \"Button\";\n\n/**\n * @deprecated Renamed to {@link Button}. `Action` remains as an alias for\n * backward compatibility and will be removed in a future major version.\n * Prefer importing `Button` from \"@particle-academy/react-fancy\".\n */\nexport const Action = Button;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/Button/Button.colors.ts","../src/components/Button/Button.tsx"],"names":["forwardRef","resolve","jsx","cn","Icon","jsxs","Fragment","sanitizeHref"],"mappings":"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","file":"chunk-FWA4PCW7.cjs","sourcesContent":["// AUTO-GENERATED by scripts/gen-button-colors — do not edit by hand.\n// Literal Tailwind class strings for every color in the v4 palette so the\n// scanner can detect them in the published dist (template-built names are\n// invisible to Tailwind's JIT). Regenerate after changing the palette.\nimport type { Color } from \"../../utils/types\";\n\nexport const buttonColorClasses: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-brand text-brand-contrast border border-brand hover:bg-brand-hover\",\n slate: \"bg-slate-500 text-white border border-slate-600 hover:bg-slate-600 dark:bg-slate-600 dark:border-slate-500 dark:hover:bg-slate-500\",\n gray: \"bg-gray-500 text-white border border-gray-600 hover:bg-gray-600 dark:bg-gray-600 dark:border-gray-500 dark:hover:bg-gray-500\",\n zinc: \"bg-zinc-500 text-white border border-zinc-600 hover:bg-zinc-600 dark:bg-zinc-600 dark:border-zinc-500 dark:hover:bg-zinc-500\",\n neutral: \"bg-neutral-500 text-white border border-neutral-600 hover:bg-neutral-600 dark:bg-neutral-600 dark:border-neutral-500 dark:hover:bg-neutral-500\",\n stone: \"bg-stone-500 text-white border border-stone-600 hover:bg-stone-600 dark:bg-stone-600 dark:border-stone-500 dark:hover:bg-stone-500\",\n red: \"bg-red-500 text-white border border-red-600 hover:bg-red-600 dark:bg-red-600 dark:border-red-500 dark:hover:bg-red-500\",\n orange: \"bg-orange-500 text-white border border-orange-600 hover:bg-orange-600 dark:bg-orange-600 dark:border-orange-500 dark:hover:bg-orange-500\",\n amber: \"bg-amber-400 text-amber-950 border border-amber-500 hover:bg-amber-500 dark:bg-amber-300 dark:text-amber-950 dark:border-amber-400 dark:hover:bg-amber-400\",\n yellow: \"bg-yellow-400 text-yellow-950 border border-yellow-500 hover:bg-yellow-500 dark:bg-yellow-300 dark:text-yellow-950 dark:border-yellow-400 dark:hover:bg-yellow-400\",\n lime: \"bg-lime-400 text-lime-950 border border-lime-500 hover:bg-lime-500 dark:bg-lime-300 dark:text-lime-950 dark:border-lime-400 dark:hover:bg-lime-400\",\n green: \"bg-green-500 text-white border border-green-600 hover:bg-green-600 dark:bg-green-600 dark:border-green-500 dark:hover:bg-green-500\",\n emerald: \"bg-emerald-500 text-white border border-emerald-600 hover:bg-emerald-600 dark:bg-emerald-600 dark:border-emerald-500 dark:hover:bg-emerald-500\",\n teal: \"bg-teal-500 text-white border border-teal-600 hover:bg-teal-600 dark:bg-teal-600 dark:border-teal-500 dark:hover:bg-teal-500\",\n cyan: \"bg-cyan-500 text-white border border-cyan-600 hover:bg-cyan-600 dark:bg-cyan-600 dark:border-cyan-500 dark:hover:bg-cyan-500\",\n sky: \"bg-sky-500 text-white border border-sky-600 hover:bg-sky-600 dark:bg-sky-600 dark:border-sky-500 dark:hover:bg-sky-500\",\n blue: \"bg-blue-500 text-white border border-blue-600 hover:bg-blue-600 dark:bg-blue-600 dark:border-blue-500 dark:hover:bg-blue-500\",\n indigo: \"bg-indigo-500 text-white border border-indigo-600 hover:bg-indigo-600 dark:bg-indigo-600 dark:border-indigo-500 dark:hover:bg-indigo-500\",\n violet: \"bg-violet-500 text-white border border-violet-600 hover:bg-violet-600 dark:bg-violet-600 dark:border-violet-500 dark:hover:bg-violet-500\",\n purple: \"bg-purple-500 text-white border border-purple-600 hover:bg-purple-600 dark:bg-purple-600 dark:border-purple-500 dark:hover:bg-purple-500\",\n fuchsia: \"bg-fuchsia-500 text-white border border-fuchsia-600 hover:bg-fuchsia-600 dark:bg-fuchsia-600 dark:border-fuchsia-500 dark:hover:bg-fuchsia-500\",\n pink: \"bg-pink-500 text-white border border-pink-600 hover:bg-pink-600 dark:bg-pink-600 dark:border-pink-500 dark:hover:bg-pink-500\",\n rose: \"bg-rose-500 text-white border border-rose-600 hover:bg-rose-600 dark:bg-rose-600 dark:border-rose-500 dark:hover:bg-rose-500\",\n};\n\nexport const buttonGhostClasses: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-transparent text-brand hover:bg-brand/10\",\n slate: \"bg-transparent text-slate-600 hover:bg-slate-50 dark:text-slate-400 dark:hover:bg-slate-950/50\",\n gray: \"bg-transparent text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-950/50\",\n zinc: \"bg-transparent text-zinc-600 hover:bg-zinc-50 dark:text-zinc-400 dark:hover:bg-zinc-950/50\",\n neutral: \"bg-transparent text-neutral-600 hover:bg-neutral-50 dark:text-neutral-400 dark:hover:bg-neutral-950/50\",\n stone: \"bg-transparent text-stone-600 hover:bg-stone-50 dark:text-stone-400 dark:hover:bg-stone-950/50\",\n red: \"bg-transparent text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/50\",\n orange: \"bg-transparent text-orange-600 hover:bg-orange-50 dark:text-orange-400 dark:hover:bg-orange-950/50\",\n amber: \"bg-transparent text-amber-600 hover:bg-amber-50 dark:text-amber-400 dark:hover:bg-amber-950/50\",\n yellow: \"bg-transparent text-yellow-600 hover:bg-yellow-50 dark:text-yellow-400 dark:hover:bg-yellow-950/50\",\n lime: \"bg-transparent text-lime-600 hover:bg-lime-50 dark:text-lime-400 dark:hover:bg-lime-950/50\",\n green: \"bg-transparent text-green-600 hover:bg-green-50 dark:text-green-400 dark:hover:bg-green-950/50\",\n emerald: \"bg-transparent text-emerald-600 hover:bg-emerald-50 dark:text-emerald-400 dark:hover:bg-emerald-950/50\",\n teal: \"bg-transparent text-teal-600 hover:bg-teal-50 dark:text-teal-400 dark:hover:bg-teal-950/50\",\n cyan: \"bg-transparent text-cyan-600 hover:bg-cyan-50 dark:text-cyan-400 dark:hover:bg-cyan-950/50\",\n sky: \"bg-transparent text-sky-600 hover:bg-sky-50 dark:text-sky-400 dark:hover:bg-sky-950/50\",\n blue: \"bg-transparent text-blue-600 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-950/50\",\n indigo: \"bg-transparent text-indigo-600 hover:bg-indigo-50 dark:text-indigo-400 dark:hover:bg-indigo-950/50\",\n violet: \"bg-transparent text-violet-600 hover:bg-violet-50 dark:text-violet-400 dark:hover:bg-violet-950/50\",\n purple: \"bg-transparent text-purple-600 hover:bg-purple-50 dark:text-purple-400 dark:hover:bg-purple-950/50\",\n fuchsia: \"bg-transparent text-fuchsia-600 hover:bg-fuchsia-50 dark:text-fuchsia-400 dark:hover:bg-fuchsia-950/50\",\n pink: \"bg-transparent text-pink-600 hover:bg-pink-50 dark:text-pink-400 dark:hover:bg-pink-950/50\",\n rose: \"bg-transparent text-rose-600 hover:bg-rose-50 dark:text-rose-400 dark:hover:bg-rose-950/50\",\n};\n","import { forwardRef, type AnchorHTMLAttributes, type ElementType, type ForwardedRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { sanitizeHref } from \"../../utils/sanitize\";\nimport { resolve } from \"../../data/emoji-utils\";\nimport { Icon } from \"../Icon/Icon\";\nimport type { ButtonProps } from \"./Button.types\";\nimport type { ButtonColor, Size } from \"../../utils/types\";\nimport {\n buttonColorClasses as colorClasses,\n buttonGhostClasses as ghostColorClasses,\n} from \"./Button.colors\";\n\nconst iconSizeMap: Record<Size, \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"sm\",\n lg: \"md\",\n xl: \"lg\",\n};\n\nconst alertIconSizeMap: Record<Size, \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"xs\",\n lg: \"sm\",\n xl: \"sm\",\n};\n\n// ---------------------------------------------------------------------------\n// Color classes\n//\n// Solid + ghost color maps live in ./Button.colors (AUTO-GENERATED, all 22\n// Tailwind v4 hues as literal strings). The state-color classes below\n// (default/active/checked/warn) branch on flags, not specific colors.\n// ---------------------------------------------------------------------------\n\nconst defaultClasses =\n \"bg-white text-zinc-700 border border-zinc-200 hover:bg-zinc-50 hover:border-zinc-300 dark:bg-zinc-800 dark:text-zinc-300 dark:border-zinc-700 dark:hover:bg-zinc-700\";\n\nconst activeClasses =\n \"bg-blue-500 text-white border border-blue-600 hover:bg-blue-600 dark:bg-blue-600 dark:border-blue-500 dark:hover:bg-blue-500\";\n\nconst checkedClasses =\n \"bg-emerald-500 text-white border border-emerald-600 hover:bg-emerald-600 dark:bg-emerald-600 dark:border-emerald-500 dark:hover:bg-emerald-500\";\n\nconst warnClasses =\n \"bg-amber-50 text-amber-700 border border-amber-200 hover:bg-amber-100 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-700 dark:hover:bg-amber-900/50\";\n\nconst ghostDefaultClasses =\n \"bg-transparent text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800\";\n\nconst ghostActiveClasses =\n \"bg-blue-50 text-blue-700 hover:bg-blue-100 dark:bg-blue-950/50 dark:text-blue-300 dark:hover:bg-blue-950\";\n\nconst ghostCheckedClasses =\n \"bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:bg-emerald-950/50 dark:text-emerald-300 dark:hover:bg-emerald-950\";\n\nconst ghostWarnClasses =\n \"bg-transparent text-amber-700 hover:bg-amber-50 dark:text-amber-300 dark:hover:bg-amber-950/50\";\n\n// ---------------------------------------------------------------------------\n// Size helpers\n// ---------------------------------------------------------------------------\n\nconst horizontalSize: Record<Size, string> = {\n xs: \"px-2 py-1 text-xs\",\n sm: \"px-2 py-1 text-xs\",\n md: \"px-3 py-1.5 text-sm\",\n lg: \"px-4 py-2.5 text-base\",\n xl: \"px-5 py-3 text-lg\",\n};\n\nconst circleSize: Record<Size, string> = {\n xs: \"w-7 h-7 text-xs\",\n sm: \"w-8 h-8 text-xs\",\n md: \"w-10 h-10 text-sm\",\n lg: \"w-12 h-12 text-base\",\n xl: \"w-14 h-14 text-lg\",\n};\n\nconst iconSize: Record<Size, string> = {\n xs: \"w-3 h-3\",\n sm: \"w-3 h-3\",\n md: \"w-4 h-4\",\n lg: \"w-5 h-5\",\n xl: \"w-6 h-6\",\n};\n\nconst avatarSize: Record<Size, string> = {\n xs: \"w-4 h-4\",\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\",\n xl: \"w-7 h-7\",\n};\n\nconst alertIconSize: Record<Size, string> = {\n xs: \"w-2 h-2\",\n sm: \"w-2.5 h-2.5\",\n md: \"w-3 h-3\",\n lg: \"w-4 h-4\",\n xl: \"w-4 h-4\",\n};\n\nconst badgeSize: Record<Size, string> = {\n xs: \"text-[10px] px-1 min-w-[14px] h-3.5\",\n sm: \"text-[10px] px-1.5 min-w-[16px] h-4\",\n md: \"text-[11px] px-1.5 min-w-[18px] h-[18px]\",\n lg: \"text-xs px-2 min-w-[22px] h-5\",\n xl: \"text-xs px-2 min-w-[24px] h-5\",\n};\n\nconst externalIconOffset: Record<Size, string> = {\n xs: \"0.75rem\",\n sm: \"0.75rem\",\n md: \"1rem\",\n lg: \"1.25rem\",\n xl: \"1.5rem\",\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isColored(color?: ButtonColor, active?: boolean, checked?: boolean): boolean {\n return !!(color || active || checked);\n}\n\nfunction getColorClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n if (color) return ghostColorClasses[color];\n if (checked) return ghostCheckedClasses;\n if (active) return ghostActiveClasses;\n if (warn) return ghostWarnClasses;\n return ghostDefaultClasses;\n }\n if (color) return colorClasses[color];\n if (checked) return checkedClasses;\n if (active) return activeClasses;\n if (warn) return warnClasses;\n return defaultClasses;\n}\n\nfunction getIconColorClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n // Ghost variant: icon inherits currentColor from the button text\n return \"text-current\";\n }\n // A filled button's icon takes the label's colour — whatever that colour class\n // says, including a host's per-mode `text-brand-contrast` and the dark labels on\n // amber / yellow / lime. Hard-coded white was invisible on any light fill.\n if (color || active || checked) return \"text-current\";\n if (warn) return \"text-amber-600 dark:text-amber-400\";\n return \"text-zinc-500 dark:text-zinc-400\";\n}\n\nfunction getBadgeClasses(\n color?: ButtonColor,\n active?: boolean,\n checked?: boolean,\n warn?: boolean,\n ghost?: boolean,\n): string {\n if (ghost) {\n return \"bg-current/10 text-current\";\n }\n // Tinted with the label's own colour, for the same reason as the icon.\n if (isColored(color, active, checked)) return \"bg-current/20 text-current\";\n if (warn) return \"bg-amber-200 text-amber-800 dark:bg-amber-800 dark:text-amber-200\";\n return \"bg-zinc-200 text-zinc-700 dark:bg-zinc-600 dark:text-zinc-200\";\n}\n\n// ---------------------------------------------------------------------------\n// Placement parsing\n// ---------------------------------------------------------------------------\n\ntype PlacementAxis = \"left\" | \"right\" | \"top\" | \"bottom\";\n\nfunction parsePlacement(iconPlace: string): { primary: PlacementAxis; secondary?: PlacementAxis } {\n const parts = iconPlace.split(\" \") as PlacementAxis[];\n return { primary: parts[0], secondary: parts[1] };\n}\n\nfunction isVerticalPrimary(primary: PlacementAxis): boolean {\n return primary === \"top\" || primary === \"bottom\";\n}\n\n// ---------------------------------------------------------------------------\n// Sort parsing\n// ---------------------------------------------------------------------------\n\ntype ElementKey = \"e\" | \"i\" | \"a\" | \"b\";\nconst DEFAULT_SORT = \"eiab\";\n\nfunction parseSortOrder(sort?: string): ElementKey[] {\n const chars = (sort ?? DEFAULT_SORT).split(\"\") as ElementKey[];\n const valid: ElementKey[] = [];\n const seen = new Set<string>();\n for (const c of chars) {\n if (\"eiab\".includes(c) && !seen.has(c)) {\n valid.push(c);\n seen.add(c);\n }\n }\n // Add missing keys in default order\n for (const c of DEFAULT_SORT.split(\"\") as ElementKey[]) {\n if (!seen.has(c)) valid.push(c);\n }\n return valid;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n className,\n variant = \"default\",\n color,\n size = \"md\",\n active,\n checked,\n warn,\n alert: alertProp,\n icon,\n iconTrailing,\n iconPlace = \"left\",\n alertIcon,\n alertIconTrailing,\n emoji,\n emojiTrailing,\n avatar,\n avatarTrailing,\n badge,\n badgeTrailing,\n sort,\n loading = false,\n disabled,\n href,\n as: As,\n responsive,\n labelClassName,\n ...props\n },\n ref,\n ) => {\n const isCircle = variant === \"circle\";\n const isGhost = variant === \"ghost\";\n const { primary, secondary } = parsePlacement(iconPlace);\n const isVertical = isVerticalPrimary(primary);\n const isCompound = !!secondary;\n const needsWrapper = isVertical || isCompound;\n const isReversed = iconPlace === \"right\";\n\n // -----------------------------------------------------------------------\n // Sizing — always use horizontalSize for the button itself\n // -----------------------------------------------------------------------\n const sizeClass = isCircle ? circleSize[size] : horizontalSize[size];\n\n // -----------------------------------------------------------------------\n // Build decorative elements\n // -----------------------------------------------------------------------\n const iconColorCls = getIconColorClasses(color, active, checked, warn, isGhost);\n\n const buildElement = (key: ElementKey, trailing: boolean): ReactNode => {\n switch (key) {\n case \"e\": {\n const slug = trailing ? emojiTrailing : emoji;\n if (!slug) return null;\n const char = resolve(slug);\n if (!char) return null;\n return (\n <span key={`emoji-${trailing ? \"t\" : \"l\"}`} data-action-emoji>\n {char}\n </span>\n );\n }\n case \"i\": {\n if (loading && !trailing) {\n return (\n <span\n key=\"spinner\"\n className={cn(\"animate-spin border-2 border-current border-t-transparent rounded-full\", iconSize[size])}\n />\n );\n }\n const iconSlug = trailing ? iconTrailing : icon;\n if (!iconSlug) return null;\n // For vertical/compound placements, icons render outside the button — not inside\n if (needsWrapper) return null;\n return (\n <span\n key={`icon-${trailing ? \"t\" : \"l\"}`}\n data-action-icon={trailing ? \"trailing\" : \"leading\"}\n className={cn(\"inline-flex items-center flex-shrink-0\", iconColorCls)}\n >\n <Icon name={iconSlug} size={iconSizeMap[size]} />\n </span>\n );\n }\n case \"a\": {\n if (!avatar) return null;\n const isTrailing = avatarTrailing ?? false;\n if (isTrailing !== trailing) return null;\n return (\n <img\n key=\"avatar\"\n src={avatar}\n alt=\"\"\n className={cn(avatarSize[size], \"rounded-full object-cover flex-shrink-0\")}\n data-action-avatar\n />\n );\n }\n case \"b\": {\n if (!badge) return null;\n const isTrailing = badgeTrailing ?? false;\n if (isTrailing !== trailing) return null;\n return (\n <span\n key=\"badge\"\n className={cn(\n \"inline-flex items-center justify-center font-medium rounded-full\",\n badgeSize[size],\n getBadgeClasses(color, active, checked, warn, isGhost),\n )}\n data-action-badge\n >\n {badge}\n </span>\n );\n }\n default:\n return null;\n }\n };\n\n // Alert icon element\n const renderAlertIcon = (trailing: boolean): ReactNode => {\n if (!alertIcon) return null;\n const isTrailing = alertIconTrailing ?? false;\n if (isTrailing !== trailing) return null;\n const alertIconEl = <Icon name={alertIcon} size={alertIconSizeMap[size]} />;\n return (\n <span\n key=\"alert-icon\"\n className=\"relative inline-flex flex-shrink-0\"\n data-action-alert\n >\n <span className=\"text-red-500 dark:text-red-400 animate-pulse\">\n {alertIconEl}\n </span>\n <span className=\"absolute inset-0 flex items-center justify-center text-red-400 dark:text-red-300 animate-ping opacity-75\">\n {alertIconEl}\n </span>\n </span>\n );\n };\n\n const sortOrder = parseSortOrder(sort);\n\n const leadingElements: ReactNode[] = [];\n const trailingElements: ReactNode[] = [];\n\n for (const key of sortOrder) {\n const leading = buildElement(key, false);\n if (leading) leadingElements.push(leading);\n const trailing = buildElement(key, true);\n if (trailing) trailingElements.push(trailing);\n }\n\n // Insert alert icon\n const leadingAlert = renderAlertIcon(false);\n if (leadingAlert) leadingElements.push(leadingAlert);\n const trailingAlert = renderAlertIcon(true);\n if (trailingAlert) trailingElements.push(trailingAlert);\n\n // -----------------------------------------------------------------------\n // Classes\n // -----------------------------------------------------------------------\n const classes = cn(\n // `text-left` overrides the UA <button> center default so a wrapped,\n // width-constrained multi-word label stacks left-aligned. Overridable —\n // twMerge lets a `text-center` / `text-right` in `className` win.\n \"inline-flex items-center justify-center text-left font-medium transition-all duration-200\",\n \"focus:outline-none focus:ring-2 focus:ring-offset-1\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n isCircle ? \"rounded-full\" : \"rounded-lg\",\n sizeClass,\n getColorClasses(color, active, checked, warn, isGhost),\n !isCircle && !needsWrapper && \"gap-2\",\n !isCircle && needsWrapper && \"gap-2\",\n isReversed && !needsWrapper && \"flex-row-reverse\",\n alertProp && \"animate-pulse\",\n className,\n );\n\n // -----------------------------------------------------------------------\n // Content\n // -----------------------------------------------------------------------\n const content = isCircle ? (\n <>\n {loading ? (\n <span\n className={cn(\n \"animate-spin border-2 border-current border-t-transparent rounded-full\",\n iconSize[size],\n )}\n />\n ) : (\n icon ? <Icon name={icon} size={iconSizeMap[size]} /> : children\n )}\n </>\n ) : (\n <>\n {leadingElements}\n {children != null && (\n <span\n data-react-fancy-button-label=\"\"\n className={cn(\n // A button label must stay on one line. When a host flex layout\n // squeezes the button, `whitespace-nowrap` keeps the label and any\n // trailing icon/arrow together instead of wrapping and stacking the\n // icon below it (the classic \"send\" over \"→\" break). `min-w-0` keeps\n // the span shrinkable so `truncate`/ellipsis still works; multi-line\n // wrapping is opt-in via `labelClassName` (\"whitespace-normal\") or\n // the `responsive` prop.\n \"min-w-0 whitespace-nowrap\",\n // `responsive` collapses to icon-only when squeezed, while keeping\n // the label readable to screen readers.\n responsive && \"sr-only sm:not-sr-only\",\n labelClassName,\n )}\n >\n {children}\n </span>\n )}\n {trailingElements}\n </>\n );\n\n // -----------------------------------------------------------------------\n // Build the button element\n // -----------------------------------------------------------------------\n const safeHref = sanitizeHref(href);\n // Anchor mode renders `as` when provided (e.g. a router's <Link> for\n // client-side navigation — Inertia, React Router, Next). Previously `as`\n // fell through ...props onto the <a> where React silently DROPS a\n // function-valued unknown attribute — so `<Button as={Link}>` looked fine\n // but did a full page load. `as` only applies in anchor mode; without an\n // href (or when disabled) the plain <button> renders as always.\n const Anchor = (As ?? \"a\") as ElementType;\n const buttonEl = safeHref && !disabled ? (\n // Anchor mode forwards the same rest props as the <button> branch so\n // onClick / target / rel / ref / ARIA / data-* reach the <a> (issue #7).\n <Anchor\n ref={ref as ForwardedRef<HTMLAnchorElement>}\n href={safeHref}\n className={classes}\n data-react-fancy-button=\"\"\n data-react-fancy-action=\"\"\n {...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {content}\n </Anchor>\n ) : (\n <button\n ref={ref}\n className={classes}\n disabled={disabled || loading}\n data-react-fancy-button=\"\"\n data-react-fancy-action=\"\"\n {...props}\n >\n {content}\n </button>\n );\n\n // -----------------------------------------------------------------------\n // Wrap for vertical/compound icon placement\n // The icon is absolutely positioned so it never shifts the button.\n // -----------------------------------------------------------------------\n if (needsWrapper && (icon || iconTrailing)) {\n const iconSlug = icon ?? iconTrailing;\n const offset = externalIconOffset[size];\n\n // Determine position styles for the icon\n const posStyle: React.CSSProperties = { position: \"absolute\" };\n\n // Primary axis: which side of the button\n if (primary === \"top\") {\n posStyle.bottom = \"100%\";\n posStyle.marginBottom = \"0.125rem\";\n } else if (primary === \"bottom\") {\n posStyle.top = \"100%\";\n posStyle.marginTop = \"0.125rem\";\n } else if (primary === \"left\") {\n posStyle.right = \"100%\";\n posStyle.marginRight = \"0.125rem\";\n } else if (primary === \"right\") {\n posStyle.left = \"100%\";\n posStyle.marginLeft = \"0.125rem\";\n }\n\n // Secondary axis: cross-axis alignment\n if (isVerticalPrimary(primary)) {\n // Vertical primary → secondary controls horizontal position\n if (secondary === \"left\") {\n posStyle.left = \"0\";\n } else if (secondary === \"right\") {\n posStyle.right = \"0\";\n } else {\n // center (default)\n posStyle.left = \"50%\";\n posStyle.transform = \"translateX(-50%)\";\n }\n } else {\n // Horizontal primary → secondary controls vertical position\n if (secondary === \"top\") {\n posStyle.top = \"0\";\n } else if (secondary === \"bottom\") {\n posStyle.bottom = \"0\";\n } else {\n // center (default)\n posStyle.top = \"50%\";\n posStyle.transform = \"translateY(-50%)\";\n }\n }\n\n const externalIcon = (\n <span\n className={cn(\"absolute flex-shrink-0\", iconColorCls)}\n style={posStyle}\n >\n <Icon name={iconSlug!} size={iconSizeMap[size]} />\n </span>\n );\n\n return (\n <span\n data-react-fancy-action-group=\"\"\n className=\"relative inline-flex\"\n >\n {buttonEl}\n {externalIcon}\n </span>\n );\n }\n\n return buttonEl;\n },\n);\n\nButton.displayName = \"Button\";\n\n/**\n * @deprecated Renamed to {@link Button}. `Action` remains as an alias for\n * backward compatibility and will be removed in a future major version.\n * Prefer importing `Button` from \"@particle-academy/react-fancy\".\n */\nexport const Action = Button;\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkWKNVZUWZ_cjs = require('./chunk-WKNVZUWZ.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkFWA4PCW7_cjs = require('./chunk-FWA4PCW7.cjs');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
7
7
|
var CONFIDENCE_TIERS = [
|
|
@@ -109,11 +109,11 @@ function ReasonTag({
|
|
|
109
109
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-zinc-400", children: "sources" }),
|
|
110
110
|
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-0.5 space-y-0.5 text-[12px]", children: sources.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: s.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { className: "text-violet-600 hover:underline", href: s.href, children: s.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-600 dark:text-zinc-300", children: s.label }) }, i)) })
|
|
111
111
|
] }),
|
|
112
|
-
onFollowUp && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
112
|
+
onFollowUp && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(chunkFWA4PCW7_cjs.Button, { size: "sm", variant: "ghost", onClick: onFollowUp, children: "ask follow-up" }) })
|
|
113
113
|
] }) })
|
|
114
114
|
] });
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
exports.ReasonTag = ReasonTag;
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
119
|
-
//# sourceMappingURL=chunk-
|
|
118
|
+
//# sourceMappingURL=chunk-GCWIZNN2.cjs.map
|
|
119
|
+
//# sourceMappingURL=chunk-GCWIZNN2.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ReasonTag/ReasonTag.tsx"],"names":["jsxs","jsx","Popover","Button"],"mappings":"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","file":"chunk-EEKXWXYO.cjs","sourcesContent":["import { Popover } from \"../Popover\";\nimport { Button } from \"../Button\";\n\n/**\n * ReasonTag — wraps any value with a small affordance that reveals the\n * agent's reasoning, sources, and confidence on hover or click.\n *\n * <ReasonTag\n * value=\"$1.4M\"\n * reason=\"Projected Q3 ARR after stacking renewals.\"\n * confidence={0.91}\n * sources={[{ label: \"Q2 actuals · CRM export\" }]}\n * by=\"Forecaster\"\n * />\n *\n * Three visual styles:\n * • \"dot\" — value with a tiny coloured dot (default, subtle)\n * • \"underline\" — dotted underline + trailing \"?\"\n * • \"chip\" — full coloured pill (loud)\n *\n * Confidence drives the colour via three tiers (high / medium / low),\n * so a quick visual scan tells the human which suggestions deserve a\n * second look without opening any tooltips.\n *\n * `pinned` swaps the popover for an inline annotation slot — useful\n * when explainability should always be visible, not buried in a hover.\n */\nexport type ReasonTagSource = { label: string; href?: string };\n\nexport type ReasonTagTheme = \"dot\" | \"underline\" | \"chip\";\n\nexport interface ReasonTagProps {\n /** The value the tag wraps — usually a number, label, or short phrase. */\n value: React.ReactNode;\n /** Free-text rationale shown in the popover / inline annotation. */\n reason: string;\n /** 0..1 confidence. Drives the tier colour. Defaults to 1. */\n confidence?: number;\n /** Optional list of sources (label + optional href). */\n sources?: ReasonTagSource[];\n /** Optional author / agent name shown in the popover header. */\n by?: string;\n /** Visual treatment for the trigger. */\n theme?: ReasonTagTheme;\n /**\n * When true, the popover is replaced with an always-visible inline\n * annotation below the value.\n */\n pinned?: boolean;\n /** Called when the user hits the \"ask follow-up\" action. */\n onFollowUp?: () => void;\n /** Optional className applied to the trigger element. */\n className?: string;\n}\n\nconst CONFIDENCE_TIERS: Array<{ min: number; color: string; label: string }> = [\n { min: 0.85, color: \"#10b981\", label: \"high\" },\n { min: 0.6, color: \"#f59e0b\", label: \"medium\" },\n { min: 0, color: \"#ef4444\", label: \"low\" },\n];\n\nfunction tier(c: number) {\n return CONFIDENCE_TIERS.find((t) => c >= t.min) ?? CONFIDENCE_TIERS[2];\n}\n\nexport function ReasonTag({\n value,\n reason,\n confidence = 1,\n sources = [],\n by,\n theme = \"dot\",\n pinned = false,\n onFollowUp,\n className,\n}: ReasonTagProps) {\n const t = tier(confidence);\n\n const trigger =\n theme === \"chip\" ? (\n <span\n className={`inline-flex cursor-help items-center gap-1 rounded-full px-2 py-0.5 text-[12px] font-medium ${className ?? \"\"}`}\n style={{ backgroundColor: t.color + \"22\", color: t.color }}\n >\n <span\n className=\"h-1.5 w-1.5 rounded-full\"\n style={{ backgroundColor: t.color }}\n />\n {value}\n <span className=\"text-[10px] opacity-70\">?</span>\n </span>\n ) : theme === \"underline\" ? (\n <span\n className={`cursor-help underline decoration-dotted underline-offset-2 ${className ?? \"\"}`}\n style={{ textDecorationColor: t.color }}\n >\n {value}\n <span\n className=\"ml-0.5 font-mono text-[10px]\"\n style={{ color: t.color }}\n >\n ?\n </span>\n </span>\n ) : (\n <span className={`inline-flex cursor-help items-baseline gap-1 ${className ?? \"\"}`}>\n <span className=\"font-medium\">{value}</span>\n <span\n className=\"inline-block h-1.5 w-1.5 rounded-full align-middle\"\n style={{ backgroundColor: t.color }}\n title=\"reason available\"\n />\n </span>\n );\n\n if (pinned) {\n return (\n <span className=\"inline-flex flex-col items-start gap-0.5 align-top\">\n {trigger}\n <span\n className=\"block max-w-[280px] rounded border-l-2 pl-2 text-[11px] leading-snug text-zinc-600 dark:text-zinc-300\"\n style={{ borderColor: t.color }}\n >\n {reason}\n </span>\n </span>\n );\n }\n\n return (\n <Popover hover>\n <Popover.Trigger>{trigger}</Popover.Trigger>\n <Popover.Content>\n <div className=\"w-72 space-y-2 text-sm\">\n <div className=\"flex items-baseline gap-2\">\n <span\n className=\"text-[10px] font-semibold uppercase tracking-wider\"\n style={{ color: t.color }}\n >\n {t.label} confidence · {(confidence * 100).toFixed(0)}%\n </span>\n {by && (\n <span className=\"ml-auto font-mono text-[10px] text-zinc-400\">\n @{by}\n </span>\n )}\n </div>\n <p className=\"text-[13px] leading-snug text-zinc-700 dark:text-zinc-200\">\n {reason}\n </p>\n {sources.length > 0 && (\n <div>\n <div className=\"text-[10px] uppercase tracking-wider text-zinc-400\">\n sources\n </div>\n <ul className=\"mt-0.5 space-y-0.5 text-[12px]\">\n {sources.map((s, i) => (\n <li key={i}>\n {s.href ? (\n <a className=\"text-violet-600 hover:underline\" href={s.href}>\n {s.label}\n </a>\n ) : (\n <span className=\"text-zinc-600 dark:text-zinc-300\">\n {s.label}\n </span>\n )}\n </li>\n ))}\n </ul>\n </div>\n )}\n {onFollowUp && (\n <div className=\"flex justify-end pt-1\">\n <Button size=\"sm\" variant=\"ghost\" onClick={onFollowUp}>\n ask follow-up\n </Button>\n </div>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ReasonTag/ReasonTag.tsx"],"names":["jsxs","jsx","Popover","Button"],"mappings":";;;;;;AAuDA,IAAM,gBAAA,GAAyE;AAAA,EAC7E,EAAE,GAAA,EAAK,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,OAAO,MAAA,EAAO;AAAA,EAC7C,EAAE,GAAA,EAAK,GAAA,EAAK,KAAA,EAAO,SAAA,EAAW,OAAO,QAAA,EAAS;AAAA,EAC9C,EAAE,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,SAAA,EAAW,OAAO,KAAA;AACrC,CAAA;AAEA,SAAS,KAAK,CAAA,EAAW;AACvB,EAAA,OAAO,gBAAA,CAAiB,KAAK,CAAC,CAAA,KAAM,KAAK,CAAA,CAAE,GAAG,CAAA,IAAK,gBAAA,CAAiB,CAAC,CAAA;AACvE;AAEO,SAAS,SAAA,CAAU;AAAA,EACxB,KAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA,GAAa,CAAA;AAAA,EACb,UAAU,EAAC;AAAA,EACX,EAAA;AAAA,EACA,KAAA,GAAQ,KAAA;AAAA,EACR,MAAA,GAAS,KAAA;AAAA,EACT,UAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,MAAM,CAAA,GAAI,KAAK,UAAU,CAAA;AAEzB,EAAA,MAAM,OAAA,GACJ,UAAU,MAAA,mBACRA,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,CAAA,4FAAA,EAA+F,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,MACzH,KAAA,EAAO,EAAE,eAAA,EAAiB,CAAA,CAAE,QAAQ,IAAA,EAAM,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,MAEzD,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,0BAAA;AAAA,YACV,KAAA,EAAO,EAAE,eAAA,EAAiB,CAAA,CAAE,KAAA;AAAM;AAAA,SACpC;AAAA,QACC,KAAA;AAAA,wBACDA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAAyB,QAAA,EAAA,GAAA,EAAC;AAAA;AAAA;AAAA,GAC5C,GACE,UAAU,WAAA,mBACZD,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,CAAA,2DAAA,EAA8D,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,MACxF,KAAA,EAAO,EAAE,mBAAA,EAAqB,CAAA,CAAE,KAAA,EAAM;AAAA,MAErC,QAAA,EAAA;AAAA,QAAA,KAAA;AAAA,wBACDC,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,8BAAA;AAAA,YACV,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM;AAAA,YACzB,QAAA,EAAA;AAAA;AAAA;AAED;AAAA;AAAA,sBAGFD,eAAA,CAAC,MAAA,EAAA,EAAK,WAAW,CAAA,6CAAA,EAAgD,SAAA,IAAa,EAAE,CAAA,CAAA,EAC9E,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBACrCA,cAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,oDAAA;AAAA,QACV,KAAA,EAAO,EAAE,eAAA,EAAiB,CAAA,CAAE,KAAA,EAAM;AAAA,QAClC,KAAA,EAAM;AAAA;AAAA;AACR,GAAA,EACF,CAAA;AAGJ,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,uBACED,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oDAAA,EACb,QAAA,EAAA;AAAA,MAAA,OAAA;AAAA,sBACDC,cAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,uGAAA;AAAA,UACV,KAAA,EAAO,EAAE,WAAA,EAAa,CAAA,CAAE,KAAA,EAAM;AAAA,UAE7B,QAAA,EAAA;AAAA;AAAA;AACH,KAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACED,eAAA,CAACE,yBAAA,EAAA,EAAQ,KAAA,EAAK,IAAA,EACZ,QAAA,EAAA;AAAA,oBAAAD,cAAA,CAACC,yBAAA,CAAQ,OAAA,EAAR,EAAiB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,mCACzBA,yBAAA,CAAQ,OAAA,EAAR,EACC,QAAA,kBAAAF,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wBAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2BAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,eAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,oDAAA;AAAA,YACV,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM;AAAA,YAEvB,QAAA,EAAA;AAAA,cAAA,CAAA,CAAE,KAAA;AAAA,cAAM,mBAAA;AAAA,cAAA,CAAgB,UAAA,GAAa,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAA;AAAA,cAAE;AAAA;AAAA;AAAA,SACxD;AAAA,QACC,EAAA,oBACCA,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6CAAA,EAA8C,QAAA,EAAA;AAAA,UAAA,GAAA;AAAA,UAC1D;AAAA,SAAA,EACJ;AAAA,OAAA,EAEJ,CAAA;AAAA,sBACAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,2DAAA,EACV,QAAA,EAAA,MAAA,EACH,CAAA;AAAA,MACC,OAAA,CAAQ,MAAA,GAAS,CAAA,oBAChBD,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EAAqD,QAAA,EAAA,SAAA,EAEpE,CAAA;AAAA,wBACAA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gCAAA,EACX,kBAAQ,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACfA,cAAA,CAAC,IAAA,EAAA,EACE,QAAA,EAAA,CAAA,CAAE,IAAA,kCACA,GAAA,EAAA,EAAE,SAAA,EAAU,iCAAA,EAAkC,IAAA,EAAM,CAAA,CAAE,IAAA,EACpD,QAAA,EAAA,CAAA,CAAE,KAAA,EACL,oBAEAA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAA,EACb,QAAA,EAAA,CAAA,CAAE,KAAA,EACL,CAAA,EAAA,EARK,CAUT,CACD,CAAA,EACH;AAAA,OAAA,EACF,CAAA;AAAA,MAED,UAAA,oBACCA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBACb,QAAA,kBAAAA,cAAA,CAACE,wBAAA,EAAA,EAAO,IAAA,EAAK,IAAA,EAAK,OAAA,EAAQ,OAAA,EAAQ,OAAA,EAAS,UAAA,EAAY,2BAEvD,CAAA,EACF;AAAA,KAAA,EAEJ,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-GCWIZNN2.cjs","sourcesContent":["import { Popover } from \"../Popover\";\nimport { Button } from \"../Button\";\n\n/**\n * ReasonTag — wraps any value with a small affordance that reveals the\n * agent's reasoning, sources, and confidence on hover or click.\n *\n * <ReasonTag\n * value=\"$1.4M\"\n * reason=\"Projected Q3 ARR after stacking renewals.\"\n * confidence={0.91}\n * sources={[{ label: \"Q2 actuals · CRM export\" }]}\n * by=\"Forecaster\"\n * />\n *\n * Three visual styles:\n * • \"dot\" — value with a tiny coloured dot (default, subtle)\n * • \"underline\" — dotted underline + trailing \"?\"\n * • \"chip\" — full coloured pill (loud)\n *\n * Confidence drives the colour via three tiers (high / medium / low),\n * so a quick visual scan tells the human which suggestions deserve a\n * second look without opening any tooltips.\n *\n * `pinned` swaps the popover for an inline annotation slot — useful\n * when explainability should always be visible, not buried in a hover.\n */\nexport type ReasonTagSource = { label: string; href?: string };\n\nexport type ReasonTagTheme = \"dot\" | \"underline\" | \"chip\";\n\nexport interface ReasonTagProps {\n /** The value the tag wraps — usually a number, label, or short phrase. */\n value: React.ReactNode;\n /** Free-text rationale shown in the popover / inline annotation. */\n reason: string;\n /** 0..1 confidence. Drives the tier colour. Defaults to 1. */\n confidence?: number;\n /** Optional list of sources (label + optional href). */\n sources?: ReasonTagSource[];\n /** Optional author / agent name shown in the popover header. */\n by?: string;\n /** Visual treatment for the trigger. */\n theme?: ReasonTagTheme;\n /**\n * When true, the popover is replaced with an always-visible inline\n * annotation below the value.\n */\n pinned?: boolean;\n /** Called when the user hits the \"ask follow-up\" action. */\n onFollowUp?: () => void;\n /** Optional className applied to the trigger element. */\n className?: string;\n}\n\nconst CONFIDENCE_TIERS: Array<{ min: number; color: string; label: string }> = [\n { min: 0.85, color: \"#10b981\", label: \"high\" },\n { min: 0.6, color: \"#f59e0b\", label: \"medium\" },\n { min: 0, color: \"#ef4444\", label: \"low\" },\n];\n\nfunction tier(c: number) {\n return CONFIDENCE_TIERS.find((t) => c >= t.min) ?? CONFIDENCE_TIERS[2];\n}\n\nexport function ReasonTag({\n value,\n reason,\n confidence = 1,\n sources = [],\n by,\n theme = \"dot\",\n pinned = false,\n onFollowUp,\n className,\n}: ReasonTagProps) {\n const t = tier(confidence);\n\n const trigger =\n theme === \"chip\" ? (\n <span\n className={`inline-flex cursor-help items-center gap-1 rounded-full px-2 py-0.5 text-[12px] font-medium ${className ?? \"\"}`}\n style={{ backgroundColor: t.color + \"22\", color: t.color }}\n >\n <span\n className=\"h-1.5 w-1.5 rounded-full\"\n style={{ backgroundColor: t.color }}\n />\n {value}\n <span className=\"text-[10px] opacity-70\">?</span>\n </span>\n ) : theme === \"underline\" ? (\n <span\n className={`cursor-help underline decoration-dotted underline-offset-2 ${className ?? \"\"}`}\n style={{ textDecorationColor: t.color }}\n >\n {value}\n <span\n className=\"ml-0.5 font-mono text-[10px]\"\n style={{ color: t.color }}\n >\n ?\n </span>\n </span>\n ) : (\n <span className={`inline-flex cursor-help items-baseline gap-1 ${className ?? \"\"}`}>\n <span className=\"font-medium\">{value}</span>\n <span\n className=\"inline-block h-1.5 w-1.5 rounded-full align-middle\"\n style={{ backgroundColor: t.color }}\n title=\"reason available\"\n />\n </span>\n );\n\n if (pinned) {\n return (\n <span className=\"inline-flex flex-col items-start gap-0.5 align-top\">\n {trigger}\n <span\n className=\"block max-w-[280px] rounded border-l-2 pl-2 text-[11px] leading-snug text-zinc-600 dark:text-zinc-300\"\n style={{ borderColor: t.color }}\n >\n {reason}\n </span>\n </span>\n );\n }\n\n return (\n <Popover hover>\n <Popover.Trigger>{trigger}</Popover.Trigger>\n <Popover.Content>\n <div className=\"w-72 space-y-2 text-sm\">\n <div className=\"flex items-baseline gap-2\">\n <span\n className=\"text-[10px] font-semibold uppercase tracking-wider\"\n style={{ color: t.color }}\n >\n {t.label} confidence · {(confidence * 100).toFixed(0)}%\n </span>\n {by && (\n <span className=\"ml-auto font-mono text-[10px] text-zinc-400\">\n @{by}\n </span>\n )}\n </div>\n <p className=\"text-[13px] leading-snug text-zinc-700 dark:text-zinc-200\">\n {reason}\n </p>\n {sources.length > 0 && (\n <div>\n <div className=\"text-[10px] uppercase tracking-wider text-zinc-400\">\n sources\n </div>\n <ul className=\"mt-0.5 space-y-0.5 text-[12px]\">\n {sources.map((s, i) => (\n <li key={i}>\n {s.href ? (\n <a className=\"text-violet-600 hover:underline\" href={s.href}>\n {s.label}\n </a>\n ) : (\n <span className=\"text-zinc-600 dark:text-zinc-300\">\n {s.label}\n </span>\n )}\n </li>\n ))}\n </ul>\n </div>\n )}\n {onFollowUp && (\n <div className=\"flex justify-end pt-1\">\n <Button size=\"sm\" variant=\"ghost\" onClick={onFollowUp}>\n ask follow-up\n </Button>\n </div>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkMSRYJETY_cjs = require('./chunk-MSRYJETY.cjs');
|
|
4
4
|
var chunkX7H75WVP_cjs = require('./chunk-X7H75WVP.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunkFWA4PCW7_cjs = require('./chunk-FWA4PCW7.cjs');
|
|
6
6
|
var chunkQKFOJKVE_cjs = require('./chunk-QKFOJKVE.cjs');
|
|
7
7
|
var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
|
|
8
8
|
var react = require('react');
|
|
@@ -379,7 +379,7 @@ function PromptInput({
|
|
|
379
379
|
] }),
|
|
380
380
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 border-t border-zinc-200 bg-zinc-50/60 px-3 py-2 dark:border-zinc-800 dark:bg-zinc-900/40", children: [
|
|
381
381
|
/* @__PURE__ */ jsxRuntime.jsx(chunkX7H75WVP_cjs.Tooltip, { content: attachButton === "icon" ? "Attach files \u2014 or drop them here" : "Drop files here, or click", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
382
|
-
|
|
382
|
+
chunkFWA4PCW7_cjs.Button,
|
|
383
383
|
{
|
|
384
384
|
variant: "ghost",
|
|
385
385
|
size: "sm",
|
|
@@ -444,7 +444,7 @@ function PromptInput({
|
|
|
444
444
|
}
|
|
445
445
|
),
|
|
446
446
|
sendButton === "icon" ? /* @__PURE__ */ jsxRuntime.jsx(chunkX7H75WVP_cjs.Tooltip, { content: `Send \xB7 ${modKey}+Enter`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
447
|
-
|
|
447
|
+
chunkFWA4PCW7_cjs.Button,
|
|
448
448
|
{
|
|
449
449
|
color: "violet",
|
|
450
450
|
size: "sm",
|
|
@@ -455,7 +455,7 @@ function PromptInput({
|
|
|
455
455
|
onClick: submit
|
|
456
456
|
}
|
|
457
457
|
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
458
|
-
|
|
458
|
+
chunkFWA4PCW7_cjs.Button,
|
|
459
459
|
{
|
|
460
460
|
color: "violet",
|
|
461
461
|
size: "sm",
|
|
@@ -486,5 +486,5 @@ exports.PromptInput = PromptInput;
|
|
|
486
486
|
exports.browserPlatformHints = browserPlatformHints;
|
|
487
487
|
exports.detectPlatform = detectPlatform;
|
|
488
488
|
exports.modifierKeyLabel = modifierKeyLabel;
|
|
489
|
-
//# sourceMappingURL=chunk-
|
|
490
|
-
//# sourceMappingURL=chunk-
|
|
489
|
+
//# sourceMappingURL=chunk-IPBEVSSC.cjs.map
|
|
490
|
+
//# sourceMappingURL=chunk-IPBEVSSC.cjs.map
|