@caseparts-org/caseblocks 0.0.111 → 0.0.113

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.
@@ -1 +1 @@
1
- ._loggedIn_w7zna_1{flex-shrink:0;gap:var(--spacing-spacing-2xs);cursor:pointer;transition:all .3s linear;display:flex;flex-direction:row;align-items:center;justify-content:center;padding:var(--spacing-spacing-3xs)}._customer_w7zna_12>a,._customer_w7zna_12>a:hover{text-decoration:none}._loggedIn_w7zna_1:hover{background-color:#f3f3f3;border-radius:var(--border-radius-md)}._placeholder_w7zna_21{height:30px;width:120px}@media (max-width:1280px){._placeholder_w7zna_21{width:30px;height:30px}}
1
+ ._loggedIn_1sipy_1{flex-shrink:0;gap:var(--spacing-spacing-2xs);cursor:pointer;transition:all .3s linear;display:flex;flex-direction:row;align-items:center;justify-content:center;padding:var(--spacing-spacing-3xs)}._customer_1sipy_12>a,._customer_1sipy_12>a:hover{text-decoration:none}._loggedIn_1sipy_1:hover{background-color:#f3f3f3;border-radius:var(--border-radius-md)}._placeholder_1sipy_21{width:32px;width:120px}@media (max-width:1280px){._placeholder_1sipy_21{width:32px;height:32px;background-color:#f3f3f3;border-radius:100%}}
@@ -0,0 +1 @@
1
+ ._overlay_vmpn5_1{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000}._container_vmpn5_11{background-color:var(--surface-surface-primary);color:var(--text-text-primary);border-radius:var(--border-radius-sm);box-shadow:0 4px 6px #0000001a;width:min(800px,92vw);max-height:80vh;display:flex;flex-direction:column;overflow:hidden}@media (max-width:767px){._container_vmpn5_11{border-radius:0;width:100%;box-shadow:none;height:100dvh;max-height:100dvh}}._header_vmpn5_30{position:sticky;top:0;display:flex;flex-direction:row;align-items:center;justify-content:space-between;background-color:var(--surface-surface-secondary);border-bottom:1px solid var(--border-border-secondary-btn);padding:var(--spacing-spacing-2xs);z-index:1}._closeButton_vmpn5_53{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background:transparent;padding:var(--spacing-spacing-4xs);cursor:pointer;display:flex;align-items:center;justify-content:center;color:inherit;padding:0}._content_vmpn5_69{overflow:auto;padding:var(--spacing-spacing-default)}@media (max-width:767px){._content_vmpn5_69{padding:var(--spacing-spacing-2xs)}}._headerPlain_vmpn5_77{background-color:transparent;border-bottom:none}
@@ -1,14 +1,47 @@
1
1
  import * as React from "react";
2
2
  type PositionKeyword = "top" | "right" | "bottom" | "left";
3
3
  type Position = "top left" | "top center" | "top right" | "right top" | "right center" | "right bottom" | "bottom left" | "bottom center" | "bottom right" | "left top" | "left center" | "left bottom" | PositionKeyword;
4
+ type PopoverAPI = {
5
+ close: () => void;
6
+ open: () => void;
7
+ toggle: () => void;
8
+ };
9
+ export declare function usePopover(): PopoverAPI;
4
10
  export type PopoverProps = {
5
11
  trigger: React.ReactElement;
6
- children: React.ReactNode;
12
+ children: React.ReactNode | ((api: PopoverAPI) => React.ReactNode);
7
13
  position?: Position;
8
14
  popoverClassName?: string;
9
15
  contentClassName?: string;
10
16
  disabled?: boolean;
11
17
  closeOnOutsideClick?: boolean;
18
+ /** If true, clicking any element with `data-popover-close` inside content will close */
19
+ closeOnInsideClickAttr?: boolean;
20
+ /** Controlled open state; when provided, component becomes controlled */
21
+ open?: boolean;
22
+ /** Controlled state change callback */
23
+ onOpenChange?: (_open: boolean) => void;
12
24
  };
25
+ /**
26
+ * Popover close control options:
27
+ * 1) Attribute-based (simple): Add `data-popover-close="true"` to any element
28
+ * inside the popover content. Clicking it will auto-close the popover.
29
+ * Ideal for links or straightforward buttons (e.g., Sign out, navigate).
30
+ *
31
+ * 2) Controlled via app context (global): Provide `open` and `onOpenChange` props
32
+ * from your app state (e.g., InterfaceProvider). This allows opening/closing
33
+ * the popover from anywhere in the application and keeps UI state consistent.
34
+ * Example: `<Popover open={accountMenuOpen} onOpenChange={setAccountMenuOpen} ... />`
35
+ *
36
+ * 3) Local control via Popover context: Use `usePopover()` inside the popover content
37
+ * to access `{ close, open, toggle }`. Call `close()` after actions (async or conditional)
38
+ * to programmatically close only the current popover instance. Alternatively, pass
39
+ * a render-prop as children and receive the same API: `{({ close }) => ... }`.
40
+ *
41
+ * Notes:
42
+ * - Each Popover instance provides its own context, so `usePopover()` affects only that instance.
43
+ * - When `open` is provided, the component becomes controlled and calls `onOpenChange`.
44
+ * - Outside-click and Escape key will still close the popover unless disabled via props.
45
+ */
13
46
  export declare const Popover: React.FC<PopoverProps>;
14
47
  export {};
@@ -1,104 +1,126 @@
1
- import { jsxs as z, Fragment as P, jsx as b } from "react/jsx-runtime";
2
- import * as u from "react";
3
- import { r as k } from "../../index-B4KbmMH3.js";
4
- import { c as x } from "../../clsx-OuTLNxxd.js";
5
- import '../../assets/Popover.css';const C = "_popover_vlr81_1", M = "_content_vlr81_7", L = {
6
- popover: C,
7
- content: M
8
- };
9
- function S(o) {
1
+ import { jsxs as H, jsx as k } from "react/jsx-runtime";
2
+ import * as s from "react";
3
+ import { r as N } from "../../index-B4KbmMH3.js";
4
+ import { c as z } from "../../clsx-OuTLNxxd.js";
5
+ import '../../assets/Popover.css';const W = "_popover_vlr81_1", q = "_content_vlr81_7", M = {
6
+ popover: W,
7
+ content: q
8
+ }, S = s.createContext(null);
9
+ function K() {
10
+ const o = s.useContext(S);
11
+ if (!o)
12
+ throw new Error("usePopover must be used within a Popover");
13
+ return o;
14
+ }
15
+ function D(o) {
10
16
  return o ? o.includes(" ") ? o : `${o} center` : "top center";
11
17
  }
12
- function j(o) {
13
- const m = S(o).toLowerCase(), [c, l] = m.split(" ");
18
+ function F(o) {
19
+ const p = D(o).toLowerCase(), [c, l] = p.split(" ");
14
20
  return { side: ["top", "right", "bottom", "left"].includes(c) ? c : "top", align: l === "left" || l === "top" ? "start" : l === "right" || l === "bottom" ? "end" : "center" };
15
21
  }
16
- function B(o, m, c, l, p = 8) {
17
- const e = o.getBoundingClientRect(), a = m.getBoundingClientRect();
18
- let i = 0, s = 0;
19
- c === "top" ? i = e.top - a.height - p : c === "bottom" ? i = e.bottom + p : c === "left" ? s = e.left - a.width - p : c === "right" && (s = e.right + p), c === "top" || c === "bottom" ? l === "start" ? s = e.left : l === "end" ? s = e.right - a.width : s = e.left + e.width / 2 - a.width / 2 : l === "start" ? i = e.top : l === "end" ? i = e.bottom - a.height : i = e.top + e.height / 2 - a.height / 2;
20
- const r = window.innerWidth, w = window.innerHeight;
21
- return i = Math.max(4, Math.min(w - a.height - 4, i)), s = Math.max(4, Math.min(r - a.width - 4, s)), { top: i, left: s };
22
+ function U(o, p, c, l, d = 8) {
23
+ const n = o.getBoundingClientRect(), u = p.getBoundingClientRect();
24
+ let a = 0, f = 0;
25
+ c === "top" ? a = n.top - u.height - d : c === "bottom" ? a = n.bottom + d : c === "left" ? f = n.left - u.width - d : c === "right" && (f = n.right + d), c === "top" || c === "bottom" ? l === "start" ? f = n.left : l === "end" ? f = n.right - u.width : f = n.left + n.width / 2 - u.width / 2 : l === "start" ? a = n.top : l === "end" ? a = n.bottom - u.height : a = n.top + n.height / 2 - u.height / 2;
26
+ const w = window.innerWidth, h = window.innerHeight;
27
+ return a = Math.max(4, Math.min(h - u.height - 4, a)), f = Math.max(4, Math.min(w - u.width - 4, f)), { top: a, left: f };
22
28
  }
23
- const q = ({
29
+ const Q = ({
24
30
  trigger: o,
25
- children: m,
31
+ children: p,
26
32
  position: c,
27
33
  popoverClassName: l,
28
- contentClassName: p,
29
- disabled: e,
30
- closeOnOutsideClick: a = !0
34
+ contentClassName: d,
35
+ disabled: n,
36
+ closeOnOutsideClick: u = !0,
37
+ closeOnInsideClickAttr: a = !0,
38
+ open: f,
39
+ onOpenChange: w
31
40
  }) => {
32
- const { side: i, align: s } = j(c), [r, w] = u.useState(!1), [f, g] = u.useState(null), v = u.useRef(null), h = u.useRef(null), R = () => {
33
- e || w((t) => !t);
34
- }, E = () => w(!1), _ = u.cloneElement(o, {
41
+ const { side: h, align: y } = F(c), [C, j] = s.useState(!1), P = typeof f == "boolean", r = P ? f : C, [v, R] = s.useState(null), b = s.useRef(null), m = s.useRef(null), x = (t) => {
42
+ const e = typeof t == "function" ? t(r) : t;
43
+ P ? w == null || w(e) : j(e);
44
+ }, L = () => {
45
+ n || x((t) => !t);
46
+ }, E = () => x(!1), _ = () => x(!0), B = s.cloneElement(o, {
35
47
  ref: (t) => {
36
- const { ref: n } = o;
37
- typeof n == "function" ? n(t) : n && (n.current = t), v.current = t;
48
+ const { ref: e } = o;
49
+ typeof e == "function" ? e(t) : e && (e.current = t), b.current = t;
38
50
  },
39
51
  onClick: (t) => {
40
- var n, d;
41
- (d = (n = o.props).onClick) == null || d.call(n, t), R();
52
+ var e, i;
53
+ (i = (e = o.props).onClick) == null || i.call(e, t), L();
42
54
  },
43
55
  "aria-haspopup": "dialog",
44
56
  "aria-expanded": r || void 0,
45
57
  "aria-controls": r ? "popover-panel" : void 0,
46
58
  style: { ...o.props.style || {}, outline: "none" }
47
59
  });
48
- return u.useLayoutEffect(() => {
60
+ return s.useLayoutEffect(() => {
49
61
  if (!r) {
50
- g(null);
62
+ R(null);
51
63
  return;
52
64
  }
53
- const t = v.current, n = h.current;
54
- if (!t || !n) return;
55
- const d = () => {
56
- g(B(t, n, i, s, 8));
65
+ const t = b.current, e = m.current;
66
+ if (!t || !e) return;
67
+ const i = () => {
68
+ R(U(t, e, h, y, 8));
57
69
  };
58
- return d(), window.addEventListener("resize", d), window.addEventListener("scroll", d, !0), () => {
59
- window.removeEventListener("resize", d), window.removeEventListener("scroll", d, !0);
70
+ return i(), window.addEventListener("resize", i), window.addEventListener("scroll", i, !0), () => {
71
+ window.removeEventListener("resize", i), window.removeEventListener("scroll", i, !0);
60
72
  };
61
- }, [r, i, s, m]), u.useEffect(() => {
62
- if (!r || !a) return;
63
- const t = (n) => {
64
- const d = h.current, y = v.current;
65
- !d || !y || d.contains(n.target) || y.contains(n.target) || E();
73
+ }, [r, h, y, p]), s.useEffect(() => {
74
+ if (!r || !u) return;
75
+ const t = (e) => {
76
+ const i = m.current, g = b.current;
77
+ !i || !g || i.contains(e.target) || g.contains(e.target) || E();
66
78
  };
67
79
  return window.addEventListener("mousedown", t), () => window.removeEventListener("mousedown", t);
68
- }, [r, a]), u.useEffect(() => {
80
+ }, [r, u]), s.useEffect(() => {
81
+ if (!r || !a) return;
82
+ const t = m.current;
83
+ if (!t) return;
84
+ const e = (i) => {
85
+ const g = i.target;
86
+ if (!g) return;
87
+ g.closest('[data-popover-close="true"]') && E();
88
+ };
89
+ return t.addEventListener("click", e), () => t.removeEventListener("click", e);
90
+ }, [r, a]), s.useEffect(() => {
69
91
  if (!r) return;
70
- const t = (n) => {
71
- n.key === "Escape" && E();
92
+ const t = (e) => {
93
+ e.key === "Escape" && E();
72
94
  };
73
95
  return window.addEventListener("keydown", t), () => window.removeEventListener("keydown", t);
74
- }, [r]), u.useEffect(() => {
75
- if (r && h.current) {
76
- const t = h.current.querySelector(
96
+ }, [r]), s.useEffect(() => {
97
+ if (r && m.current) {
98
+ const t = m.current.querySelector(
77
99
  'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
78
100
  );
79
101
  t == null || t.focus();
80
102
  }
81
- }, [r]), /* @__PURE__ */ z(P, { children: [
82
- _,
83
- r && typeof document < "u" && k.createPortal(
84
- /* @__PURE__ */ b(
103
+ }, [r]), /* @__PURE__ */ H(S.Provider, { value: { close: E, open: _, toggle: L }, children: [
104
+ B,
105
+ r && typeof document < "u" && N.createPortal(
106
+ /* @__PURE__ */ k(
85
107
  "div",
86
108
  {
87
109
  id: "popover-panel",
88
- ref: h,
110
+ ref: m,
89
111
  role: "dialog",
90
112
  "aria-modal": "false",
91
- className: x(L.popover, l),
92
- "data-side": i,
93
- "data-align": s,
113
+ className: z(M.popover, l),
114
+ "data-side": h,
115
+ "data-align": y,
94
116
  style: {
95
117
  position: "absolute",
96
- top: (f == null ? void 0 : f.top) ?? 0,
97
- left: (f == null ? void 0 : f.left) ?? 0,
98
- visibility: f ? "visible" : "hidden",
118
+ top: (v == null ? void 0 : v.top) ?? 0,
119
+ left: (v == null ? void 0 : v.left) ?? 0,
120
+ visibility: v ? "visible" : "hidden",
99
121
  zIndex: 20
100
122
  },
101
- children: /* @__PURE__ */ b("div", { className: x(L.content, p), children: m })
123
+ children: /* @__PURE__ */ k("div", { className: z(M.content, d), children: typeof p == "function" ? p({ close: E, open: _, toggle: L }) : p })
102
124
  }
103
125
  ),
104
126
  document.body
@@ -106,5 +128,6 @@ const q = ({
106
128
  ] });
107
129
  };
108
130
  export {
109
- q as Popover
131
+ Q as Popover,
132
+ K as usePopover
110
133
  };
@@ -64,3 +64,5 @@ export declare const PositionRight: Story;
64
64
  export declare const PositionLeft: Story;
65
65
  export declare const InteractiveContent: Story;
66
66
  export declare const OutsideClickDisabled: Story;
67
+ export declare const AttributeClose: Story;
68
+ export declare const RenderPropClose: Story;
@@ -57,21 +57,21 @@ const k = {
57
57
  children: { description: "Popover content (interactive)." }
58
58
  }
59
59
  }, r = () => /* @__PURE__ */ e("style", { children: ".storyRoboto{font-family:'Roboto',sans-serif;}" }), R = {
60
- render: (c) => /* @__PURE__ */ t(n, { children: [
60
+ render: (l) => /* @__PURE__ */ t(n, { children: [
61
61
  /* @__PURE__ */ e(r, {}),
62
62
  /* @__PURE__ */ e(
63
63
  i,
64
64
  {
65
- ...c,
65
+ ...l,
66
66
  contentClassName: "storyRoboto",
67
67
  trigger: /* @__PURE__ */ e(o, { size: "md", variant: "primary", children: "Open form" }),
68
68
  children: /* @__PURE__ */ e(() => {
69
- const [s, m] = a.useState(""), [p, h] = a.useState(""), [g, u] = a.useState(!1);
69
+ const [c, m] = a.useState(""), [p, h] = a.useState(""), [g, u] = a.useState(!1);
70
70
  return /* @__PURE__ */ t(
71
71
  "form",
72
72
  {
73
- onSubmit: (l) => {
74
- l.preventDefault(), u(!0);
73
+ onSubmit: (s) => {
74
+ s.preventDefault(), u(!0);
75
75
  },
76
76
  style: { display: "flex", flexDirection: "column", gap: 8, minWidth: 220 },
77
77
  children: [
@@ -80,8 +80,8 @@ const k = {
80
80
  /* @__PURE__ */ e(
81
81
  "input",
82
82
  {
83
- value: s,
84
- onChange: (l) => m(l.target.value),
83
+ value: c,
84
+ onChange: (s) => m(s.target.value),
85
85
  placeholder: "Jane Doe",
86
86
  style: { padding: 4 }
87
87
  }
@@ -94,7 +94,7 @@ const k = {
94
94
  {
95
95
  type: "email",
96
96
  value: p,
97
- onChange: (l) => h(l.target.value),
97
+ onChange: (s) => h(s.target.value),
98
98
  placeholder: "jane@example.com",
99
99
  style: { padding: 4 }
100
100
  }
@@ -103,7 +103,7 @@ const k = {
103
103
  /* @__PURE__ */ e("button", { type: "submit", style: { padding: "4px 8px" }, children: "Submit" }),
104
104
  g && /* @__PURE__ */ t("div", { style: { fontSize: 12, color: "var(--color-neutrals-neutral-6)" }, children: [
105
105
  "Submitted: ",
106
- s || "(no name)",
106
+ c || "(no name)",
107
107
  ", ",
108
108
  p || "(no email)"
109
109
  ] })
@@ -127,7 +127,7 @@ const k = {
127
127
  }
128
128
  )
129
129
  ] })
130
- }, S = {
130
+ }, z = {
131
131
  render: () => /* @__PURE__ */ t(n, { children: [
132
132
  /* @__PURE__ */ e(r, {}),
133
133
  /* @__PURE__ */ e(
@@ -140,7 +140,7 @@ const k = {
140
140
  }
141
141
  )
142
142
  ] })
143
- }, P = {
143
+ }, S = {
144
144
  render: () => /* @__PURE__ */ t(n, { children: [
145
145
  /* @__PURE__ */ e(r, {}),
146
146
  /* @__PURE__ */ e(
@@ -153,10 +153,10 @@ const k = {
153
153
  }
154
154
  )
155
155
  ] })
156
- }, O = {
156
+ }, P = {
157
157
  render: () => /* @__PURE__ */ e(y, {})
158
158
  }, y = () => {
159
- const [c, d] = a.useState(0);
159
+ const [l, d] = a.useState(0);
160
160
  return /* @__PURE__ */ t(n, { children: [
161
161
  /* @__PURE__ */ e(r, {}),
162
162
  /* @__PURE__ */ e(
@@ -168,8 +168,8 @@ const k = {
168
168
  children: /* @__PURE__ */ t("div", { style: { display: "flex", flexDirection: "column", gap: 10, minWidth: 240 }, children: [
169
169
  /* @__PURE__ */ e("div", { style: { fontWeight: 500 }, children: "Counter demo" }),
170
170
  /* @__PURE__ */ t("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
171
- /* @__PURE__ */ e(o, { size: "sm", variant: "secondary", onClick: () => d((s) => s + 1), children: "Increment" }),
172
- /* @__PURE__ */ e("span", { style: { minWidth: 32, textAlign: "center" }, children: c }),
171
+ /* @__PURE__ */ e(o, { size: "sm", variant: "secondary", onClick: () => d((c) => c + 1), children: "Increment" }),
172
+ /* @__PURE__ */ e("span", { style: { minWidth: 32, textAlign: "center" }, children: l }),
173
173
  /* @__PURE__ */ e(o, { size: "sm", variant: "tertiary", onClick: () => d(0), children: "Reset" })
174
174
  ] }),
175
175
  /* @__PURE__ */ e("hr", { style: { border: 0, height: 1, background: "#ddd" } }),
@@ -181,7 +181,7 @@ const k = {
181
181
  }
182
182
  )
183
183
  ] });
184
- }, z = {
184
+ }, D = {
185
185
  render: () => /* @__PURE__ */ t(n, { children: [
186
186
  /* @__PURE__ */ e(r, {}),
187
187
  /* @__PURE__ */ e(
@@ -195,13 +195,49 @@ const k = {
195
195
  }
196
196
  )
197
197
  ] })
198
+ }, O = {
199
+ render: () => /* @__PURE__ */ t(n, { children: [
200
+ /* @__PURE__ */ e(r, {}),
201
+ /* @__PURE__ */ e(
202
+ i,
203
+ {
204
+ position: "bottom center",
205
+ contentClassName: "storyRoboto",
206
+ trigger: /* @__PURE__ */ e(o, { size: "md", variant: "secondary", children: "Attribute close" }),
207
+ children: /* @__PURE__ */ t("div", { style: { display: "flex", flexDirection: "column", gap: 8, minWidth: 220 }, children: [
208
+ /* @__PURE__ */ e("a", { href: "#", "data-popover-close": "true", children: "Simple link (auto-close)" }),
209
+ /* @__PURE__ */ e("button", { "data-popover-close": "true", style: { padding: "4px 8px" }, children: "Button (auto-close)" })
210
+ ] })
211
+ }
212
+ )
213
+ ] })
214
+ }, W = {
215
+ render: () => /* @__PURE__ */ t(n, { children: [
216
+ /* @__PURE__ */ e(r, {}),
217
+ /* @__PURE__ */ e(
218
+ i,
219
+ {
220
+ position: "bottom center",
221
+ contentClassName: "storyRoboto",
222
+ trigger: /* @__PURE__ */ e(o, { size: "md", variant: "primary", children: "Render-prop close" }),
223
+ children: (l) => /* @__PURE__ */ t("div", { style: { display: "flex", flexDirection: "column", gap: 8, minWidth: 220 }, children: [
224
+ /* @__PURE__ */ e(o, { size: "sm", variant: "secondary", onClick: () => l.close(), children: "Close programmatically" }),
225
+ /* @__PURE__ */ e(o, { size: "sm", variant: "tertiary", onClick: () => {
226
+ setTimeout(() => l.close(), 300);
227
+ }, children: "Async close (300ms)" })
228
+ ] })
229
+ }
230
+ )
231
+ ] })
198
232
  };
199
233
  export {
234
+ O as AttributeClose,
200
235
  R as BasicClick,
201
236
  N as BottomClick,
202
- O as InteractiveContent,
203
- z as OutsideClickDisabled,
204
- P as PositionLeft,
205
- S as PositionRight,
237
+ P as InteractiveContent,
238
+ D as OutsideClickDisabled,
239
+ S as PositionLeft,
240
+ z as PositionRight,
241
+ W as RenderPropClose,
206
242
  k as default
207
243
  };
@@ -7,8 +7,10 @@ export interface AccountProps extends React.HTMLAttributes<HTMLDivElement>, Hide
7
7
  number: string;
8
8
  /** The account user's name. */
9
9
  name: string;
10
- /** The account user's initials. */
11
- initials: string;
10
+ /** The account user's initials. Used when no custom avatar JSX is provided. */
11
+ initials?: string;
12
+ /** Optional custom avatar content. If provided, it will be rendered instead of the default Avatar. */
13
+ avatar?: React.ReactNode;
12
14
  };
13
15
  onLoginClick: () => void;
14
16
  /** Optional content to show when clicking the authenticated container */
@@ -1,40 +1,40 @@
1
- import { jsx as o, jsxs as n } from "react/jsx-runtime";
2
- import { getHideAtStyles as a } from "../../atoms/HideAt.js";
1
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
2
+ import { getHideAtStyles as m } from "../../atoms/HideAt.js";
3
3
  import { Icon as f } from "../../atoms/Icon/Icon.js";
4
4
  import { Text as c } from "../../atoms/Text/Text.js";
5
- import { Avatar as h } from "../Avatar/Avatar.js";
5
+ import { Avatar as u } from "../Avatar/Avatar.js";
6
6
  import { Flex as d } from "../../atoms/Flex/Flex.js";
7
7
  import { Button as p } from "../../atoms/Button/Button.js";
8
8
  import { Popover as A } from "../../atoms/Popover/Popover.js";
9
9
  import { c as g } from "../../clsx-OuTLNxxd.js";
10
- import '../../assets/Account.css';const x = "_loggedIn_w7zna_1", v = "_customer_w7zna_12", I = "_placeholder_w7zna_21", t = {
10
+ import '../../assets/Account.css';const x = "_loggedIn_1sipy_1", v = "_customer_1sipy_12", I = "_placeholder_1sipy_21", o = {
11
11
  loggedIn: x,
12
12
  customer: v,
13
13
  placeholder: I
14
14
  };
15
- function z(i) {
15
+ function y(i) {
16
16
  return i.account !== void 0;
17
17
  }
18
- function T(i) {
19
- return i.isAccountLoading ? /* @__PURE__ */ o("div", { className: t.placeholder }) : z(i) ? /* @__PURE__ */ o(_, { ...i }) : /* @__PURE__ */ o(N, { ...i });
18
+ function j(i) {
19
+ return i.isAccountLoading ? /* @__PURE__ */ t("div", { className: o.placeholder }) : y(i) ? /* @__PURE__ */ t(_, { ...i }) : /* @__PURE__ */ t(N, { ...i });
20
20
  }
21
21
  function _(i) {
22
22
  const {
23
23
  account: e,
24
24
  className: r,
25
25
  hideAt: s,
26
- popoverContent: m,
27
- isAccountLoading: u,
26
+ popoverContent: a,
27
+ isAccountLoading: h,
28
28
  ...l
29
29
  } = i;
30
- return m ? /* @__PURE__ */ o(
30
+ return a ? /* @__PURE__ */ t(
31
31
  A,
32
32
  {
33
33
  position: "bottom right",
34
34
  trigger: /* @__PURE__ */ n(
35
35
  "div",
36
36
  {
37
- className: g(t.loggedIn, a(s), r),
37
+ className: g(o.loggedIn, m(s), r),
38
38
  ...l,
39
39
  children: [
40
40
  /* @__PURE__ */ n(
@@ -43,7 +43,7 @@ function _(i) {
43
43
  flexDirection: "column",
44
44
  alignItems: "flex-end",
45
45
  hideAt: ["sm", "md"],
46
- className: t.customer,
46
+ className: o.customer,
47
47
  children: [
48
48
  /* @__PURE__ */ n(c, { size: "xxs", children: [
49
49
  "Acct: ",
@@ -56,16 +56,16 @@ function _(i) {
56
56
  ]
57
57
  }
58
58
  ),
59
- /* @__PURE__ */ o(h, { initials: e.initials })
59
+ e.avatar ?? (e.initials ? /* @__PURE__ */ t(u, { initials: e.initials }) : null)
60
60
  ]
61
61
  }
62
62
  ),
63
- children: m
63
+ children: a
64
64
  }
65
65
  ) : /* @__PURE__ */ n(
66
66
  "div",
67
67
  {
68
- className: g(t.loggedIn, a(s), r),
68
+ className: g(o.loggedIn, m(s), r),
69
69
  ...l,
70
70
  children: [
71
71
  /* @__PURE__ */ n(
@@ -74,7 +74,7 @@ function _(i) {
74
74
  flexDirection: "column",
75
75
  alignItems: "flex-end",
76
76
  hideAt: ["sm", "md"],
77
- className: t.customer,
77
+ className: o.customer,
78
78
  children: [
79
79
  /* @__PURE__ */ n(c, { size: "xxs", children: [
80
80
  "Acct: ",
@@ -87,7 +87,7 @@ function _(i) {
87
87
  ]
88
88
  }
89
89
  ),
90
- /* @__PURE__ */ o(h, { initials: e.initials })
90
+ e.avatar ?? (e.initials ? /* @__PURE__ */ t(u, { initials: e.initials }) : null)
91
91
  ]
92
92
  }
93
93
  );
@@ -97,8 +97,8 @@ function N(i) {
97
97
  onLoginClick: e,
98
98
  className: r,
99
99
  hideAt: s,
100
- popoverContent: m,
101
- isAccountLoading: u,
100
+ popoverContent: a,
101
+ isAccountLoading: h,
102
102
  ...l
103
103
  } = i;
104
104
  return /* @__PURE__ */ n(
@@ -108,12 +108,12 @@ function N(i) {
108
108
  alignItems: "center",
109
109
  ...l,
110
110
  className: g(
111
- t.unauthenticated,
112
- a(s),
111
+ o.unauthenticated,
112
+ m(s),
113
113
  r
114
114
  ),
115
115
  children: [
116
- /* @__PURE__ */ o(
116
+ /* @__PURE__ */ t(
117
117
  p,
118
118
  {
119
119
  onClick: e,
@@ -123,11 +123,11 @@ function N(i) {
123
123
  children: "Sign In / Register"
124
124
  }
125
125
  ),
126
- /* @__PURE__ */ o(f, { iconKey: "fa-kit fa-user-anon", size: "lg", hideAt: "lg" })
126
+ /* @__PURE__ */ t(f, { iconKey: "fa-kit fa-user-anon", size: "lg", hideAt: "lg" })
127
127
  ]
128
128
  }
129
129
  );
130
130
  }
131
131
  export {
132
- T as Account
132
+ j as Account
133
133
  };
@@ -12,3 +12,4 @@ export default meta;
12
12
  type Story = StoryObj<typeof meta>;
13
13
  export declare const Unauthenticated: Story;
14
14
  export declare const Authenticated: Story;
15
+ export declare const AuthenticatedWithCustomAvatar: Story;
@@ -1,19 +1,20 @@
1
- import { Account as t } from "./Account.js";
2
- const o = {
1
+ import { jsxs as e, jsx as t } from "react/jsx-runtime";
2
+ import { Account as o } from "./Account.js";
3
+ const r = {
3
4
  title: "Case Parts/Molecules/Account",
4
- component: t,
5
+ component: o,
5
6
  parameters: {
6
7
  // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
7
8
  layout: "centered"
8
9
  },
9
10
  // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
10
11
  tags: ["autodocs"]
11
- }, e = {
12
+ }, i = {
12
13
  args: {
13
14
  onLoginClick: () => {
14
15
  }
15
16
  }
16
- }, a = {
17
+ }, c = {
17
18
  args: {
18
19
  account: {
19
20
  name: "Ringo",
@@ -21,11 +22,34 @@ const o = {
21
22
  number: "123456789012"
22
23
  },
23
24
  onLoginClick: () => {
25
+ },
26
+ popoverContent: /* @__PURE__ */ e("div", { style: { display: "flex", flexDirection: "column", gap: 8, minWidth: 220 }, children: [
27
+ /* @__PURE__ */ t("a", { href: "#", "data-popover-close": "true", children: "Profile" }),
28
+ /* @__PURE__ */ t("a", { href: "#", "data-popover-close": "true", children: "Orders" }),
29
+ /* @__PURE__ */ t("button", { "data-popover-close": "true", children: "Sign out" })
30
+ ] })
31
+ }
32
+ }, s = {
33
+ args: {
34
+ account: {
35
+ name: "Ringo",
36
+ number: "123456789012",
37
+ avatar: /* @__PURE__ */ t(
38
+ "img",
39
+ {
40
+ src: "https://avatars.githubusercontent.com/u/9919?s=80&v=4",
41
+ alt: "Custom Avatar",
42
+ style: { width: 32, height: 32, borderRadius: 9999 }
43
+ }
44
+ )
45
+ },
46
+ onLoginClick: () => {
24
47
  }
25
48
  }
26
49
  };
27
50
  export {
28
- a as Authenticated,
29
- e as Unauthenticated,
30
- o as default
51
+ c as Authenticated,
52
+ s as AuthenticatedWithCustomAvatar,
53
+ i as Unauthenticated,
54
+ r as default
31
55
  };
@@ -0,0 +1,12 @@
1
+ import { default as React } from 'react';
2
+ export type ModalHeaderSize = "sm" | "md" | "lg";
3
+ export type ModalHeaderVariant = "default" | "plain";
4
+ export interface ModalProps extends React.HTMLAttributes<HTMLDivElement> {
5
+ isOpen: boolean;
6
+ caption?: string;
7
+ onClose: () => void;
8
+ closeOnOverlayClick?: boolean;
9
+ headerSize?: ModalHeaderSize;
10
+ headerVariant?: ModalHeaderVariant;
11
+ }
12
+ export declare function Modal({ isOpen, caption, onClose, closeOnOverlayClick, headerSize, headerVariant, className, children, ...otherProps }: ModalProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,75 @@
1
+ import { jsx as n, jsxs as s } from "react/jsx-runtime";
2
+ import { c as t } from "../../clsx-OuTLNxxd.js";
3
+ import { Text as h } from "../../atoms/Text/Text.js";
4
+ import { Icon as f } from "../../atoms/Icon/Icon.js";
5
+ import '../../assets/Modal.css';const y = "_overlay_vmpn5_1", g = "_container_vmpn5_11", x = "_header_vmpn5_30", N = "_closeButton_vmpn5_53", S = "_captionSpacer_vmpn5_66", T = "_content_vmpn5_69", k = "_headerPlain_vmpn5_77", e = {
6
+ overlay: y,
7
+ container: g,
8
+ header: x,
9
+ closeButton: N,
10
+ captionSpacer: S,
11
+ content: T,
12
+ headerPlain: k
13
+ }, z = {
14
+ sm: "sm",
15
+ md: "md",
16
+ lg: "lg"
17
+ }, B = {
18
+ sm: "sm",
19
+ md: "md",
20
+ lg: "md"
21
+ };
22
+ function I({
23
+ isOpen: i,
24
+ caption: o,
25
+ onClose: c,
26
+ closeOnOverlayClick: m = !0,
27
+ headerSize: a = "md",
28
+ headerVariant: r = "default",
29
+ className: d,
30
+ children: p,
31
+ ..._
32
+ }) {
33
+ if (!i) return null;
34
+ const v = (l) => {
35
+ m && l.target === l.currentTarget && c();
36
+ }, u = r === "default" && !!o;
37
+ return /* @__PURE__ */ n("div", { className: t(e.overlay), onClick: v, children: /* @__PURE__ */ s("div", { className: t(e.container, d), role: "dialog", "aria-modal": "true", ..._, children: [
38
+ /* @__PURE__ */ s(
39
+ "div",
40
+ {
41
+ className: t(
42
+ e.header,
43
+ e[`header-${a}`],
44
+ r === "plain" && e.headerPlain
45
+ ),
46
+ children: [
47
+ u ? /* @__PURE__ */ n(
48
+ h,
49
+ {
50
+ as: "div",
51
+ size: z[a],
52
+ variant: "display",
53
+ className: e.caption,
54
+ children: o
55
+ }
56
+ ) : /* @__PURE__ */ n("div", { className: e.captionSpacer }),
57
+ /* @__PURE__ */ n(
58
+ "button",
59
+ {
60
+ type: "button",
61
+ className: e.closeButton,
62
+ "aria-label": "Close",
63
+ onClick: c,
64
+ children: /* @__PURE__ */ n(f, { iconKey: "fa-regular fa-xmark", size: B[a] })
65
+ }
66
+ )
67
+ ]
68
+ }
69
+ ),
70
+ /* @__PURE__ */ n("div", { className: e.content, children: p })
71
+ ] }) });
72
+ }
73
+ export {
74
+ I as Modal
75
+ };
@@ -0,0 +1,7 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { Modal } from './Modal';
3
+ declare const meta: Meta<typeof Modal>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Modal>;
6
+ export declare const Basic: Story;
7
+ export declare const Sizes: Story;
@@ -0,0 +1,110 @@
1
+ import { jsx as e, jsxs as d } from "react/jsx-runtime";
2
+ import { useState as l } from "react";
3
+ import { Modal as a } from "./Modal.js";
4
+ import { Text as n } from "../../atoms/Text/Text.js";
5
+ import { Button as t } from "../../atoms/Button/Button.js";
6
+ const S = {
7
+ title: "Case Parts/Molecules/Modal",
8
+ component: a,
9
+ argTypes: {
10
+ isOpen: {
11
+ control: { type: "boolean" },
12
+ description: "Controls visibility of the modal"
13
+ },
14
+ caption: {
15
+ control: { type: "text" },
16
+ description: "Caption text displayed in the header"
17
+ },
18
+ closeOnOverlayClick: {
19
+ control: { type: "boolean" },
20
+ description: "Close when clicking on overlay"
21
+ },
22
+ headerSize: {
23
+ control: { type: "radio" },
24
+ options: ["sm", "md", "lg"],
25
+ description: "Header size controlling caption and X icon"
26
+ },
27
+ headerVariant: {
28
+ control: { type: "radio" },
29
+ options: ["default", "plain"],
30
+ description: "Header variant: styled (default) or plain"
31
+ }
32
+ },
33
+ args: {
34
+ isOpen: !0,
35
+ caption: "Sample Modal",
36
+ closeOnOverlayClick: !0,
37
+ headerSize: "md",
38
+ headerVariant: "default"
39
+ }
40
+ };
41
+ function m(i) {
42
+ const [o, r] = l(!!i.isOpen);
43
+ return /* @__PURE__ */ d("div", { style: { padding: 24 }, children: [
44
+ /* @__PURE__ */ e(t, { variant: "primary", size: "md", onClick: () => r(!0), children: "Open Modal" }),
45
+ /* @__PURE__ */ d(
46
+ a,
47
+ {
48
+ isOpen: o,
49
+ caption: i.caption ?? "Sample Modal",
50
+ onClose: () => r(!1),
51
+ closeOnOverlayClick: i.closeOnOverlayClick ?? !0,
52
+ headerSize: i.headerSize ?? "md",
53
+ headerVariant: i.headerVariant ?? "default",
54
+ children: [
55
+ /* @__PURE__ */ e(n, { as: "p", size: "md", children: "This is a reusable modal with a non-scrollable header. Click the overlay or the X to close." }),
56
+ /* @__PURE__ */ e("div", { style: { height: 600 }, children: /* @__PURE__ */ e(n, { as: "p", size: "sm", children: "Scrollable content spacer..." }) })
57
+ ]
58
+ }
59
+ )
60
+ ] });
61
+ }
62
+ const C = {
63
+ render: (i) => /* @__PURE__ */ e(m, { ...i })
64
+ };
65
+ function h() {
66
+ const [i, o] = l(!1), [r, s] = l(!1), [p, c] = l(!1);
67
+ return /* @__PURE__ */ d("div", { style: { display: "grid", gap: 12 }, children: [
68
+ /* @__PURE__ */ e(t, { variant: "secondary", size: "sm", onClick: () => o(!0), children: "Small Header" }),
69
+ /* @__PURE__ */ e(
70
+ a,
71
+ {
72
+ isOpen: i,
73
+ caption: "Small Header",
74
+ onClose: () => o(!1),
75
+ headerSize: "sm",
76
+ children: /* @__PURE__ */ e(n, { as: "p", size: "sm", children: "Small header modal content." })
77
+ }
78
+ ),
79
+ /* @__PURE__ */ e(t, { variant: "primary", size: "md", onClick: () => s(!0), children: "Medium Header" }),
80
+ /* @__PURE__ */ e(
81
+ a,
82
+ {
83
+ isOpen: r,
84
+ caption: "Medium Header",
85
+ onClose: () => s(!1),
86
+ headerSize: "md",
87
+ children: /* @__PURE__ */ e(n, { as: "p", size: "md", children: "Medium header modal content." })
88
+ }
89
+ ),
90
+ /* @__PURE__ */ e(t, { variant: "cta-primary", size: "lg", onClick: () => c(!0), children: "Large Header" }),
91
+ /* @__PURE__ */ e(
92
+ a,
93
+ {
94
+ isOpen: p,
95
+ caption: "Large Header",
96
+ onClose: () => c(!1),
97
+ headerSize: "lg",
98
+ children: /* @__PURE__ */ e(n, { as: "p", size: "lg", children: "Large header modal content." })
99
+ }
100
+ )
101
+ ] });
102
+ }
103
+ const v = {
104
+ render: () => /* @__PURE__ */ e(h, {})
105
+ };
106
+ export {
107
+ C as Basic,
108
+ v as Sizes,
109
+ S as default
110
+ };
@@ -131,9 +131,9 @@ function y(e) {
131
131
  const d = /* @__PURE__ */ b("div", { style: { display: "flex", flexDirection: "column", gap: 8, minWidth: 220 }, children: [
132
132
  /* @__PURE__ */ t(s, { size: "sm", weight: "semibold", children: "Account" }),
133
133
  /* @__PURE__ */ t(s, { size: "xs", children: "Signed in as Ringo" }),
134
- /* @__PURE__ */ t(u, { href: "/account", children: "View Account" }),
135
- /* @__PURE__ */ t(u, { href: "/orders", children: "Order History" }),
136
- /* @__PURE__ */ t(p, { size: "sm", variant: "secondary", onClick: () => alert("Sign out"), children: "Sign Out" })
134
+ /* @__PURE__ */ t(u, { href: "/account", "data-popover-close": "true", children: "View Account" }),
135
+ /* @__PURE__ */ t(u, { href: "/orders", "data-popover-close": "true", children: "Order History" }),
136
+ /* @__PURE__ */ t(p, { size: "sm", variant: "secondary", "data-popover-close": "true", onClick: () => alert("Sign out"), children: "Sign Out" })
137
137
  ] }), n = (e) => {
138
138
  const [c, i] = h(!1);
139
139
  return /* @__PURE__ */ b(g, { children: [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@caseparts-org/caseblocks",
3
3
  "private": false,
4
- "version": "0.0.111",
4
+ "version": "0.0.113",
5
5
  "type": "module",
6
6
  "module": "dist/main.js",
7
7
  "types": "dist/main.d.ts",