@iris-ui-kit/vue 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 (164) hide show
  1. package/LICENSE +21 -0
  2. package/dist/admin.cjs +1869 -0
  3. package/dist/admin.cjs.map +1 -0
  4. package/dist/admin.d.cts +376 -0
  5. package/dist/admin.d.ts +376 -0
  6. package/dist/admin.js +10 -0
  7. package/dist/admin.js.map +1 -0
  8. package/dist/async.cjs +76 -0
  9. package/dist/async.cjs.map +1 -0
  10. package/dist/async.d.cts +59 -0
  11. package/dist/async.d.ts +59 -0
  12. package/dist/async.js +3 -0
  13. package/dist/async.js.map +1 -0
  14. package/dist/behaviors.cjs +659 -0
  15. package/dist/behaviors.cjs.map +1 -0
  16. package/dist/behaviors.d.cts +441 -0
  17. package/dist/behaviors.d.ts +441 -0
  18. package/dist/behaviors.js +3 -0
  19. package/dist/behaviors.js.map +1 -0
  20. package/dist/chunk-3FJUCHCC.js +146 -0
  21. package/dist/chunk-3FJUCHCC.js.map +1 -0
  22. package/dist/chunk-3R3QDLJC.js +172 -0
  23. package/dist/chunk-3R3QDLJC.js.map +1 -0
  24. package/dist/chunk-4FLIW67H.js +137 -0
  25. package/dist/chunk-4FLIW67H.js.map +1 -0
  26. package/dist/chunk-4FQ7XF52.js +3 -0
  27. package/dist/chunk-4FQ7XF52.js.map +1 -0
  28. package/dist/chunk-72PZMU6R.js +99 -0
  29. package/dist/chunk-72PZMU6R.js.map +1 -0
  30. package/dist/chunk-75GSYEJS.js +17 -0
  31. package/dist/chunk-75GSYEJS.js.map +1 -0
  32. package/dist/chunk-7IOJADZC.js +38 -0
  33. package/dist/chunk-7IOJADZC.js.map +1 -0
  34. package/dist/chunk-CIZGSGXN.js +651 -0
  35. package/dist/chunk-CIZGSGXN.js.map +1 -0
  36. package/dist/chunk-F77KIPOH.js +103 -0
  37. package/dist/chunk-F77KIPOH.js.map +1 -0
  38. package/dist/chunk-FJBYAIL4.js +1318 -0
  39. package/dist/chunk-FJBYAIL4.js.map +1 -0
  40. package/dist/chunk-H7HVVPYR.js +66 -0
  41. package/dist/chunk-H7HVVPYR.js.map +1 -0
  42. package/dist/chunk-I6D5VXQK.js +167 -0
  43. package/dist/chunk-I6D5VXQK.js.map +1 -0
  44. package/dist/chunk-PPYNXNGZ.js +73 -0
  45. package/dist/chunk-PPYNXNGZ.js.map +1 -0
  46. package/dist/chunk-QLUIKEMJ.js +1197 -0
  47. package/dist/chunk-QLUIKEMJ.js.map +1 -0
  48. package/dist/chunk-ROJV6RON.js +3 -0
  49. package/dist/chunk-ROJV6RON.js.map +1 -0
  50. package/dist/chunk-S43IHHBU.js +82 -0
  51. package/dist/chunk-S43IHHBU.js.map +1 -0
  52. package/dist/chunk-TCAXRWT6.js +108 -0
  53. package/dist/chunk-TCAXRWT6.js.map +1 -0
  54. package/dist/chunk-TQB5LVOH.js +17 -0
  55. package/dist/chunk-TQB5LVOH.js.map +1 -0
  56. package/dist/chunk-VM2CXEUA.js +46 -0
  57. package/dist/chunk-VM2CXEUA.js.map +1 -0
  58. package/dist/chunk-W2JVHGFR.js +103 -0
  59. package/dist/chunk-W2JVHGFR.js.map +1 -0
  60. package/dist/chunk-WL67XCH5.js +59 -0
  61. package/dist/chunk-WL67XCH5.js.map +1 -0
  62. package/dist/chunk-XCNCIG2I.js +165 -0
  63. package/dist/chunk-XCNCIG2I.js.map +1 -0
  64. package/dist/chunk-XSLBANUV.js +16 -0
  65. package/dist/chunk-XSLBANUV.js.map +1 -0
  66. package/dist/chunk-ZY4NLITM.js +73 -0
  67. package/dist/chunk-ZY4NLITM.js.map +1 -0
  68. package/dist/data.cjs +59 -0
  69. package/dist/data.cjs.map +1 -0
  70. package/dist/data.d.cts +46 -0
  71. package/dist/data.d.ts +46 -0
  72. package/dist/data.js +4 -0
  73. package/dist/data.js.map +1 -0
  74. package/dist/error-boundary.cjs +115 -0
  75. package/dist/error-boundary.cjs.map +1 -0
  76. package/dist/error-boundary.d.cts +60 -0
  77. package/dist/error-boundary.d.ts +60 -0
  78. package/dist/error-boundary.js +4 -0
  79. package/dist/error-boundary.js.map +1 -0
  80. package/dist/floating.cjs +149 -0
  81. package/dist/floating.cjs.map +1 -0
  82. package/dist/floating.d.cts +106 -0
  83. package/dist/floating.d.ts +106 -0
  84. package/dist/floating.js +4 -0
  85. package/dist/floating.js.map +1 -0
  86. package/dist/form.cjs +144 -0
  87. package/dist/form.cjs.map +1 -0
  88. package/dist/form.d.cts +128 -0
  89. package/dist/form.d.ts +128 -0
  90. package/dist/form.js +3 -0
  91. package/dist/form.js.map +1 -0
  92. package/dist/i18n.cjs +112 -0
  93. package/dist/i18n.cjs.map +1 -0
  94. package/dist/i18n.d.cts +99 -0
  95. package/dist/i18n.d.ts +99 -0
  96. package/dist/i18n.js +3 -0
  97. package/dist/i18n.js.map +1 -0
  98. package/dist/index.cjs +18673 -0
  99. package/dist/index.cjs.map +1 -0
  100. package/dist/index.d.cts +8087 -0
  101. package/dist/index.d.ts +8087 -0
  102. package/dist/index.js +13525 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/layouts.cjs +392 -0
  105. package/dist/layouts.cjs.map +1 -0
  106. package/dist/layouts.d.cts +406 -0
  107. package/dist/layouts.d.ts +406 -0
  108. package/dist/layouts.js +5 -0
  109. package/dist/layouts.js.map +1 -0
  110. package/dist/machine.cjs +19 -0
  111. package/dist/machine.cjs.map +1 -0
  112. package/dist/machine.d.cts +18 -0
  113. package/dist/machine.d.ts +18 -0
  114. package/dist/machine.js +4 -0
  115. package/dist/machine.js.map +1 -0
  116. package/dist/modal-utils.cjs +170 -0
  117. package/dist/modal-utils.cjs.map +1 -0
  118. package/dist/modal-utils.d.cts +43 -0
  119. package/dist/modal-utils.d.ts +43 -0
  120. package/dist/modal-utils.js +3 -0
  121. package/dist/modal-utils.js.map +1 -0
  122. package/dist/motion.cjs +88 -0
  123. package/dist/motion.cjs.map +1 -0
  124. package/dist/motion.d.cts +43 -0
  125. package/dist/motion.d.ts +43 -0
  126. package/dist/motion.js +3 -0
  127. package/dist/motion.js.map +1 -0
  128. package/dist/provider.cjs +272 -0
  129. package/dist/provider.cjs.map +1 -0
  130. package/dist/provider.d.cts +130 -0
  131. package/dist/provider.d.ts +130 -0
  132. package/dist/provider.js +6 -0
  133. package/dist/provider.js.map +1 -0
  134. package/dist/resource.cjs +25 -0
  135. package/dist/resource.cjs.map +1 -0
  136. package/dist/resource.d.cts +17 -0
  137. package/dist/resource.d.ts +17 -0
  138. package/dist/resource.js +3 -0
  139. package/dist/resource.js.map +1 -0
  140. package/dist/skeletons.cjs +1659 -0
  141. package/dist/skeletons.cjs.map +1 -0
  142. package/dist/skeletons.d.cts +179 -0
  143. package/dist/skeletons.d.ts +179 -0
  144. package/dist/skeletons.js +7 -0
  145. package/dist/skeletons.js.map +1 -0
  146. package/dist/skins.cjs +138 -0
  147. package/dist/skins.cjs.map +1 -0
  148. package/dist/skins.d.cts +67 -0
  149. package/dist/skins.d.ts +67 -0
  150. package/dist/skins.js +3 -0
  151. package/dist/skins.js.map +1 -0
  152. package/dist/theme.cjs +106 -0
  153. package/dist/theme.cjs.map +1 -0
  154. package/dist/theme.d.cts +103 -0
  155. package/dist/theme.d.ts +103 -0
  156. package/dist/theme.js +3 -0
  157. package/dist/theme.js.map +1 -0
  158. package/dist/undo.cjs +51 -0
  159. package/dist/undo.cjs.map +1 -0
  160. package/dist/undo.d.cts +48 -0
  161. package/dist/undo.d.ts +48 -0
  162. package/dist/undo.js +3 -0
  163. package/dist/undo.js.map +1 -0
  164. package/package.json +59 -0
@@ -0,0 +1,406 @@
1
+ import * as vue from 'vue';
2
+ import { PropType } from 'vue';
3
+
4
+ /**
5
+ * Two-column layout with a collapsible sidebar.
6
+ *
7
+ * Slots:
8
+ * - `sidebar` — content rendered in the sidebar (kept mounted across collapses).
9
+ * - `default` — the main content area.
10
+ *
11
+ * Use `:collapsed` for controlled mode or `:default-collapsed` for the
12
+ * uncontrolled initial state. When collapsed, the sidebar shrinks to
13
+ * `:collapsed-width` so icon-only navigation still fits.
14
+ */
15
+ declare const IrisSidebarLayout: vue.DefineComponent<vue.ExtractPropTypes<{
16
+ collapsed: {
17
+ type: BooleanConstructor;
18
+ default: undefined;
19
+ };
20
+ defaultCollapsed: {
21
+ type: BooleanConstructor;
22
+ default: boolean;
23
+ };
24
+ /** Sidebar width when expanded (px or CSS length). */
25
+ width: {
26
+ type: (StringConstructor | NumberConstructor)[];
27
+ default: number;
28
+ };
29
+ /** Sidebar width when collapsed. */
30
+ collapsedWidth: {
31
+ type: (StringConstructor | NumberConstructor)[];
32
+ default: number;
33
+ };
34
+ /** Sidebar position. */
35
+ side: {
36
+ type: () => "left" | "right";
37
+ default: string;
38
+ };
39
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
40
+ [key: string]: any;
41
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
42
+ 'update:collapsed': (_value: boolean) => true;
43
+ }, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
44
+ collapsed: {
45
+ type: BooleanConstructor;
46
+ default: undefined;
47
+ };
48
+ defaultCollapsed: {
49
+ type: BooleanConstructor;
50
+ default: boolean;
51
+ };
52
+ /** Sidebar width when expanded (px or CSS length). */
53
+ width: {
54
+ type: (StringConstructor | NumberConstructor)[];
55
+ default: number;
56
+ };
57
+ /** Sidebar width when collapsed. */
58
+ collapsedWidth: {
59
+ type: (StringConstructor | NumberConstructor)[];
60
+ default: number;
61
+ };
62
+ /** Sidebar position. */
63
+ side: {
64
+ type: () => "left" | "right";
65
+ default: string;
66
+ };
67
+ }>> & Readonly<{
68
+ "onUpdate:collapsed"?: ((_value: boolean) => any) | undefined;
69
+ }>, {
70
+ collapsed: boolean;
71
+ defaultCollapsed: boolean;
72
+ width: string | number;
73
+ collapsedWidth: string | number;
74
+ side: "left" | "right";
75
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
76
+
77
+ /**
78
+ * Two-region vertical layout: a sticky header on top, scrollable main below.
79
+ *
80
+ * Slots:
81
+ * - `header` — fixed at top.
82
+ * - `footer` — optional fixed at bottom.
83
+ * - `default` — scrollable main region.
84
+ */
85
+ declare const IrisHeaderLayout: vue.DefineComponent<vue.ExtractPropTypes<{
86
+ /** Header height (px or CSS length). Default `'auto'`. */
87
+ headerHeight: {
88
+ type: PropType<number | string>;
89
+ default: string;
90
+ };
91
+ /** Footer height (px or CSS length). Default `'auto'`. */
92
+ footerHeight: {
93
+ type: PropType<number | string>;
94
+ default: string;
95
+ };
96
+ /** When true, header sticks via `position: sticky` instead of static. */
97
+ sticky: {
98
+ type: BooleanConstructor;
99
+ default: boolean;
100
+ };
101
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
102
+ [key: string]: any;
103
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
104
+ /** Header height (px or CSS length). Default `'auto'`. */
105
+ headerHeight: {
106
+ type: PropType<number | string>;
107
+ default: string;
108
+ };
109
+ /** Footer height (px or CSS length). Default `'auto'`. */
110
+ footerHeight: {
111
+ type: PropType<number | string>;
112
+ default: string;
113
+ };
114
+ /** When true, header sticks via `position: sticky` instead of static. */
115
+ sticky: {
116
+ type: BooleanConstructor;
117
+ default: boolean;
118
+ };
119
+ }>> & Readonly<{}>, {
120
+ headerHeight: string | number;
121
+ footerHeight: string | number;
122
+ sticky: boolean;
123
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
124
+
125
+ /**
126
+ * 12-column responsive grid for dashboard composition. Each child should be
127
+ * an `IrisDashboardCard` (or any element with `grid-column: span N`).
128
+ *
129
+ * Children control their span via inline `style="grid-column: span N"` or
130
+ * by wrapping with `IrisDashboardCard` whose `col-span` / `row-span` props
131
+ * compile to the same CSS.
132
+ */
133
+ declare const IrisDashboardGrid: vue.DefineComponent<vue.ExtractPropTypes<{
134
+ columns: {
135
+ type: NumberConstructor;
136
+ default: number;
137
+ };
138
+ gap: {
139
+ type: (StringConstructor | NumberConstructor)[];
140
+ default: number;
141
+ };
142
+ /** Minimum column width via `grid-template-columns: repeat(auto-fill, minmax(...))`. */
143
+ minColWidth: {
144
+ type: (StringConstructor | NumberConstructor)[];
145
+ default: undefined;
146
+ };
147
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
148
+ [key: string]: any;
149
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
150
+ columns: {
151
+ type: NumberConstructor;
152
+ default: number;
153
+ };
154
+ gap: {
155
+ type: (StringConstructor | NumberConstructor)[];
156
+ default: number;
157
+ };
158
+ /** Minimum column width via `grid-template-columns: repeat(auto-fill, minmax(...))`. */
159
+ minColWidth: {
160
+ type: (StringConstructor | NumberConstructor)[];
161
+ default: undefined;
162
+ };
163
+ }>> & Readonly<{}>, {
164
+ gap: string | number;
165
+ columns: number;
166
+ minColWidth: string | number;
167
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
168
+ /**
169
+ * A single grid cell — wraps content in a styled card with optional span
170
+ * controls. `col-span` accepts a number (column count) or `'full'` to fill
171
+ * the entire row.
172
+ */
173
+ declare const IrisDashboardCard: vue.DefineComponent<vue.ExtractPropTypes<{
174
+ colSpan: {
175
+ type: (StringConstructor | NumberConstructor)[];
176
+ default: number;
177
+ };
178
+ rowSpan: {
179
+ type: NumberConstructor;
180
+ default: number;
181
+ };
182
+ /** Show a styled card surface (background + border). Default `true`. */
183
+ surface: {
184
+ type: BooleanConstructor;
185
+ default: boolean;
186
+ };
187
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
188
+ [key: string]: any;
189
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
190
+ colSpan: {
191
+ type: (StringConstructor | NumberConstructor)[];
192
+ default: number;
193
+ };
194
+ rowSpan: {
195
+ type: NumberConstructor;
196
+ default: number;
197
+ };
198
+ /** Show a styled card surface (background + border). Default `true`. */
199
+ surface: {
200
+ type: BooleanConstructor;
201
+ default: boolean;
202
+ };
203
+ }>> & Readonly<{}>, {
204
+ colSpan: string | number;
205
+ rowSpan: number;
206
+ surface: boolean;
207
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
208
+
209
+ type IrisStackDirection = 'row' | 'column';
210
+ type IrisStackAlign = 'start' | 'center' | 'end' | 'stretch';
211
+ type IrisStackJustify = 'start' | 'center' | 'end' | 'between' | 'around';
212
+ /**
213
+ * Flex container with token-driven spacing. The lightest possible layout
214
+ * primitive — most pages need a horizontal or vertical stack and this saves
215
+ * hand-writing `display: flex` everywhere.
216
+ *
217
+ * Use `direction`/`spacing`/`align`/`justify`/`wrap` to configure; children
218
+ * are arranged in document order with `gap: <spacing>`.
219
+ */
220
+ declare const IrisStack: vue.DefineComponent<vue.ExtractPropTypes<{
221
+ direction: {
222
+ type: PropType<IrisStackDirection>;
223
+ default: string;
224
+ };
225
+ spacing: {
226
+ type: (StringConstructor | NumberConstructor)[];
227
+ default: string;
228
+ };
229
+ align: {
230
+ type: PropType<IrisStackAlign>;
231
+ default: string;
232
+ };
233
+ justify: {
234
+ type: PropType<IrisStackJustify>;
235
+ default: string;
236
+ };
237
+ wrap: {
238
+ type: BooleanConstructor;
239
+ default: boolean;
240
+ };
241
+ /** When true, renders as an inline-flex container. */
242
+ inline: {
243
+ type: BooleanConstructor;
244
+ default: boolean;
245
+ };
246
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
247
+ [key: string]: any;
248
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
249
+ direction: {
250
+ type: PropType<IrisStackDirection>;
251
+ default: string;
252
+ };
253
+ spacing: {
254
+ type: (StringConstructor | NumberConstructor)[];
255
+ default: string;
256
+ };
257
+ align: {
258
+ type: PropType<IrisStackAlign>;
259
+ default: string;
260
+ };
261
+ justify: {
262
+ type: PropType<IrisStackJustify>;
263
+ default: string;
264
+ };
265
+ wrap: {
266
+ type: BooleanConstructor;
267
+ default: boolean;
268
+ };
269
+ /** When true, renders as an inline-flex container. */
270
+ inline: {
271
+ type: BooleanConstructor;
272
+ default: boolean;
273
+ };
274
+ }>> & Readonly<{}>, {
275
+ spacing: string | number;
276
+ inline: boolean;
277
+ wrap: boolean;
278
+ justify: IrisStackJustify;
279
+ direction: IrisStackDirection;
280
+ align: IrisStackAlign;
281
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
282
+
283
+ type IrisContainerMaxWidth = 'sm' | 'md' | 'lg' | 'xl' | 'full' | string;
284
+ /**
285
+ * Centered max-width wrapper. Use to bound content width on large screens
286
+ * without rewriting flex/grid plumbing.
287
+ *
288
+ * `maxWidth='lg'` (≈1024px) is the most common default for marketing /
289
+ * docs / app pages.
290
+ */
291
+ declare const IrisContainer: vue.DefineComponent<vue.ExtractPropTypes<{
292
+ maxWidth: {
293
+ type: PropType<IrisContainerMaxWidth>;
294
+ default: string;
295
+ };
296
+ padding: {
297
+ type: (StringConstructor | NumberConstructor)[];
298
+ default: string;
299
+ };
300
+ center: {
301
+ type: BooleanConstructor;
302
+ default: boolean;
303
+ };
304
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
305
+ [key: string]: any;
306
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
307
+ maxWidth: {
308
+ type: PropType<IrisContainerMaxWidth>;
309
+ default: string;
310
+ };
311
+ padding: {
312
+ type: (StringConstructor | NumberConstructor)[];
313
+ default: string;
314
+ };
315
+ center: {
316
+ type: BooleanConstructor;
317
+ default: boolean;
318
+ };
319
+ }>> & Readonly<{}>, {
320
+ center: boolean;
321
+ padding: string | number;
322
+ maxWidth: string;
323
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
324
+
325
+ type IrisGridColumns = number | 'auto-fit' | 'auto-fill' | string;
326
+ /**
327
+ * Two-dimensional grid layout primitive. Three column modes:
328
+ *
329
+ * - **Fixed integer** — `columns={3}` → three equal-width columns.
330
+ * - **Responsive auto-fit** — `columns="auto-fit"` + `minColWidth` → fluid
331
+ * grid where columns add/remove with container width. Most common.
332
+ * - **Raw CSS** — pass any `grid-template-columns` string.
333
+ *
334
+ * Spacing accepts token shorthand (`sm` / `md` / `lg`), numeric px, or any
335
+ * CSS length string. `gap` is a shortcut for both row + column gap.
336
+ */
337
+ declare const IrisGrid: vue.DefineComponent<vue.ExtractPropTypes<{
338
+ columns: {
339
+ type: PropType<IrisGridColumns>;
340
+ default: string;
341
+ };
342
+ /** Min width per column for `auto-fit` / `auto-fill`. */
343
+ minColWidth: {
344
+ type: StringConstructor;
345
+ default: string;
346
+ };
347
+ /** Row gap (token / px / CSS). */
348
+ rowGap: {
349
+ type: (StringConstructor | NumberConstructor)[];
350
+ default: undefined;
351
+ };
352
+ /** Column gap (token / px / CSS). */
353
+ columnGap: {
354
+ type: (StringConstructor | NumberConstructor)[];
355
+ default: undefined;
356
+ };
357
+ /** Shorthand for both row + column gap. Overridden if rowGap/columnGap given. */
358
+ gap: {
359
+ type: (StringConstructor | NumberConstructor)[];
360
+ default: string;
361
+ };
362
+ inline: {
363
+ type: BooleanConstructor;
364
+ default: boolean;
365
+ };
366
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
367
+ [key: string]: any;
368
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
369
+ columns: {
370
+ type: PropType<IrisGridColumns>;
371
+ default: string;
372
+ };
373
+ /** Min width per column for `auto-fit` / `auto-fill`. */
374
+ minColWidth: {
375
+ type: StringConstructor;
376
+ default: string;
377
+ };
378
+ /** Row gap (token / px / CSS). */
379
+ rowGap: {
380
+ type: (StringConstructor | NumberConstructor)[];
381
+ default: undefined;
382
+ };
383
+ /** Column gap (token / px / CSS). */
384
+ columnGap: {
385
+ type: (StringConstructor | NumberConstructor)[];
386
+ default: undefined;
387
+ };
388
+ /** Shorthand for both row + column gap. Overridden if rowGap/columnGap given. */
389
+ gap: {
390
+ type: (StringConstructor | NumberConstructor)[];
391
+ default: string;
392
+ };
393
+ inline: {
394
+ type: BooleanConstructor;
395
+ default: boolean;
396
+ };
397
+ }>> & Readonly<{}>, {
398
+ gap: string | number;
399
+ inline: boolean;
400
+ columns: IrisGridColumns;
401
+ minColWidth: string;
402
+ rowGap: string | number;
403
+ columnGap: string | number;
404
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
405
+
406
+ export { IrisContainer, type IrisContainerMaxWidth, IrisDashboardCard, IrisDashboardGrid, IrisGrid, type IrisGridColumns, IrisHeaderLayout, IrisSidebarLayout, IrisStack, type IrisStackAlign, type IrisStackDirection, type IrisStackJustify };
@@ -0,0 +1,5 @@
1
+ export { IrisGrid } from './chunk-WL67XCH5.js';
2
+ export { IrisContainer, IrisDashboardCard, IrisDashboardGrid, IrisStack } from './chunk-3R3QDLJC.js';
3
+ export { IrisHeaderLayout, IrisSidebarLayout } from './chunk-I6D5VXQK.js';
4
+ //# sourceMappingURL=layouts.js.map
5
+ //# sourceMappingURL=layouts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"layouts.js"}
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+
5
+ // src/machine/useMachine.ts
6
+ function useMachine(machine) {
7
+ const state = vue.ref(machine.store.getState());
8
+ const unsubscribe = machine.store.subscribe((next) => {
9
+ state.value = next;
10
+ });
11
+ vue.onBeforeUnmount(() => {
12
+ unsubscribe();
13
+ });
14
+ return { state, send: machine.send };
15
+ }
16
+
17
+ exports.useMachine = useMachine;
18
+ //# sourceMappingURL=machine.cjs.map
19
+ //# sourceMappingURL=machine.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/machine/useMachine.ts"],"names":["ref","onBeforeUnmount"],"mappings":";;;;;AAYO,SAAS,WACd,OAAA,EAIA;AACA,EAAA,MAAM,KAAA,GAAQA,OAAA,CAAI,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAA;AAC1C,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,CAAC,IAAA,KAAS;AACpD,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AAAA,EAChB,CAAC,CAAA;AACD,EAAAC,mBAAA,CAAgB,MAAM;AACpB,IAAA,WAAA,EAAY;AAAA,EACd,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAK;AACrC","file":"machine.cjs","sourcesContent":["import { onBeforeUnmount, ref, type Ref } from 'vue'\nimport type { Machine, MachineEvent, MachineState } from '@iris-ui-kit/core'\n\n/**\n * Bridge a framework-agnostic `Machine` into Vue reactivity.\n *\n * Returns a reactive ref of the current `{ value, context }` state and a\n * stable `send` function. Subscription is created eagerly and cleaned up on\n * unmount, so this hook is safe to call from any component's `setup()`.\n *\n * No primitive consumes this yet (Phase 0 ships the bridge for Phase 1).\n */\nexport function useMachine<TState extends string, TContext, TEvent extends MachineEvent>(\n machine: Machine<TState, TContext, TEvent>,\n): {\n state: Ref<MachineState<TState, TContext>>\n send: (event: TEvent) => void\n} {\n const state = ref(machine.store.getState()) as Ref<MachineState<TState, TContext>>\n const unsubscribe = machine.store.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(() => {\n unsubscribe()\n })\n return { state, send: machine.send }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { Ref } from 'vue';
2
+ import { MachineEvent, Machine, MachineState } from '@iris-ui-kit/core';
3
+
4
+ /**
5
+ * Bridge a framework-agnostic `Machine` into Vue reactivity.
6
+ *
7
+ * Returns a reactive ref of the current `{ value, context }` state and a
8
+ * stable `send` function. Subscription is created eagerly and cleaned up on
9
+ * unmount, so this hook is safe to call from any component's `setup()`.
10
+ *
11
+ * No primitive consumes this yet (Phase 0 ships the bridge for Phase 1).
12
+ */
13
+ declare function useMachine<TState extends string, TContext, TEvent extends MachineEvent>(machine: Machine<TState, TContext, TEvent>): {
14
+ state: Ref<MachineState<TState, TContext>>;
15
+ send: (event: TEvent) => void;
16
+ };
17
+
18
+ export { useMachine };
@@ -0,0 +1,18 @@
1
+ import { Ref } from 'vue';
2
+ import { MachineEvent, Machine, MachineState } from '@iris-ui-kit/core';
3
+
4
+ /**
5
+ * Bridge a framework-agnostic `Machine` into Vue reactivity.
6
+ *
7
+ * Returns a reactive ref of the current `{ value, context }` state and a
8
+ * stable `send` function. Subscription is created eagerly and cleaned up on
9
+ * unmount, so this hook is safe to call from any component's `setup()`.
10
+ *
11
+ * No primitive consumes this yet (Phase 0 ships the bridge for Phase 1).
12
+ */
13
+ declare function useMachine<TState extends string, TContext, TEvent extends MachineEvent>(machine: Machine<TState, TContext, TEvent>): {
14
+ state: Ref<MachineState<TState, TContext>>;
15
+ send: (event: TEvent) => void;
16
+ };
17
+
18
+ export { useMachine };
@@ -0,0 +1,4 @@
1
+ import './chunk-4FQ7XF52.js';
2
+ export { useMachine } from './chunk-TQB5LVOH.js';
3
+ //# sourceMappingURL=machine.js.map
4
+ //# sourceMappingURL=machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"machine.js"}
@@ -0,0 +1,170 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+
5
+ // src/primitives/modal-utils/useFocusTrap.ts
6
+ var FOCUSABLE_SELECTOR = [
7
+ "a[href]",
8
+ "area[href]",
9
+ "button:not([disabled])",
10
+ 'input:not([disabled]):not([type="hidden"])',
11
+ "select:not([disabled])",
12
+ "textarea:not([disabled])",
13
+ '[tabindex]:not([tabindex="-1"])',
14
+ '[contenteditable="true"]',
15
+ "audio[controls]",
16
+ "video[controls]",
17
+ "iframe",
18
+ "object",
19
+ "embed"
20
+ ].join(",");
21
+ function getFocusable(root) {
22
+ return Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
23
+ (el) => !el.hasAttribute("disabled") && el.tabIndex !== -1
24
+ );
25
+ }
26
+ function useFocusTrap(options) {
27
+ let previouslyFocused = null;
28
+ const onKeyDown = (event) => {
29
+ if (!options.active.value || event.key !== "Tab") return;
30
+ const root = options.container.value;
31
+ if (!root) return;
32
+ const focusables = getFocusable(root);
33
+ if (focusables.length === 0) {
34
+ event.preventDefault();
35
+ root.focus();
36
+ return;
37
+ }
38
+ const first = focusables[0];
39
+ const last = focusables[focusables.length - 1];
40
+ const active = document.activeElement;
41
+ if (event.shiftKey) {
42
+ if (active === first || !root.contains(active)) {
43
+ event.preventDefault();
44
+ last.focus();
45
+ }
46
+ } else {
47
+ if (active === last || !root.contains(active)) {
48
+ event.preventDefault();
49
+ first.focus();
50
+ }
51
+ }
52
+ };
53
+ const activate = () => {
54
+ if (typeof document === "undefined") return;
55
+ previouslyFocused = document.activeElement ?? null;
56
+ document.addEventListener("keydown", onKeyDown);
57
+ if (options.initialFocus !== false) {
58
+ requestAnimationFrame(() => {
59
+ const root = options.container.value;
60
+ if (!root) return;
61
+ const focusables = getFocusable(root);
62
+ (focusables[0] ?? root).focus();
63
+ });
64
+ }
65
+ };
66
+ const deactivate = () => {
67
+ if (typeof document === "undefined") return;
68
+ document.removeEventListener("keydown", onKeyDown);
69
+ const restore = options.returnFocusTo?.value ?? previouslyFocused;
70
+ requestAnimationFrame(() => {
71
+ if (restore && restore.isConnected) restore.focus?.();
72
+ });
73
+ previouslyFocused = null;
74
+ };
75
+ vue.watch(
76
+ options.active,
77
+ (active, wasActive) => {
78
+ if (active && !wasActive) activate();
79
+ else if (!active && wasActive) deactivate();
80
+ },
81
+ { immediate: true, flush: "post" }
82
+ );
83
+ vue.onScopeDispose(() => {
84
+ if (typeof document !== "undefined") {
85
+ document.removeEventListener("keydown", onKeyDown);
86
+ }
87
+ });
88
+ }
89
+ var lockCount = 0;
90
+ var savedOverflow = null;
91
+ var savedPaddingRight = null;
92
+ var appliedOverflow = null;
93
+ var appliedPaddingRight = null;
94
+ function lock() {
95
+ if (typeof document === "undefined") return;
96
+ lockCount += 1;
97
+ if (lockCount > 1) return;
98
+ const body = document.body;
99
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
100
+ savedOverflow = body.style.overflow;
101
+ savedPaddingRight = body.style.paddingRight;
102
+ body.style.overflow = "hidden";
103
+ appliedOverflow = "hidden";
104
+ if (scrollbarWidth > 0) {
105
+ const currentPadding = parseFloat(getComputedStyle(body).paddingRight || "0");
106
+ appliedPaddingRight = `${currentPadding + scrollbarWidth}px`;
107
+ body.style.paddingRight = appliedPaddingRight;
108
+ } else {
109
+ appliedPaddingRight = null;
110
+ }
111
+ }
112
+ function unlock() {
113
+ if (typeof document === "undefined") return;
114
+ lockCount = Math.max(0, lockCount - 1);
115
+ if (lockCount > 0) return;
116
+ const body = document.body;
117
+ if (body.style.overflow === appliedOverflow) {
118
+ body.style.overflow = savedOverflow ?? "";
119
+ }
120
+ if (appliedPaddingRight !== null && body.style.paddingRight === appliedPaddingRight) {
121
+ body.style.paddingRight = savedPaddingRight ?? "";
122
+ }
123
+ savedOverflow = null;
124
+ savedPaddingRight = null;
125
+ appliedOverflow = null;
126
+ appliedPaddingRight = null;
127
+ }
128
+ function useBodyScrollLock(active) {
129
+ let isLockedByThis = false;
130
+ vue.watch(
131
+ active,
132
+ (value) => {
133
+ if (value && !isLockedByThis) {
134
+ lock();
135
+ isLockedByThis = true;
136
+ } else if (!value && isLockedByThis) {
137
+ unlock();
138
+ isLockedByThis = false;
139
+ }
140
+ },
141
+ { immediate: true, flush: "post" }
142
+ );
143
+ vue.onScopeDispose(() => {
144
+ if (isLockedByThis) {
145
+ unlock();
146
+ isLockedByThis = false;
147
+ }
148
+ });
149
+ }
150
+ function __getBodyScrollLockCount() {
151
+ return lockCount;
152
+ }
153
+ function __resetBodyScrollLock() {
154
+ lockCount = 0;
155
+ savedOverflow = null;
156
+ savedPaddingRight = null;
157
+ appliedOverflow = null;
158
+ appliedPaddingRight = null;
159
+ if (typeof document !== "undefined") {
160
+ document.body.style.overflow = "";
161
+ document.body.style.paddingRight = "";
162
+ }
163
+ }
164
+
165
+ exports.__getBodyScrollLockCount = __getBodyScrollLockCount;
166
+ exports.__resetBodyScrollLock = __resetBodyScrollLock;
167
+ exports.useBodyScrollLock = useBodyScrollLock;
168
+ exports.useFocusTrap = useFocusTrap;
169
+ //# sourceMappingURL=modal-utils.cjs.map
170
+ //# sourceMappingURL=modal-utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/primitives/modal-utils/useFocusTrap.ts","../src/primitives/modal-utils/useBodyScrollLock.ts"],"names":["watch","onScopeDispose"],"mappings":"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","file":"modal-utils.cjs","sourcesContent":["import { onScopeDispose, watch, type Ref } from 'vue'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n 'iframe',\n 'object',\n 'embed',\n].join(',')\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => !el.hasAttribute('disabled') && el.tabIndex !== -1,\n )\n}\n\nexport interface UseFocusTrapOptions {\n /** Element whose Tab key cycle is being trapped. */\n container: Ref<HTMLElement | null>\n /** Whether the trap is currently active. */\n active: Ref<boolean>\n /** Element to restore focus to when the trap deactivates. */\n returnFocusTo?: Ref<HTMLElement | null | undefined>\n /** Whether to focus the first focusable element on activation. Default `true`. */\n initialFocus?: boolean\n}\n\n/**\n * Constrain Tab / Shift+Tab focus traversal to descendants of `container`.\n *\n * Behavior on activation:\n * - Records the currently focused element.\n * - If `initialFocus !== false`, focuses the first focusable descendant\n * (or the container itself if there are none).\n *\n * Behavior while active:\n * - Tab on the last focusable element wraps to the first; Shift+Tab on\n * the first wraps to the last.\n *\n * Behavior on deactivation:\n * - Restores focus to `returnFocusTo?.value` if provided, else to the\n * element that was focused when the trap activated.\n */\nexport function useFocusTrap(options: UseFocusTrapOptions): void {\n let previouslyFocused: HTMLElement | null = null\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!options.active.value || event.key !== 'Tab') return\n const root = options.container.value\n if (!root) return\n const focusables = getFocusable(root)\n if (focusables.length === 0) {\n event.preventDefault()\n root.focus()\n return\n }\n const first = focusables[0]!\n const last = focusables[focusables.length - 1]!\n const active = document.activeElement as HTMLElement | null\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else {\n if (active === last || !root.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n }\n\n const activate = () => {\n if (typeof document === 'undefined') return\n previouslyFocused = (document.activeElement as HTMLElement | null) ?? null\n document.addEventListener('keydown', onKeyDown)\n if (options.initialFocus !== false) {\n requestAnimationFrame(() => {\n const root = options.container.value\n if (!root) return\n const focusables = getFocusable(root)\n ;(focusables[0] ?? root).focus()\n })\n }\n }\n\n const deactivate = () => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', onKeyDown)\n const restore = options.returnFocusTo?.value ?? previouslyFocused\n requestAnimationFrame(() => {\n // The element that had focus when the trap opened may have been\n // unmounted while it was open; focusing a detached node silently drops\n // focus to <body>. Only restore if it is still in the document.\n if (restore && restore.isConnected) restore.focus?.()\n })\n previouslyFocused = null\n }\n\n watch(\n options.active,\n (active, wasActive) => {\n if (active && !wasActive) activate()\n else if (!active && wasActive) deactivate()\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(() => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('keydown', onKeyDown)\n }\n })\n}\n","import { onScopeDispose, watch, type Ref } from 'vue'\n\nlet lockCount = 0\nlet savedOverflow: string | null = null\nlet savedPaddingRight: string | null = null\n// What we actually wrote, so unlock can detect a host mutation made while\n// locked and avoid clobbering it.\nlet appliedOverflow: string | null = null\nlet appliedPaddingRight: string | null = null\n\nfunction lock() {\n if (typeof document === 'undefined') return\n lockCount += 1\n if (lockCount > 1) return\n const body = document.body\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth\n savedOverflow = body.style.overflow\n savedPaddingRight = body.style.paddingRight\n body.style.overflow = 'hidden'\n appliedOverflow = 'hidden'\n if (scrollbarWidth > 0) {\n const currentPadding = parseFloat(getComputedStyle(body).paddingRight || '0')\n appliedPaddingRight = `${currentPadding + scrollbarWidth}px`\n body.style.paddingRight = appliedPaddingRight\n } else {\n appliedPaddingRight = null\n }\n}\n\nfunction unlock() {\n if (typeof document === 'undefined') return\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount > 0) return\n const body = document.body\n // Only restore if our locked value is still in place; if a host changed body\n // overflow / padding-right while locked, respect that rather than clobber it.\n if (body.style.overflow === appliedOverflow) {\n body.style.overflow = savedOverflow ?? ''\n }\n if (appliedPaddingRight !== null && body.style.paddingRight === appliedPaddingRight) {\n body.style.paddingRight = savedPaddingRight ?? ''\n }\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n}\n\n/**\n * Lock the document body's scroll while `active` is true. Reference-counted\n * so multiple stacked Dialogs cooperate. Restores prior `overflow` and\n * `padding-right` (to compensate for the scrollbar gap) when the last lock\n * releases. SSR-safe.\n */\nexport function useBodyScrollLock(active: Ref<boolean>): void {\n let isLockedByThis = false\n\n watch(\n active,\n (value) => {\n if (value && !isLockedByThis) {\n lock()\n isLockedByThis = true\n } else if (!value && isLockedByThis) {\n unlock()\n isLockedByThis = false\n }\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(() => {\n if (isLockedByThis) {\n unlock()\n isLockedByThis = false\n }\n })\n}\n\n/** Test-only: read the current lock count. */\nexport function __getBodyScrollLockCount(): number {\n return lockCount\n}\n\n/** Test-only: hard-reset the module-level lock state. */\nexport function __resetBodyScrollLock(): void {\n lockCount = 0\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n if (typeof document !== 'undefined') {\n document.body.style.overflow = ''\n document.body.style.paddingRight = ''\n }\n}\n"]}