@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,172 @@
|
|
|
1
|
+
import { defineComponent, h, computed } from 'vue';
|
|
2
|
+
|
|
3
|
+
// src/layouts/DashboardGrid.ts
|
|
4
|
+
var IrisDashboardGrid = defineComponent({
|
|
5
|
+
name: "IrisDashboardGrid",
|
|
6
|
+
inheritAttrs: false,
|
|
7
|
+
props: {
|
|
8
|
+
columns: { type: Number, default: 12 },
|
|
9
|
+
gap: { type: [Number, String], default: 16 },
|
|
10
|
+
/** Minimum column width via `grid-template-columns: repeat(auto-fill, minmax(...))`. */
|
|
11
|
+
minColWidth: { type: [Number, String], default: void 0 }
|
|
12
|
+
},
|
|
13
|
+
setup(props, { slots, attrs }) {
|
|
14
|
+
const gap = typeof props.gap === "number" ? `${props.gap}px` : props.gap;
|
|
15
|
+
return () => {
|
|
16
|
+
const gridTemplateColumns = props.minColWidth ? `repeat(auto-fill, minmax(${typeof props.minColWidth === "number" ? `${props.minColWidth}px` : props.minColWidth}, 1fr))` : `repeat(${props.columns}, 1fr)`;
|
|
17
|
+
return h(
|
|
18
|
+
"div",
|
|
19
|
+
{
|
|
20
|
+
...attrs,
|
|
21
|
+
"data-iris-dashboard-grid": "",
|
|
22
|
+
style: {
|
|
23
|
+
display: "grid",
|
|
24
|
+
gap,
|
|
25
|
+
gridTemplateColumns,
|
|
26
|
+
width: "100%",
|
|
27
|
+
...attrs.style ?? {}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
slots.default?.()
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
var IrisDashboardCard = defineComponent({
|
|
36
|
+
name: "IrisDashboardCard",
|
|
37
|
+
inheritAttrs: false,
|
|
38
|
+
props: {
|
|
39
|
+
colSpan: { type: [Number, String], default: 1 },
|
|
40
|
+
rowSpan: { type: Number, default: 1 },
|
|
41
|
+
/** Show a styled card surface (background + border). Default `true`. */
|
|
42
|
+
surface: { type: Boolean, default: true }
|
|
43
|
+
},
|
|
44
|
+
setup(props, { slots, attrs }) {
|
|
45
|
+
return () => {
|
|
46
|
+
const colSpan = props.colSpan === "full" ? "1 / -1" : `span ${props.colSpan}`;
|
|
47
|
+
const rowSpan = props.rowSpan > 1 ? `span ${props.rowSpan}` : void 0;
|
|
48
|
+
return h(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
...attrs,
|
|
52
|
+
"data-iris-dashboard-card": "",
|
|
53
|
+
style: {
|
|
54
|
+
gridColumn: colSpan,
|
|
55
|
+
gridRow: rowSpan,
|
|
56
|
+
background: props.surface ? "var(--iris-surface)" : "transparent",
|
|
57
|
+
border: props.surface ? "1px solid var(--iris-border)" : "none",
|
|
58
|
+
borderRadius: "var(--iris-radius-md)",
|
|
59
|
+
padding: props.surface ? "var(--iris-padding-lg)" : "0",
|
|
60
|
+
minWidth: "0",
|
|
61
|
+
...attrs.style ?? {}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
slots.default?.()
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
var ALIGN_MAP = {
|
|
70
|
+
start: "flex-start",
|
|
71
|
+
center: "center",
|
|
72
|
+
end: "flex-end",
|
|
73
|
+
stretch: "stretch"
|
|
74
|
+
};
|
|
75
|
+
var JUSTIFY_MAP = {
|
|
76
|
+
start: "flex-start",
|
|
77
|
+
center: "center",
|
|
78
|
+
end: "flex-end",
|
|
79
|
+
between: "space-between",
|
|
80
|
+
around: "space-around"
|
|
81
|
+
};
|
|
82
|
+
function toCssSpacing(spacing) {
|
|
83
|
+
if (typeof spacing === "number") return `${spacing}px`;
|
|
84
|
+
if (spacing === "sm" || spacing === "md" || spacing === "lg") {
|
|
85
|
+
return `var(--iris-gap-${spacing})`;
|
|
86
|
+
}
|
|
87
|
+
return spacing;
|
|
88
|
+
}
|
|
89
|
+
var IrisStack = defineComponent({
|
|
90
|
+
name: "IrisStack",
|
|
91
|
+
inheritAttrs: false,
|
|
92
|
+
props: {
|
|
93
|
+
direction: { type: String, default: "column" },
|
|
94
|
+
spacing: { type: [String, Number], default: "md" },
|
|
95
|
+
align: { type: String, default: "stretch" },
|
|
96
|
+
justify: { type: String, default: "start" },
|
|
97
|
+
wrap: { type: Boolean, default: false },
|
|
98
|
+
/** When true, renders as an inline-flex container. */
|
|
99
|
+
inline: { type: Boolean, default: false }
|
|
100
|
+
},
|
|
101
|
+
setup(props, { slots, attrs }) {
|
|
102
|
+
const style = computed(() => ({
|
|
103
|
+
display: props.inline ? "inline-flex" : "flex",
|
|
104
|
+
flexDirection: props.direction,
|
|
105
|
+
gap: toCssSpacing(props.spacing),
|
|
106
|
+
alignItems: ALIGN_MAP[props.align],
|
|
107
|
+
justifyContent: JUSTIFY_MAP[props.justify],
|
|
108
|
+
flexWrap: props.wrap ? "wrap" : "nowrap"
|
|
109
|
+
}));
|
|
110
|
+
return () => h(
|
|
111
|
+
"div",
|
|
112
|
+
{
|
|
113
|
+
...attrs,
|
|
114
|
+
"data-iris-stack": "",
|
|
115
|
+
"data-iris-stack-direction": props.direction,
|
|
116
|
+
style: { ...style.value, ...attrs.style ?? {} }
|
|
117
|
+
},
|
|
118
|
+
slots.default?.()
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
var WIDTH_MAP = {
|
|
123
|
+
sm: "640px",
|
|
124
|
+
md: "768px",
|
|
125
|
+
lg: "1024px",
|
|
126
|
+
xl: "1280px",
|
|
127
|
+
full: "100%"
|
|
128
|
+
};
|
|
129
|
+
function resolveMaxWidth(input) {
|
|
130
|
+
if (input === "sm" || input === "md" || input === "lg" || input === "xl" || input === "full") {
|
|
131
|
+
return WIDTH_MAP[input];
|
|
132
|
+
}
|
|
133
|
+
return input;
|
|
134
|
+
}
|
|
135
|
+
function resolvePadding(input) {
|
|
136
|
+
if (typeof input === "number") return `${input}px`;
|
|
137
|
+
if (input === "sm" || input === "md" || input === "lg") {
|
|
138
|
+
return `var(--iris-padding-${input})`;
|
|
139
|
+
}
|
|
140
|
+
return input;
|
|
141
|
+
}
|
|
142
|
+
var IrisContainer = defineComponent({
|
|
143
|
+
name: "IrisContainer",
|
|
144
|
+
inheritAttrs: false,
|
|
145
|
+
props: {
|
|
146
|
+
maxWidth: { type: String, default: "lg" },
|
|
147
|
+
padding: { type: [String, Number], default: "md" },
|
|
148
|
+
center: { type: Boolean, default: true }
|
|
149
|
+
},
|
|
150
|
+
setup(props, { slots, attrs }) {
|
|
151
|
+
const style = computed(() => ({
|
|
152
|
+
width: "100%",
|
|
153
|
+
maxWidth: resolveMaxWidth(props.maxWidth),
|
|
154
|
+
padding: `0 ${resolvePadding(props.padding)}`,
|
|
155
|
+
...props.center ? { marginInlineStart: "auto", marginInlineEnd: "auto" } : {}
|
|
156
|
+
}));
|
|
157
|
+
return () => h(
|
|
158
|
+
"div",
|
|
159
|
+
{
|
|
160
|
+
...attrs,
|
|
161
|
+
"data-iris-container": "",
|
|
162
|
+
"data-iris-container-max-width": props.maxWidth,
|
|
163
|
+
style: { ...style.value, ...attrs.style ?? {} }
|
|
164
|
+
},
|
|
165
|
+
slots.default?.()
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
export { IrisContainer, IrisDashboardCard, IrisDashboardGrid, IrisStack };
|
|
171
|
+
//# sourceMappingURL=chunk-3R3QDLJC.js.map
|
|
172
|
+
//# sourceMappingURL=chunk-3R3QDLJC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/layouts/DashboardGrid.ts","../src/layouts/Stack.ts","../src/layouts/Container.ts"],"names":["defineComponent","h","computed"],"mappings":"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","file":"chunk-3R3QDLJC.js","sourcesContent":["import { defineComponent, h } from 'vue'\n\n/**\n * 12-column responsive grid for dashboard composition. Each child should be\n * an `IrisDashboardCard` (or any element with `grid-column: span N`).\n *\n * Children control their span via inline `style=\"grid-column: span N\"` or\n * by wrapping with `IrisDashboardCard` whose `col-span` / `row-span` props\n * compile to the same CSS.\n */\nexport const IrisDashboardGrid = defineComponent({\n name: 'IrisDashboardGrid',\n inheritAttrs: false,\n props: {\n columns: { type: Number, default: 12 },\n gap: { type: [Number, String], default: 16 },\n /** Minimum column width via `grid-template-columns: repeat(auto-fill, minmax(...))`. */\n minColWidth: { type: [Number, String], default: undefined },\n },\n setup(props, { slots, attrs }) {\n const gap = typeof props.gap === 'number' ? `${props.gap}px` : props.gap\n return () => {\n const gridTemplateColumns = props.minColWidth\n ? `repeat(auto-fill, minmax(${typeof props.minColWidth === 'number' ? `${props.minColWidth}px` : props.minColWidth}, 1fr))`\n : `repeat(${props.columns}, 1fr)`\n return h(\n 'div',\n {\n ...attrs,\n 'data-iris-dashboard-grid': '',\n style: {\n display: 'grid',\n gap,\n gridTemplateColumns,\n width: '100%',\n ...((attrs.style as Record<string, string> | undefined) ?? {}),\n },\n },\n slots.default?.(),\n )\n }\n },\n})\n\n/**\n * A single grid cell — wraps content in a styled card with optional span\n * controls. `col-span` accepts a number (column count) or `'full'` to fill\n * the entire row.\n */\nexport const IrisDashboardCard = defineComponent({\n name: 'IrisDashboardCard',\n inheritAttrs: false,\n props: {\n colSpan: { type: [Number, String], default: 1 },\n rowSpan: { type: Number, default: 1 },\n /** Show a styled card surface (background + border). Default `true`. */\n surface: { type: Boolean, default: true },\n },\n setup(props, { slots, attrs }) {\n return () => {\n const colSpan = props.colSpan === 'full' ? '1 / -1' : `span ${props.colSpan}`\n const rowSpan = props.rowSpan > 1 ? `span ${props.rowSpan}` : undefined\n return h(\n 'div',\n {\n ...attrs,\n 'data-iris-dashboard-card': '',\n style: {\n gridColumn: colSpan,\n gridRow: rowSpan,\n background: props.surface ? 'var(--iris-surface)' : 'transparent',\n border: props.surface ? '1px solid var(--iris-border)' : 'none',\n borderRadius: 'var(--iris-radius-md)',\n padding: props.surface ? 'var(--iris-padding-lg)' : '0',\n minWidth: '0',\n ...((attrs.style as Record<string, string> | undefined) ?? {}),\n },\n },\n slots.default?.(),\n )\n }\n },\n})\n","import { computed, defineComponent, h, type PropType } from 'vue'\n\nexport type IrisStackDirection = 'row' | 'column'\nexport type IrisStackAlign = 'start' | 'center' | 'end' | 'stretch'\nexport type IrisStackJustify = 'start' | 'center' | 'end' | 'between' | 'around'\n\nconst ALIGN_MAP: Record<IrisStackAlign, string> = {\n start: 'flex-start',\n center: 'center',\n end: 'flex-end',\n stretch: 'stretch',\n}\n\nconst JUSTIFY_MAP: Record<IrisStackJustify, string> = {\n start: 'flex-start',\n center: 'center',\n end: 'flex-end',\n between: 'space-between',\n around: 'space-around',\n}\n\nfunction toCssSpacing(spacing: string | number): string {\n if (typeof spacing === 'number') return `${spacing}px`\n // Token shorthand: \"sm\" / \"md\" / \"lg\" → var(--iris-gap-X)\n if (spacing === 'sm' || spacing === 'md' || spacing === 'lg') {\n return `var(--iris-gap-${spacing})`\n }\n return spacing\n}\n\n/**\n * Flex container with token-driven spacing. The lightest possible layout\n * primitive — most pages need a horizontal or vertical stack and this saves\n * hand-writing `display: flex` everywhere.\n *\n * Use `direction`/`spacing`/`align`/`justify`/`wrap` to configure; children\n * are arranged in document order with `gap: <spacing>`.\n */\nexport const IrisStack = defineComponent({\n name: 'IrisStack',\n inheritAttrs: false,\n props: {\n direction: { type: String as PropType<IrisStackDirection>, default: 'column' },\n spacing: { type: [String, Number], default: 'md' },\n align: { type: String as PropType<IrisStackAlign>, default: 'stretch' },\n justify: { type: String as PropType<IrisStackJustify>, default: 'start' },\n wrap: { type: Boolean, default: false },\n /** When true, renders as an inline-flex container. */\n inline: { type: Boolean, default: false },\n },\n setup(props, { slots, attrs }) {\n const style = computed<Record<string, string>>(() => ({\n display: props.inline ? 'inline-flex' : 'flex',\n flexDirection: props.direction,\n gap: toCssSpacing(props.spacing),\n alignItems: ALIGN_MAP[props.align],\n justifyContent: JUSTIFY_MAP[props.justify],\n flexWrap: props.wrap ? 'wrap' : 'nowrap',\n }))\n\n return () =>\n h(\n 'div',\n {\n ...attrs,\n 'data-iris-stack': '',\n 'data-iris-stack-direction': props.direction,\n style: { ...style.value, ...((attrs.style as Record<string, string> | undefined) ?? {}) },\n },\n slots.default?.(),\n )\n },\n})\n","import { computed, defineComponent, h, type PropType } from 'vue'\n\nexport type IrisContainerMaxWidth = 'sm' | 'md' | 'lg' | 'xl' | 'full' | string\n\nconst WIDTH_MAP: Record<'sm' | 'md' | 'lg' | 'xl' | 'full', string> = {\n sm: '640px',\n md: '768px',\n lg: '1024px',\n xl: '1280px',\n full: '100%',\n}\n\nfunction resolveMaxWidth(input: IrisContainerMaxWidth): string {\n if (input === 'sm' || input === 'md' || input === 'lg' || input === 'xl' || input === 'full') {\n return WIDTH_MAP[input]\n }\n return input // arbitrary CSS length\n}\n\nfunction resolvePadding(input: string | number): string {\n if (typeof input === 'number') return `${input}px`\n if (input === 'sm' || input === 'md' || input === 'lg') {\n return `var(--iris-padding-${input})`\n }\n return input\n}\n\n/**\n * Centered max-width wrapper. Use to bound content width on large screens\n * without rewriting flex/grid plumbing.\n *\n * `maxWidth='lg'` (≈1024px) is the most common default for marketing /\n * docs / app pages.\n */\nexport const IrisContainer = defineComponent({\n name: 'IrisContainer',\n inheritAttrs: false,\n props: {\n maxWidth: { type: String as PropType<IrisContainerMaxWidth>, default: 'lg' },\n padding: { type: [String, Number], default: 'md' },\n center: { type: Boolean, default: true },\n },\n setup(props, { slots, attrs }) {\n const style = computed<Record<string, string>>(() => ({\n width: '100%',\n maxWidth: resolveMaxWidth(props.maxWidth),\n padding: `0 ${resolvePadding(props.padding)}`,\n ...(props.center ? { marginInlineStart: 'auto', marginInlineEnd: 'auto' } : {}),\n }))\n\n return () =>\n h(\n 'div',\n {\n ...attrs,\n 'data-iris-container': '',\n 'data-iris-container-max-width': props.maxWidth,\n style: { ...style.value, ...((attrs.style as Record<string, string> | undefined) ?? {}) },\n },\n slots.default?.(),\n )\n },\n})\n"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { defineComponent, provide, ref, h, inject, onBeforeUnmount, computed } from 'vue';
|
|
2
|
+
import { createFormStore, formatPath, getByPath } from '@iris-ui-kit/core';
|
|
3
|
+
|
|
4
|
+
// src/form/Form.ts
|
|
5
|
+
var FormInjectionKey = /* @__PURE__ */ Symbol("IrisForm");
|
|
6
|
+
function useFormContext() {
|
|
7
|
+
const form = inject(FormInjectionKey, null);
|
|
8
|
+
if (!form) {
|
|
9
|
+
throw new Error("useField / useFormContext must be used within an <IrisForm>");
|
|
10
|
+
}
|
|
11
|
+
return form;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/form/Form.ts
|
|
15
|
+
function focusFirstError(formEl, errors) {
|
|
16
|
+
if (!formEl) return;
|
|
17
|
+
const keys = Object.keys(errors);
|
|
18
|
+
if (keys.length === 0) return;
|
|
19
|
+
const controls = formEl.querySelectorAll(
|
|
20
|
+
"input[name], select[name], textarea[name], [data-iris-field]"
|
|
21
|
+
);
|
|
22
|
+
for (const el of Array.from(controls)) {
|
|
23
|
+
const name = el.getAttribute("name") ?? el.getAttribute("data-iris-field");
|
|
24
|
+
if (name && keys.includes(name)) {
|
|
25
|
+
el.focus();
|
|
26
|
+
try {
|
|
27
|
+
el.scrollIntoView({ block: "center" });
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
var IrisForm = defineComponent({
|
|
35
|
+
name: "IrisForm",
|
|
36
|
+
props: {
|
|
37
|
+
/** The store from `useForm(...).form`. */
|
|
38
|
+
form: {
|
|
39
|
+
type: Object,
|
|
40
|
+
required: true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
setup(props, { slots }) {
|
|
44
|
+
provide(FormInjectionKey, props.form);
|
|
45
|
+
const formRef = ref(null);
|
|
46
|
+
return () => h(
|
|
47
|
+
"form",
|
|
48
|
+
{
|
|
49
|
+
ref: formRef,
|
|
50
|
+
"data-iris-form": "",
|
|
51
|
+
onSubmit: (event) => {
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
void props.form.handleSubmit().then(() => focusFirstError(formRef.value, props.form.getState().errors));
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
slots.default?.()
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
function useForm(config) {
|
|
61
|
+
const form = createFormStore(config);
|
|
62
|
+
const state = ref(form.getState());
|
|
63
|
+
const unsubscribe = form.subscribe((next) => {
|
|
64
|
+
state.value = next;
|
|
65
|
+
});
|
|
66
|
+
onBeforeUnmount(unsubscribe);
|
|
67
|
+
return {
|
|
68
|
+
form,
|
|
69
|
+
state,
|
|
70
|
+
values: computed(() => state.value.values),
|
|
71
|
+
errors: computed(() => state.value.errors),
|
|
72
|
+
touched: computed(() => state.value.touched),
|
|
73
|
+
dirty: computed(() => state.value.dirty),
|
|
74
|
+
isSubmitting: computed(() => state.value.isSubmitting),
|
|
75
|
+
isValidating: computed(() => state.value.isValidating),
|
|
76
|
+
submitCount: computed(() => state.value.submitCount),
|
|
77
|
+
isValid: computed(() => Object.keys(state.value.errors).length === 0),
|
|
78
|
+
setFieldValue: form.setFieldValue,
|
|
79
|
+
setValues: form.setValues,
|
|
80
|
+
setFieldTouched: form.setFieldTouched,
|
|
81
|
+
setFieldError: form.setFieldError,
|
|
82
|
+
setErrors: form.setErrors,
|
|
83
|
+
validateField: form.validateField,
|
|
84
|
+
validateForm: form.validateForm,
|
|
85
|
+
handleSubmit: form.handleSubmit,
|
|
86
|
+
reset: form.reset
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function useField(name) {
|
|
90
|
+
const form = useFormContext();
|
|
91
|
+
const state = ref(form.getState());
|
|
92
|
+
const unsubscribe = form.subscribe((next) => {
|
|
93
|
+
state.value = next;
|
|
94
|
+
});
|
|
95
|
+
onBeforeUnmount(unsubscribe);
|
|
96
|
+
const key = formatPath(name);
|
|
97
|
+
const value = computed(() => getByPath(state.value.values, name));
|
|
98
|
+
const error = computed(() => state.value.errors[key]);
|
|
99
|
+
return {
|
|
100
|
+
name,
|
|
101
|
+
value,
|
|
102
|
+
error,
|
|
103
|
+
touched: computed(() => Boolean(state.value.touched[key])),
|
|
104
|
+
dirty: computed(() => Boolean(state.value.dirty[key])),
|
|
105
|
+
setValue: (next) => form.setFieldValue(name, next),
|
|
106
|
+
setTouched: (touched = true) => form.setFieldTouched(name, touched),
|
|
107
|
+
fieldProps: computed(() => ({
|
|
108
|
+
modelValue: value.value,
|
|
109
|
+
"onUpdate:modelValue": (next) => form.setFieldValue(name, next),
|
|
110
|
+
invalid: Boolean(error.value),
|
|
111
|
+
onBlur: () => form.setFieldTouched(name, true)
|
|
112
|
+
}))
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function useFieldArray(name) {
|
|
116
|
+
const form = useFormContext();
|
|
117
|
+
const state = ref(form.getState());
|
|
118
|
+
const unsubscribe = form.subscribe((next) => {
|
|
119
|
+
state.value = next;
|
|
120
|
+
});
|
|
121
|
+
onBeforeUnmount(unsubscribe);
|
|
122
|
+
return {
|
|
123
|
+
name,
|
|
124
|
+
fields: computed(
|
|
125
|
+
() => Array.isArray(state.value.values[name]) ? state.value.values[name] : []
|
|
126
|
+
),
|
|
127
|
+
push: (item) => form.arrayPush(name, item),
|
|
128
|
+
remove: (index) => form.arrayRemove(name, index),
|
|
129
|
+
insert: (index, item) => form.arrayInsert(name, index, item),
|
|
130
|
+
move: (from, to) => form.arrayMove(name, from, to),
|
|
131
|
+
replace: (items) => form.setFieldValue(name, items)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { FormInjectionKey, IrisForm, useField, useFieldArray, useForm, useFormContext };
|
|
136
|
+
//# sourceMappingURL=chunk-4FLIW67H.js.map
|
|
137
|
+
//# sourceMappingURL=chunk-4FLIW67H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/form/context.ts","../src/form/Form.ts","../src/form/useForm.ts","../src/form/useField.ts","../src/form/useFieldArray.ts"],"names":["ref","onBeforeUnmount","computed"],"mappings":"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","file":"chunk-4FLIW67H.js","sourcesContent":["import { inject, type InjectionKey } from 'vue'\nimport type { FormStore, FormValues } from '@iris-ui-kit/core'\n\n/**\n * Provides the active form's {@link FormStore} to descendant fields so\n * `useField` can bind without prop drilling. The generic is erased at the\n * injection boundary; `useField<T>` re-applies the value type at the call site.\n */\nexport const FormInjectionKey: InjectionKey<FormStore<FormValues>> = Symbol('IrisForm')\n\nexport function useFormContext(): FormStore<FormValues> {\n const form = inject(FormInjectionKey, null)\n if (!form) {\n throw new Error('useField / useFormContext must be used within an <IrisForm>')\n }\n return form\n}\n","import { defineComponent, h, provide, ref, type PropType } from 'vue'\nimport type { FormStore, FormValues } from '@iris-ui-kit/core'\nimport { FormInjectionKey } from './context'\n\n/** Focus (and best-effort scroll to) the first errored named control in DOM order. */\nfunction focusFirstError(\n formEl: HTMLElement | null,\n errors: Record<string, string | undefined>,\n): void {\n if (!formEl) return\n const keys = Object.keys(errors)\n if (keys.length === 0) return\n const controls = formEl.querySelectorAll<HTMLElement>(\n 'input[name], select[name], textarea[name], [data-iris-field]',\n )\n for (const el of Array.from(controls)) {\n const name = el.getAttribute('name') ?? el.getAttribute('data-iris-field')\n if (name && keys.includes(name)) {\n el.focus()\n try {\n el.scrollIntoView({ block: 'center' })\n } catch {\n /* scrollIntoView is unavailable in jsdom — focus is the contract */\n }\n return\n }\n }\n}\n\n/**\n * Provides the form store to descendant `useField` calls and wires the native\n * `<form>` submit to `handleSubmit` (with `preventDefault`). Composition:\n *\n * ```html\n * <IrisForm :form=\"f.form\">\n * <IrisFormField label=\"Email\"><IrisInput v-bind=\"email.fieldProps.value\" /></IrisFormField>\n * <IrisButton type=\"submit\" :disabled=\"f.isSubmitting.value\">Save</IrisButton>\n * </IrisForm>\n * ```\n */\nexport const IrisForm = defineComponent({\n name: 'IrisForm',\n props: {\n /** The store from `useForm(...).form`. */\n form: {\n type: Object as PropType<FormStore<FormValues>>,\n required: true,\n },\n },\n setup(props, { slots }) {\n provide(FormInjectionKey, props.form)\n const formRef = ref<HTMLElement | null>(null)\n return () =>\n h(\n 'form',\n {\n ref: formRef,\n 'data-iris-form': '',\n onSubmit: (event: Event) => {\n event.preventDefault()\n // On a failed submit, move focus to the first errored field (a11y).\n void props.form\n .handleSubmit()\n .then(() => focusFirstError(formRef.value, props.form.getState().errors))\n },\n },\n slots.default?.(),\n )\n },\n})\n","import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport {\n createFormStore,\n type FieldErrors,\n type FieldFlags,\n type FormConfig,\n type FormState,\n type FormStore,\n type FormValues,\n} from '@iris-ui-kit/core'\n\nexport interface UseFormReturn<V extends FormValues> {\n /** The form store — pass to `<IrisForm :form=\"...\">`. */\n form: FormStore<V>\n /** The full reactive state snapshot. */\n state: Ref<FormState<V>>\n values: ComputedRef<V>\n errors: ComputedRef<FieldErrors<V>>\n touched: ComputedRef<FieldFlags<V>>\n dirty: ComputedRef<FieldFlags<V>>\n isSubmitting: ComputedRef<boolean>\n isValidating: ComputedRef<boolean>\n submitCount: ComputedRef<number>\n isValid: ComputedRef<boolean>\n setFieldValue: FormStore<V>['setFieldValue']\n setValues: FormStore<V>['setValues']\n setFieldTouched: FormStore<V>['setFieldTouched']\n setFieldError: FormStore<V>['setFieldError']\n setErrors: FormStore<V>['setErrors']\n validateField: FormStore<V>['validateField']\n validateForm: FormStore<V>['validateForm']\n handleSubmit: FormStore<V>['handleSubmit']\n reset: FormStore<V>['reset']\n}\n\n/**\n * Vue binding for the framework-agnostic form engine. Creates the store in\n * `setup()` (runs once) and bridges it into Vue reactivity via a `ref` updated\n * on each store change, cleaned up on unmount. Because `setup` runs once,\n * `onSubmit` / `validate` closures stay live against reactive state — no\n * stale-callback handling is needed (unlike the React adapter).\n */\nexport function useForm<V extends FormValues>(config: FormConfig<V>): UseFormReturn<V> {\n const form = createFormStore(config)\n const state = ref(form.getState()) as Ref<FormState<V>>\n const unsubscribe = form.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n return {\n form,\n state,\n values: computed(() => state.value.values),\n errors: computed(() => state.value.errors),\n touched: computed(() => state.value.touched),\n dirty: computed(() => state.value.dirty),\n isSubmitting: computed(() => state.value.isSubmitting),\n isValidating: computed(() => state.value.isValidating),\n submitCount: computed(() => state.value.submitCount),\n isValid: computed(() => Object.keys(state.value.errors).length === 0),\n setFieldValue: form.setFieldValue,\n setValues: form.setValues,\n setFieldTouched: form.setFieldTouched,\n setFieldError: form.setFieldError,\n setErrors: form.setErrors,\n validateField: form.validateField,\n validateForm: form.validateForm,\n handleSubmit: form.handleSubmit,\n reset: form.reset,\n }\n}\n","import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport { formatPath, getByPath, type FormState, type FormValues } from '@iris-ui-kit/core'\nimport { useFormContext } from './context'\n\nexport interface FieldBindProps {\n modelValue: unknown\n 'onUpdate:modelValue': (value: unknown) => void\n invalid: boolean\n onBlur: () => void\n}\n\nexport interface UseFieldReturn<T> {\n name: string\n value: ComputedRef<T>\n error: ComputedRef<string | undefined>\n touched: ComputedRef<boolean>\n dirty: ComputedRef<boolean>\n setValue: (value: T) => void\n setTouched: (touched?: boolean) => void\n /**\n * Bundle for `v-bind` onto a v-model'd Iris control (`IrisInput`,\n * `IrisSelect`, …): wires `modelValue` / `update:modelValue` / `invalid` /\n * `blur`. Use `value` + `setValue` directly for bespoke bindings.\n */\n fieldProps: ComputedRef<FieldBindProps>\n}\n\n/**\n * Binds a single field to the surrounding `<IrisForm>`. `T` is the value type\n * at the call site (the injection erases the form's generic).\n *\n * `name` may be a flat top-level key OR a nested PATH (`'address.city'`,\n * `'items[2].sku'`); a flat key is a 1-segment path and stays back-compatible\n * (v3 R19).\n */\nexport function useField<T = unknown>(name: string): UseFieldReturn<T> {\n const form = useFormContext()\n const state = ref(form.getState()) as Ref<FormState<FormValues>>\n const unsubscribe = form.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n // Canonical key for per-field state lookups (a flat key maps to itself).\n const key = formatPath(name)\n const value = computed(() => getByPath(state.value.values, name) as T)\n const error = computed(() => state.value.errors[key])\n\n return {\n name,\n value,\n error,\n touched: computed(() => Boolean(state.value.touched[key])),\n dirty: computed(() => Boolean(state.value.dirty[key])),\n setValue: (next) => form.setFieldValue(name, next as never),\n setTouched: (touched = true) => form.setFieldTouched(name, touched),\n fieldProps: computed(() => ({\n modelValue: value.value,\n 'onUpdate:modelValue': (next: unknown) => form.setFieldValue(name, next as never),\n invalid: Boolean(error.value),\n onBlur: () => form.setFieldTouched(name, true),\n })),\n }\n}\n","import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport type { FormState, FormValues } from '@iris-ui-kit/core'\nimport { useFormContext } from './context'\n\nexport interface UseFieldArrayReturn<T> {\n name: string\n /** Current array value (reactive). */\n fields: ComputedRef<T[]>\n /** Append an item. */\n push: (item: T) => void\n /** Remove the item at `index`. */\n remove: (index: number) => void\n /** Insert `item` at `index` (shifting the rest right). */\n insert: (index: number, item: T) => void\n /** Move the item from `from` to `to`. */\n move: (from: number, to: number) => void\n /** Replace the whole array. */\n replace: (items: T[]) => void\n}\n\n/**\n * Manage a dynamic array field (repeatable rows) inside an `<IrisForm>`. Mutators\n * delegate to the core {@link FormStore} array helpers (`arrayPush`/`arrayInsert`/\n * `arrayRemove`/`arrayMove`), which RE-KEY each element's error/touched/dirty/\n * validating state across the mutation — so a row's per-element validation state\n * FOLLOWS the row when rows are removed or reordered (removing `items[0]` shifts\n * `items[2]`'s error down to `items[1]`). `replace` swaps the whole array.\n */\nexport function useFieldArray<T = unknown>(name: string): UseFieldArrayReturn<T> {\n const form = useFormContext()\n const state = ref(form.getState()) as Ref<FormState<FormValues>>\n const unsubscribe = form.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n return {\n name,\n fields: computed(\n () => (Array.isArray(state.value.values[name]) ? state.value.values[name] : []) as T[],\n ),\n push: (item) => form.arrayPush(name as never, item as never),\n remove: (index) => form.arrayRemove(name as never, index),\n insert: (index, item) => form.arrayInsert(name as never, index, item as never),\n move: (from, to) => form.arrayMove(name as never, from, to),\n replace: (items) => form.setFieldValue(name, items as never),\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-4FQ7XF52.js"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { defineComponent, ref, onMounted, watch, onBeforeUnmount, provide, computed, inject } from 'vue';
|
|
2
|
+
import { injectGlobalStyles, applyTheme, applyDirection, getColorScheme, watchColorScheme } from '@iris-ui-kit/theme';
|
|
3
|
+
|
|
4
|
+
// src/theme/ThemeProvider.ts
|
|
5
|
+
var IrisThemeKey = /* @__PURE__ */ Symbol("IrisTheme");
|
|
6
|
+
var ThemeProvider = defineComponent({
|
|
7
|
+
name: "IrisThemeProvider",
|
|
8
|
+
props: {
|
|
9
|
+
store: {
|
|
10
|
+
type: Object,
|
|
11
|
+
required: true
|
|
12
|
+
},
|
|
13
|
+
target: {
|
|
14
|
+
type: Object,
|
|
15
|
+
default: null
|
|
16
|
+
},
|
|
17
|
+
/** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */
|
|
18
|
+
dir: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: "ltr"
|
|
21
|
+
},
|
|
22
|
+
/** CSP nonce for injected inline stylesheets. */
|
|
23
|
+
cspNonce: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: void 0
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
setup(props, { slots }) {
|
|
29
|
+
const current = ref(props.store.store.getState());
|
|
30
|
+
const unsubscribe = props.store.store.subscribe((next) => {
|
|
31
|
+
current.value = next;
|
|
32
|
+
});
|
|
33
|
+
let applied = null;
|
|
34
|
+
let dirApplied = null;
|
|
35
|
+
const targetEl = () => props.target ?? document.documentElement;
|
|
36
|
+
const applyCurrent = () => {
|
|
37
|
+
applied?.revert();
|
|
38
|
+
applied = applyTheme(current.value, targetEl());
|
|
39
|
+
};
|
|
40
|
+
const applyDir = () => {
|
|
41
|
+
dirApplied?.revert();
|
|
42
|
+
dirApplied = applyDirection(props.dir, targetEl());
|
|
43
|
+
};
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
injectGlobalStyles(props.cspNonce);
|
|
46
|
+
applyCurrent();
|
|
47
|
+
applyDir();
|
|
48
|
+
});
|
|
49
|
+
watch(current, () => {
|
|
50
|
+
if (applied) applyCurrent();
|
|
51
|
+
});
|
|
52
|
+
watch(
|
|
53
|
+
() => props.dir,
|
|
54
|
+
() => {
|
|
55
|
+
if (dirApplied) applyDir();
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
onBeforeUnmount(() => {
|
|
59
|
+
unsubscribe();
|
|
60
|
+
applied?.revert();
|
|
61
|
+
applied = null;
|
|
62
|
+
dirApplied?.revert();
|
|
63
|
+
dirApplied = null;
|
|
64
|
+
});
|
|
65
|
+
provide(IrisThemeKey, { store: props.store, current, dir: computed(() => props.dir) });
|
|
66
|
+
return () => slots.default?.();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
function useThemeContext() {
|
|
70
|
+
const ctx = inject(IrisThemeKey);
|
|
71
|
+
if (!ctx) {
|
|
72
|
+
throw new Error("[iris-ui] useTheme(): no <ThemeProvider> ancestor found");
|
|
73
|
+
}
|
|
74
|
+
return ctx;
|
|
75
|
+
}
|
|
76
|
+
function useDirection() {
|
|
77
|
+
const ctx = inject(IrisThemeKey, null);
|
|
78
|
+
return ctx ? ctx.dir : computed(() => "ltr");
|
|
79
|
+
}
|
|
80
|
+
function useTheme() {
|
|
81
|
+
const ctx = useThemeContext();
|
|
82
|
+
return {
|
|
83
|
+
theme: computed(() => ctx.current.value),
|
|
84
|
+
setTheme: ctx.store.setTheme,
|
|
85
|
+
availableThemes: ctx.store.availableThemes
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function useColorScheme() {
|
|
89
|
+
const scheme = ref(getColorScheme());
|
|
90
|
+
const stop = watchColorScheme((s) => {
|
|
91
|
+
scheme.value = s;
|
|
92
|
+
});
|
|
93
|
+
onBeforeUnmount(stop);
|
|
94
|
+
return scheme;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { IrisThemeKey, ThemeProvider, useColorScheme, useDirection, useTheme, useThemeContext };
|
|
98
|
+
//# sourceMappingURL=chunk-72PZMU6R.js.map
|
|
99
|
+
//# sourceMappingURL=chunk-72PZMU6R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/theme/ThemeProvider.ts","../src/theme/useTheme.ts","../src/theme/useColorScheme.ts"],"names":["computed","ref","onBeforeUnmount"],"mappings":"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","file":"chunk-72PZMU6R.js","sourcesContent":["import {\n computed,\n defineComponent,\n inject,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n watch,\n type ComputedRef,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport {\n applyDirection,\n applyTheme,\n injectGlobalStyles,\n type ApplyDirectionResult,\n type ApplyThemeResult,\n type Direction,\n type ThemeStore,\n} from '@iris-ui-kit/theme'\nimport type { IrisTheme } from '@iris-ui-kit/tokens'\n\nexport interface IrisThemeContext {\n store: ThemeStore\n current: Ref<IrisTheme>\n dir: ComputedRef<Direction>\n}\n\nexport const IrisThemeKey: InjectionKey<IrisThemeContext> = Symbol('IrisTheme')\n\n/**\n * Renderless provider that:\n * 1. exposes the theme store to descendants via `provide`,\n * 2. applies the current theme to a target element on mount and on change,\n * 3. reverts the inline custom properties on unmount.\n *\n * `target` defaults to `document.documentElement`. Pass an element ref to\n * scope a theme to a subtree.\n */\nexport const ThemeProvider = defineComponent({\n name: 'IrisThemeProvider',\n props: {\n store: {\n type: Object as PropType<ThemeStore>,\n required: true,\n },\n target: {\n type: Object as PropType<HTMLElement | null>,\n default: null,\n },\n /** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */\n dir: {\n type: String as PropType<Direction>,\n default: 'ltr',\n },\n /** CSP nonce for injected inline stylesheets. */\n cspNonce: {\n type: String,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n const current = ref(props.store.store.getState()) as Ref<IrisTheme>\n const unsubscribe = props.store.store.subscribe((next) => {\n current.value = next\n })\n\n let applied: ApplyThemeResult | null = null\n let dirApplied: ApplyDirectionResult | null = null\n\n const targetEl = () => props.target ?? document.documentElement\n\n const applyCurrent = () => {\n applied?.revert()\n applied = applyTheme(current.value, targetEl())\n }\n\n const applyDir = () => {\n dirApplied?.revert()\n dirApplied = applyDirection(props.dir, targetEl())\n }\n\n onMounted(() => {\n injectGlobalStyles(props.cspNonce)\n applyCurrent()\n applyDir()\n })\n\n watch(current, () => {\n if (applied) applyCurrent()\n })\n\n watch(\n () => props.dir,\n () => {\n if (dirApplied) applyDir()\n },\n )\n\n onBeforeUnmount(() => {\n unsubscribe()\n applied?.revert()\n applied = null\n dirApplied?.revert()\n dirApplied = null\n })\n\n provide(IrisThemeKey, { store: props.store, current, dir: computed(() => props.dir) })\n\n return () => slots.default?.()\n },\n})\n\nexport function useThemeContext(): IrisThemeContext {\n const ctx = inject(IrisThemeKey)\n if (!ctx) {\n throw new Error('[iris-ui] useTheme(): no <ThemeProvider> ancestor found')\n }\n return ctx\n}\n\n/**\n * Current writing direction (`'ltr'` / `'rtl'`) from the nearest\n * `<ThemeProvider>`, or a static `'ltr'` ref when there is none.\n */\nexport function useDirection(): ComputedRef<Direction> {\n const ctx = inject(IrisThemeKey, null)\n return ctx ? ctx.dir : computed(() => 'ltr' as Direction)\n}\n","import { computed, type ComputedRef } from 'vue'\nimport type { IrisTheme } from '@iris-ui-kit/tokens'\nimport { useThemeContext } from './ThemeProvider'\n\nexport interface UseThemeReturn {\n /** Reactive ref to the active theme. */\n theme: ComputedRef<IrisTheme>\n /** Switch by name or by passing a theme directly. */\n setTheme: (target: string | IrisTheme) => void\n /** Map of all themes registered with the store. */\n availableThemes: Record<string, IrisTheme>\n}\n\n/**\n * Read and write the current theme from anywhere inside a <ThemeProvider>.\n *\n * @example\n * const { theme, setTheme } = useTheme()\n * theme.value.colors['iris.primary']\n * setTheme('dark')\n */\nexport function useTheme(): UseThemeReturn {\n const ctx = useThemeContext()\n return {\n theme: computed(() => ctx.current.value),\n setTheme: ctx.store.setTheme,\n availableThemes: ctx.store.availableThemes,\n }\n}\n","import { onBeforeUnmount, ref, type Ref } from 'vue'\nimport { getColorScheme, watchColorScheme, type ColorScheme } from '@iris-ui-kit/theme'\n\n/**\n * Reactive system color scheme (`'light'` / `'dark'`) from\n * `prefers-color-scheme`. SSR-safe (reports `'light'` until matchMedia is\n * available). Wire it to a theme store to auto-follow the system:\n *\n * ```ts\n * const scheme = useColorScheme()\n * watch(scheme, (s) => store.setTheme(s === 'dark' ? 'dark' : 'light'), { immediate: true })\n * ```\n */\nexport function useColorScheme(): Ref<ColorScheme> {\n const scheme = ref<ColorScheme>(getColorScheme())\n const stop = watchColorScheme((s) => {\n scheme.value = s\n })\n onBeforeUnmount(stop)\n return scheme\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { shallowRef, onScopeDispose } from 'vue';
|
|
2
|
+
|
|
3
|
+
// src/useStore.ts
|
|
4
|
+
function useStore(store) {
|
|
5
|
+
const state = shallowRef(store.getState());
|
|
6
|
+
onScopeDispose(store.subscribe((next) => state.value = next));
|
|
7
|
+
return state;
|
|
8
|
+
}
|
|
9
|
+
function useStoreSelector(store, selector, equals) {
|
|
10
|
+
const slice = shallowRef(selector(store.getState()));
|
|
11
|
+
onScopeDispose(store.subscribeWith(selector, (v) => slice.value = v, equals));
|
|
12
|
+
return slice;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { useStore, useStoreSelector };
|
|
16
|
+
//# sourceMappingURL=chunk-75GSYEJS.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-75GSYEJS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/useStore.ts"],"names":[],"mappings":";;;AASO,SAAS,SAAY,KAAA,EAAkD;AAC5E,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,QAAA,EAAU,CAAA;AACzC,EAAA,cAAA,CAAe,MAAM,SAAA,CAAU,CAAC,SAAU,KAAA,CAAM,KAAA,GAAQ,IAAK,CAAC,CAAA;AAC9D,EAAA,OAAO,KAAA;AACT;AAOO,SAAS,gBAAA,CACd,KAAA,EACA,QAAA,EACA,MAAA,EACyB;AACzB,EAAA,MAAM,QAAQ,UAAA,CAAW,QAAA,CAAS,KAAA,CAAM,QAAA,EAAU,CAAC,CAAA;AACnD,EAAA,cAAA,CAAe,KAAA,CAAM,cAAc,QAAA,EAAU,CAAC,MAAO,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAI,MAAM,CAAC,CAAA;AAC9E,EAAA,OAAO,KAAA;AACT","file":"chunk-75GSYEJS.js","sourcesContent":["import { shallowRef, onScopeDispose, type ShallowRef } from 'vue'\nimport type { ReadonlyStore, Store } from '@iris-ui-kit/core'\n\n/**\n * Bridge a framework-agnostic `@iris-ui-kit/core` store into a Vue ref — updates on\n * every store emission. The mirror of React's `useSyncExternalStore`, Solid's\n * `createSignal`, and Svelte's `readable`. Seeds synchronously from\n * `store.getState()` (SSR-safe); detaches on scope dispose.\n */\nexport function useStore<T>(store: ReadonlyStore<T>): Readonly<ShallowRef<T>> {\n const state = shallowRef(store.getState()) as ShallowRef<T>\n onScopeDispose(store.subscribe((next) => (state.value = next)))\n return state\n}\n\n/**\n * Subscribe to a DERIVED slice of a core store — the ref updates only when\n * `selector(state)` changes per `equals` (default `Object.is`), not on every\n * store emission. Built on {@link Store.subscribeWith}.\n */\nexport function useStoreSelector<T, U>(\n store: Store<T>,\n selector: (state: T) => U,\n equals?: (a: U, b: U) => boolean,\n): Readonly<ShallowRef<U>> {\n const slice = shallowRef(selector(store.getState())) as ShallowRef<U>\n onScopeDispose(store.subscribeWith(selector, (v) => (slice.value = v), equals))\n return slice\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useStore } from './chunk-75GSYEJS.js';
|
|
2
|
+
import { onMounted, onScopeDispose, computed } from 'vue';
|
|
3
|
+
import { createDataSource, createGroupedView } from '@iris-ui-kit/core';
|
|
4
|
+
export { createClientDataSource, createDataSource, createGroupedView } from '@iris-ui-kit/core';
|
|
5
|
+
|
|
6
|
+
function useDataSource(config) {
|
|
7
|
+
const controller = createDataSource({ ...config, immediate: false });
|
|
8
|
+
const immediate = config.immediate !== false;
|
|
9
|
+
onMounted(() => {
|
|
10
|
+
if (immediate) void controller.load();
|
|
11
|
+
});
|
|
12
|
+
onScopeDispose(() => controller.destroy());
|
|
13
|
+
const state = useStore(controller.store);
|
|
14
|
+
return { ...controller, state };
|
|
15
|
+
}
|
|
16
|
+
function useGroupedView(config) {
|
|
17
|
+
const controller = createGroupedView(config);
|
|
18
|
+
const storeRef = useStore(controller.store);
|
|
19
|
+
const state = computed(() => {
|
|
20
|
+
const s = storeRef.value;
|
|
21
|
+
return s.state;
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
store: controller.store,
|
|
25
|
+
setRows: (rows, columns) => controller.setRows(rows, columns),
|
|
26
|
+
toggleGroup: (key) => controller.toggleGroup(key),
|
|
27
|
+
expandGroup: (key) => controller.expandGroup(key),
|
|
28
|
+
collapseGroup: (key) => controller.collapseGroup(key),
|
|
29
|
+
expandAll: () => controller.expandAll(),
|
|
30
|
+
collapseAll: () => controller.collapseAll(),
|
|
31
|
+
state,
|
|
32
|
+
setConfig: (partial) => controller.setConfig(partial)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { useDataSource, useGroupedView };
|
|
37
|
+
//# sourceMappingURL=chunk-7IOJADZC.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-7IOJADZC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data/useDataSource.ts","../src/data/useGroupedView.ts"],"names":[],"mappings":";;;;;AA8BO,SAAS,cAAiB,MAAA,EAA+C;AAC9E,EAAA,MAAM,aAAa,gBAAA,CAAiB,EAAE,GAAG,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AACnE,EAAA,MAAM,SAAA,GAAY,OAAO,SAAA,KAAc,KAAA;AAEvC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,EAAW,KAAK,UAAA,CAAW,IAAA,EAAK;AAAA,EACtC,CAAC,CAAA;AAGD,EAAA,cAAA,CAAe,MAAM,UAAA,CAAW,OAAA,EAAS,CAAA;AAEzC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AACvC,EAAA,OAAO,EAAE,GAAG,UAAA,EAAY,KAAA,EAAM;AAChC;ACfO,SAAS,eACd,MAAA,EACwB;AACxB,EAAA,MAAM,UAAA,GAAa,kBAA0B,MAAM,CAAA;AACnD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,SAAS,MAAM;AAC3B,IAAA,MAAM,IAAI,QAAA,CAAS,KAAA;AACnB,IAAA,OAAO,CAAA,CAAE,KAAA;AAAA,EACX,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,OAAO,UAAA,CAAW,KAAA;AAAA,IAClB,SAAS,CAAC,IAAA,EAAM,YAAY,UAAA,CAAW,OAAA,CAAQ,MAAM,OAAO,CAAA;AAAA,IAC5D,WAAA,EAAa,CAAC,GAAA,KAAQ,UAAA,CAAW,YAAY,GAAG,CAAA;AAAA,IAChD,WAAA,EAAa,CAAC,GAAA,KAAQ,UAAA,CAAW,YAAY,GAAG,CAAA;AAAA,IAChD,aAAA,EAAe,CAAC,GAAA,KAAQ,UAAA,CAAW,cAAc,GAAG,CAAA;AAAA,IACpD,SAAA,EAAW,MAAM,UAAA,CAAW,SAAA,EAAU;AAAA,IACtC,WAAA,EAAa,MAAM,UAAA,CAAW,WAAA,EAAY;AAAA,IAC1C,KAAA;AAAA,IACA,SAAA,EAAW,CAAC,OAAA,KAAY,UAAA,CAAW,UAAU,OAAO;AAAA,GACtD;AACF","file":"chunk-7IOJADZC.js","sourcesContent":["import { onMounted, onScopeDispose, type ShallowRef } from 'vue'\nimport {\n createDataSource,\n type DataSourceController,\n type DataSourceConfig,\n type DataSourceState,\n} from '@iris-ui-kit/core'\nimport { useStore } from '../useStore'\n\nexport interface UseDataSource<T> extends DataSourceController<T> {\n /**\n * The live data-source state as a reactive ref: rows, total, page/pageSize,\n * sort/multiSort, filters/filterRules, loading/loadingMore, hasMore,\n * selectedKeys, and the per-row pendingRows/rowErrors.\n */\n state: ShallowRef<DataSourceState<T>>\n}\n\n/**\n * Vue bridge over the framework-agnostic {@link createDataSource} — the unified\n * data engine (paged/infinite + multi-sort + typed filters + selection +\n * per-row + optimistic mutate). Creates the controller once in `setup()`,\n * mirrors its store into a reactive ref, and returns the controller plus its\n * live `state`. A thin bridge — all logic lives in `@iris-ui-kit/core`.\n *\n * Constructed with `immediate: false` so no fetch fires during `setup()`; the\n * initial load is kicked from `onMounted` and the controller is torn down on\n * scope dispose (aborting any in-flight request) so a late response never\n * writes back to a torn-down instance.\n */\nexport function useDataSource<T>(config: DataSourceConfig<T>): UseDataSource<T> {\n const controller = createDataSource({ ...config, immediate: false })\n const immediate = config.immediate !== false\n\n onMounted(() => {\n if (immediate) void controller.load()\n })\n // Abort any in-flight fetch + detach the controller's internal subscriptions\n // on unmount (a late response must not write back to a torn-down instance).\n onScopeDispose(() => controller.destroy())\n\n const state = useStore(controller.store)\n return { ...controller, state }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport {\n createGroupedView,\n type GroupedViewConfig,\n type GroupedViewState,\n type GroupedViewStore,\n} from '@iris-ui-kit/core'\nimport type { DataViewColumn } from '@iris-ui-kit/core'\nimport { useStore } from '../useStore'\n\nexport interface UseGroupedView<Row, K = string> {\n store: ReturnType<typeof createGroupedView<Row, K>>['store']\n setRows: (rows: readonly Row[], columns?: readonly DataViewColumn<Row>[]) => void\n toggleGroup: (key: K) => void\n expandGroup: (key: K) => void\n collapseGroup: (key: K) => void\n expandAll: () => void\n collapseAll: () => void\n /** Reactive live grouped-view state. */\n state: ComputedRef<GroupedViewState<Row, K>>\n setConfig: (partial: Partial<GroupedViewConfig<Row, K>>) => void\n}\n\n/**\n * Vue bridge over the framework-agnostic {@link createGroupedView}.\n * Creates the controller once, subscribes its store to a reactive ref,\n * and returns the controller plus a computed `state`.\n */\nexport function useGroupedView<Row, K = string>(\n config: GroupedViewConfig<Row, K>,\n): UseGroupedView<Row, K> {\n const controller = createGroupedView<Row, K>(config)\n const storeRef = useStore(controller.store)\n const state = computed(() => {\n const s = storeRef.value as GroupedViewStore<Row, K>\n return s.state\n })\n\n return {\n store: controller.store,\n setRows: (rows, columns) => controller.setRows(rows, columns),\n toggleGroup: (key) => controller.toggleGroup(key),\n expandGroup: (key) => controller.expandGroup(key),\n collapseGroup: (key) => controller.collapseGroup(key),\n expandAll: () => controller.expandAll(),\n collapseAll: () => controller.collapseAll(),\n state,\n setConfig: (partial) => controller.setConfig(partial),\n }\n}\n"]}
|