@caqophony/ui 0.3.0 → 0.4.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.
@@ -0,0 +1,379 @@
1
+ 'use client';
2
+ import {
3
+ Icon
4
+ } from "./chunk-BAW3RIMF.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-DP5WQAPO.js";
8
+
9
+ // src/spinner.tsx
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ function Spinner(props) {
12
+ const { size = "md", className } = props;
13
+ const glyph = /* @__PURE__ */ jsx(Icon, { name: "loader", size, className: "animate-spin" });
14
+ if (props.decorative)
15
+ return /* @__PURE__ */ jsx(
16
+ "span",
17
+ {
18
+ "aria-hidden": "true",
19
+ className: cn("inline-flex shrink-0 text-current", className),
20
+ children: glyph
21
+ }
22
+ );
23
+ return /* @__PURE__ */ jsxs(
24
+ "span",
25
+ {
26
+ role: "status",
27
+ className: cn("inline-flex shrink-0 text-current", className),
28
+ children: [
29
+ glyph,
30
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: props.label })
31
+ ]
32
+ }
33
+ );
34
+ }
35
+
36
+ // src/button.tsx
37
+ import { Slot } from "@radix-ui/react-slot";
38
+ import { cva } from "class-variance-authority";
39
+ import * as React from "react";
40
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
41
+ var buttonVariants = cva(
42
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
43
+ {
44
+ variants: {
45
+ variant: {
46
+ default: "bg-primary-solid text-primary-foreground shadow hover:bg-[color:color-mix(in_oklab,hsl(var(--primary-solid))_85%,black)]",
47
+ destructive: "bg-intent-error-solid text-intent-error-solid-fg shadow-sm hover:bg-[color:color-mix(in_oklab,hsl(var(--intent-error-solid))_85%,black)]",
48
+ outline: "border border-border dark:border-border bg-background dark:bg-background text-foreground dark:text-foreground shadow-sm hover:bg-muted dark:hover:bg-muted hover:text-foreground dark:hover:text-foreground",
49
+ secondary: "bg-muted dark:bg-muted text-muted-foreground dark:text-muted-foreground shadow-sm hover:bg-muted/80 dark:hover:bg-muted/80",
50
+ ghost: "hover:bg-muted dark:hover:bg-muted hover:text-foreground dark:hover:text-foreground",
51
+ link: "text-primary-text dark:text-primary-text underline-offset-4 hover:underline"
52
+ },
53
+ size: {
54
+ default: "h-10 px-4 py-2",
55
+ sm: "h-9 rounded-md px-3",
56
+ lg: "h-11 rounded-md px-8",
57
+ icon: "size-10"
58
+ }
59
+ },
60
+ defaultVariants: {
61
+ variant: "default",
62
+ size: "default"
63
+ }
64
+ }
65
+ );
66
+ var Button = React.forwardRef(
67
+ ({
68
+ className,
69
+ variant,
70
+ size,
71
+ asChild = false,
72
+ loading = false,
73
+ loadingText,
74
+ children,
75
+ disabled,
76
+ ...props
77
+ }, ref) => {
78
+ const Comp = asChild && !loading ? Slot : "button";
79
+ const isDisabled = disabled || loading;
80
+ return /* @__PURE__ */ jsx2(
81
+ Comp,
82
+ {
83
+ className: cn(buttonVariants({ variant, size, className })),
84
+ ref,
85
+ disabled: isDisabled,
86
+ "aria-busy": loading,
87
+ ...props,
88
+ children: loading ? /* @__PURE__ */ jsxs2(Fragment, { children: [
89
+ /* @__PURE__ */ jsx2(Spinner, { decorative: true, size: "sm" }),
90
+ /* @__PURE__ */ jsx2("span", { children: loadingText || children })
91
+ ] }) : children
92
+ }
93
+ );
94
+ }
95
+ );
96
+ Button.displayName = "Button";
97
+
98
+ // src/container.tsx
99
+ import * as React2 from "react";
100
+
101
+ // src/content-gutter.ts
102
+ var CONTENT_GUTTER = "px-4 sm:px-6 lg:px-8";
103
+
104
+ // src/container.tsx
105
+ import { jsx as jsx3 } from "react/jsx-runtime";
106
+ var SIZE_CLASSES = {
107
+ sm: "max-w-content-sm",
108
+ md: "max-w-content-md",
109
+ lg: "max-w-content-lg",
110
+ xl: "max-w-content-xl",
111
+ full: "max-w-full"
112
+ };
113
+ var Container = React2.forwardRef(
114
+ ({ className, size = "xl", padded = true, ...props }, ref) => /* @__PURE__ */ jsx3(
115
+ "div",
116
+ {
117
+ ref,
118
+ className: cn(
119
+ "mx-auto w-full",
120
+ SIZE_CLASSES[size],
121
+ padded && CONTENT_GUTTER,
122
+ className
123
+ ),
124
+ ...props
125
+ }
126
+ )
127
+ );
128
+ Container.displayName = "Container";
129
+
130
+ // src/modal-surface.ts
131
+ import * as React3 from "react";
132
+ import { createPortal } from "react-dom";
133
+ var TABBABLE = "a[href], button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]";
134
+ var neverChanges = () => () => void 0;
135
+ var tabStops = (panel) => [...panel.querySelectorAll(TABBABLE)].filter(
136
+ (el) => el.tabIndex >= 0 && el.getClientRects().length > 0 && getComputedStyle(el).visibility === "visible"
137
+ );
138
+ function holdFocus(panel) {
139
+ if (!panel.hasAttribute("tabindex")) panel.tabIndex = -1;
140
+ panel.focus();
141
+ }
142
+ var surfaces = [];
143
+ function onKey(e) {
144
+ const top = surfaces[surfaces.length - 1];
145
+ const box = top?.panel.current;
146
+ if (!top || !box) return;
147
+ const at = document.activeElement;
148
+ if (at && !box.contains(at) && box.compareDocumentPosition(at) & Node.DOCUMENT_POSITION_FOLLOWING)
149
+ return;
150
+ if (e.key === "Escape" && !e.defaultPrevented) top.escape.current?.();
151
+ if (e.key !== "Tab") return;
152
+ const stops = tabStops(box);
153
+ const first = stops[0];
154
+ const last = stops[stops.length - 1];
155
+ if (!first || !last) {
156
+ e.preventDefault();
157
+ holdFocus(box);
158
+ return;
159
+ }
160
+ const inside = box.contains(at);
161
+ if (e.shiftKey && (at === first || !inside)) {
162
+ e.preventDefault();
163
+ last.focus();
164
+ } else if (!e.shiftKey && (at === last || !inside)) {
165
+ e.preventDefault();
166
+ first.focus();
167
+ }
168
+ }
169
+ function enter(surface) {
170
+ if (surfaces.length === 0) document.addEventListener("keydown", onKey);
171
+ surfaces.push(surface);
172
+ return () => {
173
+ surfaces.splice(surfaces.indexOf(surface), 1);
174
+ if (surfaces.length === 0) document.removeEventListener("keydown", onKey);
175
+ };
176
+ }
177
+ function usePanelRef(forwarded) {
178
+ const panel = React3.useRef(null);
179
+ const setPanel = React3.useCallback(
180
+ (el) => {
181
+ panel.current = el;
182
+ if (typeof forwarded === "function") forwarded(el);
183
+ else if (forwarded) forwarded.current = el;
184
+ },
185
+ [forwarded]
186
+ );
187
+ return [panel, setPanel];
188
+ }
189
+ function useModalSurface(open, panel, onEscape) {
190
+ const hydrated = React3.useSyncExternalStore(
191
+ neverChanges,
192
+ () => true,
193
+ () => false
194
+ );
195
+ const escape = React3.useRef(onEscape);
196
+ React3.useEffect(() => {
197
+ escape.current = onEscape;
198
+ });
199
+ const active = open && hydrated;
200
+ const opener = React3.useRef(null);
201
+ React3.useInsertionEffect(() => {
202
+ if (active) opener.current = document.activeElement;
203
+ }, [active]);
204
+ React3.useEffect(() => {
205
+ const box = panel.current;
206
+ if (!active || !box) return;
207
+ if (!box.contains(document.activeElement)) {
208
+ const first = tabStops(box)[0];
209
+ if (first) first.focus();
210
+ else holdFocus(box);
211
+ }
212
+ const leave = enter({ panel, escape });
213
+ return () => {
214
+ leave();
215
+ const nowhere = !document.activeElement || document.activeElement === document.body;
216
+ const back = opener.current;
217
+ if (nowhere && back instanceof HTMLElement) back.focus();
218
+ };
219
+ }, [active, panel]);
220
+ return (surface) => hydrated ? createPortal(surface, document.body) : surface;
221
+ }
222
+
223
+ // src/nav-drawer.tsx
224
+ import * as React4 from "react";
225
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
226
+ function NavDrawer({
227
+ label,
228
+ side,
229
+ closedFrom,
230
+ defaultOpen,
231
+ children,
232
+ triggerClassName
233
+ }) {
234
+ const [open, setOpen] = React4.useState(defaultOpen);
235
+ const id = React4.useId();
236
+ const menuButton = React4.useRef(null);
237
+ const overlay = React4.useRef(null);
238
+ const panel = React4.useRef(null);
239
+ const close = React4.useCallback(() => {
240
+ setOpen(false);
241
+ menuButton.current?.focus();
242
+ }, []);
243
+ const place = useModalSurface(open, panel, close);
244
+ React4.useEffect(() => {
245
+ if (!open) return;
246
+ const onClick = (e) => {
247
+ const el = panel.current;
248
+ if (el && e.composedPath().includes(el) && e.target instanceof Element && e.target.closest("a"))
249
+ close();
250
+ };
251
+ document.addEventListener("click", onClick);
252
+ return () => document.removeEventListener("click", onClick);
253
+ }, [open, close]);
254
+ React4.useEffect(() => {
255
+ if (!open || closedFrom === null) return;
256
+ const onResize = () => {
257
+ if (overlay.current && getComputedStyle(overlay.current).display === "none")
258
+ setOpen(false);
259
+ };
260
+ onResize();
261
+ window.addEventListener("resize", onResize);
262
+ return () => window.removeEventListener("resize", onResize);
263
+ }, [open, closedFrom]);
264
+ const left = side === "left";
265
+ const drawer = open ? /* @__PURE__ */ jsxs3(
266
+ "div",
267
+ {
268
+ ref: overlay,
269
+ className: cn(
270
+ "z-overlay fixed inset-0",
271
+ closedFrom === "md" && "md:hidden",
272
+ closedFrom === "lg" && "lg:hidden"
273
+ ),
274
+ children: [
275
+ /* @__PURE__ */ jsx4(
276
+ "div",
277
+ {
278
+ "aria-hidden": "true",
279
+ className: "absolute inset-0 bg-foreground/40",
280
+ onClick: close
281
+ }
282
+ ),
283
+ /* @__PURE__ */ jsxs3(
284
+ "div",
285
+ {
286
+ ref: panel,
287
+ id,
288
+ role: "dialog",
289
+ "aria-modal": "true",
290
+ "aria-label": label,
291
+ className: cn(
292
+ "absolute inset-y-0 flex w-72 max-w-[calc(100%-3rem)] flex-col overflow-y-auto bg-card shadow-lg",
293
+ left ? "left-0 border-r" : "right-0 border-l",
294
+ "border-border"
295
+ ),
296
+ children: [
297
+ /* @__PURE__ */ jsx4(
298
+ "div",
299
+ {
300
+ className: cn(
301
+ "flex px-2 py-2",
302
+ left ? "justify-end" : "justify-start"
303
+ ),
304
+ children: /* @__PURE__ */ jsx4(
305
+ Button,
306
+ {
307
+ variant: "ghost",
308
+ size: "icon",
309
+ "aria-label": "Close",
310
+ onClick: close,
311
+ children: /* @__PURE__ */ jsx4(Icon, { name: "x", size: "sm" })
312
+ }
313
+ )
314
+ }
315
+ ),
316
+ children
317
+ ]
318
+ }
319
+ )
320
+ ]
321
+ }
322
+ ) : null;
323
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
324
+ /* @__PURE__ */ jsx4(
325
+ Button,
326
+ {
327
+ ref: menuButton,
328
+ variant: "ghost",
329
+ size: "icon",
330
+ "aria-label": label,
331
+ "aria-expanded": open,
332
+ "aria-controls": open ? id : void 0,
333
+ className: triggerClassName,
334
+ onClick: () => setOpen(!open),
335
+ children: /* @__PURE__ */ jsx4(Icon, { name: "menu", size: "sm" })
336
+ }
337
+ ),
338
+ drawer && place(drawer)
339
+ ] });
340
+ }
341
+
342
+ // src/navbar-menu.tsx
343
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
344
+ function NavbarMenu({
345
+ search,
346
+ links,
347
+ actions,
348
+ defaultOpen = false,
349
+ triggerClassName,
350
+ folded = false
351
+ }) {
352
+ return /* @__PURE__ */ jsx5("div", { className: folded ? "ml-auto" : "ml-auto md:hidden", children: /* @__PURE__ */ jsxs4(
353
+ NavDrawer,
354
+ {
355
+ label: "Navigation",
356
+ side: "right",
357
+ closedFrom: folded ? null : "md",
358
+ defaultOpen,
359
+ triggerClassName,
360
+ children: [
361
+ search && /* @__PURE__ */ jsx5("div", { className: "px-4 pb-3", children: search }),
362
+ links && /* @__PURE__ */ jsx5("nav", { className: "flex flex-col px-4 pb-3 [&>a]:whitespace-normal [&>a]:py-2.5 [&>a]:text-base", children: links }),
363
+ actions && /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-2 border-t border-border p-4 [&>*]:w-full", children: actions })
364
+ ]
365
+ }
366
+ ) });
367
+ }
368
+
369
+ export {
370
+ Spinner,
371
+ buttonVariants,
372
+ Button,
373
+ usePanelRef,
374
+ useModalSurface,
375
+ NavDrawer,
376
+ CONTENT_GUTTER,
377
+ NavbarMenu,
378
+ Container
379
+ };
@@ -0,0 +1,126 @@
1
+ 'use client';
2
+ import {
3
+ Icon
4
+ } from "./chunk-BAW3RIMF.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-DP5WQAPO.js";
8
+
9
+ // src/empty-value.tsx
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var EMPTY_VALUE_GLYPH = "\u2014";
12
+ function isEmptyValue(value) {
13
+ return value === null || value === void 0 || value === false || typeof value === "string" && value.trim() === "";
14
+ }
15
+ function EmptyValue({ className }) {
16
+ return /* @__PURE__ */ jsxs("span", { "data-empty-value": true, className: cn("text-muted-foreground", className), children: [
17
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: EMPTY_VALUE_GLYPH }),
18
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Not set" })
19
+ ] });
20
+ }
21
+
22
+ // src/alert.tsx
23
+ import * as React from "react";
24
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
25
+ var INTENT_SUBTLE_STYLES = {
26
+ success: "bg-intent-success/10 text-intent-success-foreground border-intent-success/20",
27
+ warning: "bg-intent-warning/10 text-intent-warning-foreground border-intent-warning/20",
28
+ error: "bg-intent-error/10 text-intent-error-foreground border-intent-error/20",
29
+ info: "bg-intent-info/10 text-intent-info-foreground border-intent-info/20"
30
+ };
31
+ var SOLID_STYLES = {
32
+ success: "border-transparent bg-intent-success-solid text-intent-success-solid-fg",
33
+ warning: "border-transparent bg-intent-warning-solid text-intent-warning-solid-fg",
34
+ error: "border-transparent bg-intent-error-solid text-intent-error-solid-fg",
35
+ info: "border-transparent bg-intent-info-solid text-intent-info-solid-fg"
36
+ };
37
+ var OUTLINE_STYLES = {
38
+ success: "border-intent-success-border text-intent-success-foreground bg-background",
39
+ warning: "border-intent-warning-border text-intent-warning-foreground bg-background",
40
+ error: "border-intent-error-border text-intent-error-foreground bg-background",
41
+ info: "border-intent-info-border text-intent-info-foreground bg-background"
42
+ };
43
+ var ICON_MAP = {
44
+ success: "circle-check",
45
+ warning: "triangle-alert",
46
+ error: "circle-alert",
47
+ info: "info"
48
+ };
49
+ var Alert = React.forwardRef(
50
+ ({
51
+ className,
52
+ intent = "info",
53
+ variant = "subtle",
54
+ title,
55
+ dismissible,
56
+ onDismiss,
57
+ children,
58
+ ...props
59
+ }, ref) => {
60
+ const styles = variant === "solid" ? SOLID_STYLES[intent] : variant === "outline" ? OUTLINE_STYLES[intent] : INTENT_SUBTLE_STYLES[intent];
61
+ return /* @__PURE__ */ jsxs2(
62
+ "div",
63
+ {
64
+ ref,
65
+ role: "alert",
66
+ className: cn("flex gap-3 rounded-lg border p-4", styles, className),
67
+ ...props,
68
+ children: [
69
+ /* @__PURE__ */ jsx2("span", { className: "flex-shrink-0 pt-0.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(Icon, { name: ICON_MAP[intent], size: "md" }) }),
70
+ /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
71
+ title && /* @__PURE__ */ jsx2("p", { className: "font-semibold", children: title }),
72
+ children && /* @__PURE__ */ jsx2("div", { className: cn(title && "mt-1", "text-sm"), children })
73
+ ] }),
74
+ dismissible && /* @__PURE__ */ jsx2(
75
+ "button",
76
+ {
77
+ type: "button",
78
+ onClick: onDismiss,
79
+ className: "flex-shrink-0 hover:opacity-80",
80
+ "aria-label": "Dismiss",
81
+ children: "\u2715"
82
+ }
83
+ )
84
+ ]
85
+ }
86
+ );
87
+ }
88
+ );
89
+ Alert.displayName = "Alert";
90
+
91
+ // src/intent-badge.tsx
92
+ import * as React2 from "react";
93
+ import { jsx as jsx3 } from "react/jsx-runtime";
94
+ var INTENT_CLASSES = {
95
+ neutral: "bg-muted text-muted-foreground border-border",
96
+ // the primary tint is lighter than the intents': `primary-text` on a 10%
97
+ // tint over the page grey drew 4.46:1 (W1 sheet), under AA
98
+ primary: "bg-primary/5 text-primary-text border-primary/30",
99
+ ...INTENT_SUBTLE_STYLES
100
+ };
101
+ var IntentBadge = React2.forwardRef(
102
+ ({ className, intent = "neutral", children, ...props }, ref) => /* @__PURE__ */ jsx3(
103
+ "span",
104
+ {
105
+ ref,
106
+ title: typeof children === "string" ? children : void 0,
107
+ className: cn(
108
+ "inline-flex max-w-full items-center rounded-full border px-2.5 py-0.5 text-xs font-medium",
109
+ INTENT_CLASSES[intent],
110
+ className
111
+ ),
112
+ ...props,
113
+ children: /* @__PURE__ */ jsx3("span", { className: "truncate", children: isEmptyValue(children) ? /* @__PURE__ */ jsx3(EmptyValue, {}) : children })
114
+ }
115
+ )
116
+ );
117
+ IntentBadge.displayName = "IntentBadge";
118
+
119
+ export {
120
+ EMPTY_VALUE_GLYPH,
121
+ isEmptyValue,
122
+ EmptyValue,
123
+ INTENT_SUBTLE_STYLES,
124
+ Alert,
125
+ IntentBadge
126
+ };
@@ -0,0 +1,82 @@
1
+ import * as lucide_react from 'lucide-react';
2
+ import * as React from 'react';
3
+
4
+ /** Each icon name and the glyph it draws. */
5
+ declare const ICONS: {
6
+ readonly 'arrow-left': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
7
+ readonly 'arrow-right': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
8
+ readonly bell: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
9
+ readonly calendar: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
10
+ readonly check: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
11
+ readonly 'chevron-down': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
12
+ readonly 'chevron-left': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
13
+ readonly 'chevron-right': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
14
+ readonly 'chevron-up': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
15
+ readonly 'circle-alert': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
16
+ readonly 'circle-check': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
17
+ readonly 'clipboard-list': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
18
+ readonly clock: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
19
+ readonly database: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
20
+ readonly download: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
21
+ readonly ellipsis: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
22
+ readonly 'external-link': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
23
+ readonly eye: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
24
+ readonly 'eye-off': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
25
+ readonly 'file-text': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
26
+ readonly filter: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
27
+ readonly folder: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
28
+ readonly heart: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
29
+ readonly house: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
30
+ readonly inbox: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
31
+ readonly info: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
32
+ readonly 'layout-grid': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
33
+ readonly link: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
34
+ readonly list: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
35
+ readonly loader: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
36
+ readonly lock: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
37
+ readonly 'log-out': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
38
+ readonly mail: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
39
+ readonly 'map-pin': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
40
+ readonly menu: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
41
+ readonly package: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
42
+ readonly pencil: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
43
+ readonly phone: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
44
+ readonly plus: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
45
+ readonly 'refresh-cw': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
46
+ readonly rocket: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
47
+ readonly search: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
48
+ readonly settings: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
49
+ readonly star: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
50
+ readonly tag: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
51
+ readonly trash: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
52
+ readonly 'triangle-alert': React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
53
+ readonly upload: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
54
+ readonly user: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
55
+ readonly users: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
56
+ readonly x: React.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
57
+ };
58
+ type IconName = keyof typeof ICONS;
59
+ /**
60
+ * The icon sizes, each a step of the spacing scale (`size-3` is 12px …
61
+ * `size-8` 32px): the size comes from the tokens, never lucide's 24px
62
+ * default (the class sets the box; the SVG's own width/height give way).
63
+ */
64
+ declare const ICON_SIZES: {
65
+ readonly xs: "size-3";
66
+ readonly sm: "size-4";
67
+ readonly md: "size-5";
68
+ readonly lg: "size-6";
69
+ readonly xl: "size-8";
70
+ };
71
+ type IconSize = keyof typeof ICON_SIZES;
72
+ interface IconProps {
73
+ /** One name of the closed set (`ICONS`). */
74
+ name: IconName;
75
+ /** One step of the size scale (`ICON_SIZES`). */
76
+ size: IconSize;
77
+ className?: string;
78
+ }
79
+ /** A decorative icon from the closed set (hidden from assistive technology). */
80
+ declare function Icon({ name, size, className }: IconProps): React.ReactElement;
81
+
82
+ export { type IconName as I, type IconSize as a, ICONS as b, ICON_SIZES as c, Icon as d, type IconProps as e };