gridsmith-ui 0.30.0 → 0.30.1
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 +41 -1
- package/dist/charts.js +21 -8
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +7 -7
- 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-RHWTMTU5.js → chunk-DBHVJ7Z3.js} +5 -49
- package/dist/chunk-DBHVJ7Z3.js.map +1 -0
- package/dist/chunk-IELIF4PJ.js +110 -0
- package/dist/chunk-IELIF4PJ.js.map +1 -0
- package/dist/{chunk-Z4MCD73B.js → chunk-ISONVOA7.js} +7 -7
- package/dist/{chunk-Z4MCD73B.js.map → chunk-ISONVOA7.js.map} +1 -1
- package/dist/{chunk-UNS4TGGK.js → chunk-KMKBOTFR.js} +78 -26
- package/dist/chunk-KMKBOTFR.js.map +1 -0
- package/dist/{chunk-6A5RHW2W.js → chunk-NEUWZUK6.js} +4 -5
- package/dist/chunk-NEUWZUK6.js.map +1 -0
- package/dist/{chunk-NLXQ323J.js → chunk-OVHBQT3Z.js} +5 -4
- package/dist/chunk-OVHBQT3Z.js.map +1 -0
- package/dist/{chunk-KTPGMJUK.js → chunk-OX3NNMWG.js} +4 -4
- package/dist/{chunk-KTPGMJUK.js.map → chunk-OX3NNMWG.js.map} +1 -1
- package/dist/{chunk-OIOII5L6.js → chunk-R5QXMNW7.js} +210 -17
- package/dist/chunk-R5QXMNW7.js.map +1 -0
- package/dist/chunk-SJZWEBHL.js +58 -0
- package/dist/chunk-SJZWEBHL.js.map +1 -0
- package/dist/{chunk-NI5542ZM.js → chunk-SLRTSBCJ.js} +58 -22
- package/dist/chunk-SLRTSBCJ.js.map +1 -0
- package/dist/{chunk-F2BNJSON.js → chunk-T52LAFKG.js} +71 -69
- package/dist/chunk-T52LAFKG.js.map +1 -0
- package/dist/{chunk-GQVBZ4GW.js → chunk-UDJOIVKQ.js} +5 -108
- package/dist/chunk-UDJOIVKQ.js.map +1 -0
- package/dist/{chunk-Q36JVJX4.js → chunk-ULCACQSA.js} +4 -4
- package/dist/{chunk-Q36JVJX4.js.map → chunk-ULCACQSA.js.map} +1 -1
- package/dist/{chunk-HP7WUZPK.js → chunk-WIUGPZOH.js} +10 -3
- package/dist/chunk-WIUGPZOH.js.map +1 -0
- package/dist/{chunk-JTU7OBYJ.js → chunk-YL5KD5RC.js} +4 -3
- package/dist/chunk-YL5KD5RC.js.map +1 -0
- package/dist/data-grid.js +9 -9
- package/dist/editor-mentions.js +4 -5
- package/dist/editor-mentions.js.map +1 -1
- package/dist/editor.js +9 -6
- package/dist/editor.js.map +1 -1
- package/dist/index.js +178 -91
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +12 -11
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.js +43 -13
- 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 +14 -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.map +0 -1
- package/dist/chunk-JTU7OBYJ.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
|
@@ -1 +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":"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","file":"chunk-KTPGMJUK.js","sourcesContent":["import { useState, useCallback } from \"react\";\nimport { cn, FOCUS_RING } from \"../lib/utils\";\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 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 className={wraps ? undefined : \"overflow-x-auto\"} 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"]}
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/CodeBlock.tsx","../../../showcase/src/components/Link.tsx","../../../showcase/src/components/Divider.tsx"],"names":["Link","jsxs","jsx"],"mappings":"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","file":"chunk-OX3NNMWG.js","sourcesContent":["import { useState, useCallback } from \"react\";\nimport { cn, FOCUS_RING } from \"../lib/utils\";\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 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 className={wraps ? undefined : \"overflow-x-auto\"} 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"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useLatest } from './chunk-
|
|
2
|
+
import { useLatest } from './chunk-WIUGPZOH.js';
|
|
3
3
|
import { useRef, useInsertionEffect, useEffect, useCallback, useState, useMemo, useLayoutEffect } from 'react';
|
|
4
4
|
import { flushSync } from 'react-dom';
|
|
5
5
|
|
|
@@ -55,10 +55,34 @@ function focusInitial(root, opts = {}) {
|
|
|
55
55
|
function useFocusBeforeOpen(open) {
|
|
56
56
|
const before = useRef(null);
|
|
57
57
|
useInsertionEffect(() => {
|
|
58
|
-
|
|
58
|
+
trackFocus();
|
|
59
|
+
if (!open) return;
|
|
60
|
+
const active = document.activeElement;
|
|
61
|
+
before.current = !active || active === document.body ? justLost() ?? active : active;
|
|
59
62
|
}, [open]);
|
|
60
63
|
return before;
|
|
61
64
|
}
|
|
65
|
+
var lastFocused = null;
|
|
66
|
+
var lastFocusedAt = 0;
|
|
67
|
+
var lastActedAt = 0;
|
|
68
|
+
var tracking = false;
|
|
69
|
+
function trackFocus() {
|
|
70
|
+
if (tracking || typeof document === "undefined") return;
|
|
71
|
+
tracking = true;
|
|
72
|
+
document.addEventListener("focusin", (e) => {
|
|
73
|
+
lastFocused = e.target instanceof Element ? e.target : null;
|
|
74
|
+
lastFocusedAt = performance.now();
|
|
75
|
+
}, true);
|
|
76
|
+
const acted = () => {
|
|
77
|
+
lastActedAt = performance.now();
|
|
78
|
+
};
|
|
79
|
+
for (const type of ["keydown", "pointerdown", "click"]) document.addEventListener(type, acted, true);
|
|
80
|
+
}
|
|
81
|
+
function justLost() {
|
|
82
|
+
const recent = lastActedAt >= lastFocusedAt && performance.now() - lastActedAt < 1e3;
|
|
83
|
+
return lastFocused && !lastFocused.isConnected && recent ? lastFocused : null;
|
|
84
|
+
}
|
|
85
|
+
trackFocus();
|
|
62
86
|
function pathAbove(to, from) {
|
|
63
87
|
const up = to.replace(/\/+$/, "");
|
|
64
88
|
return from.startsWith(`${up}/`) && from.replace(/\/+$/, "") !== up;
|
|
@@ -74,6 +98,59 @@ function deletedRow(before, now) {
|
|
|
74
98
|
for (let j = k; j < (refilled ? last : now.length); j++) if (now[j] !== before[j + 1]) return -1;
|
|
75
99
|
return k;
|
|
76
100
|
}
|
|
101
|
+
function focusForTheMoment(el) {
|
|
102
|
+
const own = el.getAttribute("tabindex");
|
|
103
|
+
if (own === null) el.setAttribute("tabindex", "-1");
|
|
104
|
+
el.focus();
|
|
105
|
+
if (document.activeElement !== el) {
|
|
106
|
+
if (own === null) el.removeAttribute("tabindex");
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
let ring = false;
|
|
110
|
+
try {
|
|
111
|
+
ring = el.matches(":focus-visible");
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
const { outline, outlineOffset } = el.style;
|
|
115
|
+
if (ring) {
|
|
116
|
+
el.style.outline = "2px solid var(--ds-focus)";
|
|
117
|
+
el.style.outlineOffset = "2px";
|
|
118
|
+
}
|
|
119
|
+
el.addEventListener("blur", () => {
|
|
120
|
+
if (own === null) el.removeAttribute("tabindex");
|
|
121
|
+
if (ring) Object.assign(el.style, { outline, outlineOffset });
|
|
122
|
+
}, { once: true });
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
var HEADING = 'h1, h2, h3, h4, h5, h6, [role="heading"]';
|
|
126
|
+
var LAST_RESORT_MS = 200;
|
|
127
|
+
function placesOf(el) {
|
|
128
|
+
const places = [];
|
|
129
|
+
for (let c = el, box = el.parentElement; box && box !== document.body && box.parentElement && box.parentElement !== document.body; c = box, box = box.parentElement) {
|
|
130
|
+
places.push({ box, prev: c.previousElementSibling, next: c.nextElementSibling });
|
|
131
|
+
}
|
|
132
|
+
return places;
|
|
133
|
+
}
|
|
134
|
+
function landLastResort(places, closing) {
|
|
135
|
+
const at = places.findIndex((p) => p.box.isConnected);
|
|
136
|
+
if (at < 0) return false;
|
|
137
|
+
const { box, prev, next } = places[at];
|
|
138
|
+
const kids = Array.from(box.children);
|
|
139
|
+
const from = prev?.parentElement === box ? kids.indexOf(prev) + 1 : 0;
|
|
140
|
+
const to = next?.parentElement === box ? kids.indexOf(next) : kids.length;
|
|
141
|
+
const areas = [kids.slice(from, Math.max(from, to)), ...places.slice(at).map((p) => [p.box])];
|
|
142
|
+
const counts = (el) => !closing?.contains(el);
|
|
143
|
+
for (const area of areas) {
|
|
144
|
+
const stop = area.flatMap((a) => [...isTabStop(a) ? [a] : [], ...tabStops(a)]).find(counts);
|
|
145
|
+
if (stop) {
|
|
146
|
+
stop.focus();
|
|
147
|
+
if (document.activeElement === stop) return true;
|
|
148
|
+
}
|
|
149
|
+
const heading = area.flatMap((a) => [...a.matches(HEADING) ? [a] : [], ...a.querySelectorAll(HEADING)]).find((h) => h instanceof HTMLElement && isRendered(h) && counts(h));
|
|
150
|
+
if (heading && focusForTheMoment(heading)) return true;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
77
154
|
function rememberFocus(el, { ignoreRoute = false } = {}) {
|
|
78
155
|
const { href, pathname } = location;
|
|
79
156
|
const row = el.closest(ROW);
|
|
@@ -86,6 +163,7 @@ function rememberFocus(el, { ignoreRoute = false } = {}) {
|
|
|
86
163
|
const texts = rows.map((r) => r.textContent ?? "");
|
|
87
164
|
const keyOf = (r) => r?.getAttribute("data-row-key") ?? null;
|
|
88
165
|
const key = keyOf(row);
|
|
166
|
+
const places = placesOf(el);
|
|
89
167
|
const pageChanged = () => {
|
|
90
168
|
if (ignoreRoute) return false;
|
|
91
169
|
if (location.pathname !== pathname) return !pathAbove(location.pathname, pathname);
|
|
@@ -118,16 +196,26 @@ function rememberFocus(el, { ignoreRoute = false } = {}) {
|
|
|
118
196
|
return k >= 0 && k <= at ? list.children[Math.max(0, at - 1)] ?? void 0 : void 0;
|
|
119
197
|
};
|
|
120
198
|
const neighbour = () => inRow(byKey(keyOf(before)) ?? before) || inRow(byKey(keyOf(after)) ?? after) || !!list?.isConnected && land(tabStops(list)[0]);
|
|
199
|
+
const lastResort = () => {
|
|
200
|
+
setTimeout(() => {
|
|
201
|
+
const active = document.activeElement;
|
|
202
|
+
if (active && active !== document.body && active.isConnected || pageChanged()) return;
|
|
203
|
+
landLastResort(places);
|
|
204
|
+
}, LAST_RESORT_MS);
|
|
205
|
+
return false;
|
|
206
|
+
};
|
|
121
207
|
let unwatch = null;
|
|
122
208
|
const watch = () => {
|
|
123
209
|
unwatch?.();
|
|
124
210
|
if (!list || typeof MutationObserver === "undefined") return;
|
|
125
|
-
const observer = new MutationObserver(() => {
|
|
211
|
+
const observer = new MutationObserver((changes) => {
|
|
126
212
|
if (el.isConnected) return;
|
|
127
213
|
const active = document.activeElement;
|
|
128
214
|
const dropped = !active || active === document.body || !active.isConnected;
|
|
129
215
|
stop();
|
|
130
|
-
if (dropped
|
|
216
|
+
if (!dropped || pageChanged()) return;
|
|
217
|
+
const fromList = changes.some((c) => c.target === list || c.target === list.parentNode);
|
|
218
|
+
if (!(fromList && neighbour())) lastResort();
|
|
131
219
|
});
|
|
132
220
|
const onFocusIn = (e) => {
|
|
133
221
|
if (e.target !== el) stop();
|
|
@@ -141,6 +229,7 @@ function rememberFocus(el, { ignoreRoute = false } = {}) {
|
|
|
141
229
|
}
|
|
142
230
|
observer.observe(list, { childList: true });
|
|
143
231
|
if (list.parentNode) observer.observe(list.parentNode, { childList: true });
|
|
232
|
+
for (const { box } of places) observer.observe(box, { childList: true });
|
|
144
233
|
document.addEventListener("focusin", onFocusIn, true);
|
|
145
234
|
unwatch = stop;
|
|
146
235
|
};
|
|
@@ -154,7 +243,89 @@ function rememberFocus(el, { ignoreRoute = false } = {}) {
|
|
|
154
243
|
return true;
|
|
155
244
|
}
|
|
156
245
|
if (row && !row.isConnected && neighbour()) return true;
|
|
157
|
-
return land(fallback);
|
|
246
|
+
return land(fallback) || lastResort();
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function useFocusKeptInList(listRef) {
|
|
251
|
+
useEffect(() => {
|
|
252
|
+
if (typeof MutationObserver === "undefined") return;
|
|
253
|
+
let held = null;
|
|
254
|
+
let observer = null;
|
|
255
|
+
const forget = () => {
|
|
256
|
+
held = null;
|
|
257
|
+
observer?.disconnect();
|
|
258
|
+
observer = null;
|
|
259
|
+
};
|
|
260
|
+
const onFocusIn = (e) => {
|
|
261
|
+
const list = listRef.current;
|
|
262
|
+
const t = e.target;
|
|
263
|
+
if (!list || !(t instanceof HTMLElement) || !list.contains(t)) {
|
|
264
|
+
if (held) forget();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
held = rememberFocus(t);
|
|
268
|
+
if (observer) return;
|
|
269
|
+
observer = new MutationObserver(() => {
|
|
270
|
+
const h = held;
|
|
271
|
+
if (!h || h.el.isConnected) return;
|
|
272
|
+
const active = document.activeElement;
|
|
273
|
+
forget();
|
|
274
|
+
if (!active || active === document.body || !active.isConnected) h.restore();
|
|
275
|
+
});
|
|
276
|
+
observer.observe(list, { childList: true, subtree: true });
|
|
277
|
+
};
|
|
278
|
+
const onFocusOut = (e) => {
|
|
279
|
+
if (!held || e.target !== held.el) return;
|
|
280
|
+
queueMicrotask(() => {
|
|
281
|
+
if (held?.el.isConnected && !listRef.current?.contains(document.activeElement)) forget();
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
document.addEventListener("focusin", onFocusIn, true);
|
|
285
|
+
document.addEventListener("focusout", onFocusOut, true);
|
|
286
|
+
return () => {
|
|
287
|
+
document.removeEventListener("focusin", onFocusIn, true);
|
|
288
|
+
document.removeEventListener("focusout", onFocusOut, true);
|
|
289
|
+
const h = held;
|
|
290
|
+
forget();
|
|
291
|
+
const active = document.activeElement;
|
|
292
|
+
if (h && !h.el.isConnected && (!active || active === document.body || !active.isConnected)) h.restore();
|
|
293
|
+
};
|
|
294
|
+
}, [listRef]);
|
|
295
|
+
}
|
|
296
|
+
var openers = /* @__PURE__ */ new WeakMap();
|
|
297
|
+
function rememberOpener(active, root) {
|
|
298
|
+
let own = active instanceof HTMLElement && active !== document.body && active.isConnected ? rememberFocus(active) : null;
|
|
299
|
+
const controller = !own && root?.id ? document.querySelector(`[aria-controls~="${CSS.escape(root.id)}"]`) : null;
|
|
300
|
+
if (controller) own = rememberFocus(controller);
|
|
301
|
+
let around = null;
|
|
302
|
+
for (let n = active; n && !around; n = n.parentElement) {
|
|
303
|
+
const opener = openers.get(n);
|
|
304
|
+
if (opener) around = { root: n, opener };
|
|
305
|
+
}
|
|
306
|
+
const back = own ?? around?.opener;
|
|
307
|
+
if (!back) {
|
|
308
|
+
if (!root) return null;
|
|
309
|
+
const places = placesOf(root);
|
|
310
|
+
const { pathname } = location;
|
|
311
|
+
return {
|
|
312
|
+
el: null,
|
|
313
|
+
restore() {
|
|
314
|
+
setTimeout(() => {
|
|
315
|
+
const now = document.activeElement;
|
|
316
|
+
if (now && now !== document.body && now.isConnected && !root.contains(now) || location.pathname !== pathname) return;
|
|
317
|
+
landLastResort(places, root);
|
|
318
|
+
}, LAST_RESORT_MS);
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
if (root) openers.set(root, back);
|
|
324
|
+
return {
|
|
325
|
+
el: own?.el ?? null,
|
|
326
|
+
restore(fallback) {
|
|
327
|
+
if (own?.restore(fallback)) return true;
|
|
328
|
+
return !!around && !around.root.isConnected && around.opener.restore();
|
|
158
329
|
}
|
|
159
330
|
};
|
|
160
331
|
}
|
|
@@ -163,8 +334,7 @@ function useReturnFocus(open, root) {
|
|
|
163
334
|
const before = useFocusBeforeOpen(open);
|
|
164
335
|
useEffect(() => {
|
|
165
336
|
if (open) {
|
|
166
|
-
|
|
167
|
-
remembered.current = active2 instanceof HTMLElement && active2 !== document.body && active2.isConnected ? rememberFocus(active2) : null;
|
|
337
|
+
remembered.current = rememberOpener(before.current, root?.current);
|
|
168
338
|
return;
|
|
169
339
|
}
|
|
170
340
|
const r = remembered.current;
|
|
@@ -191,10 +361,14 @@ function rovingTabStop(items, isChecked, isDisabled = () => false) {
|
|
|
191
361
|
function focusAfterRemoval(items, index, fallback) {
|
|
192
362
|
(items[index - 1] ?? items[index] ?? fallback)?.focus();
|
|
193
363
|
}
|
|
194
|
-
function
|
|
364
|
+
function mayStop(root) {
|
|
365
|
+
const disabled = (el) => (el instanceof HTMLButtonElement || el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) && el.disabled;
|
|
366
|
+
return Array.from(root.querySelectorAll(`${FOCUSABLE}, button:disabled, input:disabled, select:disabled, textarea:disabled`)).filter((el) => disabled(el) ? !(el instanceof HTMLInputElement && el.type === "hidden") : isTabStop(el)).sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
367
|
+
}
|
|
368
|
+
function focusAfterSelfRemoval(control, { item, group, to } = {}) {
|
|
195
369
|
const goes = item ?? control;
|
|
196
370
|
const within = group === void 0 ? goes.parentElement : group;
|
|
197
|
-
const stops = within ?
|
|
371
|
+
const stops = within ? mayStop(within).filter((el) => !goes.contains(el)) : [];
|
|
198
372
|
const before = stops.filter((el) => goes.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_PRECEDING).reverse();
|
|
199
373
|
const after = stops.filter((el) => goes.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING);
|
|
200
374
|
const stopsOf = (el) => [...isTabStop(el) ? [el] : [], ...tabStops(el)];
|
|
@@ -224,7 +398,7 @@ function focusAfterSelfRemoval(control, { item, group } = {}) {
|
|
|
224
398
|
within.focus();
|
|
225
399
|
return document.activeElement === within;
|
|
226
400
|
};
|
|
227
|
-
const place = () => land(
|
|
401
|
+
const place = () => land(typeof to === "function" ? to() : to) || land(sameBefore) || before.some(land) || land(sameAfter) || after.some(land) || landOnGroup();
|
|
228
402
|
if (typeof MutationObserver === "undefined") return () => {
|
|
229
403
|
};
|
|
230
404
|
const observer = new MutationObserver(() => {
|
|
@@ -338,6 +512,7 @@ function usePopupFocus(open, { trigger, panel, close, tabExits, onTabOut, marked
|
|
|
338
512
|
const inPanel = active instanceof Node && !!panel.current?.contains(active);
|
|
339
513
|
const opener = active instanceof HTMLElement && active !== document.body && !inPanel ? active : trigger.current;
|
|
340
514
|
remembered.current = opener ? rememberFocus(opener) : null;
|
|
515
|
+
if (panel.current && remembered.current) openers.set(panel.current, remembered.current);
|
|
341
516
|
lastPress.current = null;
|
|
342
517
|
}, [open, trigger, panel, before]);
|
|
343
518
|
useEffect(() => {
|
|
@@ -517,12 +692,13 @@ function useGridKeyboard({ container, active, setActive, keyOf, move, onActivate
|
|
|
517
692
|
return { onKeyDown, tabIndexOf, focusActive, focus };
|
|
518
693
|
}
|
|
519
694
|
var ALWAYS_TOP = () => true;
|
|
520
|
-
function useFocusTrap(root, active, isTop = ALWAYS_TOP) {
|
|
695
|
+
function useFocusTrap(root, active, isTop = ALWAYS_TOP, also) {
|
|
521
696
|
useEffect(() => {
|
|
522
697
|
if (!active) return;
|
|
523
698
|
const onKeyDown = (e) => {
|
|
524
699
|
if (e.key !== "Tab" || e.defaultPrevented || !root.current || !isTop()) return;
|
|
525
|
-
const
|
|
700
|
+
const scope = [root.current, also?.current].filter((el) => !!el);
|
|
701
|
+
const focusable = scope.flatMap((el) => tabStops(el)).sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
526
702
|
if (focusable.length === 0) {
|
|
527
703
|
e.preventDefault();
|
|
528
704
|
return;
|
|
@@ -530,7 +706,7 @@ function useFocusTrap(root, active, isTop = ALWAYS_TOP) {
|
|
|
530
706
|
const first = focusable[0];
|
|
531
707
|
const last = focusable[focusable.length - 1];
|
|
532
708
|
const current = document.activeElement;
|
|
533
|
-
const inside = current instanceof Node &&
|
|
709
|
+
const inside = current instanceof Node && scope.some((el) => el.contains(current));
|
|
534
710
|
if (e.shiftKey) {
|
|
535
711
|
if (!inside || current === first) {
|
|
536
712
|
e.preventDefault();
|
|
@@ -543,7 +719,24 @@ function useFocusTrap(root, active, isTop = ALWAYS_TOP) {
|
|
|
543
719
|
};
|
|
544
720
|
document.addEventListener("keydown", onKeyDown);
|
|
545
721
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
546
|
-
}, [root, active, isTop]);
|
|
722
|
+
}, [root, active, isTop, also]);
|
|
723
|
+
}
|
|
724
|
+
function inertOutside(keep, within) {
|
|
725
|
+
const made = [];
|
|
726
|
+
const visit = (el) => {
|
|
727
|
+
for (const child of Array.from(el.children)) {
|
|
728
|
+
if (keep.includes(child)) continue;
|
|
729
|
+
if (keep.some((k) => child.contains(k))) visit(child);
|
|
730
|
+
else if (!child.hasAttribute("inert")) {
|
|
731
|
+
child.setAttribute("inert", "");
|
|
732
|
+
made.push(child);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
visit(within);
|
|
737
|
+
return () => {
|
|
738
|
+
for (const el of made) el.removeAttribute("inert");
|
|
739
|
+
};
|
|
547
740
|
}
|
|
548
741
|
function useNonModalDialog(root, active, onClose, isTop = ALWAYS_TOP) {
|
|
549
742
|
const onCloseRef = useLatest(onClose);
|
|
@@ -567,6 +760,6 @@ function useNonModalDialog(root, active, onClose, isTop = ALWAYS_TOP) {
|
|
|
567
760
|
}, [active, root, isTop, onCloseRef]);
|
|
568
761
|
}
|
|
569
762
|
|
|
570
|
-
export { CONTROL_ANCESTOR, FIELD, FOCUSABLE, OVERLAY_CLOSE_ATTR, ZOOM_KEYS, focusAfterRemoval, focusAfterSelfRemoval, focusInitial, isTabStop, rememberFocus, rovingTabStop, tabStops, useCloseOnFocusOut, useFocusBeforeOpen, useFocusLeave, useFocusTrap, useGridKeyboard, useNonModalDialog, useOverlayLayer, usePopupFocus, usePressMarks, useReturnFocus };
|
|
571
|
-
//# sourceMappingURL=chunk-
|
|
572
|
-
//# sourceMappingURL=chunk-
|
|
763
|
+
export { CONTROL_ANCESTOR, FIELD, FOCUSABLE, OVERLAY_CLOSE_ATTR, ZOOM_KEYS, focusAfterRemoval, focusAfterSelfRemoval, focusInitial, inertOutside, isTabStop, rememberFocus, rememberOpener, rovingTabStop, tabStops, useCloseOnFocusOut, useFocusBeforeOpen, useFocusKeptInList, useFocusLeave, useFocusTrap, useGridKeyboard, useNonModalDialog, useOverlayLayer, usePopupFocus, usePressMarks, useReturnFocus };
|
|
764
|
+
//# sourceMappingURL=chunk-R5QXMNW7.js.map
|
|
765
|
+
//# sourceMappingURL=chunk-R5QXMNW7.js.map
|