@entifix/react-controls 0.1.2 → 0.1.4
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 +7 -7
- 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,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks the nav anchor of the section in view with `aria-current`: an
|
|
3
|
+
* enhancement over anchors that already work (ADR 0008). Renders nothing.
|
|
4
|
+
*
|
|
5
|
+
* A section counts as in view while it crosses the band just above the
|
|
6
|
+
* viewport's middle; over the hero, none does.
|
|
7
|
+
*/
|
|
8
|
+
export declare function ActiveSection({ sections }: {
|
|
9
|
+
sections: readonly string[];
|
|
10
|
+
}): null;
|
|
11
|
+
//# sourceMappingURL=active-section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-section.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/active-section/active-section.tsx"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,QAmC1E"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Marks the nav anchor of the section in view with `aria-current`: an
|
|
5
|
+
* enhancement over anchors that already work (ADR 0008). Renders nothing.
|
|
6
|
+
*
|
|
7
|
+
* A section counts as in view while it crosses the band just above the
|
|
8
|
+
* viewport's middle; over the hero, none does.
|
|
9
|
+
*/ export function ActiveSection({ sections }) {
|
|
10
|
+
useEffect(()=>{
|
|
11
|
+
const links = new Map(sections.map((id)=>[
|
|
12
|
+
id,
|
|
13
|
+
document.querySelectorAll(`a[data-section="${id}"]`)
|
|
14
|
+
]));
|
|
15
|
+
const visible = new Set();
|
|
16
|
+
const mark = ()=>{
|
|
17
|
+
const current = sections.find((id)=>visible.has(id));
|
|
18
|
+
for (const [id, anchors] of links){
|
|
19
|
+
for (const anchor of anchors){
|
|
20
|
+
if (id === current) anchor.setAttribute('aria-current', 'location');
|
|
21
|
+
else anchor.removeAttribute('aria-current');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const observer = new IntersectionObserver((entries)=>{
|
|
26
|
+
for (const entry of entries){
|
|
27
|
+
if (entry.isIntersecting) visible.add(entry.target.id);
|
|
28
|
+
else visible.delete(entry.target.id);
|
|
29
|
+
}
|
|
30
|
+
mark();
|
|
31
|
+
}, {
|
|
32
|
+
rootMargin: '-40% 0px -55% 0px'
|
|
33
|
+
});
|
|
34
|
+
for (const id of sections){
|
|
35
|
+
const section = document.getElementById(id);
|
|
36
|
+
if (section) observer.observe(section);
|
|
37
|
+
}
|
|
38
|
+
return ()=>observer.disconnect();
|
|
39
|
+
}, [
|
|
40
|
+
sections
|
|
41
|
+
]);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=active-section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/active-section/active-section.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\n\n/**\n * Marks the nav anchor of the section in view with `aria-current`: an\n * enhancement over anchors that already work (ADR 0008). Renders nothing.\n *\n * A section counts as in view while it crosses the band just above the\n * viewport's middle; over the hero, none does.\n */\nexport function ActiveSection({ sections }: { sections: readonly string[] }) {\n useEffect(() => {\n const links = new Map(\n sections.map(id => [\n id,\n document.querySelectorAll<HTMLAnchorElement>(`a[data-section=\"${id}\"]`),\n ]),\n );\n const visible = new Set<string>();\n const mark = () => {\n const current = sections.find(id => visible.has(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 }\n }\n };\n const observer = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) visible.add(entry.target.id);\n else visible.delete(entry.target.id);\n }\n mark();\n },\n { rootMargin: '-40% 0px -55% 0px' },\n );\n for (const id of sections) {\n const section = document.getElementById(id);\n if (section) observer.observe(section);\n }\n return () => observer.disconnect();\n }, [sections]);\n return null;\n}\n"],"names":["useEffect","ActiveSection","sections","links","Map","map","id","document","querySelectorAll","visible","Set","mark","current","find","has","anchors","anchor","setAttribute","removeAttribute","observer","IntersectionObserver","entries","entry","isIntersecting","add","target","delete","rootMargin","section","getElementById","observe","disconnect"],"mappings":"AAAA;AAEA,SAASA,SAAS,QAAQ,QAAQ;AAElC;;;;;;CAMC,GACD,OAAO,SAASC,cAAc,EAAEC,QAAQ,EAAmC;IACzEF,UAAU;QACR,MAAMG,QAAQ,IAAIC,IAChBF,SAASG,GAAG,CAACC,CAAAA,KAAM;gBACjBA;gBACAC,SAASC,gBAAgB,CAAoB,CAAC,gBAAgB,EAAEF,GAAG,EAAE,CAAC;aACvE;QAEH,MAAMG,UAAU,IAAIC;QACpB,MAAMC,OAAO;YACX,MAAMC,UAAUV,SAASW,IAAI,CAACP,CAAAA,KAAMG,QAAQK,GAAG,CAACR;YAChD,KAAK,MAAM,CAACA,IAAIS,QAAQ,IAAIZ,MAAO;gBACjC,KAAK,MAAMa,UAAUD,QAAS;oBAC5B,IAAIT,OAAOM,SAASI,OAAOC,YAAY,CAAC,gBAAgB;yBACnDD,OAAOE,eAAe,CAAC;gBAC9B;YACF;QACF;QACA,MAAMC,WAAW,IAAIC,qBACnBC,CAAAA;YACE,KAAK,MAAMC,SAASD,QAAS;gBAC3B,IAAIC,MAAMC,cAAc,EAAEd,QAAQe,GAAG,CAACF,MAAMG,MAAM,CAACnB,EAAE;qBAChDG,QAAQiB,MAAM,CAACJ,MAAMG,MAAM,CAACnB,EAAE;YACrC;YACAK;QACF,GACA;YAAEgB,YAAY;QAAoB;QAEpC,KAAK,MAAMrB,MAAMJ,SAAU;YACzB,MAAM0B,UAAUrB,SAASsB,cAAc,CAACvB;YACxC,IAAIsB,SAAST,SAASW,OAAO,CAACF;QAChC;QACA,OAAO,IAAMT,SAASY,UAAU;IAClC,GAAG;QAAC7B;KAAS;IACb,OAAO;AACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/active-section/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/active-section/index.ts"],"sourcesContent":["export * from './active-section.js';\n"],"names":[],"mappings":"AAAA,cAAc,sBAAsB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** A disclosure to close before paint, and when: while `query` matches. */
|
|
2
|
+
export interface Fold {
|
|
3
|
+
/** A media query: `(width >= 64rem)`. */
|
|
4
|
+
readonly query: string;
|
|
5
|
+
/** The `<details>` it closes: every element the selector matches. */
|
|
6
|
+
readonly selector: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Closes disclosures before the page paints, by screen width: an inline
|
|
10
|
+
* script, placed after them in the document, that runs long before React
|
|
11
|
+
* hydrates. The HTML leaves them open, which is what a visitor with no script
|
|
12
|
+
* gets; a `<details>` it closes needs `suppressHydrationWarning`.
|
|
13
|
+
*
|
|
14
|
+
* A media query, not a container query: nothing has been laid out yet, so the
|
|
15
|
+
* window is the one width there is to ask.
|
|
16
|
+
*/
|
|
17
|
+
export declare function FoldScript({ folds }: {
|
|
18
|
+
folds: readonly Fold[];
|
|
19
|
+
}): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=fold-script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-script.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/fold-script/fold-script.tsx"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,WAAW,IAAI;IACnB,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,IAAI,EAAE,CAAA;CAAE,+BAc/D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** A disclosure to close before paint, and when: while `query` matches. */ import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Closes disclosures before the page paints, by screen width: an inline
|
|
4
|
+
* script, placed after them in the document, that runs long before React
|
|
5
|
+
* hydrates. The HTML leaves them open, which is what a visitor with no script
|
|
6
|
+
* gets; a `<details>` it closes needs `suppressHydrationWarning`.
|
|
7
|
+
*
|
|
8
|
+
* A media query, not a container query: nothing has been laid out yet, so the
|
|
9
|
+
* window is the one width there is to ask.
|
|
10
|
+
*/ export function FoldScript({ folds }) {
|
|
11
|
+
// `<` escaped, so no selector can close the script element early.
|
|
12
|
+
const data = JSON.stringify(folds).replaceAll('<', '\\u003c');
|
|
13
|
+
const script = `(function () {
|
|
14
|
+
try {
|
|
15
|
+
var folds = ${data};
|
|
16
|
+
for (var f = 0; f < folds.length; f++) {
|
|
17
|
+
if (!window.matchMedia(folds[f].query).matches) continue;
|
|
18
|
+
var found = document.querySelectorAll(folds[f].selector);
|
|
19
|
+
for (var i = 0; i < found.length; i++) found[i].removeAttribute('open');
|
|
20
|
+
}
|
|
21
|
+
} catch (error) {}
|
|
22
|
+
})();`;
|
|
23
|
+
return /*#__PURE__*/ _jsx("script", {
|
|
24
|
+
dangerouslySetInnerHTML: {
|
|
25
|
+
__html: script
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=fold-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/fold-script/fold-script.tsx"],"sourcesContent":["/** A disclosure to close before paint, and when: while `query` matches. */\nexport interface Fold {\n /** A media query: `(width >= 64rem)`. */\n readonly query: string;\n /** The `<details>` it closes: every element the selector matches. */\n readonly selector: string;\n}\n\n/**\n * Closes disclosures before the page paints, by screen width: an inline\n * script, placed after them in the document, that runs long before React\n * hydrates. The HTML leaves them open, which is what a visitor with no script\n * gets; a `<details>` it closes needs `suppressHydrationWarning`.\n *\n * A media query, not a container query: nothing has been laid out yet, so the\n * window is the one width there is to ask.\n */\nexport function FoldScript({ folds }: { folds: readonly Fold[] }) {\n // `<` escaped, so no selector can close the script element early.\n const data = JSON.stringify(folds).replaceAll('<', '\\\\u003c');\n const script = `(function () {\n try {\n var folds = ${data};\n for (var f = 0; f < folds.length; f++) {\n if (!window.matchMedia(folds[f].query).matches) continue;\n var found = document.querySelectorAll(folds[f].selector);\n for (var i = 0; i < found.length; i++) found[i].removeAttribute('open');\n }\n } catch (error) {}\n})();`;\n return <script dangerouslySetInnerHTML={{ __html: script }} />;\n}\n"],"names":["FoldScript","folds","data","JSON","stringify","replaceAll","script","dangerouslySetInnerHTML","__html"],"mappings":"AAAA,yEAAyE;AAQzE;;;;;;;;CAQC,GACD,OAAO,SAASA,WAAW,EAAEC,KAAK,EAA8B;IAC9D,kEAAkE;IAClE,MAAMC,OAAOC,KAAKC,SAAS,CAACH,OAAOI,UAAU,CAAC,KAAK;IACnD,MAAMC,SAAS,CAAC;;gBAEF,EAAEJ,KAAK;;;;;;;KAOlB,CAAC;IACJ,qBAAO,KAACI;QAAOC,yBAAyB;YAAEC,QAAQF;QAAO;;AAC3D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/fold-script/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/fold-script/index.ts"],"sourcesContent":["export * from './fold-script.js';\n"],"names":[],"mappings":"AAAA,cAAc,mBAAmB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/keep-section/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/keep-section/index.ts"],"sourcesContent":["export * from './keep-section.js';\n"],"names":[],"mappings":"AAAA,cAAc,oBAAoB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carries the section in view across the language switch (ADR 0008): a
|
|
3
|
+
* fragment never reaches a server, so the switch's `href` is given one as it
|
|
4
|
+
* is followed. Without scripting the visitor lands at the top of the other
|
|
5
|
+
* locale. Renders nothing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function KeepSection(): null;
|
|
8
|
+
//# sourceMappingURL=keep-section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keep-section.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/keep-section/keep-section.tsx"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,SAiB1B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Carries the section in view across the language switch (ADR 0008): a
|
|
5
|
+
* fragment never reaches a server, so the switch's `href` is given one as it
|
|
6
|
+
* is followed. Without scripting the visitor lands at the top of the other
|
|
7
|
+
* locale. Renders nothing.
|
|
8
|
+
*/ export function KeepSection() {
|
|
9
|
+
useEffect(()=>{
|
|
10
|
+
const follow = (event)=>{
|
|
11
|
+
const link = event.target instanceof Element ? event.target.closest('a[data-keep-section]') : null;
|
|
12
|
+
if (!link) return;
|
|
13
|
+
const current = document.querySelector('a[data-section][aria-current]');
|
|
14
|
+
const section = current == null ? void 0 : current.getAttribute('data-section');
|
|
15
|
+
link.hash = section ? section : window.location.hash;
|
|
16
|
+
};
|
|
17
|
+
// Capture: the `href` must be set before the browser follows it.
|
|
18
|
+
document.addEventListener('click', follow, true);
|
|
19
|
+
return ()=>document.removeEventListener('click', follow, true);
|
|
20
|
+
}, []);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=keep-section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/keep-section/keep-section.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\n\n/**\n * Carries the section in view across the language switch (ADR 0008): a\n * fragment never reaches a server, so the switch's `href` is given one as it\n * is followed. Without scripting the visitor lands at the top of the other\n * locale. Renders nothing.\n */\nexport function KeepSection() {\n useEffect(() => {\n const follow = (event: MouseEvent) => {\n const link =\n event.target instanceof Element\n ? event.target.closest<HTMLAnchorElement>('a[data-keep-section]')\n : null;\n if (!link) return;\n const current = document.querySelector('a[data-section][aria-current]');\n const section = current?.getAttribute('data-section');\n link.hash = section ? section : window.location.hash;\n };\n // Capture: the `href` must be set before the browser follows it.\n document.addEventListener('click', follow, true);\n return () => document.removeEventListener('click', follow, true);\n }, []);\n return null;\n}\n"],"names":["useEffect","KeepSection","follow","event","link","target","Element","closest","current","document","querySelector","section","getAttribute","hash","window","location","addEventListener","removeEventListener"],"mappings":"AAAA;AAEA,SAASA,SAAS,QAAQ,QAAQ;AAElC;;;;;CAKC,GACD,OAAO,SAASC;IACdD,UAAU;QACR,MAAME,SAAS,CAACC;YACd,MAAMC,OACJD,MAAME,MAAM,YAAYC,UACpBH,MAAME,MAAM,CAACE,OAAO,CAAoB,0BACxC;YACN,IAAI,CAACH,MAAM;YACX,MAAMI,UAAUC,SAASC,aAAa,CAAC;YACvC,MAAMC,UAAUH,2BAAAA,QAASI,YAAY,CAAC;YACtCR,KAAKS,IAAI,GAAGF,UAAUA,UAAUG,OAAOC,QAAQ,CAACF,IAAI;QACtD;QACA,iEAAiE;QACjEJ,SAASO,gBAAgB,CAAC,SAASd,QAAQ;QAC3C,OAAO,IAAMO,SAASQ,mBAAmB,CAAC,SAASf,QAAQ;IAC7D,GAAG,EAAE;IACL,OAAO;AACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/media-query/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/media-query/index.ts"],"sourcesContent":["export * from './media-query.js';\n"],"names":[],"mappings":"AAAA,cAAc,mBAAmB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a media query matches, kept in step as the window changes. The
|
|
3
|
+
* server, and the first render in the browser, see `serverValue`: hydration
|
|
4
|
+
* then moves to the real answer without a mismatch.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useMediaQuery(query: string, serverValue: boolean): boolean;
|
|
7
|
+
//# sourceMappingURL=media-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-query.d.ts","sourceRoot":"","sources":["../../../../src/ui/utils/media-query/media-query.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAc1E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useCallback, useSyncExternalStore } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Whether a media query matches, kept in step as the window changes. The
|
|
5
|
+
* server, and the first render in the browser, see `serverValue`: hydration
|
|
6
|
+
* then moves to the real answer without a mismatch.
|
|
7
|
+
*/ export function useMediaQuery(query, serverValue) {
|
|
8
|
+
const subscribe = useCallback((onChange)=>{
|
|
9
|
+
const list = window.matchMedia(query);
|
|
10
|
+
list.addEventListener('change', onChange);
|
|
11
|
+
return ()=>list.removeEventListener('change', onChange);
|
|
12
|
+
}, [
|
|
13
|
+
query
|
|
14
|
+
]);
|
|
15
|
+
return useSyncExternalStore(subscribe, ()=>window.matchMedia(query).matches, ()=>serverValue);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=media-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/ui/utils/media-query/media-query.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useSyncExternalStore } from 'react';\n\n/**\n * Whether a media query matches, kept in step as the window changes. The\n * server, and the first render in the browser, see `serverValue`: hydration\n * then moves to the real answer without a mismatch.\n */\nexport function useMediaQuery(query: string, serverValue: boolean): boolean {\n const subscribe = useCallback(\n (onChange: () => void) => {\n const list = window.matchMedia(query);\n list.addEventListener('change', onChange);\n return () => list.removeEventListener('change', onChange);\n },\n [query],\n );\n return useSyncExternalStore(\n subscribe,\n () => window.matchMedia(query).matches,\n () => serverValue,\n );\n}\n"],"names":["useCallback","useSyncExternalStore","useMediaQuery","query","serverValue","subscribe","onChange","list","window","matchMedia","addEventListener","removeEventListener","matches"],"mappings":"AAAA;AAEA,SAASA,WAAW,EAAEC,oBAAoB,QAAQ,QAAQ;AAE1D;;;;CAIC,GACD,OAAO,SAASC,cAAcC,KAAa,EAAEC,WAAoB;IAC/D,MAAMC,YAAYL,YAChB,CAACM;QACC,MAAMC,OAAOC,OAAOC,UAAU,CAACN;QAC/BI,KAAKG,gBAAgB,CAAC,UAAUJ;QAChC,OAAO,IAAMC,KAAKI,mBAAmB,CAAC,UAAUL;IAClD,GACA;QAACH;KAAM;IAET,OAAOF,qBACLI,WACA,IAAMG,OAAOC,UAAU,CAACN,OAAOS,OAAO,EACtC,IAAMR;AAEV"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entifix/react-controls",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Entity-agnostic React UI — table, form, filters, wizard, command palette — rendered from entity metadata, plus layout primitives.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@headlessui/react": "^2.2.10",
|
|
20
20
|
"class-variance-authority": "^0.7.1",
|
|
21
21
|
"idb": "^8.0.3",
|
|
22
|
-
"@entifix/core": "0.1.
|
|
22
|
+
"@entifix/core": "0.1.4"
|
|
23
23
|
},
|
|
24
24
|
"exports": {
|
|
25
25
|
"./package.json": "./package.json",
|
|
@@ -51,13 +51,13 @@
|
|
|
51
51
|
"@storybook/addon-docs": "^10.5.3",
|
|
52
52
|
"@storybook/addon-themes": "^10.5.3",
|
|
53
53
|
"@storybook/react-vite": "^10.5.3",
|
|
54
|
-
"effect": "3.22.
|
|
54
|
+
"effect": "3.22.2",
|
|
55
55
|
"i18next": "26.3.6",
|
|
56
56
|
"react": "19.2.8",
|
|
57
57
|
"react-i18next": "17.0.11",
|
|
58
58
|
"storybook": "^10.5.3",
|
|
59
|
-
"@entifix/style": "0.1.
|
|
60
|
-
"@entifix/i18n": "0.1.
|
|
59
|
+
"@entifix/style": "0.1.4",
|
|
60
|
+
"@entifix/i18n": "0.1.4"
|
|
61
61
|
},
|
|
62
62
|
"nx": {
|
|
63
63
|
"tags": [
|
|
@@ -96,11 +96,11 @@
|
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
|
-
"effect": ">=3.22 <4",
|
|
99
|
+
"effect": ">=3.22.2 <4",
|
|
100
100
|
"i18next": ">=26 <27",
|
|
101
101
|
"react": ">=19 <20",
|
|
102
102
|
"react-i18next": ">=17 <18",
|
|
103
|
-
"@entifix/i18n": "0.1.
|
|
103
|
+
"@entifix/i18n": "0.1.4"
|
|
104
104
|
},
|
|
105
105
|
"peerDependenciesMeta": {
|
|
106
106
|
"@entifix/i18n": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"catalogs.d.ts","sourceRoot":"","sources":["../../../src/i18n/spec-support/catalogs.ts"],"names":[],"mappings":"AAsGA,wBAAgB,mBAAmB,IAAI,IAAI,CAS1C"}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
-
import { defineCatalogs } from '@entifix/i18n';
|
|
3
|
-
import { controlsCatalogs } from '../catalog/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Catalogs for this package's own specs.
|
|
6
|
-
*
|
|
7
|
-
* ⚠️ **`entity` and `errors` are fixtures here, not shipped catalogs.** Both are
|
|
8
|
-
* *host* namespaces now: `entity` names the adopter's entities and `errors` is
|
|
9
|
-
* the code vocabulary their services answer with, so a framework shipping either
|
|
10
|
-
* would be shipping product copy — which is exactly what
|
|
11
|
-
* [ADR 0059](../../../../../../docs/adr/0059-entifix-leaves-the-repo.md)
|
|
12
|
-
* removes. What these specs prove is that a `labelKey` resolves against whatever
|
|
13
|
-
* catalog is installed, and a fixture proves that as well as r10c's did.
|
|
14
|
-
*
|
|
15
|
-
* The keys below are the ones the specs actually name, kept verbatim so the
|
|
16
|
-
* assertions still read as sentences rather than as placeholders.
|
|
17
|
-
*/ const entity = {
|
|
18
|
-
es: {
|
|
19
|
-
'product-specification': {
|
|
20
|
-
label: 'Producto',
|
|
21
|
-
plural: 'Productos',
|
|
22
|
-
fields: {
|
|
23
|
-
code: 'Código',
|
|
24
|
-
name: 'Nombre'
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
'user-identity': {
|
|
28
|
-
values: {
|
|
29
|
-
role: {
|
|
30
|
-
admin: 'Administrador',
|
|
31
|
-
user: 'Usuario'
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
useCases: {
|
|
35
|
-
revokeSessions: 'Cerrar sesiones',
|
|
36
|
-
revokeSessionsConfirm: '¿Cerrar todas las sesiones?'
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
'product-brand': {
|
|
40
|
-
useCases: {
|
|
41
|
-
retire: 'Retirar',
|
|
42
|
-
retireConfirm: '¿Retirar la marca?'
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
gadget: {
|
|
46
|
-
useCases: {
|
|
47
|
-
compare: 'Comparar',
|
|
48
|
-
import: 'Importar',
|
|
49
|
-
purge: 'Purgar',
|
|
50
|
-
purgeConfirm: '¿Purgar el registro?',
|
|
51
|
-
revokeSessions: 'Cerrar sesiones',
|
|
52
|
-
revokeSessionsConfirm: '¿Cerrar todas las sesiones?',
|
|
53
|
-
settleAll: 'Liquidar todo',
|
|
54
|
-
updateAspects: 'Actualizar aspectos'
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
'context-dependent': 'Depende del contexto',
|
|
58
|
-
'context-independent': 'Independiente del contexto',
|
|
59
|
-
determining: 'Determinante'
|
|
60
|
-
},
|
|
61
|
-
en: {
|
|
62
|
-
'product-specification': {
|
|
63
|
-
label: 'Product',
|
|
64
|
-
plural: 'Products',
|
|
65
|
-
fields: {
|
|
66
|
-
code: 'Code',
|
|
67
|
-
name: 'Name'
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
'user-identity': {
|
|
71
|
-
values: {
|
|
72
|
-
role: {
|
|
73
|
-
admin: 'Administrator',
|
|
74
|
-
user: 'User'
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
useCases: {
|
|
78
|
-
revokeSessions: 'Revoke sessions',
|
|
79
|
-
revokeSessionsConfirm: 'Revoke every session?'
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
'product-brand': {
|
|
83
|
-
useCases: {
|
|
84
|
-
retire: 'Retire',
|
|
85
|
-
retireConfirm: 'Retire the brand?'
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
gadget: {
|
|
89
|
-
useCases: {
|
|
90
|
-
compare: 'Compare',
|
|
91
|
-
import: 'Import',
|
|
92
|
-
purge: 'Purge',
|
|
93
|
-
purgeConfirm: 'Purge the record?',
|
|
94
|
-
revokeSessions: 'Revoke sessions',
|
|
95
|
-
revokeSessionsConfirm: 'Revoke every session?',
|
|
96
|
-
settleAll: 'Settle all',
|
|
97
|
-
updateAspects: 'Update aspects'
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
'context-dependent': 'Context dependent',
|
|
101
|
-
'context-independent': 'Context independent',
|
|
102
|
-
determining: 'Determining'
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
const errors = {
|
|
106
|
-
es: {
|
|
107
|
-
unauthenticated: 'No autenticado',
|
|
108
|
-
forbidden: 'Sin permiso',
|
|
109
|
-
notFound: 'No encontrado',
|
|
110
|
-
invalidQuery: 'La consulta no es válida.',
|
|
111
|
-
unexpected: 'Error inesperado'
|
|
112
|
-
},
|
|
113
|
-
en: {
|
|
114
|
-
unauthenticated: 'Not authenticated',
|
|
115
|
-
forbidden: 'Forbidden',
|
|
116
|
-
notFound: 'Not found',
|
|
117
|
-
invalidQuery: 'The query is not valid.',
|
|
118
|
-
unexpected: 'Unexpected error'
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
export function installSpecCatalogs() {
|
|
122
|
-
defineCatalogs({
|
|
123
|
-
resources: {
|
|
124
|
-
es: _extends({}, controlsCatalogs.es, {
|
|
125
|
-
entity: entity.es,
|
|
126
|
-
errors: errors.es
|
|
127
|
-
}),
|
|
128
|
-
en: _extends({}, controlsCatalogs.en, {
|
|
129
|
-
entity: entity.en,
|
|
130
|
-
errors: errors.en
|
|
131
|
-
})
|
|
132
|
-
},
|
|
133
|
-
namespaces: [
|
|
134
|
-
'controls',
|
|
135
|
-
'entity',
|
|
136
|
-
'errors'
|
|
137
|
-
],
|
|
138
|
-
defaultNS: 'controls'
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
//# sourceMappingURL=catalogs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/i18n/spec-support/catalogs.ts"],"sourcesContent":["import { defineCatalogs } from '@entifix/i18n';\n\nimport { controlsCatalogs } from '../catalog/index.js';\n\n/**\n * Catalogs for this package's own specs.\n *\n * ⚠️ **`entity` and `errors` are fixtures here, not shipped catalogs.** Both are\n * *host* namespaces now: `entity` names the adopter's entities and `errors` is\n * the code vocabulary their services answer with, so a framework shipping either\n * would be shipping product copy — which is exactly what\n * [ADR 0059](../../../../../../docs/adr/0059-entifix-leaves-the-repo.md)\n * removes. What these specs prove is that a `labelKey` resolves against whatever\n * catalog is installed, and a fixture proves that as well as r10c's did.\n *\n * The keys below are the ones the specs actually name, kept verbatim so the\n * assertions still read as sentences rather than as placeholders.\n */\nconst entity = {\n es: {\n 'product-specification': {\n label: 'Producto',\n plural: 'Productos',\n fields: { code: 'Código', name: 'Nombre' },\n },\n 'user-identity': {\n values: { role: { admin: 'Administrador', user: 'Usuario' } },\n useCases: {\n revokeSessions: 'Cerrar sesiones',\n revokeSessionsConfirm: '¿Cerrar todas las sesiones?',\n },\n },\n 'product-brand': {\n useCases: { retire: 'Retirar', retireConfirm: '¿Retirar la marca?' },\n },\n gadget: {\n useCases: {\n compare: 'Comparar',\n import: 'Importar',\n purge: 'Purgar',\n purgeConfirm: '¿Purgar el registro?',\n revokeSessions: 'Cerrar sesiones',\n revokeSessionsConfirm: '¿Cerrar todas las sesiones?',\n settleAll: 'Liquidar todo',\n updateAspects: 'Actualizar aspectos',\n },\n },\n 'context-dependent': 'Depende del contexto',\n 'context-independent': 'Independiente del contexto',\n determining: 'Determinante',\n },\n en: {\n 'product-specification': {\n label: 'Product',\n plural: 'Products',\n fields: { code: 'Code', name: 'Name' },\n },\n 'user-identity': {\n values: { role: { admin: 'Administrator', user: 'User' } },\n useCases: {\n revokeSessions: 'Revoke sessions',\n revokeSessionsConfirm: 'Revoke every session?',\n },\n },\n 'product-brand': {\n useCases: { retire: 'Retire', retireConfirm: 'Retire the brand?' },\n },\n gadget: {\n useCases: {\n compare: 'Compare',\n import: 'Import',\n purge: 'Purge',\n purgeConfirm: 'Purge the record?',\n revokeSessions: 'Revoke sessions',\n revokeSessionsConfirm: 'Revoke every session?',\n settleAll: 'Settle all',\n updateAspects: 'Update aspects',\n },\n },\n 'context-dependent': 'Context dependent',\n 'context-independent': 'Context independent',\n determining: 'Determining',\n },\n} as const;\n\nconst errors = {\n es: {\n unauthenticated: 'No autenticado',\n forbidden: 'Sin permiso',\n notFound: 'No encontrado',\n invalidQuery: 'La consulta no es válida.',\n unexpected: 'Error inesperado',\n },\n en: {\n unauthenticated: 'Not authenticated',\n forbidden: 'Forbidden',\n notFound: 'Not found',\n invalidQuery: 'The query is not valid.',\n unexpected: 'Unexpected error',\n },\n} as const;\n\nexport function installSpecCatalogs(): void {\n defineCatalogs({\n resources: {\n es: { ...controlsCatalogs.es, entity: entity.es, errors: errors.es },\n en: { ...controlsCatalogs.en, entity: entity.en, errors: errors.en },\n },\n namespaces: ['controls', 'entity', 'errors'],\n defaultNS: 'controls',\n });\n}\n"],"names":["defineCatalogs","controlsCatalogs","entity","es","label","plural","fields","code","name","values","role","admin","user","useCases","revokeSessions","revokeSessionsConfirm","retire","retireConfirm","gadget","compare","import","purge","purgeConfirm","settleAll","updateAspects","determining","en","errors","unauthenticated","forbidden","notFound","invalidQuery","unexpected","installSpecCatalogs","resources","namespaces","defaultNS"],"mappings":";AAAA,SAASA,cAAc,QAAQ,gBAAgB;AAE/C,SAASC,gBAAgB,QAAQ,sBAAsB;AAEvD;;;;;;;;;;;;;CAaC,GACD,MAAMC,SAAS;IACbC,IAAI;QACF,yBAAyB;YACvBC,OAAO;YACPC,QAAQ;YACRC,QAAQ;gBAAEC,MAAM;gBAAUC,MAAM;YAAS;QAC3C;QACA,iBAAiB;YACfC,QAAQ;gBAAEC,MAAM;oBAAEC,OAAO;oBAAiBC,MAAM;gBAAU;YAAE;YAC5DC,UAAU;gBACRC,gBAAgB;gBAChBC,uBAAuB;YACzB;QACF;QACA,iBAAiB;YACfF,UAAU;gBAAEG,QAAQ;gBAAWC,eAAe;YAAqB;QACrE;QACAC,QAAQ;YACNL,UAAU;gBACRM,SAAS;gBACTC,QAAQ;gBACRC,OAAO;gBACPC,cAAc;gBACdR,gBAAgB;gBAChBC,uBAAuB;gBACvBQ,WAAW;gBACXC,eAAe;YACjB;QACF;QACA,qBAAqB;QACrB,uBAAuB;QACvBC,aAAa;IACf;IACAC,IAAI;QACF,yBAAyB;YACvBtB,OAAO;YACPC,QAAQ;YACRC,QAAQ;gBAAEC,MAAM;gBAAQC,MAAM;YAAO;QACvC;QACA,iBAAiB;YACfC,QAAQ;gBAAEC,MAAM;oBAAEC,OAAO;oBAAiBC,MAAM;gBAAO;YAAE;YACzDC,UAAU;gBACRC,gBAAgB;gBAChBC,uBAAuB;YACzB;QACF;QACA,iBAAiB;YACfF,UAAU;gBAAEG,QAAQ;gBAAUC,eAAe;YAAoB;QACnE;QACAC,QAAQ;YACNL,UAAU;gBACRM,SAAS;gBACTC,QAAQ;gBACRC,OAAO;gBACPC,cAAc;gBACdR,gBAAgB;gBAChBC,uBAAuB;gBACvBQ,WAAW;gBACXC,eAAe;YACjB;QACF;QACA,qBAAqB;QACrB,uBAAuB;QACvBC,aAAa;IACf;AACF;AAEA,MAAME,SAAS;IACbxB,IAAI;QACFyB,iBAAiB;QACjBC,WAAW;QACXC,UAAU;QACVC,cAAc;QACdC,YAAY;IACd;IACAN,IAAI;QACFE,iBAAiB;QACjBC,WAAW;QACXC,UAAU;QACVC,cAAc;QACdC,YAAY;IACd;AACF;AAEA,OAAO,SAASC;IACdjC,eAAe;QACbkC,WAAW;YACT/B,IAAI,aAAKF,iBAAiBE,EAAE;gBAAED,QAAQA,OAAOC,EAAE;gBAAEwB,QAAQA,OAAOxB,EAAE;;YAClEuB,IAAI,aAAKzB,iBAAiByB,EAAE;gBAAExB,QAAQA,OAAOwB,EAAE;gBAAEC,QAAQA,OAAOD,EAAE;;QACpE;QACAS,YAAY;YAAC;YAAY;YAAU;SAAS;QAC5CC,WAAW;IACb;AACF"}
|