@entifix/react-controls 0.1.2 → 0.1.3
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/README.md +5 -5
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/primitives.d.ts +12 -0
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +12 -0
- package/dist/primitives.js.map +1 -1
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +1 -0
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/theme-script.d.ts +26 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +38 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/dist/ui/atoms/external-link/external-link.d.ts +9 -0
- package/dist/ui/atoms/external-link/external-link.d.ts.map +1 -0
- package/dist/ui/atoms/external-link/external-link.js +13 -0
- package/dist/ui/atoms/external-link/external-link.js.map +1 -0
- package/dist/ui/atoms/external-link/index.d.ts +2 -0
- package/dist/ui/atoms/external-link/index.d.ts.map +1 -0
- package/dist/ui/atoms/external-link/index.js +3 -0
- package/dist/ui/atoms/external-link/index.js.map +1 -0
- package/dist/ui/atoms/switch/index.d.ts +2 -0
- package/dist/ui/atoms/switch/index.d.ts.map +1 -0
- package/dist/ui/atoms/switch/index.js +3 -0
- package/dist/ui/atoms/switch/index.js.map +1 -0
- package/dist/ui/atoms/switch/switch.d.ts +10 -0
- package/dist/ui/atoms/switch/switch.d.ts.map +1 -0
- package/dist/ui/atoms/switch/switch.js +43 -0
- package/dist/ui/atoms/switch/switch.js.map +1 -0
- package/dist/ui/molecules/nav-menu/index.d.ts +2 -0
- package/dist/ui/molecules/nav-menu/index.d.ts.map +1 -0
- package/dist/ui/molecules/nav-menu/index.js +3 -0
- package/dist/ui/molecules/nav-menu/index.js.map +1 -0
- package/dist/ui/molecules/nav-menu/nav-menu.d.ts +30 -0
- package/dist/ui/molecules/nav-menu/nav-menu.d.ts.map +1 -0
- package/dist/ui/molecules/nav-menu/nav-menu.js +58 -0
- package/dist/ui/molecules/nav-menu/nav-menu.js.map +1 -0
- package/dist/ui/molecules/segmented-control/index.d.ts +2 -0
- package/dist/ui/molecules/segmented-control/index.d.ts.map +1 -0
- package/dist/ui/molecules/segmented-control/index.js +3 -0
- package/dist/ui/molecules/segmented-control/index.js.map +1 -0
- package/dist/ui/molecules/segmented-control/segmented-control.d.ts +21 -0
- package/dist/ui/molecules/segmented-control/segmented-control.d.ts.map +1 -0
- package/dist/ui/molecules/segmented-control/segmented-control.js +55 -0
- package/dist/ui/molecules/segmented-control/segmented-control.js.map +1 -0
- package/dist/ui/molecules/segmented-nav/index.d.ts +2 -0
- package/dist/ui/molecules/segmented-nav/index.d.ts.map +1 -0
- package/dist/ui/molecules/segmented-nav/index.js +3 -0
- package/dist/ui/molecules/segmented-nav/index.js.map +1 -0
- package/dist/ui/molecules/segmented-nav/segment-classes.d.ts +9 -0
- package/dist/ui/molecules/segmented-nav/segment-classes.d.ts.map +1 -0
- package/dist/ui/molecules/segmented-nav/segment-classes.js +9 -0
- package/dist/ui/molecules/segmented-nav/segment-classes.js.map +1 -0
- package/dist/ui/molecules/segmented-nav/segmented-nav.d.ts +30 -0
- package/dist/ui/molecules/segmented-nav/segmented-nav.d.ts.map +1 -0
- package/dist/ui/molecules/segmented-nav/segmented-nav.js +46 -0
- package/dist/ui/molecules/segmented-nav/segmented-nav.js.map +1 -0
- package/dist/ui/molecules/split-button/index.d.ts +2 -0
- package/dist/ui/molecules/split-button/index.d.ts.map +1 -0
- package/dist/ui/molecules/split-button/index.js +3 -0
- package/dist/ui/molecules/split-button/index.js.map +1 -0
- package/dist/ui/molecules/split-button/split-button.d.ts +21 -0
- package/dist/ui/molecules/split-button/split-button.d.ts.map +1 -0
- package/dist/ui/molecules/split-button/split-button.js +35 -0
- package/dist/ui/molecules/split-button/split-button.js.map +1 -0
- package/dist/ui/molecules/split-view/index.d.ts +2 -0
- package/dist/ui/molecules/split-view/index.d.ts.map +1 -0
- package/dist/ui/molecules/split-view/index.js +3 -0
- package/dist/ui/molecules/split-view/index.js.map +1 -0
- package/dist/ui/molecules/split-view/split-view.d.ts +35 -0
- package/dist/ui/molecules/split-view/split-view.d.ts.map +1 -0
- package/dist/ui/molecules/split-view/split-view.js +76 -0
- package/dist/ui/molecules/split-view/split-view.js.map +1 -0
- package/dist/ui/utils/active-heading/active-heading.d.ts +16 -0
- package/dist/ui/utils/active-heading/active-heading.d.ts.map +1 -0
- package/dist/ui/utils/active-heading/active-heading.js +68 -0
- package/dist/ui/utils/active-heading/active-heading.js.map +1 -0
- package/dist/ui/utils/active-heading/index.d.ts +2 -0
- package/dist/ui/utils/active-heading/index.d.ts.map +1 -0
- package/dist/ui/utils/active-heading/index.js +3 -0
- package/dist/ui/utils/active-heading/index.js.map +1 -0
- package/dist/ui/utils/active-section/active-section.d.ts +11 -0
- package/dist/ui/utils/active-section/active-section.d.ts.map +1 -0
- package/dist/ui/utils/active-section/active-section.js +45 -0
- package/dist/ui/utils/active-section/active-section.js.map +1 -0
- package/dist/ui/utils/active-section/index.d.ts +2 -0
- package/dist/ui/utils/active-section/index.d.ts.map +1 -0
- package/dist/ui/utils/active-section/index.js +3 -0
- package/dist/ui/utils/active-section/index.js.map +1 -0
- package/dist/ui/utils/fold-script/fold-script.d.ts +20 -0
- package/dist/ui/utils/fold-script/fold-script.d.ts.map +1 -0
- package/dist/ui/utils/fold-script/fold-script.js +30 -0
- package/dist/ui/utils/fold-script/fold-script.js.map +1 -0
- package/dist/ui/utils/fold-script/index.d.ts +2 -0
- package/dist/ui/utils/fold-script/index.d.ts.map +1 -0
- package/dist/ui/utils/fold-script/index.js +3 -0
- package/dist/ui/utils/fold-script/index.js.map +1 -0
- package/dist/ui/utils/keep-section/index.d.ts +2 -0
- package/dist/ui/utils/keep-section/index.d.ts.map +1 -0
- package/dist/ui/utils/keep-section/index.js +3 -0
- package/dist/ui/utils/keep-section/index.js.map +1 -0
- package/dist/ui/utils/keep-section/keep-section.d.ts +8 -0
- package/dist/ui/utils/keep-section/keep-section.d.ts.map +1 -0
- package/dist/ui/utils/keep-section/keep-section.js +24 -0
- package/dist/ui/utils/keep-section/keep-section.js.map +1 -0
- package/dist/ui/utils/media-query/index.d.ts +2 -0
- package/dist/ui/utils/media-query/index.d.ts.map +1 -0
- package/dist/ui/utils/media-query/index.js +3 -0
- package/dist/ui/utils/media-query/index.js.map +1 -0
- package/dist/ui/utils/media-query/media-query.d.ts +7 -0
- package/dist/ui/utils/media-query/media-query.d.ts.map +1 -0
- package/dist/ui/utils/media-query/media-query.js +18 -0
- package/dist/ui/utils/media-query/media-query.js.map +1 -0
- package/package.json +5 -5
- package/dist/i18n/spec-support/catalogs.d.ts +0 -2
- package/dist/i18n/spec-support/catalogs.d.ts.map +0 -1
- package/dist/i18n/spec-support/catalogs.js +0 -142
- package/dist/i18n/spec-support/catalogs.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/segmented-control/index.ts"],"sourcesContent":["export * from './segmented-control.js';\n"],"names":[],"mappings":"AAAA,cAAc,yBAAyB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A choice within the page, drawn as `SegmentedNav` draws a choice between
|
|
3
|
+
* pages: one bordered track, the chosen segment filled.
|
|
4
|
+
*
|
|
5
|
+
* A radio group: one segment in the tab order, the arrow keys, Home and End
|
|
6
|
+
* moving the choice and the focus with it. It holds no state; the page keeps
|
|
7
|
+
* the value. Parts carry `data-slot` (`segmented-control`,
|
|
8
|
+
* `segmented-control-option`).
|
|
9
|
+
*/
|
|
10
|
+
export declare function SegmentedControl<Key extends string>({ label, options, value, onChange, className, }: {
|
|
11
|
+
/** The group's accessible name. */
|
|
12
|
+
label: string;
|
|
13
|
+
options: readonly {
|
|
14
|
+
readonly key: Key;
|
|
15
|
+
readonly label: string;
|
|
16
|
+
}[];
|
|
17
|
+
value: Key;
|
|
18
|
+
onChange: (key: Key) => void;
|
|
19
|
+
className?: string;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=segmented-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segmented-control.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/segmented-control/segmented-control.tsx"],"names":[],"mappings":"AAsBA;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,SAAS,MAAM,EAAE,EACnD,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClE,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BA+CA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../../utils/cn.js';
|
|
4
|
+
import { CURRENT, LIST, OTHER } from '../segmented-nav/segment-classes.js';
|
|
5
|
+
/** A segment as a button: the shared look, without a link's defaults. */ const BUTTON = 'cursor-pointer border-0 font-[inherit]';
|
|
6
|
+
/** The keys that move the choice, and where each moves it. */ const MOVES = {
|
|
7
|
+
ArrowRight: (index, count)=>(index + 1) % count,
|
|
8
|
+
ArrowDown: (index, count)=>(index + 1) % count,
|
|
9
|
+
ArrowLeft: (index, count)=>(index - 1 + count) % count,
|
|
10
|
+
ArrowUp: (index, count)=>(index - 1 + count) % count,
|
|
11
|
+
Home: ()=>0,
|
|
12
|
+
End: (_, count)=>count - 1
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A choice within the page, drawn as `SegmentedNav` draws a choice between
|
|
16
|
+
* pages: one bordered track, the chosen segment filled.
|
|
17
|
+
*
|
|
18
|
+
* A radio group: one segment in the tab order, the arrow keys, Home and End
|
|
19
|
+
* moving the choice and the focus with it. It holds no state; the page keeps
|
|
20
|
+
* the value. Parts carry `data-slot` (`segmented-control`,
|
|
21
|
+
* `segmented-control-option`).
|
|
22
|
+
*/ export function SegmentedControl({ label, options, value, onChange, className }) {
|
|
23
|
+
const chosen = Math.max(0, options.findIndex((option)=>option.key === value));
|
|
24
|
+
const move = (event)=>{
|
|
25
|
+
var _event_currentTarget_querySelectorAll_next;
|
|
26
|
+
const to = MOVES[event.key];
|
|
27
|
+
if (to === undefined) return;
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
const next = to(chosen, options.length);
|
|
30
|
+
(_event_currentTarget_querySelectorAll_next = event.currentTarget.querySelectorAll('[role="radio"]')[next]) == null ? void 0 : _event_currentTarget_querySelectorAll_next.focus();
|
|
31
|
+
onChange(options[next].key);
|
|
32
|
+
};
|
|
33
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
34
|
+
role: "radiogroup",
|
|
35
|
+
"aria-label": label,
|
|
36
|
+
"data-slot": "segmented-control",
|
|
37
|
+
onKeyDown: move,
|
|
38
|
+
className: cn(LIST, className),
|
|
39
|
+
children: options.map((option, index)=>{
|
|
40
|
+
const checked = index === chosen;
|
|
41
|
+
return /*#__PURE__*/ _jsx("button", {
|
|
42
|
+
type: "button",
|
|
43
|
+
role: "radio",
|
|
44
|
+
"aria-checked": checked,
|
|
45
|
+
tabIndex: checked ? 0 : -1,
|
|
46
|
+
"data-slot": "segmented-control-option",
|
|
47
|
+
className: cn(checked ? `${CURRENT} focus-ring` : `${OTHER} bg-transparent`, BUTTON),
|
|
48
|
+
onClick: ()=>onChange(option.key),
|
|
49
|
+
children: option.label
|
|
50
|
+
}, option.key);
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=segmented-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/segmented-control/segmented-control.tsx"],"sourcesContent":["'use client';\n\nimport type { KeyboardEvent } from 'react';\n\nimport { cn } from '../../utils/cn.js';\nimport { CURRENT, LIST, OTHER } from '../segmented-nav/segment-classes.js';\n\n/** A segment as a button: the shared look, without a link's defaults. */\nconst BUTTON = 'cursor-pointer border-0 font-[inherit]';\n\n/** The keys that move the choice, and where each moves it. */\nconst MOVES: Readonly<\n Record<string, (index: number, count: number) => number>\n> = {\n ArrowRight: (index, count) => (index + 1) % count,\n ArrowDown: (index, count) => (index + 1) % count,\n ArrowLeft: (index, count) => (index - 1 + count) % count,\n ArrowUp: (index, count) => (index - 1 + count) % count,\n Home: () => 0,\n End: (_, count) => count - 1,\n};\n\n/**\n * A choice within the page, drawn as `SegmentedNav` draws a choice between\n * pages: one bordered track, the chosen segment filled.\n *\n * A radio group: one segment in the tab order, the arrow keys, Home and End\n * moving the choice and the focus with it. It holds no state; the page keeps\n * the value. Parts carry `data-slot` (`segmented-control`,\n * `segmented-control-option`).\n */\nexport function SegmentedControl<Key extends string>({\n label,\n options,\n value,\n onChange,\n className,\n}: {\n /** The group's accessible name. */\n label: string;\n options: readonly { readonly key: Key; readonly label: string }[];\n value: Key;\n onChange: (key: Key) => void;\n className?: string;\n}) {\n const chosen = Math.max(\n 0,\n options.findIndex(option => option.key === value),\n );\n\n const move = (event: KeyboardEvent<HTMLDivElement>) => {\n const to = MOVES[event.key];\n if (to === undefined) return;\n event.preventDefault();\n const next = to(chosen, options.length);\n event.currentTarget\n .querySelectorAll<HTMLElement>('[role=\"radio\"]')\n [next]?.focus();\n onChange((options[next] as (typeof options)[number]).key);\n };\n\n return (\n <div\n role=\"radiogroup\"\n aria-label={label}\n data-slot=\"segmented-control\"\n onKeyDown={move}\n className={cn(LIST, className)}\n >\n {options.map((option, index) => {\n const checked = index === chosen;\n return (\n <button\n key={option.key}\n type=\"button\"\n role=\"radio\"\n aria-checked={checked}\n tabIndex={checked ? 0 : -1}\n data-slot=\"segmented-control-option\"\n className={cn(\n checked ? `${CURRENT} focus-ring` : `${OTHER} bg-transparent`,\n BUTTON,\n )}\n onClick={() => onChange(option.key)}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"names":["cn","CURRENT","LIST","OTHER","BUTTON","MOVES","ArrowRight","index","count","ArrowDown","ArrowLeft","ArrowUp","Home","End","_","SegmentedControl","label","options","value","onChange","className","chosen","Math","max","findIndex","option","key","move","event","to","undefined","preventDefault","next","length","currentTarget","querySelectorAll","focus","div","role","aria-label","data-slot","onKeyDown","map","checked","button","type","aria-checked","tabIndex","onClick"],"mappings":"AAAA;;AAIA,SAASA,EAAE,QAAQ,oBAAoB;AACvC,SAASC,OAAO,EAAEC,IAAI,EAAEC,KAAK,QAAQ,sCAAsC;AAE3E,uEAAuE,GACvE,MAAMC,SAAS;AAEf,4DAA4D,GAC5D,MAAMC,QAEF;IACFC,YAAY,CAACC,OAAOC,QAAU,AAACD,CAAAA,QAAQ,CAAA,IAAKC;IAC5CC,WAAW,CAACF,OAAOC,QAAU,AAACD,CAAAA,QAAQ,CAAA,IAAKC;IAC3CE,WAAW,CAACH,OAAOC,QAAU,AAACD,CAAAA,QAAQ,IAAIC,KAAI,IAAKA;IACnDG,SAAS,CAACJ,OAAOC,QAAU,AAACD,CAAAA,QAAQ,IAAIC,KAAI,IAAKA;IACjDI,MAAM,IAAM;IACZC,KAAK,CAACC,GAAGN,QAAUA,QAAQ;AAC7B;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASO,iBAAqC,EACnDC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,QAAQ,EACRC,SAAS,EAQV;IACC,MAAMC,SAASC,KAAKC,GAAG,CACrB,GACAN,QAAQO,SAAS,CAACC,CAAAA,SAAUA,OAAOC,GAAG,KAAKR;IAG7C,MAAMS,OAAO,CAACC;YAKZA;QAJA,MAAMC,KAAKxB,KAAK,CAACuB,MAAMF,GAAG,CAAC;QAC3B,IAAIG,OAAOC,WAAW;QACtBF,MAAMG,cAAc;QACpB,MAAMC,OAAOH,GAAGR,QAAQJ,QAAQgB,MAAM;SACtCL,6CAAAA,MAAMM,aAAa,CAChBC,gBAAgB,CAAc,iBAC/B,CAACH,KAAK,qBAFRJ,2CAEUQ,KAAK;QACfjB,SAAS,AAACF,OAAO,CAACe,KAAK,CAA8BN,GAAG;IAC1D;IAEA,qBACE,KAACW;QACCC,MAAK;QACLC,cAAYvB;QACZwB,aAAU;QACVC,WAAWd;QACXP,WAAWpB,GAAGE,MAAMkB;kBAEnBH,QAAQyB,GAAG,CAAC,CAACjB,QAAQlB;YACpB,MAAMoC,UAAUpC,UAAUc;YAC1B,qBACE,KAACuB;gBAECC,MAAK;gBACLP,MAAK;gBACLQ,gBAAcH;gBACdI,UAAUJ,UAAU,IAAI,CAAC;gBACzBH,aAAU;gBACVpB,WAAWpB,GACT2C,UAAU,GAAG1C,QAAQ,WAAW,CAAC,GAAG,GAAGE,MAAM,eAAe,CAAC,EAC7DC;gBAEF4C,SAAS,IAAM7B,SAASM,OAAOC,GAAG;0BAEjCD,OAAOT,KAAK;eAZRS,OAAOC,GAAG;QAerB;;AAGN"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/segmented-nav/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/segmented-nav/index.ts"],"sourcesContent":["export * from './segmented-nav.js';\n"],"names":[],"mappings":"AAAA,cAAc,qBAAqB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The segmented look, shared by `SegmentedNav` (links) and `SegmentedControl`
|
|
3
|
+
* (a choice in the page): one bordered track, the chosen segment filled.
|
|
4
|
+
*/
|
|
5
|
+
/** The joined segments; scrolls sideways rather than wrapping. */
|
|
6
|
+
export declare const LIST = "m-0 flex w-max max-w-full list-none overflow-x-auto rounded-md border border-border p-[0.1875rem] [scrollbar-width:none]";
|
|
7
|
+
export declare const OTHER = "block rounded-[calc(var(--radius-md,0.375rem)-0.125rem)] px-xs py-[0.3125rem] text-step-sm whitespace-nowrap no-underline transition-colors duration-(--duration-fast,150ms) motion-reduce:transition-none focus-ring text-content hover:bg-[color-mix(in_srgb,var(--color-content)_6%,transparent)] hover:text-primary";
|
|
8
|
+
export declare const CURRENT = "block rounded-[calc(var(--radius-md,0.375rem)-0.125rem)] px-xs py-[0.3125rem] text-step-sm whitespace-nowrap no-underline transition-colors duration-(--duration-fast,150ms) motion-reduce:transition-none bg-primary font-medium text-primary-content";
|
|
9
|
+
//# sourceMappingURL=segment-classes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-classes.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/segmented-nav/segment-classes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,kEAAkE;AAClE,eAAO,MAAM,IAAI,6HAC2G,CAAC;AAK7H,eAAO,MAAM,KAAK,4TAA4H,CAAC;AAE/I,eAAO,MAAM,OAAO,2PAA2D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The segmented look, shared by `SegmentedNav` (links) and `SegmentedControl`
|
|
3
|
+
* (a choice in the page): one bordered track, the chosen segment filled.
|
|
4
|
+
*/ /** The joined segments; scrolls sideways rather than wrapping. */ export const LIST = 'm-0 flex w-max max-w-full list-none overflow-x-auto rounded-md border border-border p-[0.1875rem] [scrollbar-width:none]';
|
|
5
|
+
const SEGMENT = 'block rounded-[calc(var(--radius-md,0.375rem)-0.125rem)] px-xs py-[0.3125rem] text-step-sm whitespace-nowrap no-underline transition-colors duration-(--duration-fast,150ms) motion-reduce:transition-none';
|
|
6
|
+
export const OTHER = `${SEGMENT} focus-ring text-content hover:bg-[color-mix(in_srgb,var(--color-content)_6%,transparent)] hover:text-primary`;
|
|
7
|
+
export const CURRENT = `${SEGMENT} bg-primary font-medium text-primary-content`;
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=segment-classes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/segmented-nav/segment-classes.ts"],"sourcesContent":["/**\n * The segmented look, shared by `SegmentedNav` (links) and `SegmentedControl`\n * (a choice in the page): one bordered track, the chosen segment filled.\n */\n/** The joined segments; scrolls sideways rather than wrapping. */\nexport const LIST =\n 'm-0 flex w-max max-w-full list-none overflow-x-auto rounded-md border border-border p-[0.1875rem] [scrollbar-width:none]';\n\nconst SEGMENT =\n 'block rounded-[calc(var(--radius-md,0.375rem)-0.125rem)] px-xs py-[0.3125rem] text-step-sm whitespace-nowrap no-underline transition-colors duration-(--duration-fast,150ms) motion-reduce:transition-none';\n\nexport const OTHER = `${SEGMENT} focus-ring text-content hover:bg-[color-mix(in_srgb,var(--color-content)_6%,transparent)] hover:text-primary`;\n\nexport const CURRENT = `${SEGMENT} bg-primary font-medium text-primary-content`;\n"],"names":["LIST","SEGMENT","OTHER","CURRENT"],"mappings":"AAAA;;;CAGC,GACD,gEAAgE,GAChE,OAAO,MAAMA,OACX,2HAA2H;AAE7H,MAAMC,UACJ;AAEF,OAAO,MAAMC,QAAQ,GAAGD,QAAQ,6GAA6G,CAAC,CAAC;AAE/I,OAAO,MAAME,UAAU,GAAGF,QAAQ,4CAA4C,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
/** One segment: a page of its own, the current one marked. */
|
|
3
|
+
export interface SegmentedNavItem {
|
|
4
|
+
readonly key: string;
|
|
5
|
+
readonly label: ReactNode;
|
|
6
|
+
readonly href: string;
|
|
7
|
+
readonly current: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** What renders a segment that leads elsewhere: an `<a>`, or a router's link. */
|
|
10
|
+
export type SegmentedNavLink = ComponentType<{
|
|
11
|
+
href: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* A choice between pages, drawn as one segmented control: each segment is a
|
|
17
|
+
* link, the current page's is a marked span. A visible label names the
|
|
18
|
+
* choice; the `<nav>` carries it for assistive technology.
|
|
19
|
+
*
|
|
20
|
+
* No hooks, so a server component renders it, and every segment works with
|
|
21
|
+
* scripting off. Its parts carry `data-slot` (`segmented-nav`,
|
|
22
|
+
* `segmented-nav-label`, `segmented-nav-list`, `segmented-nav-item`).
|
|
23
|
+
*/
|
|
24
|
+
export declare function SegmentedNav({ label, items, link: Link, className, }: {
|
|
25
|
+
label: string;
|
|
26
|
+
items: readonly SegmentedNavItem[];
|
|
27
|
+
link?: SegmentedNavLink;
|
|
28
|
+
className?: string;
|
|
29
|
+
}): import("react").JSX.Element;
|
|
30
|
+
//# sourceMappingURL=segmented-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segmented-nav.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/segmented-nav/segmented-nav.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItD,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC,CAAC;AAIH;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,IAAI,EAAE,IAAa,EACnB,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BA+BA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { CURRENT, LIST, OTHER } from './segment-classes.js';
|
|
4
|
+
const ANCHOR = (props)=>/*#__PURE__*/ _jsx("a", _extends({}, props));
|
|
5
|
+
/**
|
|
6
|
+
* A choice between pages, drawn as one segmented control: each segment is a
|
|
7
|
+
* link, the current page's is a marked span. A visible label names the
|
|
8
|
+
* choice; the `<nav>` carries it for assistive technology.
|
|
9
|
+
*
|
|
10
|
+
* No hooks, so a server component renders it, and every segment works with
|
|
11
|
+
* scripting off. Its parts carry `data-slot` (`segmented-nav`,
|
|
12
|
+
* `segmented-nav-label`, `segmented-nav-list`, `segmented-nav-item`).
|
|
13
|
+
*/ export function SegmentedNav({ label, items, link: Link = ANCHOR, className }) {
|
|
14
|
+
return /*#__PURE__*/ _jsxs("nav", {
|
|
15
|
+
"data-slot": "segmented-nav",
|
|
16
|
+
"aria-label": label,
|
|
17
|
+
className: className,
|
|
18
|
+
children: [
|
|
19
|
+
/*#__PURE__*/ _jsx("span", {
|
|
20
|
+
"data-slot": "segmented-nav-label",
|
|
21
|
+
"aria-hidden": "true",
|
|
22
|
+
className: "text-step-sm text-content-muted",
|
|
23
|
+
children: label
|
|
24
|
+
}),
|
|
25
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
26
|
+
"data-slot": "segmented-nav-list",
|
|
27
|
+
className: LIST,
|
|
28
|
+
children: items.map((item)=>/*#__PURE__*/ _jsx("li", {
|
|
29
|
+
"data-slot": "segmented-nav-item",
|
|
30
|
+
className: "flex-none",
|
|
31
|
+
children: item.current ? /*#__PURE__*/ _jsx("span", {
|
|
32
|
+
"aria-current": "page",
|
|
33
|
+
className: CURRENT,
|
|
34
|
+
children: item.label
|
|
35
|
+
}) : /*#__PURE__*/ _jsx(Link, {
|
|
36
|
+
href: item.href,
|
|
37
|
+
className: OTHER,
|
|
38
|
+
children: item.label
|
|
39
|
+
})
|
|
40
|
+
}, item.key))
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=segmented-nav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/segmented-nav/segmented-nav.tsx"],"sourcesContent":["import type { ComponentType, ReactNode } from 'react';\n\nimport { CURRENT, LIST, OTHER } from './segment-classes.js';\n\n/** One segment: a page of its own, the current one marked. */\nexport interface SegmentedNavItem {\n readonly key: string;\n readonly label: ReactNode;\n readonly href: string;\n readonly current: boolean;\n}\n\n/** What renders a segment that leads elsewhere: an `<a>`, or a router's link. */\nexport type SegmentedNavLink = ComponentType<{\n href: string;\n className?: string;\n children: ReactNode;\n}>;\n\nconst ANCHOR: SegmentedNavLink = props => <a {...props} />;\n\n/**\n * A choice between pages, drawn as one segmented control: each segment is a\n * link, the current page's is a marked span. A visible label names the\n * choice; the `<nav>` carries it for assistive technology.\n *\n * No hooks, so a server component renders it, and every segment works with\n * scripting off. Its parts carry `data-slot` (`segmented-nav`,\n * `segmented-nav-label`, `segmented-nav-list`, `segmented-nav-item`).\n */\nexport function SegmentedNav({\n label,\n items,\n link: Link = ANCHOR,\n className,\n}: {\n label: string;\n items: readonly SegmentedNavItem[];\n link?: SegmentedNavLink;\n className?: string;\n}) {\n return (\n <nav data-slot=\"segmented-nav\" aria-label={label} className={className}>\n <span\n data-slot=\"segmented-nav-label\"\n aria-hidden=\"true\"\n className=\"text-step-sm text-content-muted\"\n >\n {label}\n </span>\n <ul data-slot=\"segmented-nav-list\" className={LIST}>\n {items.map(item => (\n <li\n key={item.key}\n data-slot=\"segmented-nav-item\"\n className=\"flex-none\"\n >\n {item.current ? (\n <span aria-current=\"page\" className={CURRENT}>\n {item.label}\n </span>\n ) : (\n <Link href={item.href} className={OTHER}>\n {item.label}\n </Link>\n )}\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n"],"names":["CURRENT","LIST","OTHER","ANCHOR","props","a","SegmentedNav","label","items","link","Link","className","nav","data-slot","aria-label","span","aria-hidden","ul","map","item","li","current","aria-current","href","key"],"mappings":";;AAEA,SAASA,OAAO,EAAEC,IAAI,EAAEC,KAAK,QAAQ,uBAAuB;AAiB5D,MAAMC,SAA2BC,CAAAA,sBAAS,KAACC,kBAAMD;AAEjD;;;;;;;;CAQC,GACD,OAAO,SAASE,aAAa,EAC3BC,KAAK,EACLC,KAAK,EACLC,MAAMC,OAAOP,MAAM,EACnBQ,SAAS,EAMV;IACC,qBACE,MAACC;QAAIC,aAAU;QAAgBC,cAAYP;QAAOI,WAAWA;;0BAC3D,KAACI;gBACCF,aAAU;gBACVG,eAAY;gBACZL,WAAU;0BAETJ;;0BAEH,KAACU;gBAAGJ,aAAU;gBAAqBF,WAAWV;0BAC3CO,MAAMU,GAAG,CAACC,CAAAA,qBACT,KAACC;wBAECP,aAAU;wBACVF,WAAU;kCAETQ,KAAKE,OAAO,iBACX,KAACN;4BAAKO,gBAAa;4BAAOX,WAAWX;sCAClCmB,KAAKZ,KAAK;2CAGb,KAACG;4BAAKa,MAAMJ,KAAKI,IAAI;4BAAEZ,WAAWT;sCAC/BiB,KAAKZ,KAAK;;uBAVVY,KAAKK,GAAG;;;;AAkBzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/split-button/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/split-button/index.ts"],"sourcesContent":["export * from './split-button.js';\n"],"names":[],"mappings":"AAAA,cAAc,oBAAoB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* One main action, and a menu of the related ones beside it: `[Download │ ▾]`.
|
|
4
|
+
*
|
|
5
|
+
* The caller renders the main action — a link or a button, styled as the
|
|
6
|
+
* primary button — so it stays in the static HTML and keeps its own
|
|
7
|
+
* attributes; without `children` it stands alone, as before scripting runs.
|
|
8
|
+
* The menu is a `NavMenu`, so it opens with scripting off and the page's own
|
|
9
|
+
* menu handling closes it. Parts carry `data-slot` (`split-button`, and the
|
|
10
|
+
* menu's own).
|
|
11
|
+
*/
|
|
12
|
+
export declare function SplitButton({ primary, menuLabel, children, className, }: {
|
|
13
|
+
/** The main action, its corners squared on the side the menu joins. */
|
|
14
|
+
primary: ReactNode;
|
|
15
|
+
/** The accessible name of the ▾ trigger. */
|
|
16
|
+
menuLabel: string;
|
|
17
|
+
/** The menu's entries; none, and the main action stands alone. */
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
className?: string;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=split-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-button.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/split-button/split-button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,SAAS,EACT,QAAQ,EACR,SAAS,GACV,EAAE;IACD,uEAAuE;IACvE,OAAO,EAAE,SAAS,CAAC;IACnB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAuBA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { button } from '../../atoms/button/button-recipe.js';
|
|
3
|
+
import { cn } from '../../utils/cn.js';
|
|
4
|
+
import { NavMenu } from '../nav-menu/nav-menu.js';
|
|
5
|
+
/** The ▾ segment: the primary button's look, joined to the action before it. */ const TRIGGER = cn(button({
|
|
6
|
+
variant: 'primary',
|
|
7
|
+
size: 'sm'
|
|
8
|
+
}), 'h-auto cursor-pointer list-none self-stretch rounded-l-none border-l border-l-[color-mix(in_srgb,var(--color-primary-content)_25%,transparent)] px-2xs select-none [&_[data-slot=nav-menu-chevron]]:text-current [&::-webkit-details-marker]:hidden');
|
|
9
|
+
/**
|
|
10
|
+
* One main action, and a menu of the related ones beside it: `[Download │ ▾]`.
|
|
11
|
+
*
|
|
12
|
+
* The caller renders the main action — a link or a button, styled as the
|
|
13
|
+
* primary button — so it stays in the static HTML and keeps its own
|
|
14
|
+
* attributes; without `children` it stands alone, as before scripting runs.
|
|
15
|
+
* The menu is a `NavMenu`, so it opens with scripting off and the page's own
|
|
16
|
+
* menu handling closes it. Parts carry `data-slot` (`split-button`, and the
|
|
17
|
+
* menu's own).
|
|
18
|
+
*/ export function SplitButton({ primary, menuLabel, children, className }) {
|
|
19
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
20
|
+
"data-slot": "split-button",
|
|
21
|
+
className: cn('inline-flex items-stretch', children !== undefined && '[&>:first-child]:rounded-r-none', className),
|
|
22
|
+
children: [
|
|
23
|
+
primary,
|
|
24
|
+
children !== undefined && /*#__PURE__*/ _jsx(NavMenu, {
|
|
25
|
+
label: menuLabel,
|
|
26
|
+
icon: null,
|
|
27
|
+
className: "flex",
|
|
28
|
+
triggerClassName: TRIGGER,
|
|
29
|
+
children: children
|
|
30
|
+
})
|
|
31
|
+
]
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=split-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/split-button/split-button.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { button } from '../../atoms/button/button-recipe.js';\nimport { cn } from '../../utils/cn.js';\nimport { NavMenu } from '../nav-menu/nav-menu.js';\n\n/** The ▾ segment: the primary button's look, joined to the action before it. */\nconst TRIGGER = cn(\n button({ variant: 'primary', size: 'sm' }),\n 'h-auto cursor-pointer list-none self-stretch rounded-l-none border-l border-l-[color-mix(in_srgb,var(--color-primary-content)_25%,transparent)] px-2xs select-none [&_[data-slot=nav-menu-chevron]]:text-current [&::-webkit-details-marker]:hidden',\n);\n\n/**\n * One main action, and a menu of the related ones beside it: `[Download │ ▾]`.\n *\n * The caller renders the main action — a link or a button, styled as the\n * primary button — so it stays in the static HTML and keeps its own\n * attributes; without `children` it stands alone, as before scripting runs.\n * The menu is a `NavMenu`, so it opens with scripting off and the page's own\n * menu handling closes it. Parts carry `data-slot` (`split-button`, and the\n * menu's own).\n */\nexport function SplitButton({\n primary,\n menuLabel,\n children,\n className,\n}: {\n /** The main action, its corners squared on the side the menu joins. */\n primary: ReactNode;\n /** The accessible name of the ▾ trigger. */\n menuLabel: string;\n /** The menu's entries; none, and the main action stands alone. */\n children?: ReactNode;\n className?: string;\n}) {\n return (\n <div\n data-slot=\"split-button\"\n className={cn(\n 'inline-flex items-stretch',\n children !== undefined && '[&>:first-child]:rounded-r-none',\n className,\n )}\n >\n {primary}\n {children !== undefined && (\n <NavMenu\n label={menuLabel}\n icon={null}\n className=\"flex\"\n triggerClassName={TRIGGER}\n >\n {children}\n </NavMenu>\n )}\n </div>\n );\n}\n"],"names":["button","cn","NavMenu","TRIGGER","variant","size","SplitButton","primary","menuLabel","children","className","div","data-slot","undefined","label","icon","triggerClassName"],"mappings":";AAEA,SAASA,MAAM,QAAQ,sCAAsC;AAC7D,SAASC,EAAE,QAAQ,oBAAoB;AACvC,SAASC,OAAO,QAAQ,0BAA0B;AAElD,8EAA8E,GAC9E,MAAMC,UAAUF,GACdD,OAAO;IAAEI,SAAS;IAAWC,MAAM;AAAK,IACxC;AAGF;;;;;;;;;CASC,GACD,OAAO,SAASC,YAAY,EAC1BC,OAAO,EACPC,SAAS,EACTC,QAAQ,EACRC,SAAS,EASV;IACC,qBACE,MAACC;QACCC,aAAU;QACVF,WAAWT,GACT,6BACAQ,aAAaI,aAAa,mCAC1BH;;YAGDH;YACAE,aAAaI,2BACZ,KAACX;gBACCY,OAAON;gBACPO,MAAM;gBACNL,WAAU;gBACVM,kBAAkBb;0BAEjBM;;;;AAKX"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/split-view/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/split-view/index.ts"],"sourcesContent":["export * from './split-view.js';\n"],"names":[],"mappings":"AAAA,cAAc,kBAAkB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface SplitViewItem {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
/** What the list shows of the item: its number and title, say. */
|
|
5
|
+
readonly head: ReactNode;
|
|
6
|
+
/** What the pane shows once the item is chosen. */
|
|
7
|
+
readonly detail: ReactNode;
|
|
8
|
+
/** Where the item lives on its own: followed without scripting. */
|
|
9
|
+
readonly href: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A list beside a reading pane: the chosen item's detail shows next to the
|
|
13
|
+
* list on a wide screen, and under its own row on a narrow one, where the
|
|
14
|
+
* list reads as an accordion.
|
|
15
|
+
*
|
|
16
|
+
* One markup for both: the chosen row carries its detail. On a wide screen
|
|
17
|
+
* the list is a column of fixed height that scrolls, and the detail is placed
|
|
18
|
+
* against the whole view, so the list's overflow neither clips nor scrolls it.
|
|
19
|
+
*
|
|
20
|
+
* Each row is a link to the item's own page, which is what a visitor without
|
|
21
|
+
* scripting follows. With it, a plain click chooses instead, and ↑, ↓, Home
|
|
22
|
+
* and End move the choice, focus following it (one row in the tab order).
|
|
23
|
+
* Parts carry `data-slot` (`split-view`, `split-list`, `split-row`,
|
|
24
|
+
* `split-trigger`, `split-detail`) for a page to restyle.
|
|
25
|
+
*/
|
|
26
|
+
export declare function SplitView({ label, items, selected, onSelect, className, }: {
|
|
27
|
+
/** The list's accessible name. */
|
|
28
|
+
label: string;
|
|
29
|
+
items: readonly SplitViewItem[];
|
|
30
|
+
/** The chosen item's id; an unknown one chooses nothing. */
|
|
31
|
+
selected: string | undefined;
|
|
32
|
+
onSelect: (id: string) => void;
|
|
33
|
+
className?: string;
|
|
34
|
+
}): import("react").JSX.Element;
|
|
35
|
+
//# sourceMappingURL=split-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-view.d.ts","sourceRoot":"","sources":["../../../../src/ui/molecules/split-view/split-view.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,GACV,EAAE;IACD,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BA8DA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../../utils/cn.js';
|
|
4
|
+
/** The keys that move the choice, and where each moves it. */ const MOVES = {
|
|
5
|
+
ArrowDown: (index, count)=>Math.min(index + 1, count - 1),
|
|
6
|
+
ArrowUp: (index)=>Math.max(index - 1, 0),
|
|
7
|
+
Home: ()=>0,
|
|
8
|
+
End: (_, count)=>count - 1
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A list beside a reading pane: the chosen item's detail shows next to the
|
|
12
|
+
* list on a wide screen, and under its own row on a narrow one, where the
|
|
13
|
+
* list reads as an accordion.
|
|
14
|
+
*
|
|
15
|
+
* One markup for both: the chosen row carries its detail. On a wide screen
|
|
16
|
+
* the list is a column of fixed height that scrolls, and the detail is placed
|
|
17
|
+
* against the whole view, so the list's overflow neither clips nor scrolls it.
|
|
18
|
+
*
|
|
19
|
+
* Each row is a link to the item's own page, which is what a visitor without
|
|
20
|
+
* scripting follows. With it, a plain click chooses instead, and ↑, ↓, Home
|
|
21
|
+
* and End move the choice, focus following it (one row in the tab order).
|
|
22
|
+
* Parts carry `data-slot` (`split-view`, `split-list`, `split-row`,
|
|
23
|
+
* `split-trigger`, `split-detail`) for a page to restyle.
|
|
24
|
+
*/ export function SplitView({ label, items, selected, onSelect, className }) {
|
|
25
|
+
const index = items.findIndex((item)=>item.id === selected);
|
|
26
|
+
const focusable = index === -1 ? 0 : index;
|
|
27
|
+
const choose = (event, id)=>{
|
|
28
|
+
// A new tab or window is the link's own business.
|
|
29
|
+
if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey) return;
|
|
30
|
+
event.preventDefault();
|
|
31
|
+
onSelect(id);
|
|
32
|
+
};
|
|
33
|
+
const move = (event)=>{
|
|
34
|
+
var _event_currentTarget_querySelectorAll_next;
|
|
35
|
+
const to = MOVES[event.key];
|
|
36
|
+
if (to === undefined) return;
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
const next = to(focusable, items.length);
|
|
39
|
+
(_event_currentTarget_querySelectorAll_next = event.currentTarget.querySelectorAll('[data-slot="split-trigger"]')[next]) == null ? void 0 : _event_currentTarget_querySelectorAll_next.focus();
|
|
40
|
+
onSelect(items[next].id);
|
|
41
|
+
};
|
|
42
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
43
|
+
"data-slot": "split-view",
|
|
44
|
+
className: cn('lg:min-h-[28rem] relative', className),
|
|
45
|
+
children: /*#__PURE__*/ _jsx("ol", {
|
|
46
|
+
"data-slot": "split-list",
|
|
47
|
+
"aria-label": label,
|
|
48
|
+
onKeyDown: move,
|
|
49
|
+
className: "m-0 p-0 lg:max-h-[28rem] lg:w-[40%] lg:overflow-y-auto list-none",
|
|
50
|
+
children: items.map((item, at)=>{
|
|
51
|
+
const chosen = at === index;
|
|
52
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
53
|
+
"data-slot": "split-row",
|
|
54
|
+
children: [
|
|
55
|
+
/*#__PURE__*/ _jsx("a", {
|
|
56
|
+
href: item.href,
|
|
57
|
+
"data-slot": "split-trigger",
|
|
58
|
+
"aria-current": chosen ? 'true' : undefined,
|
|
59
|
+
tabIndex: at === focusable ? 0 : -1,
|
|
60
|
+
onClick: (event)=>choose(event, item.id),
|
|
61
|
+
className: "block rounded-md px-xs py-2xs text-inherit no-underline focus-ring hover:bg-[color-mix(in_srgb,var(--color-content)_6%,transparent)] aria-[current]:bg-[color-mix(in_srgb,var(--color-primary)_14%,transparent)]",
|
|
62
|
+
children: item.head
|
|
63
|
+
}),
|
|
64
|
+
chosen && /*#__PURE__*/ _jsx("div", {
|
|
65
|
+
"data-slot": "split-detail",
|
|
66
|
+
className: "lg:absolute lg:top-0 lg:right-0 lg:max-h-[28rem] lg:w-[58%] lg:overflow-y-auto lg:p-0 px-xs py-s",
|
|
67
|
+
children: item.detail
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
}, item.id);
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=split-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/molecules/split-view/split-view.tsx"],"sourcesContent":["'use client';\n\nimport type { KeyboardEvent, MouseEvent, ReactNode } from 'react';\n\nimport { cn } from '../../utils/cn.js';\n\nexport interface SplitViewItem {\n readonly id: string;\n /** What the list shows of the item: its number and title, say. */\n readonly head: ReactNode;\n /** What the pane shows once the item is chosen. */\n readonly detail: ReactNode;\n /** Where the item lives on its own: followed without scripting. */\n readonly href: string;\n}\n\n/** The keys that move the choice, and where each moves it. */\nconst MOVES: Readonly<\n Record<string, (index: number, count: number) => number>\n> = {\n ArrowDown: (index, count) => Math.min(index + 1, count - 1),\n ArrowUp: index => Math.max(index - 1, 0),\n Home: () => 0,\n End: (_, count) => count - 1,\n};\n\n/**\n * A list beside a reading pane: the chosen item's detail shows next to the\n * list on a wide screen, and under its own row on a narrow one, where the\n * list reads as an accordion.\n *\n * One markup for both: the chosen row carries its detail. On a wide screen\n * the list is a column of fixed height that scrolls, and the detail is placed\n * against the whole view, so the list's overflow neither clips nor scrolls it.\n *\n * Each row is a link to the item's own page, which is what a visitor without\n * scripting follows. With it, a plain click chooses instead, and ↑, ↓, Home\n * and End move the choice, focus following it (one row in the tab order).\n * Parts carry `data-slot` (`split-view`, `split-list`, `split-row`,\n * `split-trigger`, `split-detail`) for a page to restyle.\n */\nexport function SplitView({\n label,\n items,\n selected,\n onSelect,\n className,\n}: {\n /** The list's accessible name. */\n label: string;\n items: readonly SplitViewItem[];\n /** The chosen item's id; an unknown one chooses nothing. */\n selected: string | undefined;\n onSelect: (id: string) => void;\n className?: string;\n}) {\n const index = items.findIndex(item => item.id === selected);\n const focusable = index === -1 ? 0 : index;\n\n const choose = (event: MouseEvent, id: string) => {\n // A new tab or window is the link's own business.\n if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey)\n return;\n event.preventDefault();\n onSelect(id);\n };\n\n const move = (event: KeyboardEvent<HTMLOListElement>) => {\n const to = MOVES[event.key];\n if (to === undefined) return;\n event.preventDefault();\n const next = to(focusable, items.length);\n event.currentTarget\n .querySelectorAll<HTMLElement>('[data-slot=\"split-trigger\"]')\n [next]?.focus();\n onSelect((items[next] as SplitViewItem).id);\n };\n\n return (\n <div\n data-slot=\"split-view\"\n className={cn('lg:min-h-[28rem] relative', className)}\n >\n <ol\n data-slot=\"split-list\"\n aria-label={label}\n onKeyDown={move}\n className=\"m-0 p-0 lg:max-h-[28rem] lg:w-[40%] lg:overflow-y-auto list-none\"\n >\n {items.map((item, at) => {\n const chosen = at === index;\n return (\n <li key={item.id} data-slot=\"split-row\">\n <a\n href={item.href}\n data-slot=\"split-trigger\"\n aria-current={chosen ? 'true' : undefined}\n tabIndex={at === focusable ? 0 : -1}\n onClick={event => choose(event, item.id)}\n className=\"block rounded-md px-xs py-2xs text-inherit no-underline focus-ring hover:bg-[color-mix(in_srgb,var(--color-content)_6%,transparent)] aria-[current]:bg-[color-mix(in_srgb,var(--color-primary)_14%,transparent)]\"\n >\n {item.head}\n </a>\n {chosen && (\n <div\n data-slot=\"split-detail\"\n className=\"lg:absolute lg:top-0 lg:right-0 lg:max-h-[28rem] lg:w-[58%] lg:overflow-y-auto lg:p-0 px-xs py-s\"\n >\n {item.detail}\n </div>\n )}\n </li>\n );\n })}\n </ol>\n </div>\n );\n}\n"],"names":["cn","MOVES","ArrowDown","index","count","Math","min","ArrowUp","max","Home","End","_","SplitView","label","items","selected","onSelect","className","findIndex","item","id","focusable","choose","event","button","metaKey","ctrlKey","shiftKey","preventDefault","move","to","key","undefined","next","length","currentTarget","querySelectorAll","focus","div","data-slot","ol","aria-label","onKeyDown","map","at","chosen","li","a","href","aria-current","tabIndex","onClick","head","detail"],"mappings":"AAAA;;AAIA,SAASA,EAAE,QAAQ,oBAAoB;AAYvC,4DAA4D,GAC5D,MAAMC,QAEF;IACFC,WAAW,CAACC,OAAOC,QAAUC,KAAKC,GAAG,CAACH,QAAQ,GAAGC,QAAQ;IACzDG,SAASJ,CAAAA,QAASE,KAAKG,GAAG,CAACL,QAAQ,GAAG;IACtCM,MAAM,IAAM;IACZC,KAAK,CAACC,GAAGP,QAAUA,QAAQ;AAC7B;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASQ,UAAU,EACxBC,KAAK,EACLC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,SAAS,EASV;IACC,MAAMd,QAAQW,MAAMI,SAAS,CAACC,CAAAA,OAAQA,KAAKC,EAAE,KAAKL;IAClD,MAAMM,YAAYlB,UAAU,CAAC,IAAI,IAAIA;IAErC,MAAMmB,SAAS,CAACC,OAAmBH;QACjC,kDAAkD;QAClD,IAAIG,MAAMC,MAAM,KAAK,KAAKD,MAAME,OAAO,IAAIF,MAAMG,OAAO,IAAIH,MAAMI,QAAQ,EACxE;QACFJ,MAAMK,cAAc;QACpBZ,SAASI;IACX;IAEA,MAAMS,OAAO,CAACN;YAKZA;QAJA,MAAMO,KAAK7B,KAAK,CAACsB,MAAMQ,GAAG,CAAC;QAC3B,IAAID,OAAOE,WAAW;QACtBT,MAAMK,cAAc;QACpB,MAAMK,OAAOH,GAAGT,WAAWP,MAAMoB,MAAM;SACvCX,6CAAAA,MAAMY,aAAa,CAChBC,gBAAgB,CAAc,8BAC/B,CAACH,KAAK,qBAFRV,2CAEUc,KAAK;QACfrB,SAAS,AAACF,KAAK,CAACmB,KAAK,CAAmBb,EAAE;IAC5C;IAEA,qBACE,KAACkB;QACCC,aAAU;QACVtB,WAAWjB,GAAG,6BAA6BiB;kBAE3C,cAAA,KAACuB;YACCD,aAAU;YACVE,cAAY5B;YACZ6B,WAAWb;YACXZ,WAAU;sBAETH,MAAM6B,GAAG,CAAC,CAACxB,MAAMyB;gBAChB,MAAMC,SAASD,OAAOzC;gBACtB,qBACE,MAAC2C;oBAAiBP,aAAU;;sCAC1B,KAACQ;4BACCC,MAAM7B,KAAK6B,IAAI;4BACfT,aAAU;4BACVU,gBAAcJ,SAAS,SAASb;4BAChCkB,UAAUN,OAAOvB,YAAY,IAAI,CAAC;4BAClC8B,SAAS5B,CAAAA,QAASD,OAAOC,OAAOJ,KAAKC,EAAE;4BACvCH,WAAU;sCAETE,KAAKiC,IAAI;;wBAEXP,wBACC,KAACP;4BACCC,aAAU;4BACVtB,WAAU;sCAETE,KAAKkC,MAAM;;;mBAhBTlC,KAAKC,EAAE;YAqBpB;;;AAIR"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks the table-of-contents anchor of the heading being read with
|
|
3
|
+
* `aria-current`, as `ActiveSection` marks a page's nav: an enhancement over
|
|
4
|
+
* anchors that already work. Renders nothing.
|
|
5
|
+
*
|
|
6
|
+
* A heading is a point, not a section, so it never stays in a band: the one
|
|
7
|
+
* being read is the last whose top has passed a line 30% down the window —
|
|
8
|
+
* none above the first. Checked once per frame while scrolling.
|
|
9
|
+
*
|
|
10
|
+
* Where the links sit in a row that scrolls sideways (a phone's strip), the
|
|
11
|
+
* newly marked one is scrolled to the row's middle, so it stays in sight.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ActiveHeading({ ids }: {
|
|
14
|
+
ids: readonly string[];
|
|
15
|
+
}): null;
|
|
16
|
+
//# sourceMappingURL=active-heading.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-heading.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/active-heading/active-heading.tsx"],"names":[],"mappings":"AAOA;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,QA2ChE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
/** How far down the window a heading must have come to be the current one. */ const LINE = 0.3;
|
|
4
|
+
/**
|
|
5
|
+
* Marks the table-of-contents anchor of the heading being read with
|
|
6
|
+
* `aria-current`, as `ActiveSection` marks a page's nav: an enhancement over
|
|
7
|
+
* anchors that already work. Renders nothing.
|
|
8
|
+
*
|
|
9
|
+
* A heading is a point, not a section, so it never stays in a band: the one
|
|
10
|
+
* being read is the last whose top has passed a line 30% down the window —
|
|
11
|
+
* none above the first. Checked once per frame while scrolling.
|
|
12
|
+
*
|
|
13
|
+
* Where the links sit in a row that scrolls sideways (a phone's strip), the
|
|
14
|
+
* newly marked one is scrolled to the row's middle, so it stays in sight.
|
|
15
|
+
*/ export function ActiveHeading({ ids }) {
|
|
16
|
+
useEffect(()=>{
|
|
17
|
+
const links = new Map(ids.map((id)=>[
|
|
18
|
+
id,
|
|
19
|
+
document.querySelectorAll(`a[data-section="${id}"]`)
|
|
20
|
+
]));
|
|
21
|
+
const headings = ids.flatMap((id)=>{
|
|
22
|
+
const heading = document.getElementById(id);
|
|
23
|
+
return heading === null ? [] : [
|
|
24
|
+
heading
|
|
25
|
+
];
|
|
26
|
+
});
|
|
27
|
+
let marked;
|
|
28
|
+
const mark = ()=>{
|
|
29
|
+
const line = window.innerHeight * LINE;
|
|
30
|
+
let current;
|
|
31
|
+
for (const heading of headings)if (heading.getBoundingClientRect().top <= line) current = heading.id;
|
|
32
|
+
for (const [id, anchors] of links)for (const anchor of anchors)if (id === current) anchor.setAttribute('aria-current', 'location');
|
|
33
|
+
else anchor.removeAttribute('aria-current');
|
|
34
|
+
if (current !== marked && current !== undefined) // Every heading found is one of `ids`, each with its anchors.
|
|
35
|
+
for (const anchor of links.get(current))reveal(anchor);
|
|
36
|
+
marked = current;
|
|
37
|
+
};
|
|
38
|
+
let frame = 0;
|
|
39
|
+
const onScroll = ()=>{
|
|
40
|
+
cancelAnimationFrame(frame);
|
|
41
|
+
frame = requestAnimationFrame(mark);
|
|
42
|
+
};
|
|
43
|
+
mark();
|
|
44
|
+
window.addEventListener('scroll', onScroll, {
|
|
45
|
+
passive: true
|
|
46
|
+
});
|
|
47
|
+
window.addEventListener('resize', onScroll, {
|
|
48
|
+
passive: true
|
|
49
|
+
});
|
|
50
|
+
return ()=>{
|
|
51
|
+
cancelAnimationFrame(frame);
|
|
52
|
+
window.removeEventListener('scroll', onScroll);
|
|
53
|
+
window.removeEventListener('resize', onScroll);
|
|
54
|
+
};
|
|
55
|
+
}, [
|
|
56
|
+
ids
|
|
57
|
+
]);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/** Scrolls a link to the middle of its list, if the list scrolls sideways. */ function reveal(anchor) {
|
|
61
|
+
const list = anchor.closest('ol, ul');
|
|
62
|
+
if (list === null || list.scrollWidth <= list.clientWidth) return;
|
|
63
|
+
const link = anchor.getBoundingClientRect();
|
|
64
|
+
const box = list.getBoundingClientRect();
|
|
65
|
+
list.scrollLeft += link.left - box.left - (box.width - link.width) / 2;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=active-heading.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/active-heading/active-heading.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\n\n/** How far down the window a heading must have come to be the current one. */\nconst LINE = 0.3;\n\n/**\n * Marks the table-of-contents anchor of the heading being read with\n * `aria-current`, as `ActiveSection` marks a page's nav: an enhancement over\n * anchors that already work. Renders nothing.\n *\n * A heading is a point, not a section, so it never stays in a band: the one\n * being read is the last whose top has passed a line 30% down the window —\n * none above the first. Checked once per frame while scrolling.\n *\n * Where the links sit in a row that scrolls sideways (a phone's strip), the\n * newly marked one is scrolled to the row's middle, so it stays in sight.\n */\nexport function ActiveHeading({ ids }: { ids: readonly string[] }) {\n useEffect(() => {\n const links = new Map(\n ids.map(id => [\n id,\n document.querySelectorAll<HTMLAnchorElement>(`a[data-section=\"${id}\"]`),\n ]),\n );\n const headings = ids.flatMap(id => {\n const heading = document.getElementById(id);\n return heading === null ? [] : [heading];\n });\n let marked: string | undefined;\n const mark = () => {\n const line = window.innerHeight * LINE;\n let current: string | undefined;\n for (const heading of headings)\n if (heading.getBoundingClientRect().top <= line) current = heading.id;\n for (const [id, anchors] of links)\n for (const anchor of anchors)\n if (id === current) anchor.setAttribute('aria-current', 'location');\n else anchor.removeAttribute('aria-current');\n if (current !== marked && current !== undefined)\n // Every heading found is one of `ids`, each with its anchors.\n for (const anchor of links.get(current) as Iterable<HTMLElement>)\n reveal(anchor);\n marked = current;\n };\n let frame = 0;\n const onScroll = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(mark);\n };\n mark();\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('resize', onScroll, { passive: true });\n return () => {\n cancelAnimationFrame(frame);\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onScroll);\n };\n }, [ids]);\n return null;\n}\n\n/** Scrolls a link to the middle of its list, if the list scrolls sideways. */\nfunction reveal(anchor: HTMLElement) {\n const list = anchor.closest('ol, ul');\n if (list === null || list.scrollWidth <= list.clientWidth) return;\n const link = anchor.getBoundingClientRect();\n const box = list.getBoundingClientRect();\n list.scrollLeft += link.left - box.left - (box.width - link.width) / 2;\n}\n"],"names":["useEffect","LINE","ActiveHeading","ids","links","Map","map","id","document","querySelectorAll","headings","flatMap","heading","getElementById","marked","mark","line","window","innerHeight","current","getBoundingClientRect","top","anchors","anchor","setAttribute","removeAttribute","undefined","get","reveal","frame","onScroll","cancelAnimationFrame","requestAnimationFrame","addEventListener","passive","removeEventListener","list","closest","scrollWidth","clientWidth","link","box","scrollLeft","left","width"],"mappings":"AAAA;AAEA,SAASA,SAAS,QAAQ,QAAQ;AAElC,4EAA4E,GAC5E,MAAMC,OAAO;AAEb;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,cAAc,EAAEC,GAAG,EAA8B;IAC/DH,UAAU;QACR,MAAMI,QAAQ,IAAIC,IAChBF,IAAIG,GAAG,CAACC,CAAAA,KAAM;gBACZA;gBACAC,SAASC,gBAAgB,CAAoB,CAAC,gBAAgB,EAAEF,GAAG,EAAE,CAAC;aACvE;QAEH,MAAMG,WAAWP,IAAIQ,OAAO,CAACJ,CAAAA;YAC3B,MAAMK,UAAUJ,SAASK,cAAc,CAACN;YACxC,OAAOK,YAAY,OAAO,EAAE,GAAG;gBAACA;aAAQ;QAC1C;QACA,IAAIE;QACJ,MAAMC,OAAO;YACX,MAAMC,OAAOC,OAAOC,WAAW,GAAGjB;YAClC,IAAIkB;YACJ,KAAK,MAAMP,WAAWF,SACpB,IAAIE,QAAQQ,qBAAqB,GAAGC,GAAG,IAAIL,MAAMG,UAAUP,QAAQL,EAAE;YACvE,KAAK,MAAM,CAACA,IAAIe,QAAQ,IAAIlB,MAC1B,KAAK,MAAMmB,UAAUD,QACnB,IAAIf,OAAOY,SAASI,OAAOC,YAAY,CAAC,gBAAgB;iBACnDD,OAAOE,eAAe,CAAC;YAChC,IAAIN,YAAYL,UAAUK,YAAYO,WACpC,8DAA8D;YAC9D,KAAK,MAAMH,UAAUnB,MAAMuB,GAAG,CAACR,SAC7BS,OAAOL;YACXT,SAASK;QACX;QACA,IAAIU,QAAQ;QACZ,MAAMC,WAAW;YACfC,qBAAqBF;YACrBA,QAAQG,sBAAsBjB;QAChC;QACAA;QACAE,OAAOgB,gBAAgB,CAAC,UAAUH,UAAU;YAAEI,SAAS;QAAK;QAC5DjB,OAAOgB,gBAAgB,CAAC,UAAUH,UAAU;YAAEI,SAAS;QAAK;QAC5D,OAAO;YACLH,qBAAqBF;YACrBZ,OAAOkB,mBAAmB,CAAC,UAAUL;YACrCb,OAAOkB,mBAAmB,CAAC,UAAUL;QACvC;IACF,GAAG;QAAC3B;KAAI;IACR,OAAO;AACT;AAEA,4EAA4E,GAC5E,SAASyB,OAAOL,MAAmB;IACjC,MAAMa,OAAOb,OAAOc,OAAO,CAAC;IAC5B,IAAID,SAAS,QAAQA,KAAKE,WAAW,IAAIF,KAAKG,WAAW,EAAE;IAC3D,MAAMC,OAAOjB,OAAOH,qBAAqB;IACzC,MAAMqB,MAAML,KAAKhB,qBAAqB;IACtCgB,KAAKM,UAAU,IAAIF,KAAKG,IAAI,GAAGF,IAAIE,IAAI,GAAG,AAACF,CAAAA,IAAIG,KAAK,GAAGJ,KAAKI,KAAK,AAAD,IAAK;AACvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/active-heading/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/active-heading/index.ts"],"sourcesContent":["export * from './active-heading.js';\n"],"names":[],"mappings":"AAAA,cAAc,sBAAsB"}
|