@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.
- package/LICENSE +21 -0
- package/dist/admin.cjs +1869 -0
- package/dist/admin.cjs.map +1 -0
- package/dist/admin.d.cts +376 -0
- package/dist/admin.d.ts +376 -0
- package/dist/admin.js +10 -0
- package/dist/admin.js.map +1 -0
- package/dist/async.cjs +76 -0
- package/dist/async.cjs.map +1 -0
- package/dist/async.d.cts +59 -0
- package/dist/async.d.ts +59 -0
- package/dist/async.js +3 -0
- package/dist/async.js.map +1 -0
- package/dist/behaviors.cjs +659 -0
- package/dist/behaviors.cjs.map +1 -0
- package/dist/behaviors.d.cts +441 -0
- package/dist/behaviors.d.ts +441 -0
- package/dist/behaviors.js +3 -0
- package/dist/behaviors.js.map +1 -0
- package/dist/chunk-3FJUCHCC.js +146 -0
- package/dist/chunk-3FJUCHCC.js.map +1 -0
- package/dist/chunk-3R3QDLJC.js +172 -0
- package/dist/chunk-3R3QDLJC.js.map +1 -0
- package/dist/chunk-4FLIW67H.js +137 -0
- package/dist/chunk-4FLIW67H.js.map +1 -0
- package/dist/chunk-4FQ7XF52.js +3 -0
- package/dist/chunk-4FQ7XF52.js.map +1 -0
- package/dist/chunk-72PZMU6R.js +99 -0
- package/dist/chunk-72PZMU6R.js.map +1 -0
- package/dist/chunk-75GSYEJS.js +17 -0
- package/dist/chunk-75GSYEJS.js.map +1 -0
- package/dist/chunk-7IOJADZC.js +38 -0
- package/dist/chunk-7IOJADZC.js.map +1 -0
- package/dist/chunk-CIZGSGXN.js +651 -0
- package/dist/chunk-CIZGSGXN.js.map +1 -0
- package/dist/chunk-F77KIPOH.js +103 -0
- package/dist/chunk-F77KIPOH.js.map +1 -0
- package/dist/chunk-FJBYAIL4.js +1318 -0
- package/dist/chunk-FJBYAIL4.js.map +1 -0
- package/dist/chunk-H7HVVPYR.js +66 -0
- package/dist/chunk-H7HVVPYR.js.map +1 -0
- package/dist/chunk-I6D5VXQK.js +167 -0
- package/dist/chunk-I6D5VXQK.js.map +1 -0
- package/dist/chunk-PPYNXNGZ.js +73 -0
- package/dist/chunk-PPYNXNGZ.js.map +1 -0
- package/dist/chunk-QLUIKEMJ.js +1197 -0
- package/dist/chunk-QLUIKEMJ.js.map +1 -0
- package/dist/chunk-ROJV6RON.js +3 -0
- package/dist/chunk-ROJV6RON.js.map +1 -0
- package/dist/chunk-S43IHHBU.js +82 -0
- package/dist/chunk-S43IHHBU.js.map +1 -0
- package/dist/chunk-TCAXRWT6.js +108 -0
- package/dist/chunk-TCAXRWT6.js.map +1 -0
- package/dist/chunk-TQB5LVOH.js +17 -0
- package/dist/chunk-TQB5LVOH.js.map +1 -0
- package/dist/chunk-VM2CXEUA.js +46 -0
- package/dist/chunk-VM2CXEUA.js.map +1 -0
- package/dist/chunk-W2JVHGFR.js +103 -0
- package/dist/chunk-W2JVHGFR.js.map +1 -0
- package/dist/chunk-WL67XCH5.js +59 -0
- package/dist/chunk-WL67XCH5.js.map +1 -0
- package/dist/chunk-XCNCIG2I.js +165 -0
- package/dist/chunk-XCNCIG2I.js.map +1 -0
- package/dist/chunk-XSLBANUV.js +16 -0
- package/dist/chunk-XSLBANUV.js.map +1 -0
- package/dist/chunk-ZY4NLITM.js +73 -0
- package/dist/chunk-ZY4NLITM.js.map +1 -0
- package/dist/data.cjs +59 -0
- package/dist/data.cjs.map +1 -0
- package/dist/data.d.cts +46 -0
- package/dist/data.d.ts +46 -0
- package/dist/data.js +4 -0
- package/dist/data.js.map +1 -0
- package/dist/error-boundary.cjs +115 -0
- package/dist/error-boundary.cjs.map +1 -0
- package/dist/error-boundary.d.cts +60 -0
- package/dist/error-boundary.d.ts +60 -0
- package/dist/error-boundary.js +4 -0
- package/dist/error-boundary.js.map +1 -0
- package/dist/floating.cjs +149 -0
- package/dist/floating.cjs.map +1 -0
- package/dist/floating.d.cts +106 -0
- package/dist/floating.d.ts +106 -0
- package/dist/floating.js +4 -0
- package/dist/floating.js.map +1 -0
- package/dist/form.cjs +144 -0
- package/dist/form.cjs.map +1 -0
- package/dist/form.d.cts +128 -0
- package/dist/form.d.ts +128 -0
- package/dist/form.js +3 -0
- package/dist/form.js.map +1 -0
- package/dist/i18n.cjs +112 -0
- package/dist/i18n.cjs.map +1 -0
- package/dist/i18n.d.cts +99 -0
- package/dist/i18n.d.ts +99 -0
- package/dist/i18n.js +3 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.cjs +18673 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +8087 -0
- package/dist/index.d.ts +8087 -0
- package/dist/index.js +13525 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts.cjs +392 -0
- package/dist/layouts.cjs.map +1 -0
- package/dist/layouts.d.cts +406 -0
- package/dist/layouts.d.ts +406 -0
- package/dist/layouts.js +5 -0
- package/dist/layouts.js.map +1 -0
- package/dist/machine.cjs +19 -0
- package/dist/machine.cjs.map +1 -0
- package/dist/machine.d.cts +18 -0
- package/dist/machine.d.ts +18 -0
- package/dist/machine.js +4 -0
- package/dist/machine.js.map +1 -0
- package/dist/modal-utils.cjs +170 -0
- package/dist/modal-utils.cjs.map +1 -0
- package/dist/modal-utils.d.cts +43 -0
- package/dist/modal-utils.d.ts +43 -0
- package/dist/modal-utils.js +3 -0
- package/dist/modal-utils.js.map +1 -0
- package/dist/motion.cjs +88 -0
- package/dist/motion.cjs.map +1 -0
- package/dist/motion.d.cts +43 -0
- package/dist/motion.d.ts +43 -0
- package/dist/motion.js +3 -0
- package/dist/motion.js.map +1 -0
- package/dist/provider.cjs +272 -0
- package/dist/provider.cjs.map +1 -0
- package/dist/provider.d.cts +130 -0
- package/dist/provider.d.ts +130 -0
- package/dist/provider.js +6 -0
- package/dist/provider.js.map +1 -0
- package/dist/resource.cjs +25 -0
- package/dist/resource.cjs.map +1 -0
- package/dist/resource.d.cts +17 -0
- package/dist/resource.d.ts +17 -0
- package/dist/resource.js +3 -0
- package/dist/resource.js.map +1 -0
- package/dist/skeletons.cjs +1659 -0
- package/dist/skeletons.cjs.map +1 -0
- package/dist/skeletons.d.cts +179 -0
- package/dist/skeletons.d.ts +179 -0
- package/dist/skeletons.js +7 -0
- package/dist/skeletons.js.map +1 -0
- package/dist/skins.cjs +138 -0
- package/dist/skins.cjs.map +1 -0
- package/dist/skins.d.cts +67 -0
- package/dist/skins.d.ts +67 -0
- package/dist/skins.js +3 -0
- package/dist/skins.js.map +1 -0
- package/dist/theme.cjs +106 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.cts +103 -0
- package/dist/theme.d.ts +103 -0
- package/dist/theme.js +3 -0
- package/dist/theme.js.map +1 -0
- package/dist/undo.cjs +51 -0
- package/dist/undo.cjs.map +1 -0
- package/dist/undo.d.cts +48 -0
- package/dist/undo.d.ts +48 -0
- package/dist/undo.js +3 -0
- package/dist/undo.js.map +1 -0
- 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 };
|
package/dist/layouts.js
ADDED
|
@@ -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"}
|
package/dist/machine.cjs
ADDED
|
@@ -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 };
|
package/dist/machine.js
ADDED
|
@@ -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"]}
|