namps-ui 0.1.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,976 @@
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ Accordion: () => Accordion,
35
+ AccordionItem: () => AccordionItem,
36
+ Alert: () => Alert,
37
+ Avatar: () => Avatar,
38
+ AvatarGroup: () => AvatarGroup,
39
+ Badge: () => Badge,
40
+ Breadcrumbs: () => Breadcrumbs,
41
+ Button: () => Button,
42
+ Card: () => Card,
43
+ Checkbox: () => Checkbox,
44
+ CodeBlock: () => CodeBlock,
45
+ Drawer: () => Drawer,
46
+ DropdownMenu: () => DropdownMenu,
47
+ EmptyState: () => EmptyState,
48
+ Field: () => Field,
49
+ Icons: () => icons_exports,
50
+ Input: () => Input,
51
+ Kbd: () => Kbd,
52
+ Link: () => Link,
53
+ List: () => List,
54
+ ListItem: () => ListItem,
55
+ MenuSeparator: () => MenuSeparator,
56
+ Modal: () => Modal,
57
+ Pagination: () => Pagination,
58
+ Popover: () => Popover,
59
+ Progress: () => Progress,
60
+ RadioGroup: () => RadioGroup,
61
+ SearchInput: () => SearchInput,
62
+ Segmented: () => Segmented,
63
+ Select: () => Select,
64
+ Separator: () => Separator,
65
+ Skeleton: () => Skeleton,
66
+ Slider: () => Slider,
67
+ Spinner: () => Spinner,
68
+ StatCard: () => StatCard,
69
+ Stepper: () => Stepper,
70
+ Switch: () => Switch,
71
+ Tab: () => Tab,
72
+ TabList: () => TabList,
73
+ TabPanel: () => TabPanel,
74
+ Table: () => Table,
75
+ Tabs: () => Tabs,
76
+ Tag: () => Tag,
77
+ Textarea: () => Textarea,
78
+ ThemeProvider: () => ThemeProvider,
79
+ ThemeToggle: () => ThemeToggle,
80
+ ToastProvider: () => ToastProvider,
81
+ ToggleGroup: () => ToggleGroup,
82
+ Tooltip: () => Tooltip,
83
+ cx: () => cx,
84
+ initials: () => initials,
85
+ useTheme: () => useTheme,
86
+ useToast: () => useToast
87
+ });
88
+ module.exports = __toCommonJS(index_exports);
89
+
90
+ // src/theme.tsx
91
+ var React = __toESM(require("react"), 1);
92
+
93
+ // src/icons.tsx
94
+ var icons_exports = {};
95
+ __export(icons_exports, {
96
+ AlertTriangle: () => AlertTriangle,
97
+ ArrowRight: () => ArrowRight,
98
+ Check: () => Check,
99
+ CheckCircle: () => CheckCircle,
100
+ ChevronDown: () => ChevronDown,
101
+ ChevronLeft: () => ChevronLeft,
102
+ ChevronRight: () => ChevronRight,
103
+ DotsVertical: () => DotsVertical,
104
+ Info: () => Info,
105
+ Moon: () => Moon,
106
+ Plus: () => Plus,
107
+ Search: () => Search,
108
+ Sort: () => Sort,
109
+ Sun: () => Sun,
110
+ X: () => X,
111
+ XCircle: () => XCircle
112
+ });
113
+ var import_jsx_runtime = require("react/jsx-runtime");
114
+ var base = (path) => function Icon({ className, ...props }) {
115
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
116
+ "svg",
117
+ {
118
+ viewBox: "0 0 24 24",
119
+ fill: "none",
120
+ stroke: "currentColor",
121
+ strokeWidth: 1.8,
122
+ strokeLinecap: "round",
123
+ strokeLinejoin: "round",
124
+ className: className ?? "pui-icon",
125
+ "aria-hidden": "true",
126
+ ...props,
127
+ children: path
128
+ }
129
+ );
130
+ };
131
+ var ChevronDown = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 9l6 6 6-6" }));
132
+ var ChevronRight = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 6l6 6-6 6" }));
133
+ var ChevronLeft = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 6l-6 6 6 6" }));
134
+ var Check = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 12l4 4 10-10" }));
135
+ var X = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 6l12 12M18 6L6 18" }));
136
+ var Search = base(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "11", cy: "11", r: "7" }),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 21l-4.3-4.3" })
139
+ ] }));
140
+ var Plus = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 5v14M5 12h14" }));
141
+ var Sun = base(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
143
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2v2M12 20v2M4 12H2M22 12h-2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M18.4 5.6L17 7M7 17l-1.4 1.4" })
144
+ ] }));
145
+ var Moon = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8Z" }));
146
+ var Info = base(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
148
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 11v5M12 8h.01" })
149
+ ] }));
150
+ var AlertTriangle = base(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10.3 3.3 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.3a2 2 0 0 0-3.4 0Z" }),
152
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 9v4M12 17h.01" })
153
+ ] }));
154
+ var CheckCircle = base(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
155
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 12l3 3 5-6" })
157
+ ] }));
158
+ var XCircle = base(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 9l-6 6M9 9l6 6" })
161
+ ] }));
162
+ var ArrowRight = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 12h14M13 6l6 6-6 6" }));
163
+ var Sort = base(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 9l4-4 4 4M8 15l4 4 4-4" }));
164
+ function DotsVertical({ className, ...props }) {
165
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: className ?? "pui-icon", "aria-hidden": "true", ...props, children: [
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "5", r: "1.6" }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "1.6" }),
168
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "19", r: "1.6" })
169
+ ] });
170
+ }
171
+
172
+ // src/utils.ts
173
+ function cx(...parts) {
174
+ return parts.filter(Boolean).join(" ");
175
+ }
176
+ function initials(name) {
177
+ const words = name.trim().split(/\s+/);
178
+ if (words.length === 0) return "?";
179
+ if (words.length === 1) return words[0].slice(0, 2).toUpperCase();
180
+ return (words[0][0] + words[words.length - 1][0]).toUpperCase();
181
+ }
182
+
183
+ // src/theme.tsx
184
+ var import_jsx_runtime2 = require("react/jsx-runtime");
185
+ var ThemeContext = React.createContext(null);
186
+ function ThemeProvider({
187
+ children,
188
+ defaultTheme = "light",
189
+ storageKey = "pui-theme",
190
+ attributeTarget = "html"
191
+ }) {
192
+ const [theme, setThemeState] = React.useState(defaultTheme);
193
+ React.useEffect(() => {
194
+ if (storageKey) {
195
+ const stored = window.localStorage.getItem(storageKey);
196
+ if (stored === "light" || stored === "dark") setThemeState(stored);
197
+ }
198
+ }, [storageKey]);
199
+ React.useEffect(() => {
200
+ if (attributeTarget === "html") {
201
+ document.documentElement.setAttribute("data-theme", theme);
202
+ }
203
+ if (storageKey) window.localStorage.setItem(storageKey, theme);
204
+ }, [theme, attributeTarget, storageKey]);
205
+ const value = React.useMemo(
206
+ () => ({
207
+ theme,
208
+ setTheme: setThemeState,
209
+ toggle: () => setThemeState((t) => t === "light" ? "dark" : "light")
210
+ }),
211
+ [theme]
212
+ );
213
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeContext.Provider, { value, children: attributeTarget === "self" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { "data-theme": theme, children }) : children });
214
+ }
215
+ function useTheme() {
216
+ const ctx = React.useContext(ThemeContext);
217
+ if (!ctx) throw new Error("useTheme must be used within a <ThemeProvider>");
218
+ return ctx;
219
+ }
220
+ function ThemeToggle({ className, ...props }) {
221
+ const { theme, toggle } = useTheme();
222
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
223
+ "button",
224
+ {
225
+ type: "button",
226
+ "aria-label": "Toggle color theme",
227
+ onClick: toggle,
228
+ className: cx("pui-btn", "pui-btn--secondary", "pui-btn--icon", className),
229
+ ...props,
230
+ children: theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Moon, { className: "pui-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Sun, { className: "pui-icon" })
231
+ }
232
+ );
233
+ }
234
+
235
+ // src/components/Button.tsx
236
+ var React2 = __toESM(require("react"), 1);
237
+ var import_jsx_runtime3 = require("react/jsx-runtime");
238
+ var Button = React2.forwardRef(function Button2({
239
+ variant = "primary",
240
+ size = "md",
241
+ loading = false,
242
+ iconOnly = false,
243
+ block = false,
244
+ leftIcon,
245
+ rightIcon,
246
+ disabled,
247
+ className,
248
+ children,
249
+ ...props
250
+ }, ref) {
251
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
252
+ "button",
253
+ {
254
+ ref,
255
+ disabled: disabled || loading,
256
+ className: cx(
257
+ "pui-btn",
258
+ `pui-btn--${variant}`,
259
+ size !== "md" && `pui-btn--${size}`,
260
+ iconOnly && "pui-btn--icon",
261
+ block && "pui-btn--block",
262
+ className
263
+ ),
264
+ ...props,
265
+ children: [
266
+ loading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pui-btn__spinner", "aria-hidden": "true" }),
267
+ !loading && leftIcon,
268
+ children,
269
+ !loading && rightIcon
270
+ ]
271
+ }
272
+ );
273
+ });
274
+
275
+ // src/components/Form.tsx
276
+ var React3 = __toESM(require("react"), 1);
277
+ var import_jsx_runtime4 = require("react/jsx-runtime");
278
+ function Field({ label, hint, error, htmlFor, children, className, style }) {
279
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cx("pui-field", className), style, children: [
280
+ label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "pui-label", htmlFor, children: label }),
281
+ children,
282
+ error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "pui-error", children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(XCircle, { style: { width: 13, height: 13 } }),
284
+ error
285
+ ] }) : hint && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "pui-hint", children: hint })
286
+ ] });
287
+ }
288
+ var Input = React3.forwardRef(function Input2({ invalid, className, ...props }, ref) {
289
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
290
+ "input",
291
+ {
292
+ ref,
293
+ "aria-invalid": invalid || void 0,
294
+ className: cx("pui-input", invalid && "pui-input--invalid", className),
295
+ ...props
296
+ }
297
+ );
298
+ });
299
+ var SearchInput = React3.forwardRef(function SearchInput2({ className, ...props }, ref) {
300
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "pui-input-wrap", children: [
301
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Search, { className: "pui-input-wrap__icon" }),
302
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Input, { ref, className, ...props })
303
+ ] });
304
+ });
305
+ var Textarea = React3.forwardRef(function Textarea2({ invalid, className, rows = 3, ...props }, ref) {
306
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
307
+ "textarea",
308
+ {
309
+ ref,
310
+ rows,
311
+ "aria-invalid": invalid || void 0,
312
+ className: cx("pui-textarea", invalid && "pui-textarea--invalid", className),
313
+ ...props
314
+ }
315
+ );
316
+ });
317
+ var Select = React3.forwardRef(function Select2({ options, className, children, ...props }, ref) {
318
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "pui-select-wrap", children: [
319
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("select", { ref, className: cx("pui-select", className), ...props, children: options ? options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: o.value, children: o.label }, o.value)) : children }),
320
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChevronDown, { className: "pui-select-wrap__caret" })
321
+ ] });
322
+ });
323
+ var Checkbox = React3.forwardRef(function Checkbox2({ label, disabled, className, ...props }, ref) {
324
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: cx("pui-checkbox", disabled && "pui-checkbox--disabled", className), children: [
325
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("input", { ref, type: "checkbox", disabled, ...props }),
326
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "pui-checkbox__box", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Check, {}) }),
327
+ label
328
+ ] });
329
+ });
330
+ var Switch = React3.forwardRef(function Switch2({ className, ...props }, ref) {
331
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: cx("pui-switch", className), children: [
332
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("input", { ref, type: "checkbox", role: "switch", ...props }),
333
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "pui-switch__track" })
334
+ ] });
335
+ });
336
+ function RadioGroup({ name, value, onValueChange, options, className }) {
337
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cx("pui-radio-group", className), role: "radiogroup", children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "pui-radio-card", children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
339
+ "input",
340
+ {
341
+ type: "radio",
342
+ name,
343
+ value: o.value,
344
+ checked: value === o.value,
345
+ onChange: () => onValueChange(o.value)
346
+ }
347
+ ),
348
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "pui-radio-card__dot" }),
349
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
350
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "pui-radio-card__title", children: o.title }),
351
+ o.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "pui-radio-card__desc", children: o.description })
352
+ ] })
353
+ ] }, o.value)) });
354
+ }
355
+ function Slider({ value, min = 0, max = 100, onValueChange, className, ...props }) {
356
+ const pct = (value - min) / (max - min) * 100;
357
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cx("pui-slider", className), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "pui-slider__row", children: [
358
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pui-slider__track" }),
359
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pui-slider__fill", style: { width: `${pct}%` } }),
360
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
361
+ "input",
362
+ {
363
+ type: "range",
364
+ min,
365
+ max,
366
+ value,
367
+ onChange: (e) => onValueChange(Number(e.target.value)),
368
+ ...props
369
+ }
370
+ )
371
+ ] }) });
372
+ }
373
+
374
+ // src/components/Display.tsx
375
+ var React4 = __toESM(require("react"), 1);
376
+ var import_jsx_runtime5 = require("react/jsx-runtime");
377
+ function Badge({ tone = "neutral", solid, dot, className, children, ...props }) {
378
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
379
+ "span",
380
+ {
381
+ className: cx("pui-badge", className),
382
+ "data-tone": tone === "neutral" ? void 0 : tone,
383
+ "data-solid": solid || void 0,
384
+ ...props,
385
+ children: [
386
+ dot && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pui-badge__dot" }),
387
+ children
388
+ ]
389
+ }
390
+ );
391
+ }
392
+ function Tag({ onRemove, className, children, ...props }) {
393
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: cx("pui-tag", className), ...props, children: [
394
+ children,
395
+ onRemove && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "pui-tag__close", "aria-label": "Remove", onClick: onRemove, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(X, {}) })
396
+ ] });
397
+ }
398
+ function Avatar({ name, src, size = "md", tone = "accent", status, className, ...props }) {
399
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
400
+ "span",
401
+ {
402
+ className: cx("pui-avatar", className),
403
+ "data-size": size,
404
+ "data-tone": tone === "accent" ? void 0 : tone,
405
+ title: name,
406
+ ...props,
407
+ children: [
408
+ src ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src, alt: name }) : initials(name),
409
+ status && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pui-avatar__status", "data-status": status })
410
+ ]
411
+ }
412
+ );
413
+ }
414
+ function AvatarGroup({ children, max, size = "md", className }) {
415
+ const items = React4.Children.toArray(children);
416
+ const shown = max ? items.slice(0, max) : items;
417
+ const extra = max ? items.length - shown.length : 0;
418
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cx("pui-avatar-group", className), children: [
419
+ shown,
420
+ extra > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "pui-avatar pui-avatar-group__more", "data-size": size, children: [
421
+ "+",
422
+ extra
423
+ ] })
424
+ ] });
425
+ }
426
+ function Card({ padded = true, className, children, ...props }) {
427
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cx("pui-card", padded && "pui-card--pad", className), ...props, children });
428
+ }
429
+ function StatCard({ label, value, delta, className }) {
430
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cx("pui-stat", className), children: [
431
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pui-stat__label", children: label }),
432
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pui-stat__value", children: value }),
433
+ delta && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pui-stat__delta", "data-dir": delta.direction, children: [
434
+ delta.direction === "up" ? "\u25B2" : "\u25BC",
435
+ " ",
436
+ delta.value
437
+ ] })
438
+ ] });
439
+ }
440
+ function Progress({ value, className, ...props }) {
441
+ const indeterminate = value == null;
442
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
443
+ "div",
444
+ {
445
+ className: cx("pui-progress", className),
446
+ "data-indeterminate": indeterminate || void 0,
447
+ role: "progressbar",
448
+ "aria-valuenow": indeterminate ? void 0 : value,
449
+ "aria-valuemin": 0,
450
+ "aria-valuemax": 100,
451
+ ...props,
452
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pui-progress__bar", style: indeterminate ? void 0 : { width: `${value}%` } })
453
+ }
454
+ );
455
+ }
456
+ function Spinner({ size = 30, className, style, ...props }) {
457
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { role: "status", "aria-label": "Loading", className: cx("pui-spinner", className), style: { width: size, height: size, ...style }, ...props });
458
+ }
459
+ function Skeleton({ width, height = 11, className, style, ...props }) {
460
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cx("pui-skeleton", className), style: { width, height, ...style }, ...props });
461
+ }
462
+ function EmptyState({ icon, title, description, action, className }) {
463
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cx("pui-empty", className), children: [
464
+ icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pui-empty__icon", children: icon }),
465
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pui-empty__title", children: title }),
466
+ description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pui-empty__desc", children: description }),
467
+ action && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginTop: 10 }, children: action })
468
+ ] });
469
+ }
470
+
471
+ // src/components/Accordion.tsx
472
+ var React5 = __toESM(require("react"), 1);
473
+ var import_jsx_runtime6 = require("react/jsx-runtime");
474
+ var AccordionContext = React5.createContext(null);
475
+ function Accordion({ children, type = "single", defaultValue, className }) {
476
+ const [open, setOpen] = React5.useState(
477
+ defaultValue == null ? [] : Array.isArray(defaultValue) ? defaultValue : [defaultValue]
478
+ );
479
+ const value = React5.useMemo(
480
+ () => ({
481
+ isOpen: (v) => open.includes(v),
482
+ toggle: (v) => setOpen((prev) => {
483
+ const has = prev.includes(v);
484
+ if (type === "single") return has ? [] : [v];
485
+ return has ? prev.filter((x) => x !== v) : [...prev, v];
486
+ })
487
+ }),
488
+ [open, type]
489
+ );
490
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cx("pui-accordion", className), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AccordionContext.Provider, { value, children }) });
491
+ }
492
+ function AccordionItem({ value, title, children }) {
493
+ const ctx = React5.useContext(AccordionContext);
494
+ if (!ctx) throw new Error("AccordionItem must be used within <Accordion>");
495
+ const open = ctx.isOpen(value);
496
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "pui-accordion__item", "data-open": open || void 0, children: [
497
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
498
+ "button",
499
+ {
500
+ type: "button",
501
+ className: "pui-accordion__trigger",
502
+ "aria-expanded": open,
503
+ onClick: () => ctx.toggle(value),
504
+ children: [
505
+ title,
506
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronDown, { className: "pui-accordion__chevron" })
507
+ ]
508
+ }
509
+ ),
510
+ open && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pui-accordion__panel", children })
511
+ ] });
512
+ }
513
+
514
+ // src/components/Tabs.tsx
515
+ var React6 = __toESM(require("react"), 1);
516
+ var import_jsx_runtime7 = require("react/jsx-runtime");
517
+ var TabsContext = React6.createContext(null);
518
+ function Tabs({ children, defaultValue, value, onValueChange, className }) {
519
+ const [internal, setInternal] = React6.useState(defaultValue);
520
+ const current = value ?? internal;
521
+ const setValue = (v) => {
522
+ if (value === void 0) setInternal(v);
523
+ onValueChange?.(v);
524
+ };
525
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TabsContext.Provider, { value: { value: current, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className, children }) });
526
+ }
527
+ function useTabs(component) {
528
+ const ctx = React6.useContext(TabsContext);
529
+ if (!ctx) throw new Error(`${component} must be used within <Tabs>`);
530
+ return ctx;
531
+ }
532
+ function TabList({ children, className }) {
533
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "tablist", className: cx("pui-tabs__list", className), children });
534
+ }
535
+ function Tab({ value, children }) {
536
+ const ctx = useTabs("Tab");
537
+ const active = ctx.value === value;
538
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
539
+ "button",
540
+ {
541
+ type: "button",
542
+ role: "tab",
543
+ "aria-selected": active,
544
+ "data-active": active || void 0,
545
+ className: "pui-tabs__tab",
546
+ onClick: () => ctx.setValue(value),
547
+ children
548
+ }
549
+ );
550
+ }
551
+ function TabPanel({ value, children, className }) {
552
+ const ctx = useTabs("TabPanel");
553
+ if (ctx.value !== value) return null;
554
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "tabpanel", className: cx("pui-tabs__panel", className), children });
555
+ }
556
+
557
+ // src/components/Navigation.tsx
558
+ var React7 = __toESM(require("react"), 1);
559
+ var import_jsx_runtime8 = require("react/jsx-runtime");
560
+ function Breadcrumbs({ items, className }) {
561
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("nav", { "aria-label": "Breadcrumb", className: cx("pui-breadcrumbs", className), children: items.map((c, i) => {
562
+ const last = i === items.length - 1;
563
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(React7.Fragment, { children: [
564
+ last || !c.href ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: last ? "pui-breadcrumbs__current" : void 0, "aria-current": last ? "page" : void 0, children: c.label }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: c.href, children: c.label }),
565
+ !last && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronRight, { className: "pui-breadcrumbs__sep" })
566
+ ] }, i);
567
+ }) });
568
+ }
569
+ function range(start, end) {
570
+ return Array.from({ length: end - start + 1 }, (_, i) => start + i);
571
+ }
572
+ function Pagination({ page, count, onChange, siblings = 1, className }) {
573
+ const pages = React7.useMemo(() => {
574
+ const total = count;
575
+ const left = Math.max(2, page - siblings);
576
+ const right = Math.min(total - 1, page + siblings);
577
+ const out = [1];
578
+ if (left > 2) out.push("\u2026");
579
+ out.push(...range(left, right));
580
+ if (right < total - 1) out.push("\u2026");
581
+ if (total > 1) out.push(total);
582
+ return out.filter((v, i, a) => v !== a[i - 1]);
583
+ }, [page, count, siblings]);
584
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("nav", { className: cx("pui-pagination", className), "aria-label": "Pagination", children: [
585
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { className: "pui-pagination__btn", disabled: page <= 1, onClick: () => onChange(page - 1), children: [
586
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronLeft, {}),
587
+ "Prev"
588
+ ] }),
589
+ pages.map(
590
+ (p, i) => p === "\u2026" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pui-pagination__ellipsis", children: "\u2026" }, `e${i}`) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
591
+ "button",
592
+ {
593
+ className: "pui-pagination__btn",
594
+ "data-active": p === page || void 0,
595
+ "aria-current": p === page ? "page" : void 0,
596
+ onClick: () => onChange(p),
597
+ children: p
598
+ },
599
+ p
600
+ )
601
+ ),
602
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { className: "pui-pagination__btn", disabled: page >= count, onClick: () => onChange(page + 1), children: [
603
+ "Next",
604
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronRight, {})
605
+ ] })
606
+ ] });
607
+ }
608
+ function Segmented({ options, value, onValueChange, className }) {
609
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cx("pui-segmented", className), role: "tablist", children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
610
+ "button",
611
+ {
612
+ type: "button",
613
+ role: "tab",
614
+ "aria-selected": value === o.value,
615
+ "data-active": value === o.value || void 0,
616
+ className: "pui-segmented__btn",
617
+ onClick: () => onValueChange(o.value),
618
+ children: o.label
619
+ },
620
+ o.value
621
+ )) });
622
+ }
623
+
624
+ // src/components/Table.tsx
625
+ var React8 = __toESM(require("react"), 1);
626
+ var import_jsx_runtime9 = require("react/jsx-runtime");
627
+ function Table({ columns, data, rowKey, className }) {
628
+ const [sort, setSort] = React8.useState(null);
629
+ const sorted = React8.useMemo(() => {
630
+ if (!sort) return data;
631
+ const col = columns.find((c) => c.key === sort.key);
632
+ if (!col?.sortValue) return data;
633
+ const next = [...data].sort((a, b) => {
634
+ const va = col.sortValue(a);
635
+ const vb = col.sortValue(b);
636
+ if (va < vb) return sort.dir === "asc" ? -1 : 1;
637
+ if (va > vb) return sort.dir === "asc" ? 1 : -1;
638
+ return 0;
639
+ });
640
+ return next;
641
+ }, [data, columns, sort]);
642
+ const onSort = (col) => {
643
+ if (!col.sortable) return;
644
+ setSort(
645
+ (prev) => prev?.key === col.key ? { key: col.key, dir: prev.dir === "asc" ? "desc" : "asc" } : { key: col.key, dir: "asc" }
646
+ );
647
+ };
648
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cx("pui-table-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: "pui-table", children: [
649
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
650
+ "th",
651
+ {
652
+ "data-sortable": col.sortable || void 0,
653
+ onClick: () => onSort(col),
654
+ style: { width: col.width, textAlign: col.align },
655
+ children: col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "pui-table__sort", children: [
656
+ col.header,
657
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Sort, { style: { width: 13, height: 13 } })
658
+ ] }) : col.header
659
+ },
660
+ col.key
661
+ )) }) }),
662
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { children: sorted.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { style: { textAlign: col.align }, children: col.cell(row) }, col.key)) }, rowKey(row, i))) })
663
+ ] }) });
664
+ }
665
+
666
+ // src/components/Alert.tsx
667
+ var import_jsx_runtime10 = require("react/jsx-runtime");
668
+ var ICONS = {
669
+ info: Info,
670
+ success: CheckCircle,
671
+ warning: AlertTriangle,
672
+ danger: XCircle
673
+ };
674
+ function Alert({ tone = "info", title, onDismiss, className, children, ...props }) {
675
+ const Icon = ICONS[tone];
676
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cx("pui-alert", className), "data-tone": tone === "info" ? void 0 : tone, role: "alert", ...props, children: [
677
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { className: "pui-alert__icon" }),
678
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { flex: 1 }, children: [
679
+ title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pui-alert__title", children: title }),
680
+ children && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pui-alert__body", children })
681
+ ] }),
682
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "pui-alert__close", "aria-label": "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(X, { style: { width: 16, height: 16 } }) })
683
+ ] });
684
+ }
685
+
686
+ // src/components/Toast.tsx
687
+ var React9 = __toESM(require("react"), 1);
688
+ var import_jsx_runtime11 = require("react/jsx-runtime");
689
+ var ToastContext = React9.createContext(null);
690
+ var ICONS2 = { info: Info, success: CheckCircle, danger: XCircle };
691
+ function ToastProvider({ children }) {
692
+ const [items, setItems] = React9.useState([]);
693
+ const timers = React9.useRef({});
694
+ const dismiss = React9.useCallback((id) => {
695
+ setItems((prev) => prev.filter((t) => t.id !== id));
696
+ if (timers.current[id]) {
697
+ clearTimeout(timers.current[id]);
698
+ delete timers.current[id];
699
+ }
700
+ }, []);
701
+ const toast = React9.useCallback(
702
+ (opts) => {
703
+ const id = Date.now() + Math.random();
704
+ setItems((prev) => [...prev, { id, ...opts }]);
705
+ const duration = opts.duration ?? 4500;
706
+ if (duration > 0) timers.current[id] = setTimeout(() => dismiss(id), duration);
707
+ return id;
708
+ },
709
+ [dismiss]
710
+ );
711
+ React9.useEffect(() => () => Object.values(timers.current).forEach(clearTimeout), []);
712
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ToastContext.Provider, { value: { toast, dismiss }, children: [
713
+ children,
714
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pui-toast-region", role: "region", "aria-label": "Notifications", children: items.map((t) => {
715
+ const Icon = ICONS2[t.tone ?? "info"];
716
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "pui-toast", children: [
717
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "pui-toast__icon", "data-tone": t.tone ?? "info", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, {}) }),
718
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
719
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pui-toast__title", children: t.title }),
720
+ t.description && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pui-toast__desc", children: t.description })
721
+ ] }),
722
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "pui-toast__close", "aria-label": "Dismiss", onClick: () => dismiss(t.id), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(X, { style: { width: 15, height: 15 } }) })
723
+ ] }, t.id);
724
+ }) })
725
+ ] });
726
+ }
727
+ function useToast() {
728
+ const ctx = React9.useContext(ToastContext);
729
+ if (!ctx) throw new Error("useToast must be used within a <ToastProvider>");
730
+ return ctx;
731
+ }
732
+
733
+ // src/components/Overlay.tsx
734
+ var React10 = __toESM(require("react"), 1);
735
+ var import_jsx_runtime12 = require("react/jsx-runtime");
736
+ function Tooltip({ label, children, className }) {
737
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: cx("pui-tooltip", className), children: [
738
+ children,
739
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { role: "tooltip", className: "pui-tooltip__bubble", children: label })
740
+ ] });
741
+ }
742
+ function useDismiss(open, onClose) {
743
+ const ref = React10.useRef(null);
744
+ React10.useEffect(() => {
745
+ if (!open) return;
746
+ const onClick = (e) => {
747
+ if (ref.current && !ref.current.contains(e.target)) onClose();
748
+ };
749
+ const onKey = (e) => e.key === "Escape" && onClose();
750
+ document.addEventListener("mousedown", onClick);
751
+ document.addEventListener("keydown", onKey);
752
+ return () => {
753
+ document.removeEventListener("mousedown", onClick);
754
+ document.removeEventListener("keydown", onKey);
755
+ };
756
+ }, [open, onClose]);
757
+ return ref;
758
+ }
759
+ function DropdownMenu({ trigger, children, items, align = "start", className }) {
760
+ const [open, setOpen] = React10.useState(false);
761
+ const ref = useDismiss(open, () => setOpen(false));
762
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cx("pui-menu", className), ref, children: [
763
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { onClick: () => setOpen((o) => !o), children: trigger }),
764
+ open && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pui-menu__panel", "data-align": align, role: "menu", children: items ? items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
765
+ "button",
766
+ {
767
+ type: "button",
768
+ role: "menuitem",
769
+ className: "pui-menu__item",
770
+ "data-tone": item.tone === "danger" ? "danger" : void 0,
771
+ onClick: () => {
772
+ item.onSelect?.();
773
+ setOpen(false);
774
+ },
775
+ children: [
776
+ item.icon,
777
+ item.label
778
+ ]
779
+ },
780
+ i
781
+ )) : children })
782
+ ] });
783
+ }
784
+ function MenuSeparator() {
785
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pui-menu__sep" });
786
+ }
787
+ function Modal({ open, onClose, title, children, footer, icon }) {
788
+ React10.useEffect(() => {
789
+ if (!open) return;
790
+ const onKey = (e) => e.key === "Escape" && onClose();
791
+ document.addEventListener("keydown", onKey);
792
+ return () => document.removeEventListener("keydown", onKey);
793
+ }, [open, onClose]);
794
+ if (!open) return null;
795
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pui-overlay", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "pui-dialog", role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [
796
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "pui-dialog__head", children: [
797
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", gap: 13, alignItems: "flex-start" }, children: [
798
+ icon,
799
+ title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pui-dialog__title", children: title })
800
+ ] }),
801
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "pui-dialog__close", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(X, { style: { width: 20, height: 20 } }) })
802
+ ] }),
803
+ children && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pui-dialog__body", children }),
804
+ footer && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pui-dialog__footer", children: footer })
805
+ ] }) });
806
+ }
807
+
808
+ // src/components/Extras.tsx
809
+ var React11 = __toESM(require("react"), 1);
810
+ var import_jsx_runtime13 = require("react/jsx-runtime");
811
+ function Separator({ orientation = "horizontal", className, ...props }) {
812
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
813
+ "div",
814
+ {
815
+ role: "separator",
816
+ "aria-orientation": orientation,
817
+ "data-orientation": orientation,
818
+ className: cx("pui-separator", className),
819
+ ...props
820
+ }
821
+ );
822
+ }
823
+ function Kbd({ children, className }) {
824
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("kbd", { className: cx("pui-kbd", className), children });
825
+ }
826
+ function Link({ external, className, children, ...props }) {
827
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
828
+ "a",
829
+ {
830
+ className: cx("pui-link", className),
831
+ ...external ? { target: "_blank", rel: "noreferrer" } : {},
832
+ ...props,
833
+ children
834
+ }
835
+ );
836
+ }
837
+ function useDismiss2(open, onClose) {
838
+ const ref = React11.useRef(null);
839
+ React11.useEffect(() => {
840
+ if (!open) return;
841
+ const onClick = (e) => {
842
+ if (ref.current && !ref.current.contains(e.target)) onClose();
843
+ };
844
+ const onKey = (e) => e.key === "Escape" && onClose();
845
+ document.addEventListener("mousedown", onClick);
846
+ document.addEventListener("keydown", onKey);
847
+ return () => {
848
+ document.removeEventListener("mousedown", onClick);
849
+ document.removeEventListener("keydown", onKey);
850
+ };
851
+ }, [open, onClose]);
852
+ return ref;
853
+ }
854
+ function Popover({ trigger, children, align = "start", className }) {
855
+ const [open, setOpen] = React11.useState(false);
856
+ const ref = useDismiss2(open, () => setOpen(false));
857
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cx("pui-menu", className), ref, children: [
858
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { onClick: () => setOpen((o) => !o), children: trigger }),
859
+ open && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pui-popover", "data-align": align, role: "dialog", children })
860
+ ] });
861
+ }
862
+ function Drawer({ open, onClose, side = "right", title, children, footer }) {
863
+ React11.useEffect(() => {
864
+ if (!open) return;
865
+ const onKey = (e) => e.key === "Escape" && onClose();
866
+ document.addEventListener("keydown", onKey);
867
+ return () => document.removeEventListener("keydown", onKey);
868
+ }, [open, onClose]);
869
+ if (!open) return null;
870
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pui-drawer-overlay", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "pui-drawer", "data-side": side, role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [
871
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "pui-drawer__head", children: [
872
+ title && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pui-drawer__title", children: title }),
873
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "pui-dialog__close", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(X, { style: { width: 20, height: 20 } }) })
874
+ ] }),
875
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pui-drawer__body", children }),
876
+ footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pui-drawer__footer", children: footer })
877
+ ] }) });
878
+ }
879
+ function ToggleGroup({ options, value, onValueChange, className }) {
880
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cx("pui-toggle-group", className), role: "group", children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
881
+ "button",
882
+ {
883
+ type: "button",
884
+ "aria-pressed": value === o.value,
885
+ "data-active": value === o.value || void 0,
886
+ className: "pui-toggle",
887
+ onClick: () => onValueChange(o.value),
888
+ children: [
889
+ o.icon,
890
+ o.label
891
+ ]
892
+ },
893
+ o.value
894
+ )) });
895
+ }
896
+ function Stepper({ steps, current, className }) {
897
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ol", { className: cx("pui-stepper", className), children: steps.map((s, i) => {
898
+ const state = i < current ? "done" : i === current ? "current" : "upcoming";
899
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("li", { className: "pui-step", "data-state": state, children: [
900
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pui-step__marker", children: i < current ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Check, {}) : i + 1 }),
901
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "pui-step__body", children: [
902
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pui-step__label", children: s.label }),
903
+ s.description && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pui-step__desc", children: s.description })
904
+ ] })
905
+ ] }, i);
906
+ }) });
907
+ }
908
+ function CodeBlock({ code, filename, className }) {
909
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cx("pui-code", className), children: [
910
+ filename && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "pui-code__bar", children: filename }),
911
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { className: "pui-code__pre", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("code", { children: code }) })
912
+ ] });
913
+ }
914
+ function List({ children, className }) {
915
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ul", { className: cx("pui-list", className), children });
916
+ }
917
+ function ListItem({ children, className, ...props }) {
918
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: cx("pui-list-item", className), ...props, children });
919
+ }
920
+ // Annotate the CommonJS export names for ESM import in node:
921
+ 0 && (module.exports = {
922
+ Accordion,
923
+ AccordionItem,
924
+ Alert,
925
+ Avatar,
926
+ AvatarGroup,
927
+ Badge,
928
+ Breadcrumbs,
929
+ Button,
930
+ Card,
931
+ Checkbox,
932
+ CodeBlock,
933
+ Drawer,
934
+ DropdownMenu,
935
+ EmptyState,
936
+ Field,
937
+ Icons,
938
+ Input,
939
+ Kbd,
940
+ Link,
941
+ List,
942
+ ListItem,
943
+ MenuSeparator,
944
+ Modal,
945
+ Pagination,
946
+ Popover,
947
+ Progress,
948
+ RadioGroup,
949
+ SearchInput,
950
+ Segmented,
951
+ Select,
952
+ Separator,
953
+ Skeleton,
954
+ Slider,
955
+ Spinner,
956
+ StatCard,
957
+ Stepper,
958
+ Switch,
959
+ Tab,
960
+ TabList,
961
+ TabPanel,
962
+ Table,
963
+ Tabs,
964
+ Tag,
965
+ Textarea,
966
+ ThemeProvider,
967
+ ThemeToggle,
968
+ ToastProvider,
969
+ ToggleGroup,
970
+ Tooltip,
971
+ cx,
972
+ initials,
973
+ useTheme,
974
+ useToast
975
+ });
976
+ //# sourceMappingURL=index.cjs.map