@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.
- package/chunks/Layer.js +2022 -0
- package/chunks/Layer.js.map +1 -0
- package/chunks/useTransitionState.js +69 -0
- package/chunks/useTransitionState.js.map +1 -0
- package/examples/backdrop-demo.js +1 -1
- package/examples/layer-buttons-demo.d.ts +1 -0
- package/examples/layer-buttons-demo.js +43 -0
- package/examples/layer-buttons-demo.js.map +1 -0
- package/examples/layer-demo.d.ts +1 -0
- package/examples/layer-demo.js +30 -0
- package/examples/layer-demo.js.map +1 -0
- package/examples/layer-header-demo.d.ts +1 -0
- package/examples/layer-header-demo.js +27 -0
- package/examples/layer-header-demo.js.map +1 -0
- package/examples/layer-nested-demo.d.ts +1 -0
- package/examples/layer-nested-demo.js +51 -0
- package/examples/layer-nested-demo.js.map +1 -0
- package/examples/layer-pinned-demo.d.ts +1 -0
- package/examples/layer-pinned-demo.js +36 -0
- package/examples/layer-pinned-demo.js.map +1 -0
- package/examples/layer-scale-demo.d.ts +1 -0
- package/examples/layer-scale-demo.js +34 -0
- package/examples/layer-scale-demo.js.map +1 -0
- package/examples/layer-use-layer-demo.d.ts +1 -0
- package/examples/layer-use-layer-demo.js +33 -0
- package/examples/layer-use-layer-demo.js.map +1 -0
- package/package.json +2 -1
- package/ui/Backdrop.d.ts +5 -0
- package/ui/Backdrop.js +54 -2
- package/ui/Backdrop.js.map +1 -0
- package/ui/Layer.d.ts +72 -0
- package/ui/Layer.js +2 -0
- package/ui/LayerHeader.d.ts +33 -0
- package/ui/LayerHeader.js +45 -0
- package/ui/LayerHeader.js.map +1 -0
- package/ui/Loader.js +2 -1
- package/ui/Loader.js.map +1 -1
- package/ui/Popin.d.ts +6 -0
- package/ui/Popin.js +11 -10
- package/ui/Popin.js.map +1 -1
- package/ui/hooks/useIsomorphicLayoutEffect.d.ts +6 -0
- package/ui/hooks/useIsomorphicLayoutEffect.js +7 -0
- package/ui/hooks/useIsomorphicLayoutEffect.js.map +1 -0
- package/ui/hooks/useLayer.d.ts +13 -0
- package/ui/hooks/useLayer.js +31 -0
- package/ui/hooks/useLayer.js.map +1 -0
- package/ui/hooks/useTransitionState.d.ts +7 -0
- package/ui/hooks/useTransitionState.js +15 -0
- package/ui/hooks/useTransitionState.js.map +1 -0
- package/ui/hooks/useVisualViewportBox.d.ts +7 -0
- package/ui/hooks/useVisualViewportBox.js +22 -0
- package/ui/hooks/useVisualViewportBox.js.map +1 -0
- package/chunks/Backdrop.js +0 -105
- 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 "../
|
|
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.
|
|
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/
|
|
2
|
-
|
|
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,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>;
|