@morscherlab/mint-sdk 1.3.0-beta.3 → 1.3.0-beta.5

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 (113) hide show
  1. package/README.md +23 -140
  2. package/dist/{ResourcePickerListInternal-c3IT8PIu.js → ResourcePickerListInternal-BEXnyBNz.js} +7 -3
  3. package/dist/ResourcePickerListInternal-BEXnyBNz.js.map +1 -0
  4. package/dist/components/FilePicker.vue.d.ts +4 -1
  5. package/dist/components/WellPlate.colors.d.ts +1 -5
  6. package/dist/components/WellPlate.rendering.d.ts +5 -2
  7. package/dist/components/index.d.ts +32 -17
  8. package/dist/components/index.js +3 -3
  9. package/dist/components/internal/FilePickerListInternal.vue.d.ts +2 -0
  10. package/dist/{components-CvY105kJ.js → components-BTzcqrJp.js} +400 -358
  11. package/dist/components-BTzcqrJp.js.map +1 -0
  12. package/dist/composables/createFilePickerAdapter.d.ts +5 -1
  13. package/dist/composables/filePicker/usePickerNavigation.d.ts +3 -2
  14. package/dist/composables/index.d.ts +0 -3
  15. package/dist/composables/index.js +4 -4
  16. package/dist/composables/useAutoGroup.d.ts +1 -1
  17. package/dist/composables/useBioTemplateComponents.d.ts +15 -3
  18. package/dist/composables/useBioTemplateControls.d.ts +5 -1
  19. package/dist/composables/useBioTemplatePackWorkspace.d.ts +2 -0
  20. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +5 -1
  21. package/dist/composables/useBioTemplateWorkspace.d.ts +5 -1
  22. package/dist/composables/useExperimentSave.d.ts +5 -1
  23. package/dist/composables/useFilePicker.d.ts +4 -1
  24. package/dist/composables/useGroupAssignment.d.ts +5 -1
  25. package/dist/composables/useTemplateCollection.d.ts +5 -1
  26. package/dist/composables-Doqb7g1z.js +591 -0
  27. package/dist/composables-Doqb7g1z.js.map +1 -0
  28. package/dist/index.js +24 -24
  29. package/dist/index.js.map +1 -1
  30. package/dist/install.js +1 -1
  31. package/dist/lcms.d.ts +11 -11
  32. package/dist/styles.css +60 -89
  33. package/dist/templates/index.js +1 -1
  34. package/dist/{templates-Bj9hZ7iV.js → templates-DgAG5kMq.js} +2 -2
  35. package/dist/{templates-Bj9hZ7iV.js.map → templates-DgAG5kMq.js.map} +1 -1
  36. package/dist/types/auth.d.ts +0 -27
  37. package/dist/types/components.d.ts +4 -0
  38. package/dist/types/fileBrowserTypes.d.ts +13 -0
  39. package/dist/types/filePicker.d.ts +8 -1
  40. package/dist/types/index.d.ts +2 -2
  41. package/dist/utils/rack.d.ts +16 -16
  42. package/dist/{validation-B4Y8_eEe.js → validation-DILksa0c.js} +50 -12
  43. package/dist/validation-DILksa0c.js.map +1 -0
  44. package/package.json +1 -6
  45. package/src/__tests__/components/ActionMenu.test.ts +10 -0
  46. package/src/__tests__/components/AppTopBar.test.ts +16 -8
  47. package/src/__tests__/components/EmptyState.test.ts +15 -0
  48. package/src/__tests__/components/FilePicker.test.ts +65 -1
  49. package/src/__tests__/components/WellPlate.decoration.test.ts +4 -28
  50. package/src/__tests__/components/WellPlate.rendering.test.ts +20 -33
  51. package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +7 -7
  52. package/src/__tests__/composables/createFilePickerAdapter.test.ts +92 -1
  53. package/src/__tests__/composables/usePickerNavigation.test.ts +61 -1
  54. package/src/__tests__/composables/usePlatformFilePickerAdapter.test.ts +18 -6
  55. package/src/__tests__/docs/frontendDocsCatalog.test.ts +2 -2
  56. package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
  57. package/src/__tests__/styles/menusShellRefresh.test.ts +8 -2
  58. package/src/__tests__/templates/templatesDeprecation.test.ts +51 -11
  59. package/src/components/ActionMenu.vue +10 -2
  60. package/src/components/AppTopBar.vue +2 -4
  61. package/src/components/EmptyState.vue +3 -1
  62. package/src/components/FilePicker.vue +42 -0
  63. package/src/components/WellPlate.colors.ts +6 -10
  64. package/src/components/WellPlate.legend.ts +4 -4
  65. package/src/components/WellPlate.rendering.ts +9 -8
  66. package/src/components/WellPlate.vue +5 -22
  67. package/src/components/index.ts +32 -17
  68. package/src/components/internal/FilePickerListInternal.vue +11 -2
  69. package/src/composables/autoGroup/index.ts +1 -1
  70. package/src/composables/createFilePickerAdapter.ts +82 -22
  71. package/src/composables/filePicker/usePickerNavigation.ts +29 -2
  72. package/src/composables/index.ts +0 -7
  73. package/src/composables/useAutoGroup.ts +1 -1
  74. package/src/composables/useBioTemplateComponents.ts +15 -3
  75. package/src/composables/useBioTemplateControls.ts +5 -1
  76. package/src/composables/useBioTemplatePackWorkspace.ts +2 -0
  77. package/src/composables/useBioTemplatePresetWorkspace.ts +5 -1
  78. package/src/composables/useBioTemplateWorkspace.ts +5 -1
  79. package/src/composables/useExperimentSave.ts +5 -1
  80. package/src/composables/useFilePicker.ts +8 -1
  81. package/src/composables/useGroupAssignment.ts +5 -1
  82. package/src/composables/usePlatformFilePickerAdapter.ts +26 -4
  83. package/src/composables/useTemplateCollection.ts +5 -1
  84. package/src/index.ts +1 -1
  85. package/src/lcms.ts +11 -11
  86. package/src/styles/components/action-menu.css +10 -0
  87. package/src/styles/components/app-top-bar.css +7 -31
  88. package/src/styles/components/empty-state.css +3 -2
  89. package/src/styles/components/file-picker.css +23 -1
  90. package/src/styles/components/well-plate.css +18 -55
  91. package/src/types/auth.ts +0 -37
  92. package/src/types/components.ts +4 -0
  93. package/src/types/fileBrowserTypes.ts +15 -0
  94. package/src/types/filePicker.ts +8 -1
  95. package/src/types/index.ts +2 -5
  96. package/src/utils/rack.ts +16 -16
  97. package/dist/ResourcePickerListInternal-c3IT8PIu.js.map +0 -1
  98. package/dist/__tests__/composables/useAuth.test.d.ts +0 -1
  99. package/dist/__tests__/composables/usePasskey.test.d.ts +0 -1
  100. package/dist/components-CvY105kJ.js.map +0 -1
  101. package/dist/composables/useAuth.d.ts +0 -47
  102. package/dist/composables/usePasskey.d.ts +0 -10
  103. package/dist/composables/useWellPlateEditor.d.ts +0 -33
  104. package/dist/composables-DL4Vca7L.js +0 -1193
  105. package/dist/composables-DL4Vca7L.js.map +0 -1
  106. package/dist/plotly.min-D6Ge6qgX.js +0 -168582
  107. package/dist/plotly.min-D6Ge6qgX.js.map +0 -1
  108. package/dist/validation-B4Y8_eEe.js.map +0 -1
  109. package/src/__tests__/composables/useAuth.test.ts +0 -290
  110. package/src/__tests__/composables/usePasskey.test.ts +0 -38
  111. package/src/composables/useAuth.ts +0 -470
  112. package/src/composables/usePasskey.ts +0 -216
  113. package/src/composables/useWellPlateEditor.ts +0 -415
package/README.md CHANGED
@@ -59,17 +59,13 @@ export default {
59
59
  ```vue
60
60
  <script setup lang="ts">
61
61
  import { BaseButton, BaseInput, FormField } from '@morscherlab/mint-sdk'
62
- import { useToast, useAuth } from '@morscherlab/mint-sdk'
62
+ import { useToast } from '@morscherlab/mint-sdk'
63
63
  import type { ButtonVariant } from '@morscherlab/mint-sdk'
64
64
 
65
65
  const { success } = useToast()
66
- const { login } = useAuth()
67
66
 
68
- async function handleSubmit() {
69
- const result = await login(username, password)
70
- if (result) {
71
- success('Login successful!')
72
- }
67
+ function handleSubmit() {
68
+ success('Saved!')
73
69
  }
74
70
  </script>
75
71
 
@@ -79,7 +75,7 @@ async function handleSubmit() {
79
75
  </FormField>
80
76
 
81
77
  <BaseButton variant="primary" @click="handleSubmit">
82
- Login
78
+ Save
83
79
  </BaseButton>
84
80
  </template>
85
81
  ```
@@ -198,76 +194,16 @@ async function saveCurrentExperiment() {
198
194
  }
199
195
  ```
200
196
 
201
- ### 5. Use Biology Data Templates
197
+ ### 5. Biology Data Templates (deprecated)
202
198
 
203
- > Deprecated: the template catalogs leave the core SDK in MINT 1.4 and move to a
204
- > dedicated package or the owning plugins.
199
+ > Deprecated in MINT 1.3 and removed in 1.4, with no SDK replacement: the
200
+ > biology data templates (`@morscherlab/mint-sdk/templates`, `mint_sdk.templates`,
201
+ > `mint add data-template*`), the `BioTemplate*` views, the `useBioTemplate*`
202
+ > composables, `useTemplateCollection()`, `useExperimentSave()`, and the
203
+ > template-only components `ReagentList`, `ReagentEditor`, `ExperimentTimeline`,
204
+ > `SampleLegend` and `FitPanel`.
205
205
 
206
- Plugin frontends can import standard biology template builders and adapters instead of inventing ad-hoc JSON shapes:
207
-
208
- ```typescript
209
- import {
210
- createWellPlateScreenCollection,
211
- createTemplateCollection,
212
- createPlateMapTemplate,
213
- createSampleSheetTemplate,
214
- ensureTemplateFromCollection,
215
- listBioTemplateCatalog,
216
- listBioTemplatePresets,
217
- toPlateMapEditorState,
218
- toTemplateDataFrame,
219
- } from '@morscherlab/mint-sdk/templates'
220
-
221
- const catalog = listBioTemplateCatalog()
222
- const presets = listBioTemplatePresets()
223
- const template = createPlateMapTemplate({
224
- samples: ['Control', 'Treatment'],
225
- })
226
- const plateEditorState = toPlateMapEditorState(template)
227
-
228
- const sampleFrame = toTemplateDataFrame(createSampleSheetTemplate({
229
- samples: [{ sampleId: 'S001', name: 'Control 1' }],
230
- }))
231
- // <DataFrame v-bind="sampleFrame" />
232
-
233
- const collection = createTemplateCollection([template])
234
- const loadedPlate = ensureTemplateFromCollection(collection, 'plate-map')
235
-
236
- const screenCollection = createWellPlateScreenCollection({
237
- samples: ['Control', 'Treatment'],
238
- compounds: { 'Drug A': [10, 1, 0.1] },
239
- unit: 'uM',
240
- })
241
- ```
242
-
243
- For frontend wiring, `useBioTemplateWorkspace()` combines the generated
244
- controls, sidebar/forms, renderer props, and SDK component bindings:
245
-
246
- ```typescript
247
- import { useBioTemplateWorkspace } from '@morscherlab/mint-sdk'
248
- import { createWellPlateScreenCollection } from '@morscherlab/mint-sdk/templates'
249
-
250
- const collection = createWellPlateScreenCollection({
251
- samples: ['Control', 'Treatment'],
252
- compounds: { 'Drug A': [10, 1, 0.1] },
253
- })
254
- const workspace = useBioTemplateWorkspace(collection)
255
-
256
- // <AppSidebar v-bind="workspace.sidebar" />
257
- // <FormBuilder v-bind="workspace.form" />
258
- // <BioTemplateRenderer v-if="workspace.renderer" v-bind="workspace.renderer" />
259
- ```
260
-
261
- For editable built-in presets, `useBioTemplatePresetWorkspace()` also manages
262
- the generated control values, collection updates, and current-experiment save:
263
-
264
- ```typescript
265
- import { BioTemplatePresetWorkspaceView, useBioTemplatePresetWorkspace } from '@morscherlab/mint-sdk'
266
-
267
- const workspace = useBioTemplatePresetWorkspace('wellplate-screen')
268
-
269
- // <BioTemplatePresetWorkspaceView :workspace="workspace" />
270
- ```
206
+ ### 6. Build Control Workspaces
271
207
 
272
208
  For custom plugin tools, pass one workspace model to `ControlWorkspaceView` to
273
209
  generate `AppTopBar`, `AppSidebar`, `FormBuilder`, component prop bindings, and
@@ -328,26 +264,6 @@ const workspaceModel = defineDoseDesignControlModel({
328
264
  </template>
329
265
  ```
330
266
 
331
- Built-in templates include `plate-map`, `sample-sheet`, `sample-prep`,
332
- `dose-response`, `calibration-curve`, `time-course`, `protocol-steps`, `assay-matrix`,
333
- `reagent-list`, `flow-cytometry-panel`, `instrument-run`, and `qpcr-plate`. In
334
- plugin projects, `mint add data-template <name> --page` generates the
335
- matching backend route, typed frontend composable, and starter view.
336
- Generated composables use `ensureTemplateEnvelope()` to validate backend
337
- template payloads before assigning typed frontend state. Use
338
- `createTemplateCollection()`, `extractTemplateCollection()`, and
339
- `ensureTemplateFromCollection()` when a plugin view reads or writes the shared
340
- `design_data.templates` layout. `mint add data-template-pack <name> --page`
341
- generates a pack-level composable that uses these helpers for curated
342
- experiment scaffolds.
343
- Use `mint add data-template-pack <name> --page` for curated sets such as
344
- `cell-culture-screen`, `omics-assay`, `longitudinal-study`, and
345
- `molecular-assay`.
346
- For no-scaffold defaults that can be saved directly to `design_data`, use
347
- template presets such as `createWellPlateScreenCollection()`,
348
- `createQpcrExpressionCollection()`, `createLcmsBatchCollection()`, and
349
- `createWesternBlotAssayCollection()`.
350
-
351
267
  ## Components
352
268
 
353
269
  ### Base Components
@@ -379,19 +295,15 @@ not define its own input, select, textarea, unit or button looks.
379
295
  - `AppTopBar` - Application header with slots
380
296
  - `AppSidebar` - Context sidebar that accepts panels/forms or a compact `controls` schema
381
297
 
382
- ### Biological Template Components
383
- - `BioTemplateRenderer` - Render template envelopes or collections with matching SDK components
384
- - `BioTemplateExperimentWorkspaceView` - Current-experiment load/save/reset workspace for one template or collection
385
- - `BioTemplatePresetWorkspaceView` - Full editable preset workspace from `useBioTemplatePresetWorkspace()`
386
-
387
298
  ### File & Data Components
388
299
  - `FileUploader` - Drag-and-drop file upload with file/folder mode support
389
300
 
390
301
  ### Sample Management Components
391
- - `SampleSelector` - Hierarchical sample grouping with auto-group, CSV metadata import, and optional experiment `design_data` sample loading
392
- - `SmartGroupModal` - Smart Group auto Field Recipe and manual cohort builder
393
- - `AutoGroupModal` - Deprecated, removed from the public exports in MINT 1.4; use `SmartGroupModal`. `SampleSelector` keeps its built-in auto-group flow
394
- - `GroupAssigner` - Drag-and-drop group assignment for comparisons (e.g., Control vs Treatment)
302
+
303
+ Deprecated in MINT 1.3 and removed in 1.4, with no SDK replacement: sample
304
+ grouping as a whole (`SampleSelector`, `SmartGroupModal`,
305
+ `SmartGroupFieldRecipe`, `SmartGroupManual`, `AutoGroupModal`,
306
+ `useAutoGroup`, `GroupAssigner`, `useGroupAssignment`).
395
307
 
396
308
  ### Removed Compatibility APIs
397
309
 
@@ -399,7 +311,7 @@ The public SDK no longer exports `ToastNotification`, `GroupingModal`,
399
311
  `SettingsButton`, `FormSection`, `FormFieldRenderer`, `usePluginApi()`, or
400
312
  `usePluginConfig()`. The identity-only `usePluginClient()` and the legacy
401
313
  `useJobsStatusTray()` job adapter API remain deprecated until MINT 1.4.
402
- Use `AppToastContainer`, `SmartGroupModal`, `AppTopBar` settings or
314
+ Use `AppToastContainer`, `AppTopBar` settings or
403
315
  `SettingsModal`, `FormBuilder`, `usePluginSettings()`, generated
404
316
  `useGeneratedPluginClient()` helpers, and source-driven `usePluginJobCenter()`
405
317
  instead.
@@ -409,10 +321,11 @@ MINT 1.3 also removed `ColorSlider` (pass `colorStops`, `thresholds`,
409
321
  (`BaseSelect` or `SearchableSelect` for values, `ActionMenu` for actions),
410
322
  `InstrumentAlertLog`, `InstrumentStatusCard`, `LcmsSequenceTable`, `useAsync()`,
411
323
  `useOptimisticMutation()` (use `useRequestSyncState()`), `useResourceCrud()`
412
- (use `useGeneratedPluginClient()`), `useCommandHistory()`, `useWellPainting()`,
413
- `useWellPlateAdapter()` and `useWellPlateValidation()` (use
414
- `useWellPlateEditor()`). `mint doctor` still detects old imports and reports the
415
- replacement path.
324
+ (use `useGeneratedPluginClient()`), `useCommandHistory()`,
325
+ `useWellPlateAdapter()`, `useWellPlateValidation()` (no SDK replacement; keep
326
+ them in the plugin), `useWellPainting()` and `useWellPlateEditor()` (use
327
+ `useRackEditor()` with `PlateEditor`). `mint doctor` still detects old imports
328
+ and reports the replacement path.
416
329
 
417
330
  MINT 1.3 removed `AppPluginSwitcher` and its `PluginSwitcherPlugin` /
418
331
  `PluginSwitcherInfo` types, with the `pluginSwitcher` prop and
@@ -545,35 +458,6 @@ callers can present a single sign-in prompt without risking duplicate writes.
545
458
  Clients created with `withAuth: false` retain their existing auth state and
546
459
  receive the original HTTP error.
547
460
 
548
- ### `useAuth()`
549
- Authentication methods.
550
-
551
- ```typescript
552
- const { login, logout, initializeAuth, getCurrentUser } = useAuth()
553
-
554
- // Initialize on app mount
555
- await initializeAuth()
556
-
557
- // Login
558
- const success = await login(username, password)
559
-
560
- // Get current user
561
- const user = await getCurrentUser()
562
- ```
563
-
564
- ### `usePasskey()`
565
- WebAuthn/FIDO2 passkey support.
566
-
567
- ```typescript
568
- const { isSupported, registerPasskey, loginWithPasskey } = usePasskey()
569
-
570
- if (isSupported()) {
571
- await registerPasskey('My Device')
572
- // or
573
- await loginWithPasskey()
574
- }
575
- ```
576
-
577
461
  ### `useTheme()`
578
462
  Theme switching.
579
463
 
@@ -676,7 +560,6 @@ import type {
676
560
  // Auth
677
561
  AuthConfig,
678
562
  UserInfo,
679
- LoginResponse,
680
563
 
681
564
  // Platform
682
565
  PluginInfo,
@@ -272,6 +272,10 @@ var _hoisted_5$1 = {
272
272
  class: "mint-empty-state__description"
273
273
  };
274
274
  var _hoisted_6$1 = {
275
+ key: 2,
276
+ class: "mint-empty-state__content"
277
+ };
278
+ var _hoisted_7$1 = {
275
279
  key: 0,
276
280
  class: "mint-empty-state__action"
277
281
  };
@@ -324,9 +328,9 @@ var EmptyState_default = /* @__PURE__ */ defineComponent({
324
328
  createElementVNode("div", _hoisted_3$1, [
325
329
  __props.title ? (openBlock(), createElementBlock("h3", _hoisted_4$1, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
326
330
  __props.description ? (openBlock(), createElementBlock("p", _hoisted_5$1, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
327
- renderSlot(_ctx.$slots, "default")
331
+ _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_6$1, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true)
328
332
  ]),
329
- __props.actionLabel ? (openBlock(), createElementBlock("div", _hoisted_6$1, [createVNode(BaseButton_default, {
333
+ __props.actionLabel ? (openBlock(), createElementBlock("div", _hoisted_7$1, [createVNode(BaseButton_default, {
330
334
  variant: "secondary",
331
335
  onClick: _cache[0] || (_cache[0] = ($event) => emit("action"))
332
336
  }, {
@@ -595,4 +599,4 @@ var ResourcePickerListInternal_default = /* @__PURE__ */ defineComponent({
595
599
  //#endregion
596
600
  export { normalizeOptionInput as a, BaseSelect_default as i, Skeleton_default as n, BaseInput_default as o, EmptyState_default as r, ResourcePickerListInternal_default as t };
597
601
 
598
- //# sourceMappingURL=ResourcePickerListInternal-c3IT8PIu.js.map
602
+ //# sourceMappingURL=ResourcePickerListInternal-BEXnyBNz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourcePickerListInternal-BEXnyBNz.js","names":["$slots","$slots"],"sources":["../src/components/BaseInput.vue","../src/components/BaseInput.vue","../src/utils/options.ts","../src/components/BaseSelect.vue","../src/components/BaseSelect.vue","../src/components/EmptyState.vue","../src/components/EmptyState.vue","../src/components/Skeleton.vue","../src/components/Skeleton.vue","../src/components/internal/ResourcePickerListInternal.vue","../src/components/internal/ResourcePickerListInternal.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Renders a styled `<input>` supporting text/number/email types, size, error, and readonly states.\n * Optional `#prefix` (bare leading glyph, e.g. a search icon) and `#suffix` (neutral unit segment) slots sit inside the field border.\n */\nimport { computed, useAttrs, useSlots, type StyleValue } from 'vue'\nimport type { InputType } from '../types'\n\ndefineOptions({ inheritAttrs: false })\n\ninterface Props {\n modelValue?: string | number\n type?: InputType\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n autocomplete?: string\n autofocus?: boolean\n min?: number\n max?: number\n step?: number\n list?: string\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'text',\n disabled: false,\n readonly: false,\n error: false,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number | null]\n focus: [event: FocusEvent]\n blur: [event: FocusEvent]\n keydown: [event: KeyboardEvent]\n}>()\n\ndefineSlots<{\n /** Leading glyph inside the field border (search icon, currency, …), no segment background. */\n prefix?: () => unknown\n /** Trailing segment inside the field border, e.g. a unit (mono 12px on `--bg-primary`). */\n suffix?: () => unknown\n}>()\n\nconst attrs = useAttrs()\nconst slots = useSlots()\nconst wrapped = computed(() => Boolean(slots.prefix || slots.suffix))\n\n/** Wrapped: class/style style the group, every other attribute (id, name, aria-*) stays on the input. */\nconst inputAttrs = computed(() => {\n if (!wrapped.value) return attrs\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nfunction handleInput(event: Event) {\n const target = event.target as HTMLInputElement\n const value = props.type === 'number'\n ? (target.value === '' ? null : Number(target.value))\n : target.value\n emit('update:modelValue', value as string | number)\n}\n</script>\n\n<template>\n <div\n v-if=\"wrapped\"\n :class=\"[\n 'mint-input-group',\n `mint-input-group--${size}`,\n error ? 'mint-input-group--error' : '',\n disabled ? 'mint-input-group--disabled' : '',\n attrs.class,\n ]\"\n :style=\"attrs.style as StyleValue\"\n >\n <span v-if=\"slots.prefix\" class=\"mint-input-group__prefix\"><slot name=\"prefix\" /></span>\n <input\n v-bind=\"inputAttrs\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :autocomplete=\"autocomplete\"\n :autofocus=\"autofocus\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :list=\"list\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"['mint-input', `mint-input--${size}`, 'mint-input-group__control']\"\n @input=\"handleInput\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @keydown=\"emit('keydown', $event)\"\n />\n <span v-if=\"slots.suffix\" class=\"mint-input-group__suffix\"><slot name=\"suffix\" /></span>\n </div>\n <input\n v-else\n v-bind=\"inputAttrs\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :autocomplete=\"autocomplete\"\n :autofocus=\"autofocus\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :list=\"list\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-input',\n `mint-input--${size}`,\n error ? 'mint-input--error' : '',\n disabled ? 'mint-input--disabled' : '',\n ]\"\n @input=\"handleInput\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @keydown=\"emit('keydown', $event)\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * Renders a styled `<input>` supporting text/number/email types, size, error, and readonly states.\n * Optional `#prefix` (bare leading glyph, e.g. a search icon) and `#suffix` (neutral unit segment) slots sit inside the field border.\n */\nimport { computed, useAttrs, useSlots, type StyleValue } from 'vue'\nimport type { InputType } from '../types'\n\ndefineOptions({ inheritAttrs: false })\n\ninterface Props {\n modelValue?: string | number\n type?: InputType\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n autocomplete?: string\n autofocus?: boolean\n min?: number\n max?: number\n step?: number\n list?: string\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'text',\n disabled: false,\n readonly: false,\n error: false,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number | null]\n focus: [event: FocusEvent]\n blur: [event: FocusEvent]\n keydown: [event: KeyboardEvent]\n}>()\n\ndefineSlots<{\n /** Leading glyph inside the field border (search icon, currency, …), no segment background. */\n prefix?: () => unknown\n /** Trailing segment inside the field border, e.g. a unit (mono 12px on `--bg-primary`). */\n suffix?: () => unknown\n}>()\n\nconst attrs = useAttrs()\nconst slots = useSlots()\nconst wrapped = computed(() => Boolean(slots.prefix || slots.suffix))\n\n/** Wrapped: class/style style the group, every other attribute (id, name, aria-*) stays on the input. */\nconst inputAttrs = computed(() => {\n if (!wrapped.value) return attrs\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nfunction handleInput(event: Event) {\n const target = event.target as HTMLInputElement\n const value = props.type === 'number'\n ? (target.value === '' ? null : Number(target.value))\n : target.value\n emit('update:modelValue', value as string | number)\n}\n</script>\n\n<template>\n <div\n v-if=\"wrapped\"\n :class=\"[\n 'mint-input-group',\n `mint-input-group--${size}`,\n error ? 'mint-input-group--error' : '',\n disabled ? 'mint-input-group--disabled' : '',\n attrs.class,\n ]\"\n :style=\"attrs.style as StyleValue\"\n >\n <span v-if=\"slots.prefix\" class=\"mint-input-group__prefix\"><slot name=\"prefix\" /></span>\n <input\n v-bind=\"inputAttrs\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :autocomplete=\"autocomplete\"\n :autofocus=\"autofocus\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :list=\"list\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"['mint-input', `mint-input--${size}`, 'mint-input-group__control']\"\n @input=\"handleInput\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @keydown=\"emit('keydown', $event)\"\n />\n <span v-if=\"slots.suffix\" class=\"mint-input-group__suffix\"><slot name=\"suffix\" /></span>\n </div>\n <input\n v-else\n v-bind=\"inputAttrs\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :autocomplete=\"autocomplete\"\n :autofocus=\"autofocus\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :list=\"list\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-input',\n `mint-input--${size}`,\n error ? 'mint-input--error' : '',\n disabled ? 'mint-input--disabled' : '',\n ]\"\n @input=\"handleInput\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @keydown=\"emit('keydown', $event)\"\n />\n</template>\n","export type OptionLike<TValue extends string | number> = {\n value: TValue\n label: string\n}\n\nexport function normalizeOptionInput<\n TValue extends string | number,\n TOption extends OptionLike<TValue>,\n>(option: TOption | TValue): TOption {\n if (typeof option === 'object') return option\n\n return {\n value: option,\n label: String(option),\n } as TOption\n}\n\nexport function findOptionByDomValue<\n TValue extends string | number,\n TOption extends OptionLike<TValue>,\n>(options: TOption[], value: string): TOption | undefined {\n return options.find(option => String(option.value) === value)\n}\n","<script setup lang=\"ts\">\n/** Renders a native `<select>` element with size, error, and disabled states. */\nimport { computed, useAttrs } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport type { SelectOption, SelectOptionInput } from '../types'\nimport { findOptionByDomValue, normalizeOptionInput } from '../utils/options'\n\ndefineOptions({ inheritAttrs: false })\n\ninterface Props {\n modelValue?: string | number\n options: SelectOptionInput<string | number>[]\n placeholder?: string\n disabled?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n error: false,\n size: 'md',\n})\nconst attrs = useAttrs()\n\nconst controlAttrs = computed(() => {\n const { class: _class, style: _style, ...nativeAttrs } = attrs\n return nativeAttrs\n})\nconst wrapperAttrs = computed<Pick<HTMLAttributes, 'class' | 'style'>>(() => ({\n class: attrs.class as HTMLAttributes['class'],\n style: attrs.style as HTMLAttributes['style'],\n}))\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n}>()\n\nconst normalizedOptions = computed<SelectOption<string | number>[]>(() =>\n props.options.map(normalizeOptionInput)\n)\n\nfunction handleChange(event: Event) {\n const target = event.target as HTMLSelectElement\n const option = findOptionByDomValue(normalizedOptions.value, target.value)\n emit('update:modelValue', option?.value ?? target.value)\n}\n</script>\n\n<template>\n <div v-bind=\"wrapperAttrs\" class=\"mint-select\">\n <select\n v-bind=\"controlAttrs\"\n :value=\"modelValue\"\n :disabled=\"disabled\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-select__control',\n `mint-select__control--${size}`,\n error ? 'mint-select__control--error' : '',\n disabled ? 'mint-select__control--disabled' : '',\n ]\"\n @change=\"handleChange\"\n >\n <option v-if=\"placeholder\" value=\"\" disabled>\n {{ placeholder }}\n </option>\n <option\n v-for=\"option in normalizedOptions\"\n :key=\"String(option.value)\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n <div class=\"mint-select__icon\">\n <svg fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Renders a native `<select>` element with size, error, and disabled states. */\nimport { computed, useAttrs } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport type { SelectOption, SelectOptionInput } from '../types'\nimport { findOptionByDomValue, normalizeOptionInput } from '../utils/options'\n\ndefineOptions({ inheritAttrs: false })\n\ninterface Props {\n modelValue?: string | number\n options: SelectOptionInput<string | number>[]\n placeholder?: string\n disabled?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n error: false,\n size: 'md',\n})\nconst attrs = useAttrs()\n\nconst controlAttrs = computed(() => {\n const { class: _class, style: _style, ...nativeAttrs } = attrs\n return nativeAttrs\n})\nconst wrapperAttrs = computed<Pick<HTMLAttributes, 'class' | 'style'>>(() => ({\n class: attrs.class as HTMLAttributes['class'],\n style: attrs.style as HTMLAttributes['style'],\n}))\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n}>()\n\nconst normalizedOptions = computed<SelectOption<string | number>[]>(() =>\n props.options.map(normalizeOptionInput)\n)\n\nfunction handleChange(event: Event) {\n const target = event.target as HTMLSelectElement\n const option = findOptionByDomValue(normalizedOptions.value, target.value)\n emit('update:modelValue', option?.value ?? target.value)\n}\n</script>\n\n<template>\n <div v-bind=\"wrapperAttrs\" class=\"mint-select\">\n <select\n v-bind=\"controlAttrs\"\n :value=\"modelValue\"\n :disabled=\"disabled\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-select__control',\n `mint-select__control--${size}`,\n error ? 'mint-select__control--error' : '',\n disabled ? 'mint-select__control--disabled' : '',\n ]\"\n @change=\"handleChange\"\n >\n <option v-if=\"placeholder\" value=\"\" disabled>\n {{ placeholder }}\n </option>\n <option\n v-for=\"option in normalizedOptions\"\n :key=\"String(option.value)\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n <div class=\"mint-select__icon\">\n <svg fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Empty-state placeholder with icon badge, headline, description, default slot, and optional CTA button. */\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n title?: string\n description?: string\n iconPath?: string\n color?: 'primary' | 'cta' | 'success' | 'warning' | 'error' | 'muted'\n size?: 'sm' | 'md' | 'lg'\n variant?: 'illustrated' | 'inline'\n actionLabel?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n color: 'primary',\n size: 'md',\n variant: 'illustrated',\n})\n\nconst emit = defineEmits<{\n action: []\n}>()\n\nconst defaultIconPaths = [\n 'M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z',\n 'M7 11h10',\n 'M7 15h6',\n 'M7 7h8',\n]\n</script>\n\n<template>\n <div :class=\"['mint-empty-state', `mint-empty-state--${variant}`, `mint-empty-state--${size}`]\">\n <div :class=\"['mint-empty-state__icon-wrapper', `mint-empty-state__icon-wrapper--${color}`]\">\n <slot name=\"icon\">\n <svg\n class=\"mint-empty-state__icon\"\n :class=\"`mint-empty-state__icon--${color}`\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <template v-if=\"iconPath\">\n <path :d=\"iconPath\" />\n </template>\n <template v-else>\n <path v-for=\"(d, i) in defaultIconPaths\" :key=\"i\" :d=\"d\" />\n </template>\n </svg>\n </slot>\n </div>\n <div class=\"mint-empty-state__body\">\n <h3 v-if=\"title\" class=\"mint-empty-state__title\">{{ title }}</h3>\n <p v-if=\"description\" class=\"mint-empty-state__description\">{{ description }}</p>\n <div v-if=\"$slots.default\" class=\"mint-empty-state__content\">\n <slot />\n </div>\n </div>\n <div v-if=\"actionLabel\" class=\"mint-empty-state__action\">\n <BaseButton variant=\"secondary\" @click=\"emit('action')\">\n {{ actionLabel }}\n </BaseButton>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Empty-state placeholder with icon badge, headline, description, default slot, and optional CTA button. */\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n title?: string\n description?: string\n iconPath?: string\n color?: 'primary' | 'cta' | 'success' | 'warning' | 'error' | 'muted'\n size?: 'sm' | 'md' | 'lg'\n variant?: 'illustrated' | 'inline'\n actionLabel?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n color: 'primary',\n size: 'md',\n variant: 'illustrated',\n})\n\nconst emit = defineEmits<{\n action: []\n}>()\n\nconst defaultIconPaths = [\n 'M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z',\n 'M7 11h10',\n 'M7 15h6',\n 'M7 7h8',\n]\n</script>\n\n<template>\n <div :class=\"['mint-empty-state', `mint-empty-state--${variant}`, `mint-empty-state--${size}`]\">\n <div :class=\"['mint-empty-state__icon-wrapper', `mint-empty-state__icon-wrapper--${color}`]\">\n <slot name=\"icon\">\n <svg\n class=\"mint-empty-state__icon\"\n :class=\"`mint-empty-state__icon--${color}`\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <template v-if=\"iconPath\">\n <path :d=\"iconPath\" />\n </template>\n <template v-else>\n <path v-for=\"(d, i) in defaultIconPaths\" :key=\"i\" :d=\"d\" />\n </template>\n </svg>\n </slot>\n </div>\n <div class=\"mint-empty-state__body\">\n <h3 v-if=\"title\" class=\"mint-empty-state__title\">{{ title }}</h3>\n <p v-if=\"description\" class=\"mint-empty-state__description\">{{ description }}</p>\n <div v-if=\"$slots.default\" class=\"mint-empty-state__content\">\n <slot />\n </div>\n </div>\n <div v-if=\"actionLabel\" class=\"mint-empty-state__action\">\n <BaseButton variant=\"secondary\" @click=\"emit('action')\">\n {{ actionLabel }}\n </BaseButton>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Animated loading placeholder in text, circular, rectangular, or rounded variants with pulse or wave animation. */\nimport { computed } from 'vue'\n\ninterface Props {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded'\n width?: string | number\n height?: string | number\n animation?: 'pulse' | 'wave' | 'none'\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'text',\n animation: 'wave',\n})\n\nconst style = computed(() => {\n const s: Record<string, string> = {}\n\n if (props.width) {\n s.width = typeof props.width === 'number' ? `${props.width}px` : props.width\n }\n\n if (props.height) {\n s.height = typeof props.height === 'number' ? `${props.height}px` : props.height\n }\n\n return s\n})\n\nconst classes = computed(() => [\n 'mint-skeleton',\n `mint-skeleton--${props.variant}`,\n // pulse and wave both breathe (3e); the shimmer is gone.\n props.animation === 'none' ? '' : 'skeleton-wave',\n])\n</script>\n\n<template>\n <div :class=\"classes\" :style=\"style\" />\n</template>\n","<script setup lang=\"ts\">\n/** Animated loading placeholder in text, circular, rectangular, or rounded variants with pulse or wave animation. */\nimport { computed } from 'vue'\n\ninterface Props {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded'\n width?: string | number\n height?: string | number\n animation?: 'pulse' | 'wave' | 'none'\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'text',\n animation: 'wave',\n})\n\nconst style = computed(() => {\n const s: Record<string, string> = {}\n\n if (props.width) {\n s.width = typeof props.width === 'number' ? `${props.width}px` : props.width\n }\n\n if (props.height) {\n s.height = typeof props.height === 'number' ? `${props.height}px` : props.height\n }\n\n return s\n})\n\nconst classes = computed(() => [\n 'mint-skeleton',\n `mint-skeleton--${props.variant}`,\n // pulse and wave both breathe (3e); the shimmer is gone.\n props.animation === 'none' ? '' : 'skeleton-wave',\n])\n</script>\n\n<template>\n <div :class=\"classes\" :style=\"style\" />\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\n/**\n * Searchable, optionally grouped single-select list shared by the experiment and\n * artifact selector modals (8b): 44px two-line rows, trailing check, skeleton,\n * error and empty states, and the combobox keyboard model (↑ ↓ Enter).\n */\nimport { computed, nextTick, reactive, ref, useId, watch } from 'vue'\nimport BaseInput from '../BaseInput.vue'\nimport Skeleton from '../Skeleton.vue'\nimport EmptyState from '../EmptyState.vue'\n\nexport interface ResourcePickerRow {\n /** Identifier shown in mono before the title, e.g. an experiment code. */\n code?: string\n title: string\n /** Second-line facts, joined with \" · \". */\n meta?: string[]\n /** Rendered last on the second line, in mono. */\n date?: string\n}\n\nconst props = withDefaults(\n defineProps<{\n items: T[]\n /** When set, rows render under collapsible group headers in this order. */\n groups?: { label: string; items: T[] }[] | null\n itemKey: (item: T) => string | number\n describe: (item: T) => ResourcePickerRow\n selectedKey?: string | number | null\n search: string\n /** Accessible name of the list; the search field is labelled \"Search {label}\". */\n label: string\n placeholder?: string\n loading?: boolean\n error?: string | null\n emptyTitle?: string\n emptyDescription?: string\n }>(),\n {\n groups: null,\n selectedKey: null,\n placeholder: 'Search…',\n loading: false,\n error: null,\n emptyTitle: 'Nothing found',\n emptyDescription: 'Try adjusting your search or filters.',\n },\n)\nconst emit = defineEmits<{\n select: [item: T]\n 'update:search': [value: string]\n}>()\ndefineSlots<{\n /** Extra filters on the search row. */\n filters?: () => unknown\n /** A second filter row under the search. */\n advanced?: () => unknown\n /** Row controls before the check; keys pressed inside them never select the row. */\n actions?: (props: { item: T }) => unknown\n}>()\n\nconst listId = `mint-resource-picker-${useId().replace(/:/g, '')}`\nconst collapsed = reactive(new Set<string>())\nconst activeIndex = ref(-1)\nconst listRef = ref<HTMLElement | null>(null)\n\nconst visibleGroups = computed(() =>\n props.groups?.map((group) => ({\n ...group,\n rows: collapsed.has(group.label) ? [] : group.items,\n })),\n)\n/** Keyboard order: the rows on screen, top to bottom. */\nconst flat = computed(() =>\n visibleGroups.value ? visibleGroups.value.flatMap((group) => group.rows) : props.items,\n)\nconst indexByKey = computed(() => new Map(flat.value.map((item, i) => [props.itemKey(item), i])))\nconst showList = computed(() => !props.loading && !props.error && props.items.length > 0)\n\nfunction optionId(item: T): string {\n return `${listId}-${props.itemKey(item)}`\n}\nconst activeDescendant = computed(() => {\n const item = flat.value[activeIndex.value]\n return item === undefined ? undefined : optionId(item)\n})\n\nfunction indexOf(item: T): number {\n return indexByKey.value.get(props.itemKey(item)) ?? -1\n}\nfunction toggleGroup(label: string) {\n if (collapsed.has(label)) collapsed.delete(label)\n else collapsed.add(label)\n}\nfunction keydown(event: KeyboardEvent) {\n // Keys belong to the search combobox; a focused header, filter or row action keeps its own Enter.\n const target = event.target as HTMLElement | null\n if (target !== event.currentTarget && !target?.closest('.mint-resource-picker__search')) return\n const rows = flat.value\n if (!rows.length) return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n activeIndex.value =\n event.key === 'ArrowDown'\n ? Math.min(activeIndex.value + 1, rows.length - 1)\n : Math.max(activeIndex.value - 1, 0)\n nextTick(() =>\n listRef.value\n ?.querySelector('.mint-resource-picker__row--active')\n ?.scrollIntoView({ block: 'nearest' }),\n )\n } else if (event.key === 'Enter' && rows[activeIndex.value] !== undefined) {\n event.preventDefault()\n emit('select', rows[activeIndex.value]!)\n }\n}\n\nwatch(\n () => [props.items, props.groups],\n () => {\n activeIndex.value = -1\n },\n)\n</script>\n\n<template>\n <div class=\"mint-resource-picker\" @keydown=\"keydown\">\n <div class=\"mint-resource-picker__toolbar\">\n <BaseInput\n class=\"mint-resource-picker__search\"\n :model-value=\"search\"\n :placeholder=\"placeholder\"\n size=\"sm\"\n type=\"search\"\n role=\"combobox\"\n :aria-label=\"`Search ${label.toLowerCase()}`\"\n :aria-expanded=\"showList\"\n :aria-controls=\"listId\"\n :aria-activedescendant=\"activeDescendant\"\n @update:model-value=\"emit('update:search', String($event ?? ''))\"\n >\n <template #prefix>\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" aria-hidden=\"true\">\n <path d=\"M7 11.5a4.5 4.5 0 1 1 0-9 4.5 4.5 0 0 1 0 9zM10.5 10.5L14 14\" />\n </svg>\n </template>\n </BaseInput>\n <slot name=\"filters\" />\n </div>\n <slot name=\"advanced\" />\n\n <div v-if=\"loading\" class=\"mint-resource-picker__frame\" aria-busy=\"true\">\n <div v-for=\"n in 4\" :key=\"n\" class=\"mint-resource-picker__skeleton-row\">\n <Skeleton :width=\"`${40 + n * 10}%`\" height=\"0.75rem\" />\n <Skeleton width=\"30%\" height=\"0.625rem\" />\n </div>\n </div>\n <div v-else-if=\"error\" class=\"mint-resource-picker__error\" role=\"alert\">{{ error }}</div>\n <EmptyState\n v-else-if=\"!items.length\"\n :title=\"emptyTitle\"\n :description=\"emptyDescription\"\n size=\"sm\"\n />\n <div\n v-else\n :id=\"listId\"\n ref=\"listRef\"\n class=\"mint-resource-picker__frame mint-resource-picker__list\"\n role=\"listbox\"\n :aria-label=\"label\"\n >\n <template v-for=\"group in visibleGroups ?? [{ label: '', items, rows: items }]\" :key=\"group.label\">\n <button\n v-if=\"visibleGroups\"\n type=\"button\"\n class=\"mint-resource-picker__group\"\n :aria-expanded=\"!collapsed.has(group.label)\"\n @click=\"toggleGroup(group.label)\"\n >\n <svg\n class=\"mint-resource-picker__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6l4 4 4-4\" />\n </svg>\n <span class=\"mint-resource-picker__group-label\">{{ group.label }}</span>\n <span class=\"mint-resource-picker__group-count\">{{ group.items.length }}</span>\n </button>\n <div\n v-for=\"item in group.rows\"\n :id=\"optionId(item)\"\n :key=\"itemKey(item)\"\n role=\"option\"\n :aria-selected=\"itemKey(item) === selectedKey\"\n class=\"mint-resource-picker__row\"\n :class=\"{\n 'mint-resource-picker__row--selected': itemKey(item) === selectedKey,\n 'mint-resource-picker__row--active': indexOf(item) === activeIndex,\n }\"\n @click=\"emit('select', item)\"\n @mouseenter=\"activeIndex = indexOf(item)\"\n >\n <span class=\"mint-resource-picker__text\">\n <span class=\"mint-resource-picker__title\"\n ><template v-if=\"describe(item).code\"\n ><span class=\"mint-resource-picker__code\">{{ describe(item).code }}</span> · </template\n >{{ describe(item).title }}</span\n >\n <span\n v-if=\"describe(item).meta?.length || describe(item).date\"\n class=\"mint-resource-picker__meta\"\n >{{ [...(describe(item).meta ?? [])].join(' · ')\n }}<template v-if=\"describe(item).date\"\n >{{ describe(item).meta?.length ? ' · ' : ''\n }}<span class=\"mint-resource-picker__date\">{{ describe(item).date }}</span></template\n ></span\n >\n </span>\n <span v-if=\"$slots.actions\" class=\"mint-resource-picker__actions\" @click.stop>\n <slot name=\"actions\" :item=\"item\" />\n </span>\n <span class=\"mint-resource-picker__check-slot\" aria-hidden=\"true\">\n <svg\n v-if=\"itemKey(item) === selectedKey\"\n class=\"mint-resource-picker__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n </span>\n </div>\n </template>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\n/**\n * Searchable, optionally grouped single-select list shared by the experiment and\n * artifact selector modals (8b): 44px two-line rows, trailing check, skeleton,\n * error and empty states, and the combobox keyboard model (↑ ↓ Enter).\n */\nimport { computed, nextTick, reactive, ref, useId, watch } from 'vue'\nimport BaseInput from '../BaseInput.vue'\nimport Skeleton from '../Skeleton.vue'\nimport EmptyState from '../EmptyState.vue'\n\nexport interface ResourcePickerRow {\n /** Identifier shown in mono before the title, e.g. an experiment code. */\n code?: string\n title: string\n /** Second-line facts, joined with \" · \". */\n meta?: string[]\n /** Rendered last on the second line, in mono. */\n date?: string\n}\n\nconst props = withDefaults(\n defineProps<{\n items: T[]\n /** When set, rows render under collapsible group headers in this order. */\n groups?: { label: string; items: T[] }[] | null\n itemKey: (item: T) => string | number\n describe: (item: T) => ResourcePickerRow\n selectedKey?: string | number | null\n search: string\n /** Accessible name of the list; the search field is labelled \"Search {label}\". */\n label: string\n placeholder?: string\n loading?: boolean\n error?: string | null\n emptyTitle?: string\n emptyDescription?: string\n }>(),\n {\n groups: null,\n selectedKey: null,\n placeholder: 'Search…',\n loading: false,\n error: null,\n emptyTitle: 'Nothing found',\n emptyDescription: 'Try adjusting your search or filters.',\n },\n)\nconst emit = defineEmits<{\n select: [item: T]\n 'update:search': [value: string]\n}>()\ndefineSlots<{\n /** Extra filters on the search row. */\n filters?: () => unknown\n /** A second filter row under the search. */\n advanced?: () => unknown\n /** Row controls before the check; keys pressed inside them never select the row. */\n actions?: (props: { item: T }) => unknown\n}>()\n\nconst listId = `mint-resource-picker-${useId().replace(/:/g, '')}`\nconst collapsed = reactive(new Set<string>())\nconst activeIndex = ref(-1)\nconst listRef = ref<HTMLElement | null>(null)\n\nconst visibleGroups = computed(() =>\n props.groups?.map((group) => ({\n ...group,\n rows: collapsed.has(group.label) ? [] : group.items,\n })),\n)\n/** Keyboard order: the rows on screen, top to bottom. */\nconst flat = computed(() =>\n visibleGroups.value ? visibleGroups.value.flatMap((group) => group.rows) : props.items,\n)\nconst indexByKey = computed(() => new Map(flat.value.map((item, i) => [props.itemKey(item), i])))\nconst showList = computed(() => !props.loading && !props.error && props.items.length > 0)\n\nfunction optionId(item: T): string {\n return `${listId}-${props.itemKey(item)}`\n}\nconst activeDescendant = computed(() => {\n const item = flat.value[activeIndex.value]\n return item === undefined ? undefined : optionId(item)\n})\n\nfunction indexOf(item: T): number {\n return indexByKey.value.get(props.itemKey(item)) ?? -1\n}\nfunction toggleGroup(label: string) {\n if (collapsed.has(label)) collapsed.delete(label)\n else collapsed.add(label)\n}\nfunction keydown(event: KeyboardEvent) {\n // Keys belong to the search combobox; a focused header, filter or row action keeps its own Enter.\n const target = event.target as HTMLElement | null\n if (target !== event.currentTarget && !target?.closest('.mint-resource-picker__search')) return\n const rows = flat.value\n if (!rows.length) return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n activeIndex.value =\n event.key === 'ArrowDown'\n ? Math.min(activeIndex.value + 1, rows.length - 1)\n : Math.max(activeIndex.value - 1, 0)\n nextTick(() =>\n listRef.value\n ?.querySelector('.mint-resource-picker__row--active')\n ?.scrollIntoView({ block: 'nearest' }),\n )\n } else if (event.key === 'Enter' && rows[activeIndex.value] !== undefined) {\n event.preventDefault()\n emit('select', rows[activeIndex.value]!)\n }\n}\n\nwatch(\n () => [props.items, props.groups],\n () => {\n activeIndex.value = -1\n },\n)\n</script>\n\n<template>\n <div class=\"mint-resource-picker\" @keydown=\"keydown\">\n <div class=\"mint-resource-picker__toolbar\">\n <BaseInput\n class=\"mint-resource-picker__search\"\n :model-value=\"search\"\n :placeholder=\"placeholder\"\n size=\"sm\"\n type=\"search\"\n role=\"combobox\"\n :aria-label=\"`Search ${label.toLowerCase()}`\"\n :aria-expanded=\"showList\"\n :aria-controls=\"listId\"\n :aria-activedescendant=\"activeDescendant\"\n @update:model-value=\"emit('update:search', String($event ?? ''))\"\n >\n <template #prefix>\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" aria-hidden=\"true\">\n <path d=\"M7 11.5a4.5 4.5 0 1 1 0-9 4.5 4.5 0 0 1 0 9zM10.5 10.5L14 14\" />\n </svg>\n </template>\n </BaseInput>\n <slot name=\"filters\" />\n </div>\n <slot name=\"advanced\" />\n\n <div v-if=\"loading\" class=\"mint-resource-picker__frame\" aria-busy=\"true\">\n <div v-for=\"n in 4\" :key=\"n\" class=\"mint-resource-picker__skeleton-row\">\n <Skeleton :width=\"`${40 + n * 10}%`\" height=\"0.75rem\" />\n <Skeleton width=\"30%\" height=\"0.625rem\" />\n </div>\n </div>\n <div v-else-if=\"error\" class=\"mint-resource-picker__error\" role=\"alert\">{{ error }}</div>\n <EmptyState\n v-else-if=\"!items.length\"\n :title=\"emptyTitle\"\n :description=\"emptyDescription\"\n size=\"sm\"\n />\n <div\n v-else\n :id=\"listId\"\n ref=\"listRef\"\n class=\"mint-resource-picker__frame mint-resource-picker__list\"\n role=\"listbox\"\n :aria-label=\"label\"\n >\n <template v-for=\"group in visibleGroups ?? [{ label: '', items, rows: items }]\" :key=\"group.label\">\n <button\n v-if=\"visibleGroups\"\n type=\"button\"\n class=\"mint-resource-picker__group\"\n :aria-expanded=\"!collapsed.has(group.label)\"\n @click=\"toggleGroup(group.label)\"\n >\n <svg\n class=\"mint-resource-picker__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6l4 4 4-4\" />\n </svg>\n <span class=\"mint-resource-picker__group-label\">{{ group.label }}</span>\n <span class=\"mint-resource-picker__group-count\">{{ group.items.length }}</span>\n </button>\n <div\n v-for=\"item in group.rows\"\n :id=\"optionId(item)\"\n :key=\"itemKey(item)\"\n role=\"option\"\n :aria-selected=\"itemKey(item) === selectedKey\"\n class=\"mint-resource-picker__row\"\n :class=\"{\n 'mint-resource-picker__row--selected': itemKey(item) === selectedKey,\n 'mint-resource-picker__row--active': indexOf(item) === activeIndex,\n }\"\n @click=\"emit('select', item)\"\n @mouseenter=\"activeIndex = indexOf(item)\"\n >\n <span class=\"mint-resource-picker__text\">\n <span class=\"mint-resource-picker__title\"\n ><template v-if=\"describe(item).code\"\n ><span class=\"mint-resource-picker__code\">{{ describe(item).code }}</span> · </template\n >{{ describe(item).title }}</span\n >\n <span\n v-if=\"describe(item).meta?.length || describe(item).date\"\n class=\"mint-resource-picker__meta\"\n >{{ [...(describe(item).meta ?? [])].join(' · ')\n }}<template v-if=\"describe(item).date\"\n >{{ describe(item).meta?.length ? ' · ' : ''\n }}<span class=\"mint-resource-picker__date\">{{ describe(item).date }}</span></template\n ></span\n >\n </span>\n <span v-if=\"$slots.actions\" class=\"mint-resource-picker__actions\" @click.stop>\n <slot name=\"actions\" :item=\"item\" />\n </span>\n <span class=\"mint-resource-picker__check-slot\" aria-hidden=\"true\">\n <svg\n v-if=\"itemKey(item) === selectedKey\"\n class=\"mint-resource-picker__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n </span>\n </div>\n </template>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { PickerAdapter, PickerCapabilities, PickerNode, PickerSelection, PickerSelectionMode, PickerSource, PickerView } from '../types/filePicker';
1
+ import { PickerAdapter, PickerCapabilities, PickerNode, PickerSelection, PickerSelectionMode, PickerSort, PickerSource, PickerView } from '../types/filePicker';
2
2
  interface Props {
3
3
  open: boolean;
4
4
  adapter: PickerAdapter;
@@ -10,6 +10,8 @@ interface Props {
10
10
  title?: string;
11
11
  /** `list` shows one folder at a time; `tree` adds disclosure triangles. */
12
12
  view?: PickerView;
13
+ /** Row order on each open; the user can change it from the path bar until closing. */
14
+ defaultSort?: PickerSort;
13
15
  /** Host-owned visibility/selection filter; backend must still enforce access. */
14
16
  systemFilter?: (node: PickerNode, source: PickerSource) => boolean;
15
17
  }
@@ -29,6 +31,7 @@ declare const __VLS_export: import('vue').DefineComponent<Props, {}, {}, {}, {},
29
31
  capabilities: PickerCapabilities;
30
32
  initialPath: string;
31
33
  initialSelection: PickerSelection | null;
34
+ defaultSort: PickerSort;
32
35
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
33
36
  declare const _default: typeof __VLS_export;
34
37
  export default _default;
@@ -1,9 +1,5 @@
1
1
  import { HeatmapConfig } from '../types';
2
- /**
3
- * Group color for the built-in sample types when `sampleColors` has no entry.
4
- * Color encodes the group and shape encodes the type (3a): blank and QC render
5
- * neutral markers and ignore it; iQC takes it like a sample.
6
- */
2
+ /** Color for the built-in sample types when `sampleColors` has no entry. */
7
3
  export declare const DEFAULT_SAMPLE_TYPE_COLORS: Record<string, string>;
8
4
  export declare const HEATMAP_COLORS: Record<string, string[]>;
9
5
  export declare function conditionGradientStyle(color: string, concentration: number, concentrations: number[]): Record<string, string>;
@@ -16,8 +16,11 @@ export interface WellStyleState {
16
16
  }
17
17
  export declare function wellClasses(well: Well, state: WellClassState): string[];
18
18
  export declare function wellStyle(well: Well, state: WellStyleState): Record<string, string>;
19
- /** In-well glyph of the 3a sample-type marker: `Q` for QC, `i` for iQC. */
20
- export declare function sampleTypeGlyph(well: Well): string | null;
19
+ /** 15% fill and 40% outline of a sample color; color-mix accepts hex and `var()` tokens alike. */
20
+ export declare function sampleTint(color: string): {
21
+ backgroundColor: string;
22
+ border: string;
23
+ };
21
24
  /** One dev-only warning per page for the no-op `showSampleTypeIndicator` prop. */
22
25
  export declare function warnSampleTypeIndicatorDeprecated(): void;
23
26
  export declare function wellLabel(well: Well, showWellLabels: boolean): string | undefined;
@@ -39,7 +39,8 @@ export { default as GeneratedResultRenderer } from './GeneratedResultRenderer.vu
39
39
  export { default as GeneratedPlotlyResult } from './GeneratedPlotlyResult.vue';
40
40
  export { default as ComponentBindingRenderer } from './ComponentBindingRenderer.vue';
41
41
  export { default as ControlWorkspaceView } from './ControlWorkspaceView.vue';
42
- export { default as DoseDesignWorkspaceView } from './DoseDesignWorkspaceView.vue';
42
+ /** Complete ControlWorkspaceView page shell for WellPlate + DoseCalculator dose design. @deprecated Scheduled for removal in MINT 1.4; use `ControlWorkspaceView` instead, with `defineDoseDesignControlModel()`. */
43
+ export { /** @deprecated Removed in MINT 1.4. */ default as DoseDesignWorkspaceView } from './DoseDesignWorkspaceView.vue';
43
44
  export { default as AppContainer } from './AppContainer.vue';
44
45
  export { default as PluginIcon } from './PluginIcon.vue';
45
46
  export { default as LayoutResizeHandle } from './LayoutResizeHandle.vue';
@@ -56,26 +57,39 @@ export { default as ConfirmDialog } from './ConfirmDialog.vue';
56
57
  export { default as ChartContainer } from './ChartContainer.vue';
57
58
  export { default as AdductText } from './AdductText.vue';
58
59
  export { default as SettingsModal } from './SettingsModal.vue';
59
- export { default as BioTemplateRenderer } from './BioTemplateRenderer.vue';
60
- export { default as BioTemplateExperimentWorkspaceView } from './BioTemplateExperimentWorkspaceView.vue';
61
- export { default as BioTemplatePackWorkspaceView } from './BioTemplatePackWorkspaceView.vue';
62
- export { default as BioTemplatePresetWorkspaceView } from './BioTemplatePresetWorkspaceView.vue';
60
+ /** Render biology template envelopes with matching SDK components such as WellPlate, DoseCalculator, and DataFrame. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
61
+ export { /** @deprecated Removed in MINT 1.4. */ default as BioTemplateRenderer } from './BioTemplateRenderer.vue';
62
+ /** Current-experiment template workspace with load/save/reset controls and WellPlate/DataFrame/DoseCalculator previews. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
63
+ export { /** @deprecated Removed in MINT 1.4. */ default as BioTemplateExperimentWorkspaceView } from './BioTemplateExperimentWorkspaceView.vue';
64
+ /** Complete current-experiment workspace for a curated biology template pack with save/load controls and component-prop slots. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
65
+ export { /** @deprecated Removed in MINT 1.4. */ default as BioTemplatePackWorkspaceView } from './BioTemplatePackWorkspaceView.vue';
66
+ /** Complete editable biology template preset workspace for WellPlate/DoseCalculator, LC-MS, qPCR, generated controls, preview components, and current-experiment save wiring. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
67
+ export { /** @deprecated Removed in MINT 1.4. */ default as BioTemplatePresetWorkspaceView } from './BioTemplatePresetWorkspaceView.vue';
63
68
  export { default as WellPlate } from './WellPlate.vue';
64
69
  export { default as PlateEditor } from './PlateEditor.vue';
65
- export { default as SampleLegend } from './SampleLegend.vue';
66
- export { default as ExperimentTimeline } from './ExperimentTimeline.vue';
67
- export { default as SampleSelector } from './SampleSelector.vue';
68
- /** Smart Group modal wired to the `useAutoGroup` engine. @deprecated Scheduled for removal in MINT 1.4; use `SmartGroupModal` instead. */
69
- export { default as AutoGroupModal } from './AutoGroupModal.vue';
70
- export { default as GroupAssigner } from './GroupAssigner.vue';
71
- export { default as SmartGroupModal } from './SmartGroupModal.vue';
72
- export { default as SmartGroupFieldRecipe } from './SmartGroupFieldRecipe.vue';
73
- export { default as SmartGroupManual } from './SmartGroupManual.vue';
70
+ /** Clickable color-swatch legend for plate sample types, supporting selection, count display, add/remove, and custom color assignment. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
71
+ export { /** @deprecated Removed in MINT 1.4. */ default as SampleLegend } from './SampleLegend.vue';
72
+ /** Horizontal or vertical timeline of ordered protocol steps with status indicators, drag-to-reorder, and step-type iconography. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
73
+ export { /** @deprecated Removed in MINT 1.4. */ default as ExperimentTimeline } from './ExperimentTimeline.vue';
74
+ /** Interactive sample list with drag-and-drop group assignment, color labeling, and smart-group support. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
75
+ export { /** @deprecated Removed in MINT 1.4. */ default as SampleSelector } from './SampleSelector.vue';
76
+ /** Smart Group modal wired to the `useAutoGroup` engine. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
77
+ export { /** @deprecated Removed in MINT 1.4. */ default as AutoGroupModal } from './AutoGroupModal.vue';
78
+ /** Drag-and-drop two-zone assigner for splitting sample groups into control and treatment arms. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
79
+ export { /** @deprecated Removed in MINT 1.4. */ default as GroupAssigner } from './GroupAssigner.vue';
80
+ /** Smart Group modal with the auto Field Recipe and the manual cohort builder. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
81
+ export { /** @deprecated Removed in MINT 1.4. */ default as SmartGroupModal } from './SmartGroupModal.vue';
82
+ /** Smart Group auto mode: groups samples by a field recipe. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
83
+ export { /** @deprecated Removed in MINT 1.4. */ default as SmartGroupFieldRecipe } from './SmartGroupFieldRecipe.vue';
84
+ /** Smart Group manual mode: builds cohorts from selected samples. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
85
+ export { /** @deprecated Removed in MINT 1.4. */ default as SmartGroupManual } from './SmartGroupManual.vue';
74
86
  export { default as MoleculeInput } from './MoleculeInput.vue';
75
87
  export { default as ConcentrationInput } from './ConcentrationInput.vue';
76
88
  export { default as DoseCalculator } from './DoseCalculator.vue';
77
- export { default as ReagentEditor, type ReagentDefinition } from './ReagentEditor.vue';
78
- export { default as ReagentList } from './ReagentList.vue';
89
+ /** Editor for a single reagent definition with axis orientation, dilution-series generator, and position-count validation for 96/384-well plates. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
90
+ export { /** @deprecated Removed in MINT 1.4. */ default as ReagentEditor, type ReagentDefinition } from './ReagentEditor.vue';
91
+ /** Sortable, searchable table of experiment reagents showing lot number, expiry, storage conditions, and stock level with low-stock warnings. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
92
+ export { /** @deprecated Removed in MINT 1.4. */ default as ReagentList } from './ReagentList.vue';
79
93
  export { default as SampleHierarchyTree } from './SampleHierarchyTree.vue';
80
94
  export { default as ProtocolStepEditor } from './ProtocolStepEditor.vue';
81
95
  export { default as PlotlyChart } from './PlotlyChart.vue';
@@ -107,5 +121,6 @@ export { default as ArtifactSelectorModal } from './ArtifactSelectorModal.vue';
107
121
  export { default as GeneratedPathInput } from './GeneratedPathInput.vue';
108
122
  export { default as ArtifactSaveDialog } from './ArtifactSaveDialog.vue';
109
123
  export { default as ExperimentPopover } from './ExperimentPopover.vue';
110
- export { default as FitPanel } from './FitPanel.vue';
124
+ /** Control panel for running a curve-fit job with progress bar, results table, and error display. @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */
125
+ export { /** @deprecated Removed in MINT 1.4. */ default as FitPanel } from './FitPanel.vue';
111
126
  export { default as FilePicker } from './FilePicker.vue';
@@ -1,5 +1,5 @@
1
- import { $ as PlateEditor_default, A as SampleLegend_default, At as AppToastContainer_default, B as StatusIndicator_default, C as ChemicalFormula_default, Ct as AppAvatarMenu_default, D as ReagentEditor_default, Dt as ActionMenu_default, E as SampleHierarchyTree_default, Et as ThemeToggle_default, F as SettingsModal_default, Ft as Calendar_default, G as ControlWorkspaceView_default, H as LayoutResizeHandle_default, I as AdductText_default, It as BasePill_default, J as SampleSelector_default, K as ComponentBindingRenderer_default, L as Breadcrumb_default, Lt as SegmentedControl_default, M as BioTemplatePackWorkspaceView_default, Mt as FormField_default, N as BioTemplateExperimentWorkspaceView_default, Nt as DataFrame_default, O as SmartGroupModal_default, Ot as IconButton_default, P as BioTemplateRenderer_default, Pt as LoadingSpinner_default, Q as ReagentList_default, R as Avatar_default, Rt as BaseTabs_default, St as AppTopBar_default, T as ProtocolStepEditor_default, Tt as CollapsibleCard_default, U as AppContainer_default, V as Divider_default, W as DoseDesignWorkspaceView_default, X as SmartGroupManual_default, Y as AutoGroupModal_default, Z as SmartGroupFieldRecipe_default, _t as AppLayout_default, a as ArtifactSaveDialog_default, at as GeneratedPluginView_default, bt as FormActions_default, c as SectionCard_default, ct as GeneratedPlotlyResult_default, d as ExperimentCodeBadge_default, dt as ChartContainer_default, et as ConfirmDialog_default, f as ExperimentDataViewer_default, g as SequenceProgressBar_default, gt as MobileSupportGate_default, h as InstrumentStateBadge_default, ht as PluginWorkspaceView_default, i as ExperimentPopover_default, it as DoseCalculator_default, j as BioTemplatePresetWorkspaceView_default, jt as AlertBox_default, k as GroupAssigner_default, kt as RuntimeUpdateNotice_default, l as ResourceCard_default, lt as PlotlyChart_default, m as AuditTrail_default, n as FilePicker_default, o as ArtifactSelectorModal_default, ot as JobsStatusTray_default, p as BatchProgressList_default, q as ScheduleCalendar_default, r as FitPanel_default, rt as ExperimentTimeline_default, s as ExperimentSelectorModal_default, st as GeneratedResultRenderer_default, tt as WellPlate_default, u as TimeRangeInput_default, vt as AppSidebar_default, w as ScientificNumber_default, wt as PluginIcon_default, xt as StepWizard_default, yt as FormBuilder_default, z as ProgressBar_default, zt as SearchableSelect_default } from "../components-CvY105kJ.js";
1
+ import { $ as PlateEditor_default, A as SampleLegend_default, At as AppToastContainer_default, B as StatusIndicator_default, C as ChemicalFormula_default, Ct as AppAvatarMenu_default, D as ReagentEditor_default, Dt as ActionMenu_default, E as SampleHierarchyTree_default, Et as ThemeToggle_default, F as SettingsModal_default, Ft as Calendar_default, G as ControlWorkspaceView_default, H as LayoutResizeHandle_default, I as AdductText_default, It as BasePill_default, J as SampleSelector_default, K as ComponentBindingRenderer_default, L as Breadcrumb_default, Lt as SegmentedControl_default, M as BioTemplatePackWorkspaceView_default, Mt as FormField_default, N as BioTemplateExperimentWorkspaceView_default, Nt as DataFrame_default, O as SmartGroupModal_default, Ot as IconButton_default, P as BioTemplateRenderer_default, Pt as LoadingSpinner_default, Q as ReagentList_default, R as Avatar_default, Rt as BaseTabs_default, St as AppTopBar_default, T as ProtocolStepEditor_default, Tt as CollapsibleCard_default, U as AppContainer_default, V as Divider_default, W as DoseDesignWorkspaceView_default, X as SmartGroupManual_default, Y as AutoGroupModal_default, Z as SmartGroupFieldRecipe_default, _t as AppLayout_default, a as ArtifactSaveDialog_default, at as GeneratedPluginView_default, bt as FormActions_default, c as SectionCard_default, ct as GeneratedPlotlyResult_default, d as ExperimentCodeBadge_default, dt as ChartContainer_default, et as ConfirmDialog_default, f as ExperimentDataViewer_default, g as SequenceProgressBar_default, gt as MobileSupportGate_default, h as InstrumentStateBadge_default, ht as PluginWorkspaceView_default, i as ExperimentPopover_default, it as DoseCalculator_default, j as BioTemplatePresetWorkspaceView_default, jt as AlertBox_default, k as GroupAssigner_default, kt as RuntimeUpdateNotice_default, l as ResourceCard_default, lt as PlotlyChart_default, m as AuditTrail_default, n as FilePicker_default, o as ArtifactSelectorModal_default, ot as JobsStatusTray_default, p as BatchProgressList_default, q as ScheduleCalendar_default, r as FitPanel_default, rt as ExperimentTimeline_default, s as ExperimentSelectorModal_default, st as GeneratedResultRenderer_default, tt as WellPlate_default, u as TimeRangeInput_default, vt as AppSidebar_default, w as ScientificNumber_default, wt as PluginIcon_default, xt as StepWizard_default, yt as FormBuilder_default, z as ProgressBar_default, zt as SearchableSelect_default } from "../components-BTzcqrJp.js";
2
2
  import { f as BaseModal_default, h as BaseButton_default } from "../experiment-utils-DTANyVKV.js";
3
- import { i as BaseSelect_default, n as Skeleton_default, o as BaseInput_default, r as EmptyState_default } from "../ResourcePickerListInternal-c3IT8PIu.js";
4
- import { $n as FormulaInput_default, Cr as FileUploader_default, Jn as UnitInput_default, Rr as TagsInput_default, Tr as SecretInput_default, Xn as MoleculeInput_default, Zn as SequenceInput_default, ci as BaseRadioGroup_default, di as Tooltip_default, fi as BaseTextarea_default, ii as MultiSelect_default, li as BaseToggle_default, ni as DatePicker_default, nr as GeneratedPathInput_default, qn as ConcentrationInput_default, si as BaseSlider_default, ui as BaseCheckbox_default, wr as NumberInput_default, yr as DateTimePicker_default, zr as TimePicker_default } from "../templates-Bj9hZ7iV.js";
3
+ import { i as BaseSelect_default, n as Skeleton_default, o as BaseInput_default, r as EmptyState_default } from "../ResourcePickerListInternal-BEXnyBNz.js";
4
+ import { $n as FormulaInput_default, Cr as FileUploader_default, Jn as UnitInput_default, Rr as TagsInput_default, Tr as SecretInput_default, Xn as MoleculeInput_default, Zn as SequenceInput_default, ci as BaseRadioGroup_default, di as Tooltip_default, fi as BaseTextarea_default, ii as MultiSelect_default, li as BaseToggle_default, ni as DatePicker_default, nr as GeneratedPathInput_default, qn as ConcentrationInput_default, si as BaseSlider_default, ui as BaseCheckbox_default, wr as NumberInput_default, yr as DateTimePicker_default, zr as TimePicker_default } from "../templates-DgAG5kMq.js";
5
5
  export { ActionMenu_default as ActionMenu, AdductText_default as AdductText, AlertBox_default as AlertBox, AppAvatarMenu_default as AppAvatarMenu, AppContainer_default as AppContainer, AppLayout_default as AppLayout, AppSidebar_default as AppSidebar, AppToastContainer_default as AppToastContainer, AppTopBar_default as AppTopBar, ArtifactSaveDialog_default as ArtifactSaveDialog, ArtifactSelectorModal_default as ArtifactSelectorModal, AuditTrail_default as AuditTrail, AutoGroupModal_default as AutoGroupModal, Avatar_default as Avatar, BaseButton_default as BaseButton, BaseCheckbox_default as BaseCheckbox, BaseInput_default as BaseInput, BaseModal_default as BaseModal, BasePill_default as BasePill, BaseRadioGroup_default as BaseRadioGroup, BaseSelect_default as BaseSelect, BaseSlider_default as BaseSlider, BaseTabs_default as BaseTabs, BaseTextarea_default as BaseTextarea, BaseToggle_default as BaseToggle, BatchProgressList_default as BatchProgressList, BioTemplateExperimentWorkspaceView_default as BioTemplateExperimentWorkspaceView, BioTemplatePackWorkspaceView_default as BioTemplatePackWorkspaceView, BioTemplatePresetWorkspaceView_default as BioTemplatePresetWorkspaceView, BioTemplateRenderer_default as BioTemplateRenderer, Breadcrumb_default as Breadcrumb, Calendar_default as Calendar, ChartContainer_default as ChartContainer, ChemicalFormula_default as ChemicalFormula, CollapsibleCard_default as CollapsibleCard, ComponentBindingRenderer_default as ComponentBindingRenderer, ConcentrationInput_default as ConcentrationInput, ConfirmDialog_default as ConfirmDialog, ControlWorkspaceView_default as ControlWorkspaceView, DataFrame_default as DataFrame, DatePicker_default as DatePicker, DateTimePicker_default as DateTimePicker, Divider_default as Divider, DoseCalculator_default as DoseCalculator, DoseDesignWorkspaceView_default as DoseDesignWorkspaceView, EmptyState_default as EmptyState, ExperimentCodeBadge_default as ExperimentCodeBadge, ExperimentDataViewer_default as ExperimentDataViewer, ExperimentPopover_default as ExperimentPopover, ExperimentSelectorModal_default as ExperimentSelectorModal, ExperimentTimeline_default as ExperimentTimeline, FilePicker_default as FilePicker, FileUploader_default as FileUploader, FitPanel_default as FitPanel, FormActions_default as FormActions, FormBuilder_default as FormBuilder, FormField_default as FormField, FormulaInput_default as FormulaInput, GeneratedPathInput_default as GeneratedPathInput, GeneratedPlotlyResult_default as GeneratedPlotlyResult, GeneratedPluginView_default as GeneratedPluginView, GeneratedResultRenderer_default as GeneratedResultRenderer, GroupAssigner_default as GroupAssigner, IconButton_default as IconButton, InstrumentStateBadge_default as InstrumentStateBadge, JobsStatusTray_default as JobsStatusTray, LayoutResizeHandle_default as LayoutResizeHandle, LoadingSpinner_default as LoadingSpinner, MobileSupportGate_default as MobileSupportGate, MoleculeInput_default as MoleculeInput, MultiSelect_default as MultiSelect, NumberInput_default as NumberInput, PlateEditor_default as PlateEditor, PlotlyChart_default as PlotlyChart, PluginIcon_default as PluginIcon, PluginWorkspaceView_default as PluginWorkspaceView, ProgressBar_default as ProgressBar, ProtocolStepEditor_default as ProtocolStepEditor, ReagentEditor_default as ReagentEditor, ReagentList_default as ReagentList, ResourceCard_default as ResourceCard, RuntimeUpdateNotice_default as RuntimeUpdateNotice, SampleHierarchyTree_default as SampleHierarchyTree, SampleLegend_default as SampleLegend, SampleSelector_default as SampleSelector, ScheduleCalendar_default as ScheduleCalendar, ScientificNumber_default as ScientificNumber, SearchableSelect_default as SearchableSelect, SecretInput_default as SecretInput, SectionCard_default as SectionCard, SegmentedControl_default as SegmentedControl, SequenceInput_default as SequenceInput, SequenceProgressBar_default as SequenceProgressBar, SettingsModal_default as SettingsModal, Skeleton_default as Skeleton, SmartGroupFieldRecipe_default as SmartGroupFieldRecipe, SmartGroupManual_default as SmartGroupManual, SmartGroupModal_default as SmartGroupModal, StatusIndicator_default as StatusIndicator, StepWizard_default as StepWizard, TagsInput_default as TagsInput, ThemeToggle_default as ThemeToggle, TimePicker_default as TimePicker, TimeRangeInput_default as TimeRangeInput, Tooltip_default as Tooltip, UnitInput_default as UnitInput, WellPlate_default as WellPlate };
@@ -6,6 +6,8 @@ type __VLS_Props = {
6
6
  loading: boolean;
7
7
  error: string;
8
8
  query: string;
9
+ /** Search results stopped at a limit; the rows are the first matches only. */
10
+ truncated?: boolean;
9
11
  mode: PickerSelectionMode;
10
12
  selected: (node: PickerNode) => boolean;
11
13
  selectable: (node: PickerNode) => boolean;