asma-ui-core 3.89.0 → 3.90.0

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 (27) hide show
  1. package/Readme.md +56 -10
  2. package/dist/asma-ui-core.css +1 -1
  3. package/dist/components/utils/bottom-sheet/StyledBottomSheet.js +137 -0
  4. package/dist/components/utils/bottom-sheet/StyledBottomSheet.module.js +4 -0
  5. package/dist/components/utils/bottom-sheet/formatResultsLabel.js +4 -0
  6. package/dist/components/utils/bottom-sheet/useDragToDismiss.hook.js +40 -0
  7. package/dist/components/utils/popover/PopoverSheet.js +165 -0
  8. package/dist/hooks/useBodyScrollLock.hook.js +13 -0
  9. package/dist/hooks/useDebouncedValue.hook.js +15 -0
  10. package/dist/hooks/useMediaQuery.hook.js +10 -9
  11. package/dist/index.js +184 -180
  12. package/dist/src/components/utils/bottom-sheet/StyledBottomSheet.d.ts +59 -0
  13. package/dist/src/components/utils/bottom-sheet/formatResultsLabel.d.ts +9 -0
  14. package/dist/src/components/utils/bottom-sheet/formatResultsLabel.test.d.ts +1 -0
  15. package/dist/src/components/utils/bottom-sheet/index.d.ts +2 -0
  16. package/dist/src/components/utils/bottom-sheet/story/BottomSheetCases.d.ts +1 -0
  17. package/dist/src/components/utils/bottom-sheet/story/BottomSheetDemo.d.ts +22 -0
  18. package/dist/src/components/utils/bottom-sheet/useDragToDismiss.hook.d.ts +22 -0
  19. package/dist/src/components/utils/popover/PopoverAnatomy.d.ts +1 -1
  20. package/dist/src/components/utils/popover/{StyledPopoverV2.d.ts → PopoverSheet.d.ts} +12 -2
  21. package/dist/src/components/utils/popover/index.d.ts +1 -1
  22. package/dist/src/hooks/useBodyScrollLock.hook.d.ts +7 -0
  23. package/dist/src/hooks/useDebouncedValue.hook.d.ts +2 -0
  24. package/dist/src/hooks/useMediaQuery.hook.d.ts +2 -0
  25. package/dist/src/index.d.ts +1 -0
  26. package/package.json +1 -1
  27. package/dist/components/utils/popover/StyledPopoverV2.js +0 -140
@@ -0,0 +1,137 @@
1
+ import { cn as n } from "../../../helpers/cn.js";
2
+ import { CloseIcon as A } from "../../icons/close-icon/CloseIcon.js";
3
+ import { IndeterminateIcon as H } from "../../icons/indeterminate-icon/IndeterminateIcon.js";
4
+ import { registerOpenModalDialog as q } from "../../../hooks/useTopLayer.hook.js";
5
+ import { StyledButton as I } from "../../inputs/button/StyledButton.js";
6
+ import { useShortViewportMediaQuery as G } from "../../../hooks/useMediaQuery.hook.js";
7
+ import { useDebouncedValue as P } from "../../../hooks/useDebouncedValue.hook.js";
8
+ import { useFocusTrap as Q } from "../../../hooks/useFocusTrap.hook.js";
9
+ import { formatResultsLabel as Y } from "./formatResultsLabel.js";
10
+ import { useBodyScrollLock as z } from "../../../hooks/useBodyScrollLock.hook.js";
11
+ import J from "./StyledBottomSheet.module.js";
12
+ import { useDragToDismiss as K } from "./useDragToDismiss.hook.js";
13
+ import { useEffect as W, useId as X, useLayoutEffect as Z, useRef as d, useState as ee } from "react";
14
+ import { jsx as t, jsxs as i } from "react/jsx-runtime";
15
+ var te = 500, xe = ({ dataTest: r, id: D, open: a, onClose: o, title: s, ariaLabel: L, children: j, viewResultsAction: p, resetAction: F, footerActions: M, resultCount: h, closeLabel: _ = "Lukk", className: C }) => {
16
+ const b = X(), m = d(null), x = d(null), v = d(null), [u, y] = ee(!1), O = G(), g = d(o);
17
+ W(() => {
18
+ g.current = o;
19
+ }, [o]);
20
+ const { dragHandleProps: $, dragOffset: w } = K(x, () => {
21
+ g.current("drag");
22
+ });
23
+ z(a), Q(a, m), Z(() => {
24
+ const e = m.current;
25
+ if (!a || !e) return;
26
+ v.current = document.activeElement instanceof HTMLElement ? document.activeElement : null, e.open || e.showModal(), e.focus({ preventScroll: !0 });
27
+ const U = requestAnimationFrame(() => {
28
+ y(!0);
29
+ }), V = q(e);
30
+ return () => {
31
+ cancelAnimationFrame(U), V(), y(!1), e.open && e.close();
32
+ const E = v.current;
33
+ E?.isConnected && E.focus({ preventScroll: !0 });
34
+ };
35
+ }, [a]);
36
+ const S = Y(P(h, te));
37
+ if (!a) return null;
38
+ const T = { close: () => {
39
+ o("action");
40
+ } }, l = (e) => typeof e == "function" ? e(T) : e, N = h !== void 0, f = p !== void 0 ? l(p) : N ? /* @__PURE__ */ t(I, {
41
+ dataTest: `${r}-view-results`,
42
+ type: "button",
43
+ variant: "text",
44
+ onClick: () => {
45
+ o("viewResults");
46
+ },
47
+ children: S
48
+ }) : void 0, k = l(F), c = l(M), R = !!(f ?? k), B = w > 0;
49
+ return /* @__PURE__ */ i("dialog", {
50
+ ref: m,
51
+ id: D,
52
+ tabIndex: -1,
53
+ "aria-modal": "true",
54
+ "aria-labelledby": s ? b : void 0,
55
+ "aria-label": s ? void 0 : L,
56
+ "data-test": r,
57
+ "data-testid": r,
58
+ onCancel: (e) => {
59
+ e.preventDefault(), o("escape");
60
+ },
61
+ className: n(J.StyledBottomSheet, "fixed inset-0 m-0 h-full max-h-none w-full max-w-none flex-col items-center justify-end overflow-hidden border-0 bg-transparent p-0 outline-none open:flex"),
62
+ children: [/* @__PURE__ */ t("div", {
63
+ "aria-hidden": "true",
64
+ "data-testid": `${r}-scrim`,
65
+ onClick: () => {
66
+ o("scrim");
67
+ },
68
+ className: n("absolute inset-0 bg-[#626e7eb2] transition-opacity duration-[250ms] ease-out motion-reduce:duration-150", u ? "opacity-100" : "opacity-0")
69
+ }), /* @__PURE__ */ i("div", {
70
+ ref: x,
71
+ "data-state": u ? "open" : "closed",
72
+ style: B ? { transform: `translateY(${w}px)` } : void 0,
73
+ className: n("relative box-border flex w-full max-w-[640px] flex-col border border-solid border-delta-300 bg-white text-delta-700 outline-none", O ? "h-full max-h-none rounded-none" : "max-h-[90dvh] rounded-t-[28px]", !B && ["ease-out motion-safe:transition-transform motion-safe:duration-[250ms] motion-reduce:transition-opacity motion-reduce:duration-150", u ? "translate-y-0 opacity-100" : "motion-safe:translate-y-full motion-reduce:opacity-0"], C),
74
+ children: [
75
+ /* @__PURE__ */ i("div", {
76
+ className: "border-b-solid shrink-0 border-b border-delta-200 pb-2",
77
+ children: [/* @__PURE__ */ i("div", {
78
+ ...$,
79
+ className: "relative flex h-12 touch-none items-center gap-2 px-2",
80
+ children: [
81
+ /* @__PURE__ */ t("div", { className: "min-w-0 flex-1" }),
82
+ /* @__PURE__ */ t(I, {
83
+ dataTest: `${r}-close`,
84
+ variant: "textGray",
85
+ type: "button",
86
+ "aria-label": _,
87
+ onClick: () => {
88
+ o("closeButton");
89
+ },
90
+ startIcon: /* @__PURE__ */ t(A, {
91
+ width: 24,
92
+ height: 24
93
+ })
94
+ }),
95
+ /* @__PURE__ */ t(H, {
96
+ "aria-hidden": "true",
97
+ focusable: "false",
98
+ width: 24,
99
+ height: 24,
100
+ className: "pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-delta-800"
101
+ })
102
+ ]
103
+ }), s && /* @__PURE__ */ t("div", {
104
+ id: b,
105
+ className: "truncate px-4 text-lg font-semibold leading-7 text-delta-800",
106
+ children: s
107
+ })]
108
+ }),
109
+ /* @__PURE__ */ t("div", {
110
+ className: n("flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto overscroll-contain pl-4 pr-2 pt-2", R || c ? "pb-2" : "pb-[max(0.5rem,env(safe-area-inset-bottom))]"),
111
+ children: l(j)
112
+ }),
113
+ R && /* @__PURE__ */ i("div", {
114
+ className: n("border-t-solid flex shrink-0 items-start border-t border-delta-200 bg-white p-1", f ? "justify-between" : "justify-end", !c && "pb-[max(0.25rem,env(safe-area-inset-bottom))]"),
115
+ children: [
116
+ f,
117
+ k,
118
+ N && /* @__PURE__ */ t("span", {
119
+ className: "sr-only",
120
+ role: "status",
121
+ "aria-live": "polite",
122
+ "aria-atomic": "true",
123
+ children: S
124
+ })
125
+ ]
126
+ }),
127
+ c && /* @__PURE__ */ t("div", {
128
+ className: "flex shrink-0 flex-col items-end bg-white p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]",
129
+ children: c
130
+ })
131
+ ]
132
+ })]
133
+ });
134
+ };
135
+ export {
136
+ xe as StyledBottomSheet
137
+ };
@@ -0,0 +1,4 @@
1
+ var t = "_StyledBottomSheet_11e4g_1", e = { StyledBottomSheet: t };
2
+ export {
3
+ e as default
4
+ };
@@ -0,0 +1,4 @@
1
+ var e = 9999, t = (r) => r == null ? "Vis resultater" : r === 0 ? "Ingen treff" : r > e ? `Vis resultater (${e}+)` : `Vis resultater (${r})`;
2
+ export {
3
+ t as formatResultsLabel
4
+ };
@@ -0,0 +1,40 @@
1
+ import { useRef as c, useState as l } from "react";
2
+ var p = 0.3, f = (i, u) => {
3
+ const [a, n] = l(0), e = c(null), o = (r, t) => {
4
+ e.current?.pointerId === r.pointerId && (e.current = null, r.currentTarget.hasPointerCapture(r.pointerId) && r.currentTarget.releasePointerCapture(r.pointerId), n(0), t && u());
5
+ };
6
+ return {
7
+ dragOffset: a,
8
+ dragHandleProps: {
9
+ onPointerDown: (r) => {
10
+ if (r.pointerType === "mouse" && r.button !== 0 || r.target instanceof Element && r.target.closest("button")) return;
11
+ const t = i.current;
12
+ if (t) {
13
+ e.current = {
14
+ pointerId: r.pointerId,
15
+ startY: r.clientY,
16
+ height: t.getBoundingClientRect().height
17
+ };
18
+ try {
19
+ r.currentTarget.setPointerCapture(r.pointerId);
20
+ } catch {
21
+ }
22
+ }
23
+ },
24
+ onPointerMove: (r) => {
25
+ const t = e.current;
26
+ t?.pointerId === r.pointerId && n(Math.max(0, r.clientY - t.startY));
27
+ },
28
+ onPointerUp: (r) => {
29
+ const t = e.current, s = t ? r.clientY - t.startY : 0;
30
+ o(r, t !== null && s > t.height * p);
31
+ },
32
+ onPointerCancel: (r) => {
33
+ o(r, !1);
34
+ }
35
+ }
36
+ };
37
+ };
38
+ export {
39
+ f as useDragToDismiss
40
+ };
@@ -0,0 +1,165 @@
1
+ import { cn as oe } from "../../../helpers/cn.js";
2
+ import { firstTabbable as re } from "../../../helpers/focusable.js";
3
+ import { TOP_LAYER_PROPS as ne, TOP_LAYER_RESET_STYLE as ie, getOpenModalDialogAncestor as se, shouldUsePopoverTopLayer as ae, useTopLayerRef as ce } from "../../../hooks/useTopLayer.hook.js";
4
+ import { StyledButton as le } from "../../inputs/button/StyledButton.js";
5
+ import { useMobileMediaQuery as de } from "../../../hooks/useMediaQuery.hook.js";
6
+ import { useDebouncedValue as ue } from "../../../hooks/useDebouncedValue.hook.js";
7
+ import { useFocusTrap as fe } from "../../../hooks/useFocusTrap.hook.js";
8
+ import { formatResultsLabel as pe } from "../bottom-sheet/formatResultsLabel.js";
9
+ import { StyledBottomSheet as me } from "../bottom-sheet/StyledBottomSheet.js";
10
+ import { PopoverAnatomy as ge } from "./PopoverAnatomy.js";
11
+ import { useCallback as m, useEffect as y, useId as ve, useRef as R, useState as g } from "react";
12
+ import { Fragment as N, jsx as c, jsxs as W } from "react/jsx-runtime";
13
+ import { FloatingPortal as he, autoUpdate as xe, flip as be, offset as Pe, shift as ye, size as Re, useDismiss as _e, useFloating as Ee, useInteractions as Se, useMergeRefs as Te } from "@floating-ui/react";
14
+ var Ae = 240, Me = {
15
+ info: 360,
16
+ action: 400
17
+ }, we = 0.6, B = "calc(100vw - 32px)", je = ({ dataTest: s, renderTrigger: _, variant: E = "info", title: l, children: S, viewResultsAction: T, resetAction: A, footerActions: M, resultCount: v, closeLabel: w = "Lukk", ariaLabel: F, onOpenChange: I, className: O }) => {
18
+ const a = ve(), L = `${a}-title`, [o, X] = g(!1), [H, U] = g(), [Y, $] = g(), d = de(), t = E === "action", j = d && !t, k = d && t, u = m((e) => {
19
+ X(e), I?.(e);
20
+ }, [I]), { refs: h, floatingStyles: q, context: z } = Ee({
21
+ open: o,
22
+ onOpenChange: u,
23
+ placement: "bottom-start",
24
+ strategy: "fixed",
25
+ whileElementsMounted: xe,
26
+ middleware: [
27
+ Pe(8),
28
+ ...j ? [] : [be({ padding: 8 })],
29
+ ye({ padding: 8 }),
30
+ Re({
31
+ padding: 8,
32
+ apply({ availableHeight: e }) {
33
+ $(Math.min(e, Math.round(window.innerHeight * we)));
34
+ }
35
+ })
36
+ ]
37
+ }), { getFloatingProps: V } = Se([_e(z, {
38
+ enabled: !k,
39
+ escapeKey: !0,
40
+ outsidePress: (e) => {
41
+ const i = f.current;
42
+ return !(i && e.target instanceof Node && i.contains(e.target));
43
+ }
44
+ })]), x = ae(H), C = R(null), [r, G] = g(null), K = m((e) => {
45
+ C.current = e, G(e);
46
+ }, []), Q = Te([ce(h.setFloating, x), K]), f = R(null), J = m((e) => {
47
+ f.current = e, h.setReference(e);
48
+ }, [h]), n = m(() => {
49
+ u(!1);
50
+ }, [u]);
51
+ fe(o && t && r !== null, C), y(() => {
52
+ if (!r) return;
53
+ const e = requestAnimationFrame(() => {
54
+ (t ? re(r) : r)?.focus({ preventScroll: !0 });
55
+ });
56
+ return () => {
57
+ cancelAnimationFrame(e);
58
+ };
59
+ }, [r, t]), y(() => {
60
+ if (!r || t) return;
61
+ const e = (i) => {
62
+ const P = i.relatedTarget;
63
+ P instanceof Node && (r.contains(P) || f.current?.contains(P)) || n();
64
+ };
65
+ return r.addEventListener("focusout", e), () => {
66
+ r.removeEventListener("focusout", e);
67
+ };
68
+ }, [
69
+ r,
70
+ t,
71
+ n
72
+ ]);
73
+ const b = R(!1);
74
+ y(() => {
75
+ if (o) {
76
+ b.current = !0;
77
+ return;
78
+ }
79
+ if (!b.current) return;
80
+ b.current = !1;
81
+ const e = f.current;
82
+ if (!e) return;
83
+ const i = requestAnimationFrame(() => {
84
+ document.activeElement === document.body && e.focus();
85
+ });
86
+ return () => {
87
+ cancelAnimationFrame(i);
88
+ };
89
+ }, [o]);
90
+ const D = {
91
+ ref: J,
92
+ isOpen: o,
93
+ triggerProps: {
94
+ onClick: (e) => {
95
+ if (o) {
96
+ n();
97
+ return;
98
+ }
99
+ U(se(e.currentTarget)), u(!0);
100
+ },
101
+ "aria-expanded": o,
102
+ "aria-controls": o ? a : void 0,
103
+ "aria-haspopup": t ? "dialog" : void 0,
104
+ "aria-describedby": !t && o ? a : void 0
105
+ }
106
+ }, p = (e) => typeof e == "function" ? e({ close: n }) : e, Z = ue(v, 500), ee = T ?? (v === void 0 ? void 0 : /* @__PURE__ */ c(le, {
107
+ dataTest: `${s}-view-results`,
108
+ type: "button",
109
+ variant: "text",
110
+ onClick: n,
111
+ children: pe(Z)
112
+ })), te = d ? B : Me[E];
113
+ return k ? /* @__PURE__ */ W(N, { children: [_(D), /* @__PURE__ */ c(me, {
114
+ id: a,
115
+ dataTest: s,
116
+ open: o,
117
+ onClose: n,
118
+ title: l,
119
+ ariaLabel: F,
120
+ viewResultsAction: T,
121
+ resetAction: A,
122
+ footerActions: M,
123
+ resultCount: v,
124
+ closeLabel: w,
125
+ className: O,
126
+ children: S
127
+ })] }) : /* @__PURE__ */ W(N, { children: [_(D), o && /* @__PURE__ */ c(he, {
128
+ root: H,
129
+ children: /* @__PURE__ */ c("div", {
130
+ ...V(),
131
+ ref: Q,
132
+ id: a,
133
+ "data-test": s,
134
+ "data-testid": s,
135
+ role: t ? "dialog" : void 0,
136
+ "aria-labelledby": t && l ? L : void 0,
137
+ "aria-label": t && !l ? F : void 0,
138
+ tabIndex: t ? void 0 : -1,
139
+ ...x ? ne : {},
140
+ style: {
141
+ ...x ? ie : {},
142
+ ...q,
143
+ minWidth: Ae,
144
+ width: d ? B : void 0,
145
+ maxWidth: te,
146
+ maxHeight: Y
147
+ },
148
+ className: oe("z-[1300]", "box-border flex flex-col overflow-hidden rounded-lg border border-solid border-delta-300 bg-white text-delta-700 outline-none shadow-[0px_4px_40px_0px_#22213366]", O),
149
+ children: /* @__PURE__ */ c(ge, {
150
+ dataTest: s,
151
+ title: l,
152
+ titleId: L,
153
+ viewResultsAction: p(ee),
154
+ resetAction: p(A),
155
+ footerActions: p(M),
156
+ closeLabel: w,
157
+ onClose: n,
158
+ children: p(S)
159
+ })
160
+ })
161
+ })] });
162
+ };
163
+ export {
164
+ je as PopoverSheet
165
+ };
@@ -0,0 +1,13 @@
1
+ import { useEffect as n } from "react";
2
+ var c = (l) => {
3
+ n(() => {
4
+ if (!l) return;
5
+ const { body: o, documentElement: e } = document, r = window.scrollY, t = o.style.overflow, s = e.style.overflow;
6
+ return o.style.overflow = "hidden", e.style.overflow = "hidden", () => {
7
+ o.style.overflow = t, e.style.overflow = s, window.scrollTo(window.scrollX, r);
8
+ };
9
+ }, [l]);
10
+ };
11
+ export {
12
+ c as useBodyScrollLock
13
+ };
@@ -0,0 +1,15 @@
1
+ import { useEffect as u, useState as c } from "react";
2
+ var s = (e, t) => {
3
+ const [o, r] = c(e);
4
+ return u(() => {
5
+ const n = window.setTimeout(() => {
6
+ r(e);
7
+ }, t);
8
+ return () => {
9
+ window.clearTimeout(n);
10
+ };
11
+ }, [e, t]), o;
12
+ };
13
+ export {
14
+ s as useDebouncedValue
15
+ };
@@ -1,19 +1,20 @@
1
1
  import { useSyncExternalStore as o } from "react";
2
- function u(t) {
3
- function r() {
2
+ function n(t) {
3
+ function i() {
4
4
  return window.matchMedia(t).matches;
5
5
  }
6
- function i(e) {
7
- const n = window.matchMedia(t);
8
- return n.addEventListener("change", e), () => {
9
- n.removeEventListener("change", e);
6
+ function a(e) {
7
+ const r = window.matchMedia(t);
8
+ return r.addEventListener("change", e), () => {
9
+ r.removeEventListener("change", e);
10
10
  };
11
11
  }
12
12
  return function() {
13
- return o(i, r);
13
+ return o(a, i);
14
14
  };
15
15
  }
16
- var s = u("(max-width: 743px)");
16
+ var s = n("(max-width: 743px)"), d = n("(max-height: 480px)");
17
17
  export {
18
- s as useMobileMediaQuery
18
+ s as useMobileMediaQuery,
19
+ d as useShortViewportMediaQuery
19
20
  };