gridsmith-ui 0.6.6 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/charts.js +2 -2
- package/dist/chat.d.ts +12 -0
- package/dist/chat.js +94 -0
- package/dist/chat.js.map +1 -0
- package/dist/{chunk-TTZSZNJ6.js → chunk-4KVFH5KC.js} +7 -3
- package/dist/chunk-4KVFH5KC.js.map +1 -0
- package/dist/{chunk-6UZZYWTY.js → chunk-ADTPGMOD.js} +5 -5
- package/dist/{chunk-6UZZYWTY.js.map → chunk-ADTPGMOD.js.map} +1 -1
- package/dist/{chunk-DDKCQVKO.js → chunk-LTV5X3S7.js} +48 -20
- package/dist/chunk-LTV5X3S7.js.map +1 -0
- package/dist/{chunk-QGBG72OB.js → chunk-M3AARGLI.js} +3 -3
- package/dist/{chunk-QGBG72OB.js.map → chunk-M3AARGLI.js.map} +1 -1
- package/dist/{chunk-GX6O72IV.js → chunk-NM3BFWHH.js} +19 -26
- package/dist/chunk-NM3BFWHH.js.map +1 -0
- package/dist/{chunk-GYVBRUO2.js → chunk-NRHIYS5W.js} +14 -3
- package/dist/chunk-NRHIYS5W.js.map +1 -0
- package/dist/chunk-R2HNSJJG.js +156 -0
- package/dist/chunk-R2HNSJJG.js.map +1 -0
- package/dist/chunk-RLUK575N.js +136 -0
- package/dist/chunk-RLUK575N.js.map +1 -0
- package/dist/chunk-WH2FUFAC.js +14 -0
- package/dist/chunk-WH2FUFAC.js.map +1 -0
- package/dist/data-grid.js +4 -3
- package/dist/data-grid.js.map +1 -1
- package/dist/editor.js +17 -13
- package/dist/editor.js.map +1 -1
- package/dist/feather-B65FI6CY.js +76 -0
- package/dist/feather-B65FI6CY.js.map +1 -0
- package/dist/heroicons-DIR7PXCR.js +76 -0
- package/dist/heroicons-DIR7PXCR.js.map +1 -0
- package/dist/icons.d.ts +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +352 -17
- package/dist/index.js +4596 -3468
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +5 -4
- package/dist/kanban.js.map +1 -1
- package/dist/lucide-JH2R3TFV.js +76 -0
- package/dist/lucide-JH2R3TFV.js.map +1 -0
- package/dist/phosphor-HCVUMVT5.js +76 -0
- package/dist/phosphor-HCVUMVT5.js.map +1 -0
- package/dist/resizable.js +2 -2
- package/dist/roots.css +97 -22
- package/dist/tabler-HHIXSM73.js +76 -0
- package/dist/tabler-HHIXSM73.js.map +1 -0
- package/dist/tokens.css +14 -7
- package/dist/utils.js +1 -1
- package/dist/virtualized.js +1 -1
- package/dist-static/tokens.css +14 -7
- package/package.json +14 -2
- package/dist/chunk-DDKCQVKO.js.map +0 -1
- package/dist/chunk-GX6O72IV.js.map +0 -1
- package/dist/chunk-GYVBRUO2.js.map +0 -1
- package/dist/chunk-TTZSZNJ6.js.map +0 -1
- package/dist/feather-U45EQTAU.js +0 -72
- package/dist/feather-U45EQTAU.js.map +0 -1
- package/dist/heroicons-D3G7QU45.js +0 -72
- package/dist/heroicons-D3G7QU45.js.map +0 -1
- package/dist/lucide-OGUV44TQ.js +0 -72
- package/dist/lucide-OGUV44TQ.js.map +0 -1
- package/dist/phosphor-QG2ZMEMZ.js +0 -72
- package/dist/phosphor-QG2ZMEMZ.js.map +0 -1
- package/dist/tabler-MW2HN55L.js +0 -72
- package/dist/tabler-MW2HN55L.js.map +0 -1
package/dist/charts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Skeleton } from './chunk-
|
|
2
|
-
import { cn, GLASS_SURFACE } from './chunk-
|
|
1
|
+
import { Skeleton } from './chunk-M3AARGLI.js';
|
|
2
|
+
import { cn, GLASS_SURFACE } from './chunk-4KVFH5KC.js';
|
|
3
3
|
import { createContext, forwardRef, useId, useContext, useSyncExternalStore, useState, useLayoutEffect } from 'react';
|
|
4
4
|
import { ResponsiveContainer, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LineChart as LineChart$1, Line, AreaChart as AreaChart$1, Area, PieChart as PieChart$1, Pie, Cell, ComposedChart, ScatterChart as ScatterChart$1, ZAxis, Scatter, RadarChart as RadarChart$1, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, RadialBarChart as RadialBarChart$1, RadialBar, FunnelChart as FunnelChart$1, Funnel, LabelList, Treemap, Sankey, Text } from 'recharts';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
package/dist/chat.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface MarkdownContentProps {
|
|
4
|
+
/** The markdown source — a model's reply, an API's description. Raw HTML in it is never rendered. */
|
|
5
|
+
children: string;
|
|
6
|
+
/** Show a caret at the end of the last block while the source is still arriving. Pass a message's status === "streaming" from ChatMessageList's renderContent. */
|
|
7
|
+
streaming?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function MarkdownContent(props: MarkdownContentProps): react_jsx_runtime.JSX.Element;
|
|
11
|
+
|
|
12
|
+
export { MarkdownContent, type MarkdownContentProps };
|
package/dist/chat.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Divider, CodeBlock, Link } from './chunk-R2HNSJJG.js';
|
|
2
|
+
import './chunk-ADTPGMOD.js';
|
|
3
|
+
import './chunk-LTV5X3S7.js';
|
|
4
|
+
import './chunk-WH2FUFAC.js';
|
|
5
|
+
import './chunk-NM3BFWHH.js';
|
|
6
|
+
import { cn } from './chunk-4KVFH5KC.js';
|
|
7
|
+
import { memo, Children, isValidElement } from 'react';
|
|
8
|
+
import Markdown from 'react-markdown';
|
|
9
|
+
import remarkGfm from 'remark-gfm';
|
|
10
|
+
import { jsx } from 'react/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
var isExternal = (href) => /^(https?:)?\/\//i.test(href);
|
|
13
|
+
function codeFromPre(children) {
|
|
14
|
+
const only = Children.toArray(children).find(isValidElement);
|
|
15
|
+
const cls = only?.props.className ?? "";
|
|
16
|
+
const language = /language-([\w+-]+)/.exec(cls)?.[1];
|
|
17
|
+
const raw = only ? only.props.children : children;
|
|
18
|
+
const code = Children.toArray(raw).map((c) => typeof c === "string" || typeof c === "number" ? String(c) : "").join("").replace(/\n$/, "");
|
|
19
|
+
return { code, language };
|
|
20
|
+
}
|
|
21
|
+
var components = {
|
|
22
|
+
p: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("p", { ...props }),
|
|
23
|
+
a: ({ node: _n, href = "#", children, ...props }) => /* @__PURE__ */ jsx(
|
|
24
|
+
Link,
|
|
25
|
+
{
|
|
26
|
+
href,
|
|
27
|
+
underline: "always",
|
|
28
|
+
...isExternal(href) ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
29
|
+
...props,
|
|
30
|
+
children
|
|
31
|
+
}
|
|
32
|
+
),
|
|
33
|
+
pre: ({ node: _n, children }) => {
|
|
34
|
+
const { code, language } = codeFromPre(children);
|
|
35
|
+
return /* @__PURE__ */ jsx(CodeBlock, { code, language });
|
|
36
|
+
},
|
|
37
|
+
code: ({ node: _n, className, children, ...props }) => /* @__PURE__ */ jsx(
|
|
38
|
+
"code",
|
|
39
|
+
{
|
|
40
|
+
className: cn(
|
|
41
|
+
"rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)] px-ds-1 py-[1px] font-[family-name:var(--ds-font-mono)] text-[0.9em]",
|
|
42
|
+
className
|
|
43
|
+
),
|
|
44
|
+
...props,
|
|
45
|
+
children
|
|
46
|
+
}
|
|
47
|
+
),
|
|
48
|
+
ul: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("ul", { className: "list-disc space-y-ds-1 pl-ds-5", ...props }),
|
|
49
|
+
ol: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("ol", { className: "list-decimal space-y-ds-1 pl-ds-5", ...props }),
|
|
50
|
+
li: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("li", { ...props }),
|
|
51
|
+
h1: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-[var(--ds-text-primary)]", ...props }),
|
|
52
|
+
h2: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-[var(--ds-text-primary)]", ...props }),
|
|
53
|
+
h3: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-[var(--ds-text-primary)]", ...props }),
|
|
54
|
+
h4: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-[var(--ds-text-primary)]", ...props }),
|
|
55
|
+
h5: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("h5", { className: "text-sm font-medium text-[var(--ds-text-primary)]", ...props }),
|
|
56
|
+
h6: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("h6", { className: "text-sm font-medium text-[var(--ds-text-secondary)]", ...props }),
|
|
57
|
+
blockquote: ({ node: _n, ...props }) => /* @__PURE__ */ jsx(
|
|
58
|
+
"blockquote",
|
|
59
|
+
{
|
|
60
|
+
className: "border-l-[length:calc(var(--ds-border-width)*2)] border-[var(--ds-border-default)] pl-ds-3 text-[var(--ds-text-secondary)]",
|
|
61
|
+
...props
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
hr: () => /* @__PURE__ */ jsx(Divider, {}),
|
|
65
|
+
strong: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", ...props }),
|
|
66
|
+
// Wide content scrolls inside its own container; the page never scrolls sideways.
|
|
67
|
+
table: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]", children: /* @__PURE__ */ jsx("table", { className: "w-full border-collapse text-sm", ...props }) }),
|
|
68
|
+
thead: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("thead", { className: "bg-[var(--ds-bg-muted)]", ...props }),
|
|
69
|
+
th: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("th", { className: "px-ds-3 py-ds-2 text-left text-xs font-semibold uppercase tracking-wide text-[var(--ds-text-secondary)]", ...props }),
|
|
70
|
+
td: ({ node: _n, ...props }) => /* @__PURE__ */ jsx("td", { className: "border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] px-ds-3 py-ds-2 align-top", ...props }),
|
|
71
|
+
img: ({ node: _n, alt = "", ...props }) => /* @__PURE__ */ jsx("img", { alt, className: "max-w-full rounded-[var(--ds-radius-md)]", ...props })
|
|
72
|
+
};
|
|
73
|
+
var STREAMING_CARET = cn(
|
|
74
|
+
"[&>:last-child]:after:content-['\u258D'] [&>:last-child]:after:ml-ds-0.5",
|
|
75
|
+
"[&>:last-child]:after:text-[var(--ds-accent-primary)] [&>:last-child]:after:animate-pulse"
|
|
76
|
+
);
|
|
77
|
+
var Memoised = memo(function MarkdownContentInner({ children, streaming, className }) {
|
|
78
|
+
return /* @__PURE__ */ jsx(
|
|
79
|
+
"div",
|
|
80
|
+
{
|
|
81
|
+
className: cn("space-y-ds-4 text-sm leading-relaxed text-[var(--ds-text-primary)]", streaming && STREAMING_CARET, className),
|
|
82
|
+
"data-markdown": "",
|
|
83
|
+
"data-streaming": streaming || void 0,
|
|
84
|
+
children: /* @__PURE__ */ jsx(Markdown, { remarkPlugins: [remarkGfm], components, skipHtml: true, children })
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
function MarkdownContent(props) {
|
|
89
|
+
return /* @__PURE__ */ jsx(Memoised, { ...props });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { MarkdownContent };
|
|
93
|
+
//# sourceMappingURL=chat.js.map
|
|
94
|
+
//# sourceMappingURL=chat.js.map
|
package/dist/chat.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/MarkdownContent.tsx"],"names":[],"mappings":"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","file":"chat.js","sourcesContent":["import { memo, Children, isValidElement, type ComponentProps, type ReactElement, type ReactNode } from \"react\";\nimport Markdown, { type Components } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { cn } from \"../lib/utils\";\nimport { CodeBlock } from \"./CodeBlock\";\nimport { Link } from \"./Link\";\nimport { Divider } from \"./Divider\";\n\nexport interface MarkdownContentProps {\n /** The markdown source — a model's reply, an API's description. Raw HTML in it is never rendered. */\n children: string;\n /** Show a caret at the end of the last block while the source is still arriving. Pass a message's status === \"streaming\" from ChatMessageList's renderContent. */\n streaming?: boolean;\n className?: string;\n}\n\nconst isExternal = (href: string) => /^(https?:)?\\/\\//i.test(href);\n\n/** Pull the code string and language out of the single <code> child react-markdown gives a <pre>. */\nfunction codeFromPre(children: ReactNode): { code: string; language?: string } {\n const only = Children.toArray(children).find(isValidElement) as ReactElement<{ className?: string; children?: ReactNode }> | undefined;\n const cls = only?.props.className ?? \"\";\n const language = /language-([\\w+-]+)/.exec(cls)?.[1];\n const raw = only ? only.props.children : children;\n const code = Children.toArray(raw)\n .map((c) => (typeof c === \"string\" || typeof c === \"number\" ? String(c) : \"\"))\n .join(\"\")\n .replace(/\\n$/, \"\");\n return { code, language };\n}\n\ntype P<T extends keyof React.JSX.IntrinsicElements> = ComponentProps<T> & { node?: unknown };\n\nconst components: Components = {\n p: ({ node: _n, ...props }: P<\"p\">) => <p {...props} />,\n a: ({ node: _n, href = \"#\", children, ...props }: P<\"a\">) => (\n <Link\n href={href}\n underline=\"always\"\n {...(isExternal(href) ? { target: \"_blank\", rel: \"noopener noreferrer\" } : {})}\n {...(props as Record<string, unknown>)}\n >\n {children}\n </Link>\n ),\n pre: ({ node: _n, children }: P<\"pre\">) => {\n const { code, language } = codeFromPre(children);\n return <CodeBlock code={code} language={language} />;\n },\n code: ({ node: _n, className, children, ...props }: P<\"code\">) => (\n <code\n className={cn(\n \"rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)] px-ds-1 py-[1px] font-[family-name:var(--ds-font-mono)] text-[0.9em]\",\n className,\n )}\n {...props}\n >\n {children}\n </code>\n ),\n ul: ({ node: _n, ...props }: P<\"ul\">) => <ul className=\"list-disc space-y-ds-1 pl-ds-5\" {...props} />,\n ol: ({ node: _n, ...props }: P<\"ol\">) => <ol className=\"list-decimal space-y-ds-1 pl-ds-5\" {...props} />,\n li: ({ node: _n, ...props }: P<\"li\">) => <li {...props} />,\n h1: ({ node: _n, ...props }: P<\"h1\">) => <h3 className=\"text-base font-semibold text-[var(--ds-text-primary)]\" {...props} />,\n h2: ({ node: _n, ...props }: P<\"h2\">) => <h3 className=\"text-base font-semibold text-[var(--ds-text-primary)]\" {...props} />,\n h3: ({ node: _n, ...props }: P<\"h3\">) => <h4 className=\"text-sm font-semibold text-[var(--ds-text-primary)]\" {...props} />,\n h4: ({ node: _n, ...props }: P<\"h4\">) => <h4 className=\"text-sm font-semibold text-[var(--ds-text-primary)]\" {...props} />,\n h5: ({ node: _n, ...props }: P<\"h5\">) => <h5 className=\"text-sm font-medium text-[var(--ds-text-primary)]\" {...props} />,\n h6: ({ node: _n, ...props }: P<\"h6\">) => <h6 className=\"text-sm font-medium text-[var(--ds-text-secondary)]\" {...props} />,\n blockquote: ({ node: _n, ...props }: P<\"blockquote\">) => (\n <blockquote\n className=\"border-l-[length:calc(var(--ds-border-width)*2)] border-[var(--ds-border-default)] pl-ds-3 text-[var(--ds-text-secondary)]\"\n {...props}\n />\n ),\n hr: () => <Divider />,\n strong: ({ node: _n, ...props }: P<\"strong\">) => <strong className=\"font-semibold\" {...props} />,\n // Wide content scrolls inside its own container; the page never scrolls sideways.\n table: ({ node: _n, ...props }: P<\"table\">) => (\n <div className=\"overflow-x-auto rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\">\n <table className=\"w-full border-collapse text-sm\" {...props} />\n </div>\n ),\n thead: ({ node: _n, ...props }: P<\"thead\">) => <thead className=\"bg-[var(--ds-bg-muted)]\" {...props} />,\n th: ({ node: _n, ...props }: P<\"th\">) => (\n <th className=\"px-ds-3 py-ds-2 text-left text-xs font-semibold uppercase tracking-wide text-[var(--ds-text-secondary)]\" {...props} />\n ),\n td: ({ node: _n, ...props }: P<\"td\">) => (\n <td className=\"border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] px-ds-3 py-ds-2 align-top\" {...props} />\n ),\n img: ({ node: _n, alt = \"\", ...props }: P<\"img\">) => <img alt={alt} className=\"max-w-full rounded-[var(--ds-radius-md)]\" {...props} />,\n};\n\n/**\n * Renders markdown (GitHub flavour: tables, task lists, strikethrough) with\n * Gridsmith primitives: fenced code becomes CodeBlock, links become Link,\n * a rule becomes Divider, everything else is token-styled markup. Raw HTML is\n * not rendered — the source is untrusted by default. Memoised: an unchanged\n * message never re-parses; a streaming message re-parses only its own string.\n *\n * Lives on the `gridsmith-ui/chat` entry point (react-markdown and remark-gfm\n * are optional peers), so apps without a chat never load a markdown parser.\n */\n// The caret is a pseudo-element on the last block, so it sits at the end of the\n// last line of text instead of on a line of its own below a block element.\nconst STREAMING_CARET = cn(\n \"[&>:last-child]:after:content-['▍'] [&>:last-child]:after:ml-ds-0.5\",\n \"[&>:last-child]:after:text-[var(--ds-accent-primary)] [&>:last-child]:after:animate-pulse\",\n);\n\nconst Memoised = memo(function MarkdownContentInner({ children, streaming, className }: MarkdownContentProps) {\n return (\n <div\n className={cn(\"space-y-ds-4 text-sm leading-relaxed text-[var(--ds-text-primary)]\", streaming && STREAMING_CARET, className)}\n data-markdown=\"\"\n data-streaming={streaming || undefined}\n >\n <Markdown remarkPlugins={[remarkGfm]} components={components} skipHtml>\n {children}\n </Markdown>\n </div>\n );\n});\n\n// A plain function export so the registry extractor (which reads `export function`)\n// documents it; the memo above still skips re-parsing unchanged sources.\nexport function MarkdownContent(props: MarkdownContentProps) {\n return <Memoised {...props} />;\n}\n"]}
|
|
@@ -13,6 +13,10 @@ var ACTIVE_RING = "border-[var(--ds-border-focus)] ring-2 ring-[var(--ds-ring-ac
|
|
|
13
13
|
var FOCUS_RING = "focus-visible:outline-none focus-visible:border-[var(--ds-border-focus)] focus-visible:ring-2 focus-visible:ring-[var(--ds-ring-active)]";
|
|
14
14
|
var FOCUS_WITHIN_RING = "focus-within:border-[var(--ds-border-focus)] focus-within:ring-2 focus-within:ring-[var(--ds-ring-active)]";
|
|
15
15
|
var HAS_FOCUS_RING = "has-[:focus-visible]:border-[var(--ds-border-focus)] has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-[var(--ds-ring-active)]";
|
|
16
|
+
var ERROR_ACTIVE_RING = "border-[var(--ds-status-error)] ring-2 ring-[var(--ds-ring-error)]";
|
|
17
|
+
var ERROR_FOCUS_RING = "focus-visible:outline-none focus-visible:border-[var(--ds-status-error)] focus-visible:ring-2 focus-visible:ring-[var(--ds-ring-error)]";
|
|
18
|
+
var ERROR_FOCUS_WITHIN_RING = "focus-within:border-[var(--ds-status-error)] focus-within:ring-2 focus-within:ring-[var(--ds-ring-error)]";
|
|
19
|
+
var ERROR_HAS_FOCUS_RING = "has-[:focus-visible]:border-[var(--ds-status-error)] has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-[var(--ds-ring-error)]";
|
|
16
20
|
var scrollLockCount = 0;
|
|
17
21
|
var scrollLockPreviousOverflow = "";
|
|
18
22
|
function lockBodyScroll() {
|
|
@@ -31,6 +35,6 @@ function unlockBodyScroll() {
|
|
|
31
35
|
}
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
export { ACTIVE_RING, FOCUS_RING, FOCUS_WITHIN_RING, GLASS_BACKDROP, GLASS_DROPDOWN, GLASS_OVERLAY, GLASS_SURFACE, HAS_FOCUS_RING, cn, lockBodyScroll, unlockBodyScroll };
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
36
|
-
//# sourceMappingURL=chunk-
|
|
38
|
+
export { ACTIVE_RING, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, ERROR_HAS_FOCUS_RING, FOCUS_RING, FOCUS_WITHIN_RING, GLASS_BACKDROP, GLASS_DROPDOWN, GLASS_OVERLAY, GLASS_SURFACE, HAS_FOCUS_RING, cn, lockBodyScroll, unlockBodyScroll };
|
|
39
|
+
//# sourceMappingURL=chunk-4KVFH5KC.js.map
|
|
40
|
+
//# sourceMappingURL=chunk-4KVFH5KC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/utils.ts"],"names":[],"mappings":";;;;AAGO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;AAEO,IAAM,cAAA,GAAiB;AAEvB,IAAM,aAAA,GAAgB,GAAG,cAAc,CAAA,qDAAA;AAEvC,IAAM,aAAA,GAAgB,GAAG,cAAc,CAAA,sDAAA;AAEvC,IAAM,cAAA,GAAiB,GAAG,cAAc,CAAA,yDAAA;AAKxC,IAAM,WAAA,GAAc;AAEpB,IAAM,UAAA,GAAa;AAEnB,IAAM,iBAAA,GAAoB;AAE1B,IAAM,cAAA,GAAiB;AAIvB,IAAM,iBAAA,GAAoB;AAE1B,IAAM,gBAAA,GAAmB;AAEzB,IAAM,uBAAA,GAA0B;AAEhC,IAAM,oBAAA,GAAuB;AAMpC,IAAI,eAAA,GAAkB,CAAA;AACtB,IAAI,0BAAA,GAA6B,EAAA;AAE1B,SAAS,cAAA,GAAiB;AAC/B,EAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,IAAA,0BAAA,GAA6B,QAAA,CAAS,KAAK,KAAA,CAAM,QAAA;AACjD,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,QAAA;AAAA,EACjC;AACA,EAAA,eAAA,EAAA;AACF;AAEO,SAAS,gBAAA,GAAmB;AACjC,EAAA,IAAI,oBAAoB,CAAA,EAAG;AAC3B,EAAA,eAAA,EAAA;AACA,EAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,0BAAA;AAC/B,IAAA,0BAAA,GAA6B,EAAA;AAAA,EAC/B;AACF","file":"chunk-4KVFH5KC.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n\nexport const GLASS_BACKDROP = \"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]\";\n\nexport const GLASS_SURFACE = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-card),var(--ds-glass-inset)]`;\n\nexport const GLASS_OVERLAY = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-modal),var(--ds-glass-inset)]`;\n\nexport const GLASS_DROPDOWN = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]`;\n\n// One grammar for every stroke-based active state (focused, selected, open):\n// a solid accent stroke plus a soft halo. Borderless controls keep the solid\n// --ds-shadow-focus ring so keyboard focus stays high-contrast.\nexport const ACTIVE_RING = \"border-[var(--ds-border-focus)] ring-2 ring-[var(--ds-ring-active)]\";\n\nexport const FOCUS_RING = \"focus-visible:outline-none focus-visible:border-[var(--ds-border-focus)] focus-visible:ring-2 focus-visible:ring-[var(--ds-ring-active)]\";\n\nexport const FOCUS_WITHIN_RING = \"focus-within:border-[var(--ds-border-focus)] focus-within:ring-2 focus-within:ring-[var(--ds-ring-active)]\";\n\nexport const HAS_FOCUS_RING = \"has-[:focus-visible]:border-[var(--ds-border-focus)] has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-[var(--ds-ring-active)]\";\n\n// Same grammar in the error hue: the invalid stroke stays red on focus and\n// the halo is a 30% error mix, mirroring --ds-accent-soft.\nexport const ERROR_ACTIVE_RING = \"border-[var(--ds-status-error)] ring-2 ring-[var(--ds-ring-error)]\";\n\nexport const ERROR_FOCUS_RING = \"focus-visible:outline-none focus-visible:border-[var(--ds-status-error)] focus-visible:ring-2 focus-visible:ring-[var(--ds-ring-error)]\";\n\nexport const ERROR_FOCUS_WITHIN_RING = \"focus-within:border-[var(--ds-status-error)] focus-within:ring-2 focus-within:ring-[var(--ds-ring-error)]\";\n\nexport const ERROR_HAS_FOCUS_RING = \"has-[:focus-visible]:border-[var(--ds-status-error)] has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-[var(--ds-ring-error)]\";\n\n// Body scroll lock is reference-counted so stacked overlays (a Dialog opened\n// from a Drawer, for example) only restore scrolling when the LAST one\n// closes. The original overflow value is captured on the first lock and put\n// back on the last unlock; an unbalanced unlock is clamped at zero.\nlet scrollLockCount = 0;\nlet scrollLockPreviousOverflow = \"\";\n\nexport function lockBodyScroll() {\n if (scrollLockCount === 0) {\n scrollLockPreviousOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n }\n scrollLockCount++;\n}\n\nexport function unlockBodyScroll() {\n if (scrollLockCount === 0) return;\n scrollLockCount--;\n if (scrollLockCount === 0) {\n document.body.style.overflow = scrollLockPreviousOverflow;\n scrollLockPreviousOverflow = \"\";\n }\n}\n\n/** Test-only: current number of active locks. */\nexport function getBodyScrollLockCount() {\n return scrollLockCount;\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useTextOverflow, Tooltip } from './chunk-
|
|
2
|
-
import { Icon } from './chunk-
|
|
3
|
-
import { cn } from './chunk-
|
|
1
|
+
import { useTextOverflow, Tooltip } from './chunk-LTV5X3S7.js';
|
|
2
|
+
import { Icon } from './chunk-NM3BFWHH.js';
|
|
3
|
+
import { cn } from './chunk-4KVFH5KC.js';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
6
|
var variantStyles = {
|
|
@@ -89,5 +89,5 @@ function Badge({ variant = "default", size = "md", color, iconLeft, iconRight, m
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
export { Badge };
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-ADTPGMOD.js.map
|
|
93
|
+
//# sourceMappingURL=chunk-ADTPGMOD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/Badge.tsx"],"names":[],"mappings":";;;;;AAqBA,IAAM,aAAA,GAA8C;AAAA,EAClD,OAAA,EAAS,sGAAA;AAAA,EACT,OAAA,EAAS,kEAAA;AAAA,EACT,MAAA,EAAQ,yDAAA;AAAA,EACR,OAAA,EAAS,gEAAA;AAAA,EACT,cAAA,EAAgB,iJAAA;AAAA,EAChB,OAAA,EAAS,gEAAA;AAAA,EACT,cAAA,EAAgB,sJAAA;AAAA,EAChB,KAAA,EAAO,4DAAA;AAAA,EACP,YAAA,EAAc,2IAAA;AAAA,EACd,OAAA,EAAS;AACX,CAAA;AAEA,IAAM,UAAA,GAAwC;AAAA,EAC5C,EAAA,EAAI,iDAAA;AAAA,EACJ,EAAA,EAAI,iEAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,SAAA,GAAuC;AAAA,EAC3C,EAAA,EAAI,EAAA;AAAA,EACJ,EAAA,EAAI,EAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAIA,IAAM,gBAAA,GAAmD;AAAA,EACvD,OAAA,EAAS,CAAC,CAAA,KAAM,cAAA,CAAe,CAAC,CAAA;AAAA,EAChC,OAAA,EAAS,CAAC,CAAA,KAAM,aAAA,CAAc,CAAC,CAAA;AAAA,EAC/B,MAAA,EAAQ,CAAC,CAAA,KAAM,aAAA,CAAc,CAAC,CAAA;AAAA,EAC9B,OAAA,EAAS,CAAC,CAAA,KAAM,cAAA,CAAe,CAAC;AAClC,CAAA;AAEA,IAAM,cAAA,GAAoD;AAAA,EACxD,CAAA,EAAG,kEAAA;AAAA,EACH,CAAA,EAAG,kEAAA;AAAA,EACH,CAAA,EAAG,kEAAA;AAAA,EACH,CAAA,EAAG,kEAAA;AAAA,EACH,CAAA,EAAG;AACL,CAAA;AAEA,IAAM,aAAA,GAAmD;AAAA,EACvD,CAAA,EAAG,6DAAA;AAAA,EACH,CAAA,EAAG,6DAAA;AAAA,EACH,CAAA,EAAG,6DAAA;AAAA,EACH,CAAA,EAAG,6DAAA;AAAA,EACH,CAAA,EAAG;AACL,CAAA;AAEA,IAAM,cAAA,GAAoD;AAAA,EACxD,CAAA,EAAG,yHAAA;AAAA,EACH,CAAA,EAAG,yHAAA;AAAA,EACH,CAAA,EAAG,yHAAA;AAAA,EACH,CAAA,EAAG,yHAAA;AAAA,EACH,CAAA,EAAG;AACL,CAAA;AAEA,SAAS,iBAAA,CAAkB,OAA0B,OAAA,EAA+B;AAClF,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,OAAO,CAAA,IAAK,gBAAA,CAAiB,OAAA;AAC9D,EAAA,OAAO,QAAQ,KAAK,CAAA;AACtB;AAiBO,SAAS,KAAA,CAAM,EAAE,OAAA,GAAU,SAAA,EAAW,IAAA,GAAO,IAAA,EAAM,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,QAAA,EAAU,SAAA,EAAW,QAAA,EAAS,EAAe;AACjI,EAAA,MAAM,EAAE,GAAA,EAAK,QAAA,EAAU,WAAA,EAAY,GAAI,eAAA,CAAgB,EAAE,KAAA,EAAO,CAAA,EAAG,QAAA,EAAU,CAAC,QAAA,EAAU,CAAA;AACxF,EAAA,MAAM,QAAA,GAAW,UAAU,IAAI,CAAA;AAC/B,EAAA,MAAM,UAAA,GAAA,CAAc,QAAA,IAAY,SAAA,KAAc,CAAC,QAAA;AAE/C,EAAA,MAAM,eAAe,KAAA,GACjB,iBAAA,CAAkB,OAAO,OAAO,CAAA,GAChC,cAAc,OAAO,CAAA;AAEzB,EAAA,MAAM,KAAA,mBACJ,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,mEAAA;AAAA,QACA,iCAAA;AAAA,QACA,WAAW,IAAI,CAAA;AAAA,QACf,UAAA,IAAc,SAAS,IAAA,IAAQ,UAAA;AAAA,QAC/B,UAAA,IAAc,SAAS,IAAA,IAAQ,SAAA;AAAA,QAC/B,UAAA,IAAc,SAAS,IAAA,IAAQ,WAAA;AAAA,QAC/B,YAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,KAAA,EAAO,QAAA,GAAW,EAAE,QAAA,EAAS,GAAI,MAAA;AAAA,MAEhC,QAAA,EAAA;AAAA,QAAA,QAAA,wBAAa,IAAA,EAAA,EAAK,IAAA,EAAM,UAAU,IAAA,EAAM,QAAA,EAAU,WAAU,UAAA,EAAW,CAAA;AAAA,QACvE,QAAA,uBACE,MAAA,EAAA,EAAK,GAAA,EAAK,UAAU,SAAA,EAAU,UAAA,EAAY,UAAS,CAAA,GAEpD,QAAA;AAAA,QAED,SAAA,wBAAc,IAAA,EAAA,EAAK,IAAA,EAAM,WAAW,IAAA,EAAM,QAAA,EAAU,WAAU,UAAA,EAAW;AAAA;AAAA;AAAA,GAC5E;AAGF,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,uBAAO,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAS,QAAA,EAAW,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,KAAA;AACT","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/Badge.tsx"],"names":[],"mappings":"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","file":"chunk-ADTPGMOD.js","sourcesContent":["import { cn } from \"../lib/utils\";\nimport { Icon, type IconName } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport type { ReactNode } from \"react\";\n\nexport type BadgeVariant =\n | \"default\"\n | \"neutral\"\n | \"subtle\"\n | \"success\"\n | \"success-soft\"\n | \"warning\"\n | \"warning-soft\"\n | \"error\"\n | \"error-soft\"\n | \"outline\";\n\nexport type BadgeSize = \"xs\" | \"sm\" | \"md\";\nexport type BadgePaletteColor = 1 | 2 | 3 | 4 | 5;\n\nconst variantStyles: Record<BadgeVariant, string> = {\n default: \"bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] text-[var(--ds-text-on-primary)]\",\n neutral: \"bg-[var(--ds-text-muted)]/[0.12] text-[var(--ds-text-secondary)]\",\n subtle: \"bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)]\",\n success: \"bg-[var(--ds-status-success)] text-[var(--ds-text-on-success)]\",\n \"success-soft\": \"bg-[var(--ds-status-success-bg)] text-[var(--ds-status-success)] border-[length:var(--ds-border-width)] border-[var(--ds-status-success)]/[0.2]\",\n warning: \"bg-[var(--ds-status-warning)] text-[var(--ds-text-on-warning)]\",\n \"warning-soft\": \"bg-[var(--ds-status-warning-bg)] text-[var(--ds-status-warning-text)] border-[length:var(--ds-border-width)] border-[var(--ds-status-warning)]/[0.2]\",\n error: \"bg-[var(--ds-status-error)] text-[var(--ds-text-on-error)]\",\n \"error-soft\": \"bg-[var(--ds-status-error-bg)] text-[var(--ds-status-error)] border-[length:var(--ds-border-width)] border-[var(--ds-status-error)]/[0.2]\",\n outline: \"bg-transparent text-[var(--ds-text-primary)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n};\n\nconst sizeStyles: Record<BadgeSize, string> = {\n xs: \"px-ds-1.5 py-[1px] text-[length:10px] gap-[3px]\",\n sm: \"px-ds-2 py-ds-0.5 text-[length:var(--ds-font-size-xs)] gap-ds-1\",\n md: \"px-ds-2.5 py-ds-0.5 text-[length:var(--ds-font-size-xs)] gap-ds-1\",\n};\n\nconst iconSizes: Record<BadgeSize, number> = {\n xs: 10,\n sm: 12,\n md: 12,\n};\n\ntype PaletteStyleFn = (n: BadgePaletteColor) => string;\n\nconst paletteByVariant: Record<string, PaletteStyleFn> = {\n default: (n) => paletteDefault[n],\n neutral: (n) => paletteSubtle[n],\n subtle: (n) => paletteSubtle[n],\n outline: (n) => paletteOutline[n],\n};\n\nconst paletteDefault: Record<BadgePaletteColor, string> = {\n 1: \"bg-[var(--ds-palette-1-bold)] text-[var(--ds-palette-1-on-bold)]\",\n 2: \"bg-[var(--ds-palette-2-bold)] text-[var(--ds-palette-2-on-bold)]\",\n 3: \"bg-[var(--ds-palette-3-bold)] text-[var(--ds-palette-3-on-bold)]\",\n 4: \"bg-[var(--ds-palette-4-bold)] text-[var(--ds-palette-4-on-bold)]\",\n 5: \"bg-[var(--ds-palette-5-bold)] text-[var(--ds-palette-5-on-bold)]\",\n};\n\nconst paletteSubtle: Record<BadgePaletteColor, string> = {\n 1: \"bg-[var(--ds-palette-1-bg)] text-[var(--ds-palette-1-text)]\",\n 2: \"bg-[var(--ds-palette-2-bg)] text-[var(--ds-palette-2-text)]\",\n 3: \"bg-[var(--ds-palette-3-bg)] text-[var(--ds-palette-3-text)]\",\n 4: \"bg-[var(--ds-palette-4-bg)] text-[var(--ds-palette-4-text)]\",\n 5: \"bg-[var(--ds-palette-5-bg)] text-[var(--ds-palette-5-text)]\",\n};\n\nconst paletteOutline: Record<BadgePaletteColor, string> = {\n 1: \"bg-transparent text-[var(--ds-palette-1-bold)] border-[length:var(--ds-border-width)] border-[var(--ds-palette-1-bold)]\",\n 2: \"bg-transparent text-[var(--ds-palette-2-bold)] border-[length:var(--ds-border-width)] border-[var(--ds-palette-2-bold)]\",\n 3: \"bg-transparent text-[var(--ds-palette-3-bold)] border-[length:var(--ds-border-width)] border-[var(--ds-palette-3-bold)]\",\n 4: \"bg-transparent text-[var(--ds-palette-4-bold)] border-[length:var(--ds-border-width)] border-[var(--ds-palette-4-bold)]\",\n 5: \"bg-transparent text-[var(--ds-palette-5-bold)] border-[length:var(--ds-border-width)] border-[var(--ds-palette-5-bold)]\",\n};\n\nfunction getPaletteClasses(color: BadgePaletteColor, variant: BadgeVariant): string {\n const styleFn = paletteByVariant[variant] ?? paletteByVariant.default;\n return styleFn(color);\n}\n\ninterface BadgeProps {\n variant?: BadgeVariant;\n size?: BadgeSize;\n /** Palette colour (1-5). Overrides variant colour with decorative palette tokens. */\n color?: BadgePaletteColor;\n /** Icon to show before the label */\n iconLeft?: IconName;\n /** Icon to show after the label */\n iconRight?: IconName;\n /** Max width before truncation (e.g. \"120px\", \"16ch\"). Shows tooltip when truncated. */\n maxWidth?: string;\n className?: string;\n children?: ReactNode;\n}\n\nexport function Badge({ variant = \"default\", size = \"md\", color, iconLeft, iconRight, maxWidth, className, children }: BadgeProps) {\n const { ref: truncRef, isTruncated } = useTextOverflow({ lines: 1, disabled: !maxWidth });\n const iconSize = iconSizes[size];\n const isIconOnly = (iconLeft || iconRight) && !children;\n\n const colorClasses = color\n ? getPaletteClasses(color, variant)\n : variantStyles[variant];\n\n const badge = (\n <span\n className={cn(\n \"inline-flex items-center font-medium max-w-full whitespace-nowrap\",\n \"rounded-[var(--ds-radius-full)]\",\n sizeStyles[size],\n isIconOnly && size === \"xs\" && \"px-[3px]\",\n isIconOnly && size === \"sm\" && \"px-ds-1\",\n isIconOnly && size === \"md\" && \"px-ds-1.5\",\n colorClasses,\n className\n )}\n style={maxWidth ? { maxWidth } : undefined}\n >\n {iconLeft && <Icon name={iconLeft} size={iconSize} className=\"shrink-0\" />}\n {maxWidth ? (\n <span ref={truncRef} className=\"truncate\">{children}</span>\n ) : (\n children\n )}\n {iconRight && <Icon name={iconRight} size={iconSize} className=\"shrink-0\" />}\n </span>\n );\n\n if (isTruncated) {\n return <Tooltip content={children}>{badge}</Tooltip>;\n }\n return badge;\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatest } from './chunk-WH2FUFAC.js';
|
|
2
|
+
import { cn, GLASS_DROPDOWN } from './chunk-4KVFH5KC.js';
|
|
2
3
|
import { isValidElement, cloneElement, useState, useRef, useCallback, useLayoutEffect, useId, useEffect } from 'react';
|
|
3
4
|
import { createPortal } from 'react-dom';
|
|
4
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
@@ -117,29 +118,65 @@ function usePosition(triggerRef, floatingRef, open, options = {}) {
|
|
|
117
118
|
}, [open, compute]);
|
|
118
119
|
return pos;
|
|
119
120
|
}
|
|
120
|
-
function Tooltip({ content, children, side = "top", delay =
|
|
121
|
+
function Tooltip({ content, children, side = "top", delay = 600, className, container }) {
|
|
121
122
|
const [open, setOpen] = useState(false);
|
|
122
123
|
const triggerRef = useRef(null);
|
|
123
124
|
const floatingRef = useRef(null);
|
|
124
125
|
const timeoutRef = useRef(void 0);
|
|
126
|
+
const suppressedRef = useRef(false);
|
|
125
127
|
const id = useId();
|
|
126
128
|
const pos = usePosition(triggerRef, floatingRef, open, { side, offset: 6, flip: true });
|
|
129
|
+
const cancel = useCallback(() => {
|
|
130
|
+
clearTimeout(timeoutRef.current);
|
|
131
|
+
timeoutRef.current = void 0;
|
|
132
|
+
}, []);
|
|
127
133
|
const show = useCallback(() => {
|
|
134
|
+
if (suppressedRef.current) return;
|
|
135
|
+
cancel();
|
|
128
136
|
timeoutRef.current = setTimeout(() => setOpen(true), delay);
|
|
129
|
-
}, [delay]);
|
|
137
|
+
}, [delay, cancel]);
|
|
130
138
|
const hide = useCallback(() => {
|
|
131
|
-
|
|
139
|
+
cancel();
|
|
132
140
|
setOpen(false);
|
|
133
|
-
}, []);
|
|
141
|
+
}, [cancel]);
|
|
142
|
+
const showOnFocus = useCallback((e) => {
|
|
143
|
+
let keyboard = true;
|
|
144
|
+
try {
|
|
145
|
+
keyboard = e.currentTarget.matches(":focus-visible");
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
if (keyboard) show();
|
|
149
|
+
}, [show]);
|
|
150
|
+
const dismissOnActivate = useCallback(() => {
|
|
151
|
+
suppressedRef.current = true;
|
|
152
|
+
hide();
|
|
153
|
+
}, [hide]);
|
|
154
|
+
const leave = useCallback(() => {
|
|
155
|
+
suppressedRef.current = false;
|
|
156
|
+
hide();
|
|
157
|
+
}, [hide]);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (!open) return;
|
|
160
|
+
const onKey = (e) => {
|
|
161
|
+
if (e.key === "Escape") hide();
|
|
162
|
+
};
|
|
163
|
+
document.addEventListener("keydown", onKey);
|
|
164
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
165
|
+
}, [open, hide]);
|
|
166
|
+
useEffect(() => cancel, [cancel]);
|
|
134
167
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
135
168
|
/* @__PURE__ */ jsx(
|
|
136
169
|
Slot,
|
|
137
170
|
{
|
|
138
171
|
ref: triggerRef,
|
|
139
172
|
onMouseEnter: show,
|
|
140
|
-
onMouseLeave:
|
|
141
|
-
onFocus:
|
|
142
|
-
onBlur:
|
|
173
|
+
onMouseLeave: leave,
|
|
174
|
+
onFocus: showOnFocus,
|
|
175
|
+
onBlur: leave,
|
|
176
|
+
onPointerDown: dismissOnActivate,
|
|
177
|
+
onKeyDown: (e) => {
|
|
178
|
+
if (e.key === "Enter" || e.key === " ") dismissOnActivate();
|
|
179
|
+
},
|
|
143
180
|
"aria-describedby": open ? id : void 0,
|
|
144
181
|
children
|
|
145
182
|
}
|
|
@@ -169,15 +206,6 @@ function Tooltip({ content, children, side = "top", delay = 300, className, cont
|
|
|
169
206
|
)
|
|
170
207
|
] });
|
|
171
208
|
}
|
|
172
|
-
function useLatest(value) {
|
|
173
|
-
const ref = useRef(value);
|
|
174
|
-
useLayoutEffect(() => {
|
|
175
|
-
ref.current = value;
|
|
176
|
-
});
|
|
177
|
-
return ref;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// ../../showcase/src/lib/use-text-overflow.ts
|
|
181
209
|
var registry = /* @__PURE__ */ new WeakMap();
|
|
182
210
|
var sharedObserver = null;
|
|
183
211
|
var rafId = null;
|
|
@@ -281,6 +309,6 @@ function useTextOverflow(options = {}) {
|
|
|
281
309
|
return { ref, isTruncated };
|
|
282
310
|
}
|
|
283
311
|
|
|
284
|
-
export { Slot, Tooltip,
|
|
285
|
-
//# sourceMappingURL=chunk-
|
|
286
|
-
//# sourceMappingURL=chunk-
|
|
312
|
+
export { Slot, Tooltip, usePosition, useTextOverflow };
|
|
313
|
+
//# sourceMappingURL=chunk-LTV5X3S7.js.map
|
|
314
|
+
//# sourceMappingURL=chunk-LTV5X3S7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/slot.tsx","../../../showcase/src/lib/use-position.ts","../../../showcase/src/components/Tooltip.tsx","../../../showcase/src/lib/use-text-overflow.ts"],"names":["rafId","useState","useRef","useCallback","jsx","useEffect"],"mappings":"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","file":"chunk-LTV5X3S7.js","sourcesContent":["import {\n type ReactNode,\n type ReactElement,\n type HTMLAttributes,\n type Ref,\n isValidElement,\n cloneElement,\n createElement,\n Children,\n} from \"react\";\n\ntype SlotProps = HTMLAttributes<HTMLElement> & {\n children?: ReactNode;\n ref?: Ref<HTMLElement>;\n};\n\nfunction mergeRefs(...refs: (Ref<HTMLElement> | undefined)[]): Ref<HTMLElement> | undefined {\n const filtered = refs.filter(Boolean) as Ref<HTMLElement>[];\n if (filtered.length === 0) return undefined;\n if (filtered.length === 1) return filtered[0];\n return (node: HTMLElement | null) => {\n for (const ref of filtered) {\n if (typeof ref === \"function\") ref(node);\n else if (ref && typeof ref === \"object\") (ref as { current: HTMLElement | null }).current = node;\n }\n };\n}\n\n/**\n * Merges its own props onto its single React element child instead of\n * rendering a wrapper DOM node. Used by trigger-based components\n * (Tooltip, HoverCard, Popover, DropdownMenu) via the `asChild` prop\n * to let consumers control the rendered element.\n *\n * Follows the same contract as Radix UI's Slot / `asChild` pattern.\n */\nexport function Slot({ children, ref, ...slotProps }: SlotProps) {\n if (!isValidElement(children)) {\n console.warn(\"Slot: expected a single React element child.\");\n return null;\n }\n\n const childProps = children.props as Record<string, unknown>;\n const slotRecord = slotProps as Record<string, unknown>;\n\n const mergedProps: Record<string, unknown> = { ...slotProps };\n for (const key of Object.keys(childProps)) {\n if (key === \"style\") {\n mergedProps.style = { ...(slotProps.style ?? {}), ...(childProps.style as object) };\n } else if (key === \"className\") {\n mergedProps.className = [slotProps.className, childProps.className].filter(Boolean).join(\" \");\n } else if (key.startsWith(\"on\") && typeof slotRecord[key] === \"function\") {\n const slotHandler = slotRecord[key] as (...args: unknown[]) => void;\n const childHandler = childProps[key] as (...args: unknown[]) => void;\n mergedProps[key] = (...args: unknown[]) => {\n childHandler?.(...args);\n slotHandler?.(...args);\n };\n } else {\n mergedProps[key] = childProps[key] ?? slotRecord[key];\n }\n }\n\n if (ref) {\n const childRef = (children as ReactElement & { ref?: Ref<HTMLElement> }).ref ?? (childProps.ref as Ref<HTMLElement> | undefined);\n mergedProps.ref = mergeRefs(ref, childRef);\n }\n\n return cloneElement(children as ReactElement, mergedProps);\n}\n\n/**\n * Renders either a Slot (when `asChild` is true — merging props onto\n * the consumer's child element) or the given `fallback` tag (default\n * behaviour, rendering a wrapper element with the given props).\n */\nexport function Slottable({\n asChild,\n fallback: Tag = \"span\",\n children,\n ref,\n ...rest\n}: {\n asChild?: boolean;\n fallback?: keyof HTMLElementTagNameMap;\n children?: ReactNode;\n ref?: Ref<HTMLElement>;\n} & HTMLAttributes<HTMLElement>) {\n if (asChild) {\n const child = Children.only(children);\n return <Slot ref={ref} {...rest}>{child}</Slot>;\n }\n // `ref` is a forwarded prop being passed on, not a ref object being read.\n // eslint-disable-next-line react-hooks/refs -- forwarding, not dereferencing\n return createElement(Tag, { ref, ...rest } as Record<string, unknown>, children);\n}\n","import { useState, useCallback, useLayoutEffect, useRef, type RefObject } from \"react\";\n\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\nexport type Align = \"start\" | \"center\" | \"end\";\n\ninterface PositionOptions {\n side?: Side;\n align?: Align;\n offset?: number;\n flip?: boolean;\n}\n\ninterface PositionResult {\n top: number;\n left: number;\n placement: Side;\n}\n\nconst VIEWPORT_PADDING = 8;\n\nexport function usePosition(\n triggerRef: RefObject<HTMLElement | null>,\n floatingRef: RefObject<HTMLElement | null>,\n open: boolean,\n options: PositionOptions = {}\n): PositionResult {\n const { side = \"bottom\", align = \"center\", offset = 8, flip = true } = options;\n const [pos, setPos] = useState<PositionResult>({ top: 0, left: 0, placement: side });\n const rafId = useRef(0);\n\n const compute = useCallback(() => {\n const trigger = triggerRef.current;\n const floating = floatingRef.current;\n if (!trigger || !floating) return;\n\n const tRect = trigger.getBoundingClientRect();\n const fRect = floating.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n let placement = side;\n\n if (flip) {\n if (placement === \"bottom\" && tRect.bottom + offset + fRect.height > vh - VIEWPORT_PADDING && tRect.top - offset - fRect.height > VIEWPORT_PADDING) {\n placement = \"top\";\n } else if (placement === \"top\" && tRect.top - offset - fRect.height < VIEWPORT_PADDING && tRect.bottom + offset + fRect.height < vh - VIEWPORT_PADDING) {\n placement = \"bottom\";\n } else if (placement === \"right\" && tRect.right + offset + fRect.width > vw - VIEWPORT_PADDING && tRect.left - offset - fRect.width > VIEWPORT_PADDING) {\n placement = \"left\";\n } else if (placement === \"left\" && tRect.left - offset - fRect.width < VIEWPORT_PADDING && tRect.right + offset + fRect.width < vw - VIEWPORT_PADDING) {\n placement = \"right\";\n }\n }\n\n let top: number;\n let left: number;\n\n if (placement === \"bottom\" || placement === \"top\") {\n top = placement === \"bottom\" ? tRect.bottom + offset : tRect.top - fRect.height - offset;\n\n switch (align) {\n case \"start\":\n left = tRect.left;\n break;\n case \"end\":\n left = tRect.right - fRect.width;\n break;\n default:\n left = tRect.left + (tRect.width - fRect.width) / 2;\n }\n } else {\n left = placement === \"right\" ? tRect.right + offset : tRect.left - fRect.width - offset;\n\n switch (align) {\n case \"start\":\n top = tRect.top;\n break;\n case \"end\":\n top = tRect.bottom - fRect.height;\n break;\n default:\n top = tRect.top + (tRect.height - fRect.height) / 2;\n }\n }\n\n left = Math.max(VIEWPORT_PADDING, Math.min(left, vw - fRect.width - VIEWPORT_PADDING));\n top = Math.max(VIEWPORT_PADDING, Math.min(top, vh - fRect.height - VIEWPORT_PADDING));\n\n setPos({ top, left, placement });\n }, [triggerRef, floatingRef, side, align, offset, flip]);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n compute();\n\n const onUpdate = () => {\n cancelAnimationFrame(rafId.current);\n rafId.current = requestAnimationFrame(compute);\n };\n\n window.addEventListener(\"scroll\", onUpdate, true);\n window.addEventListener(\"resize\", onUpdate);\n\n return () => {\n cancelAnimationFrame(rafId.current);\n window.removeEventListener(\"scroll\", onUpdate, true);\n window.removeEventListener(\"resize\", onUpdate);\n };\n }, [open, compute]);\n\n return pos;\n}\n","import { useState, useRef, useCallback, useEffect, useId, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn, GLASS_DROPDOWN } from \"../lib/utils\";\nimport { Slot } from \"../lib/slot\";\nimport { usePosition, type Side } from \"../lib/use-position\";\n\ninterface TooltipProps {\n content: ReactNode;\n children: ReactNode;\n side?: Side;\n delay?: number;\n className?: string;\n container?: Element | DocumentFragment;\n}\n\n// 600ms: long enough that passing the pointer over a toolbar, or landing focus\n// on an icon button, does not flash a label; short enough to still feel live.\nexport function Tooltip({ content, children, side = \"top\", delay = 600, className, container }: TooltipProps) {\n const [open, setOpen] = useState(false);\n const triggerRef = useRef<HTMLElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n // Set when the trigger is activated: the label must not reappear (from the\n // focus the click leaves behind, or a still-pending timer) until the pointer\n // leaves and comes back.\n const suppressedRef = useRef(false);\n const id = useId();\n\n const pos = usePosition(triggerRef, floatingRef, open, { side, offset: 6, flip: true });\n\n const cancel = useCallback(() => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }, []);\n\n // One pending timer at a time: hover and focus both call show(), and the\n // earlier timer used to be orphaned, firing after hide() had run and leaving\n // the tooltip up with nothing left to close it.\n const show = useCallback(() => {\n if (suppressedRef.current) return;\n cancel();\n timeoutRef.current = setTimeout(() => setOpen(true), delay);\n }, [delay, cancel]);\n\n const hide = useCallback(() => {\n cancel();\n setOpen(false);\n }, [cancel]);\n\n // Pointer focus (a click) does not warrant a label; keyboard focus does.\n const showOnFocus = useCallback((e: React.FocusEvent<HTMLElement>) => {\n let keyboard = true;\n try { keyboard = e.currentTarget.matches(\":focus-visible\"); } catch { /* selector unsupported: assume keyboard */ }\n if (keyboard) show();\n }, [show]);\n\n // Activating the trigger dismisses the label and keeps it away until the\n // pointer has left — what opens next (a menu, a dialog) owns the screen.\n const dismissOnActivate = useCallback(() => {\n suppressedRef.current = true;\n hide();\n }, [hide]);\n\n // Suppression lifts when the pointer leaves or focus moves on — a keyboard\n // user never produces a mouseleave, so blur must reset it too.\n const leave = useCallback(() => {\n suppressedRef.current = false;\n hide();\n }, [hide]);\n\n // Escape dismisses an open tooltip (WCAG 1.4.13); it does not stop the key\n // reaching whatever overlay is also listening.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") hide(); };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, hide]);\n\n useEffect(() => cancel, [cancel]);\n\n return (\n <>\n <Slot\n ref={triggerRef}\n onMouseEnter={show}\n onMouseLeave={leave}\n onFocus={showOnFocus}\n onBlur={leave}\n onPointerDown={dismissOnActivate}\n onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") dismissOnActivate(); }}\n aria-describedby={open ? id : undefined}\n >\n {children}\n </Slot>\n {open && createPortal(\n <div\n ref={floatingRef}\n id={id}\n role=\"tooltip\"\n className={cn(\n \"fixed z-[var(--ds-z-tooltip)] pointer-events-none\",\n \"px-ds-2.5 py-ds-1.5 text-xs\",\n \"max-w-[280px] break-words\",\n \"bg-[var(--ds-bg-surface-elevated)] text-[var(--ds-text-primary)]\",\n GLASS_DROPDOWN,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-sm)]\",\n className\n )}\n style={{ top: pos.top, left: pos.left }}\n >\n {content}\n </div>,\n container ?? document.body\n )}\n </>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport { useLatest } from \"./use-latest\";\n\n// ─── Shared ResizeObserver (singleton per document) ────────────────────────────\n// All useTextOverflow instances share a single ResizeObserver. This avoids the\n// performance cost of 80+ independent observers on pages with many truncated elements.\n\ntype OverflowCallback = () => void;\n\nconst registry = new WeakMap<Element, Set<OverflowCallback>>();\nlet sharedObserver: ResizeObserver | null = null;\nlet rafId: number | null = null;\nconst pendingElements = new Set<Element>();\n\nfunction getSharedObserver(): ResizeObserver {\n if (sharedObserver) return sharedObserver;\n sharedObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n pendingElements.add(entry.target);\n }\n if (rafId === null) {\n rafId = requestAnimationFrame(flush);\n }\n });\n return sharedObserver;\n}\n\nfunction flush() {\n rafId = null;\n for (const el of pendingElements) {\n const callbacks = registry.get(el);\n if (callbacks) {\n for (const cb of callbacks) cb();\n }\n }\n pendingElements.clear();\n}\n\nfunction observe(el: Element, callback: OverflowCallback) {\n let set = registry.get(el);\n if (!set) {\n set = new Set();\n registry.set(el, set);\n }\n set.add(callback);\n if (set.size === 1) {\n getSharedObserver().observe(el);\n }\n}\n\nfunction unobserve(el: Element, callback: OverflowCallback) {\n const set = registry.get(el);\n if (!set) return;\n set.delete(callback);\n if (set.size === 0) {\n registry.delete(el);\n getSharedObserver().unobserve(el);\n }\n}\n\n// ─── Overflow detection ────────────────────────────────────────────────────────\n\nconst TOLERANCE = 1; // px — accounts for integer rounding in scrollWidth/clientWidth\n\nfunction checkOverflow(el: HTMLElement, lines: number): boolean {\n if (lines <= 1) {\n return el.scrollWidth - el.clientWidth > TOLERANCE;\n }\n return el.scrollHeight - el.clientHeight > TOLERANCE;\n}\n\n// ─── Hook ──────────────────────────────────────────────────────────────────────\n\nexport interface UseTextOverflowOptions {\n /** Number of visible lines before truncation. 1 = single-line ellipsis, >1 = line-clamp. */\n lines?: number;\n /** Disable overflow detection (e.g. when component is hidden) */\n disabled?: boolean;\n /** Content key — triggers re-check when this value changes (use for dynamic text content) */\n content?: unknown;\n}\n\nexport interface UseTextOverflowResult {\n /** Callback ref — attach to the element that has truncation CSS applied */\n ref: (node: HTMLElement | null) => void;\n /** True when the element's text is currently overflowing/truncated */\n isTruncated: boolean;\n}\n\n/**\n * Detects whether an element's text content is overflowing (truncated).\n * Uses a single shared ResizeObserver for all instances on the page.\n *\n * @example\n * const { ref, isTruncated } = useTextOverflow({ lines: 1 });\n * return (\n * <Tooltip content={fullText} disabled={!isTruncated}>\n * <span ref={ref} className=\"truncate\">{fullText}</span>\n * </Tooltip>\n * );\n */\nexport function useTextOverflow(options: UseTextOverflowOptions = {}): UseTextOverflowResult {\n const { lines = 1, disabled = false, content } = options;\n const [isTruncated, setIsTruncated] = useState(false);\n const elementRef = useRef<HTMLElement | null>(null);\n // The observer-registered wrapper delegates to the latest check logic via checkRef.\n const registeredRef = useRef<OverflowCallback | null>(null);\n\n const doCheck = useCallback(() => {\n if (!elementRef.current || disabled) {\n setIsTruncated(false);\n return;\n }\n const next = checkOverflow(elementRef.current, lines);\n setIsTruncated((prev) => (prev !== next ? next : prev));\n }, [lines, disabled]);\n\n // Latest check logic, updated in a layout effect so the stable wrapper never runs a stale closure.\n const checkRef = useLatest<OverflowCallback>(doCheck);\n\n // Re-check when content changes (handles dynamic text like Dropdown selection)\n // or when disabled state changes\n // Measures the committed DOM, so it must stay a post-layout effect.\n /* eslint-disable react-hooks/set-state-in-effect -- overflow is a layout measurement */\n useEffect(() => {\n if (disabled) {\n setIsTruncated(false);\n } else if (elementRef.current) {\n const next = checkOverflow(elementRef.current, lines);\n setIsTruncated((prev) => (prev !== next ? next : prev));\n }\n }, [content, lines, disabled]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n const ref = useCallback(\n (node: HTMLElement | null) => {\n const prev = elementRef.current;\n\n // Unregister previous element using the SAME function we registered with\n if (prev && registeredRef.current) {\n unobserve(prev, registeredRef.current);\n registeredRef.current = null;\n }\n\n elementRef.current = node;\n\n if (node && !disabled) {\n // Stable wrapper that delegates to the latest check logic\n const wrapper: OverflowCallback = () => checkRef.current?.();\n registeredRef.current = wrapper;\n observe(node, wrapper);\n // Initial check on mount\n const initial = checkOverflow(node, lines);\n setIsTruncated(initial);\n }\n },\n [lines, disabled, checkRef],\n );\n\n // Cleanup on unmount — uses the registered wrapper, not the check function\n useEffect(() => {\n return () => {\n if (elementRef.current && registeredRef.current) {\n unobserve(elementRef.current, registeredRef.current);\n }\n };\n }, []);\n\n return { ref, isTruncated };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from './chunk-
|
|
1
|
+
import { cn } from './chunk-4KVFH5KC.js';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
function Bone({ className, style }) {
|
|
@@ -37,5 +37,5 @@ function Skeleton({ variant = "text", lines = 3, width, height, className }) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export { Skeleton };
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-M3AARGLI.js.map
|
|
41
|
+
//# sourceMappingURL=chunk-M3AARGLI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/Skeleton.tsx"],"names":[],"mappings":";;;AAUA,SAAS,IAAA,CAAK,EAAE,SAAA,EAAW,KAAA,EAAM,EAAwD;AACvF,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,wEAAA,EAA0E,SAAS,CAAA;AAAA,MACjG;AAAA;AAAA,GACF;AAEJ;AAEO,SAAS,QAAA,CAAS,EAAE,OAAA,GAAU,MAAA,EAAQ,QAAQ,CAAA,EAAG,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAU,EAAkB;AACjG,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,2BAAQ,IAAA,EAAA,EAAK,SAAA,EAAsB,OAAO,EAAE,KAAA,EAAO,QAAO,EAAG,CAAA;AAAA,EAC/D;AAEA,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,2BAAQ,IAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,2CAAA,EAA6C,SAAS,CAAA,EAAG,CAAA;AAAA,EACtF;AAEA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EAC1C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,2CAAA,EAA4C,CAAA;AAAA,sBAC5D,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,sBAC5B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAY;AAAA,KAAA,EAC9B,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,IAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,eAAA,EAAiB,SAAS,CAAA,EAC3C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,sBAC/B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EAAe,CAAA;AAAA,sBAC/B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa,CAAA;AAAA,sBAC7B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa;AAAA,KAAA,EAC/B,CAAA;AAAA,EAEJ;AAGA,EAAA,MAAM,SAAS,CAAC,OAAA,EAAS,OAAA,EAAS,OAAA,EAAS,SAAS,OAAO,CAAA;AAC3D,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EACzC,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,EAAM,EAAG,CAAC,CAAA,EAAG,CAAA,qBACjC,GAAA,CAAC,IAAA,EAAA,EAAa,SAAA,EAAW,EAAA,CAAG,KAAA,EAAO,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM,CAAC,CAAA,EAAA,EAAjD,CAAoD,CAChE,CAAA,EACH,CAAA;AAEJ","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/Skeleton.tsx"],"names":[],"mappings":";;;AAUA,SAAS,IAAA,CAAK,EAAE,SAAA,EAAW,KAAA,EAAM,EAAwD;AACvF,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,wEAAA,EAA0E,SAAS,CAAA;AAAA,MACjG;AAAA;AAAA,GACF;AAEJ;AAEO,SAAS,QAAA,CAAS,EAAE,OAAA,GAAU,MAAA,EAAQ,QAAQ,CAAA,EAAG,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAU,EAAkB;AACjG,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,2BAAQ,IAAA,EAAA,EAAK,SAAA,EAAsB,OAAO,EAAE,KAAA,EAAO,QAAO,EAAG,CAAA;AAAA,EAC/D;AAEA,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,2BAAQ,IAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,2CAAA,EAA6C,SAAS,CAAA,EAAG,CAAA;AAAA,EACtF;AAEA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EAC1C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,2CAAA,EAA4C,CAAA;AAAA,sBAC5D,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,sBAC5B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAY;AAAA,KAAA,EAC9B,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,IAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,eAAA,EAAiB,SAAS,CAAA,EAC3C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,sBAC/B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EAAe,CAAA;AAAA,sBAC/B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa,CAAA;AAAA,sBAC7B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa;AAAA,KAAA,EAC/B,CAAA;AAAA,EAEJ;AAGA,EAAA,MAAM,SAAS,CAAC,OAAA,EAAS,OAAA,EAAS,OAAA,EAAS,SAAS,OAAO,CAAA;AAC3D,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EACzC,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,EAAM,EAAG,CAAC,CAAA,EAAG,CAAA,qBACjC,GAAA,CAAC,IAAA,EAAA,EAAa,SAAA,EAAW,EAAA,CAAG,KAAA,EAAO,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM,CAAC,CAAA,EAAA,EAAjD,CAAoD,CAChE,CAAA,EACH,CAAA;AAEJ","file":"chunk-M3AARGLI.js","sourcesContent":["import { cn } from \"../lib/utils\";\n\ninterface SkeletonProps {\n variant?: \"text\" | \"avatar\" | \"card\" | \"table-row\" | \"custom\";\n lines?: number;\n width?: string;\n height?: string;\n className?: string;\n}\n\nfunction Bone({ className, style }: { className?: string; style?: React.CSSProperties }) {\n return (\n <div\n className={cn(\"rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-emphasis)] animate-pulse\", className)}\n style={style}\n />\n );\n}\n\nexport function Skeleton({ variant = \"text\", lines = 3, width, height, className }: SkeletonProps) {\n if (variant === \"custom\") {\n return <Bone className={className} style={{ width, height }} />;\n }\n\n if (variant === \"avatar\") {\n return <Bone className={cn(\"h-10 w-10 rounded-[var(--ds-radius-full)]\", className)} />;\n }\n\n if (variant === \"card\") {\n return (\n <div className={cn(\"space-y-ds-3\", className)}>\n <Bone className=\"h-32 w-full rounded-[var(--ds-radius-md)]\" />\n <Bone className=\"h-4 w-3/4\" />\n <Bone className=\"h-4 w-1/2\" />\n </div>\n );\n }\n\n if (variant === \"table-row\") {\n return (\n <div className={cn(\"flex gap-ds-4\", className)}>\n <Bone className=\"h-4 flex-[3]\" />\n <Bone className=\"h-4 flex-[2]\" />\n <Bone className=\"h-4 flex-1\" />\n <Bone className=\"h-4 flex-1\" />\n </div>\n );\n }\n\n // text variant\n const widths = [\"w-3/4\", \"w-1/2\", \"w-5/6\", \"w-2/3\", \"w-4/5\"];\n return (\n <div className={cn(\"space-y-ds-3\", className)}>\n {Array.from({ length: lines }, (_, i) => (\n <Bone key={i} className={cn(\"h-4\", widths[i % widths.length])} />\n ))}\n </div>\n );\n}\n"]}
|
|
@@ -30,51 +30,44 @@ function useExtendedMap(pack) {
|
|
|
30
30
|
}
|
|
31
31
|
var loadingPacks = /* @__PURE__ */ new Set();
|
|
32
32
|
var failedPacks = /* @__PURE__ */ new Set();
|
|
33
|
+
var PEER_PACKAGE = {
|
|
34
|
+
lucide: "lucide-react",
|
|
35
|
+
phosphor: "@phosphor-icons/react",
|
|
36
|
+
heroicons: "@heroicons/react",
|
|
37
|
+
tabler: "@tabler/icons-react",
|
|
38
|
+
feather: "react-icons"
|
|
39
|
+
};
|
|
33
40
|
async function loadPack(pack) {
|
|
34
41
|
if (curatedCache.has(pack) || loadingPacks.has(pack) || failedPacks.has(pack)) return;
|
|
35
42
|
loadingPacks.add(pack);
|
|
36
43
|
let mod;
|
|
44
|
+
let curated;
|
|
37
45
|
try {
|
|
38
46
|
switch (pack) {
|
|
39
47
|
case "lucide":
|
|
40
|
-
mod = await import('./lucide-
|
|
48
|
+
mod = await import('./lucide-JH2R3TFV.js');
|
|
41
49
|
break;
|
|
42
50
|
case "phosphor":
|
|
43
|
-
|
|
44
|
-
mod = await import('./phosphor-QG2ZMEMZ.js');
|
|
45
|
-
} catch {
|
|
46
|
-
throw new Error("gridsmith-ui: @phosphor-icons/react is not installed. Run: npm install @phosphor-icons/react");
|
|
47
|
-
}
|
|
51
|
+
mod = await import('./phosphor-HCVUMVT5.js');
|
|
48
52
|
break;
|
|
49
53
|
case "heroicons":
|
|
50
|
-
|
|
51
|
-
mod = await import('./heroicons-D3G7QU45.js');
|
|
52
|
-
} catch {
|
|
53
|
-
throw new Error("gridsmith-ui: @heroicons/react is not installed. Run: npm install @heroicons/react");
|
|
54
|
-
}
|
|
54
|
+
mod = await import('./heroicons-DIR7PXCR.js');
|
|
55
55
|
break;
|
|
56
56
|
case "tabler":
|
|
57
|
-
|
|
58
|
-
mod = await import('./tabler-MW2HN55L.js');
|
|
59
|
-
} catch {
|
|
60
|
-
throw new Error("gridsmith-ui: @tabler/icons-react is not installed. Run: npm install @tabler/icons-react");
|
|
61
|
-
}
|
|
57
|
+
mod = await import('./tabler-HHIXSM73.js');
|
|
62
58
|
break;
|
|
63
59
|
case "feather":
|
|
64
|
-
|
|
65
|
-
mod = await import('./feather-U45EQTAU.js');
|
|
66
|
-
} catch {
|
|
67
|
-
throw new Error("gridsmith-ui: react-icons is not installed. Run: npm install react-icons");
|
|
68
|
-
}
|
|
60
|
+
mod = await import('./feather-B65FI6CY.js');
|
|
69
61
|
break;
|
|
70
62
|
}
|
|
71
|
-
|
|
63
|
+
curated = await mod.loadCurated();
|
|
64
|
+
} catch {
|
|
72
65
|
loadingPacks.delete(pack);
|
|
73
66
|
failedPacks.add(pack);
|
|
74
|
-
console.error(
|
|
67
|
+
console.error(`gridsmith-ui: ${PEER_PACKAGE[pack]} is not installed. Run: npm install ${PEER_PACKAGE[pack]}`);
|
|
75
68
|
return;
|
|
76
69
|
}
|
|
77
|
-
curatedCache.set(pack,
|
|
70
|
+
curatedCache.set(pack, curated);
|
|
78
71
|
notifySubscribers();
|
|
79
72
|
mod.loadExtended().then((extended) => {
|
|
80
73
|
extendedCache.set(pack, extended);
|
|
@@ -145,5 +138,5 @@ function Icon({ name, size = 16, className }) {
|
|
|
145
138
|
}
|
|
146
139
|
|
|
147
140
|
export { Icon, IconProvider, preloadPack };
|
|
148
|
-
//# sourceMappingURL=chunk-
|
|
149
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-NM3BFWHH.js.map
|
|
142
|
+
//# sourceMappingURL=chunk-NM3BFWHH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/icons.tsx"],"names":[],"mappings":"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","file":"chunk-NM3BFWHH.js","sourcesContent":["import { createContext, useContext, useEffect, useSyncExternalStore, type ReactNode, type ComponentType } from \"react\";\n\n/* ── Types ────────────────────────────────────────────────────── */\n\n/**\n * Runtime list of curated icon names. The CuratedIconName type derives from\n * this array, so adding a name here extends autocomplete automatically.\n * Every name must have an alias (or auto-kebab match) in ALL five packs —\n * icon-completeness.test.tsx enforces this.\n */\nexport const CURATED_ICON_NAMES = [\n \"home\", \"folder\", \"chart\", \"settings\",\n \"chevron-right\", \"close\", \"plus\", \"search\",\n \"bell\", \"user\", \"check\", \"warning\", \"info\", \"error\",\n \"clock\", \"calendar\",\n \"bold\", \"italic\", \"underline\", \"strikethrough\",\n \"align-left\", \"align-center\", \"align-right\",\n \"list\", \"list-ordered\", \"list-checks\",\n \"link\", \"image\", \"table\", \"code\", \"quote\", \"minus\",\n \"superscript\", \"subscript\", \"highlight\", \"type\",\n \"chevron-up\", \"chevron-down\", \"trash\",\n \"undo\", \"redo\",\n \"arrow-left\", \"grip-vertical\",\n \"mic\", \"paperclip\", \"send\",\n \"log-out\", \"edit\", \"menu\", \"more-horizontal\",\n \"star\", \"bookmark\", \"download\", \"upload\", \"sparkles\",\n] as const;\n\ntype CuratedIconName = (typeof CURATED_ICON_NAMES)[number];\n\n/**\n * Curated names provide autocomplete and work identically across all 5 packs.\n * Any kebab-case string is also accepted — it resolves directly against the\n * active pack's native exports (e.g. \"clipboard-copy\" → Lucide's ClipboardCopy).\n */\nexport type IconName = CuratedIconName | (string & {});\n\nexport type IconPack = \"lucide\" | \"phosphor\" | \"heroicons\" | \"tabler\" | \"feather\";\n\ntype IconComponent = ComponentType<Record<string, unknown>>;\ntype IconMap = Record<string, IconComponent>;\n\n/* ── External store ──────────────────────────────────────────── */\n\ntype Subscriber = () => void;\nconst subscribers = new Set<Subscriber>();\nfunction notifySubscribers() {\n subscribers.forEach((fn) => fn());\n}\nfunction subscribe(cb: Subscriber): () => void {\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nconst curatedCache = new Map<IconPack, IconMap>();\nconst extendedCache = new Map<IconPack, IconMap>();\n\nfunction useCuratedMap(pack: IconPack): IconMap | null {\n return useSyncExternalStore(\n subscribe,\n () => curatedCache.get(pack) ?? null,\n () => null,\n );\n}\n\nfunction useExtendedMap(pack: IconPack): IconMap | null {\n return useSyncExternalStore(\n subscribe,\n () => extendedCache.get(pack) ?? null,\n () => null,\n );\n}\n\n/* ── Pack loading ────────────────────────────────────────────────\n Each pack is isolated in its own file under ./icon-packs/.\n Only the active pack's module is dynamically imported at runtime,\n so bundlers won't resolve unused pack dependencies at build time.\n\n Loading is two-phase:\n 1. Curated map (50 static named imports) — available as soon as\n the pack chunk loads, cached and notified immediately.\n 2. Extended map (full barrel import + kebab-case iteration) —\n loaded in the background, cached and notified when ready. */\n\nconst loadingPacks = new Set<IconPack>();\nconst failedPacks = new Set<IconPack>();\n\ntype PackModule = {\n loadCurated(): Promise<IconMap>;\n loadExtended(): Promise<IconMap>;\n};\n\n/** The npm package each pack needs — named in the error when a pack is missing. */\nconst PEER_PACKAGE: Record<IconPack, string> = {\n lucide: \"lucide-react\",\n phosphor: \"@phosphor-icons/react\",\n heroicons: \"@heroicons/react\",\n tabler: \"@tabler/icons-react\",\n feather: \"react-icons\",\n};\n\nasync function loadPack(pack: IconPack): Promise<void> {\n if (curatedCache.has(pack) || loadingPacks.has(pack) || failedPacks.has(pack)) return;\n loadingPacks.add(pack);\n\n // Each pack module reaches its peer only through a dynamic import (see\n // icon-packs/*.ts), so the chunk import below always succeeds and it is\n // loadCurated() that rejects when the pack is not installed.\n let mod: PackModule;\n let curated: IconMap;\n try {\n switch (pack) {\n case \"lucide\": mod = await import(\"./icon-packs/lucide\"); break;\n case \"phosphor\": mod = await import(\"./icon-packs/phosphor\"); break;\n case \"heroicons\": mod = await import(\"./icon-packs/heroicons\"); break;\n case \"tabler\": mod = await import(\"./icon-packs/tabler\"); break;\n case \"feather\": mod = await import(\"./icon-packs/feather\"); break;\n }\n curated = await mod!.loadCurated();\n } catch {\n loadingPacks.delete(pack);\n failedPacks.add(pack);\n console.error(`gridsmith-ui: ${PEER_PACKAGE[pack]} is not installed. Run: npm install ${PEER_PACKAGE[pack]}`);\n return;\n }\n\n curatedCache.set(pack, curated);\n notifySubscribers();\n\n mod!.loadExtended().then((extended) => {\n extendedCache.set(pack, extended);\n notifySubscribers();\n }).catch(() => {\n // Extended map failed (e.g. network error loading the full barrel).\n // Curated icons still work; extended names will not resolve.\n });\n}\n\n/** Exported for the icon-completeness test — not part of the public API. */\nexport const packLoaders: Record<IconPack, {\n curated: () => Promise<IconMap>;\n extended: () => Promise<IconMap>;\n}> = {\n lucide: { curated: () => import(\"./icon-packs/lucide\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/lucide\").then((m) => m.loadExtended()) },\n phosphor: { curated: () => import(\"./icon-packs/phosphor\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/phosphor\").then((m) => m.loadExtended()) },\n heroicons: { curated: () => import(\"./icon-packs/heroicons\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/heroicons\").then((m) => m.loadExtended()) },\n tabler: { curated: () => import(\"./icon-packs/tabler\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/tabler\").then((m) => m.loadExtended()) },\n feather: { curated: () => import(\"./icon-packs/feather\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/feather\").then((m) => m.loadExtended()) },\n};\n\n/* ── Context ──────────────────────────────────────────────────── */\n\ninterface IconContextValue {\n pack: IconPack;\n weight: number;\n}\n\nconst IconCtx = createContext<IconContextValue>({ pack: \"lucide\", weight: 1.5 });\n\nexport function IconProvider({ pack, weight, children }: { pack: IconPack; weight: number; children: ReactNode }) {\n useEffect(() => {\n loadPack(pack);\n if (pack !== \"lucide\") loadPack(\"lucide\");\n }, [pack]);\n\n return <IconCtx.Provider value={{ pack, weight }}>{children}</IconCtx.Provider>;\n}\n\n/**\n * Start loading a pack's icon chunk before React mounts. Call this in your\n * app's entry point (e.g. main.tsx) for the fastest possible cold start:\n *\n * import { preloadPack } from 'gridsmith-ui/icons'\n * preloadPack('lucide')\n */\nexport function preloadPack(pack: IconPack): void {\n loadPack(pack);\n}\n\n/* ── Phosphor weight mapping ──────────────────────────────────── */\n\nfunction getPhosphorWeight(numericWeight: number): \"thin\" | \"light\" | \"regular\" | \"bold\" | \"fill\" | \"duotone\" {\n if (numericWeight <= 0.75) return \"thin\";\n if (numericWeight <= 1.25) return \"light\";\n if (numericWeight <= 1.75) return \"regular\";\n if (numericWeight <= 2.25) return \"bold\";\n return \"fill\";\n}\n\n/* ── Icon component ───────────────────────────────────────────── */\n\nexport function Icon({ name, size = 16, className }: { name: IconName; size?: number; className?: string }) {\n const { pack, weight } = useContext(IconCtx);\n\n const curatedMap = useCuratedMap(pack);\n const extendedMap = useExtendedMap(pack);\n const lucideCurated = useCuratedMap(\"lucide\");\n const lucideExtended = useExtendedMap(\"lucide\");\n\n // Ensure the active pack is loading (covers cases where Icon mounts\n // before IconProvider's useEffect fires, e.g. during SSR hydration)\n if (!curatedCache.has(pack) && !loadingPacks.has(pack)) {\n loadPack(pack);\n }\n\n let Comp: IconComponent | undefined | null = null;\n let renderPack: IconPack = pack;\n\n // Tier 1: curated map (available once pack chunk has loaded)\n if (curatedMap) {\n Comp = curatedMap[name];\n }\n\n // Tier 2: extended map (available after barrel import completes)\n if (!Comp && extendedMap) {\n Comp = extendedMap[name];\n }\n\n // Tier 3: lucide fallback (curated first, then extended)\n if (!Comp && pack !== \"lucide\") {\n const fallback = lucideCurated?.[name] ?? lucideExtended?.[name];\n if (fallback) {\n Comp = fallback;\n renderPack = \"lucide\";\n }\n }\n\n if (!Comp) {\n const allMapsLoaded = curatedMap && extendedMap &&\n (pack === \"lucide\" || (lucideCurated && lucideExtended));\n if (allMapsLoaded) return null;\n return <span style={{ display: \"inline-block\", width: size, height: size }} className={className} />;\n }\n\n if (renderPack === \"phosphor\") {\n return <Comp size={size} weight={getPhosphorWeight(weight)} className={className} />;\n }\n\n if (renderPack === \"heroicons\") {\n return <Comp className={className} style={{ width: size, height: size, strokeWidth: weight }} />;\n }\n\n if (renderPack === \"tabler\") {\n return <Comp size={size} stroke={weight} className={className} />;\n }\n\n if (renderPack === \"feather\") {\n return <Comp size={size} className={className} strokeWidth={weight} />;\n }\n\n return <Comp size={size} strokeWidth={weight} className={className} />;\n}\n"]}
|
|
@@ -6,6 +6,17 @@ function isRenderableComponent(value) {
|
|
|
6
6
|
if (typeof value === "function") return true;
|
|
7
7
|
return typeof value === "object" && value !== null && "$$typeof" in value;
|
|
8
8
|
}
|
|
9
|
+
function pickCurated(mod, names) {
|
|
10
|
+
const map = {};
|
|
11
|
+
const missing = [];
|
|
12
|
+
for (const [key, exportName] of Object.entries(names)) {
|
|
13
|
+
const value = mod[exportName];
|
|
14
|
+
if (isRenderableComponent(value)) map[key] = value;
|
|
15
|
+
else missing.push(exportName);
|
|
16
|
+
}
|
|
17
|
+
if (missing.length > 0) console.warn(`gridsmith-ui: ${missing.length} curated icon export(s) not found in the installed pack: ${missing.join(", ")}`);
|
|
18
|
+
return map;
|
|
19
|
+
}
|
|
9
20
|
function buildExtendedMap(mod, aliases, opts) {
|
|
10
21
|
const map = {};
|
|
11
22
|
for (const [exportName, value] of Object.entries(mod)) {
|
|
@@ -25,6 +36,6 @@ function buildExtendedMap(mod, aliases, opts) {
|
|
|
25
36
|
return map;
|
|
26
37
|
}
|
|
27
38
|
|
|
28
|
-
export { buildExtendedMap };
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
39
|
+
export { buildExtendedMap, pickCurated };
|
|
40
|
+
//# sourceMappingURL=chunk-NRHIYS5W.js.map
|
|
41
|
+
//# sourceMappingURL=chunk-NRHIYS5W.js.map
|