@morscherlab/mint-sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/BaseModal-B9UA8Y_I.js +165 -0
  2. package/dist/BaseModal-B9UA8Y_I.js.map +1 -0
  3. package/dist/BaseSelect-DksaKYq_.js +176 -0
  4. package/dist/BaseSelect-DksaKYq_.js.map +1 -0
  5. package/dist/ExperimentPopover-CCYB1oWp.js +361 -0
  6. package/dist/ExperimentPopover-CCYB1oWp.js.map +1 -0
  7. package/dist/ExperimentPopover-D0bg_fqM.js +3 -0
  8. package/dist/ExperimentSelectorModal-B_kPbXcg.js +4 -0
  9. package/dist/ExperimentSelectorModal-wm7yUdAr.js +720 -0
  10. package/dist/ExperimentSelectorModal-wm7yUdAr.js.map +1 -0
  11. package/dist/SettingsModal-L7Ejny45.js +5 -0
  12. package/dist/SettingsModal-LEKI6Ebl.js +521 -0
  13. package/dist/SettingsModal-LEKI6Ebl.js.map +1 -0
  14. package/dist/{auth-BulIv_km.js → auth-D9q2GIcv.js} +3 -80
  15. package/dist/auth-D9q2GIcv.js.map +1 -0
  16. package/dist/components/DataFrame.vue.d.ts +3 -0
  17. package/dist/components/ExperimentDataViewer.vue.d.ts +2 -0
  18. package/dist/components/PluginWorkspaceView.vue.d.ts +2 -2
  19. package/dist/components/index.js +7 -2
  20. package/dist/{components-DtX3LDLq.js → components-CdjRzHI2.js} +533 -2025
  21. package/dist/components-CdjRzHI2.js.map +1 -0
  22. package/dist/composables/index.js +9 -3
  23. package/dist/composables/usePluginClient.d.ts +2 -1
  24. package/dist/{composables-wNt7VtkF.js → composables-DJgqPrlR.js} +7 -12
  25. package/dist/{composables-wNt7VtkF.js.map → composables-DJgqPrlR.js.map} +1 -1
  26. package/dist/experiment-utils-hGXMHlAc.js +109 -0
  27. package/dist/experiment-utils-hGXMHlAc.js.map +1 -0
  28. package/dist/index.js +16 -5
  29. package/dist/index.js.map +1 -1
  30. package/dist/install.js +7 -2
  31. package/dist/install.js.map +1 -1
  32. package/dist/permissions.js +81 -0
  33. package/dist/permissions.js.map +1 -0
  34. package/dist/stores/index.js +1 -1
  35. package/dist/styles.css +3233 -3185
  36. package/dist/templates/index.js +3 -1
  37. package/dist/templates-Do43ZIMb.js +5065 -0
  38. package/dist/templates-Do43ZIMb.js.map +1 -0
  39. package/dist/{templates-DSbHJC4v.js → useControlSchema-0n8Bcftq.js} +10 -5335
  40. package/dist/useControlSchema-0n8Bcftq.js.map +1 -0
  41. package/dist/useDropdownState-Ben4DnjJ.js +47 -0
  42. package/dist/useDropdownState-Ben4DnjJ.js.map +1 -0
  43. package/dist/useEventListener-CfVkP9Xz.js +57 -0
  44. package/dist/useEventListener-CfVkP9Xz.js.map +1 -0
  45. package/dist/useExperimentSelector-BpZklTbV.js +469 -0
  46. package/dist/useExperimentSelector-BpZklTbV.js.map +1 -0
  47. package/dist/useFormBuilder-COfYWDuC.js +729 -0
  48. package/dist/useFormBuilder-COfYWDuC.js.map +1 -0
  49. package/dist/{useProtocolTemplates-DwBhEPPU.js → useProtocolTemplates-TUQO_F3n.js} +8 -1298
  50. package/dist/useProtocolTemplates-TUQO_F3n.js.map +1 -0
  51. package/dist/utils/pluginIcon.d.ts +29 -2
  52. package/package.json +5 -1
  53. package/src/__tests__/components/DataFrame.test.ts +37 -0
  54. package/src/__tests__/components/PluginIcon.test.ts +77 -0
  55. package/src/__tests__/composables/usePluginClient.test.ts +11 -10
  56. package/src/components/AppTopBar.vue +7 -6
  57. package/src/components/DataFrame.vue +27 -2
  58. package/src/components/ExperimentDataViewer.vue +5 -1
  59. package/src/components/PluginIcon.story.vue +31 -1
  60. package/src/components/PluginIcon.vue +94 -4
  61. package/src/composables/usePluginClient.ts +3 -12
  62. package/src/styles/components/dataframe.css +26 -0
  63. package/src/styles/components/plugin-icon.css +5 -0
  64. package/src/utils/pluginIcon.ts +159 -2
  65. package/dist/auth-BulIv_km.js.map +0 -1
  66. package/dist/components-DtX3LDLq.js.map +0 -1
  67. package/dist/templates-DSbHJC4v.js.map +0 -1
  68. package/dist/useProtocolTemplates-DwBhEPPU.js.map +0 -1
@@ -0,0 +1,521 @@
1
+ import { E as getFieldRegistryEntry, b as controlsToSettingsSchema, f as resolveControlModel, g as mergeControlWorkspaceOptions } from "./useControlSchema-0n8Bcftq.js";
2
+ import { t as BaseModal_default } from "./BaseModal-B9UA8Y_I.js";
3
+ import { n as colorPalettes, r as useSettingsStore, t as useAuthStore } from "./auth-D9q2GIcv.js";
4
+ import { i as usePlatformContext, t as useFormBuilder } from "./useFormBuilder-COfYWDuC.js";
5
+ import { canAccessByPolicy } from "./permissions.js";
6
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, normalizeProps, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, vShow, watch, withCtx, withDirectives } from "vue";
7
+ //#region src/utils/items.ts
8
+ function normalizeItemInput(item) {
9
+ if (typeof item === "object") return item;
10
+ return {
11
+ id: item,
12
+ label: item
13
+ };
14
+ }
15
+ function normalizeLabelItemInput(item) {
16
+ if (typeof item === "object") return item;
17
+ return { label: item };
18
+ }
19
+ //#endregion
20
+ //#region src/components/FormField.vue?vue&type=script&setup=true&lang.ts
21
+ var _hoisted_1$1 = { class: "mint-form-field" };
22
+ var _hoisted_2$1 = {
23
+ key: 0,
24
+ class: "mint-form-field__label-row"
25
+ };
26
+ var _hoisted_3$1 = ["for"];
27
+ var _hoisted_4$1 = {
28
+ key: 0,
29
+ class: "mint-form-field__required",
30
+ "aria-hidden": "true"
31
+ };
32
+ var _hoisted_5$1 = {
33
+ key: 0,
34
+ class: "mint-form-field__optional"
35
+ };
36
+ var _hoisted_6$1 = ["id"];
37
+ var _hoisted_7$1 = ["id"];
38
+ //#endregion
39
+ //#region src/components/FormField.vue
40
+ var FormField_default = /* @__PURE__ */ defineComponent({
41
+ __name: "FormField",
42
+ props: {
43
+ label: {},
44
+ error: {},
45
+ hint: {},
46
+ required: { type: Boolean },
47
+ showOptional: { type: Boolean },
48
+ htmlFor: {},
49
+ fieldId: {}
50
+ },
51
+ setup(__props) {
52
+ /** Wraps a form control with a label, optional hint text, and validation error display. */
53
+ const props = __props;
54
+ const errorId = computed(() => props.error && props.fieldId ? `${props.fieldId}-error` : void 0);
55
+ const hintId = computed(() => !props.error && props.hint && props.fieldId ? `${props.fieldId}-hint` : void 0);
56
+ const describedBy = computed(() => errorId.value ?? hintId.value);
57
+ return (_ctx, _cache) => {
58
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [
59
+ __props.label ? (openBlock(), createElementBlock("div", _hoisted_2$1, [createElementVNode("label", {
60
+ for: __props.htmlFor,
61
+ class: "mint-form-field__label"
62
+ }, [createTextVNode(toDisplayString(__props.label) + " ", 1), __props.required ? (openBlock(), createElementBlock("span", _hoisted_4$1, "*")) : createCommentVNode("", true)], 8, _hoisted_3$1), !__props.required && __props.showOptional ? (openBlock(), createElementBlock("span", _hoisted_5$1, " optional ")) : createCommentVNode("", true)])) : createCommentVNode("", true),
63
+ renderSlot(_ctx.$slots, "default", { describedBy: describedBy.value }),
64
+ __props.error ? (openBlock(), createElementBlock("p", {
65
+ key: 1,
66
+ id: errorId.value,
67
+ class: "mint-form-field__error",
68
+ role: "alert"
69
+ }, toDisplayString(__props.error), 9, _hoisted_6$1)) : __props.hint ? (openBlock(), createElementBlock("p", {
70
+ key: 2,
71
+ id: hintId.value,
72
+ class: "mint-form-field__hint"
73
+ }, toDisplayString(__props.hint), 9, _hoisted_7$1)) : createCommentVNode("", true)
74
+ ]);
75
+ };
76
+ }
77
+ });
78
+ //#endregion
79
+ //#region src/utils/formModelSync.ts
80
+ function recordValuesEqualForKeys(left, right, keys) {
81
+ for (const key of keys) if (!valuesEqual(left[key], right[key])) return false;
82
+ return true;
83
+ }
84
+ function pickRecordKeys(source, keys) {
85
+ return Object.fromEntries(keys.map((key) => [key, source[key]]));
86
+ }
87
+ function pickExistingRecordKeys(source, keys) {
88
+ return Object.fromEntries(keys.filter((key) => Object.prototype.hasOwnProperty.call(source, key)).map((key) => [key, source[key]]));
89
+ }
90
+ function formSchemaFieldNames(schema) {
91
+ return (schema.steps ? schema.steps.flatMap((step) => step.sections) : schema.sections).flatMap((section) => section.fields.map((field) => field.name));
92
+ }
93
+ function valuesEqual(left, right) {
94
+ if (Object.is(left, right)) return true;
95
+ if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((item, index) => valuesEqual(item, right[index]));
96
+ if (isRecord(left) && isRecord(right)) return recordValuesEqualForKeys(left, right, [...new Set([...Object.keys(left), ...Object.keys(right)])]);
97
+ return false;
98
+ }
99
+ function isRecord(value) {
100
+ return typeof value === "object" && value !== null && !Array.isArray(value);
101
+ }
102
+ //#endregion
103
+ //#region src/components/internal/FormFieldRendererInternal.vue
104
+ var FormFieldRendererInternal_default = /* @__PURE__ */ defineComponent({
105
+ __name: "FormFieldRendererInternal",
106
+ props: {
107
+ field: {},
108
+ resolvedProps: {},
109
+ form: {}
110
+ },
111
+ setup(__props) {
112
+ const props = __props;
113
+ const entry = computed(() => getFieldRegistryEntry(props.field.type));
114
+ const isChoiceField = computed(() => props.field.type === "checkbox" || props.field.type === "toggle");
115
+ const componentProps = computed(() => {
116
+ if (!isChoiceField.value) return props.resolvedProps;
117
+ return {
118
+ variant: "row",
119
+ label: props.field.label,
120
+ description: props.field.hint,
121
+ icon: props.field.icon,
122
+ iconColor: props.field.iconColor,
123
+ iconBg: props.field.iconBg,
124
+ ...props.resolvedProps
125
+ };
126
+ });
127
+ const errorMessage = computed(() => {
128
+ const name = props.field.name;
129
+ return props.form.touched[name] ? props.form.errors[name] : null;
130
+ });
131
+ function handleUpload(files) {
132
+ props.form.setFieldValue(props.field.name, files);
133
+ }
134
+ return (_ctx, _cache) => {
135
+ return openBlock(), createBlock(FormField_default, {
136
+ label: isChoiceField.value ? void 0 : __props.field.label,
137
+ error: errorMessage.value ?? void 0,
138
+ hint: isChoiceField.value ? void 0 : __props.field.hint,
139
+ required: !!__props.field.validation?.required,
140
+ "html-for": isChoiceField.value ? void 0 : __props.field.name
141
+ }, {
142
+ default: withCtx(() => [renderSlot(_ctx.$slots, `field:${__props.field.name}`, {
143
+ field: __props.field,
144
+ form: __props.form,
145
+ fieldProps: __props.form.getFieldProps(__props.field.name)
146
+ }, () => [entry.value.vModel ? (openBlock(), createBlock(resolveDynamicComponent(entry.value.component), normalizeProps(mergeProps({ key: 0 }, componentProps.value)), null, 16)) : (openBlock(), createBlock(resolveDynamicComponent(entry.value.component), mergeProps({ key: 1 }, componentProps.value, { onUpload: handleUpload }), null, 16))])]),
147
+ _: 3
148
+ }, 8, [
149
+ "label",
150
+ "error",
151
+ "hint",
152
+ "required",
153
+ "html-for"
154
+ ]);
155
+ };
156
+ }
157
+ });
158
+ //#endregion
159
+ //#region src/components/SettingsModal.schema.ts
160
+ var APPEARANCE_TAB_ID = "appearance";
161
+ var APPEARANCE_TAB = {
162
+ id: APPEARANCE_TAB_ID,
163
+ label: "Appearance",
164
+ description: "Theme, color palette, and table density"
165
+ };
166
+ function buildFlatSettingsSchema(schema) {
167
+ return { sections: schema.groups.map((group) => ({
168
+ id: group.id,
169
+ title: "",
170
+ fields: group.fields,
171
+ columns: group.columns,
172
+ condition: group.condition
173
+ })) };
174
+ }
175
+ function filterSettingsSchemaByAccess(schema, canShow) {
176
+ return { groups: schema.groups.flatMap((group) => {
177
+ if (!canShow(group)) return [];
178
+ const fields = group.fields.filter(canShow);
179
+ if (fields.length === 0) return [];
180
+ return [{
181
+ ...group,
182
+ fields
183
+ }];
184
+ }) };
185
+ }
186
+ function settingsGroupToTab(group) {
187
+ return {
188
+ id: group.id,
189
+ label: group.label,
190
+ icon: group.icon,
191
+ description: group.description
192
+ };
193
+ }
194
+ function normalizeVisibleSettingsTabs(tabs, canShow) {
195
+ return tabs.map(normalizeItemInput).filter(canShow);
196
+ }
197
+ function buildSettingsTabs(baseTabs, showAppearance) {
198
+ return showAppearance ? [...baseTabs, APPEARANCE_TAB] : baseTabs;
199
+ }
200
+ //#endregion
201
+ //#region src/components/SettingsModal.vue?vue&type=script&setup=true&lang.ts
202
+ var _hoisted_1 = {
203
+ key: 0,
204
+ class: "mint-settings-modal__tabs"
205
+ };
206
+ var _hoisted_2 = ["onClick"];
207
+ var _hoisted_3 = {
208
+ key: 1,
209
+ class: "mint-settings-modal__rail",
210
+ role: "tablist",
211
+ "aria-orientation": "vertical",
212
+ "aria-label": "Settings sections"
213
+ };
214
+ var _hoisted_4 = [
215
+ "id",
216
+ "aria-selected",
217
+ "aria-controls",
218
+ "tabindex",
219
+ "onClick"
220
+ ];
221
+ var _hoisted_5 = {
222
+ class: "mint-settings-modal__rail-item-icon",
223
+ "aria-hidden": "true"
224
+ };
225
+ var _hoisted_6 = ["innerHTML"];
226
+ var _hoisted_7 = { class: "mint-settings-modal__rail-item-text" };
227
+ var _hoisted_8 = { class: "mint-settings-modal__rail-item-label" };
228
+ var _hoisted_9 = {
229
+ key: 0,
230
+ class: "mint-settings-modal__rail-item-description"
231
+ };
232
+ var _hoisted_10 = {
233
+ key: 0,
234
+ class: "mint-settings-modal__pane-header"
235
+ };
236
+ var _hoisted_11 = { class: "mint-settings-modal__pane-title" };
237
+ var _hoisted_12 = {
238
+ key: 0,
239
+ class: "mint-settings-modal__pane-subtitle"
240
+ };
241
+ var _hoisted_13 = { key: 2 };
242
+ var _hoisted_14 = { class: "mint-settings-modal__section" };
243
+ var _hoisted_15 = { class: "mint-settings-modal__option-group" };
244
+ var _hoisted_16 = ["onClick"];
245
+ var _hoisted_17 = { class: "mint-settings-modal__section" };
246
+ var _hoisted_18 = { class: "mint-settings-modal__option-group" };
247
+ var _hoisted_19 = ["onClick"];
248
+ var _hoisted_20 = { class: "mint-settings-modal__section" };
249
+ var _hoisted_21 = { class: "mint-settings-modal__option-group" };
250
+ var _hoisted_22 = ["onClick"];
251
+ var _hoisted_23 = {
252
+ key: 0,
253
+ class: "mint-settings-modal__footer"
254
+ };
255
+ //#endregion
256
+ //#region src/components/SettingsModal.vue
257
+ var SettingsModal_default = /* @__PURE__ */ defineComponent({
258
+ __name: "SettingsModal",
259
+ props: {
260
+ modelValue: { type: Boolean },
261
+ title: { default: "Settings" },
262
+ tabs: { default: () => [] },
263
+ showAppearance: {
264
+ type: Boolean,
265
+ default: true
266
+ },
267
+ size: { default: "lg" },
268
+ layout: { default: "horizontal" },
269
+ schema: {},
270
+ model: { default: void 0 },
271
+ controls: {},
272
+ controlOptions: {},
273
+ values: {},
274
+ enhancements: {},
275
+ userType: {}
276
+ },
277
+ emits: [
278
+ "update:modelValue",
279
+ "update:values",
280
+ "close"
281
+ ],
282
+ setup(__props, { emit: __emit }) {
283
+ /**
284
+ * Tabbed settings modal with three usage modes:
285
+ *
286
+ * 1. Schema-driven (recommended) — pass `schema`, compact `controls`, or a
287
+ * complete `defineControlModel()` result plus `v-model:values`. Each
288
+ * group/section becomes a tab; fields auto-render via the SDK form field
289
+ * registry (text, select, number, toggle, molecule, concentration, …).
290
+ * Conditional visibility, validation, and dynamic options come for free.
291
+ *
292
+ * 2. Manual tabs + slots — pass `tabs` and a `<template #tab-{id}>` slot
293
+ * per tab. Use this when you need bespoke widgets the form-builder
294
+ * registry doesn't cover (or for legacy plugins).
295
+ *
296
+ * 3. Appearance only — `showAppearance` (default true) renders the built-in
297
+ * theme / palette / table-density tab. Works alongside both modes above.
298
+ *
299
+ * Layout: `horizontal` (underline tabs, default) or `vertical` (sidebar rail
300
+ * with optional icons + descriptions, recommended for 5+ groups).
301
+ */
302
+ const props = __props;
303
+ const emit = __emit;
304
+ const settings = useSettingsStore();
305
+ const auth = useAuthStore();
306
+ const { user: platformUser } = usePlatformContext();
307
+ const isVertical = computed(() => props.layout === "vertical");
308
+ const uid = `mint-settings-${Math.random().toString(36).slice(2, 9)}`;
309
+ const tabId = (id) => `${uid}-tab-${id}`;
310
+ const panelId = (id) => `${uid}-panel-${id}`;
311
+ const resolvedModel = computed(() => {
312
+ return resolveControlModel(props.model);
313
+ });
314
+ const resolvedControls = computed(() => props.controls ?? resolvedModel.value?.controls);
315
+ const resolvedControlOptions = computed(() => mergeControlWorkspaceOptions(resolvedModel.value?.controlOptions ?? {}, props.controlOptions));
316
+ const sourceSettingsSchema = computed(() => props.schema ?? (resolvedControls.value ? controlsToSettingsSchema(resolvedControls.value, resolvedControlOptions.value) : void 0));
317
+ const currentAccessUser = computed(() => {
318
+ if (props.userType) return { role: props.userType === "admin" ? "admin" : "user" };
319
+ return auth.userInfo ?? platformUser.value ?? null;
320
+ });
321
+ const isAccessUserAuthenticated = computed(() => props.userType !== void 0 || auth.isAuthenticated || !!platformUser.value);
322
+ const settingsSchema = computed(() => {
323
+ if (!sourceSettingsSchema.value) return void 0;
324
+ return filterSettingsSchemaByAccess(sourceSettingsSchema.value, canShowForCurrentUser);
325
+ });
326
+ const isSchemaDriven = computed(() => !!settingsSchema.value);
327
+ const resolvedValues = computed(() => ({
328
+ ...resolvedControlOptions.value.initialValues ?? {},
329
+ ...props.values ?? {}
330
+ }));
331
+ const builder = useFormBuilder(settingsSchema.value ? buildFlatSettingsSchema(settingsSchema.value) : { sections: [] }, resolvedValues.value, props.enhancements);
332
+ watch(() => settingsSchema.value, (schema) => {
333
+ if (!schema) {
334
+ builder.updateSchema({ sections: [] }, {});
335
+ return;
336
+ }
337
+ const flatSchema = buildFlatSettingsSchema(schema);
338
+ const fieldNames = formSchemaFieldNames(flatSchema);
339
+ const sourceValues = props.values === void 0 ? {
340
+ ...resolvedValues.value,
341
+ ...builder.form.data
342
+ } : resolvedValues.value;
343
+ builder.updateSchema(flatSchema, pickExistingRecordKeys(sourceValues ?? {}, fieldNames));
344
+ }, { deep: true });
345
+ watch(() => ({ ...resolvedValues.value }), (data) => {
346
+ if (!settingsSchema.value) return;
347
+ const fieldNames = builderFieldNames();
348
+ if (recordValuesEqualForKeys(data, builder.form.data, fieldNames)) return;
349
+ builder.reset(pickRecordKeys(data, fieldNames));
350
+ }, { deep: true });
351
+ watch(() => ({ ...builder.form.data }), (data) => {
352
+ if (settingsSchema.value) emit("update:values", data);
353
+ }, { deep: true });
354
+ const visibleSchemaGroups = computed(() => settingsSchema.value ? settingsSchema.value.groups.filter((g) => builder.isSectionVisible(g.id)) : []);
355
+ const manualTabs = computed(() => normalizeVisibleSettingsTabs(props.tabs, canShowForCurrentUser));
356
+ const allTabs = computed(() => {
357
+ return buildSettingsTabs(settingsSchema.value ? visibleSchemaGroups.value.map(settingsGroupToTab) : manualTabs.value, props.showAppearance);
358
+ });
359
+ const activeTab = ref(allTabs.value[0]?.id || "appearance");
360
+ const activeTabMeta = computed(() => allTabs.value.find((t) => t.id === activeTab.value));
361
+ watch(allTabs, (tabs) => {
362
+ if (!tabs.some((t) => t.id === activeTab.value)) activeTab.value = tabs[0]?.id ?? "appearance";
363
+ });
364
+ const activeGroup = computed(() => visibleSchemaGroups.value.find((g) => g.id === activeTab.value));
365
+ const activeGroupVisibleFields = computed(() => {
366
+ if (!activeGroup.value) return [];
367
+ return activeGroup.value.fields.filter((f) => builder.isFieldVisible(f.name));
368
+ });
369
+ const themeOptions = [
370
+ {
371
+ value: "light",
372
+ label: "Light"
373
+ },
374
+ {
375
+ value: "dark",
376
+ label: "Dark"
377
+ },
378
+ {
379
+ value: "system",
380
+ label: "System"
381
+ }
382
+ ];
383
+ const densityOptions = [
384
+ {
385
+ value: "compact",
386
+ label: "Compact"
387
+ },
388
+ {
389
+ value: "normal",
390
+ label: "Normal"
391
+ },
392
+ {
393
+ value: "comfortable",
394
+ label: "Comfortable"
395
+ }
396
+ ];
397
+ function handleClose() {
398
+ emit("update:modelValue", false);
399
+ emit("close");
400
+ }
401
+ function builderFieldNames() {
402
+ return builder.fields.map((field) => field.name);
403
+ }
404
+ function canShowForCurrentUser(item) {
405
+ return canAccessByPolicy(currentAccessUser.value, item, isAccessUserAuthenticated.value);
406
+ }
407
+ return (_ctx, _cache) => {
408
+ return openBlock(), createBlock(BaseModal_default, {
409
+ "model-value": __props.modelValue,
410
+ title: __props.title,
411
+ size: __props.size,
412
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event)),
413
+ onClose: handleClose
414
+ }, {
415
+ default: withCtx(() => [createElementVNode("div", { class: normalizeClass(["mint-settings-modal", `mint-settings-modal--${__props.layout}`]) }, [!isVertical.value && allTabs.value.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(allTabs.value, (tab) => {
416
+ return openBlock(), createElementBlock("button", {
417
+ key: tab.id,
418
+ type: "button",
419
+ class: normalizeClass(["mint-settings-modal__tab", { "mint-settings-modal__tab--active": activeTab.value === tab.id }]),
420
+ onClick: ($event) => activeTab.value = tab.id
421
+ }, toDisplayString(tab.label), 11, _hoisted_2);
422
+ }), 128))])) : isVertical.value ? (openBlock(), createElementBlock("div", _hoisted_3, [(openBlock(true), createElementBlock(Fragment, null, renderList(allTabs.value, (tab) => {
423
+ return openBlock(), createElementBlock("button", {
424
+ id: tabId(tab.id),
425
+ key: tab.id,
426
+ type: "button",
427
+ role: "tab",
428
+ class: normalizeClass(["mint-settings-modal__rail-item", { "mint-settings-modal__rail-item--active": activeTab.value === tab.id }]),
429
+ "aria-selected": activeTab.value === tab.id,
430
+ "aria-controls": panelId(tab.id),
431
+ tabindex: activeTab.value === tab.id ? 0 : -1,
432
+ onClick: ($event) => activeTab.value = tab.id
433
+ }, [createElementVNode("span", _hoisted_5, [tab.icon ? (openBlock(), createElementBlock("span", {
434
+ key: 0,
435
+ innerHTML: tab.icon
436
+ }, null, 8, _hoisted_6)) : createCommentVNode("", true)]), createElementVNode("span", _hoisted_7, [createElementVNode("span", _hoisted_8, toDisplayString(tab.label), 1), tab.description ? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(tab.description), 1)) : createCommentVNode("", true)])], 10, _hoisted_4);
437
+ }), 128))])) : createCommentVNode("", true), (openBlock(), createBlock(resolveDynamicComponent(isVertical.value ? "section" : "div"), {
438
+ class: normalizeClass(isVertical.value ? "mint-settings-modal__pane" : "mint-settings-modal__content"),
439
+ id: isVertical.value && activeTabMeta.value ? panelId(activeTabMeta.value.id) : void 0,
440
+ role: isVertical.value ? "tabpanel" : void 0,
441
+ "aria-labelledby": isVertical.value && activeTabMeta.value ? tabId(activeTabMeta.value.id) : void 0,
442
+ tabindex: isVertical.value ? 0 : void 0
443
+ }, {
444
+ default: withCtx(() => [isVertical.value && activeTabMeta.value?.label ? (openBlock(), createElementBlock("header", _hoisted_10, [createElementVNode("h4", _hoisted_11, toDisplayString(activeTabMeta.value.label), 1), activeTabMeta.value.description ? (openBlock(), createElementBlock("p", _hoisted_12, toDisplayString(activeTabMeta.value.description), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("div", { class: normalizeClass(isVertical.value ? "mint-settings-modal__pane-body" : null) }, [isSchemaDriven.value && activeGroup.value ? (openBlock(), createElementBlock("div", {
445
+ key: 0,
446
+ class: "mint-settings-modal__group-grid",
447
+ style: normalizeStyle({ "--mint-settings-cols": activeGroup.value.columns ?? 1 })
448
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(activeGroupVisibleFields.value, (field) => {
449
+ return openBlock(), createElementBlock("div", {
450
+ key: field.name,
451
+ style: normalizeStyle(field.colSpan ? { gridColumn: `span ${field.colSpan}` } : void 0)
452
+ }, [renderSlot(_ctx.$slots, `field:${field.name}`, {
453
+ field,
454
+ form: unref(builder).form,
455
+ fieldProps: unref(builder).form.getFieldProps(field.name)
456
+ }, () => [createVNode(FormFieldRendererInternal_default, {
457
+ field,
458
+ "resolved-props": unref(builder).getResolvedFieldProps(field),
459
+ form: unref(builder).form
460
+ }, null, 8, [
461
+ "field",
462
+ "resolved-props",
463
+ "form"
464
+ ])])], 4);
465
+ }), 128))], 4)) : !isSchemaDriven.value ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(manualTabs.value, (tab) => {
466
+ return withDirectives((openBlock(), createElementBlock("div", { key: tab.id }, [renderSlot(_ctx.$slots, `tab-${tab.id}`)], 512)), [[vShow, activeTab.value === tab.id]]);
467
+ }), 128)) : createCommentVNode("", true), __props.showAppearance ? withDirectives((openBlock(), createElementBlock("div", _hoisted_13, [
468
+ createElementVNode("div", _hoisted_14, [_cache[1] || (_cache[1] = createElementVNode("div", { class: "mint-settings-modal__section-label" }, "Theme", -1)), createElementVNode("div", _hoisted_15, [(openBlock(), createElementBlock(Fragment, null, renderList(themeOptions, (opt) => {
469
+ return createElementVNode("button", {
470
+ key: opt.value,
471
+ type: "button",
472
+ class: normalizeClass(["mint-settings-modal__option-btn", { "mint-settings-modal__option-btn--active": unref(settings).theme === opt.value }]),
473
+ onClick: ($event) => unref(settings).theme = opt.value
474
+ }, toDisplayString(opt.label), 11, _hoisted_16);
475
+ }), 64))])]),
476
+ createElementVNode("div", _hoisted_17, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-settings-modal__section-label" }, "Color Palette", -1)), createElementVNode("div", _hoisted_18, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(colorPalettes), (palette, key) => {
477
+ return openBlock(), createElementBlock("button", {
478
+ key,
479
+ type: "button",
480
+ class: normalizeClass(["mint-settings-modal__option-btn", { "mint-settings-modal__option-btn--active": unref(settings).colorPalette === key }]),
481
+ onClick: ($event) => unref(settings).colorPalette = key
482
+ }, toDisplayString(palette.name), 11, _hoisted_19);
483
+ }), 128))])]),
484
+ createElementVNode("div", _hoisted_20, [
485
+ _cache[3] || (_cache[3] = createElementVNode("div", { class: "mint-settings-modal__section-label" }, "Table Density", -1)),
486
+ createElementVNode("div", _hoisted_21, [(openBlock(), createElementBlock(Fragment, null, renderList(densityOptions, (opt) => {
487
+ return createElementVNode("button", {
488
+ key: opt.value,
489
+ type: "button",
490
+ class: normalizeClass(["mint-settings-modal__option-btn", { "mint-settings-modal__option-btn--active": unref(settings).tableDensity === opt.value }]),
491
+ onClick: ($event) => unref(settings).tableDensity = opt.value
492
+ }, toDisplayString(opt.label), 11, _hoisted_22);
493
+ }), 64))]),
494
+ _cache[4] || (_cache[4] = createElementVNode("p", { class: "mint-settings-modal__note" }, "Adjusts row height in data tables.", -1))
495
+ ]),
496
+ renderSlot(_ctx.$slots, "appearance")
497
+ ], 512)), [[vShow, activeTab.value === unref(APPEARANCE_TAB_ID)]]) : createCommentVNode("", true)], 2)]),
498
+ _: 3
499
+ }, 8, [
500
+ "class",
501
+ "id",
502
+ "role",
503
+ "aria-labelledby",
504
+ "tabindex"
505
+ ]))], 2), _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_23, [renderSlot(_ctx.$slots, "footer", {
506
+ values: unref(builder).form.data,
507
+ close: handleClose
508
+ })])) : createCommentVNode("", true)]),
509
+ _: 3
510
+ }, 8, [
511
+ "model-value",
512
+ "title",
513
+ "size"
514
+ ]);
515
+ };
516
+ }
517
+ });
518
+ //#endregion
519
+ export { recordValuesEqualForKeys as a, normalizeLabelItemInput as c, pickExistingRecordKeys as i, FormFieldRendererInternal_default as n, FormField_default as o, formSchemaFieldNames as r, normalizeItemInput as s, SettingsModal_default as t };
520
+
521
+ //# sourceMappingURL=SettingsModal-LEKI6Ebl.js.map