@morscherlab/mint-sdk 1.4.12 → 1.4.13

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/dist/styles.css CHANGED
@@ -1422,7 +1422,7 @@ button, input, select, textarea {
1422
1422
  .mint-alert__icon--info { background-color: var(--mint-info-bg); color: var(--mint-info); }
1423
1423
  .mint-alert__icon--neutral { background-color: var(--bg-tertiary); color: var(--text-secondary); }
1424
1424
  .mint-alert__icon--primary { background-color: var(--color-primary-soft); color: var(--color-primary); }
1425
- .mint-alert__icon--cta { background-color: var(--color-primary-soft); color: var(--color-primary-hover); }
1425
+ .mint-alert__icon--cta { background-color: var(--color-primary-soft); color: var(--_ink-primary); }
1426
1426
 
1427
1427
  .mint-alert__content {
1428
1428
  flex: 1;
@@ -2424,7 +2424,8 @@ button, input, select, textarea {
2424
2424
  .mint-topbar__plugin-name,
2425
2425
  .mint-topbar__plugin-subtitle,
2426
2426
  .mint-topbar-title,
2427
- .mint-topbar-subtitle {
2427
+ .mint-topbar-subtitle,
2428
+ .mint-topbar__title-only {
2428
2429
  overflow: hidden;
2429
2430
  text-overflow: ellipsis;
2430
2431
  white-space: nowrap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morscherlab/mint-sdk",
3
- "version": "1.4.12",
3
+ "version": "1.4.13",
4
4
  "description": "MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec Infrastructure for Next-generation Toolkits.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -392,6 +392,25 @@ describe('PluginWorkspaceView', () => {
392
392
  expect(wrapper.get('[data-test="sidebar-footer"]').text()).toBe('Run')
393
393
  })
394
394
 
395
+ it.each([
396
+ { name: 'bound v-model', sidebarCollapsed: true, collapsedWidth: undefined, expected: '3rem' },
397
+ { name: 'its own state', sidebarCollapsed: undefined, collapsedWidth: '3.5rem', expected: '3.5rem' },
398
+ ])('should give AppLayout the collapsed width when the sidebar collapses through $name', async ({ sidebarCollapsed, collapsedWidth, expected }) => {
399
+ const wrapper = mount(PluginWorkspaceView, {
400
+ props: {
401
+ sidebarCollapsed,
402
+ spec: { title: 'Tools', sidebar: { width: '20rem', collapsible: true, collapsedWidth, whenEmpty: true } },
403
+ },
404
+ global: globalOptions,
405
+ })
406
+ expect(wrapper.findComponent(AppLayout).props('sidebarWidth')).toBe(sidebarCollapsed ? expected : '20rem')
407
+
408
+ wrapper.findComponent(AppSidebar).vm.$emit('update:collapsed', true)
409
+ await nextTick()
410
+
411
+ expect(wrapper.findComponent(AppLayout).props('sidebarWidth')).toBe(expected)
412
+ })
413
+
395
414
  it('can provide AppTopBar experiment selection and save wiring from the shared store', async () => {
396
415
  vi.mocked(usePlatform).mockReturnValueOnce({
397
416
  integrated: computed(() => true),
@@ -40,6 +40,11 @@ describe('menus and app shell styles', () => {
40
40
  expect(css('app-page-selector.css')).toMatch(new RegExp(`\\.mint-page-selector__${part}\\s*\\{[^}]*box-sizing:\\s*border-box;`))
41
41
  })
42
42
 
43
+ // Beside a nav slot, a title without a subtitle broke at its hyphen ("LEAF-" over "cal").
44
+ it('should keep a title-only top-bar label on one line', () => {
45
+ expect(css('app-top-bar.css')).toMatch(/\.mint-topbar__title-only[^{]*\{[^}]*white-space:\s*nowrap;/)
46
+ })
47
+
43
48
  // Shrinking the tile beside the identity also shrank structured icons inside their solid chip, drawing a ring.
44
49
  it('should keep the plugin tile beside the static plugin identity (5a)', () => {
45
50
  expect(css('app-top-bar.css')).not.toMatch(/:has\(\+ \.mint-topbar__plugin-identity\)/)
@@ -93,6 +93,7 @@ const {
93
93
  controls,
94
94
  handleControlValuesUpdate,
95
95
  handlePillSelect,
96
+ handleSidebarCollapsedUpdate,
96
97
  } = usePluginWorkspace({
97
98
  props,
98
99
  slots,
@@ -146,7 +147,7 @@ function handleFormCancel(sectionId: string) {
146
147
  <WorkspaceSidebarInternal
147
148
  :sidebar="sidebar"
148
149
  @update:values="handleControlValuesUpdate"
149
- @update:collapsed="emit('update:sidebarCollapsed', $event)"
150
+ @update:collapsed="handleSidebarCollapsedUpdate"
150
151
  @update:toggle="handleToggle"
151
152
  @section-action="(sectionId: string, actionId: string) => emit('section-action', sectionId, actionId)"
152
153
  @form-submit="handleFormSubmit"
@@ -1,4 +1,4 @@
1
- import { computed } from 'vue'
1
+ import { computed, ref } from 'vue'
2
2
  import type { ComputedRef } from 'vue'
3
3
  import type { PillNavItem, PluginWorkspaceSidebarSpec } from '../types'
4
4
  import type {
@@ -48,6 +48,8 @@ export interface UsePluginWorkspaceReturn {
48
48
  handleControlValuesUpdate: (values: Record<string, unknown>) => void
49
49
  /** Resolves an AppTopBar `pill-select` payload into the active view and emits `update:pill` and `pill-select`. */
50
50
  handlePillSelect: (item: PillNavItem) => void
51
+ /** Applies an AppSidebar `update:collapsed` payload and emits `update:sidebarCollapsed`. */
52
+ handleSidebarCollapsedUpdate: (value: boolean) => void
51
53
  }
52
54
 
53
55
  /**
@@ -94,6 +96,14 @@ export function usePluginWorkspace(options: UsePluginWorkspaceOptions): UsePlugi
94
96
  const topBarSlotNames = computed<string[]>(() => getPluginWorkspaceTopBarSlotNames(slots))
95
97
  const sidebarSlotNames = computed<string[]>(() => getPluginWorkspaceSidebarSlotNames(slots))
96
98
 
99
+ // The workspace owns the collapsed state (unless bound) so AppLayout reserves the collapsed width.
100
+ const internalCollapsed = ref(false)
101
+ const sidebarCollapsed = computed(() => props.sidebarCollapsed ?? internalCollapsed.value)
102
+ function handleSidebarCollapsedUpdate(value: boolean) {
103
+ internalCollapsed.value = value
104
+ emit('update:sidebarCollapsed', value)
105
+ }
106
+
97
107
  const hasSidebarSurface = computed(() => hasPluginWorkspaceSidebarSurface({
98
108
  sidebar: sidebarSpec.value,
99
109
  hasSidebarSlot: Boolean(slots.sidebar),
@@ -114,7 +124,7 @@ export function usePluginWorkspace(options: UsePluginWorkspaceOptions): UsePlugi
114
124
  const sidebar = sidebarSpec.value === false ? {} : sidebarSpec.value
115
125
  return {
116
126
  sidebarPosition: sidebar.position ?? 'left',
117
- sidebarWidth: sidebar.width,
127
+ sidebarWidth: sidebarCollapsed.value ? (sidebar.collapsedWidth ?? '3rem') : sidebar.width,
118
128
  floating: props.spec?.floating ?? true,
119
129
  responsiveSidebar: sidebar.responsive ?? true,
120
130
  sidebarToggleLabel: sidebar.toggleLabel ?? 'Open workspace sidebar',
@@ -142,7 +152,7 @@ export function usePluginWorkspace(options: UsePluginWorkspaceOptions): UsePlugi
142
152
  },
143
153
  activeView: navigationState.resolvedActiveView.value,
144
154
  values: controlsState.internalControlValues,
145
- collapsed: props.sidebarCollapsed,
155
+ collapsed: sidebarCollapsed.value,
146
156
  formLoading: props.formLoading ?? false,
147
157
  formDisabled: props.formDisabled ?? false,
148
158
  formReadonly: props.formReadonly ?? false,
@@ -157,5 +167,6 @@ export function usePluginWorkspace(options: UsePluginWorkspaceOptions): UsePlugi
157
167
  hasSidebarSurface,
158
168
  handleControlValuesUpdate: controlsState.handleControlValuesUpdate,
159
169
  handlePillSelect: navigationState.handlePillSelect,
170
+ handleSidebarCollapsedUpdate,
160
171
  }
161
172
  }
@@ -31,7 +31,7 @@
31
31
  .mint-alert__icon--info { background-color: var(--mint-info-bg); color: var(--mint-info); }
32
32
  .mint-alert__icon--neutral { background-color: var(--bg-tertiary); color: var(--text-secondary); }
33
33
  .mint-alert__icon--primary { background-color: var(--color-primary-soft); color: var(--color-primary); }
34
- .mint-alert__icon--cta { background-color: var(--color-primary-soft); color: var(--color-primary-hover); }
34
+ .mint-alert__icon--cta { background-color: var(--color-primary-soft); color: var(--_ink-primary); }
35
35
 
36
36
  .mint-alert__content {
37
37
  flex: 1;
@@ -170,7 +170,8 @@
170
170
  .mint-topbar__plugin-name,
171
171
  .mint-topbar__plugin-subtitle,
172
172
  .mint-topbar-title,
173
- .mint-topbar-subtitle {
173
+ .mint-topbar-subtitle,
174
+ .mint-topbar__title-only {
174
175
  overflow: hidden;
175
176
  text-overflow: ellipsis;
176
177
  white-space: nowrap;