@clubmed/trident-ui 2.1.0-beta.4 → 2.1.0-beta.5

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.
Files changed (54) hide show
  1. package/chunks/Layer.js +2022 -0
  2. package/chunks/Layer.js.map +1 -0
  3. package/chunks/useTransitionState.js +69 -0
  4. package/chunks/useTransitionState.js.map +1 -0
  5. package/examples/backdrop-demo.js +1 -1
  6. package/examples/layer-buttons-demo.d.ts +1 -0
  7. package/examples/layer-buttons-demo.js +43 -0
  8. package/examples/layer-buttons-demo.js.map +1 -0
  9. package/examples/layer-demo.d.ts +1 -0
  10. package/examples/layer-demo.js +30 -0
  11. package/examples/layer-demo.js.map +1 -0
  12. package/examples/layer-header-demo.d.ts +1 -0
  13. package/examples/layer-header-demo.js +27 -0
  14. package/examples/layer-header-demo.js.map +1 -0
  15. package/examples/layer-nested-demo.d.ts +1 -0
  16. package/examples/layer-nested-demo.js +51 -0
  17. package/examples/layer-nested-demo.js.map +1 -0
  18. package/examples/layer-pinned-demo.d.ts +1 -0
  19. package/examples/layer-pinned-demo.js +36 -0
  20. package/examples/layer-pinned-demo.js.map +1 -0
  21. package/examples/layer-scale-demo.d.ts +1 -0
  22. package/examples/layer-scale-demo.js +34 -0
  23. package/examples/layer-scale-demo.js.map +1 -0
  24. package/examples/layer-use-layer-demo.d.ts +1 -0
  25. package/examples/layer-use-layer-demo.js +33 -0
  26. package/examples/layer-use-layer-demo.js.map +1 -0
  27. package/package.json +2 -1
  28. package/ui/Backdrop.d.ts +5 -0
  29. package/ui/Backdrop.js +54 -2
  30. package/ui/Backdrop.js.map +1 -0
  31. package/ui/Layer.d.ts +72 -0
  32. package/ui/Layer.js +2 -0
  33. package/ui/LayerHeader.d.ts +33 -0
  34. package/ui/LayerHeader.js +45 -0
  35. package/ui/LayerHeader.js.map +1 -0
  36. package/ui/Loader.js +2 -1
  37. package/ui/Loader.js.map +1 -1
  38. package/ui/Popin.d.ts +6 -0
  39. package/ui/Popin.js +11 -10
  40. package/ui/Popin.js.map +1 -1
  41. package/ui/hooks/useIsomorphicLayoutEffect.d.ts +6 -0
  42. package/ui/hooks/useIsomorphicLayoutEffect.js +7 -0
  43. package/ui/hooks/useIsomorphicLayoutEffect.js.map +1 -0
  44. package/ui/hooks/useLayer.d.ts +13 -0
  45. package/ui/hooks/useLayer.js +31 -0
  46. package/ui/hooks/useLayer.js.map +1 -0
  47. package/ui/hooks/useTransitionState.d.ts +7 -0
  48. package/ui/hooks/useTransitionState.js +15 -0
  49. package/ui/hooks/useTransitionState.js.map +1 -0
  50. package/ui/hooks/useVisualViewportBox.d.ts +7 -0
  51. package/ui/hooks/useVisualViewportBox.js +22 -0
  52. package/ui/hooks/useVisualViewportBox.js.map +1 -0
  53. package/chunks/Backdrop.js +0 -105
  54. package/chunks/Backdrop.js.map +0 -1
@@ -0,0 +1,69 @@
1
+ import { useCallback as e, useRef as t, useState as n } from "react";
2
+ var r = 5, i = 6, a = [
3
+ "preEnter",
4
+ "entering",
5
+ "entered",
6
+ "preExit",
7
+ "exiting",
8
+ "exited",
9
+ "unmounted"
10
+ ], o = (e) => ({
11
+ _s: e,
12
+ status: a[e],
13
+ isEnter: e < 3,
14
+ isMounted: e !== i,
15
+ isResolved: e === 2 || e > 4
16
+ }), s = (e) => e ? i : r, c = (e, t) => {
17
+ switch (e) {
18
+ case 1:
19
+ case 0: return 2;
20
+ case 4:
21
+ case 3: return s(t);
22
+ }
23
+ }, l = (e) => typeof e == "object" ? [e.enter, e.exit] : [e, e], u = (...e) => setTimeout(...e), d = (e, t) => u(() => {
24
+ isNaN(document.body.offsetTop) || e(t + 1);
25
+ }, 0), f = (e, t, n, r, i) => {
26
+ clearTimeout(r.current);
27
+ let a = o(e);
28
+ t(a), n.current = a, i && i({ current: a });
29
+ }, p = ({ enter: r = !0, exit: i = !0, preEnter: a, preExit: p, timeout: m, initialEntered: h, mountOnEnter: g, unmountOnExit: _, onStateChange: v } = {}) => {
30
+ let [y, b] = n(() => o(h ? 2 : s(g))), x = t(y), S = t(0), [C, w] = l(m), T = e(() => {
31
+ let e = c(x.current._s, _);
32
+ e && f(e, b, x, S, v);
33
+ }, [v, _]);
34
+ return [
35
+ y,
36
+ e((e) => {
37
+ let t = (e) => {
38
+ switch (f(e, b, x, S, v), e) {
39
+ case 1:
40
+ C >= 0 && (S.current = u(T, C));
41
+ break;
42
+ case 4:
43
+ w >= 0 && (S.current = u(T, w));
44
+ break;
45
+ case 0:
46
+ case 3:
47
+ S.current = d(t, e);
48
+ break;
49
+ }
50
+ }, n = x.current.isEnter;
51
+ typeof e != "boolean" && (e = !n), e ? !n && t(r ? a ? 0 : 1 : 2) : n && t(i ? p ? 3 : 4 : s(_));
52
+ }, [
53
+ T,
54
+ v,
55
+ r,
56
+ i,
57
+ a,
58
+ p,
59
+ C,
60
+ w,
61
+ _
62
+ ]),
63
+ T
64
+ ];
65
+ };
66
+ //#endregion
67
+ export { p as t };
68
+
69
+ //# sourceMappingURL=useTransitionState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTransitionState.js","names":[],"sources":["../../../../node_modules/.pnpm/react-transition-state@2.3.3_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/react-transition-state/dist/esm/utils.mjs","../../../../node_modules/.pnpm/react-transition-state@2.3.3_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/react-transition-state/dist/esm/useTransitionState.mjs"],"sourcesContent":["//#region src/utils.ts\nconst PRE_ENTER = 0;\nconst ENTERING = 1;\nconst ENTERED = 2;\nconst PRE_EXIT = 3;\nconst EXITING = 4;\nconst EXITED = 5;\nconst UNMOUNTED = 6;\nconst STATUS = [\n\t\"preEnter\",\n\t\"entering\",\n\t\"entered\",\n\t\"preExit\",\n\t\"exiting\",\n\t\"exited\",\n\t\"unmounted\"\n];\nconst getState = (status) => ({\n\t_s: status,\n\tstatus: STATUS[status],\n\tisEnter: status < PRE_EXIT,\n\tisMounted: status !== UNMOUNTED,\n\tisResolved: status === ENTERED || status > EXITING\n});\nconst startOrEnd = (unmounted) => unmounted ? UNMOUNTED : EXITED;\nconst getEndStatus = (status, unmountOnExit) => {\n\tswitch (status) {\n\t\tcase ENTERING:\n\t\tcase PRE_ENTER: return ENTERED;\n\t\tcase EXITING:\n\t\tcase PRE_EXIT: return startOrEnd(unmountOnExit);\n\t}\n};\nconst getTimeout = (timeout) => typeof timeout === \"object\" ? [timeout.enter, timeout.exit] : [timeout, timeout];\nconst _setTimeout = (...args) => setTimeout(...args);\nconst nextTick = (transitState, status) => _setTimeout(() => {\n\tisNaN(document.body.offsetTop) || transitState(status + 1);\n}, 0);\n\n//#endregion\nexport { ENTERED, ENTERING, EXITING, PRE_ENTER, PRE_EXIT, _setTimeout, getEndStatus, getState, getTimeout, nextTick, startOrEnd };","import { ENTERED, ENTERING, EXITING, PRE_ENTER, PRE_EXIT, _setTimeout, getEndStatus, getState, getTimeout, nextTick, startOrEnd } from \"./utils.mjs\";\nimport { useCallback, useRef, useState } from \"react\";\n\n//#region src/useTransitionState.ts\nconst updateState = (status, setState, latestState, timeoutId, onChange) => {\n\tclearTimeout(timeoutId.current);\n\tconst state = getState(status);\n\tsetState(state);\n\tlatestState.current = state;\n\tonChange && onChange({ current: state });\n};\nconst useTransitionState = ({ enter = true, exit = true, preEnter, preExit, timeout, initialEntered, mountOnEnter, unmountOnExit, onStateChange: onChange } = {}) => {\n\tconst [state, setState] = useState(() => getState(initialEntered ? ENTERED : startOrEnd(mountOnEnter)));\n\tconst latestState = useRef(state);\n\tconst timeoutId = useRef(0);\n\tconst [enterTimeout, exitTimeout] = getTimeout(timeout);\n\tconst endTransition = useCallback(() => {\n\t\tconst status = getEndStatus(latestState.current._s, unmountOnExit);\n\t\tstatus && updateState(status, setState, latestState, timeoutId, onChange);\n\t}, [onChange, unmountOnExit]);\n\treturn [\n\t\tstate,\n\t\tuseCallback((toEnter) => {\n\t\t\tconst transitState = (status) => {\n\t\t\t\tupdateState(status, setState, latestState, timeoutId, onChange);\n\t\t\t\tswitch (status) {\n\t\t\t\t\tcase ENTERING:\n\t\t\t\t\t\tif (enterTimeout >= 0) timeoutId.current = _setTimeout(endTransition, enterTimeout);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EXITING:\n\t\t\t\t\t\tif (exitTimeout >= 0) timeoutId.current = _setTimeout(endTransition, exitTimeout);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PRE_ENTER:\n\t\t\t\t\tcase PRE_EXIT:\n\t\t\t\t\t\ttimeoutId.current = nextTick(transitState, status);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst enterStage = latestState.current.isEnter;\n\t\t\tif (typeof toEnter !== \"boolean\") toEnter = !enterStage;\n\t\t\tif (toEnter) !enterStage && transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);\n\t\t\telse enterStage && transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));\n\t\t}, [\n\t\t\tendTransition,\n\t\t\tonChange,\n\t\t\tenter,\n\t\t\texit,\n\t\t\tpreEnter,\n\t\t\tpreExit,\n\t\t\tenterTimeout,\n\t\t\texitTimeout,\n\t\t\tunmountOnExit\n\t\t]),\n\t\tendTransition\n\t];\n};\n\n//#endregion\nexport { useTransitionState };"],"x_google_ignoreList":[0,1],"mappings":";AAMA,IAAM,IAAS,GACT,IAAY,GACZ,IAAS;CACd;CACA;CACA;CACA;CACA;CACA;CACA;CACA,EACK,KAAY,OAAY;CAC7B,IAAI;CACJ,QAAQ,EAAO;CACf,SAAS,IAAA;CACT,WAAW,MAAW;CACtB,YAAY,MAAA,KAAsB,IAAA;CAClC,GACK,KAAc,MAAc,IAAY,IAAY,GACpD,KAAgB,GAAQ,MAAkB;AAC/C,SAAQ,GAAR;EACC,KAAA;EACA,KAAA,EAAgB,QAAA;EAChB,KAAA;EACA,KAAA,EAAe,QAAO,EAAW,EAAc;;GAG3C,KAAc,MAAY,OAAO,KAAY,WAAW,CAAC,EAAQ,OAAO,EAAQ,KAAK,GAAG,CAAC,GAAS,EAAQ,EAC1G,KAAe,GAAG,MAAS,WAAW,GAAG,EAAK,EAC9C,KAAY,GAAc,MAAW,QAAkB;AAC5D,OAAM,SAAS,KAAK,UAAU,IAAI,EAAa,IAAS,EAAE;GACxD,EAAE,ECjCC,KAAe,GAAQ,GAAU,GAAa,GAAW,MAAa;AAC3E,cAAa,EAAU,QAAQ;CAC/B,IAAM,IAAQ,EAAS,EAAO;AAG9B,CAFA,EAAS,EAAM,EACf,EAAY,UAAU,GACtB,KAAY,EAAS,EAAE,SAAS,GAAO,CAAC;GAEnC,KAAsB,EAAE,WAAQ,IAAM,UAAO,IAAM,aAAU,YAAS,YAAS,mBAAgB,iBAAc,kBAAe,eAAe,MAAa,EAAE,KAAK;CACpK,IAAM,CAAC,GAAO,KAAY,QAAe,EAAS,IAAA,IAA2B,EAAW,EAAa,CAAC,CAAC,EACjG,IAAc,EAAO,EAAM,EAC3B,IAAY,EAAO,EAAE,EACrB,CAAC,GAAc,KAAe,EAAW,EAAQ,EACjD,IAAgB,QAAkB;EACvC,IAAM,IAAS,EAAa,EAAY,QAAQ,IAAI,EAAc;AAClE,OAAU,EAAY,GAAQ,GAAU,GAAa,GAAW,EAAS;IACvE,CAAC,GAAU,EAAc,CAAC;AAC7B,QAAO;EACN;EACA,GAAa,MAAY;GACxB,IAAM,KAAgB,MAAW;AAEhC,YADA,EAAY,GAAQ,GAAU,GAAa,GAAW,EAAS,EACvD,GAAR;KACC,KAAA;AACC,MAAI,KAAgB,MAAG,EAAU,UAAU,EAAY,GAAe,EAAa;AACnF;KACD,KAAA;AACC,MAAI,KAAe,MAAG,EAAU,UAAU,EAAY,GAAe,EAAY;AACjF;KACD,KAAA;KACA,KAAA;AACC,QAAU,UAAU,EAAS,GAAc,EAAO;AAClD;;MAGG,IAAa,EAAY,QAAQ;AAEvC,GADI,OAAO,KAAY,cAAW,IAAU,CAAC,IACzC,IAAS,CAAC,KAAc,EAAa,IAAQ,IAAA,IAAA,IAAA,EAA0C,GACtF,KAAc,EAAa,IAAO,IAAA,IAAA,IAA+B,EAAW,EAAc,CAAC;KAC9F;GACF;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,CAAC;EACF;EACA"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Button as e } from "../ui/buttons/Button.js";
3
- import { t } from "../chunks/Backdrop.js";
3
+ import { Backdrop as t } from "../ui/Backdrop.js";
4
4
  import { useState as n } from "react";
5
5
  import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
6
  //#region lib/examples/backdrop-demo.tsx
@@ -0,0 +1 @@
1
+ export default function LayerButtonsDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { Button as e } from "../ui/buttons/Button.js";
3
+ import { t } from "../chunks/Layer.js";
4
+ import { useState as n } from "react";
5
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ //#region lib/examples/layer-buttons-demo.tsx
7
+ function o() {
8
+ let [o, s] = n(!1), [c, l] = n(1), u = () => {
9
+ s(!1), l(1);
10
+ };
11
+ return /* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i(e, {
12
+ onClick: () => s(!0),
13
+ children: "Book an activity"
14
+ }), /* @__PURE__ */ i(t, {
15
+ heading: `Step ${c} of 2`,
16
+ isOpen: o,
17
+ onClose: u,
18
+ leftButton: c > 1 ? {
19
+ label: "Previous step",
20
+ icon: "ArrowDefaultLeft",
21
+ onClick: () => l(1)
22
+ } : void 0,
23
+ rightButton: {
24
+ label: "Close",
25
+ icon: "CrossDefault",
26
+ onClick: u
27
+ },
28
+ children: /* @__PURE__ */ i("div", {
29
+ className: "space-y-20 p-20",
30
+ children: c === 1 ? /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i("p", { children: "Choose an activity for your stay." }), /* @__PURE__ */ i(e, {
31
+ onClick: () => l(2),
32
+ children: "Continue"
33
+ })] }) : /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i("p", { children: "Pick a time slot. The back arrow returns to the previous step." }), /* @__PURE__ */ i(e, {
34
+ onClick: u,
35
+ children: "Confirm"
36
+ })] })
37
+ })
38
+ })] });
39
+ }
40
+ //#endregion
41
+ export { o as default };
42
+
43
+ //# sourceMappingURL=layer-buttons-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-buttons-demo.js","names":[],"sources":["../../lib/examples/layer-buttons-demo.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Layer } from '@/ui/Layer';\nimport { Button } from '@/ui/buttons/Button';\n\nexport default function LayerButtonsDemo() {\n const [isOpen, setIsOpen] = useState(false);\n const [step, setStep] = useState(1);\n\n const close = () => {\n setIsOpen(false);\n setStep(1);\n };\n\n return (\n <div>\n <Button onClick={() => setIsOpen(true)}>Book an activity</Button>\n <Layer\n heading={`Step ${step} of 2`}\n isOpen={isOpen}\n onClose={close}\n leftButton={\n step > 1\n ? { label: 'Previous step', icon: 'ArrowDefaultLeft', onClick: () => setStep(1) }\n : undefined\n }\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: close }}\n >\n <div className=\"space-y-20 p-20\">\n {step === 1 ? (\n <>\n <p>Choose an activity for your stay.</p>\n <Button onClick={() => setStep(2)}>Continue</Button>\n </>\n ) : (\n <>\n <p>Pick a time slot. The back arrow returns to the previous step.</p>\n <Button onClick={close}>Confirm</Button>\n </>\n )}\n </div>\n </Layer>\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAwB,IAAmB;CACzC,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,CAAC,GAAM,KAAW,EAAS,EAAE,EAE7B,UAAc;AAElB,EADA,EAAU,GAAM,EAChB,EAAQ,EAAE;;AAGZ,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAQ,eAAe,EAAU,GAAK;YAAE;EAAyB,CAAA,EACjE,kBAAC,GAAD;EACE,SAAS,QAAQ,EAAK;EACd;EACR,SAAS;EACT,YACE,IAAO,IACH;GAAE,OAAO;GAAiB,MAAM;GAAoB,eAAe,EAAQ,EAAA;GAAI,GAC/E,KAAA;EAEN,aAAa;GAAE,OAAO;GAAS,MAAM;GAAgB,SAAS;GAAO;YAErE,kBAAC,OAAD;GAAK,WAAU;aACZ,MAAS,IACR,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,KAAD,EAAA,UAAG,qCAAqC,CAAA,EACxC,kBAAC,GAAD;IAAQ,eAAe,EAAQ,EAAE;cAAE;IAAiB,CAAA,CACnD,EAAA,CAAA,GAEH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,KAAD,EAAA,UAAG,kEAAkE,CAAA,EACrE,kBAAC,GAAD;IAAQ,SAAS;cAAO;IAAgB,CAAA,CACvC,EAAA,CAAA;GAED,CAAA;EACA,CAAA,CACJ,EAAA,CAAA"}
@@ -0,0 +1 @@
1
+ export default function LayerDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { Button as e } from "../ui/buttons/Button.js";
3
+ import { t } from "../chunks/Layer.js";
4
+ import { useState as n } from "react";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ //#region lib/examples/layer-demo.tsx
7
+ function a() {
8
+ let [a, o] = n(!1), s = () => o(!1);
9
+ return /* @__PURE__ */ i("div", { children: [/* @__PURE__ */ r(e, {
10
+ onClick: () => o(!0),
11
+ children: "Open Layer"
12
+ }), /* @__PURE__ */ r(t, {
13
+ heading: "Your stay",
14
+ isOpen: a,
15
+ onClose: s,
16
+ rightButton: {
17
+ label: "Close",
18
+ icon: "CrossDefault",
19
+ onClick: s
20
+ },
21
+ children: /* @__PURE__ */ i("div", {
22
+ className: "space-y-20 p-20",
23
+ children: [/* @__PURE__ */ r("p", { children: "A Layer covers the whole screen and slides in from the side. Press Escape or use the close button to dismiss it." }), /* @__PURE__ */ r("p", { children: "Its body scrolls on its own, below the header, while the page behind it stays locked." })]
24
+ })
25
+ })] });
26
+ }
27
+ //#endregion
28
+ export { a as default };
29
+
30
+ //# sourceMappingURL=layer-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-demo.js","names":[],"sources":["../../lib/examples/layer-demo.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Layer } from '@/ui/Layer';\nimport { Button } from '@/ui/buttons/Button';\n\nexport default function LayerDemo() {\n const [isOpen, setIsOpen] = useState(false);\n const close = () => setIsOpen(false);\n\n return (\n <div>\n <Button onClick={() => setIsOpen(true)}>Open Layer</Button>\n <Layer\n heading=\"Your stay\"\n isOpen={isOpen}\n onClose={close}\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: close }}\n >\n <div className=\"space-y-20 p-20\">\n <p>\n A Layer covers the whole screen and slides in from the side. Press Escape or use the\n close button to dismiss it.\n </p>\n <p>\n Its body scrolls on its own, below the header, while the page behind it stays locked.\n </p>\n </div>\n </Layer>\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAwB,IAAY;CAClC,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,UAAc,EAAU,GAAM;AAEpC,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAQ,eAAe,EAAU,GAAK;YAAE;EAAmB,CAAA,EAC3D,kBAAC,GAAD;EACE,SAAQ;EACA;EACR,SAAS;EACT,aAAa;GAAE,OAAO;GAAS,MAAM;GAAgB,SAAS;GAAO;YAErE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD,EAAA,UAAG,oHAGC,CAAA,EACJ,kBAAC,KAAD,EAAA,UAAG,yFAEC,CAAA,CAAA;;EAEA,CAAA,CACJ,EAAA,CAAA"}
@@ -0,0 +1 @@
1
+ export default function LayerHeaderDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { LayerHeader as e } from "../ui/LayerHeader.js";
3
+ import { jsx as t } from "react/jsx-runtime";
4
+ //#region lib/examples/layer-header-demo.tsx
5
+ function n() {
6
+ return /* @__PURE__ */ t("div", {
7
+ className: "border-lightGrey w-full border",
8
+ children: /* @__PURE__ */ t(e, {
9
+ hLevel: 2,
10
+ leftButton: {
11
+ label: "Back",
12
+ icon: "ArrowDefaultLeft",
13
+ onClick: () => {}
14
+ },
15
+ rightButton: {
16
+ label: "Close",
17
+ icon: "CrossDefault",
18
+ onClick: () => {}
19
+ },
20
+ children: "Search filters"
21
+ })
22
+ });
23
+ }
24
+ //#endregion
25
+ export { n as default };
26
+
27
+ //# sourceMappingURL=layer-header-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-header-demo.js","names":[],"sources":["../../lib/examples/layer-header-demo.tsx"],"sourcesContent":["'use client';\n\nimport { LayerHeader } from '@/ui/LayerHeader';\n\nexport default function LayerHeaderDemo() {\n return (\n <div className=\"border-lightGrey w-full border\">\n <LayerHeader\n hLevel={2}\n leftButton={{ label: 'Back', icon: 'ArrowDefaultLeft', onClick: () => {} }}\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: () => {} }}\n >\n Search filters\n </LayerHeader>\n </div>\n );\n}\n"],"mappings":";;;;AAIA,SAAwB,IAAkB;AACxC,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,QAAQ;GACR,YAAY;IAAE,OAAO;IAAQ,MAAM;IAAoB,eAAe;IAAI;GAC1E,aAAa;IAAE,OAAO;IAAS,MAAM;IAAgB,eAAe;IAAI;aACzE;GAEa,CAAA;EACV,CAAA"}
@@ -0,0 +1 @@
1
+ export default function LayerNestedDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,51 @@
1
+ "use client";
2
+ import { Button as e } from "../ui/buttons/Button.js";
3
+ import { t } from "../chunks/Layer.js";
4
+ import { useState as n } from "react";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ //#region lib/examples/layer-nested-demo.tsx
7
+ function a() {
8
+ let [a, o] = n(!1), [s, c] = n(!1), l = () => o(!1), u = () => c(!1);
9
+ return /* @__PURE__ */ i("div", { children: [
10
+ /* @__PURE__ */ r(e, {
11
+ onClick: () => o(!0),
12
+ children: "Filters"
13
+ }),
14
+ /* @__PURE__ */ r(t, {
15
+ heading: "Filters",
16
+ isOpen: a,
17
+ onClose: l,
18
+ rightButton: {
19
+ label: "Close",
20
+ icon: "CrossDefault",
21
+ onClick: l
22
+ },
23
+ children: /* @__PURE__ */ i("div", {
24
+ className: "space-y-20 p-20",
25
+ children: [/* @__PURE__ */ r("p", { children: "A second layer can open on top of this one." }), /* @__PURE__ */ r(e, {
26
+ onClick: () => c(!0),
27
+ children: "Choose dates"
28
+ })]
29
+ })
30
+ }),
31
+ /* @__PURE__ */ r(t, {
32
+ heading: "Dates",
33
+ hLevel: 2,
34
+ isOpen: s,
35
+ onClose: u,
36
+ leftButton: {
37
+ label: "Back to filters",
38
+ icon: "ArrowDefaultLeft",
39
+ onClick: u
40
+ },
41
+ children: /* @__PURE__ */ r("div", {
42
+ className: "p-20",
43
+ children: /* @__PURE__ */ r("p", { children: "Escape closes this layer only, and returns to the filters." })
44
+ })
45
+ })
46
+ ] });
47
+ }
48
+ //#endregion
49
+ export { a as default };
50
+
51
+ //# sourceMappingURL=layer-nested-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-nested-demo.js","names":[],"sources":["../../lib/examples/layer-nested-demo.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Layer } from '@/ui/Layer';\nimport { Button } from '@/ui/buttons/Button';\n\nexport default function LayerNestedDemo() {\n const [isFiltersOpen, setIsFiltersOpen] = useState(false);\n const [isDatesOpen, setIsDatesOpen] = useState(false);\n\n const closeFilters = () => setIsFiltersOpen(false);\n const closeDates = () => setIsDatesOpen(false);\n\n return (\n <div>\n <Button onClick={() => setIsFiltersOpen(true)}>Filters</Button>\n <Layer\n heading=\"Filters\"\n isOpen={isFiltersOpen}\n onClose={closeFilters}\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: closeFilters }}\n >\n <div className=\"space-y-20 p-20\">\n <p>A second layer can open on top of this one.</p>\n <Button onClick={() => setIsDatesOpen(true)}>Choose dates</Button>\n </div>\n </Layer>\n <Layer\n heading=\"Dates\"\n hLevel={2}\n isOpen={isDatesOpen}\n onClose={closeDates}\n leftButton={{ label: 'Back to filters', icon: 'ArrowDefaultLeft', onClick: closeDates }}\n >\n <div className=\"p-20\">\n <p>Escape closes this layer only, and returns to the filters.</p>\n </div>\n </Layer>\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAwB,IAAkB;CACxC,IAAM,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAa,KAAkB,EAAS,GAAM,EAE/C,UAAqB,EAAiB,GAAM,EAC5C,UAAmB,EAAe,GAAM;AAE9C,QACE,kBAAC,OAAD,EAAA,UAAA;EACE,kBAAC,GAAD;GAAQ,eAAe,EAAiB,GAAK;aAAE;GAAgB,CAAA;EAC/D,kBAAC,GAAD;GACE,SAAQ;GACR,QAAQ;GACR,SAAS;GACT,aAAa;IAAE,OAAO;IAAS,MAAM;IAAgB,SAAS;IAAc;aAE5E,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD,EAAA,UAAG,+CAA+C,CAAA,EAClD,kBAAC,GAAD;KAAQ,eAAe,EAAe,GAAK;eAAE;KAAqB,CAAA,CAAA;;GAE9D,CAAA;EACR,kBAAC,GAAD;GACE,SAAQ;GACR,QAAQ;GACR,QAAQ;GACR,SAAS;GACT,YAAY;IAAE,OAAO;IAAmB,MAAM;IAAoB,SAAS;IAAY;aAEvF,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,KAAD,EAAA,UAAG,8DAA8D,CAAA;IAC7D,CAAA;GACA,CAAA;EACJ,EAAA,CAAA"}
@@ -0,0 +1 @@
1
+ export default function LayerPinnedDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { Button as e } from "../ui/buttons/Button.js";
3
+ import { t } from "../chunks/Layer.js";
4
+ import { useState as n } from "react";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ //#region lib/examples/layer-pinned-demo.tsx
7
+ function a() {
8
+ let [a, o] = n(!1), s = () => o(!1);
9
+ return /* @__PURE__ */ i("div", { children: [/* @__PURE__ */ r(e, {
10
+ onClick: () => o(!0),
11
+ icon: "Search",
12
+ children: "Search a resort"
13
+ }), /* @__PURE__ */ r(t, {
14
+ heading: "Search",
15
+ isOpen: a,
16
+ onClose: s,
17
+ pinToVisualViewport: !0,
18
+ rightButton: {
19
+ label: "Close",
20
+ icon: "CrossDefault",
21
+ onClick: s
22
+ },
23
+ children: /* @__PURE__ */ r("div", {
24
+ className: "p-20",
25
+ children: /* @__PURE__ */ r("input", {
26
+ "aria-label": "Destination",
27
+ className: "w-full rounded-pill border border-black px-20 py-12",
28
+ placeholder: "Where do you want to go?"
29
+ })
30
+ })
31
+ })] });
32
+ }
33
+ //#endregion
34
+ export { a as default };
35
+
36
+ //# sourceMappingURL=layer-pinned-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-pinned-demo.js","names":[],"sources":["../../lib/examples/layer-pinned-demo.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Layer } from '@/ui/Layer';\nimport { Button } from '@/ui/buttons/Button';\n\nexport default function LayerPinnedDemo() {\n const [isOpen, setIsOpen] = useState(false);\n const close = () => setIsOpen(false);\n\n return (\n <div>\n <Button onClick={() => setIsOpen(true)} icon=\"Search\">\n Search a resort\n </Button>\n <Layer\n heading=\"Search\"\n isOpen={isOpen}\n onClose={close}\n pinToVisualViewport\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: close }}\n >\n <div className=\"p-20\">\n <input\n aria-label=\"Destination\"\n className=\"w-full rounded-pill border border-black px-20 py-12\"\n placeholder=\"Where do you want to go?\"\n />\n </div>\n </Layer>\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAwB,IAAkB;CACxC,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,UAAc,EAAU,GAAM;AAEpC,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAQ,eAAe,EAAU,GAAK;EAAE,MAAK;YAAS;EAE7C,CAAA,EACT,kBAAC,GAAD;EACE,SAAQ;EACA;EACR,SAAS;EACT,qBAAA;EACA,aAAa;GAAE,OAAO;GAAS,MAAM;GAAgB,SAAS;GAAO;YAErE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,SAAD;IACE,cAAW;IACX,WAAU;IACV,aAAY;IACZ,CAAA;GACE,CAAA;EACA,CAAA,CACJ,EAAA,CAAA"}
@@ -0,0 +1 @@
1
+ export default function LayerScaleDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { Button as e } from "../ui/buttons/Button.js";
3
+ import { t } from "../chunks/Layer.js";
4
+ import { useRef as n, useState as r } from "react";
5
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ //#region lib/examples/layer-scale-demo.tsx
7
+ function o() {
8
+ let [o, s] = r(!1), c = n(null), l = () => s(!1);
9
+ return /* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i(e, {
10
+ ref: c,
11
+ onClick: () => s(!0),
12
+ icon: "ArrowDefaultRight",
13
+ children: "See the gallery"
14
+ }), /* @__PURE__ */ i(t, {
15
+ animation: "scale",
16
+ origin: c,
17
+ heading: "Gallery",
18
+ isOpen: o,
19
+ onClose: l,
20
+ rightButton: {
21
+ label: "Close",
22
+ icon: "CrossDefault",
23
+ onClick: l
24
+ },
25
+ children: /* @__PURE__ */ i("div", {
26
+ className: "grid grid-cols-2 gap-8 p-20 md:grid-cols-3",
27
+ children: Array.from({ length: 9 }, (e, t) => /* @__PURE__ */ i("div", { className: "bg-lightSand rounded-16 aspect-square" }, t))
28
+ })
29
+ })] });
30
+ }
31
+ //#endregion
32
+ export { o as default };
33
+
34
+ //# sourceMappingURL=layer-scale-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-scale-demo.js","names":[],"sources":["../../lib/examples/layer-scale-demo.tsx"],"sourcesContent":["'use client';\n\nimport { useRef, useState } from 'react';\nimport { Layer } from '@/ui/Layer';\nimport { Button } from '@/ui/buttons/Button';\n\nexport default function LayerScaleDemo() {\n const [isOpen, setIsOpen] = useState(false);\n const trigger = useRef<HTMLButtonElement>(null);\n const close = () => setIsOpen(false);\n\n return (\n <div>\n <Button ref={trigger} onClick={() => setIsOpen(true)} icon=\"ArrowDefaultRight\">\n See the gallery\n </Button>\n <Layer\n animation=\"scale\"\n origin={trigger}\n heading=\"Gallery\"\n isOpen={isOpen}\n onClose={close}\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: close }}\n >\n <div className=\"grid grid-cols-2 gap-8 p-20 md:grid-cols-3\">\n {Array.from({ length: 9 }, (_, index) => (\n <div key={index} className=\"bg-lightSand rounded-16 aspect-square\" />\n ))}\n </div>\n </Layer>\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAwB,IAAiB;CACvC,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,IAAU,EAA0B,KAAK,EACzC,UAAc,EAAU,GAAM;AAEpC,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAQ,KAAK;EAAS,eAAe,EAAU,GAAK;EAAE,MAAK;YAAoB;EAEtE,CAAA,EACT,kBAAC,GAAD;EACE,WAAU;EACV,QAAQ;EACR,SAAQ;EACA;EACR,SAAS;EACT,aAAa;GAAE,OAAO;GAAS,MAAM;GAAgB,SAAS;GAAO;YAErE,kBAAC,OAAD;GAAK,WAAU;aACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,GAAG,MAC7B,kBAAC,OAAD,EAAiB,WAAU,yCAA0C,EAA3D,EAA2D,CAAA;GAEnE,CAAA;EACA,CAAA,CACJ,EAAA,CAAA"}
@@ -0,0 +1 @@
1
+ export default function LayerUseLayerDemo(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { Button as e } from "../ui/buttons/Button.js";
3
+ import { t } from "../chunks/Layer.js";
4
+ import { useLayer as n } from "../ui/hooks/useLayer.js";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ //#region lib/examples/layer-use-layer-demo.tsx
7
+ function a() {
8
+ let { close: a, isOpen: o, open: s } = n({
9
+ onClose: () => console.log("Layer closed"),
10
+ onOpen: () => console.log("Layer opened")
11
+ });
12
+ return /* @__PURE__ */ i("div", { children: [/* @__PURE__ */ r(e, {
13
+ onClick: s,
14
+ children: "Open with useLayer"
15
+ }), /* @__PURE__ */ r(t, {
16
+ heading: "Driven by useLayer",
17
+ isOpen: o,
18
+ onClose: a,
19
+ rightButton: {
20
+ label: "Close",
21
+ icon: "CrossDefault",
22
+ onClick: a
23
+ },
24
+ children: /* @__PURE__ */ r("div", {
25
+ className: "p-20",
26
+ children: /* @__PURE__ */ r("p", { children: "`open` and `close` keep the same identity across renders." })
27
+ })
28
+ })] });
29
+ }
30
+ //#endregion
31
+ export { a as default };
32
+
33
+ //# sourceMappingURL=layer-use-layer-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-use-layer-demo.js","names":[],"sources":["../../lib/examples/layer-use-layer-demo.tsx"],"sourcesContent":["'use client';\n\nimport { Layer } from '@/ui/Layer';\nimport { Button } from '@/ui/buttons/Button';\nimport { useLayer } from '@/ui/hooks/useLayer';\n\nexport default function LayerUseLayerDemo() {\n const { close, isOpen, open } = useLayer({\n onClose: () => console.log('Layer closed'),\n onOpen: () => console.log('Layer opened'),\n });\n\n return (\n <div>\n <Button onClick={open}>Open with useLayer</Button>\n <Layer\n heading=\"Driven by useLayer\"\n isOpen={isOpen}\n onClose={close}\n rightButton={{ label: 'Close', icon: 'CrossDefault', onClick: close }}\n >\n <div className=\"p-20\">\n <p>`open` and `close` keep the same identity across renders.</p>\n </div>\n </Layer>\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAwB,IAAoB;CAC1C,IAAM,EAAE,UAAO,WAAQ,YAAS,EAAS;EACvC,eAAe,QAAQ,IAAI,eAAe;EAC1C,cAAc,QAAQ,IAAI,eAAA;EAC3B,CAAC;AAEF,QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAQ,SAAS;YAAM;EAA2B,CAAA,EAClD,kBAAC,GAAD;EACE,SAAQ;EACA;EACR,SAAS;EACT,aAAa;GAAE,OAAO;GAAS,MAAM;GAAgB,SAAS;GAAO;YAErE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,KAAD,EAAA,UAAG,6DAA6D,CAAA;GAC5D,CAAA;EACA,CAAA,CACJ,EAAA,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clubmed/trident-ui",
3
- "version": "2.1.0-beta.4",
3
+ "version": "2.1.0-beta.5",
4
4
  "type": "module",
5
5
  "description": "Shared ClubMed React UI components",
6
6
  "keywords": [
@@ -87,6 +87,7 @@
87
87
  "embla-carousel-react": "^8.6.0",
88
88
  "embla-carousel-wheel-gestures": "^8.1.0",
89
89
  "react-day-picker": ">=8.10.0",
90
+ "react-focus-on": ">=3.10.2",
90
91
  "react-hot-toast": ">=2.4.1",
91
92
  "react-transition-state": ">=2.3.2",
92
93
  "react-use-measure": ">=2.1.1",
package/ui/Backdrop.d.ts CHANGED
@@ -19,5 +19,10 @@ export interface BackdropProps extends ComponentProps<'div'> {
19
19
  * Target ID for the Portal component
20
20
  */
21
21
  target?: ComponentProps<typeof Portal>['target'];
22
+ /**
23
+ * Whether backdrop click should trigger onClose
24
+ * @default true
25
+ */
26
+ dismissable?: boolean;
22
27
  }
23
28
  export declare const Backdrop: FunctionComponent<PropsWithChildren<BackdropProps>>;
package/ui/Backdrop.js CHANGED
@@ -1,2 +1,54 @@
1
- import { t as e } from "../chunks/Backdrop.js";
2
- export { e as Backdrop };
1
+ import { t as e } from "../chunks/clsx.js";
2
+ import { t } from "../chunks/useTransitionState.js";
3
+ import { Portal as n } from "./Portal.js";
4
+ import { useEffect as r } from "react";
5
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ //#region lib/ui/Backdrop.tsx
7
+ var o = ({ children: o, className: s = "flex justify-center", onClose: c, isVisible: l, target: u = "backdrop", sweep: d = !1, dismissable: f = !0, ...p }) => {
8
+ let [m, h] = t({
9
+ timeout: {
10
+ enter: 0,
11
+ exit: 500
12
+ },
13
+ mountOnEnter: !0,
14
+ unmountOnExit: !0,
15
+ preEnter: !0
16
+ }), { status: g, isMounted: _ } = m;
17
+ r(() => {
18
+ h(l);
19
+ }, [l, h]), r(() => {
20
+ if (!_ || !f || !c) return;
21
+ let e = (e) => {
22
+ e.key === "Escape" && c(e);
23
+ };
24
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
25
+ }, [
26
+ _,
27
+ f,
28
+ c
29
+ ]);
30
+ let v = g === "preEnter" || g === "exiting";
31
+ return /* @__PURE__ */ i(n, {
32
+ target: u,
33
+ children: _ && /* @__PURE__ */ a("div", {
34
+ ...p,
35
+ role: "presentation",
36
+ className: e(s, "fixed inset-0 isolate items-center"),
37
+ children: [/* @__PURE__ */ i("button", {
38
+ "aria-hidden": "true",
39
+ className: e("absolute inset-0 -z-1 transition-all duration-500 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2", {
40
+ "bg-white/80 backdrop-blur": !v,
41
+ "bg-white/0 backdrop-blur-none": v,
42
+ "-translate-x-full": d && (g === "preEnter" || g === "entering"),
43
+ "translate-x-full": d && g === "exiting"
44
+ }),
45
+ onClick: f ? c : void 0,
46
+ type: "button"
47
+ }), o]
48
+ })
49
+ });
50
+ };
51
+ //#endregion
52
+ export { o as Backdrop };
53
+
54
+ //# sourceMappingURL=Backdrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Backdrop.js","names":[],"sources":["../../lib/ui/Backdrop.tsx"],"sourcesContent":["import {\n type ComponentProps,\n type FunctionComponent,\n type MouseEvent,\n type PropsWithChildren,\n useEffect,\n} from 'react';\nimport clsx from 'clsx';\nimport { useTransitionState } from 'react-transition-state';\nimport { Portal } from './Portal';\n\nexport interface BackdropProps extends ComponentProps<'div'> {\n /**\n * On close\n * @param event\n */\n onClose?: (event: MouseEvent<HTMLButtonElement>) => void;\n /**\n * Is visible\n */\n isVisible?: boolean;\n /**\n * Sweep Mode™\n * (makes it appear from the sides instead of from everywhere)\n */\n sweep?: boolean;\n /**\n * Target ID for the Portal component\n */\n target?: ComponentProps<typeof Portal>['target'];\n /**\n * Whether backdrop click should trigger onClose\n * @default true\n */\n dismissable?: boolean;\n}\n\nexport const Backdrop: FunctionComponent<PropsWithChildren<BackdropProps>> = ({\n children,\n className = 'flex justify-center',\n onClose,\n isVisible,\n target = 'backdrop',\n sweep = false,\n dismissable = true,\n ...attrs\n}) => {\n const [state, toggle] = useTransitionState({\n timeout: { enter: 0, exit: 500 },\n mountOnEnter: true,\n unmountOnExit: true,\n preEnter: true,\n });\n\n const { status, isMounted } = state;\n\n useEffect(() => {\n toggle(isVisible);\n }, [isVisible, toggle]);\n\n useEffect(() => {\n if (!isMounted || !dismissable || !onClose) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose(event as unknown as MouseEvent<HTMLButtonElement>);\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isMounted, dismissable, onClose]);\n\n const animated = status === 'preEnter' || status === 'exiting';\n\n return (\n <Portal target={target}>\n {isMounted && (\n <div\n {...attrs}\n role=\"presentation\"\n className={clsx(className, 'fixed inset-0 isolate items-center')}\n >\n <button\n aria-hidden=\"true\"\n className={clsx(\n 'absolute inset-0 -z-1 transition-all duration-500 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2',\n {\n 'bg-white/80 backdrop-blur': !animated,\n 'bg-white/0 backdrop-blur-none': animated,\n '-translate-x-full': sweep && (status === 'preEnter' || status === 'entering'),\n 'translate-x-full': sweep && status === 'exiting',\n },\n )}\n onClick={dismissable ? onClose : undefined}\n type=\"button\"\n />\n {children}\n </div>\n )}\n </Portal>\n );\n};\n"],"mappings":";;;;;;AAqCA,IAAa,KAAiE,EAC5E,aACA,eAAY,uBACZ,YACA,cACA,YAAS,YACT,WAAQ,IACR,iBAAc,IACd,GAAG,QACC;CACJ,IAAM,CAAC,GAAO,KAAU,EAAmB;EACzC,SAAS;GAAE,OAAO;GAAG,MAAM;GAAK;EAChC,cAAc;EACd,eAAe;EACf,UAAU;EACX,CAAC,EAEI,EAAE,WAAQ,iBAAc;AAM9B,CAJA,QAAgB;AACd,IAAO,EAAU;IAChB,CAAC,GAAW,EAAO,CAAC,EAEvB,QAAgB;AACd,MAAI,CAAC,KAAa,CAAC,KAAe,CAAC,EAAS;EAE5C,IAAM,KAAgB,MAAyB;AAC7C,GAAI,EAAM,QAAQ,YAChB,EAAQ,EAAkD;;AAK9D,SADA,SAAS,iBAAiB,WAAW,EAAa,QACrC,SAAS,oBAAoB,WAAW,EAAa;IACjE;EAAC;EAAW;EAAa;EAAQ,CAAC;CAErC,IAAM,IAAW,MAAW,cAAc,MAAW;AAErD,QACE,kBAAC,GAAD;EAAgB;YACb,KACC,kBAAC,OAAD;GACE,GAAI;GACJ,MAAK;GACL,WAAW,EAAK,GAAW,qCAAqC;aAHlE,CAKE,kBAAC,UAAD;IACE,eAAY;IACZ,WAAW,EACT,4IACA;KACE,6BAA6B,CAAC;KAC9B,iCAAiC;KACjC,qBAAqB,MAAU,MAAW,cAAc,MAAW;KACnE,oBAAoB,KAAS,MAAW;KACzC,CACF;IACD,SAAS,IAAc,IAAU,KAAA;IACjC,MAAK;IACL,CAAA,EACD,EACG;;EAED,CAAA"}
package/ui/Layer.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ import { ComponentProps, FunctionComponent, ReactNode, RefObject } from 'react';
2
+ import { FocusOn } from 'react-focus-on';
3
+ import { LayerHeaderProps } from './LayerHeader';
4
+ import { PortalProps } from './Portal';
5
+ declare const ANIMATIONS: {
6
+ readonly scale: {
7
+ readonly from: "scale-[0.167] opacity-0";
8
+ readonly to: "scale-100 opacity-100";
9
+ };
10
+ readonly slide: {
11
+ readonly from: "translate-x-full rtl:-translate-x-full opacity-0";
12
+ readonly to: "translate-x-0 opacity-100";
13
+ };
14
+ };
15
+ export interface LayerProps extends ComponentProps<'div'> {
16
+ /**
17
+ * How the layer enters and leaves the screen
18
+ * @default 'slide'
19
+ */
20
+ animation?: keyof typeof ANIMATIONS;
21
+ /**
22
+ * Traps the focus, locks the page scroll and closes on Escape / outside click while open
23
+ * @default true
24
+ */
25
+ hasFocusTrap?: boolean;
26
+ /**
27
+ * Keeps pinch zoom available while the page scroll is locked
28
+ * @default true
29
+ */
30
+ hasPinchZoom?: ComponentProps<typeof FocusOn>['allowPinchZoom'];
31
+ /**
32
+ * Content of the header heading, also used as the accessible name of the dialog
33
+ */
34
+ heading: ReactNode;
35
+ /**
36
+ * Level of the header heading tag
37
+ * @default 1
38
+ */
39
+ hLevel?: LayerHeaderProps['hLevel'];
40
+ /**
41
+ * Whether the layer is displayed
42
+ */
43
+ isOpen: boolean;
44
+ /**
45
+ * Round button pinned to the inline start of the header
46
+ */
47
+ leftButton?: LayerHeaderProps['leftButton'];
48
+ /**
49
+ * Called on Escape or on a click outside the layer
50
+ */
51
+ onClose: () => void;
52
+ /**
53
+ * Element the `scale` animation grows from and shrinks back to
54
+ */
55
+ origin?: RefObject<HTMLElement | null>;
56
+ /**
57
+ * Pins the layer to the visual viewport, so the iOS keyboard does not push it off-screen
58
+ * @default false
59
+ */
60
+ pinToVisualViewport?: boolean;
61
+ /**
62
+ * Round button pinned to the inline end of the header
63
+ */
64
+ rightButton?: LayerHeaderProps['rightButton'];
65
+ /**
66
+ * Id of the element the layer is rendered in, created at the end of the `body` when missing
67
+ * @default 'portal'
68
+ */
69
+ target?: PortalProps['target'];
70
+ }
71
+ export declare const Layer: FunctionComponent<LayerProps>;
72
+ export {};
package/ui/Layer.js ADDED
@@ -0,0 +1,2 @@
1
+ import { t as e } from "../chunks/Layer.js";
2
+ export { e as Layer };
@@ -0,0 +1,33 @@
1
+ import { ComponentProps, FunctionComponent, MouseEventHandler } from 'react';
2
+ import { ButtonProps as Btn } from './buttons/Button.type';
3
+ import { HeadingProps } from './heading/Heading';
4
+ export interface LayerHeaderButtonProps extends Omit<ComponentProps<'button'>, 'color' | 'onClick'>, Omit<Btn, 'variant' | 'theme'> {
5
+ /**
6
+ * Icon displayed in the round button
7
+ */
8
+ icon: Exclude<Btn['icon'], undefined>;
9
+ /**
10
+ * Accessible name of the button (rendered as `aria-label`)
11
+ */
12
+ label: string;
13
+ onClick: MouseEventHandler<HTMLButtonElement>;
14
+ }
15
+ export interface LayerHeaderProps extends ComponentProps<'header'> {
16
+ /**
17
+ * Overrides the level announced to assistive technologies, without changing the tag
18
+ */
19
+ hAriaLevel?: number;
20
+ /**
21
+ * Level of the heading tag (h1 to h6)
22
+ */
23
+ hLevel?: HeadingProps['level'];
24
+ /**
25
+ * Round button pinned to the inline start of the header (e.g. a "back" arrow)
26
+ */
27
+ leftButton?: LayerHeaderButtonProps;
28
+ /**
29
+ * Round button pinned to the inline end of the header (e.g. a "close" cross)
30
+ */
31
+ rightButton?: LayerHeaderButtonProps;
32
+ }
33
+ export declare const LayerHeader: FunctionComponent<LayerHeaderProps>;