gridsmith-ui 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -1
- package/dist/charts.js +21 -8
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +15 -9
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-OIOII5L6.js → chunk-4HJDOZ2M.js} +303 -20
- package/dist/chunk-4HJDOZ2M.js.map +1 -0
- package/dist/{chunk-INGF2CPW.js → chunk-6C2IUMY7.js} +3 -3
- package/dist/{chunk-INGF2CPW.js.map → chunk-6C2IUMY7.js.map} +1 -1
- package/dist/chunk-ACLKDE5W.js +59 -0
- package/dist/chunk-ACLKDE5W.js.map +1 -0
- package/dist/{chunk-NLXQ323J.js → chunk-BZRZENBS.js} +5 -4
- package/dist/chunk-BZRZENBS.js.map +1 -0
- package/dist/{chunk-RHWTMTU5.js → chunk-DBHVJ7Z3.js} +5 -49
- package/dist/chunk-DBHVJ7Z3.js.map +1 -0
- package/dist/{chunk-Z4MCD73B.js → chunk-HVGHGBKV.js} +6 -7
- package/dist/chunk-HVGHGBKV.js.map +1 -0
- package/dist/{chunk-UNS4TGGK.js → chunk-K6IDOCGE.js} +77 -27
- package/dist/chunk-K6IDOCGE.js.map +1 -0
- package/dist/{chunk-Q36JVJX4.js → chunk-MIUSSYVE.js} +4 -4
- package/dist/{chunk-Q36JVJX4.js.map → chunk-MIUSSYVE.js.map} +1 -1
- package/dist/{chunk-F2BNJSON.js → chunk-SIWERRP2.js} +70 -69
- package/dist/chunk-SIWERRP2.js.map +1 -0
- package/dist/{chunk-KTPGMJUK.js → chunk-SQHKC4HA.js} +8 -5
- package/dist/chunk-SQHKC4HA.js.map +1 -0
- package/dist/{chunk-NI5542ZM.js → chunk-USHW523V.js} +81 -24
- package/dist/chunk-USHW523V.js.map +1 -0
- package/dist/{chunk-GQVBZ4GW.js → chunk-WWN6CQKI.js} +31 -104
- package/dist/chunk-WWN6CQKI.js.map +1 -0
- package/dist/{chunk-JTU7OBYJ.js → chunk-YL5KD5RC.js} +4 -3
- package/dist/chunk-YL5KD5RC.js.map +1 -0
- package/dist/{chunk-6A5RHW2W.js → chunk-ZASGFL5D.js} +4 -5
- package/dist/chunk-ZASGFL5D.js.map +1 -0
- package/dist/chunk-ZCDA74RQ.js +110 -0
- package/dist/chunk-ZCDA74RQ.js.map +1 -0
- package/dist/data-grid.js +8 -10
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +3 -5
- package/dist/editor-mentions.js.map +1 -1
- package/dist/editor.js +8 -7
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +198 -105
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +11 -12
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.js +42 -14
- package/dist/resizable.js.map +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/virtualized.d.ts +6 -1
- package/dist/virtualized.js +12 -11
- package/dist/virtualized.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6A5RHW2W.js.map +0 -1
- package/dist/chunk-F2BNJSON.js.map +0 -1
- package/dist/chunk-GQVBZ4GW.js.map +0 -1
- package/dist/chunk-HP7WUZPK.js +0 -81
- package/dist/chunk-HP7WUZPK.js.map +0 -1
- package/dist/chunk-HTXP5BMM.js +0 -38
- package/dist/chunk-HTXP5BMM.js.map +0 -1
- package/dist/chunk-JTU7OBYJ.js.map +0 -1
- package/dist/chunk-KTPGMJUK.js.map +0 -1
- package/dist/chunk-NI5542ZM.js.map +0 -1
- package/dist/chunk-NLXQ323J.js.map +0 -1
- package/dist/chunk-OIOII5L6.js.map +0 -1
- package/dist/chunk-RHWTMTU5.js.map +0 -1
- package/dist/chunk-UNS4TGGK.js.map +0 -1
- package/dist/chunk-WH2FUFAC.js +0 -15
- package/dist/chunk-WH2FUFAC.js.map +0 -1
- package/dist/chunk-Z4MCD73B.js.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { Badge } from './chunk-
|
|
2
|
+
import { Badge } from './chunk-BZRZENBS.js';
|
|
3
|
+
import { useKeyboardScroll } from './chunk-ACLKDE5W.js';
|
|
3
4
|
import { slotIcon, Icon } from './chunk-L6HWACK7.js';
|
|
4
|
-
import { cn, FOCUS_RING } from './chunk-
|
|
5
|
+
import { cn, FOCUS_RING, FOCUS_INSET } from './chunk-YL5KD5RC.js';
|
|
5
6
|
import { forwardRef, useState, useCallback } from 'react';
|
|
6
7
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
7
8
|
|
|
@@ -23,6 +24,8 @@ function CodeBlock({
|
|
|
23
24
|
}, [code]);
|
|
24
25
|
const lines = code.split("\n");
|
|
25
26
|
const wraps = wrap ?? lines.length === 1;
|
|
27
|
+
const [scroller, setScroller] = useState(null);
|
|
28
|
+
useKeyboardScroll(scroller, "Code", !wraps, false, "x");
|
|
26
29
|
const gutterWidth = showLineNumbers ? `${String(lines.length).length + 1}ch` : void 0;
|
|
27
30
|
return /* @__PURE__ */ jsxs(
|
|
28
31
|
"div",
|
|
@@ -60,7 +63,7 @@ function CodeBlock({
|
|
|
60
63
|
}
|
|
61
64
|
)
|
|
62
65
|
] }),
|
|
63
|
-
/* @__PURE__ */ jsx("div", { className: wraps ? void 0 : "overflow-x-auto", "data-wrap": wraps ? "true" : void 0, children: /* @__PURE__ */ jsx("pre", { className: cn("p-ds-4 text-sm leading-relaxed font-[family-name:var(--ds-font-mono)]", wraps && "whitespace-pre-wrap break-words"), children: /* @__PURE__ */ jsx("code", { children: lines.map((line, i) => (
|
|
66
|
+
/* @__PURE__ */ jsx("div", { ref: setScroller, className: wraps ? void 0 : cn("overflow-x-auto", FOCUS_INSET), "data-wrap": wraps ? "true" : void 0, children: /* @__PURE__ */ jsx("pre", { className: cn("p-ds-4 text-sm leading-relaxed font-[family-name:var(--ds-font-mono)]", wraps && "whitespace-pre-wrap break-words"), children: /* @__PURE__ */ jsx("code", { children: lines.map((line, i) => (
|
|
64
67
|
// with line numbers each line is a two-column row, so a wrapped line continues under its text, not under the gutter
|
|
65
68
|
/* @__PURE__ */ jsxs("span", { className: showLineNumbers ? "grid grid-cols-[max-content_1fr]" : "block", children: [
|
|
66
69
|
showLineNumbers && /* @__PURE__ */ jsx(
|
|
@@ -159,5 +162,5 @@ function Divider({
|
|
|
159
162
|
}
|
|
160
163
|
|
|
161
164
|
export { CodeBlock, Divider, Link };
|
|
162
|
-
//# sourceMappingURL=chunk-
|
|
163
|
-
//# sourceMappingURL=chunk-
|
|
165
|
+
//# sourceMappingURL=chunk-SQHKC4HA.js.map
|
|
166
|
+
//# sourceMappingURL=chunk-SQHKC4HA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/CodeBlock.tsx","../../../showcase/src/components/Link.tsx","../../../showcase/src/components/Divider.tsx"],"names":["Link","jsxs","jsx"],"mappings":";;;;;;;;AAeO,SAAS,SAAA,CAAU;AAAA,EACxB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA,GAAkB,KAAA;AAAA,EAClB,IAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAE1C,EAAA,MAAM,UAAA,GAAa,YAAY,YAAY;AACzC,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AACxC,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,CAAA,EAAG,GAAI,CAAA;AAAA,IACzC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,EAAA,MAAM,KAAA,GAAQ,IAAA,IAAQ,KAAA,CAAM,MAAA,KAAW,CAAA;AAEvC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAgC,IAAI,CAAA;AACpE,EAAA,iBAAA,CAAkB,QAAA,EAAU,MAAA,EAAQ,CAAC,KAAA,EAAO,OAAO,GAAG,CAAA;AACtD,EAAA,MAAM,WAAA,GAAc,kBAAkB,CAAA,EAAG,MAAA,CAAO,MAAM,MAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,EAAA,CAAA,GAAO,MAAA;AAE/E,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,gBAAA;AAAA,QACA,yDAAA;AAAA,QACA,yEAAA;AAAA,QACA,+BAAA;AAAA,QACA,8BAAA;AAAA,QACA,iBAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,qJAAA,EACb,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACZ,QAAA,EAAA,QAAA,oBAAY,GAAA,CAAC,KAAA,EAAA,EAAM,OAAA,EAAQ,SAAA,EAAU,IAAA,EAAK,IAAA,EAAM,QAAA,EAAA,QAAA,EAAS,CAAA,EAC5D,CAAA;AAAA,0BACA,IAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,UAAA;AAAA,cACT,SAAA,EAAW,EAAA;AAAA,gBACT,wFAAA;AAAA,gBACA,iEAAA;AAAA,gBACA,+BAAA;AAAA,gBACA,iCAAA;AAAA,gBACA,mBAAA;AAAA,gBACA;AAAA,eACF;AAAA,cACA,YAAA,EAAY,SAAS,QAAA,GAAW,WAAA;AAAA,cAGhC,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,QAAK,IAAA,EAAM,MAAA,GAAS,OAAA,GAAU,MAAA,EAAQ,MAAM,EAAA,EAAI,CAAA;AAAA,gBAChD,SAAS,QAAA,GAAW;AAAA;AAAA;AAAA;AACvB,SAAA,EACF,CAAA;AAAA,wBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,WAAA,EAAa,SAAA,EAAW,KAAA,GAAQ,MAAA,GAAY,EAAA,CAAG,iBAAA,EAAmB,WAAW,CAAA,EAAG,WAAA,EAAW,KAAA,GAAQ,MAAA,GAAS,MAAA,EACpH,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,uEAAA,EAAyE,KAAA,IAAS,iCAAiC,CAAA,EACpI,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA;AAAA;AAAA,0BAEhB,IAAA,CAAC,MAAA,EAAA,EAAa,SAAA,EAAW,eAAA,GAAkB,qCAAqC,OAAA,EAC7E,QAAA,EAAA;AAAA,YAAA,eAAA,oBACC,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,uEAAA;AAAA,gBACV,KAAA,EAAO,EAAE,KAAA,EAAO,WAAA,EAAY;AAAA,gBAE3B,QAAA,EAAA,CAAA,GAAI;AAAA;AAAA,aACP;AAAA,4BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,kBAAQ,GAAA,EAAI;AAAA,WAAA,EAAA,EAT9B,CAUX;AAAA,SACD,CAAA,EACH,GACF,CAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;ACnEA,IAAM,UAAA,GAAuC;AAAA,EAC3C,MAAA,EAAQ,uHAAA;AAAA,EACR,KAAA,EAAO,qEAAA;AAAA,EACP,OAAA,EAAS;AACX,CAAA;AAEA,IAAM,eAAA,GAAiD;AAAA,EACrD,KAAA,EAAO,8BAAA;AAAA,EACP,MAAA,EAAQ,8BAAA;AAAA,EACR,IAAA,EAAM;AACR,CAAA;AAWO,IAAM,IAAA,GAAO,WAAyC,SAASA,KAAAA,CACpE,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,GAAY,OAAA,EAAS,IAAA,GAAO,QAAA,EAAU,WAAW,KAAA,EAAO,SAAA,EAAW,SAAA,EAAW,QAAA,EAAU,SAAA,EAAW,SAAA,EAAW,QAAQ,GAAA,EAAK,GAAG,KAAA,EAAM,EACtJ,GAAA,EACA;AACA,EAAA,MAAM,OAAA,GAAU,EAAA;AAAA,IACd,8DAAA;AAAA,IACA,yDAAA;AAAA,IACA,UAAA;AAAA,IACA,+BAAA;AAAA,IACA,WAAW,IAAI,CAAA;AAAA,IACf,gBAAgB,SAAS,CAAA;AAAA,IACzB;AAAA,GACF;AACA,EAAA,MAAM,cAAA,GAAiB,WAAW,QAAA,GAAW,MAAA;AAC7C,EAAA,MAAM,WAAA,GAAc,QAAA,GAAW,EAAA,CAAG,qBAAA,EAAuB,GAAG,CAAA,GAAI,GAAA;AAChE,EAAA,MAAM,OAAA,mBACJC,IAAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,QAAA,CAAS,QAAA,EAAU,IAAI,iBAAiB,CAAA;AAAA,IACxC,QAAA;AAAA,IACA,QAAA,CAAS,SAAA,EAAW,EAAA,EAAI,kBAAkB;AAAA,GAAA,EAC7C,CAAA;AAGF,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,uBACEC,GAAAA,CAAC,SAAA,EAAA,EAAU,GAAA,EAAU,MAAY,EAAA,EAAI,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,QAAQ,cAAA,EAAgB,GAAA,EAAK,WAAA,EAAc,GAAG,OAC1G,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACEA,GAAAA,CAAC,GAAA,EAAA,EAAE,GAAA,EAAU,IAAA,EAAY,SAAA,EAAW,OAAA,EAAS,MAAA,EAAQ,cAAA,EAAgB,GAAA,EAAK,WAAA,EAAc,GAAG,OACxF,QAAA,EAAA,OAAA,EACH,CAAA;AAEJ,CAAC;AC7EM,SAAS,OAAA,CAAQ;AAAA,EACtB,WAAA,GAAc,YAAA;AAAA,EACd,KAAA;AAAA,EACA;AACF,CAAA,EAAiB;AACf,EAAA,IAAI,gBAAgB,UAAA,EAAY;AAC9B,IAAA,uBACEA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,WAAA;AAAA,QACL,kBAAA,EAAiB,UAAA;AAAA,QACjB,SAAA,EAAW,EAAA;AAAA,UACT,uCAAA;AAAA,UACA,6BAAA;AAAA,UACA,+BAAA;AAAA,UACA;AAAA;AACF;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,uBACED,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,WAAA;AAAA,QACL,SAAA,EAAW,EAAA,CAAG,4BAAA,EAA8B,SAAS,CAAA;AAAA,QAErD,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kEAAA,EAAmE,CAAA;AAAA,0BACnFA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4DACb,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,0BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kEAAA,EAAmE;AAAA;AAAA;AAAA,KACrF;AAAA,EAEJ;AAEA,EAAA,uBACEA,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,WAAA;AAAA,MACL,SAAA,EAAW,EAAA;AAAA,QACT,oBAAA;AAAA,QACA,6BAAA;AAAA,QACA,+BAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ","file":"chunk-SQHKC4HA.js","sourcesContent":["import { useState, useCallback } from \"react\";\nimport { cn, FOCUS_INSET, FOCUS_RING } from \"../lib/utils\";\nimport { useKeyboardScroll } from \"../lib/use-keyboard-scroll\";\nimport { Icon } from \"../lib/icons\";\nimport { Badge } from \"./Badge\";\n\ninterface CodeBlockProps {\n code: string;\n language?: string;\n showLineNumbers?: boolean;\n /** Wrap long lines instead of scrolling sideways. Default: on for a single-line snippet (a tracking tag, a command), off for multi-line code. */\n wrap?: boolean;\n className?: string;\n}\n\nexport function CodeBlock({\n code,\n language,\n showLineNumbers = false,\n wrap,\n className,\n}: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n /* clipboard not available */\n }\n }, [code]);\n\n const lines = code.split(\"\\n\");\n const wraps = wrap ?? lines.length === 1;\n // code that scrolls sideways, with nothing in it to Tab to: a Tab stop while it scrolls (Sprint 25.30 item 2)\n const [scroller, setScroller] = useState<HTMLDivElement | null>(null);\n useKeyboardScroll(scroller, \"Code\", !wraps, false, \"x\");\n const gutterWidth = showLineNumbers ? `${String(lines.length).length + 1}ch` : undefined;\n\n return (\n <div\n className={cn(\n \"relative group\",\n \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-shadow-sm)]\",\n \"overflow-hidden\",\n className,\n )}\n >\n <div className=\"flex items-center justify-between px-ds-4 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] bg-[var(--ds-bg-muted)]\">\n <div className=\"flex items-center gap-ds-2\">\n {language && <Badge variant=\"outline\" size=\"sm\">{language}</Badge>}\n </div>\n <button\n type=\"button\"\n onClick={handleCopy}\n className={cn(\n \"inline-flex items-center gap-ds-1.5 px-ds-2 py-ds-1 text-xs font-medium cursor-pointer\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)]\",\n \"rounded-[var(--ds-radius-sm)]\",\n \"hover:bg-[var(--ds-bg-surface)]\",\n \"transition-colors\",\n FOCUS_RING,\n )}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n >\n {/* Sprint 25.8.7 item 12: the copy icon, where a folder stood */}\n <Icon name={copied ? \"check\" : \"copy\"} size={14} />\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n\n <div ref={setScroller} className={wraps ? undefined : cn(\"overflow-x-auto\", FOCUS_INSET)} data-wrap={wraps ? \"true\" : undefined}>\n <pre className={cn(\"p-ds-4 text-sm leading-relaxed font-[family-name:var(--ds-font-mono)]\", wraps && \"whitespace-pre-wrap break-words\")}>\n <code>\n {lines.map((line, i) => (\n // with line numbers each line is a two-column row, so a wrapped line continues under its text, not under the gutter\n <span key={i} className={showLineNumbers ? \"grid grid-cols-[max-content_1fr]\" : \"block\"}>\n {showLineNumbers && (\n <span\n className=\"text-right text-[var(--ds-text-muted)] select-none mr-ds-4 opacity-50\"\n style={{ width: gutterWidth }}\n >\n {i + 1}\n </span>\n )}\n <span className=\"min-w-0\">{line || \" \"}</span>\n </span>\n ))}\n </code>\n </pre>\n </div>\n </div>\n );\n}\n","import { forwardRef, type AnchorHTMLAttributes, type ElementType, type ReactNode } from \"react\";\nimport { cn, FOCUS_RING } from \"../lib/utils\";\nimport { slotIcon, type IconSlot } from \"../lib/icons\";\n\ntype LinkUnderline = \"hover\" | \"always\" | \"none\";\ntype LinkTone = \"accent\" | \"muted\" | \"inherit\";\n\nexport interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string;\n children: ReactNode;\n /** When to show the underline. Default \"hover\". */\n underline?: LinkUnderline;\n /** Colour: accent (default), muted for secondary links, inherit to match surrounding text. */\n tone?: LinkTone;\n /** Opens in a new tab with rel=\"noopener noreferrer\". Default false. */\n external?: boolean;\n /**\n * Render through a router link component instead of a plain anchor\n * (e.g. `component={RouterLink}` from react-router or next/link). The\n * component receives the same props; `href` is also passed as `to` for\n * react-router compatibility. Any element type: a router's Link requires\n * its own props (react-router's `to`), which a narrower type refused under\n * strict TypeScript (Sprint 25.16 A19).\n */\n component?: ElementType;\n /** An icon name (\"info\"), drawn as the theme's icon at 14 px, or an element. Not text: use children. */\n iconLeft?: IconSlot;\n /** As iconLeft, after the label. */\n iconRight?: IconSlot;\n}\n\nconst toneStyles: Record<LinkTone, string> = {\n accent: \"text-[var(--ds-accent-ink)] hover:text-[var(--ds-accent-primary-hover)] active:text-[var(--ds-accent-primary-active)]\",\n muted: \"text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)]\",\n inherit: \"text-inherit hover:text-[var(--ds-accent-ink)]\",\n};\n\nconst underlineStyles: Record<LinkUnderline, string> = {\n hover: \"no-underline hover:underline\",\n always: \"underline underline-offset-2\",\n none: \"no-underline\",\n};\n\n/**\n * Navigation link. Renders a real <a> (or a router link via `component`) so\n * middle-click, open-in-new-tab, right-click \"copy link\" and screen readers\n * all behave correctly. Visually identical to Button variant=\"link\".\n *\n * Use Link for NAVIGATION (to a page or URL). Use Button variant=\"link\" for an\n * ACTION that should look like a link (show more, resend code). Never use a\n * ghost Button for inline text — its padding breaks the line.\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(\n { href, children, underline = \"hover\", tone = \"accent\", external = false, component: Component, iconLeft, iconRight, className, target, rel, ...props },\n ref,\n) {\n const classes = cn(\n \"inline-flex items-center gap-ds-1 font-medium cursor-pointer\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n FOCUS_RING,\n \"rounded-[var(--ds-radius-sm)]\",\n toneStyles[tone],\n underlineStyles[underline],\n className,\n );\n const resolvedTarget = external ? \"_blank\" : target;\n const resolvedRel = external ? cn(\"noopener noreferrer\", rel) : rel;\n const content = (\n <>\n {slotIcon(iconLeft, 14, \"Link's iconLeft\")}\n {children}\n {slotIcon(iconRight, 14, \"Link's iconRight\")}\n </>\n );\n\n if (Component) {\n return (\n <Component ref={ref} href={href} to={href} className={classes} target={resolvedTarget} rel={resolvedRel} {...props}>\n {content}\n </Component>\n );\n }\n\n return (\n <a ref={ref} href={href} className={classes} target={resolvedTarget} rel={resolvedRel} {...props}>\n {content}\n </a>\n );\n});\n","import { cn } from \"../lib/utils\";\nimport type { ReactNode } from \"react\";\n\ntype Orientation = \"horizontal\" | \"vertical\";\n\ninterface DividerProps {\n orientation?: Orientation;\n label?: ReactNode;\n className?: string;\n}\n\nexport function Divider({\n orientation = \"horizontal\",\n label,\n className,\n}: DividerProps) {\n if (orientation === \"vertical\") {\n return (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cn(\n \"inline-block self-stretch min-h-[1em]\",\n \"w-[var(--ds-divider-width)]\",\n \"bg-[var(--ds-border-default)]\",\n className,\n )}\n />\n );\n }\n\n if (label) {\n return (\n <div\n role=\"separator\"\n className={cn(\"flex items-center gap-ds-3\", className)}\n >\n <span className=\"flex-1 h-[var(--ds-divider-width)] bg-[var(--ds-border-default)]\" />\n <span className=\"text-xs font-medium text-[var(--ds-text-muted)] shrink-0\">\n {label}\n </span>\n <span className=\"flex-1 h-[var(--ds-divider-width)] bg-[var(--ds-border-default)]\" />\n </div>\n );\n }\n\n return (\n <hr\n role=\"separator\"\n className={cn(\n \"border-none w-full\",\n \"h-[var(--ds-divider-width)]\",\n \"bg-[var(--ds-border-default)]\",\n className,\n )}\n />\n );\n}\n"]}
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
import { useShellPreferences, PREFERENCE_HOUSE_DEFAULTS } from './chunk-TYNDXMBV.js';
|
|
3
3
|
import { useInputModality } from './chunk-7RKC5C7G.js';
|
|
4
4
|
import { useReportedChange, useOptionalFormContext, FormChangeCtx } from './chunk-72SDAX54.js';
|
|
5
|
-
import { ControlSizeContext, triggerType, RowsCtx, Button } from './chunk-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { useTextOverflow, AutoTooltip } from './chunk-GQVBZ4GW.js';
|
|
9
|
-
import { Slot } from './chunk-7Q46JXSK.js';
|
|
5
|
+
import { ControlSizeContext, triggerType, RowsCtx, Button } from './chunk-MIUSSYVE.js';
|
|
6
|
+
import { useTextOverflow } from './chunk-ZCDA74RQ.js';
|
|
7
|
+
import { useRevealFocus, AutoTooltip } from './chunk-WWN6CQKI.js';
|
|
10
8
|
import { Icon, warnOnce } from './chunk-L6HWACK7.js';
|
|
11
|
-
import {
|
|
12
|
-
import { useLatest } from './chunk-
|
|
13
|
-
import { cn, ERROR_HAS_FOCUS_RING, FIELD_HAS_FOCUS_RING, ERROR_FOCUS_RING, FIELD_FOCUS_RING, FOCUS_RING, ERROR_ACTIVE_RING, ACTIVE_RING, ERROR_FOCUS_WITHIN_RING, FIELD_FOCUS_WITHIN_RING, GLASS_DROPDOWN } from './chunk-
|
|
9
|
+
import { Slot } from './chunk-7Q46JXSK.js';
|
|
10
|
+
import { useLatest, useFocusLeave, usePopupFocus, focusAfterRemoval, usePosition, usePressMarks, focusInitial, focusAfterSelfRemoval, tabStops } from './chunk-4HJDOZ2M.js';
|
|
11
|
+
import { cn, ERROR_HAS_FOCUS_RING, FIELD_HAS_FOCUS_RING, ERROR_FOCUS_RING, FIELD_FOCUS_RING, FOCUS_RING, ERROR_ACTIVE_RING, ACTIVE_RING, ERROR_FOCUS_WITHIN_RING, FIELD_FOCUS_WITHIN_RING, GLASS_DROPDOWN } from './chunk-YL5KD5RC.js';
|
|
14
12
|
import { createContext, useContext, useRef, useCallback, useEffect, useId, useState, Children, isValidElement, useMemo, cloneElement, useLayoutEffect } from 'react';
|
|
15
13
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
16
14
|
import { createPortal } from 'react-dom';
|
|
@@ -411,6 +409,7 @@ function Dropdown({
|
|
|
411
409
|
const triggerId = control.id ?? generatedId;
|
|
412
410
|
const labelSpanId = `${triggerId}-label`;
|
|
413
411
|
const labelledBy = control.labelId ? `${control.labelId} ${triggerId}` : label && !ariaLabel ? `${labelSpanId} ${triggerId}` : void 0;
|
|
412
|
+
const listLabelledBy = control.labelId ?? (label && !ariaLabel ? labelSpanId : void 0);
|
|
414
413
|
const invalid = control.invalid;
|
|
415
414
|
const size = sizeProp ?? contextSize ?? "md";
|
|
416
415
|
const [open, setOpen] = useState(false);
|
|
@@ -558,6 +557,8 @@ function Dropdown({
|
|
|
558
557
|
groups.get(g).push(opt);
|
|
559
558
|
}
|
|
560
559
|
const hasGroups = Array.from(groups.keys()).some((k) => k !== "");
|
|
560
|
+
const drawn = hasGroups ? Array.from(groups.values()).flat() : filtered;
|
|
561
|
+
const stopId = (drawn.find((o) => selectedValues.includes(o.id)) ?? drawn[0])?.id;
|
|
561
562
|
const handleSelect = (id) => {
|
|
562
563
|
if (multiple) {
|
|
563
564
|
const arr = selectedValues.includes(id) ? selectedValues.filter((v) => v !== id) : [...selectedValues, id];
|
|
@@ -654,12 +655,13 @@ function Dropdown({
|
|
|
654
655
|
className: cn("w-full bg-transparent text-[var(--ds-text-primary)] placeholder:text-[var(--ds-text-muted)] outline-none", size === "sm" ? "text-xs" : "text-sm")
|
|
655
656
|
}
|
|
656
657
|
) }),
|
|
657
|
-
/* @__PURE__ */ jsx("div", { ref: setListbox, role: "listbox", className: "overflow-y-auto scroll-p-[4px]", style: { padding: "max(var(--ds-space-1), 4px)", maxHeight: "var(--ds-dropdown-max-height)" }, children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: cn("text-[var(--ds-text-muted)] text-center py-ds-4", size === "sm" ? "text-xs" : "text-sm"), children: "No options found" }) : hasGroups ? Array.from(groups.entries()).map(([group, opts]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
658
|
+
/* @__PURE__ */ jsx("div", { ref: setListbox, role: "listbox", "aria-labelledby": listLabelledBy, "aria-label": listLabelledBy ? void 0 : ariaLabel, "aria-multiselectable": multiple || void 0, className: "overflow-y-auto scroll-p-[4px]", style: { padding: "max(var(--ds-space-1), 4px)", maxHeight: "var(--ds-dropdown-max-height)" }, children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: cn("text-[var(--ds-text-muted)] text-center py-ds-4", size === "sm" ? "text-xs" : "text-sm"), children: "No options found" }) : hasGroups ? Array.from(groups.entries()).map(([group, opts]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
658
659
|
group && /* @__PURE__ */ jsx("p", { className: "text-2xs font-medium uppercase tracking-wider text-[var(--ds-text-muted)] px-ds-2 pt-ds-2 pb-ds-1", children: group }),
|
|
659
660
|
opts.map((opt) => /* @__PURE__ */ jsx(
|
|
660
661
|
OptionButton,
|
|
661
662
|
{
|
|
662
663
|
opt,
|
|
664
|
+
tabStop: opt.id === stopId,
|
|
663
665
|
isSelected: selectedValues.includes(opt.id),
|
|
664
666
|
multiple,
|
|
665
667
|
onSelect: handleSelect,
|
|
@@ -671,6 +673,7 @@ function Dropdown({
|
|
|
671
673
|
OptionButton,
|
|
672
674
|
{
|
|
673
675
|
opt,
|
|
676
|
+
tabStop: opt.id === stopId,
|
|
674
677
|
isSelected: selectedValues.includes(opt.id),
|
|
675
678
|
multiple,
|
|
676
679
|
onSelect: handleSelect,
|
|
@@ -691,7 +694,7 @@ function Dropdown({
|
|
|
691
694
|
className: "inline-flex items-center gap-ds-1 text-xs rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)] px-ds-1.5 py-ds-0.5",
|
|
692
695
|
children: [
|
|
693
696
|
opt.label,
|
|
694
|
-
/* @__PURE__ */ jsx(
|
|
697
|
+
/* @__PURE__ */ jsx(AutoTooltip, { content: `Remove ${opt.label}`, children: /* @__PURE__ */ jsx(
|
|
695
698
|
"button",
|
|
696
699
|
{
|
|
697
700
|
type: "button",
|
|
@@ -704,7 +707,7 @@ function Dropdown({
|
|
|
704
707
|
"aria-label": `Remove ${opt.label}`,
|
|
705
708
|
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 10 })
|
|
706
709
|
}
|
|
707
|
-
)
|
|
710
|
+
) })
|
|
708
711
|
]
|
|
709
712
|
},
|
|
710
713
|
v
|
|
@@ -714,6 +717,7 @@ function Dropdown({
|
|
|
714
717
|
}
|
|
715
718
|
function OptionButton({
|
|
716
719
|
opt,
|
|
720
|
+
tabStop,
|
|
717
721
|
isSelected,
|
|
718
722
|
multiple,
|
|
719
723
|
onSelect,
|
|
@@ -726,7 +730,7 @@ function OptionButton({
|
|
|
726
730
|
role: "option",
|
|
727
731
|
"data-option-id": opt.id,
|
|
728
732
|
"aria-selected": isSelected,
|
|
729
|
-
tabIndex: -1,
|
|
733
|
+
tabIndex: tabStop ? 0 : -1,
|
|
730
734
|
onClick: () => onSelect(opt.id),
|
|
731
735
|
className: cn(
|
|
732
736
|
"w-full text-left cursor-pointer rounded-[var(--ds-radius-sm)]",
|
|
@@ -1098,11 +1102,31 @@ function contentTop(el) {
|
|
|
1098
1102
|
}
|
|
1099
1103
|
function LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, className }) {
|
|
1100
1104
|
const marker = useRef(null);
|
|
1105
|
+
const button = useRef(null);
|
|
1106
|
+
const pager = useRef(null);
|
|
1107
|
+
const watching = useRef(null);
|
|
1108
|
+
const press = () => {
|
|
1109
|
+
const b = button.current, root = pager.current;
|
|
1110
|
+
if (b && root && document.activeElement === b) {
|
|
1111
|
+
const list = root.previousElementSibling;
|
|
1112
|
+
const had = new Set(rowsOf(list));
|
|
1113
|
+
watching.current?.();
|
|
1114
|
+
watching.current = focusAfterSelfRemoval(b, {
|
|
1115
|
+
item: root,
|
|
1116
|
+
to: () => {
|
|
1117
|
+
const fresh = rowsOf(list).find((r) => !had.has(r));
|
|
1118
|
+
return fresh ? tabStops(fresh)[0] ?? fresh : null;
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
onLoadMore();
|
|
1123
|
+
};
|
|
1101
1124
|
const load = useLatest(onLoadMore);
|
|
1102
1125
|
const loadedAt = useRef(null);
|
|
1126
|
+
const [held, setHeld] = useState(false);
|
|
1103
1127
|
useEffect(() => {
|
|
1104
1128
|
const el = marker.current;
|
|
1105
|
-
if (!scroll || !hasMore || !el || typeof IntersectionObserver === "undefined") return;
|
|
1129
|
+
if (!scroll || !hasMore || !el || held || typeof IntersectionObserver === "undefined") return;
|
|
1106
1130
|
const observer = new IntersectionObserver((entries) => {
|
|
1107
1131
|
if (!entries.some((e) => e.isIntersecting)) return;
|
|
1108
1132
|
const at = contentTop(el);
|
|
@@ -1119,13 +1143,40 @@ function LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, cla
|
|
|
1119
1143
|
observer.disconnect();
|
|
1120
1144
|
window.removeEventListener("scroll", rearm, { capture: true });
|
|
1121
1145
|
};
|
|
1122
|
-
}, [scroll, hasMore, currentPage, load]);
|
|
1146
|
+
}, [scroll, hasMore, currentPage, load, held]);
|
|
1147
|
+
useEffect(() => {
|
|
1148
|
+
const b = button.current;
|
|
1149
|
+
if (b && document.activeElement === b) b.scrollIntoView?.({ block: "nearest" });
|
|
1150
|
+
}, [currentPage]);
|
|
1123
1151
|
if (!hasMore) return null;
|
|
1124
|
-
return /* @__PURE__ */ jsxs("div", { "data-ds-pager": "", "data-pagination-mode": scroll ? "infinite-scroll" : "load-more", className: cn("flex flex-col items-center", className), children: [
|
|
1152
|
+
return /* @__PURE__ */ jsxs("div", { ref: pager, "data-ds-pager": "", "data-pagination-mode": scroll ? "infinite-scroll" : "load-more", className: cn("flex flex-col items-center", className), children: [
|
|
1125
1153
|
scroll && /* @__PURE__ */ jsx("div", { ref: marker, "data-load-more-trigger": "", "aria-hidden": "true", className: "h-px w-full" }),
|
|
1126
|
-
/* @__PURE__ */ jsx(
|
|
1154
|
+
/* @__PURE__ */ jsx(
|
|
1155
|
+
Button,
|
|
1156
|
+
{
|
|
1157
|
+
ref: button,
|
|
1158
|
+
type: "button",
|
|
1159
|
+
variant: "secondary",
|
|
1160
|
+
onClick: press,
|
|
1161
|
+
onFocus: (e) => setHeld(scroll && byKeyboard(e.currentTarget)),
|
|
1162
|
+
onBlur: () => setHeld(false),
|
|
1163
|
+
children: loadMoreLabel ?? "Load more"
|
|
1164
|
+
}
|
|
1165
|
+
)
|
|
1127
1166
|
] });
|
|
1128
1167
|
}
|
|
1168
|
+
function rowsOf(list) {
|
|
1169
|
+
if (!list) return [];
|
|
1170
|
+
const marked = list.querySelectorAll("[data-row-key], [data-row-index]");
|
|
1171
|
+
return Array.from(marked.length ? marked : list.querySelectorAll('tbody > tr, li, [role="row"], [data-card]'));
|
|
1172
|
+
}
|
|
1173
|
+
function byKeyboard(el) {
|
|
1174
|
+
try {
|
|
1175
|
+
return el.matches(":focus-visible");
|
|
1176
|
+
} catch {
|
|
1177
|
+
return true;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1129
1180
|
function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSizeProp, pageSizeOptions, onPageSizeChange, className }) {
|
|
1130
1181
|
const pages = buildPageRange(currentPage, totalPages);
|
|
1131
1182
|
const preferences = useShellPreferences();
|
|
@@ -1148,11 +1199,14 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
1148
1199
|
) })
|
|
1149
1200
|
] }),
|
|
1150
1201
|
totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-1", children: [
|
|
1151
|
-
/* @__PURE__ */ jsx(
|
|
1202
|
+
/* @__PURE__ */ jsx(AutoTooltip, { content: "Previous page", children: /* @__PURE__ */ jsx(
|
|
1152
1203
|
"button",
|
|
1153
1204
|
{
|
|
1154
1205
|
type: "button",
|
|
1155
|
-
onClick: () =>
|
|
1206
|
+
onClick: (e) => {
|
|
1207
|
+
focusAfterSelfRemoval(e.currentTarget);
|
|
1208
|
+
onPageChange(currentPage - 1);
|
|
1209
|
+
},
|
|
1156
1210
|
disabled: currentPage <= 1,
|
|
1157
1211
|
"aria-label": "Previous page",
|
|
1158
1212
|
className: cn(
|
|
@@ -1167,7 +1221,7 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
1167
1221
|
),
|
|
1168
1222
|
children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 16, className: "rotate-180" })
|
|
1169
1223
|
}
|
|
1170
|
-
),
|
|
1224
|
+
) }),
|
|
1171
1225
|
pages.map(
|
|
1172
1226
|
(p, i) => p === "..." ? /* @__PURE__ */ jsx(EllipsisJumper, { totalPages, onPageChange }, `ellipsis-${i}`) : /* @__PURE__ */ jsx(
|
|
1173
1227
|
"button",
|
|
@@ -1188,11 +1242,14 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
1188
1242
|
p
|
|
1189
1243
|
)
|
|
1190
1244
|
),
|
|
1191
|
-
/* @__PURE__ */ jsx(
|
|
1245
|
+
/* @__PURE__ */ jsx(AutoTooltip, { content: "Next page", children: /* @__PURE__ */ jsx(
|
|
1192
1246
|
"button",
|
|
1193
1247
|
{
|
|
1194
1248
|
type: "button",
|
|
1195
|
-
onClick: () =>
|
|
1249
|
+
onClick: (e) => {
|
|
1250
|
+
focusAfterSelfRemoval(e.currentTarget);
|
|
1251
|
+
onPageChange(currentPage + 1);
|
|
1252
|
+
},
|
|
1196
1253
|
disabled: currentPage >= totalPages,
|
|
1197
1254
|
"aria-label": "Next page",
|
|
1198
1255
|
className: cn(
|
|
@@ -1207,7 +1264,7 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
1207
1264
|
),
|
|
1208
1265
|
children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 16 })
|
|
1209
1266
|
}
|
|
1210
|
-
)
|
|
1267
|
+
) })
|
|
1211
1268
|
] })
|
|
1212
1269
|
] });
|
|
1213
1270
|
}
|
|
@@ -1374,5 +1431,5 @@ function useWholeListCheck(component, length, pager) {
|
|
|
1374
1431
|
}
|
|
1375
1432
|
|
|
1376
1433
|
export { AddAnotherRowCtx, CHECK_FILL, Dropdown, Field, FilterRowContext, InlineFieldError, Input, Label, NumberInput, OutsideField, Pagination, Popover, SWITCH_KNOB_MOTION, SWITCH_KNOB_OFF, SWITCH_KNOB_ON, SWITCH_TRACK_OFF, SWITCH_TRACK_ON, Textarea, Toggle, pagerPart, useField, useFieldControl, usePagination, useWholeListCheck };
|
|
1377
|
-
//# sourceMappingURL=chunk-
|
|
1378
|
-
//# sourceMappingURL=chunk-
|
|
1434
|
+
//# sourceMappingURL=chunk-USHW523V.js.map
|
|
1435
|
+
//# sourceMappingURL=chunk-USHW523V.js.map
|