@morscherlab/mint-sdk 1.4.13 → 1.5.0-beta.10

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 (132) hide show
  1. package/dist/{AlertBox-CexONPhA.js → AlertBox-Cai0w7gF.js} +3 -3
  2. package/dist/{AlertBox-CexONPhA.js.map → AlertBox-Cai0w7gF.js.map} +1 -1
  3. package/dist/{AppSidebar-CIBehlYL.js → AppSidebar-C-Vq5x4I.js} +354 -93
  4. package/dist/AppSidebar-C-Vq5x4I.js.map +1 -0
  5. package/dist/{ConfirmDialog-CjWoxAD1.js → ConfirmDialog-BjFsOpBe.js} +3 -3
  6. package/dist/ConfirmDialog-BjFsOpBe.js.map +1 -0
  7. package/dist/{ExperimentPopover-CzV1--OY.js → ExperimentPopover-DYy_s0kI.js} +25 -37
  8. package/dist/ExperimentPopover-DYy_s0kI.js.map +1 -0
  9. package/dist/{ExperimentSelectorModal-CUkKmgfr.js → ExperimentSelectorModal-Bfh5bdkv.js} +5 -5
  10. package/dist/{ExperimentSelectorModal-CUkKmgfr.js.map → ExperimentSelectorModal-Bfh5bdkv.js.map} +1 -1
  11. package/dist/{SegmentedControl-C-sckoJZ.js → SegmentedControl-B8KgyOjd.js} +2 -2
  12. package/dist/{SegmentedControl-C-sckoJZ.js.map → SegmentedControl-B8KgyOjd.js.map} +1 -1
  13. package/dist/{SettingsModal-jW7Z4i_1.js → SettingsModal-DwfrD1ER.js} +7 -7
  14. package/dist/{SettingsModal-jW7Z4i_1.js.map → SettingsModal-DwfrD1ER.js.map} +1 -1
  15. package/dist/__tests__/components/AppTopBarCompact.test.d.ts +1 -0
  16. package/dist/__tests__/components/AppTopBarCompactReset.test.d.ts +1 -0
  17. package/dist/__tests__/components/AutoGroupModal.experimentLoad.test.d.ts +1 -0
  18. package/dist/components/AppTopBar.compact.d.ts +5 -0
  19. package/dist/components/AppTopBar.vue.d.ts +17 -17
  20. package/dist/components/FormBuilder.vue.d.ts +1 -1
  21. package/dist/components/PluginIcon.vue.d.ts +2 -2
  22. package/dist/components/PluginWorkspaceView.vue.d.ts +4 -0
  23. package/dist/components/SettingsModal.vue.d.ts +1 -1
  24. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -2
  25. package/dist/components/internal/FormSchemaInternal.vue.d.ts +9 -9
  26. package/dist/components/internal/FormSectionRenderer.vue.d.ts +4 -4
  27. package/dist/components/internal/LucideIconInternal.vue.d.ts +17 -0
  28. package/dist/composables/appLayoutSidebar.d.ts +9 -0
  29. package/dist/composables/useVersionedSave.d.ts +5 -2
  30. package/dist/{controlSchemaModel-C_XqpkgE.js → controlSchemaModel-BtFNZj8t.js} +2 -2
  31. package/dist/{controlSchemaModel-C_XqpkgE.js.map → controlSchemaModel-BtFNZj8t.js.map} +1 -1
  32. package/dist/{data-8G-U6Pb0.js → data-CJztFns8.js} +31 -15
  33. package/dist/{data-8G-U6Pb0.js.map → data-CJztFns8.js.map} +1 -1
  34. package/dist/data.js +8 -8
  35. package/dist/{experimentStatus-DCn2QKG7.js → experimentStatus-Deokk7Br.js} +2 -2
  36. package/dist/{experimentStatus-DCn2QKG7.js.map → experimentStatus-Deokk7Br.js.map} +1 -1
  37. package/dist/index.d.ts +0 -1
  38. package/dist/index.js +15 -20
  39. package/dist/index.js.map +1 -1
  40. package/dist/{install-CM33AZhf.js → install-Bk02tJ5M.js} +14 -15
  41. package/dist/{install-CM33AZhf.js.map → install-Bk02tJ5M.js.map} +1 -1
  42. package/dist/install.js +1 -1
  43. package/dist/{lab-CPJ7n7e5.js → lab-BYhb_cJI.js} +22 -14
  44. package/dist/lab-BYhb_cJI.js.map +1 -0
  45. package/dist/lab.js +4 -4
  46. package/dist/{records-BAymyHAn.js → records-GtiVMlTQ.js} +198 -62
  47. package/dist/records-GtiVMlTQ.js.map +1 -0
  48. package/dist/{runtime-PntKXQ7K.js → runtime-aZPUPxoB.js} +29 -12
  49. package/dist/runtime-aZPUPxoB.js.map +1 -0
  50. package/dist/runtime.js +6 -6
  51. package/dist/{shell-B-woqThX.js → shell-Bk9mD4Lc.js} +5 -5
  52. package/dist/{shell-B-woqThX.js.map → shell-Bk9mD4Lc.js.map} +1 -1
  53. package/dist/shell.js +5 -5
  54. package/dist/styles.css +139 -15
  55. package/dist/types/components.d.ts +22 -2
  56. package/dist/types/generated-ui.d.ts +2 -0
  57. package/dist/types/index.d.ts +2 -2
  58. package/dist/types/instrument.d.ts +0 -17
  59. package/dist/{useDropdownState-uFIz6Yv8.js → useDropdownState-CcBzUYZ6.js} +14 -5
  60. package/dist/useDropdownState-CcBzUYZ6.js.map +1 -0
  61. package/dist/{useExperimentSamples-DEDAKa2E.js → useExperimentSamples-CpNXvpUn.js} +3 -3
  62. package/dist/{useExperimentSamples-DEDAKa2E.js.map → useExperimentSamples-CpNXvpUn.js.map} +1 -1
  63. package/dist/{useListReorder-W1bzK_bo.js → useListReorder-Bp4EAI2w.js} +3 -3
  64. package/dist/{useListReorder-W1bzK_bo.js.map → useListReorder-Bp4EAI2w.js.map} +1 -1
  65. package/dist/{useRackEditor-BWOnob3i.js → useRackEditor-i2bdPUFf.js} +8 -8
  66. package/dist/{useRackEditor-BWOnob3i.js.map → useRackEditor-i2bdPUFf.js.map} +1 -1
  67. package/dist/{useRealtime-B0u_FvEH.js → useRealtime-BLQEjbuq.js} +3 -3
  68. package/dist/{useRealtime-B0u_FvEH.js.map → useRealtime-BLQEjbuq.js.map} +1 -1
  69. package/dist/useRequest-CXyPw3eh.js +76 -0
  70. package/dist/useRequest-CXyPw3eh.js.map +1 -0
  71. package/dist/utils/deprecation.d.ts +2 -0
  72. package/dist/utils/lucideIcon.d.ts +4 -0
  73. package/package.json +1 -1
  74. package/src/__tests__/components/AppTopBar.test.ts +102 -20
  75. package/src/__tests__/components/AppTopBarCompact.test.ts +65 -0
  76. package/src/__tests__/components/AppTopBarCompactReset.test.ts +24 -0
  77. package/src/__tests__/components/AutoGroupModal.experimentLoad.test.ts +58 -0
  78. package/src/__tests__/components/BaseModal.test.ts +33 -2
  79. package/src/__tests__/components/ConfirmDialog.test.ts +2 -2
  80. package/src/__tests__/components/ExperimentPopover.test.ts +32 -0
  81. package/src/__tests__/components/PluginWorkspaceView.test.ts +1 -1
  82. package/src/__tests__/components/deprecationTags.test.ts +4 -18
  83. package/src/__tests__/composables/useJobCenter.test.ts +35 -0
  84. package/src/__tests__/composables/useVersionedSave.test.ts +71 -6
  85. package/src/__tests__/docs/frontendDocsCatalog.test.ts +3 -3
  86. package/src/__tests__/styles/menusShellRefresh.test.ts +5 -0
  87. package/src/components/AppLayout.story.vue +5 -5
  88. package/src/components/AppLayout.vue +13 -1
  89. package/src/components/AppSidebar.vue +2 -2
  90. package/src/components/AppTopBar.compact.ts +60 -0
  91. package/src/components/AppTopBar.story.vue +39 -14
  92. package/src/components/AppTopBar.vue +222 -89
  93. package/src/components/BaseModal.vue +16 -5
  94. package/src/components/CollapsibleCard.vue +1 -1
  95. package/src/components/ConfirmDialog.vue +1 -1
  96. package/src/components/ExperimentPopover.story.vue +2 -2
  97. package/src/components/ExperimentPopover.vue +6 -22
  98. package/src/components/GeneratedPluginView.vue +0 -1
  99. package/src/components/PluginIcon.story.vue +2 -2
  100. package/src/components/PluginIcon.vue +2 -2
  101. package/src/components/PluginWorkspaceView.vue +8 -0
  102. package/src/components/internal/AppTopBarPageSelectorInternal.vue +12 -0
  103. package/src/components/internal/AutoGroupModalInternal.vue +14 -3
  104. package/src/components/internal/LucideIconInternal.vue +23 -0
  105. package/src/composables/appLayoutSidebar.ts +11 -0
  106. package/src/composables/index.ts +1 -2
  107. package/src/composables/useJobCenter.ts +21 -1
  108. package/src/composables/usePluginWorkspace.ts +1 -1
  109. package/src/composables/useVersionedSave.ts +32 -7
  110. package/src/index.ts +0 -3
  111. package/src/styles/components/app-layout.css +5 -0
  112. package/src/styles/components/app-top-bar.css +128 -8
  113. package/src/styles/components/plugin-icon.css +1 -1
  114. package/src/styles/variables.css +2 -2
  115. package/src/types/components.ts +23 -2
  116. package/src/types/generated-ui.ts +2 -0
  117. package/src/types/index.ts +1 -1
  118. package/src/types/instrument.ts +0 -18
  119. package/src/utils/deprecation.ts +8 -0
  120. package/src/utils/lucideIcon.ts +25 -0
  121. package/src/utils/lucideIconIndex.d.ts +2 -0
  122. package/dist/AppSidebar-CIBehlYL.js.map +0 -1
  123. package/dist/ConfirmDialog-CjWoxAD1.js.map +0 -1
  124. package/dist/ExperimentPopover-CzV1--OY.js.map +0 -1
  125. package/dist/deprecatedRootExports.d.ts +0 -191
  126. package/dist/lab-CPJ7n7e5.js.map +0 -1
  127. package/dist/records-BAymyHAn.js.map +0 -1
  128. package/dist/runtime-PntKXQ7K.js.map +0 -1
  129. package/dist/useDropdownState-uFIz6Yv8.js.map +0 -1
  130. package/dist/useRequest-D9-3BS-3.js +0 -215
  131. package/dist/useRequest-D9-3BS-3.js.map +0 -1
  132. package/src/deprecatedRootExports.ts +0 -226
@@ -1,7 +1,7 @@
1
- import { i as useEventListener, o as __exportAll, r as useFocusTrap } from "./useDropdownState-uFIz6Yv8.js";
2
- import { E as useMenuKeyboard, H as useListSelection, R as useRovingFocus, U as useSelectionLimit } from "./records-BAymyHAn.js";
3
- import { B as compareSortValues, V as useSortedItems, i as useReorderAnnouncer, n as reorderList, r as useListReorder, t as REORDER_ANNOUNCER_STYLE } from "./useListReorder-W1bzK_bo.js";
4
- import { C as usePluginWorkspace, S as AppLayout_default, _ as provideOnboarding, f as AppTopBar_default, g as defineOnboarding, h as ONBOARDING_KEY, m as ANCHOR_WAIT_MS, t as AppSidebar_default, v as useOnboarding } from "./AppSidebar-CIBehlYL.js";
1
+ import { i as useEventListener, o as __exportAll, r as useFocusTrap } from "./useDropdownState-CcBzUYZ6.js";
2
+ import { D as useMenuKeyboard, U as useListSelection, W as useSelectionLimit, z as useRovingFocus } from "./records-GtiVMlTQ.js";
3
+ import { B as compareSortValues, V as useSortedItems, i as useReorderAnnouncer, n as reorderList, r as useListReorder, t as REORDER_ANNOUNCER_STYLE } from "./useListReorder-Bp4EAI2w.js";
4
+ import { S as AppLayout_default, _ as provideOnboarding, f as AppTopBar_default, g as defineOnboarding, h as ONBOARDING_KEY, m as ANCHOR_WAIT_MS, t as AppSidebar_default, v as useOnboarding, w as usePluginWorkspace } from "./AppSidebar-C-Vq5x4I.js";
5
5
  import { t as useDebouncedWatch } from "./useDebouncedWatch-BPwyl6eS.js";
6
6
  import { t as useExpansionSet } from "./useExpansionSet-CvoNMZJi.js";
7
7
  import { computed, createElementBlock, createElementVNode, defineComponent, normalizeClass, onBeforeUnmount, openBlock, shallowRef, toValue, watch } from "vue";
@@ -199,4 +199,4 @@ var shell_exports = /* @__PURE__ */ __exportAll({
199
199
  //#endregion
200
200
  export { useManualLayoutResize as a, resizedVerticalSplitPercent as i, resizedLeadingPanelWidth as n, LayoutResizeHandle_default as o, resizedTrailingPanelWidth as r, shell_exports as t };
201
201
 
202
- //# sourceMappingURL=shell-B-woqThX.js.map
202
+ //# sourceMappingURL=shell-Bk9mD4Lc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shell-B-woqThX.js","names":[],"sources":["../src/components/LayoutResizeHandle.vue","../src/components/LayoutResizeHandle.vue","../src/composables/useManualLayoutResize.ts","../src/shell.ts"],"sourcesContent":["<script setup lang=\"ts\">\n/** Accessible pointer and keyboard handle for resizable workbench panes. */\ninterface Props {\n modelValue: number\n min: number\n max: number\n label: string\n orientation: 'vertical' | 'horizontal'\n edge?: 'left' | 'right'\n step?: number\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n edge: undefined,\n step: 10,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number]\n 'resize-start': [event: PointerEvent]\n}>()\n\nfunction update(value: number): void {\n emit('update:modelValue', Math.min(props.max, Math.max(props.min, value)))\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (props.disabled) return\n const decrement = props.orientation === 'vertical' ? 'ArrowLeft' : 'ArrowUp'\n const increment = props.orientation === 'vertical' ? 'ArrowRight' : 'ArrowDown'\n if (event.key === decrement) update(props.modelValue - props.step)\n else if (event.key === increment) update(props.modelValue + props.step)\n else if (event.key === 'Home') update(props.min)\n else if (event.key === 'End') update(props.max)\n else return\n event.preventDefault()\n}\n</script>\n\n<template>\n <div\n role=\"separator\"\n :tabindex=\"disabled ? -1 : 0\"\n :class=\"[\n 'mint-layout-resize-handle',\n `mint-layout-resize-handle--${orientation}`,\n edge ? `mint-layout-resize-handle--edge-${edge}` : '',\n ]\"\n :aria-label=\"label\"\n :aria-orientation=\"orientation\"\n :aria-valuemin=\"min\"\n :aria-valuemax=\"max\"\n :aria-valuenow=\"modelValue\"\n :aria-disabled=\"disabled || undefined\"\n @pointerdown=\"!disabled && emit('resize-start', $event)\"\n @keydown=\"handleKeydown\"\n >\n <span class=\"mint-layout-resize-handle__bar\" aria-hidden=\"true\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Accessible pointer and keyboard handle for resizable workbench panes. */\ninterface Props {\n modelValue: number\n min: number\n max: number\n label: string\n orientation: 'vertical' | 'horizontal'\n edge?: 'left' | 'right'\n step?: number\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n edge: undefined,\n step: 10,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number]\n 'resize-start': [event: PointerEvent]\n}>()\n\nfunction update(value: number): void {\n emit('update:modelValue', Math.min(props.max, Math.max(props.min, value)))\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (props.disabled) return\n const decrement = props.orientation === 'vertical' ? 'ArrowLeft' : 'ArrowUp'\n const increment = props.orientation === 'vertical' ? 'ArrowRight' : 'ArrowDown'\n if (event.key === decrement) update(props.modelValue - props.step)\n else if (event.key === increment) update(props.modelValue + props.step)\n else if (event.key === 'Home') update(props.min)\n else if (event.key === 'End') update(props.max)\n else return\n event.preventDefault()\n}\n</script>\n\n<template>\n <div\n role=\"separator\"\n :tabindex=\"disabled ? -1 : 0\"\n :class=\"[\n 'mint-layout-resize-handle',\n `mint-layout-resize-handle--${orientation}`,\n edge ? `mint-layout-resize-handle--edge-${edge}` : '',\n ]\"\n :aria-label=\"label\"\n :aria-orientation=\"orientation\"\n :aria-valuemin=\"min\"\n :aria-valuemax=\"max\"\n :aria-valuenow=\"modelValue\"\n :aria-disabled=\"disabled || undefined\"\n @pointerdown=\"!disabled && emit('resize-start', $event)\"\n @keydown=\"handleKeydown\"\n >\n <span class=\"mint-layout-resize-handle__bar\" aria-hidden=\"true\" />\n </div>\n</template>\n","import { computed, onBeforeUnmount, shallowRef, toValue, watch, type MaybeRefOrGetter } from 'vue'\n\nexport interface ResizePanelWidthConstraints {\n minWidth: number\n maxWidth: number\n mainMinWidth?: number\n layoutGap?: number\n}\n\nexport interface ResizePercentConstraints {\n minPercent: number\n maxPercent: number\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction availablePanelWidth(\n containerWidth: number,\n constraints: ResizePanelWidthConstraints,\n): number {\n return Math.min(\n constraints.maxWidth,\n containerWidth - (constraints.mainMinWidth ?? 0) - (constraints.layoutGap ?? 0),\n )\n}\n\nexport function resizedLeadingPanelWidth(\n startWidth: number,\n deltaX: number,\n containerWidth: number,\n constraints: ResizePanelWidthConstraints,\n): number {\n return Math.round(clamp(\n startWidth + deltaX,\n constraints.minWidth,\n Math.max(constraints.minWidth, availablePanelWidth(containerWidth, constraints)),\n ))\n}\n\nexport function resizedTrailingPanelWidth(\n startWidth: number,\n deltaX: number,\n containerWidth: number,\n constraints: ResizePanelWidthConstraints,\n): number {\n return resizedLeadingPanelWidth(startWidth, -deltaX, containerWidth, constraints)\n}\n\nexport function resizedVerticalSplitPercent(\n startPercent: number,\n deltaY: number,\n containerHeight: number,\n constraints: ResizePercentConstraints,\n): number {\n if (containerHeight <= 0) return startPercent\n return Math.round(clamp(\n startPercent + (deltaY / containerHeight) * 100,\n constraints.minPercent,\n constraints.maxPercent,\n ))\n}\n\nexport interface ManualLayoutResizeContext<TKind extends string> {\n kind: TKind\n startValue: number\n deltaX: number\n deltaY: number\n containerRect: DOMRectReadOnly\n secondaryRect: DOMRectReadOnly | null\n}\n\nexport interface ManualLayoutResizeTarget<TKind extends string> {\n cursor?: string\n getContainerElement: () => HTMLElement | null\n getSecondaryElement?: () => HTMLElement | null\n getStartValue: () => number\n onResize: (context: ManualLayoutResizeContext<TKind>) => void\n}\n\n/** Coordinates pointer-driven resizing for one or more layout splitters. */\nexport function useManualLayoutResize<TKind extends string>(options: {\n enabled: MaybeRefOrGetter<boolean>\n resolveTarget: (kind: TKind) => ManualLayoutResizeTarget<TKind> | null\n}) {\n const activeResize = shallowRef<{\n kind: TKind\n startClientX: number\n startClientY: number\n startValue: number\n containerRect: DOMRectReadOnly\n secondaryRect: DOMRectReadOnly | null\n cursor: string\n } | null>(null)\n const isResizing = computed(() => activeResize.value !== null)\n let previousBodyCursor = ''\n let previousBodyUserSelect = ''\n\n function stopResize(): void {\n if (!activeResize.value) return\n activeResize.value = null\n window.removeEventListener('pointermove', handlePointerMove)\n window.removeEventListener('pointerup', stopResize)\n window.removeEventListener('pointercancel', stopResize)\n if (typeof document !== 'undefined') {\n document.body.style.cursor = previousBodyCursor\n document.body.style.userSelect = previousBodyUserSelect\n }\n }\n\n function handlePointerMove(event: PointerEvent): void {\n const state = activeResize.value\n if (!state) return\n options.resolveTarget(state.kind)?.onResize({\n kind: state.kind,\n startValue: state.startValue,\n deltaX: event.clientX - state.startClientX,\n deltaY: event.clientY - state.startClientY,\n containerRect: state.containerRect,\n secondaryRect: state.secondaryRect,\n })\n }\n\n function startResize(kind: TKind, event: PointerEvent): void {\n if (!toValue(options.enabled) || event.button !== 0) return\n const target = options.resolveTarget(kind)\n const containerRect = target?.getContainerElement()?.getBoundingClientRect()\n if (!target || !containerRect) return\n\n event.preventDefault()\n if (event.currentTarget instanceof HTMLElement) {\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n const secondary = target.getSecondaryElement?.() ?? null\n activeResize.value = {\n kind,\n startClientX: event.clientX,\n startClientY: event.clientY,\n startValue: target.getStartValue(),\n containerRect,\n secondaryRect: secondary?.getBoundingClientRect() ?? null,\n cursor: target.cursor ?? 'col-resize',\n }\n\n if (typeof document !== 'undefined') {\n previousBodyCursor = document.body.style.cursor\n previousBodyUserSelect = document.body.style.userSelect\n document.body.style.cursor = activeResize.value.cursor\n document.body.style.userSelect = 'none'\n }\n window.addEventListener('pointermove', handlePointerMove)\n window.addEventListener('pointerup', stopResize)\n window.addEventListener('pointercancel', stopResize)\n }\n\n function isResizingKind(kind: TKind): boolean {\n return activeResize.value?.kind === kind\n }\n\n watch(() => toValue(options.enabled), enabled => { if (!enabled) stopResize() })\n onBeforeUnmount(stopResize)\n\n return { activeResize, isResizing, isResizingKind, startResize, stopResize }\n}\n","// Application shell components (`@morscherlab/mint-sdk/shell`).\n\n// Layout components\nexport { default as AppTopBar } from './components/AppTopBar.vue'\nexport { default as AppSidebar } from './components/AppSidebar.vue'\nexport { default as AppLayout } from './components/AppLayout.vue'\nexport { default as LayoutResizeHandle } from './components/LayoutResizeHandle.vue'\n\n// Headless interaction composables\nexport {\n useEventListener,\n type EventListenerEnabled,\n type EventFor,\n type EventListenerStop,\n type EventMapFor,\n type EventTargetGetter,\n type EventTargetLike,\n type UseEventListenerObjectOptions,\n type UseEventListenerOptions,\n} from './composables/useEventListener'\nexport {\n useDebouncedWatch,\n type DebouncedWatchCallback,\n type DebouncedWatchCleanup,\n type DebouncedWatchSource,\n type UseDebouncedWatchOptions,\n type UseDebouncedWatchReturn,\n} from './composables/useDebouncedWatch'\nexport {\n useFocusTrap,\n type UseFocusTrapOptions,\n type UseFocusTrapReturn,\n} from './composables/useFocusTrap'\nexport {\n useRovingFocus,\n type UseRovingFocusOptions,\n type UseRovingFocusReturn,\n} from './composables/useRovingFocus'\nexport {\n reorderList,\n useListReorder,\n useReorderAnnouncer,\n REORDER_ANNOUNCER_STYLE,\n type ListReorderMove,\n type UseListReorderOptions,\n type UseListReorderReturn,\n type UseReorderAnnouncerReturn,\n} from './composables/useListReorder'\nexport {\n useMenuKeyboard,\n type UseMenuKeyboardOptions,\n type UseMenuKeyboardReturn,\n} from './composables/useMenuKeyboard'\n\n// Layout, selection, expansion and sort primitives\nexport {\n resizedLeadingPanelWidth,\n resizedTrailingPanelWidth,\n resizedVerticalSplitPercent,\n useManualLayoutResize,\n type ManualLayoutResizeContext,\n type ManualLayoutResizeTarget,\n type ResizePanelWidthConstraints,\n type ResizePercentConstraints,\n} from './composables/useManualLayoutResize'\nexport {\n useSelectionLimit,\n type SelectionLimitSource,\n type UseSelectionLimitOptions,\n type UseSelectionLimitReturn,\n} from './composables/useSelectionLimit'\nexport {\n useListSelection,\n type ListSelectionSource,\n type ListSelectionValue,\n type UseListSelectionOptions,\n type UseListSelectionReturn,\n type WidenListSelectionValue,\n} from './composables/useListSelection'\nexport {\n useExpansionSet,\n type ExpansionSetSource,\n type UseExpansionSetOptions,\n type UseExpansionSetReturn,\n} from './composables/useExpansionSet'\nexport {\n compareSortValues,\n useSortedItems,\n type CompareSortValuesOptions,\n type SortComparator,\n type SortComparatorContext,\n type SortDescriptor,\n type SortedItemsSource,\n type SortOrder,\n type UseSortedItemsOptions,\n type UseSortedItemsReturn,\n} from './composables/useSortedItems'\nexport {\n usePluginWorkspace,\n type PluginWorkspaceSlotsLike,\n type UsePluginWorkspaceOptions,\n type UsePluginWorkspaceReturn,\n} from './composables/usePluginWorkspace'\n\n// Onboarding: tours, the Getting started checklist and what's-new hints\nexport {\n ANCHOR_WAIT_MS,\n defineOnboarding,\n provideOnboarding,\n useOnboarding,\n ONBOARDING_KEY,\n type OnboardingActiveStep,\n type OnboardingDefinition,\n type OnboardingNews,\n type OnboardingState,\n type OnboardingStep,\n type OnboardingTask,\n type OnboardingTour,\n type ProvideOnboardingOptions,\n} from './composables/useOnboarding'\n"],"mappings":"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"}
1
+ {"version":3,"file":"shell-Bk9mD4Lc.js","names":[],"sources":["../src/components/LayoutResizeHandle.vue","../src/components/LayoutResizeHandle.vue","../src/composables/useManualLayoutResize.ts","../src/shell.ts"],"sourcesContent":["<script setup lang=\"ts\">\n/** Accessible pointer and keyboard handle for resizable workbench panes. */\ninterface Props {\n modelValue: number\n min: number\n max: number\n label: string\n orientation: 'vertical' | 'horizontal'\n edge?: 'left' | 'right'\n step?: number\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n edge: undefined,\n step: 10,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number]\n 'resize-start': [event: PointerEvent]\n}>()\n\nfunction update(value: number): void {\n emit('update:modelValue', Math.min(props.max, Math.max(props.min, value)))\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (props.disabled) return\n const decrement = props.orientation === 'vertical' ? 'ArrowLeft' : 'ArrowUp'\n const increment = props.orientation === 'vertical' ? 'ArrowRight' : 'ArrowDown'\n if (event.key === decrement) update(props.modelValue - props.step)\n else if (event.key === increment) update(props.modelValue + props.step)\n else if (event.key === 'Home') update(props.min)\n else if (event.key === 'End') update(props.max)\n else return\n event.preventDefault()\n}\n</script>\n\n<template>\n <div\n role=\"separator\"\n :tabindex=\"disabled ? -1 : 0\"\n :class=\"[\n 'mint-layout-resize-handle',\n `mint-layout-resize-handle--${orientation}`,\n edge ? `mint-layout-resize-handle--edge-${edge}` : '',\n ]\"\n :aria-label=\"label\"\n :aria-orientation=\"orientation\"\n :aria-valuemin=\"min\"\n :aria-valuemax=\"max\"\n :aria-valuenow=\"modelValue\"\n :aria-disabled=\"disabled || undefined\"\n @pointerdown=\"!disabled && emit('resize-start', $event)\"\n @keydown=\"handleKeydown\"\n >\n <span class=\"mint-layout-resize-handle__bar\" aria-hidden=\"true\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Accessible pointer and keyboard handle for resizable workbench panes. */\ninterface Props {\n modelValue: number\n min: number\n max: number\n label: string\n orientation: 'vertical' | 'horizontal'\n edge?: 'left' | 'right'\n step?: number\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n edge: undefined,\n step: 10,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number]\n 'resize-start': [event: PointerEvent]\n}>()\n\nfunction update(value: number): void {\n emit('update:modelValue', Math.min(props.max, Math.max(props.min, value)))\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (props.disabled) return\n const decrement = props.orientation === 'vertical' ? 'ArrowLeft' : 'ArrowUp'\n const increment = props.orientation === 'vertical' ? 'ArrowRight' : 'ArrowDown'\n if (event.key === decrement) update(props.modelValue - props.step)\n else if (event.key === increment) update(props.modelValue + props.step)\n else if (event.key === 'Home') update(props.min)\n else if (event.key === 'End') update(props.max)\n else return\n event.preventDefault()\n}\n</script>\n\n<template>\n <div\n role=\"separator\"\n :tabindex=\"disabled ? -1 : 0\"\n :class=\"[\n 'mint-layout-resize-handle',\n `mint-layout-resize-handle--${orientation}`,\n edge ? `mint-layout-resize-handle--edge-${edge}` : '',\n ]\"\n :aria-label=\"label\"\n :aria-orientation=\"orientation\"\n :aria-valuemin=\"min\"\n :aria-valuemax=\"max\"\n :aria-valuenow=\"modelValue\"\n :aria-disabled=\"disabled || undefined\"\n @pointerdown=\"!disabled && emit('resize-start', $event)\"\n @keydown=\"handleKeydown\"\n >\n <span class=\"mint-layout-resize-handle__bar\" aria-hidden=\"true\" />\n </div>\n</template>\n","import { computed, onBeforeUnmount, shallowRef, toValue, watch, type MaybeRefOrGetter } from 'vue'\n\nexport interface ResizePanelWidthConstraints {\n minWidth: number\n maxWidth: number\n mainMinWidth?: number\n layoutGap?: number\n}\n\nexport interface ResizePercentConstraints {\n minPercent: number\n maxPercent: number\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction availablePanelWidth(\n containerWidth: number,\n constraints: ResizePanelWidthConstraints,\n): number {\n return Math.min(\n constraints.maxWidth,\n containerWidth - (constraints.mainMinWidth ?? 0) - (constraints.layoutGap ?? 0),\n )\n}\n\nexport function resizedLeadingPanelWidth(\n startWidth: number,\n deltaX: number,\n containerWidth: number,\n constraints: ResizePanelWidthConstraints,\n): number {\n return Math.round(clamp(\n startWidth + deltaX,\n constraints.minWidth,\n Math.max(constraints.minWidth, availablePanelWidth(containerWidth, constraints)),\n ))\n}\n\nexport function resizedTrailingPanelWidth(\n startWidth: number,\n deltaX: number,\n containerWidth: number,\n constraints: ResizePanelWidthConstraints,\n): number {\n return resizedLeadingPanelWidth(startWidth, -deltaX, containerWidth, constraints)\n}\n\nexport function resizedVerticalSplitPercent(\n startPercent: number,\n deltaY: number,\n containerHeight: number,\n constraints: ResizePercentConstraints,\n): number {\n if (containerHeight <= 0) return startPercent\n return Math.round(clamp(\n startPercent + (deltaY / containerHeight) * 100,\n constraints.minPercent,\n constraints.maxPercent,\n ))\n}\n\nexport interface ManualLayoutResizeContext<TKind extends string> {\n kind: TKind\n startValue: number\n deltaX: number\n deltaY: number\n containerRect: DOMRectReadOnly\n secondaryRect: DOMRectReadOnly | null\n}\n\nexport interface ManualLayoutResizeTarget<TKind extends string> {\n cursor?: string\n getContainerElement: () => HTMLElement | null\n getSecondaryElement?: () => HTMLElement | null\n getStartValue: () => number\n onResize: (context: ManualLayoutResizeContext<TKind>) => void\n}\n\n/** Coordinates pointer-driven resizing for one or more layout splitters. */\nexport function useManualLayoutResize<TKind extends string>(options: {\n enabled: MaybeRefOrGetter<boolean>\n resolveTarget: (kind: TKind) => ManualLayoutResizeTarget<TKind> | null\n}) {\n const activeResize = shallowRef<{\n kind: TKind\n startClientX: number\n startClientY: number\n startValue: number\n containerRect: DOMRectReadOnly\n secondaryRect: DOMRectReadOnly | null\n cursor: string\n } | null>(null)\n const isResizing = computed(() => activeResize.value !== null)\n let previousBodyCursor = ''\n let previousBodyUserSelect = ''\n\n function stopResize(): void {\n if (!activeResize.value) return\n activeResize.value = null\n window.removeEventListener('pointermove', handlePointerMove)\n window.removeEventListener('pointerup', stopResize)\n window.removeEventListener('pointercancel', stopResize)\n if (typeof document !== 'undefined') {\n document.body.style.cursor = previousBodyCursor\n document.body.style.userSelect = previousBodyUserSelect\n }\n }\n\n function handlePointerMove(event: PointerEvent): void {\n const state = activeResize.value\n if (!state) return\n options.resolveTarget(state.kind)?.onResize({\n kind: state.kind,\n startValue: state.startValue,\n deltaX: event.clientX - state.startClientX,\n deltaY: event.clientY - state.startClientY,\n containerRect: state.containerRect,\n secondaryRect: state.secondaryRect,\n })\n }\n\n function startResize(kind: TKind, event: PointerEvent): void {\n if (!toValue(options.enabled) || event.button !== 0) return\n const target = options.resolveTarget(kind)\n const containerRect = target?.getContainerElement()?.getBoundingClientRect()\n if (!target || !containerRect) return\n\n event.preventDefault()\n if (event.currentTarget instanceof HTMLElement) {\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n const secondary = target.getSecondaryElement?.() ?? null\n activeResize.value = {\n kind,\n startClientX: event.clientX,\n startClientY: event.clientY,\n startValue: target.getStartValue(),\n containerRect,\n secondaryRect: secondary?.getBoundingClientRect() ?? null,\n cursor: target.cursor ?? 'col-resize',\n }\n\n if (typeof document !== 'undefined') {\n previousBodyCursor = document.body.style.cursor\n previousBodyUserSelect = document.body.style.userSelect\n document.body.style.cursor = activeResize.value.cursor\n document.body.style.userSelect = 'none'\n }\n window.addEventListener('pointermove', handlePointerMove)\n window.addEventListener('pointerup', stopResize)\n window.addEventListener('pointercancel', stopResize)\n }\n\n function isResizingKind(kind: TKind): boolean {\n return activeResize.value?.kind === kind\n }\n\n watch(() => toValue(options.enabled), enabled => { if (!enabled) stopResize() })\n onBeforeUnmount(stopResize)\n\n return { activeResize, isResizing, isResizingKind, startResize, stopResize }\n}\n","// Application shell components (`@morscherlab/mint-sdk/shell`).\n\n// Layout components\nexport { default as AppTopBar } from './components/AppTopBar.vue'\nexport { default as AppSidebar } from './components/AppSidebar.vue'\nexport { default as AppLayout } from './components/AppLayout.vue'\nexport { default as LayoutResizeHandle } from './components/LayoutResizeHandle.vue'\n\n// Headless interaction composables\nexport {\n useEventListener,\n type EventListenerEnabled,\n type EventFor,\n type EventListenerStop,\n type EventMapFor,\n type EventTargetGetter,\n type EventTargetLike,\n type UseEventListenerObjectOptions,\n type UseEventListenerOptions,\n} from './composables/useEventListener'\nexport {\n useDebouncedWatch,\n type DebouncedWatchCallback,\n type DebouncedWatchCleanup,\n type DebouncedWatchSource,\n type UseDebouncedWatchOptions,\n type UseDebouncedWatchReturn,\n} from './composables/useDebouncedWatch'\nexport {\n useFocusTrap,\n type UseFocusTrapOptions,\n type UseFocusTrapReturn,\n} from './composables/useFocusTrap'\nexport {\n useRovingFocus,\n type UseRovingFocusOptions,\n type UseRovingFocusReturn,\n} from './composables/useRovingFocus'\nexport {\n reorderList,\n useListReorder,\n useReorderAnnouncer,\n REORDER_ANNOUNCER_STYLE,\n type ListReorderMove,\n type UseListReorderOptions,\n type UseListReorderReturn,\n type UseReorderAnnouncerReturn,\n} from './composables/useListReorder'\nexport {\n useMenuKeyboard,\n type UseMenuKeyboardOptions,\n type UseMenuKeyboardReturn,\n} from './composables/useMenuKeyboard'\n\n// Layout, selection, expansion and sort primitives\nexport {\n resizedLeadingPanelWidth,\n resizedTrailingPanelWidth,\n resizedVerticalSplitPercent,\n useManualLayoutResize,\n type ManualLayoutResizeContext,\n type ManualLayoutResizeTarget,\n type ResizePanelWidthConstraints,\n type ResizePercentConstraints,\n} from './composables/useManualLayoutResize'\nexport {\n useSelectionLimit,\n type SelectionLimitSource,\n type UseSelectionLimitOptions,\n type UseSelectionLimitReturn,\n} from './composables/useSelectionLimit'\nexport {\n useListSelection,\n type ListSelectionSource,\n type ListSelectionValue,\n type UseListSelectionOptions,\n type UseListSelectionReturn,\n type WidenListSelectionValue,\n} from './composables/useListSelection'\nexport {\n useExpansionSet,\n type ExpansionSetSource,\n type UseExpansionSetOptions,\n type UseExpansionSetReturn,\n} from './composables/useExpansionSet'\nexport {\n compareSortValues,\n useSortedItems,\n type CompareSortValuesOptions,\n type SortComparator,\n type SortComparatorContext,\n type SortDescriptor,\n type SortedItemsSource,\n type SortOrder,\n type UseSortedItemsOptions,\n type UseSortedItemsReturn,\n} from './composables/useSortedItems'\nexport {\n usePluginWorkspace,\n type PluginWorkspaceSlotsLike,\n type UsePluginWorkspaceOptions,\n type UsePluginWorkspaceReturn,\n} from './composables/usePluginWorkspace'\n\n// Onboarding: tours, the Getting started checklist and what's-new hints\nexport {\n ANCHOR_WAIT_MS,\n defineOnboarding,\n provideOnboarding,\n useOnboarding,\n ONBOARDING_KEY,\n type OnboardingActiveStep,\n type OnboardingDefinition,\n type OnboardingNews,\n type OnboardingState,\n type OnboardingStep,\n type OnboardingTask,\n type OnboardingTour,\n type ProvideOnboardingOptions,\n} from './composables/useOnboarding'\n"],"mappings":"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"}
package/dist/shell.js CHANGED
@@ -1,8 +1,8 @@
1
- import { i as useEventListener, r as useFocusTrap } from "./useDropdownState-uFIz6Yv8.js";
2
- import { E as useMenuKeyboard, H as useListSelection, R as useRovingFocus, U as useSelectionLimit } from "./records-BAymyHAn.js";
3
- import { B as compareSortValues, V as useSortedItems, i as useReorderAnnouncer, n as reorderList, r as useListReorder, t as REORDER_ANNOUNCER_STYLE } from "./useListReorder-W1bzK_bo.js";
4
- import { C as usePluginWorkspace, S as AppLayout_default, _ as provideOnboarding, f as AppTopBar_default, g as defineOnboarding, h as ONBOARDING_KEY, m as ANCHOR_WAIT_MS, t as AppSidebar_default, v as useOnboarding } from "./AppSidebar-CIBehlYL.js";
1
+ import { i as useEventListener, r as useFocusTrap } from "./useDropdownState-CcBzUYZ6.js";
2
+ import { D as useMenuKeyboard, U as useListSelection, W as useSelectionLimit, z as useRovingFocus } from "./records-GtiVMlTQ.js";
3
+ import { B as compareSortValues, V as useSortedItems, i as useReorderAnnouncer, n as reorderList, r as useListReorder, t as REORDER_ANNOUNCER_STYLE } from "./useListReorder-Bp4EAI2w.js";
4
+ import { S as AppLayout_default, _ as provideOnboarding, f as AppTopBar_default, g as defineOnboarding, h as ONBOARDING_KEY, m as ANCHOR_WAIT_MS, t as AppSidebar_default, v as useOnboarding, w as usePluginWorkspace } from "./AppSidebar-C-Vq5x4I.js";
5
5
  import { t as useDebouncedWatch } from "./useDebouncedWatch-BPwyl6eS.js";
6
6
  import { t as useExpansionSet } from "./useExpansionSet-CvoNMZJi.js";
7
- import { a as useManualLayoutResize, i as resizedVerticalSplitPercent, n as resizedLeadingPanelWidth, o as LayoutResizeHandle_default, r as resizedTrailingPanelWidth } from "./shell-B-woqThX.js";
7
+ import { a as useManualLayoutResize, i as resizedVerticalSplitPercent, n as resizedLeadingPanelWidth, o as LayoutResizeHandle_default, r as resizedTrailingPanelWidth } from "./shell-Bk9mD4Lc.js";
8
8
  export { ANCHOR_WAIT_MS, AppLayout_default as AppLayout, AppSidebar_default as AppSidebar, AppTopBar_default as AppTopBar, LayoutResizeHandle_default as LayoutResizeHandle, ONBOARDING_KEY, REORDER_ANNOUNCER_STYLE, compareSortValues, defineOnboarding, provideOnboarding, reorderList, resizedLeadingPanelWidth, resizedTrailingPanelWidth, resizedVerticalSplitPercent, useDebouncedWatch, useEventListener, useExpansionSet, useFocusTrap, useListReorder, useListSelection, useManualLayoutResize, useMenuKeyboard, useOnboarding, usePluginWorkspace, useReorderAnnouncer, useRovingFocus, useSelectionLimit, useSortedItems };
package/dist/styles.css CHANGED
@@ -122,12 +122,12 @@
122
122
  overflow-wrap: anywhere;
123
123
  }
124
124
 
125
- .mint-generated-workspace[data-v-90271c34] {
125
+ .mint-generated-workspace[data-v-7ba9e342] {
126
126
  min-width: 0;
127
127
  min-height: 0;
128
128
  overflow-y: auto;
129
129
  }
130
- .mint-generated-workspace__loading[data-v-90271c34] {
130
+ .mint-generated-workspace__loading[data-v-7ba9e342] {
131
131
  display: flex;
132
132
  flex: 1;
133
133
  align-items: center;
@@ -135,12 +135,12 @@
135
135
  gap: 0.75rem;
136
136
  color: var(--text-secondary);
137
137
  }
138
- .mint-generated-workspace__resources[data-v-90271c34] {
138
+ .mint-generated-workspace__resources[data-v-7ba9e342] {
139
139
  color: var(--text-muted);
140
140
  font-family: var(--font-mono);
141
141
  font-size: 0.75rem;
142
142
  }
143
- .mint-generated-workspace__description[data-v-90271c34] {
143
+ .mint-generated-workspace__description[data-v-7ba9e342] {
144
144
  margin: 0 0 var(--mint-gutter);
145
145
  color: var(--text-secondary);
146
146
  }
@@ -323,12 +323,12 @@
323
323
  --text-on-danger: #FFFFFF;
324
324
  /* Knob of a toggle or slider, and the mark of a disabled checkbox; white in both themes. */
325
325
  --control-knob: #FFFFFF;
326
- /* Retired hues, aliased to the accent until 1.5 (mint doctor warns on use). */
326
+ /* Retired hues, aliased to the accent until 2.0 (mint doctor warns on use). */
327
327
  --color-cta: var(--color-primary);
328
328
  --color-cta-hover: var(--color-primary-hover);
329
329
  --color-purple: var(--color-primary);
330
330
 
331
- /* Entity colors — retired hues, aliased to slate until 1.5. Entities are told
331
+ /* Entity colors — retired hues, aliased to slate until 2.0. Entities are told
332
332
  apart by icon and label, not by hue. Only -hover has no neutral token. */
333
333
  --color-experiment: var(--text-secondary-strong);
334
334
  --color-experiment-hover: #334155;
@@ -1707,6 +1707,10 @@ button, input, select, textarea {
1707
1707
  }
1708
1708
  }
1709
1709
 
1710
+ /* An AppTopBar in the layout renders the drawer button itself. */
1711
+ .mint-layout--responsive-sidebar:has(.mint-topbar__sidebar-toggle) .mint-layout__sidebar-toggle {
1712
+ display: none;
1713
+ }
1710
1714
  /* AppSidebar Component Styles */
1711
1715
 
1712
1716
  .mint-sidebar {
@@ -2266,6 +2270,8 @@ button, input, select, textarea {
2266
2270
  padding: 0.75rem 1rem;
2267
2271
  background-color: var(--bg-secondary);
2268
2272
  box-sizing: border-box;
2273
+ /* The two-row layout follows the bar's own width, not the window's. */
2274
+ container: mint-topbar / inline-size;
2269
2275
  }
2270
2276
 
2271
2277
  /* Main container layout — equal side columns keep the centre nav on the bar
@@ -2326,11 +2332,62 @@ button, input, select, textarea {
2326
2332
  grid-column: 3;
2327
2333
  display: flex;
2328
2334
  align-items: center;
2329
- gap: 0.125rem;
2335
+ gap: 0.375rem;
2330
2336
  min-width: 0;
2331
2337
  justify-content: flex-end;
2332
2338
  }
2333
2339
 
2340
+ /* Context group (standalone badge, run slot, onboarding, plugin buttons), then
2341
+ the fixed tail: theme, settings and the host's account controls, always last. */
2342
+ .mint-topbar__context,
2343
+ .mint-topbar__tail {
2344
+ display: flex;
2345
+ align-items: center;
2346
+ gap: 0.125rem;
2347
+ min-width: 0;
2348
+ }
2349
+
2350
+ .mint-topbar__tail {
2351
+ flex-shrink: 0;
2352
+ }
2353
+
2354
+ /* The deprecated #actions slot keeps a fixed width, so its content cannot push the bar. */
2355
+ .mint-topbar__legacy-actions {
2356
+ display: inline-flex;
2357
+ align-items: center;
2358
+ max-width: 16rem;
2359
+ overflow: hidden;
2360
+ }
2361
+
2362
+ /* Below 1024px of bar width: row 1 is identity + tail, row 2 the pills + context.
2363
+ Row 1 never holds more than the identity, so the tail never moves. */
2364
+ @container mint-topbar (max-width: 1023.98px) {
2365
+ .mint-topbar__container--stackable {
2366
+ /* The pills keep their width while it fits; the context group takes the rest and its experiment
2367
+ name truncates. On a bar narrower than the pills they overflow their cell, never the tail. */
2368
+ grid-template-columns: minmax(0, max-content) minmax(0, 1fr) auto;
2369
+ grid-template-areas:
2370
+ "start start tail"
2371
+ "center context context";
2372
+ row-gap: 0.375rem;
2373
+ }
2374
+
2375
+ .mint-topbar__container--stackable .mint-topbar__start { grid-area: start; }
2376
+ .mint-topbar__container--stackable .mint-topbar__right { display: contents; }
2377
+ .mint-topbar__container--stackable .mint-topbar__tail { grid-area: tail; }
2378
+
2379
+ .mint-topbar__container--stackable .mint-topbar__center {
2380
+ grid-area: center;
2381
+ justify-content: flex-start;
2382
+ }
2383
+
2384
+ .mint-topbar__container--stackable .mint-topbar__context {
2385
+ /* Stretch, not justify-self: end, which would size the group to its nowrap min-content. */
2386
+ grid-area: context;
2387
+ justify-content: flex-end;
2388
+ }
2389
+ }
2390
+
2334
2391
  /* Logo styles */
2335
2392
  .mint-topbar__logo {
2336
2393
  display: flex;
@@ -2431,11 +2488,13 @@ button, input, select, textarea {
2431
2488
  white-space: nowrap;
2432
2489
  }
2433
2490
 
2434
- /* The settings button has the IconButton ghost look: 32px, --radius-md,
2435
- 16px icon, neutral ink, offset focus ring. */
2436
- .mint-topbar__settings-btn {
2491
+ /* The settings button, plugin icon buttons and the drawer button have the
2492
+ IconButton ghost look: 32px, --radius-md, 16px icon, neutral ink, offset focus ring. */
2493
+ .mint-topbar__settings-btn,
2494
+ .mint-topbar__icon-btn {
2437
2495
  position: relative;
2438
2496
  display: inline-flex;
2497
+ flex-shrink: 0;
2439
2498
  align-items: center;
2440
2499
  justify-content: center;
2441
2500
  width: 2rem;
@@ -2450,23 +2509,62 @@ button, input, select, textarea {
2450
2509
  transition: background-color var(--mint-transition), color var(--mint-transition);
2451
2510
  }
2452
2511
 
2453
- .mint-topbar__settings-btn:hover {
2512
+ .mint-topbar__settings-btn:hover,
2513
+ .mint-topbar__icon-btn:hover:not(:disabled) {
2454
2514
  background: var(--bg-hover);
2455
2515
  color: var(--text-primary);
2456
2516
  }
2457
2517
 
2458
- .mint-topbar__settings-btn:focus-visible {
2518
+ .mint-topbar__settings-btn:focus-visible,
2519
+ .mint-topbar__icon-btn:focus-visible {
2459
2520
  outline: none;
2460
2521
  box-shadow: var(--focus-ring-offset);
2461
2522
  }
2462
2523
 
2463
- .mint-topbar__settings-icon {
2524
+ .mint-topbar__icon-btn:disabled {
2525
+ cursor: not-allowed;
2526
+ opacity: 0.5;
2527
+ }
2528
+
2529
+ .mint-topbar__settings-icon,
2530
+ .mint-topbar__icon-btn-icon {
2464
2531
  width: 1rem;
2465
2532
  height: 1rem;
2466
2533
  }
2467
2534
 
2535
+ /* Status dot of a plugin icon button (TopBarAction.dot). */
2536
+ .mint-topbar__icon-btn-dot {
2537
+ position: absolute;
2538
+ top: 0.3125rem;
2539
+ right: 0.3125rem;
2540
+ width: 0.4375rem;
2541
+ height: 0.4375rem;
2542
+ border-radius: 50%;
2543
+ box-shadow: 0 0 0 2px var(--bg-secondary);
2544
+ background: var(--text-muted);
2545
+ }
2546
+
2547
+ .mint-topbar__icon-btn-dot--primary,
2548
+ .mint-topbar__icon-btn-dot--cta { background: var(--color-primary); }
2549
+ .mint-topbar__icon-btn-dot--success { background: var(--mint-success); }
2550
+ .mint-topbar__icon-btn-dot--warning { background: var(--mint-warning); }
2551
+ .mint-topbar__icon-btn-dot--error { background: var(--mint-error); }
2552
+ .mint-topbar__icon-btn-dot--info { background: var(--mint-info); }
2553
+
2554
+ /* The drawer button shows only while the AppLayout sidebar is a drawer. */
2555
+ .mint-topbar__sidebar-toggle {
2556
+ display: none;
2557
+ }
2558
+
2559
+ @media (max-width: 1023.98px) {
2560
+ .mint-topbar__sidebar-toggle {
2561
+ display: inline-flex;
2562
+ }
2563
+ }
2564
+
2468
2565
  @media (prefers-reduced-motion: reduce) {
2469
- .mint-topbar__settings-btn {
2566
+ .mint-topbar__settings-btn,
2567
+ .mint-topbar__icon-btn {
2470
2568
  transition: none;
2471
2569
  }
2472
2570
  }
@@ -2648,6 +2746,32 @@ button, input, select, textarea {
2648
2746
  clip-path: inset(50%);
2649
2747
  white-space: nowrap;
2650
2748
  }
2749
+
2750
+ /* ─── Labels or icons, by fit ───
2751
+ Save and Jobs show their words while the content fits; AppTopBar.compact.ts
2752
+ sets --compact when it does not (a name is cut, the experiment chip is
2753
+ squeezed or a group overflows), and they keep only their icons. Plugin
2754
+ buttons with an icon are always icon-only. Accessible names and tooltips
2755
+ keep the words. */
2756
+ .mint-topbar--compact .mint-experiment-popover__save {
2757
+ width: 32px;
2758
+ padding: 0;
2759
+ justify-content: center;
2760
+ }
2761
+
2762
+ .mint-topbar--compact .mint-experiment-popover__save-label,
2763
+ .mint-topbar--compact .mint-topbar__job-label {
2764
+ display: none;
2765
+ }
2766
+
2767
+ .mint-topbar--compact .mint-topbar__job--idle {
2768
+ padding-inline: 0.5rem;
2769
+ }
2770
+
2771
+ /* One total width cap for the experiment chip, code and chevron included. */
2772
+ .mint-topbar .mint-experiment-popover__trigger {
2773
+ max-width: 16rem;
2774
+ }
2651
2775
  /* BaseButton Component Styles */
2652
2776
 
2653
2777
  .mint-button {
@@ -18313,7 +18437,7 @@ button.mint-unit-input__unit:focus-visible {
18313
18437
  .mint-plugin-icon--topbar { width: 2.25rem; height: 2.25rem; }
18314
18438
  .mint-plugin-icon--lg { width: 3rem; height: 3rem; }
18315
18439
 
18316
- /* Tones (deprecated with the tone/color props, removed in 1.5): the v2 tile no longer reads the variable. */
18440
+ /* Tones (deprecated with the tone/color props, removed in 2.0): the v2 tile no longer reads the variable. */
18317
18441
  .mint-plugin-icon--neutral { --mint-plugin-icon-tone: var(--text-secondary); }
18318
18442
  .mint-plugin-icon--primary { --mint-plugin-icon-tone: var(--color-primary); }
18319
18443
  .mint-plugin-icon--cta { --mint-plugin-icon-tone: var(--color-primary); }
@@ -169,6 +169,7 @@ export type PillNavItemInput = (Omit<PillNavItem, 'children'> & {
169
169
  export interface PageSelectorItem {
170
170
  id: string;
171
171
  label: string;
172
+ /** A Lucide icon name (`'activity'`, `'flask-conical'`) or a plugin icon (path, data URL, `mint-icon` JSON). Without one the page shows its first letter. */
172
173
  icon?: string;
173
174
  hint?: string;
174
175
  to?: string;
@@ -186,12 +187,31 @@ export interface PluginWorkspaceTopBarSpec {
186
187
  logo?: boolean;
187
188
  /** Centered pill navigation for the local modes of the current route (bind `v-model:pill`). */
188
189
  pills?: PillNavItemInput[];
189
- /** Show the theme toggle. */
190
+ /** @deprecated Ignored: the theme toggle always shows. Removed in 2.0. */
190
191
  themeToggle?: boolean;
191
- /** Settings button and modal; `false` hides the button. A getter can switch it per user. */
192
+ /**
193
+ * Settings modal of the always-present settings button. `false` (or a getter that returns it)
194
+ * gives the modal only its Appearance tab; it no longer hides the button.
195
+ */
192
196
  settings?: import('vue').MaybeRefOrGetter<false | TopBarSettingsConfig>;
193
197
  /** Standalone badge text when the plugin runs outside the platform; `false` hides it. */
194
198
  standaloneLabel?: false | string;
199
+ /** Plugin buttons, before the theme and settings buttons. The first two show; the rest go into a More menu. */
200
+ actions?: TopBarAction[];
201
+ }
202
+ /** One plugin button of the top bar. With `icon` it is an icon button and `label` is its accessible name and tooltip. */
203
+ export interface TopBarAction {
204
+ id: string;
205
+ label: string;
206
+ /** A Lucide icon name, such as `'database'`. */
207
+ icon?: string;
208
+ /** A small status dot on the button. */
209
+ dot?: Tone;
210
+ /** Tooltip; defaults to `label`. */
211
+ title?: string;
212
+ loading?: boolean;
213
+ disabled?: boolean;
214
+ onSelect: () => void;
195
215
  }
196
216
  /** Sidebar part of a PluginWorkspaceView spec; also the `:spec` of AppSidebar. */
197
217
  export interface PluginWorkspaceSidebarSpec {
@@ -117,6 +117,8 @@ export interface GeneratedJobDefinition {
117
117
  cpu: number;
118
118
  /** Who may submit the job when integrated: `use`, `configure` (`plugins.configure`) or `admin`. */
119
119
  access?: 'use' | 'configure' | 'admin';
120
+ /** The plugins that may start the job through the platform: `'readers'` or plugin names. Absent before SDK 1.5. */
121
+ callers?: 'readers' | string[];
120
122
  /** Defaults to process for manifests generated before lifecycle profiles. */
121
123
  lifecycle?: GeneratedJobLifecycle;
122
124
  /** Defaults to `{ kind: 'process' }` for older manifests. */
@@ -1,10 +1,10 @@
1
- export type { Tone, ContainerDirection, ButtonVariant, ButtonSize, ActionMenuItem, InputType, ModalSize, ModalVariant, ModalLayout, ModalTab, Toast, ToastAction, ToastOptions, OptionPrimitive, SelectOption, SelectOptionInput, FormFieldProps, SectionCardAccent, SectionCardDivider, SidebarToolSection, SidebarToolSectionAction, CollapsibleState, TopBarVariant, TopBarSettingsConfig, PillNavOption, PillNavOptionInput, PillNavItem, PillNavItemInput, PageSelectorItem, PageSelectorItemInput, PluginWorkspaceTopBarSpec, PluginWorkspaceSidebarSpec, PluginWorkspaceViewSpec, WellPlateFormat, WellState, WellPlateSelectionMode, WellPlateSize, WellShape, Well, WellClassValue, WellClassResolver, WellStyleResolver, HeatmapColorScale, HeatmapConfig, SlotPosition, WellExtendedData, WellEditData, WellEditField, WellSampleDropData, WellSampleDropContext, WellSampleDropParser, WellLegendItem, PlateCondition, ColumnCondition, RowCondition, Rack, PlateEditorClearConfirm, WellPlateSpec, PlateEditorSpec, SampleType, ProtocolStepType, ProtocolStepStatus, ProtocolStep, SampleGroup, FileUploaderMode, ChartLegendItem, SegmentedControlVariant, SegmentedControlSize, PillVariant, PillSize, CalendarSelectionMode, CalendarMarker, CalendarDayContext, SortDirection, SortState, DataFrameColumn, DataFrameSpec, SpinnerSize, DividerSpacing, ProgressSize, AvatarSize, EmptyStateSize, BreadcrumbItem, BreadcrumbItemInput, TooltipPosition, SettingsTab, SettingsTabInput, SettingsModalLayout, SettingsGroup, SettingsModalSchema, SettingsUserType, SettingsAudience, SettingsAudienceInput, NumberNotation, UnitOption, WizardStep, WizardStepState, AuditEntryType, AuditEntry, BatchItemStatus, BatchItem, BatchSummary, TimeSlotDisabledFn, TimeRange, ScheduleView, ScheduleEventStatus, ScheduleEvent, ScheduleBlockedSlot, ScheduleSlotContext, ScheduleEventCreateContext, ScheduleEventUpdateContext, SummarySectionItem, SummarySection, SummaryData, ResourceStatus, ResourceSpec, MoleculeData, ExperimentStatus, DatePreset, ExperimentSortField, ExperimentTypeOption, ExperimentSummary, ExperimentListResponse, ExperimentFilters, TreeNodeType, BadgeVariant, TreeNode, } from './components';
1
+ export type { Tone, ContainerDirection, ButtonVariant, ButtonSize, ActionMenuItem, InputType, ModalSize, ModalVariant, ModalLayout, ModalTab, Toast, ToastAction, ToastOptions, OptionPrimitive, SelectOption, SelectOptionInput, FormFieldProps, SectionCardAccent, SectionCardDivider, SidebarToolSection, SidebarToolSectionAction, CollapsibleState, TopBarVariant, TopBarSettingsConfig, PillNavOption, PillNavOptionInput, PillNavItem, PillNavItemInput, PageSelectorItem, PageSelectorItemInput, PluginWorkspaceTopBarSpec, TopBarAction, PluginWorkspaceSidebarSpec, PluginWorkspaceViewSpec, WellPlateFormat, WellState, WellPlateSelectionMode, WellPlateSize, WellShape, Well, WellClassValue, WellClassResolver, WellStyleResolver, HeatmapColorScale, HeatmapConfig, SlotPosition, WellExtendedData, WellEditData, WellEditField, WellSampleDropData, WellSampleDropContext, WellSampleDropParser, WellLegendItem, PlateCondition, ColumnCondition, RowCondition, Rack, PlateEditorClearConfirm, WellPlateSpec, PlateEditorSpec, SampleType, ProtocolStepType, ProtocolStepStatus, ProtocolStep, SampleGroup, FileUploaderMode, ChartLegendItem, SegmentedControlVariant, SegmentedControlSize, PillVariant, PillSize, CalendarSelectionMode, CalendarMarker, CalendarDayContext, SortDirection, SortState, DataFrameColumn, DataFrameSpec, SpinnerSize, DividerSpacing, ProgressSize, AvatarSize, EmptyStateSize, BreadcrumbItem, BreadcrumbItemInput, TooltipPosition, SettingsTab, SettingsTabInput, SettingsModalLayout, SettingsGroup, SettingsModalSchema, SettingsUserType, SettingsAudience, SettingsAudienceInput, NumberNotation, UnitOption, WizardStep, WizardStepState, AuditEntryType, AuditEntry, BatchItemStatus, BatchItem, BatchSummary, TimeSlotDisabledFn, TimeRange, ScheduleView, ScheduleEventStatus, ScheduleEvent, ScheduleBlockedSlot, ScheduleSlotContext, ScheduleEventCreateContext, ScheduleEventUpdateContext, SummarySectionItem, SummarySection, SummaryData, ResourceStatus, ResourceSpec, MoleculeData, ExperimentStatus, DatePreset, ExperimentSortField, ExperimentTypeOption, ExperimentSummary, ExperimentListResponse, ExperimentFilters, TreeNodeType, BadgeVariant, TreeNode, } from './components';
2
2
  export type * from './generated-ui';
3
3
  export type { AnalysisArtifactStatus, AnalysisArtifactStatusFilter, AnalysisArtifactSummary, AnalysisArtifactDetail, AnalysisArtifactListResponse, AnalysisArtifactTarget, AnalysisArtifactMetadataUpdate, ArtifactSaveMode, ArtifactFileSource, JsonArtifactSavePayload, FileArtifactCreatePayload, FileArtifactUpdatePayload, HandlerFileArtifactCreatePayload, HandlerFileArtifactUpdatePayload, ArtifactSavePayload, HandlerArtifactSavePayload, ArtifactSaveDialogPayload, ArtifactSaveResult, ArtifactSaveHandler, HandlerArtifactSaveHandler, ArtifactSaveDialogHandler, } from './analysisArtifactTypes';
4
4
  export { ANALYSIS_FILE_ARTIFACT_SCHEMA } from './analysisArtifactTypes';
5
5
  export type { FileBrowserLocation, FileBrowserSortKey, FileDirectoryListing, FileDirectoryTree, FileEntry, FileEntryKind, FilePathCrumb, FileSearchResult, FileSelection, ServerMount, } from './fileBrowserTypes';
6
6
  export type { JobListPayload, JobProgress, JobSnapshotPayload, JobState, JobStateInput, JobStatus, JobStreamData, TopBarJob, } from './jobs';
7
- export type { InjectionMetricSeries, InstrumentAlert, InstrumentAlertLevel, InstrumentAlertList, InstrumentBadgeState, InstrumentLiveProgress, InstrumentLiveStatus, InstrumentState, InstrumentStatus, InstrumentStatusReporter, SampleInfo, SampleInfo as InstrumentSampleInfo, SequenceProgress, StatusPanel, } from './instrument';
7
+ export type { InjectionMetricSeries, InstrumentAlert, InstrumentAlertLevel, InstrumentAlertList, InstrumentBadgeState, InstrumentLiveProgress, InstrumentLiveStatus, InstrumentState, InstrumentStatusReporter, SampleInfo, SampleInfo as InstrumentSampleInfo, SequenceProgress, StatusPanel, } from './instrument';
8
8
  export type { AccessAudience, AccessAudienceInput, AccessPolicy, AccessControlled, PermissionUser, RoleInfo, } from '../permissions';
9
9
  export type { FormFieldType, FieldCondition, FieldValidation, FormFieldSchema, FormOptionInput, FormSectionSchema, FormStepSchema, FormSchema, FieldEnhancement, FormEnhancements, UseFormBuilderReturn, } from './form-builder';
10
10
  export type { OutlierAction, InputMode, OutlierInfo, ColumnInfo, MetadataRow, AutoGroupResult, ParsedCsvData, } from './auto-group';
@@ -21,23 +21,6 @@ export interface SequenceProgress {
21
21
  estimated_finish_time?: string | Date | null;
22
22
  sample_durations?: readonly number[];
23
23
  }
24
- /** @deprecated Scheduled for removal in MINT 1.4; instrument monitor types move to the mld-ms plugins. */
25
- export interface InstrumentStatus {
26
- instrument_id: string;
27
- instrument_name?: string | null;
28
- monitor_id?: string | null;
29
- state: InstrumentState;
30
- active_method?: string | null;
31
- current_sample?: SampleInfo | null;
32
- sequence_progress?: SequenceProgress | null;
33
- timestamp?: string | Date;
34
- last_seen?: string | Date | null;
35
- connected?: boolean;
36
- sequence_file?: string | null;
37
- sequence_row_index?: number | null;
38
- current_raw_file?: string | null;
39
- method_elapsed_pct?: number | null;
40
- }
41
24
  /** A state the platform derives for an instrument: its reported state, `never` (no report yet) or `inactive`. */
42
25
  export type InstrumentBadgeState = InstrumentState | 'never' | 'inactive';
43
26
  /** One per-injection metric over the current sequence; `values[i]` belongs to position `i + 1`, up to the last finished one (pad to `total_samples`). */
@@ -345,6 +345,15 @@ var _hoisted_29 = {
345
345
  };
346
346
  /** Open modals, oldest first; shared by every BaseModal instance. */
347
347
  var openModals = [];
348
+ /** Body overflow from before the first modal opened, restored when the last one closes. */
349
+ var bodyOverflowBeforeLock = "";
350
+ /** Body scroll follows the stack: locked while any modal is open. */
351
+ function syncBodyScrollLock(wasEmpty) {
352
+ if (wasEmpty && openModals.length > 0) {
353
+ bodyOverflowBeforeLock = document.body.style.overflow;
354
+ document.body.style.overflow = "hidden";
355
+ } else if (!wasEmpty && openModals.length === 0) document.body.style.overflow = bodyOverflowBeforeLock;
356
+ }
348
357
  //#endregion
349
358
  //#region src/components/BaseModal.vue
350
359
  var BaseModal_default = /* @__PURE__ */ defineComponent({
@@ -417,14 +426,13 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
417
426
  containerRef,
418
427
  active: toRef(props, "open")
419
428
  });
420
- watch(() => props.open, (isOpen) => {
421
- document.body.style.overflow = isOpen ? "hidden" : "";
422
- });
423
429
  const self = {};
424
430
  watch(() => props.open, (isOpen) => {
431
+ const wasEmpty = openModals.length === 0;
425
432
  const index = openModals.indexOf(self);
426
433
  if (isOpen && index === -1) openModals.push(self);
427
434
  if (!isOpen && index !== -1) openModals.splice(index, 1);
435
+ syncBodyScrollLock(wasEmpty);
428
436
  }, { immediate: true });
429
437
  function handleEscapeKeydown(event) {
430
438
  if (event.key === "Escape" && !event.defaultPrevented && props.closeOnEscape && props.open && openModals[openModals.length - 1] === self) close();
@@ -440,9 +448,10 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
440
448
  }
441
449
  useEventListener(() => document, "keydown", handleEscapeKeydown);
442
450
  onUnmounted(() => {
443
- document.body.style.overflow = "";
451
+ const wasEmpty = openModals.length === 0;
444
452
  const index = openModals.indexOf(self);
445
453
  if (index !== -1) openModals.splice(index, 1);
454
+ syncBodyScrollLock(wasEmpty);
446
455
  });
447
456
  return (_ctx, _cache) => {
448
457
  return openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, { name: `modal-${__props.variant}` }, {
@@ -605,4 +614,4 @@ function useDropdownState(options = {}) {
605
614
  //#endregion
606
615
  export { BaseButton_default as a, useEventListener as i, BaseModal_default as n, __exportAll as o, useFocusTrap as r, useDropdownState as t };
607
616
 
608
- //# sourceMappingURL=useDropdownState-uFIz6Yv8.js.map
617
+ //# sourceMappingURL=useDropdownState-CcBzUYZ6.js.map