@iris-ui-kit/react 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.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/dist/SidebarLayout-fWQRvK0a.d.cts +26 -0
  3. package/dist/SidebarLayout-fWQRvK0a.d.ts +26 -0
  4. package/dist/admin.cjs +1583 -0
  5. package/dist/admin.cjs.map +1 -0
  6. package/dist/admin.d.cts +183 -0
  7. package/dist/admin.d.ts +183 -0
  8. package/dist/admin.js +9 -0
  9. package/dist/admin.js.map +1 -0
  10. package/dist/async.cjs +97 -0
  11. package/dist/async.cjs.map +1 -0
  12. package/dist/async.d.cts +57 -0
  13. package/dist/async.d.ts +57 -0
  14. package/dist/async.js +5 -0
  15. package/dist/async.js.map +1 -0
  16. package/dist/behaviors.cjs +569 -0
  17. package/dist/behaviors.cjs.map +1 -0
  18. package/dist/behaviors.d.cts +188 -0
  19. package/dist/behaviors.d.ts +188 -0
  20. package/dist/behaviors.js +4 -0
  21. package/dist/behaviors.js.map +1 -0
  22. package/dist/chunk-2TQSTINK.js +541 -0
  23. package/dist/chunk-2TQSTINK.js.map +1 -0
  24. package/dist/chunk-53KFLVIZ.js +68 -0
  25. package/dist/chunk-53KFLVIZ.js.map +1 -0
  26. package/dist/chunk-6BMFMCMQ.js +140 -0
  27. package/dist/chunk-6BMFMCMQ.js.map +1 -0
  28. package/dist/chunk-AUA5GBT6.js +143 -0
  29. package/dist/chunk-AUA5GBT6.js.map +1 -0
  30. package/dist/chunk-DE6V6NOI.js +122 -0
  31. package/dist/chunk-DE6V6NOI.js.map +1 -0
  32. package/dist/chunk-HEJGN6UI.js +78 -0
  33. package/dist/chunk-HEJGN6UI.js.map +1 -0
  34. package/dist/chunk-IDD35UJ6.js +83 -0
  35. package/dist/chunk-IDD35UJ6.js.map +1 -0
  36. package/dist/chunk-J5FB2UB2.js +166 -0
  37. package/dist/chunk-J5FB2UB2.js.map +1 -0
  38. package/dist/chunk-OMOTUHYI.js +66 -0
  39. package/dist/chunk-OMOTUHYI.js.map +1 -0
  40. package/dist/chunk-RZNYIFV2.js +34 -0
  41. package/dist/chunk-RZNYIFV2.js.map +1 -0
  42. package/dist/chunk-SJO74IB3.js +54 -0
  43. package/dist/chunk-SJO74IB3.js.map +1 -0
  44. package/dist/chunk-SORLRLS4.js +53 -0
  45. package/dist/chunk-SORLRLS4.js.map +1 -0
  46. package/dist/chunk-TO7YVSAI.js +64 -0
  47. package/dist/chunk-TO7YVSAI.js.map +1 -0
  48. package/dist/chunk-TQ33XJIK.js +22 -0
  49. package/dist/chunk-TQ33XJIK.js.map +1 -0
  50. package/dist/chunk-UWUUEZCD.js +950 -0
  51. package/dist/chunk-UWUUEZCD.js.map +1 -0
  52. package/dist/chunk-VWCJJRSC.js +1200 -0
  53. package/dist/chunk-VWCJJRSC.js.map +1 -0
  54. package/dist/chunk-WIHBIDVJ.js +54 -0
  55. package/dist/chunk-WIHBIDVJ.js.map +1 -0
  56. package/dist/chunk-XCK4RIXB.js +66 -0
  57. package/dist/chunk-XCK4RIXB.js.map +1 -0
  58. package/dist/chunk-YAHXR2CJ.js +48 -0
  59. package/dist/chunk-YAHXR2CJ.js.map +1 -0
  60. package/dist/chunk-YXIO5THG.js +4 -0
  61. package/dist/chunk-YXIO5THG.js.map +1 -0
  62. package/dist/chunk-ZKBDUWUD.js +156 -0
  63. package/dist/chunk-ZKBDUWUD.js.map +1 -0
  64. package/dist/data.cjs +112 -0
  65. package/dist/data.cjs.map +1 -0
  66. package/dist/data.d.cts +53 -0
  67. package/dist/data.d.ts +53 -0
  68. package/dist/data.js +5 -0
  69. package/dist/data.js.map +1 -0
  70. package/dist/error-boundary.cjs +106 -0
  71. package/dist/error-boundary.cjs.map +1 -0
  72. package/dist/error-boundary.d.cts +41 -0
  73. package/dist/error-boundary.d.ts +41 -0
  74. package/dist/error-boundary.js +6 -0
  75. package/dist/error-boundary.js.map +1 -0
  76. package/dist/floating.cjs +163 -0
  77. package/dist/floating.cjs.map +1 -0
  78. package/dist/floating.d.cts +92 -0
  79. package/dist/floating.d.ts +92 -0
  80. package/dist/floating.js +5 -0
  81. package/dist/floating.js.map +1 -0
  82. package/dist/form.cjs +159 -0
  83. package/dist/form.cjs.map +1 -0
  84. package/dist/form.d.cts +120 -0
  85. package/dist/form.d.ts +120 -0
  86. package/dist/form.js +5 -0
  87. package/dist/form.js.map +1 -0
  88. package/dist/i18n.cjs +100 -0
  89. package/dist/i18n.cjs.map +1 -0
  90. package/dist/i18n.d.cts +50 -0
  91. package/dist/i18n.d.ts +50 -0
  92. package/dist/i18n.js +5 -0
  93. package/dist/i18n.js.map +1 -0
  94. package/dist/index.cjs +16635 -0
  95. package/dist/index.cjs.map +1 -0
  96. package/dist/index.d.cts +2964 -0
  97. package/dist/index.d.ts +2964 -0
  98. package/dist/index.js +12217 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/layouts.cjs +386 -0
  101. package/dist/layouts.cjs.map +1 -0
  102. package/dist/layouts.d.cts +92 -0
  103. package/dist/layouts.d.ts +92 -0
  104. package/dist/layouts.js +6 -0
  105. package/dist/layouts.js.map +1 -0
  106. package/dist/modal-utils.cjs +168 -0
  107. package/dist/modal-utils.cjs.map +1 -0
  108. package/dist/modal-utils.d.cts +43 -0
  109. package/dist/modal-utils.d.ts +43 -0
  110. package/dist/modal-utils.js +4 -0
  111. package/dist/modal-utils.js.map +1 -0
  112. package/dist/motion.cjs +104 -0
  113. package/dist/motion.cjs.map +1 -0
  114. package/dist/motion.d.cts +41 -0
  115. package/dist/motion.d.ts +41 -0
  116. package/dist/motion.js +4 -0
  117. package/dist/motion.js.map +1 -0
  118. package/dist/provider.cjs +191 -0
  119. package/dist/provider.cjs.map +1 -0
  120. package/dist/provider.d.cts +62 -0
  121. package/dist/provider.d.ts +62 -0
  122. package/dist/provider.js +8 -0
  123. package/dist/provider.js.map +1 -0
  124. package/dist/resource.cjs +61 -0
  125. package/dist/resource.cjs.map +1 -0
  126. package/dist/resource.d.cts +21 -0
  127. package/dist/resource.d.ts +21 -0
  128. package/dist/resource.js +5 -0
  129. package/dist/resource.js.map +1 -0
  130. package/dist/skeletons.cjs +1304 -0
  131. package/dist/skeletons.cjs.map +1 -0
  132. package/dist/skeletons.d.cts +70 -0
  133. package/dist/skeletons.d.ts +70 -0
  134. package/dist/skeletons.js +8 -0
  135. package/dist/skeletons.js.map +1 -0
  136. package/dist/skins.cjs +134 -0
  137. package/dist/skins.cjs.map +1 -0
  138. package/dist/skins.d.cts +45 -0
  139. package/dist/skins.d.ts +45 -0
  140. package/dist/skins.js +5 -0
  141. package/dist/skins.js.map +1 -0
  142. package/dist/theme.cjs +100 -0
  143. package/dist/theme.cjs.map +1 -0
  144. package/dist/theme.d.cts +71 -0
  145. package/dist/theme.d.ts +71 -0
  146. package/dist/theme.js +5 -0
  147. package/dist/theme.js.map +1 -0
  148. package/dist/undo.cjs +73 -0
  149. package/dist/undo.cjs.map +1 -0
  150. package/dist/undo.d.cts +47 -0
  151. package/dist/undo.d.ts +47 -0
  152. package/dist/undo.js +4 -0
  153. package/dist/undo.js.map +1 -0
  154. package/package.json +61 -0
@@ -0,0 +1,950 @@
1
+ 'use client'
2
+ import { IrisContainer, IrisStack, IrisDashboardGrid, IrisDashboardCard } from './chunk-ZKBDUWUD.js';
3
+ import { IrisSidebarLayout, IrisHeaderLayout } from './chunk-J5FB2UB2.js';
4
+ import { useI18n } from './chunk-OMOTUHYI.js';
5
+ import * as React4 from 'react';
6
+ import { useEffect, Children, isValidElement, cloneElement } from 'react';
7
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
+ import { composeEventHandlers } from '@iris-ui-kit/core';
9
+
10
+ var SIZE_MAP = {
11
+ sm: { padding: "4px 8px", fontSize: "12px", minHeight: "28px" },
12
+ md: { padding: "6px 12px", fontSize: "14px", minHeight: "34px" },
13
+ lg: { padding: "8px 12px", fontSize: "16px", minHeight: "40px" }
14
+ };
15
+ var IrisInput = React4.forwardRef(function IrisInput2({
16
+ size = "md",
17
+ type = "text",
18
+ invalid = false,
19
+ ariaDescribedby,
20
+ prefix,
21
+ suffix,
22
+ style,
23
+ onFocus,
24
+ onBlur,
25
+ ...rest
26
+ }, ref) {
27
+ const [focused, setFocused] = React4.useState(false);
28
+ const sizeStyles = SIZE_MAP[size];
29
+ const borderColor = invalid ? "var(--iris-danger)" : focused ? "var(--iris-primary)" : "var(--iris-border)";
30
+ const boxShadow = focused ? `0 0 0 3px ${invalid ? "rgba(239, 68, 68, 0.18)" : "rgba(99, 102, 241, 0.18)"}` : "none";
31
+ const wrapperStyle = {
32
+ display: "inline-flex",
33
+ alignItems: "center",
34
+ gap: "6px",
35
+ background: "var(--iris-background)",
36
+ color: "var(--iris-foreground)",
37
+ border: `1px solid ${borderColor}`,
38
+ borderRadius: "var(--iris-radius-md, 6px)",
39
+ cursor: rest.disabled ? "not-allowed" : "text",
40
+ opacity: rest.disabled ? 0.6 : 1,
41
+ transition: "border-color 120ms ease, box-shadow 120ms ease",
42
+ boxShadow,
43
+ padding: sizeStyles.padding,
44
+ minHeight: sizeStyles.minHeight,
45
+ fontSize: sizeStyles.fontSize,
46
+ ...style
47
+ };
48
+ const inputStyle = {
49
+ flex: 1,
50
+ minWidth: 0,
51
+ border: "none",
52
+ outline: "none",
53
+ background: "transparent",
54
+ color: "inherit",
55
+ fontFamily: "inherit",
56
+ fontSize: "inherit",
57
+ padding: 0
58
+ };
59
+ return /* @__PURE__ */ jsxs(
60
+ "label",
61
+ {
62
+ "data-iris-input": "",
63
+ "data-iris-input-size": size,
64
+ "data-state": invalid ? "invalid" : focused ? "focused" : "idle",
65
+ style: wrapperStyle,
66
+ children: [
67
+ prefix ? /* @__PURE__ */ jsx(
68
+ "span",
69
+ {
70
+ "data-iris-input-prefix": "",
71
+ style: { display: "inline-flex", alignItems: "center", color: "var(--iris-muted)" },
72
+ children: prefix
73
+ }
74
+ ) : null,
75
+ /* @__PURE__ */ jsx(
76
+ "input",
77
+ {
78
+ ...rest,
79
+ ref,
80
+ type,
81
+ "aria-invalid": invalid ? "true" : void 0,
82
+ "aria-describedby": ariaDescribedby,
83
+ style: inputStyle,
84
+ onFocus: (e) => {
85
+ setFocused(true);
86
+ onFocus?.(e);
87
+ },
88
+ onBlur: (e) => {
89
+ setFocused(false);
90
+ onBlur?.(e);
91
+ }
92
+ }
93
+ ),
94
+ suffix ? /* @__PURE__ */ jsx(
95
+ "span",
96
+ {
97
+ "data-iris-input-suffix": "",
98
+ style: { display: "inline-flex", alignItems: "center", color: "var(--iris-muted)" },
99
+ children: suffix
100
+ }
101
+ ) : null
102
+ ]
103
+ }
104
+ );
105
+ });
106
+ var IrisPasswordInput = React4.forwardRef(
107
+ function IrisPasswordInput2({ showToggle = true, suffix, prefix, disabled, readOnly, ...rest }, ref) {
108
+ const { t } = useI18n();
109
+ const [visible, setVisible] = React4.useState(false);
110
+ const toggle = () => {
111
+ if (disabled || readOnly) return;
112
+ setVisible((v) => !v);
113
+ };
114
+ const toggleBtn = showToggle ? /* @__PURE__ */ jsx(
115
+ "button",
116
+ {
117
+ type: "button",
118
+ "data-iris-password-input-toggle": "",
119
+ "aria-label": visible ? t("passwordInput.hide") : t("passwordInput.show"),
120
+ "aria-pressed": visible ? "true" : "false",
121
+ onClick: toggle,
122
+ style: {
123
+ background: "transparent",
124
+ border: "none",
125
+ cursor: disabled ? "not-allowed" : "pointer",
126
+ color: "var(--iris-muted)",
127
+ padding: "0 2px",
128
+ fontSize: 13,
129
+ lineHeight: 1
130
+ },
131
+ children: visible ? "\u{1F648}" : "\u{1F441}"
132
+ }
133
+ ) : null;
134
+ return /* @__PURE__ */ jsx(
135
+ IrisInput,
136
+ {
137
+ ...rest,
138
+ ref,
139
+ type: visible ? "text" : "password",
140
+ disabled,
141
+ readOnly,
142
+ prefix,
143
+ suffix: /* @__PURE__ */ jsxs(Fragment, { children: [
144
+ suffix,
145
+ toggleBtn
146
+ ] }),
147
+ "data-iris-password-input": ""
148
+ }
149
+ );
150
+ }
151
+ );
152
+ var DIM_MAP = {
153
+ sm: "14px",
154
+ md: "18px",
155
+ lg: "22px"
156
+ };
157
+ var IrisCheckbox = React4.forwardRef(
158
+ function IrisCheckbox2({
159
+ checked,
160
+ defaultChecked = false,
161
+ onChange,
162
+ size = "md",
163
+ disabled = false,
164
+ invalid = false,
165
+ ariaDescribedby,
166
+ children,
167
+ style,
168
+ ...rest
169
+ }, ref) {
170
+ const [internalChecked, setInternalChecked] = React4.useState(defaultChecked);
171
+ const isControlled = checked !== void 0;
172
+ const value = isControlled ? checked : internalChecked;
173
+ const innerRef = React4.useRef(null);
174
+ React4.useImperativeHandle(ref, () => innerRef.current, []);
175
+ React4.useEffect(() => {
176
+ const el = innerRef.current;
177
+ if (el) el.indeterminate = value === "indeterminate";
178
+ }, [value]);
179
+ const handleChange = (e) => {
180
+ if (disabled) return;
181
+ const next = e.target.checked;
182
+ if (!isControlled) setInternalChecked(next);
183
+ onChange?.(next, e);
184
+ };
185
+ const state = value === "indeterminate" ? "indeterminate" : value ? "checked" : "unchecked";
186
+ const dim = DIM_MAP[size];
187
+ const boxStyle = {
188
+ display: "inline-flex",
189
+ alignItems: "center",
190
+ justifyContent: "center",
191
+ width: dim,
192
+ height: dim,
193
+ borderRadius: "var(--iris-radius-sm, 4px)",
194
+ border: `1px solid ${state === "unchecked" ? "var(--iris-border)" : "var(--iris-primary)"}`,
195
+ background: state === "unchecked" ? "var(--iris-background)" : "var(--iris-primary)",
196
+ color: "var(--iris-primary-foreground, #fff)",
197
+ cursor: disabled ? "not-allowed" : "pointer",
198
+ opacity: disabled ? 0.6 : 1,
199
+ transition: "background-color 120ms ease, border-color 120ms ease",
200
+ flexShrink: 0
201
+ };
202
+ const indicator = state === "checked" ? "\u2713" : state === "indeterminate" ? "\u2014" : null;
203
+ return /* @__PURE__ */ jsxs(
204
+ "label",
205
+ {
206
+ "data-iris-checkbox": "",
207
+ "data-iris-checkbox-size": size,
208
+ "data-state": state,
209
+ style: {
210
+ display: "inline-flex",
211
+ alignItems: "center",
212
+ gap: 8,
213
+ cursor: disabled ? "not-allowed" : "pointer",
214
+ userSelect: "none",
215
+ ...style
216
+ },
217
+ children: [
218
+ /* @__PURE__ */ jsx(
219
+ "input",
220
+ {
221
+ ...rest,
222
+ ref: innerRef,
223
+ type: "checkbox",
224
+ checked: value === true,
225
+ disabled,
226
+ "aria-checked": state === "indeterminate" ? "mixed" : state === "checked" ? "true" : "false",
227
+ "aria-describedby": ariaDescribedby,
228
+ "aria-invalid": invalid ? "true" : void 0,
229
+ onChange: handleChange,
230
+ style: {
231
+ position: "absolute",
232
+ opacity: 0,
233
+ width: 0,
234
+ height: 0,
235
+ pointerEvents: "none"
236
+ }
237
+ }
238
+ ),
239
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: boxStyle, children: indicator }),
240
+ children
241
+ ]
242
+ }
243
+ );
244
+ }
245
+ );
246
+
247
+ // src/primitives/button/styles.ts
248
+ var STYLE_ID = "iris-button-styles";
249
+ var CSS = `
250
+ .iris-button {
251
+ cursor: pointer;
252
+ display: inline-flex;
253
+ align-items: center;
254
+ justify-content: center;
255
+ gap: var(--iris-gap-sm, 4px);
256
+ font-family: inherit;
257
+ font-weight: 500;
258
+ line-height: 1.2;
259
+ border-radius: var(--iris-radius-md, 6px);
260
+ white-space: nowrap;
261
+ user-select: none;
262
+ position: relative;
263
+ transition:
264
+ background-color 120ms ease,
265
+ border-color 120ms ease,
266
+ color 120ms ease,
267
+ filter 120ms ease;
268
+ }
269
+ .iris-button:focus-visible {
270
+ outline: 2px solid var(--iris-primary);
271
+ outline-offset: 2px;
272
+ }
273
+ .iris-button[disabled],
274
+ .iris-button[aria-busy="true"] {
275
+ cursor: not-allowed;
276
+ opacity: 0.6;
277
+ }
278
+ .iris-button[data-iris-button-variant="solid"]:not([disabled]):not([aria-busy="true"]):hover {
279
+ filter: brightness(1.08);
280
+ }
281
+ .iris-button[data-iris-button-variant="outline"]:not([disabled]):not([aria-busy="true"]):hover,
282
+ .iris-button[data-iris-button-variant="ghost"]:not([disabled]):not([aria-busy="true"]):hover {
283
+ background-color: var(--iris-surface-hover);
284
+ }
285
+ .iris-button[data-iris-button-variant="link"]:not([disabled]):not([aria-busy="true"]):hover {
286
+ text-decoration: underline;
287
+ }
288
+ .iris-button-leading {
289
+ display: inline-flex;
290
+ align-items: center;
291
+ }
292
+ .iris-button-spinner {
293
+ width: 1em;
294
+ height: 1em;
295
+ display: inline-block;
296
+ animation: iris-button-spin 0.7s linear infinite;
297
+ }
298
+ @keyframes iris-button-spin {
299
+ to { transform: rotate(360deg); }
300
+ }
301
+ `;
302
+ var installed = false;
303
+ function installButtonStyles() {
304
+ if (installed) return;
305
+ if (typeof document === "undefined") return;
306
+ if (document.getElementById(STYLE_ID)) {
307
+ installed = true;
308
+ return;
309
+ }
310
+ const style = document.createElement("style");
311
+ style.id = STYLE_ID;
312
+ style.textContent = CSS;
313
+ document.head.appendChild(style);
314
+ installed = true;
315
+ }
316
+ var SIZE_STYLES = {
317
+ sm: { padding: "var(--iris-padding-sm) var(--iris-padding-md)", fontSize: "12px" },
318
+ md: { padding: "var(--iris-padding-sm) var(--iris-padding-lg)", fontSize: "14px" },
319
+ lg: { padding: "var(--iris-padding-md) var(--iris-padding-lg)", fontSize: "16px" }
320
+ };
321
+ var VARIANT_STYLES = {
322
+ solid: {
323
+ background: "var(--iris-primary)",
324
+ color: "var(--iris-primary-foreground)",
325
+ border: "1px solid var(--iris-primary)"
326
+ },
327
+ outline: {
328
+ background: "transparent",
329
+ color: "var(--iris-primary)",
330
+ border: "1px solid var(--iris-border)"
331
+ },
332
+ ghost: {
333
+ background: "transparent",
334
+ color: "var(--iris-foreground)",
335
+ border: "1px solid transparent"
336
+ },
337
+ link: {
338
+ background: "transparent",
339
+ color: "var(--iris-primary)",
340
+ border: "1px solid transparent",
341
+ textDecoration: "none"
342
+ }
343
+ };
344
+ function buildInlineStyle(variant, size) {
345
+ const base = { ...SIZE_STYLES[size], ...VARIANT_STYLES[variant] };
346
+ if (variant === "link") base.padding = "0";
347
+ return base;
348
+ }
349
+ function Spinner() {
350
+ return /* @__PURE__ */ jsxs("svg", { className: "iris-button-spinner", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
351
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "3" }),
352
+ /* @__PURE__ */ jsx(
353
+ "path",
354
+ {
355
+ d: "M22 12a10 10 0 0 1-10 10",
356
+ stroke: "currentColor",
357
+ strokeWidth: "3",
358
+ strokeLinecap: "round"
359
+ }
360
+ )
361
+ ] });
362
+ }
363
+ function IrisButton({
364
+ variant = "solid",
365
+ size = "md",
366
+ disabled = false,
367
+ loading = false,
368
+ type = "button",
369
+ asChild = false,
370
+ leading,
371
+ children,
372
+ className,
373
+ style,
374
+ onClick,
375
+ ...rest
376
+ }) {
377
+ useEffect(() => {
378
+ installButtonStyles();
379
+ }, []);
380
+ const isInteractive = !disabled && !loading;
381
+ const handleClick = (event) => {
382
+ if (!isInteractive) {
383
+ event.preventDefault();
384
+ event.stopPropagation();
385
+ return;
386
+ }
387
+ onClick?.(event);
388
+ };
389
+ const baseProps = {
390
+ className: ["iris-button", className].filter(Boolean).join(" "),
391
+ "data-iris-button-variant": variant,
392
+ "data-iris-button-size": size,
393
+ "aria-disabled": disabled ? "true" : void 0,
394
+ "aria-busy": loading ? "true" : void 0,
395
+ style: { ...buildInlineStyle(variant, size), ...style ?? {} }
396
+ };
397
+ if (asChild) {
398
+ const only = Children.only(children);
399
+ if (!only || !isValidElement(only)) {
400
+ if (typeof process === "undefined" || process.env?.NODE_ENV !== "production") {
401
+ console.warn("[iris-ui] IrisButton: as-child requires a single React element child");
402
+ }
403
+ return null;
404
+ }
405
+ const childProps = only.props;
406
+ return cloneElement(only, {
407
+ ...rest,
408
+ ...baseProps,
409
+ className: [baseProps.className, childProps.className].filter(Boolean).join(" "),
410
+ style: { ...baseProps.style, ...childProps.style ?? {} },
411
+ onClick: composeEventHandlers(
412
+ handleClick,
413
+ childProps.onClick ?? (() => {
414
+ })
415
+ ),
416
+ ...isInteractive ? {} : { disabled: true }
417
+ });
418
+ }
419
+ return /* @__PURE__ */ jsxs("button", { ...rest, type, disabled: !isInteractive, onClick: handleClick, ...baseProps, children: [
420
+ (loading || leading) && /* @__PURE__ */ jsx("span", { className: "iris-button-leading", children: loading ? /* @__PURE__ */ jsx(Spinner, {}) : leading }),
421
+ children
422
+ ] });
423
+ }
424
+ var IrisFormField = React4.forwardRef(
425
+ function IrisFormField2({ label, hint, error, required = false, labelFor, size = "md", style, children, ...rest }, ref) {
426
+ const generated = React4.useId();
427
+ const controlId = labelFor || `${generated}-control`;
428
+ const hintId = `${generated}-hint`;
429
+ const errorId = `${generated}-error`;
430
+ const describedBy = React4.useMemo(() => {
431
+ const ids = [];
432
+ if (hint && !error) ids.push(hintId);
433
+ if (error) ids.push(errorId);
434
+ return ids.length > 0 ? ids.join(" ") : void 0;
435
+ }, [hint, error, hintId, errorId]);
436
+ let injected = false;
437
+ const decorated = React4.Children.map(children, (child) => {
438
+ if (!injected && React4.isValidElement(child)) {
439
+ injected = true;
440
+ const injectedProps = {
441
+ id: controlId,
442
+ invalid: error ? true : void 0,
443
+ ariaDescribedby: describedBy
444
+ };
445
+ return React4.cloneElement(child, injectedProps);
446
+ }
447
+ return child;
448
+ });
449
+ const labelStyle = {
450
+ fontSize: size === "sm" ? "12px" : "14px",
451
+ fontWeight: 500,
452
+ color: error ? "var(--iris-danger)" : "var(--iris-foreground)",
453
+ display: "inline-flex",
454
+ alignItems: "center",
455
+ gap: "4px"
456
+ };
457
+ return /* @__PURE__ */ jsxs(
458
+ "div",
459
+ {
460
+ ...rest,
461
+ ref,
462
+ "data-iris-form-field": "",
463
+ "data-iris-form-field-state": error ? "invalid" : "valid",
464
+ style: {
465
+ display: "flex",
466
+ flexDirection: "column",
467
+ gap: "4px",
468
+ ...style
469
+ },
470
+ children: [
471
+ label ? /* @__PURE__ */ jsxs("label", { htmlFor: controlId, "data-iris-form-field-label": "", style: labelStyle, children: [
472
+ label,
473
+ required ? /* @__PURE__ */ jsx(
474
+ "span",
475
+ {
476
+ "aria-hidden": "true",
477
+ "data-iris-form-field-required": "",
478
+ style: { color: "var(--iris-danger)" },
479
+ children: "*"
480
+ }
481
+ ) : null
482
+ ] }) : null,
483
+ decorated,
484
+ hint && !error ? /* @__PURE__ */ jsx(
485
+ "div",
486
+ {
487
+ id: hintId,
488
+ "data-iris-form-field-hint": "",
489
+ style: { fontSize: 12, color: "var(--iris-muted)" },
490
+ children: hint
491
+ }
492
+ ) : null,
493
+ error ? /* @__PURE__ */ jsx(
494
+ "div",
495
+ {
496
+ id: errorId,
497
+ "data-iris-form-field-error": "",
498
+ role: "alert",
499
+ style: { fontSize: 12, color: "var(--iris-danger)" },
500
+ children: error
501
+ }
502
+ ) : null
503
+ ]
504
+ }
505
+ );
506
+ }
507
+ );
508
+ var TONE_TO_VAR = {
509
+ info: "--iris-primary",
510
+ success: "--iris-success",
511
+ warning: "--iris-warning",
512
+ danger: "--iris-danger"
513
+ };
514
+ function IrisAlert({
515
+ tone = "info",
516
+ title,
517
+ closable = false,
518
+ open,
519
+ onClose,
520
+ icon,
521
+ children,
522
+ style,
523
+ ...rest
524
+ }) {
525
+ const { t } = useI18n();
526
+ const [internalOpen, setInternalOpen] = React4.useState(true);
527
+ React4.useEffect(() => {
528
+ if (open !== void 0) setInternalOpen(open);
529
+ }, [open]);
530
+ const isOpen = open !== void 0 ? open : internalOpen;
531
+ if (!isOpen) return null;
532
+ const tonalVar = `var(${TONE_TO_VAR[tone]})`;
533
+ const handleClose = () => {
534
+ if (open === void 0) setInternalOpen(false);
535
+ onClose?.();
536
+ };
537
+ return /* @__PURE__ */ jsxs(
538
+ "div",
539
+ {
540
+ ...rest,
541
+ role: tone === "danger" || tone === "warning" ? "alert" : "status",
542
+ "data-iris-alert": "",
543
+ "data-iris-alert-tone": tone,
544
+ style: {
545
+ display: "flex",
546
+ gap: "var(--iris-gap-md, 12px)",
547
+ padding: "var(--iris-padding-md, 12px)",
548
+ borderRadius: "var(--iris-radius-md, 6px)",
549
+ border: `1px solid ${tonalVar}`,
550
+ // `backgroundColor` is the precomputed fallback under color-mix (engines
551
+ // without it); the `background` shorthand overrides with the exact mix.
552
+ backgroundColor: `var(${TONE_TO_VAR[tone]}-subtle)`,
553
+ background: `color-mix(in srgb, ${tonalVar} 10%, var(--iris-background))`,
554
+ color: "var(--iris-foreground)",
555
+ alignItems: "flex-start",
556
+ ...style
557
+ },
558
+ children: [
559
+ icon ? /* @__PURE__ */ jsx(
560
+ "span",
561
+ {
562
+ "data-iris-alert-icon": "",
563
+ style: { color: tonalVar, flexShrink: 0, display: "inline-flex" },
564
+ children: icon
565
+ }
566
+ ) : null,
567
+ /* @__PURE__ */ jsxs("div", { "data-iris-alert-body": "", style: { flex: 1, minWidth: 0 }, children: [
568
+ title ? /* @__PURE__ */ jsx(
569
+ "div",
570
+ {
571
+ "data-iris-alert-title": "",
572
+ style: { fontWeight: 600, marginBottom: 4, color: tonalVar },
573
+ children: title
574
+ }
575
+ ) : null,
576
+ /* @__PURE__ */ jsx("div", { "data-iris-alert-content": "", children })
577
+ ] }),
578
+ closable ? /* @__PURE__ */ jsx(
579
+ "button",
580
+ {
581
+ type: "button",
582
+ "data-iris-alert-close": "",
583
+ "aria-label": t("alert.close"),
584
+ onClick: handleClose,
585
+ style: {
586
+ background: "transparent",
587
+ border: "none",
588
+ cursor: "pointer",
589
+ color: "var(--iris-muted)",
590
+ fontSize: 16,
591
+ padding: 0,
592
+ lineHeight: 1,
593
+ flexShrink: 0
594
+ },
595
+ children: "\u2715"
596
+ }
597
+ ) : null
598
+ ]
599
+ }
600
+ );
601
+ }
602
+ var SPACING_MAP = {
603
+ sm: "8px",
604
+ md: "16px",
605
+ lg: "24px"
606
+ };
607
+ function IrisDivider({
608
+ orientation = "horizontal",
609
+ label,
610
+ spacing = "md",
611
+ children,
612
+ style,
613
+ ...rest
614
+ }) {
615
+ const isHorizontal = orientation === "horizontal";
616
+ const hasLabel = Boolean(label || children);
617
+ if (isHorizontal && !hasLabel) {
618
+ return /* @__PURE__ */ jsx(
619
+ "hr",
620
+ {
621
+ ...rest,
622
+ "data-iris-divider": "",
623
+ "data-iris-divider-orientation": "horizontal",
624
+ style: {
625
+ border: "none",
626
+ borderTop: "1px solid var(--iris-border)",
627
+ margin: `${SPACING_MAP[spacing]} 0`,
628
+ width: "100%",
629
+ ...style
630
+ }
631
+ }
632
+ );
633
+ }
634
+ if (!isHorizontal) {
635
+ return /* @__PURE__ */ jsx(
636
+ "div",
637
+ {
638
+ ...rest,
639
+ role: "separator",
640
+ "aria-orientation": "vertical",
641
+ "data-iris-divider": "",
642
+ "data-iris-divider-orientation": "vertical",
643
+ style: {
644
+ display: "inline-block",
645
+ width: 1,
646
+ alignSelf: "stretch",
647
+ background: "var(--iris-border)",
648
+ margin: `0 ${SPACING_MAP[spacing]}`,
649
+ ...style
650
+ }
651
+ }
652
+ );
653
+ }
654
+ return /* @__PURE__ */ jsxs(
655
+ "div",
656
+ {
657
+ ...rest,
658
+ role: "separator",
659
+ "aria-orientation": "horizontal",
660
+ "data-iris-divider": "",
661
+ "data-iris-divider-orientation": "horizontal",
662
+ "data-iris-divider-has-label": "true",
663
+ style: {
664
+ display: "flex",
665
+ alignItems: "center",
666
+ gap: 8,
667
+ margin: `${SPACING_MAP[spacing]} 0`,
668
+ color: "var(--iris-muted)",
669
+ fontSize: 12,
670
+ textTransform: "uppercase",
671
+ letterSpacing: "0.04em",
672
+ ...style
673
+ },
674
+ children: [
675
+ /* @__PURE__ */ jsx("span", { "data-iris-divider-line": "before", style: lineStyle }),
676
+ /* @__PURE__ */ jsx("span", { "data-iris-divider-label": "", children: children ?? label }),
677
+ /* @__PURE__ */ jsx("span", { "data-iris-divider-line": "after", style: lineStyle })
678
+ ]
679
+ }
680
+ );
681
+ }
682
+ var lineStyle = {
683
+ flex: 1,
684
+ height: 1,
685
+ background: "var(--iris-border)"
686
+ };
687
+ function IrisLoginTemplate({
688
+ title = "Sign in",
689
+ description = "",
690
+ showRemember = true,
691
+ error = "",
692
+ submitLabel = "Sign in",
693
+ loading = false,
694
+ header,
695
+ forgot,
696
+ footer,
697
+ onSubmit,
698
+ style,
699
+ className
700
+ }) {
701
+ const [email, setEmail] = React4.useState("");
702
+ const [password, setPassword] = React4.useState("");
703
+ const [remember, setRemember] = React4.useState(false);
704
+ const handleSubmit = (e) => {
705
+ e.preventDefault();
706
+ onSubmit?.({ email, password, remember });
707
+ };
708
+ return /* @__PURE__ */ jsx(
709
+ "div",
710
+ {
711
+ "data-iris-login-template": "",
712
+ className,
713
+ style: {
714
+ minHeight: "100vh",
715
+ display: "flex",
716
+ alignItems: "center",
717
+ justifyContent: "center",
718
+ background: "var(--iris-background)",
719
+ color: "var(--iris-foreground)",
720
+ padding: 24,
721
+ ...style
722
+ },
723
+ children: /* @__PURE__ */ jsx(IrisContainer, { maxWidth: "420px", padding: 0, children: /* @__PURE__ */ jsx(
724
+ "form",
725
+ {
726
+ onSubmit: handleSubmit,
727
+ "data-iris-login-form": "",
728
+ style: {
729
+ background: "var(--iris-surface)",
730
+ border: "1px solid var(--iris-border)",
731
+ borderRadius: "var(--iris-radius-lg, 8px)",
732
+ padding: 32,
733
+ boxShadow: "0 6px 20px -8px rgba(0, 0, 0, 0.16)"
734
+ },
735
+ children: /* @__PURE__ */ jsxs(IrisStack, { spacing: "lg", children: [
736
+ header ?? /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
737
+ /* @__PURE__ */ jsx("h1", { style: { margin: "0 0 4px 0", fontSize: 22, fontWeight: 700 }, children: title }),
738
+ description ? /* @__PURE__ */ jsx(
739
+ "p",
740
+ {
741
+ style: {
742
+ margin: 0,
743
+ color: "var(--iris-muted)",
744
+ fontSize: 14
745
+ },
746
+ children: description
747
+ }
748
+ ) : null
749
+ ] }),
750
+ error ? /* @__PURE__ */ jsx(IrisAlert, { tone: "danger", title: error }) : null,
751
+ /* @__PURE__ */ jsx(IrisFormField, { label: "Email", required: true, children: /* @__PURE__ */ jsx(
752
+ IrisInput,
753
+ {
754
+ type: "email",
755
+ value: email,
756
+ onChange: (e) => setEmail(e.target.value),
757
+ placeholder: "you@example.com",
758
+ disabled: loading,
759
+ autoComplete: "email"
760
+ }
761
+ ) }),
762
+ /* @__PURE__ */ jsx(IrisFormField, { label: "Password", required: true, children: /* @__PURE__ */ jsx(
763
+ IrisPasswordInput,
764
+ {
765
+ value: password,
766
+ onChange: (e) => setPassword(e.target.value),
767
+ placeholder: "Enter your password",
768
+ disabled: loading,
769
+ autoComplete: "current-password"
770
+ }
771
+ ) }),
772
+ showRemember ? /* @__PURE__ */ jsxs(
773
+ "div",
774
+ {
775
+ style: {
776
+ display: "flex",
777
+ alignItems: "center",
778
+ justifyContent: "space-between"
779
+ },
780
+ children: [
781
+ /* @__PURE__ */ jsx(
782
+ IrisCheckbox,
783
+ {
784
+ checked: remember,
785
+ onChange: (next) => setRemember(next),
786
+ disabled: loading,
787
+ children: "Remember me"
788
+ }
789
+ ),
790
+ forgot ?? null
791
+ ]
792
+ }
793
+ ) : null,
794
+ /* @__PURE__ */ jsx(IrisButton, { type: "submit", variant: "solid", loading, style: { width: "100%" }, children: submitLabel }),
795
+ footer ? /* @__PURE__ */ jsxs("div", { children: [
796
+ /* @__PURE__ */ jsx(IrisDivider, { spacing: "md", label: "or" }),
797
+ footer
798
+ ] }) : null
799
+ ] })
800
+ }
801
+ ) })
802
+ }
803
+ );
804
+ }
805
+ function IrisDashboardTemplate({
806
+ title = "Dashboard",
807
+ sidebarTitle = "",
808
+ nav = [],
809
+ activeId = "",
810
+ onActiveIdChange,
811
+ cards = [],
812
+ defaultCollapsed = false,
813
+ onCollapsedChange,
814
+ header,
815
+ sidebarHeader,
816
+ children,
817
+ cardSlots,
818
+ style,
819
+ className
820
+ }) {
821
+ const [collapsed, setCollapsed] = React4.useState(defaultCollapsed);
822
+ const handleCollapsed = (next) => {
823
+ setCollapsed(next);
824
+ onCollapsedChange?.(next);
825
+ };
826
+ return /* @__PURE__ */ jsx(
827
+ "div",
828
+ {
829
+ "data-iris-dashboard-template": "",
830
+ className,
831
+ style: {
832
+ width: "100%",
833
+ height: "100vh",
834
+ background: "var(--iris-background)",
835
+ color: "var(--iris-foreground)",
836
+ ...style
837
+ },
838
+ children: /* @__PURE__ */ jsx(
839
+ IrisSidebarLayout,
840
+ {
841
+ collapsed,
842
+ onCollapsedChange: handleCollapsed,
843
+ width: 240,
844
+ collapsedWidth: 64,
845
+ sidebar: (state) => /* @__PURE__ */ jsxs(IrisStack, { spacing: "sm", style: { padding: 12 }, children: [
846
+ sidebarHeader ? sidebarHeader(state) : sidebarTitle ? /* @__PURE__ */ jsx(
847
+ "div",
848
+ {
849
+ style: {
850
+ padding: "8px 12px",
851
+ fontSize: 14,
852
+ fontWeight: 600,
853
+ color: "var(--iris-foreground)",
854
+ opacity: state.collapsed ? 0 : 1,
855
+ transition: "opacity 120ms ease",
856
+ whiteSpace: "nowrap",
857
+ overflow: "hidden"
858
+ },
859
+ children: sidebarTitle
860
+ }
861
+ ) : null,
862
+ /* @__PURE__ */ jsx("nav", { "aria-label": "Primary", style: { display: "flex", flexDirection: "column", gap: 2 }, children: nav.map((item) => {
863
+ const isActive = item.id === activeId;
864
+ return /* @__PURE__ */ jsxs(
865
+ "button",
866
+ {
867
+ type: "button",
868
+ "data-iris-dashboard-nav-item": item.id,
869
+ "data-iris-dashboard-nav-active": isActive ? "true" : void 0,
870
+ onClick: () => onActiveIdChange?.(item.id),
871
+ style: {
872
+ display: "flex",
873
+ alignItems: "center",
874
+ gap: 10,
875
+ padding: "8px 12px",
876
+ background: isActive ? "var(--iris-primary)" : "transparent",
877
+ color: isActive ? "var(--iris-primary-foreground, #fff)" : "var(--iris-foreground)",
878
+ border: "none",
879
+ borderRadius: "var(--iris-radius-sm, 4px)",
880
+ cursor: "pointer",
881
+ fontSize: 14,
882
+ fontFamily: "inherit",
883
+ textAlign: "start",
884
+ outline: "none"
885
+ },
886
+ children: [
887
+ item.icon ? /* @__PURE__ */ jsx(
888
+ "span",
889
+ {
890
+ "aria-hidden": "true",
891
+ style: { width: 16, display: "inline-flex", justifyContent: "center" },
892
+ children: item.icon
893
+ }
894
+ ) : null,
895
+ /* @__PURE__ */ jsx(
896
+ "span",
897
+ {
898
+ style: {
899
+ opacity: state.collapsed ? 0 : 1,
900
+ transition: "opacity 120ms ease",
901
+ whiteSpace: "nowrap"
902
+ },
903
+ children: item.label
904
+ }
905
+ )
906
+ ]
907
+ },
908
+ item.id
909
+ );
910
+ }) })
911
+ ] }),
912
+ children: /* @__PURE__ */ jsx(
913
+ IrisHeaderLayout,
914
+ {
915
+ header: header ?? /* @__PURE__ */ jsx("div", { style: { padding: "12px 20px", fontSize: 16, fontWeight: 600 }, children: title }),
916
+ children: children ?? /* @__PURE__ */ jsx("div", { style: { padding: 20 }, children: /* @__PURE__ */ jsx(IrisDashboardGrid, { columns: 12, gap: 16, children: cards.map((card) => /* @__PURE__ */ jsxs(
917
+ IrisDashboardCard,
918
+ {
919
+ colSpan: card.colSpan ?? 4,
920
+ rowSpan: card.rowSpan ?? 1,
921
+ "data-iris-dashboard-card-id": card.id,
922
+ children: [
923
+ /* @__PURE__ */ jsx(
924
+ "h3",
925
+ {
926
+ style: {
927
+ margin: "0 0 8px 0",
928
+ fontSize: 14,
929
+ fontWeight: 600,
930
+ color: "var(--iris-foreground)"
931
+ },
932
+ children: card.title
933
+ }
934
+ ),
935
+ cardSlots?.[card.id] !== void 0 ? cardSlots[card.id] : card.body ? /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: "var(--iris-muted)" }, children: card.body }) : null
936
+ ]
937
+ },
938
+ card.id
939
+ )) }) })
940
+ }
941
+ )
942
+ }
943
+ )
944
+ }
945
+ );
946
+ }
947
+
948
+ export { IrisAlert, IrisButton, IrisCheckbox, IrisDashboardTemplate, IrisDivider, IrisFormField, IrisInput, IrisLoginTemplate, IrisPasswordInput };
949
+ //# sourceMappingURL=chunk-UWUUEZCD.js.map
950
+ //# sourceMappingURL=chunk-UWUUEZCD.js.map