@morscherlab/mint-sdk 1.4.0-beta.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -3
- package/dist/{ActionMenu-CScINahU.js → AlertBox-DwgNTEqf.js} +40 -209
- package/dist/AlertBox-DwgNTEqf.js.map +1 -0
- package/dist/{AppSidebar-BmiiPfz9.js → AppSidebar-CZZaxni0.js} +1249 -239
- package/dist/AppSidebar-CZZaxni0.js.map +1 -0
- package/dist/{ConfirmDialog-CJ7hqYUP.js → ConfirmDialog-CjWoxAD1.js} +2 -2
- package/dist/{ConfirmDialog-CJ7hqYUP.js.map → ConfirmDialog-CjWoxAD1.js.map} +1 -1
- package/dist/ExperimentPopover-DujiuQIO.js +337 -0
- package/dist/ExperimentPopover-DujiuQIO.js.map +1 -0
- package/dist/{ExperimentSelectorModal-D-9z7cNx.js → ExperimentSelectorModal-B4j4eUOJ.js} +244 -211
- package/dist/ExperimentSelectorModal-B4j4eUOJ.js.map +1 -0
- package/dist/{SegmentedControl-DERBN-Xd.js → SegmentedControl-DyUPH3I5.js} +2 -2
- package/dist/{SegmentedControl-DERBN-Xd.js.map → SegmentedControl-DyUPH3I5.js.map} +1 -1
- package/dist/{SettingsModal-CSLE31yg.js → SettingsModal-D2MOOtuO.js} +28 -27
- package/dist/SettingsModal-D2MOOtuO.js.map +1 -0
- package/dist/__stories__/experiment-helpers.d.ts +10 -0
- package/dist/__tests__/components/AppTopBarOnboarding.test.d.ts +1 -0
- package/dist/__tests__/components/FloatingPanelsInModal.test.d.ts +1 -0
- package/dist/__tests__/composables/useFloatingPanel.test.d.ts +1 -0
- package/dist/__tests__/composables/useOnboarding.test.d.ts +1 -0
- package/dist/__tests__/styles/paletteTokens.test.d.ts +1 -0
- package/dist/__tests__/styles/v2AuditRules.test.d.ts +1 -0
- package/dist/components/AppSidebar.vue.d.ts +1 -1
- package/dist/components/AppTopBar.vue.d.ts +20 -5
- package/dist/components/ArtifactSaveDialog.vue.d.ts +9 -1
- package/dist/components/AuditTrail.vue.d.ts +1 -1
- package/dist/components/BaseButton.vue.d.ts +4 -2
- package/dist/components/BaseSelect.vue.d.ts +2 -2
- package/dist/components/ChartContainer.vue.d.ts +2 -0
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/ExperimentPopover.vue.d.ts +18 -0
- package/dist/components/ExperimentSelectorModal.vue.d.ts +15 -5
- package/dist/components/FilePicker.vue.d.ts +1 -1
- package/dist/components/FileUploader.vue.d.ts +2 -2
- package/dist/components/JobsStatusTray.vue.d.ts +15 -4
- package/dist/components/PluginIcon.vue.d.ts +2 -2
- package/dist/components/PluginWorkspaceView.props.d.ts +3 -0
- package/dist/components/PluginWorkspaceView.vue.d.ts +3 -0
- package/dist/components/SampleSelector.vue.d.ts +6 -6
- package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
- package/dist/components/SmartGroupFieldRecipe.vue.d.ts +3 -3
- package/dist/components/StepWizard.vue.d.ts +3 -0
- package/dist/components/internal/AppTopBarOnboardingInternal.vue.d.ts +7 -0
- package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -1
- package/dist/components/internal/AutoGroupModalInternal.vue.d.ts +3 -3
- package/dist/components/internal/DatePickerTimeInternal.vue.d.ts +1 -1
- package/dist/components/internal/OnboardingLayerInternal.vue.d.ts +7 -0
- package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +2 -7
- package/dist/components/internal/SelectMultipleInternal.vue.d.ts +4 -0
- package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +8 -0
- package/dist/composables/createClient.d.ts +2 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/pluginIdentity.d.ts +24 -0
- package/dist/composables/pluginWorkspaceModel.d.ts +2 -2
- package/dist/composables/useAppExperiment.d.ts +8 -0
- package/dist/composables/useCalendarGrid.d.ts +1 -1
- package/dist/composables/useExperimentSelector.d.ts +6 -2
- package/dist/composables/useFileImport.d.ts +7 -0
- package/dist/composables/useFloatingPanel.d.ts +29 -0
- package/dist/composables/useJobCenter.d.ts +41 -3
- package/dist/composables/useOnboarding.d.ts +119 -0
- package/dist/composables/usePlatform.d.ts +1 -0
- package/dist/{controlSchemaModel-CP5-_nAj.js → controlSchemaModel-Bsg0t5Ab.js} +2 -2
- package/dist/{controlSchemaModel-CP5-_nAj.js.map → controlSchemaModel-Bsg0t5Ab.js.map} +1 -1
- package/dist/{data-C2PwI_dn.js → data-Boeh4uPI.js} +180 -125
- package/dist/data-Boeh4uPI.js.map +1 -0
- package/dist/data.d.ts +1 -1
- package/dist/data.js +9 -9
- package/dist/{experiment-43OJtH7R.js → experiment-DyO54FQB.js} +25 -61
- package/dist/experiment-DyO54FQB.js.map +1 -0
- package/dist/{experimentStatus-BZmU4czV.js → experimentStatus-DCn2QKG7.js} +3 -3
- package/dist/{experimentStatus-BZmU4czV.js.map → experimentStatus-DCn2QKG7.js.map} +1 -1
- package/dist/index.js +20 -20
- package/dist/{install-DAID6c2-.js → install-BEHp7Mo-.js} +15 -14
- package/dist/{install-DAID6c2-.js.map → install-BEHp7Mo-.js.map} +1 -1
- package/dist/install.js +1 -1
- package/dist/{lab-DLwRl_Ql.js → lab-D61eaX6f.js} +136 -148
- package/dist/lab-D61eaX6f.js.map +1 -0
- package/dist/lab.js +4 -3
- package/dist/{records-BzTcxekG.js → records-D4aQXyZu.js} +647 -389
- package/dist/records-D4aQXyZu.js.map +1 -0
- package/dist/{runtime-D6gVat6r.js → runtime-q-R0CNLh.js} +417 -54
- package/dist/runtime-q-R0CNLh.js.map +1 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +7 -7
- package/dist/{shell-5ju97nOS.js → shell-6CGFvUUw.js} +10 -5
- package/dist/{shell-5ju97nOS.js.map → shell-6CGFvUUw.js.map} +1 -1
- package/dist/shell.d.ts +1 -0
- package/dist/shell.js +6 -6
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +2 -2
- package/dist/stores/settings.d.ts +4 -12
- package/dist/styles.css +2753 -2101
- package/dist/types/componentWorkflowTypes.d.ts +2 -0
- package/dist/types/components.d.ts +2 -0
- package/dist/types/generated/platformContext.d.ts +1 -0
- package/dist/types/generated-ui.d.ts +4 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/jobs.d.ts +9 -0
- package/dist/types/platform.d.ts +1 -1
- package/dist/{BaseModal-DfRIuVoj.js → useDropdownState-uFIz6Yv8.js} +75 -5
- package/dist/useDropdownState-uFIz6Yv8.js.map +1 -0
- package/dist/{useExperimentSamples-CxcnxZ8h.js → useExperimentSamples-QEFoq4tf.js} +48 -6
- package/dist/useExperimentSamples-QEFoq4tf.js.map +1 -0
- package/dist/{useListReorder-CcbEYxX-.js → useListReorder-DsuzwWGS.js} +219 -437
- package/dist/useListReorder-DsuzwWGS.js.map +1 -0
- package/dist/{useRackEditor-BD5NIo5s.js → useRackEditor-KpZ4iJ6o.js} +85 -81
- package/dist/useRackEditor-KpZ4iJ6o.js.map +1 -0
- package/dist/useRealtime-B58Lo-Tm.js +508 -0
- package/dist/useRealtime-B58Lo-Tm.js.map +1 -0
- package/dist/useRequest-BuDmW8Jc.js +215 -0
- package/dist/useRequest-BuDmW8Jc.js.map +1 -0
- package/dist/utils/time.d.ts +7 -0
- package/package.json +3 -2
- package/src/__stories__/experiment-helpers.ts +3 -3
- package/src/__tests__/components/ActionMenu.test.ts +2 -2
- package/src/__tests__/components/AppTopBar.test.ts +257 -3
- package/src/__tests__/components/AppTopBarOnboarding.test.ts +160 -0
- package/src/__tests__/components/AppTopBarPageSelector.test.ts +125 -9
- package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
- package/src/__tests__/components/ArtifactSaveDialog.test.ts +78 -0
- package/src/__tests__/components/BaseButton.test.ts +19 -0
- package/src/__tests__/components/BaseModal.test.ts +13 -0
- package/src/__tests__/components/BaseSelect.multiple.test.ts +87 -32
- package/src/__tests__/components/BaseSelect.test.ts +2 -1
- package/src/__tests__/components/BatchProgressList.test.ts +16 -0
- package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
- package/src/__tests__/components/ChartContainer.test.ts +11 -0
- package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
- package/src/__tests__/components/DatePicker.datetime.test.ts +6 -0
- package/src/__tests__/components/DatePicker.test.ts +21 -0
- package/src/__tests__/components/DatePicker.time.test.ts +2 -2
- package/src/__tests__/components/EmptyState.test.ts +1 -1
- package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
- package/src/__tests__/components/ExperimentSelectorModal.test.ts +153 -14
- package/src/__tests__/components/FloatingPanelsInModal.test.ts +94 -0
- package/src/__tests__/components/GeneratedPluginView.test.ts +23 -2
- package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
- package/src/__tests__/components/JobsStatusTray.test.ts +373 -71
- package/src/__tests__/components/PluginWorkspaceView.test.ts +63 -1
- package/src/__tests__/components/ResourcePickerListInternal.test.ts +0 -20
- package/src/__tests__/components/SampleSelector.test.ts +33 -8
- package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
- package/src/__tests__/components/SettingsModal.test.ts +9 -2
- package/src/__tests__/components/StepWizard.test.ts +11 -0
- package/src/__tests__/components/WellPlate.decoration.test.ts +11 -4
- package/src/__tests__/components/deprecationTags.test.ts +1 -1
- package/src/__tests__/composables/useAppExperiment.test.ts +27 -1
- package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
- package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
- package/src/__tests__/composables/useFileImport.test.ts +36 -0
- package/src/__tests__/composables/useFloatingPanel.test.ts +68 -0
- package/src/__tests__/composables/useJobCenter.test.ts +262 -3
- package/src/__tests__/composables/useOnboarding.test.ts +317 -0
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +4 -3
- package/src/__tests__/fixtures/table-import/cells.xlsx +0 -0
- package/src/__tests__/fixtures/table-import/samples.xlsx +0 -0
- package/src/__tests__/stores/settings.test.ts +21 -21
- package/src/__tests__/styles/baseControlsRules.test.ts +6 -2
- package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
- package/src/__tests__/styles/cssTokens.test.ts +6 -3
- package/src/__tests__/styles/menusShellRefresh.test.ts +22 -12
- package/src/__tests__/styles/paletteTokens.test.ts +44 -0
- package/src/__tests__/styles/v2AuditRules.test.ts +104 -0
- package/src/__tests__/utils/plotlyTemplate.test.ts +4 -4
- package/src/__tests__/utils/time.test.ts +18 -1
- package/src/components/ActionMenu.vue +6 -37
- package/src/components/AdductText.story.vue +7 -0
- package/src/components/AdductText.vue +1 -1
- package/src/components/AlertBox.story.vue +2 -2
- package/src/components/AlertBox.vue +18 -16
- package/src/components/AppSidebar.story.vue +0 -28
- package/src/components/AppTopBar.onboarding.story.vue +69 -0
- package/src/components/AppTopBar.story.vue +105 -15
- package/src/components/AppTopBar.vue +248 -122
- package/src/components/ArtifactSaveDialog.story.vue +23 -0
- package/src/components/ArtifactSaveDialog.vue +102 -12
- package/src/components/AuditTrail.story.vue +2 -1
- package/src/components/AuditTrail.vue +2 -21
- package/src/components/Avatar.vue +10 -14
- package/src/components/BaseButton.vue +16 -2
- package/src/components/BaseModal.vue +2 -1
- package/src/components/BaseSelect.multiple.story.vue +13 -2
- package/src/components/BaseSelect.vue +4 -3
- package/src/components/BatchProgressList.vue +35 -25
- package/src/components/ChartContainer.story.vue +2 -1
- package/src/components/ChartContainer.vue +8 -6
- package/src/components/ConfirmDialog.story.vue +1 -1
- package/src/components/EmptyState.vue +1 -1
- package/src/components/ExperimentPopover.story.vue +165 -53
- package/src/components/ExperimentPopover.vue +169 -187
- package/src/components/ExperimentSelectorModal.story.vue +73 -31
- package/src/components/ExperimentSelectorModal.vue +144 -111
- package/src/components/FormField.story.vue +8 -48
- package/src/components/GeneratedPluginView.vue +11 -10
- package/src/components/GeneratedResultRenderer.vue +3 -4
- package/src/components/InstrumentStateBadge.vue +1 -1
- package/src/components/JobsStatusTray.story.vue +97 -43
- package/src/components/JobsStatusTray.vue +287 -290
- package/src/components/LayoutResizeHandle.story.vue +65 -4
- package/src/components/LoadingSpinner.vue +1 -1
- package/src/components/NumberInput.vue +3 -6
- package/src/components/PluginIcon.story.vue +2 -10
- package/src/components/PluginIcon.vue +2 -2
- package/src/components/PluginWorkspaceView.props.ts +3 -0
- package/src/components/PluginWorkspaceView.story.vue +1 -1
- package/src/components/PluginWorkspaceView.vue +17 -0
- package/src/components/RuntimeUpdateNotice.vue +1 -1
- package/src/components/SampleSelector.story.vue +22 -7
- package/src/components/SampleSelector.vue +34 -37
- package/src/components/SampleSelectorGroupNode.vue +1 -1
- package/src/components/SectionCard.story.vue +35 -2
- package/src/components/SequenceProgressBar.story.vue +9 -0
- package/src/components/SequenceProgressBar.vue +6 -1
- package/src/components/SettingsModal.schema.ts +1 -1
- package/src/components/SettingsModal.vue +9 -14
- package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
- package/src/components/SmartGroupManual.story.vue +1 -1
- package/src/components/StepWizard.story.vue +33 -0
- package/src/components/StepWizard.vue +8 -1
- package/src/components/Tooltip.vue +9 -32
- package/src/components/WellPlate.story.vue +3 -1
- package/src/components/WellPlate.vue +7 -0
- package/src/components/internal/AppTopBarOnboardingInternal.vue +172 -0
- package/src/components/internal/AppTopBarPageSelectorInternal.vue +140 -72
- package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
- package/src/components/internal/DatePickerDateInternal.vue +23 -85
- package/src/components/internal/DatePickerDateTimeInternal.vue +10 -14
- package/src/components/internal/DatePickerTimeInternal.vue +13 -9
- package/src/components/internal/NumberUnitInputInternal.vue +4 -18
- package/src/components/internal/OnboardingLayerInternal.vue +173 -0
- package/src/components/internal/ResourcePickerListInternal.vue +45 -85
- package/src/components/internal/SelectMultipleInternal.vue +187 -65
- package/src/components/internal/SelectSearchableInternal.vue +8 -4
- package/src/components/internal/WellEditPopupInternal.vue +11 -22
- package/src/components/internal/WorkspaceShellInternal.vue +12 -0
- package/src/composables/createClient.ts +2 -0
- package/src/composables/index.ts +1 -0
- package/src/composables/pluginIdentity.ts +31 -0
- package/src/composables/pluginWorkspaceModel.ts +2 -2
- package/src/composables/useAppExperiment.ts +20 -0
- package/src/composables/useCalendarGrid.ts +4 -3
- package/src/composables/useExperimentSelector.ts +77 -31
- package/src/composables/useFileImport.ts +51 -1
- package/src/composables/useFloatingPanel.ts +107 -0
- package/src/composables/useJobCenter.ts +188 -6
- package/src/composables/useOnboarding.ts +465 -0
- package/src/composables/usePluginWorkspace.ts +1 -1
- package/src/data.ts +1 -0
- package/src/runtime.ts +2 -1
- package/src/shell.ts +17 -0
- package/src/stores/index.ts +0 -2
- package/src/stores/settings.ts +20 -50
- package/src/styles/components/action-menu.css +1 -1
- package/src/styles/components/adduct-text.css +13 -5
- package/src/styles/components/alert-box.css +39 -58
- package/src/styles/components/app-layout.css +10 -6
- package/src/styles/components/app-page-selector.css +121 -44
- package/src/styles/components/app-pill-nav.css +11 -12
- package/src/styles/components/app-sidebar.css +9 -18
- package/src/styles/components/app-top-bar.css +219 -55
- package/src/styles/components/artifact-save-dialog.css +153 -2
- package/src/styles/components/audit-trail.css +16 -19
- package/src/styles/components/avatar.css +6 -4
- package/src/styles/components/batch-progress-list.css +38 -36
- package/src/styles/components/button.css +36 -59
- package/src/styles/components/calendar.css +12 -12
- package/src/styles/components/chart-container.css +34 -23
- package/src/styles/components/checkbox.css +2 -12
- package/src/styles/components/collapsible-card.css +27 -29
- package/src/styles/components/confirm-dialog.css +13 -14
- package/src/styles/components/dataframe.css +13 -5
- package/src/styles/components/date-picker.css +84 -94
- package/src/styles/components/datetime-picker.css +35 -47
- package/src/styles/components/divider.css +20 -20
- package/src/styles/components/dose-calculator.css +3 -3
- package/src/styles/components/empty-state.css +20 -17
- package/src/styles/components/experiment-code-badge.css +2 -0
- package/src/styles/components/experiment-popover.css +174 -329
- package/src/styles/components/experiment-selector-modal.css +88 -56
- package/src/styles/components/file-picker.css +3 -3
- package/src/styles/components/file-uploader.css +38 -49
- package/src/styles/components/form-builder.css +3 -3
- package/src/styles/components/formula-input.css +1 -1
- package/src/styles/components/icon-button.css +18 -24
- package/src/styles/components/input.css +5 -4
- package/src/styles/components/instrument-monitor.css +13 -15
- package/src/styles/components/jobs-status-tray.css +140 -296
- package/src/styles/components/layout-resize-handle.css +59 -16
- package/src/styles/components/modal.css +5 -7
- package/src/styles/components/molecule-input.css +2 -2
- package/src/styles/components/multi-select.css +65 -117
- package/src/styles/components/number-input.css +26 -19
- package/src/styles/components/onboarding.css +368 -0
- package/src/styles/components/pill.css +3 -2
- package/src/styles/components/plate-editor.css +0 -1
- package/src/styles/components/plugin-icon.css +26 -23
- package/src/styles/components/popover.css +2 -2
- package/src/styles/components/presence-avatars.css +1 -1
- package/src/styles/components/progress-bar.css +3 -3
- package/src/styles/components/protocol-step-editor.css +1 -3
- package/src/styles/components/resource-card.css +2 -2
- package/src/styles/components/resource-picker-list.css +6 -57
- package/src/styles/components/sample-hierarchy-tree.css +4 -4
- package/src/styles/components/sample-selector.css +138 -79
- package/src/styles/components/schedule-calendar.css +8 -8
- package/src/styles/components/searchable-select.css +15 -19
- package/src/styles/components/section-card.css +54 -49
- package/src/styles/components/segmented-control.css +18 -15
- package/src/styles/components/select.css +3 -3
- package/src/styles/components/sequence-input.css +2 -2
- package/src/styles/components/sequence-progress-bar.css +17 -8
- package/src/styles/components/settings-modal.css +7 -2
- package/src/styles/components/smart-group.css +18 -18
- package/src/styles/components/step-wizard.css +52 -16
- package/src/styles/components/tabs.css +2 -2
- package/src/styles/components/textarea.css +3 -3
- package/src/styles/components/time-picker.css +37 -25
- package/src/styles/components/toast.css +13 -11
- package/src/styles/components/toggle.css +1 -11
- package/src/styles/components/tooltip.css +12 -11
- package/src/styles/components/unit-input.css +9 -8
- package/src/styles/components/well-edit-popup.css +2 -2
- package/src/styles/components/well-plate.css +9 -2
- package/src/styles/index.css +1 -0
- package/src/styles/variables.css +247 -78
- package/src/types/componentWorkflowTypes.ts +2 -0
- package/src/types/components.ts +2 -0
- package/src/types/generated/platformContext.ts +1 -0
- package/src/types/generated-ui.ts +4 -0
- package/src/types/index.ts +1 -0
- package/src/types/jobs.ts +10 -0
- package/src/types/platform.ts +1 -1
- package/src/utils/time.ts +21 -0
- package/dist/ActionMenu-CScINahU.js.map +0 -1
- package/dist/AppSidebar-BmiiPfz9.js.map +0 -1
- package/dist/BaseModal-DfRIuVoj.js.map +0 -1
- package/dist/ExperimentPopover-C4sGw-is.js +0 -359
- package/dist/ExperimentPopover-C4sGw-is.js.map +0 -1
- package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +0 -1
- package/dist/SettingsModal-CSLE31yg.js.map +0 -1
- package/dist/data-C2PwI_dn.js.map +0 -1
- package/dist/experiment-43OJtH7R.js.map +0 -1
- package/dist/lab-DLwRl_Ql.js.map +0 -1
- package/dist/records-BzTcxekG.js.map +0 -1
- package/dist/runtime-D6gVat6r.js.map +0 -1
- package/dist/useExperimentSamples-CxcnxZ8h.js.map +0 -1
- package/dist/useListReorder-CcbEYxX-.js.map +0 -1
- package/dist/useRackEditor-BD5NIo5s.js.map +0 -1
- package/dist/useRealtime-PalKue84.js +0 -696
- package/dist/useRealtime-PalKue84.js.map +0 -1
- package/dist/useRequest-D5JDfsgZ.js +0 -76
- package/dist/useRequest-D5JDfsgZ.js.map +0 -1
package/src/styles/variables.css
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
* @import '@morscherlab/mint-sdk/styles';
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
@import url('https://fonts.googleapis.com/css2?family=
|
|
6
|
+
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap');
|
|
7
|
+
|
|
8
|
+
/* Tailwind v4's layer order, declared first so the SDK's base and utilities
|
|
9
|
+
layers sort the same way with or without Tailwind in the host. */
|
|
10
|
+
@layer theme, base, components, utilities;
|
|
7
11
|
|
|
8
12
|
/* ==========================================================================
|
|
9
13
|
CSS Variables - Light Mode
|
|
@@ -21,9 +25,9 @@
|
|
|
21
25
|
/* Strong control border — unchecked checkbox/radio, toggle off track, dashed outlines (~3.2:1 light, ~4.2:1 dark). */
|
|
22
26
|
--_control-border-strong: color-mix(in srgb, var(--text-secondary) 75%, var(--border-color));
|
|
23
27
|
/* Field border on hover. */
|
|
24
|
-
--_field-border-hover:
|
|
25
|
-
/* Ink: primary / error text on card and tinted surfaces.
|
|
26
|
-
|
|
28
|
+
--_field-border-hover: var(--border-strong);
|
|
29
|
+
/* Ink: primary / error text on card and tinted surfaces. html.dark lifts
|
|
30
|
+
these toward --text-primary. */
|
|
27
31
|
--_ink-primary: var(--color-primary-hover);
|
|
28
32
|
--_ink-error: var(--mint-error-hover);
|
|
29
33
|
|
|
@@ -33,11 +37,12 @@
|
|
|
33
37
|
--bg-tertiary: #F1F5F9;
|
|
34
38
|
--bg-card: #FFFFFF;
|
|
35
39
|
--bg-hover: #F1F5F9;
|
|
36
|
-
--border-color: #
|
|
37
|
-
--border-light: #
|
|
40
|
+
--border-color: #E2E8F0;
|
|
41
|
+
--border-light: #F1F5F9;
|
|
42
|
+
--border-strong: #CBD5E1;
|
|
38
43
|
|
|
39
44
|
/* Text colors */
|
|
40
|
-
--text-primary: #
|
|
45
|
+
--text-primary: #0F172A;
|
|
41
46
|
--text-secondary: #64748B;
|
|
42
47
|
--text-muted: #94A3B8;
|
|
43
48
|
/* De-emphasized label for low-emphasis interactive controls (secondary/ghost
|
|
@@ -46,25 +51,31 @@
|
|
|
46
51
|
where --text-secondary would drop to ~4.35:1. */
|
|
47
52
|
--text-secondary-strong: #475569;
|
|
48
53
|
|
|
49
|
-
/* Brand colors
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
--color-primary-
|
|
53
|
-
--color-
|
|
54
|
-
--color-
|
|
55
|
-
--color-
|
|
56
|
-
|
|
57
|
-
/*
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
--color-
|
|
61
|
-
--color-
|
|
62
|
-
--color-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
--color-
|
|
67
|
-
--color-
|
|
54
|
+
/* Brand colors: the accent (--color-primary*) comes from the palette
|
|
55
|
+
blocks below the dark block (html[data-palette], default teal). */
|
|
56
|
+
/* Fixed teal scale, the same in both themes. */
|
|
57
|
+
--color-primary-50: #F0FDFA;
|
|
58
|
+
--color-primary-100: #CCFBF1;
|
|
59
|
+
--color-primary-500: #14B8A6;
|
|
60
|
+
--color-primary-600: #0D9488;
|
|
61
|
+
--mint-primary: var(--color-primary);
|
|
62
|
+
/* Text and icons on an accent fill (filled buttons, Save). */
|
|
63
|
+
--text-on-accent: #FFFFFF;
|
|
64
|
+
/* Retired hues, aliased to the accent until 1.5 (mint doctor warns on use). */
|
|
65
|
+
--color-cta: var(--color-primary);
|
|
66
|
+
--color-cta-hover: var(--color-primary-hover);
|
|
67
|
+
--color-purple: var(--color-primary);
|
|
68
|
+
|
|
69
|
+
/* Entity colors — retired hues, aliased to slate until 1.5. Entities are told
|
|
70
|
+
apart by icon and label, not by hue. Only -hover has no neutral token. */
|
|
71
|
+
--color-experiment: var(--text-secondary-strong);
|
|
72
|
+
--color-experiment-hover: #334155;
|
|
73
|
+
--color-experiment-soft: var(--bg-tertiary);
|
|
74
|
+
--color-experiment-border: var(--border-strong);
|
|
75
|
+
--color-project: var(--color-experiment);
|
|
76
|
+
--color-project-hover: var(--color-experiment-hover);
|
|
77
|
+
--color-project-soft: var(--color-experiment-soft);
|
|
78
|
+
--color-project-border: var(--color-experiment-border);
|
|
68
79
|
|
|
69
80
|
/* MINT brand mark — used for browser theme-color, marketing chrome, app icon background */
|
|
70
81
|
--mint-brand: #7BD0B5;
|
|
@@ -76,13 +87,14 @@
|
|
|
76
87
|
--scrollbar-thumb: #D1D5DB;
|
|
77
88
|
--scrollbar-hover: #9CA3AF;
|
|
78
89
|
|
|
79
|
-
/* Shadows
|
|
80
|
-
|
|
81
|
-
--shadow:
|
|
82
|
-
--shadow
|
|
83
|
-
--shadow
|
|
84
|
-
|
|
85
|
-
--
|
|
90
|
+
/* Shadows — flat by default (borders, not shadows); only floating layers
|
|
91
|
+
(popovers, menus, dialogs) get one. */
|
|
92
|
+
--shadow-sm: none;
|
|
93
|
+
--shadow: none;
|
|
94
|
+
--card-shadow: none;
|
|
95
|
+
--shadow-md: 0 4px 12px -2px rgba(15, 23, 42, 0.10), 0 1px 3px rgba(15, 23, 42, 0.06);
|
|
96
|
+
--shadow-lg: 0 16px 40px -8px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.06);
|
|
97
|
+
--mint-shadow-pop: 0 4px 12px -2px rgba(15, 23, 42, 0.10), 0 1px 3px rgba(15, 23, 42, 0.06);
|
|
86
98
|
|
|
87
99
|
/* Categorical sample scale — mirrored by SAMPLE_COLOR_SCALE in
|
|
88
100
|
src/utils/color.ts. The JS constant carries the same hexes as a
|
|
@@ -106,20 +118,24 @@
|
|
|
106
118
|
/* Motion — the SDK's standard easing curve. */
|
|
107
119
|
--mint-ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
|
|
108
120
|
|
|
109
|
-
/* Typography —
|
|
110
|
-
--font-sans: '
|
|
111
|
-
--font-mono: '
|
|
112
|
-
|
|
113
|
-
/* Border radius */
|
|
114
|
-
--radius-sm:
|
|
115
|
-
--radius:
|
|
116
|
-
--radius-md:
|
|
117
|
-
--radius-lg:
|
|
118
|
-
|
|
119
|
-
/* Form element heights
|
|
120
|
-
|
|
121
|
-
--form-height-
|
|
122
|
-
--form-height-
|
|
121
|
+
/* Typography — Geist for UI text, Geist Mono for codes, m/z, RT, counts and timestamps. */
|
|
122
|
+
--font-sans: 'Geist', system-ui, -apple-system, sans-serif;
|
|
123
|
+
--font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
124
|
+
|
|
125
|
+
/* Border radius — code badges, tags, buttons/inputs, cards/dialogs. */
|
|
126
|
+
--radius-sm: 3px;
|
|
127
|
+
--radius: 4px;
|
|
128
|
+
--radius-md: 6px;
|
|
129
|
+
--radius-lg: 8px;
|
|
130
|
+
|
|
131
|
+
/* Form element heights and page gutter — compact (normal and compact
|
|
132
|
+
density); [data-density="comfortable"] below restores the larger set. */
|
|
133
|
+
--form-height-sm: 1.75rem;
|
|
134
|
+
--form-height-md: 2rem;
|
|
135
|
+
--form-height-lg: 2.5rem;
|
|
136
|
+
--mint-gutter: 0.5rem;
|
|
137
|
+
/* Distance from the outermost cards to the window edge, in every density. */
|
|
138
|
+
--mint-page-inset: 1rem;
|
|
123
139
|
|
|
124
140
|
/* Semantic colors */
|
|
125
141
|
--mint-success: #10B981;
|
|
@@ -141,20 +157,20 @@
|
|
|
141
157
|
--mint-info-border: rgba(59, 130, 246, 0.3);
|
|
142
158
|
|
|
143
159
|
/* Extended brand tokens */
|
|
144
|
-
--color-primary-light: #
|
|
160
|
+
--color-primary-light: #5EEAD4;
|
|
145
161
|
|
|
146
162
|
/* Shared component tokens */
|
|
147
163
|
--mint-disabled-opacity: 0.6;
|
|
148
164
|
|
|
149
165
|
/* Focus ring tokens */
|
|
150
166
|
--focus-ring: 0 0 0 2px var(--color-primary);
|
|
151
|
-
--focus-ring-offset: 0 0 0 2px
|
|
167
|
+
--focus-ring-offset: 0 0 0 2px #FFFFFF, 0 0 0 4px var(--color-primary);
|
|
152
168
|
--focus-ring-error: 0 0 0 2px var(--mint-error);
|
|
153
169
|
|
|
154
170
|
/* Soft focus rings — 3px translucent. Used by all form primitives
|
|
155
171
|
post-0.16 visual refresh. Solid variants above kept for legacy
|
|
156
172
|
components that haven't migrated yet. */
|
|
157
|
-
--focus-ring-soft: 0 0 0 3px
|
|
173
|
+
--focus-ring-soft: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
|
|
158
174
|
/* Red is perceptually brighter than teal at equal alpha; drop 2pp to keep visual weight matched. */
|
|
159
175
|
--focus-ring-soft-error: 0 0 0 3px rgba(239, 68, 68, 0.18);
|
|
160
176
|
|
|
@@ -174,7 +190,14 @@
|
|
|
174
190
|
--mint-text-inverse: #FFFFFF;
|
|
175
191
|
--mint-border: var(--border-color);
|
|
176
192
|
--mint-border-focus: var(--color-primary);
|
|
177
|
-
|
|
193
|
+
/* Colour-only transitions; no lift, bounce or glow. */
|
|
194
|
+
--mint-transition: 120ms ease;
|
|
195
|
+
/* Stacking layers: modal < jobs tray < onboarding tour < floating panels < tooltips and toasts. */
|
|
196
|
+
--mint-z-modal: 50;
|
|
197
|
+
--mint-z-tray: 1000;
|
|
198
|
+
--mint-z-tour: 1100;
|
|
199
|
+
--mint-z-popover: 1200;
|
|
200
|
+
--mint-z-toast: 9999;
|
|
178
201
|
}
|
|
179
202
|
|
|
180
203
|
/* ==========================================================================
|
|
@@ -182,24 +205,30 @@
|
|
|
182
205
|
========================================================================== */
|
|
183
206
|
html.dark {
|
|
184
207
|
/* Background colors */
|
|
185
|
-
--bg-primary: #
|
|
186
|
-
--bg-secondary: #
|
|
187
|
-
--bg-tertiary: #
|
|
188
|
-
--bg-card: #
|
|
189
|
-
--bg-hover: #
|
|
190
|
-
--border-color: #
|
|
191
|
-
--border-light: #
|
|
208
|
+
--bg-primary: #0B1120;
|
|
209
|
+
--bg-secondary: #111827;
|
|
210
|
+
--bg-tertiary: #1E293B;
|
|
211
|
+
--bg-card: #111827;
|
|
212
|
+
--bg-hover: #1E293B;
|
|
213
|
+
--border-color: #1F2937;
|
|
214
|
+
--border-light: #172033;
|
|
215
|
+
--border-strong: #334155;
|
|
216
|
+
|
|
217
|
+
/* Brand colors - Dark mode: the accent comes from the palette blocks below. */
|
|
218
|
+
/* Dark ink on the light accent fill (10.1:1 on #2DD4BF). */
|
|
219
|
+
--text-on-accent: #0B1120;
|
|
220
|
+
--color-experiment-hover: #E2E8F0;
|
|
192
221
|
|
|
193
222
|
/* Ink aliases (see :root): ~7:1 on --bg-card, tints included. */
|
|
194
223
|
--_ink-primary: color-mix(in srgb, var(--color-primary) 50%, var(--text-primary));
|
|
195
224
|
--_ink-error: color-mix(in srgb, var(--mint-error) 50%, var(--text-primary));
|
|
196
225
|
|
|
197
226
|
/* Text colors */
|
|
198
|
-
--text-primary: #
|
|
227
|
+
--text-primary: #F1F5F9;
|
|
199
228
|
--text-secondary: #94A3B8;
|
|
200
229
|
--text-muted: #64748B;
|
|
201
|
-
/* Dark-mode analog: soft light-gray instead of near-white, AA-safe (
|
|
202
|
-
on the dark secondary hover surface (--bg-tertiary #
|
|
230
|
+
/* Dark-mode analog: soft light-gray instead of near-white, AA-safe (9.9:1)
|
|
231
|
+
on the dark secondary hover surface (--bg-tertiary #1E293B). */
|
|
203
232
|
--text-secondary-strong: #CBD5E1;
|
|
204
233
|
|
|
205
234
|
/* Scrollbar */
|
|
@@ -207,22 +236,10 @@ html.dark {
|
|
|
207
236
|
--scrollbar-thumb: #475569;
|
|
208
237
|
--scrollbar-hover: #64748B;
|
|
209
238
|
|
|
210
|
-
/* Shadows - Dark mode */
|
|
211
|
-
--shadow-
|
|
212
|
-
--shadow: 0
|
|
213
|
-
--shadow-
|
|
214
|
-
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.2);
|
|
215
|
-
--card-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.24), 0 1px 3px 0 rgb(0 0 0 / 0.32);
|
|
216
|
-
|
|
217
|
-
/* Entity accent colors - Dark mode */
|
|
218
|
-
--color-experiment: #22D3EE;
|
|
219
|
-
--color-experiment-hover: #67E8F9;
|
|
220
|
-
--color-experiment-soft: rgba(34, 211, 238, 0.16);
|
|
221
|
-
--color-experiment-border: rgba(34, 211, 238, 0.36);
|
|
222
|
-
--color-project: #38BDF8;
|
|
223
|
-
--color-project-hover: #7DD3FC;
|
|
224
|
-
--color-project-soft: rgba(56, 189, 248, 0.16);
|
|
225
|
-
--color-project-border: rgba(56, 189, 248, 0.38);
|
|
239
|
+
/* Shadows - Dark mode (floating layers only; --shadow-sm/--shadow/--card-shadow stay none) */
|
|
240
|
+
--shadow-md: 0 6px 16px -4px rgba(0, 0, 0, 0.6);
|
|
241
|
+
--shadow-lg: 0 16px 40px -8px rgba(0, 0, 0, 0.7);
|
|
242
|
+
--mint-shadow-pop: 0 6px 16px -4px rgba(0, 0, 0, 0.6);
|
|
226
243
|
|
|
227
244
|
/* Semantic colors - Dark mode */
|
|
228
245
|
--mint-success-bg: rgba(16, 185, 129, 0.15);
|
|
@@ -233,7 +250,7 @@ html.dark {
|
|
|
233
250
|
|
|
234
251
|
/* Focus ring - dark mode offset uses bg-primary instead of white */
|
|
235
252
|
--focus-ring-offset: 0 0 0 2px var(--bg-primary), 0 0 0 4px var(--color-primary);
|
|
236
|
-
--focus-ring-soft: 0 0 0 3px
|
|
253
|
+
--focus-ring-soft: 0 0 0 3px color-mix(in srgb, var(--color-primary) 22%, transparent);
|
|
237
254
|
--focus-ring-soft-error: 0 0 0 3px rgba(248, 113, 113, 0.26);
|
|
238
255
|
|
|
239
256
|
/* Legacy aliases */
|
|
@@ -243,6 +260,131 @@ html.dark {
|
|
|
243
260
|
color-scheme: dark;
|
|
244
261
|
}
|
|
245
262
|
|
|
263
|
+
/* Accent palettes (Settings → Color palette). The settings store writes
|
|
264
|
+
html[data-palette]; the palette swatches set the same attribute on their
|
|
265
|
+
strip to preview a palette. Each palette is one accent in both themes: white
|
|
266
|
+
text on the light-mode fill, dark text (--text-on-accent) on the dark-mode
|
|
267
|
+
fill. Hues come from the biology plot-style palettes. */
|
|
268
|
+
|
|
269
|
+
/* Teal (default): teal-600 fill, teal-700 hover + ink, teal-800 pressed.
|
|
270
|
+
White on #0D9488 is 3.74:1, a known AA exception. */
|
|
271
|
+
:root,
|
|
272
|
+
[data-palette="default"] {
|
|
273
|
+
--color-primary: #0D9488;
|
|
274
|
+
--color-primary-hover: #0F766E;
|
|
275
|
+
--color-primary-pressed: #115E59;
|
|
276
|
+
--color-primary-soft: rgba(13, 148, 136, 0.10);
|
|
277
|
+
--color-primary-border: #99F6E4;
|
|
278
|
+
}
|
|
279
|
+
html.dark,
|
|
280
|
+
html.dark [data-palette="default"] {
|
|
281
|
+
--color-primary: #2DD4BF;
|
|
282
|
+
--color-primary-hover: #5EEAD4;
|
|
283
|
+
--color-primary-pressed: #99F6E4;
|
|
284
|
+
--color-primary-soft: rgba(45, 212, 191, 0.12);
|
|
285
|
+
--color-primary-border: rgba(45, 212, 191, 0.35);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* Colour-blind safe: Okabe-Ito blue accent, and Okabe-Ito bluish green,
|
|
289
|
+
vermilion and orange for status, so success and error differ for every
|
|
290
|
+
colour-vision type. White on #0072B2 is 5.19:1. */
|
|
291
|
+
:root[data-palette="colorblind"],
|
|
292
|
+
[data-palette="colorblind"] {
|
|
293
|
+
--color-primary: #0072B2;
|
|
294
|
+
--color-primary-hover: #005F94;
|
|
295
|
+
--color-primary-pressed: #004C77;
|
|
296
|
+
--color-primary-soft: rgba(0, 114, 178, 0.10);
|
|
297
|
+
--color-primary-border: #B3D5EA;
|
|
298
|
+
--mint-success: #009E73;
|
|
299
|
+
--mint-success-hover: #00805D;
|
|
300
|
+
--mint-success-bg: rgba(0, 158, 115, 0.1);
|
|
301
|
+
--mint-success-border: rgba(0, 158, 115, 0.3);
|
|
302
|
+
--mint-error: #D55E00;
|
|
303
|
+
--mint-error-hover: #B34E00;
|
|
304
|
+
--mint-error-bg: rgba(213, 94, 0, 0.1);
|
|
305
|
+
--mint-error-border: rgba(213, 94, 0, 0.3);
|
|
306
|
+
--mint-warning: #E69F00;
|
|
307
|
+
--mint-warning-hover: #C78800;
|
|
308
|
+
--mint-warning-bg: rgba(230, 159, 0, 0.1);
|
|
309
|
+
--mint-warning-border: rgba(230, 159, 0, 0.3);
|
|
310
|
+
--mint-warning-text: #8F5F00;
|
|
311
|
+
}
|
|
312
|
+
html.dark[data-palette="colorblind"],
|
|
313
|
+
html.dark [data-palette="colorblind"] {
|
|
314
|
+
--color-primary: #56B4E9;
|
|
315
|
+
--color-primary-hover: #7CC5EE;
|
|
316
|
+
--color-primary-pressed: #A3D6F3;
|
|
317
|
+
--color-primary-soft: rgba(86, 180, 233, 0.14);
|
|
318
|
+
--color-primary-border: rgba(86, 180, 233, 0.38);
|
|
319
|
+
--mint-success-bg: rgba(0, 158, 115, 0.15);
|
|
320
|
+
--mint-error-bg: rgba(213, 94, 0, 0.15);
|
|
321
|
+
--mint-warning-bg: rgba(230, 159, 0, 0.15);
|
|
322
|
+
--mint-warning-text: #FCD34D;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Purple: plot-style purple #8781bd, deepened so white text is 5.15:1. */
|
|
326
|
+
:root[data-palette="purple"],
|
|
327
|
+
[data-palette="purple"] {
|
|
328
|
+
--color-primary: #6B64B0;
|
|
329
|
+
--color-primary-hover: #5A539E;
|
|
330
|
+
--color-primary-pressed: #4A448A;
|
|
331
|
+
--color-primary-soft: rgba(107, 100, 176, 0.10);
|
|
332
|
+
--color-primary-border: #D3D0EC;
|
|
333
|
+
}
|
|
334
|
+
html.dark[data-palette="purple"],
|
|
335
|
+
html.dark [data-palette="purple"] {
|
|
336
|
+
--color-primary: #A9A3DB;
|
|
337
|
+
--color-primary-hover: #C2BDE7;
|
|
338
|
+
--color-primary-pressed: #D8D4F1;
|
|
339
|
+
--color-primary-soft: rgba(169, 163, 219, 0.14);
|
|
340
|
+
--color-primary-border: rgba(169, 163, 219, 0.38);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* Ocean: plot-style ocean ramp, #2171B5 fill (white 5.13:1), #6BAED6 dark. */
|
|
344
|
+
:root[data-palette="ocean"],
|
|
345
|
+
[data-palette="ocean"] {
|
|
346
|
+
--color-primary: #2171B5;
|
|
347
|
+
--color-primary-hover: #1B5F99;
|
|
348
|
+
--color-primary-pressed: #164E7E;
|
|
349
|
+
--color-primary-soft: rgba(33, 113, 181, 0.10);
|
|
350
|
+
--color-primary-border: #BBD7EE;
|
|
351
|
+
}
|
|
352
|
+
html.dark[data-palette="ocean"],
|
|
353
|
+
html.dark [data-palette="ocean"] {
|
|
354
|
+
--color-primary: #6BAED6;
|
|
355
|
+
--color-primary-hover: #8EC2E2;
|
|
356
|
+
--color-primary-pressed: #B0D5EC;
|
|
357
|
+
--color-primary-soft: rgba(107, 174, 214, 0.14);
|
|
358
|
+
--color-primary-border: rgba(107, 174, 214, 0.38);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* Forest: plot-style forest_clay, #2F6B4F fill (white 6.29:1), #7AA874 dark. */
|
|
362
|
+
:root[data-palette="forest"],
|
|
363
|
+
[data-palette="forest"] {
|
|
364
|
+
--color-primary: #2F6B4F;
|
|
365
|
+
--color-primary-hover: #275A42;
|
|
366
|
+
--color-primary-pressed: #1F4935;
|
|
367
|
+
--color-primary-soft: rgba(47, 107, 79, 0.10);
|
|
368
|
+
--color-primary-border: #BFD8C6;
|
|
369
|
+
}
|
|
370
|
+
html.dark[data-palette="forest"],
|
|
371
|
+
html.dark [data-palette="forest"] {
|
|
372
|
+
--color-primary: #7AA874;
|
|
373
|
+
--color-primary-hover: #95BC90;
|
|
374
|
+
--color-primary-pressed: #B1CFAD;
|
|
375
|
+
--color-primary-soft: rgba(122, 168, 116, 0.14);
|
|
376
|
+
--color-primary-border: rgba(122, 168, 116, 0.38);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* Comfortable density (html[data-density], written by the settings store):
|
|
380
|
+
the pre-v2 control heights and a wider gutter. */
|
|
381
|
+
[data-density="comfortable"] {
|
|
382
|
+
--form-height-sm: 2rem;
|
|
383
|
+
--form-height-md: 2.25rem;
|
|
384
|
+
--form-height-lg: 3rem;
|
|
385
|
+
--mint-gutter: 0.75rem;
|
|
386
|
+
}
|
|
387
|
+
|
|
246
388
|
/* ==========================================================================
|
|
247
389
|
Base Styles
|
|
248
390
|
========================================================================== */
|
|
@@ -257,10 +399,33 @@ body {
|
|
|
257
399
|
transition: background-color 0.15s, color 0.15s;
|
|
258
400
|
}
|
|
259
401
|
|
|
402
|
+
/* No page-level rubber-band bounce or pull-to-refresh; overflow: hidden does
|
|
403
|
+
not stop it. Panels still scroll, and their overscroll stops at their own
|
|
404
|
+
edge. A browser tab keeps the horizontal swipe for back and forward; an
|
|
405
|
+
installed PWA has no history swipe, so it drops both axes. */
|
|
406
|
+
html,
|
|
407
|
+
body {
|
|
408
|
+
overscroll-behavior-y: none;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
@media (display-mode: standalone) {
|
|
412
|
+
html,
|
|
413
|
+
body {
|
|
414
|
+
overscroll-behavior: none;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
260
418
|
code, pre {
|
|
261
419
|
font-family: var(--font-mono);
|
|
262
420
|
}
|
|
263
421
|
|
|
422
|
+
/* Links: accent ink. In the base layer, so Tailwind utilities and component
|
|
423
|
+
rules (both win over a layered element rule) keep their own link colours. */
|
|
424
|
+
@layer base {
|
|
425
|
+
a { color: var(--color-primary-hover); }
|
|
426
|
+
a:hover { color: var(--color-primary-pressed); }
|
|
427
|
+
}
|
|
428
|
+
|
|
264
429
|
/* Native controls do not inherit the page font; Tailwind preflight covers this
|
|
265
430
|
in the platform, but SDK consumers without it render buttons and selects in
|
|
266
431
|
the UA font. */
|
|
@@ -313,6 +478,9 @@ button, input, select, textarea {
|
|
|
313
478
|
/* ==========================================================================
|
|
314
479
|
MINT Utility Classes (for Tailwind v4 compatibility)
|
|
315
480
|
========================================================================== */
|
|
481
|
+
/* In Tailwind's utilities layer: unlayered, these beat every layered rule, so a
|
|
482
|
+
host's responsive variant (`lg:flex-row`) lost to the SDK's `.flex-col`. */
|
|
483
|
+
@layer utilities {
|
|
316
484
|
.bg-bg-hover {
|
|
317
485
|
background-color: var(--bg-tertiary);
|
|
318
486
|
}
|
|
@@ -688,6 +856,7 @@ button, input, select, textarea {
|
|
|
688
856
|
.max-w-sm {
|
|
689
857
|
max-width: 24rem;
|
|
690
858
|
}
|
|
859
|
+
} /* @layer utilities */
|
|
691
860
|
|
|
692
861
|
/* ==========================================================================
|
|
693
862
|
Reduced Motion
|
package/src/types/components.ts
CHANGED
|
@@ -317,6 +317,8 @@ export interface PluginWorkspaceViewSpec {
|
|
|
317
317
|
disabled?: import('vue').MaybeRefOrGetter<boolean>
|
|
318
318
|
reason?: import('vue').MaybeRefOrGetter<string | undefined>
|
|
319
319
|
}
|
|
320
|
+
/** Job source: the top bar shows the viewer's job and opens a JobsStatusTray. Read once at setup, like `experiment`. */
|
|
321
|
+
jobs?: import('vue').MaybeRefOrGetter<import('../composables/useJobCenter').PluginJobCenterSource | undefined>
|
|
320
322
|
}
|
|
321
323
|
|
|
322
324
|
|
|
@@ -151,7 +151,11 @@ export interface GeneratedAnalysisManifest {
|
|
|
151
151
|
}
|
|
152
152
|
ui: {
|
|
153
153
|
title: string
|
|
154
|
+
/** Second top-bar line; the top bar falls back to `description`. */
|
|
155
|
+
subtitle?: string
|
|
154
156
|
description: string
|
|
157
|
+
/** Plugin icon for the standalone top bar. */
|
|
158
|
+
icon?: string
|
|
155
159
|
}
|
|
156
160
|
jobs: GeneratedJobDefinition[]
|
|
157
161
|
}
|
package/src/types/index.ts
CHANGED
package/src/types/jobs.ts
CHANGED
|
@@ -68,3 +68,13 @@ export interface JobSnapshotPayload {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export type JobStreamData = JobStateInput | JobSnapshotPayload
|
|
71
|
+
|
|
72
|
+
/** What the top-bar run slot shows for the viewer's own job. The plugin picks the job. */
|
|
73
|
+
export interface TopBarJob {
|
|
74
|
+
/** Lifecycle of the shown job; sets the icon and the tone. */
|
|
75
|
+
status: JobStatus
|
|
76
|
+
/** Tooltip and accessible name, e.g. "Extracting", "Saved to EXP-0142". Not shown as text. */
|
|
77
|
+
label: string
|
|
78
|
+
/** 0-100; drawn as a small bar after the icon. */
|
|
79
|
+
percent?: number | null
|
|
80
|
+
}
|
package/src/types/platform.ts
CHANGED
|
@@ -66,5 +66,5 @@ export type PlatformContext = Partial<Omit<PlatformFrontendContext, 'plugin'>> &
|
|
|
66
66
|
|
|
67
67
|
// Settings state types
|
|
68
68
|
export type ThemeMode = 'light' | 'dark' | 'system'
|
|
69
|
-
export type ColorPalette = 'default' | 'colorblind' | '
|
|
69
|
+
export type ColorPalette = 'default' | 'colorblind' | 'purple' | 'ocean' | 'forest'
|
|
70
70
|
export type TableDensity = 'compact' | 'normal' | 'comfortable'
|
package/src/utils/time.ts
CHANGED
|
@@ -122,6 +122,27 @@ export function findNearestTimeSlotIndex(time: string, slots: readonly string[])
|
|
|
122
122
|
return bestIndex
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
const relativeTimeFormat = new Intl.RelativeTimeFormat('en', { numeric: 'auto' })
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* "in 5 minutes" / "2 hours ago" up to a week, then a locale date.
|
|
129
|
+
* With `weeks`, times up to five weeks away read as a week count first.
|
|
130
|
+
*/
|
|
131
|
+
export function formatRelativeTime(value: Date | string, { weeks = false }: { weeks?: boolean } = {}): string {
|
|
132
|
+
const date = value instanceof Date ? value : new Date(value)
|
|
133
|
+
const diffSec = Math.round((date.getTime() - Date.now()) / 1000)
|
|
134
|
+
const diffMin = Math.round(diffSec / 60)
|
|
135
|
+
const diffHr = Math.round(diffMin / 60)
|
|
136
|
+
const diffDay = Math.round(diffHr / 24)
|
|
137
|
+
const diffWeek = Math.round(diffDay / 7)
|
|
138
|
+
if (Math.abs(diffSec) < 60) return relativeTimeFormat.format(diffSec, 'second')
|
|
139
|
+
if (Math.abs(diffMin) < 60) return relativeTimeFormat.format(diffMin, 'minute')
|
|
140
|
+
if (Math.abs(diffHr) < 24) return relativeTimeFormat.format(diffHr, 'hour')
|
|
141
|
+
if (Math.abs(diffDay) < 7) return relativeTimeFormat.format(diffDay, 'day')
|
|
142
|
+
if (weeks && Math.abs(diffWeek) < 5) return relativeTimeFormat.format(diffWeek, 'week')
|
|
143
|
+
return date.toLocaleDateString()
|
|
144
|
+
}
|
|
145
|
+
|
|
125
146
|
export function toMinutes(time: string): number {
|
|
126
147
|
const { hour, minute } = parseTime(time)
|
|
127
148
|
return hour * 60 + minute
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ActionMenu-CScINahU.js","names":[],"sources":["../src/composables/useTextSearch.ts","../src/components/LoadingSpinner.vue","../src/components/LoadingSpinner.vue","../src/components/internal/DataStateInternal.vue","../src/components/internal/DataStateInternal.vue","../src/components/AlertBox.vue","../src/components/AlertBox.vue","../src/components/ActionMenu.vue","../src/components/ActionMenu.vue"],"sourcesContent":["import { computed, toValue, type ComputedRef, type Ref } from 'vue'\n\nexport type TextSearchSource<T> =\n | T\n | Ref<T>\n | ComputedRef<T>\n | (() => T)\n\nexport type TextSearchCandidate = unknown | readonly unknown[]\n\nexport interface UseTextSearchOptions<TItem> {\n items: TextSearchSource<readonly TItem[]>\n query: TextSearchSource<string | null | undefined>\n enabled?: TextSearchSource<boolean | null | undefined>\n getText: (item: TItem) => TextSearchCandidate\n}\n\nexport interface UseTextSearchReturn<TItem> {\n query: ComputedRef<string>\n filteredItems: ComputedRef<TItem[]>\n matches: (item: TItem, query?: string | null | undefined) => boolean\n}\n\n/** Shared text-search filtering for tables, lists, selectors, and chip inputs. */\nexport function useTextSearch<TItem>(options: UseTextSearchOptions<TItem>): UseTextSearchReturn<TItem> {\n const query = computed(() => normalizeSearchQuery(toValue(options.query)))\n const enabled = computed(() => toValue(options.enabled) ?? true)\n\n function matches(item: TItem, overrideQuery?: string | null | undefined): boolean {\n const activeQuery = overrideQuery === undefined ? query.value : normalizeSearchQuery(overrideQuery)\n if (!activeQuery) return true\n return candidateMatchesSearch(options.getText(item), activeQuery)\n }\n\n const filteredItems = computed(() => {\n const items = [...toValue(options.items)]\n if (!enabled.value || !query.value) return items\n return items.filter(item => matches(item))\n })\n\n return {\n query,\n filteredItems,\n matches,\n }\n}\n\nexport function normalizeSearchQuery(value: string | null | undefined): string {\n return (value ?? '').trim().toLowerCase()\n}\n\nexport function candidateMatchesSearch(candidate: TextSearchCandidate, query: string): boolean {\n const normalizedQuery = normalizeSearchQuery(query)\n if (!normalizedQuery) return true\n const values = Array.isArray(candidate) ? candidate : [candidate]\n return values.some((value) => {\n if (value === null || value === undefined) return false\n return String(value).toLowerCase().includes(normalizedQuery)\n })\n}\n","<script setup lang=\"ts\">\n/** Animated SVG spinner with size and tone, and a visually hidden status label for screen readers. `tone=\"inherit\"` takes the parent's text color. */\nimport type { Tone } from '../types'\n\ninterface Props {\n size?: 'xs' | 'sm' | 'md' | 'lg'\n tone?: Tone | 'inherit'\n label?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n size: 'md',\n tone: 'primary',\n label: 'Loading',\n})\n</script>\n\n<template>\n <div\n :class=\"[\n 'mint-spinner',\n `mint-spinner--${size}`,\n `mint-spinner--${tone}`,\n ]\"\n role=\"status\"\n >\n <svg\n class=\"mint-spinner__svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style=\"opacity: 0.25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n />\n <path\n style=\"opacity: 0.75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <span class=\"mint-spinner__label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Animated SVG spinner with size and tone, and a visually hidden status label for screen readers. `tone=\"inherit\"` takes the parent's text color. */\nimport type { Tone } from '../types'\n\ninterface Props {\n size?: 'xs' | 'sm' | 'md' | 'lg'\n tone?: Tone | 'inherit'\n label?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n size: 'md',\n tone: 'primary',\n label: 'Loading',\n})\n</script>\n\n<template>\n <div\n :class=\"[\n 'mint-spinner',\n `mint-spinner--${size}`,\n `mint-spinner--${tone}`,\n ]\"\n role=\"status\"\n >\n <svg\n class=\"mint-spinner__svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style=\"opacity: 0.25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n />\n <path\n style=\"opacity: 0.75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <span class=\"mint-spinner__label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Shared loading / error / empty presentation for the SDK data components.\n *\n * Internal: not exported from the package entrypoints. Data components render\n * this instead of hand-rolling their own placeholder markup so that the\n * loading, error and empty states look the same everywhere.\n */\nimport { computed } from 'vue'\nimport EmptyState from '../EmptyState.vue'\nimport LoadingSpinner from '../LoadingSpinner.vue'\n\n/** Single-path warning triangle used for the error state. */\nconst ERROR_ICON_PATH\n = 'M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'\n + 'M12 9v4M12 17h.01'\n\ninterface Props {\n /** Which of the three placeholder states to render. */\n state: 'loading' | 'error' | 'empty'\n /** Headline for the empty/error state. */\n title?: string\n /** Supporting copy for the empty/error state. */\n description?: string\n /** Custom `<path d>` for the empty state icon (the error state has its own). */\n iconPath?: string\n /** Placeholder scale; also drives the loading spinner size. */\n size?: 'sm' | 'md' | 'lg'\n /** `EmptyState` layout variant. */\n variant?: 'illustrated' | 'inline'\n /** Accessible label (and visible caption) for the loading state. */\n loadingLabel?: string\n /** Optional call-to-action rendered under the empty/error copy. */\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'illustrated',\n loadingLabel: 'Loading',\n})\n\nconst emit = defineEmits<{\n action: []\n}>()\n\nconst spinnerSize = computed(() => (props.size === 'sm' ? 'sm' : props.size === 'lg' ? 'lg' : 'md'))\n</script>\n\n<template>\n <div\n :class=\"['mint-data-state', `mint-data-state--${state}`, `mint-data-state--${size}`]\"\n :data-state=\"state\"\n >\n <template v-if=\"state === 'loading'\">\n <LoadingSpinner :size=\"spinnerSize\" :label=\"loadingLabel\" />\n <p class=\"mint-data-state__loading-text\" aria-hidden=\"true\">{{ loadingLabel }}</p>\n </template>\n <EmptyState\n v-else\n :title=\"title\"\n :description=\"description\"\n :icon-path=\"state === 'error' ? ERROR_ICON_PATH : iconPath\"\n :tone=\"state === 'error' ? 'error' : 'neutral'\"\n :size=\"size\"\n :variant=\"variant\"\n :action-label=\"actionLabel\"\n @action=\"emit('action')\"\n >\n <slot />\n </EmptyState>\n </div>\n</template>\n\n","<script setup lang=\"ts\">\n/**\n * Shared loading / error / empty presentation for the SDK data components.\n *\n * Internal: not exported from the package entrypoints. Data components render\n * this instead of hand-rolling their own placeholder markup so that the\n * loading, error and empty states look the same everywhere.\n */\nimport { computed } from 'vue'\nimport EmptyState from '../EmptyState.vue'\nimport LoadingSpinner from '../LoadingSpinner.vue'\n\n/** Single-path warning triangle used for the error state. */\nconst ERROR_ICON_PATH\n = 'M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'\n + 'M12 9v4M12 17h.01'\n\ninterface Props {\n /** Which of the three placeholder states to render. */\n state: 'loading' | 'error' | 'empty'\n /** Headline for the empty/error state. */\n title?: string\n /** Supporting copy for the empty/error state. */\n description?: string\n /** Custom `<path d>` for the empty state icon (the error state has its own). */\n iconPath?: string\n /** Placeholder scale; also drives the loading spinner size. */\n size?: 'sm' | 'md' | 'lg'\n /** `EmptyState` layout variant. */\n variant?: 'illustrated' | 'inline'\n /** Accessible label (and visible caption) for the loading state. */\n loadingLabel?: string\n /** Optional call-to-action rendered under the empty/error copy. */\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'illustrated',\n loadingLabel: 'Loading',\n})\n\nconst emit = defineEmits<{\n action: []\n}>()\n\nconst spinnerSize = computed(() => (props.size === 'sm' ? 'sm' : props.size === 'lg' ? 'lg' : 'md'))\n</script>\n\n<template>\n <div\n :class=\"['mint-data-state', `mint-data-state--${state}`, `mint-data-state--${size}`]\"\n :data-state=\"state\"\n >\n <template v-if=\"state === 'loading'\">\n <LoadingSpinner :size=\"spinnerSize\" :label=\"loadingLabel\" />\n <p class=\"mint-data-state__loading-text\" aria-hidden=\"true\">{{ loadingLabel }}</p>\n </template>\n <EmptyState\n v-else\n :title=\"title\"\n :description=\"description\"\n :icon-path=\"state === 'error' ? ERROR_ICON_PATH : iconPath\"\n :tone=\"state === 'error' ? 'error' : 'neutral'\"\n :size=\"size\"\n :variant=\"variant\"\n :action-label=\"actionLabel\"\n @action=\"emit('action')\"\n >\n <slot />\n </EmptyState>\n </div>\n</template>\n\n","<script setup lang=\"ts\">\n/** Inline alert banner with semantic icon, title, message slot, optional action button, and optional dismiss button. */\nimport { useSlots } from 'vue'\nimport type { Tone } from '../types'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n tone?: Tone\n title?: string\n dismissible?: boolean\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n tone: 'info',\n dismissible: false,\n})\n\nconst emit = defineEmits<{\n dismiss: []\n action: []\n}>()\n\nconst slots = useSlots()\nconst hasActions = () => !!props.actionLabel || !!slots.actions\n</script>\n\n<template>\n <div\n class=\"mint-alert\"\n :class=\"`mint-alert--${props.tone}`\"\n role=\"alert\"\n >\n <!-- Lucide circle-check -->\n <svg v-if=\"props.tone === 'success'\" class=\"mint-alert__icon mint-alert__icon--success\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m9 12 2 2 4-4\" />\n </svg>\n <!-- Lucide circle-x -->\n <svg v-else-if=\"props.tone === 'error'\" class=\"mint-alert__icon mint-alert__icon--error\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m15 9-6 6\" /><path d=\"m9 9 6 6\" />\n </svg>\n <!-- Lucide triangle-alert -->\n <svg v-else-if=\"props.tone === 'warning'\" class=\"mint-alert__icon mint-alert__icon--warning\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" /><path d=\"M12 9v4\" /><path d=\"M12 17h.01\" />\n </svg>\n <!-- Lucide info -->\n <svg v-else :class=\"['mint-alert__icon', `mint-alert__icon--${props.tone}`]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M12 16v-4\" /><path d=\"M12 8h.01\" />\n </svg>\n\n <div class=\"mint-alert__content\">\n <h4 v-if=\"props.title\" class=\"mint-alert__title\">\n {{ props.title }}\n </h4>\n <div class=\"mint-alert__message\">\n <slot />\n </div>\n </div>\n\n <div v-if=\"hasActions()\" class=\"mint-alert__actions\">\n <slot name=\"actions\">\n <BaseButton variant=\"secondary\" size=\"sm\" @click=\"emit('action')\">\n {{ props.actionLabel }}\n </BaseButton>\n </slot>\n </div>\n\n <button\n v-if=\"props.dismissible\"\n type=\"button\"\n class=\"mint-alert__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"emit('dismiss')\"\n >\n <svg class=\"mint-alert__dismiss-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Inline alert banner with semantic icon, title, message slot, optional action button, and optional dismiss button. */\nimport { useSlots } from 'vue'\nimport type { Tone } from '../types'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n tone?: Tone\n title?: string\n dismissible?: boolean\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n tone: 'info',\n dismissible: false,\n})\n\nconst emit = defineEmits<{\n dismiss: []\n action: []\n}>()\n\nconst slots = useSlots()\nconst hasActions = () => !!props.actionLabel || !!slots.actions\n</script>\n\n<template>\n <div\n class=\"mint-alert\"\n :class=\"`mint-alert--${props.tone}`\"\n role=\"alert\"\n >\n <!-- Lucide circle-check -->\n <svg v-if=\"props.tone === 'success'\" class=\"mint-alert__icon mint-alert__icon--success\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m9 12 2 2 4-4\" />\n </svg>\n <!-- Lucide circle-x -->\n <svg v-else-if=\"props.tone === 'error'\" class=\"mint-alert__icon mint-alert__icon--error\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m15 9-6 6\" /><path d=\"m9 9 6 6\" />\n </svg>\n <!-- Lucide triangle-alert -->\n <svg v-else-if=\"props.tone === 'warning'\" class=\"mint-alert__icon mint-alert__icon--warning\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" /><path d=\"M12 9v4\" /><path d=\"M12 17h.01\" />\n </svg>\n <!-- Lucide info -->\n <svg v-else :class=\"['mint-alert__icon', `mint-alert__icon--${props.tone}`]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M12 16v-4\" /><path d=\"M12 8h.01\" />\n </svg>\n\n <div class=\"mint-alert__content\">\n <h4 v-if=\"props.title\" class=\"mint-alert__title\">\n {{ props.title }}\n </h4>\n <div class=\"mint-alert__message\">\n <slot />\n </div>\n </div>\n\n <div v-if=\"hasActions()\" class=\"mint-alert__actions\">\n <slot name=\"actions\">\n <BaseButton variant=\"secondary\" size=\"sm\" @click=\"emit('action')\">\n {{ props.actionLabel }}\n </BaseButton>\n </slot>\n </div>\n\n <button\n v-if=\"props.dismissible\"\n type=\"button\"\n class=\"mint-alert__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"emit('dismiss')\"\n >\n <svg class=\"mint-alert__dismiss-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Compact overflow actions with an icon-only BaseButton trigger and a viewport-safe teleported menu. */\nimport { computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { Check, Ellipsis } from 'lucide-vue-next'\nimport { nextTick, onMounted, ref, watch } from 'vue'\nimport { useDropdownState } from '../composables/useDropdownState'\nimport { useMenuKeyboard } from '../composables/useMenuKeyboard'\nimport type { ActionMenuItem } from '../types/components'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n label: string\n items: ActionMenuItem[]\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n})\n\nconst emit = defineEmits<{\n select: [item: ActionMenuItem]\n open: []\n close: []\n}>()\n\ndefineSlots<{\n /** Replaces the ellipsis button; `toggle` and `keydown` go on the slotted button. */\n trigger?: (props: { open: boolean; toggle: () => void; keydown: (event: KeyboardEvent) => void }) => unknown\n}>()\n\nconst panelRef = ref<HTMLElement | null>(null)\nconst panelStyle = ref<Record<string, string>>({ visibility: 'hidden' })\n\n// Disclosure state (outside-click, Escape, scroll/resize closing, focus return)\n// comes from the shared composable; only floating-ui placement stays local.\nconst { isOpen, rootRef, triggerRef, open, close } = useDropdownState({\n closeOnScroll: true,\n insideRefs: [panelRef],\n onOpen: () => {\n panelStyle.value = { visibility: 'hidden' }\n emit('open')\n },\n onClose: () => emit('close'),\n})\n\n// BaseButton owns the actual <button>, so the trigger element is resolved from\n// the wrapper once mounted rather than bound with a template ref.\nonMounted(() => {\n triggerRef.value = rootRef.value?.querySelector('button') ?? null\n})\n\nfunction menuItems(): HTMLElement[] {\n if (!panelRef.value) return []\n return Array.from(\n panelRef.value.querySelectorAll<HTMLElement>('.mint-action-menu__item:not(:disabled)'),\n )\n}\n\nasync function positionPanel() {\n const trigger = triggerRef.value\n const panel = panelRef.value\n if (!trigger || !panel) return\n\n const position = await computePosition(trigger, panel, {\n placement: 'bottom-end',\n strategy: 'fixed',\n middleware: [\n offset(4),\n flip(),\n shift({ padding: 8 }),\n ],\n })\n panelStyle.value = {\n left: `${position.x}px`,\n top: `${position.y}px`,\n visibility: 'visible',\n }\n}\n\n/** `focusFirst` is false when the keyboard composable owns the initial focus. */\nfunction openMenu(focusFirst = true) {\n if (props.disabled || isOpen.value) return\n open()\n if (focusFirst) {\n void nextTick(() => menuItems()[0]?.focus())\n }\n}\n\nfunction toggleMenu() {\n if (props.disabled) return\n if (isOpen.value) close()\n else openMenu()\n}\n\nconst { handleTriggerKeydown, handlePanelKeydown } = useMenuKeyboard({\n items: menuItems,\n isOpen: () => isOpen.value,\n open: () => openMenu(false),\n close,\n})\n\nfunction handleSelect(item: ActionMenuItem) {\n if (item.disabled) return\n emit('select', item)\n close()\n}\n\nwatch(isOpen, async (opened) => {\n if (!opened) return\n await nextTick()\n await positionPanel()\n})\n</script>\n\n<template>\n <span ref=\"rootRef\" class=\"mint-action-menu\">\n <!-- A custom trigger must render one <button> and wire toggle + keydown to it. -->\n <slot name=\"trigger\" :open=\"isOpen\" :toggle=\"toggleMenu\" :keydown=\"handleTriggerKeydown\">\n <BaseButton\n variant=\"secondary\"\n size=\"sm\"\n :icon=\"Ellipsis\"\n :label=\"label\"\n :disabled=\"disabled\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"handleTriggerKeydown\"\n />\n </slot>\n </span>\n\n <Teleport to=\"body\">\n <div\n v-if=\"isOpen\"\n ref=\"panelRef\"\n class=\"mint-popover mint-action-menu__panel\"\n :style=\"panelStyle\"\n role=\"menu\"\n @keydown=\"handlePanelKeydown\"\n >\n <template v-for=\"(item, index) in items\" :key=\"item.id\">\n <div\n v-if=\"item.danger && index > 0 && !items[index - 1].danger\"\n class=\"mint-menu-separator\"\n role=\"separator\"\n />\n <a\n v-if=\"item.href !== undefined && !item.disabled\"\n :href=\"item.href\"\n :target=\"item.target\"\n :rel=\"item.target === '_blank' ? 'noopener noreferrer' : undefined\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n role=\"menuitem\"\n @click=\"handleSelect(item)\"\n >\n {{ item.label }}\n </a>\n <button\n v-else\n type=\"button\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n :role=\"item.checked === undefined ? 'menuitem' : 'menuitemradio'\"\n :aria-checked=\"item.checked\"\n :disabled=\"item.disabled\"\n @click=\"handleSelect(item)\"\n >\n <Check\n v-if=\"item.checked !== undefined\"\n class=\"mint-action-menu__check\"\n :class=\"{ 'mint-action-menu__check--off': !item.checked }\"\n :size=\"14\"\n aria-hidden=\"true\"\n />\n {{ item.label }}\n </button>\n </template>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\n/** Compact overflow actions with an icon-only BaseButton trigger and a viewport-safe teleported menu. */\nimport { computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { Check, Ellipsis } from 'lucide-vue-next'\nimport { nextTick, onMounted, ref, watch } from 'vue'\nimport { useDropdownState } from '../composables/useDropdownState'\nimport { useMenuKeyboard } from '../composables/useMenuKeyboard'\nimport type { ActionMenuItem } from '../types/components'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n label: string\n items: ActionMenuItem[]\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n})\n\nconst emit = defineEmits<{\n select: [item: ActionMenuItem]\n open: []\n close: []\n}>()\n\ndefineSlots<{\n /** Replaces the ellipsis button; `toggle` and `keydown` go on the slotted button. */\n trigger?: (props: { open: boolean; toggle: () => void; keydown: (event: KeyboardEvent) => void }) => unknown\n}>()\n\nconst panelRef = ref<HTMLElement | null>(null)\nconst panelStyle = ref<Record<string, string>>({ visibility: 'hidden' })\n\n// Disclosure state (outside-click, Escape, scroll/resize closing, focus return)\n// comes from the shared composable; only floating-ui placement stays local.\nconst { isOpen, rootRef, triggerRef, open, close } = useDropdownState({\n closeOnScroll: true,\n insideRefs: [panelRef],\n onOpen: () => {\n panelStyle.value = { visibility: 'hidden' }\n emit('open')\n },\n onClose: () => emit('close'),\n})\n\n// BaseButton owns the actual <button>, so the trigger element is resolved from\n// the wrapper once mounted rather than bound with a template ref.\nonMounted(() => {\n triggerRef.value = rootRef.value?.querySelector('button') ?? null\n})\n\nfunction menuItems(): HTMLElement[] {\n if (!panelRef.value) return []\n return Array.from(\n panelRef.value.querySelectorAll<HTMLElement>('.mint-action-menu__item:not(:disabled)'),\n )\n}\n\nasync function positionPanel() {\n const trigger = triggerRef.value\n const panel = panelRef.value\n if (!trigger || !panel) return\n\n const position = await computePosition(trigger, panel, {\n placement: 'bottom-end',\n strategy: 'fixed',\n middleware: [\n offset(4),\n flip(),\n shift({ padding: 8 }),\n ],\n })\n panelStyle.value = {\n left: `${position.x}px`,\n top: `${position.y}px`,\n visibility: 'visible',\n }\n}\n\n/** `focusFirst` is false when the keyboard composable owns the initial focus. */\nfunction openMenu(focusFirst = true) {\n if (props.disabled || isOpen.value) return\n open()\n if (focusFirst) {\n void nextTick(() => menuItems()[0]?.focus())\n }\n}\n\nfunction toggleMenu() {\n if (props.disabled) return\n if (isOpen.value) close()\n else openMenu()\n}\n\nconst { handleTriggerKeydown, handlePanelKeydown } = useMenuKeyboard({\n items: menuItems,\n isOpen: () => isOpen.value,\n open: () => openMenu(false),\n close,\n})\n\nfunction handleSelect(item: ActionMenuItem) {\n if (item.disabled) return\n emit('select', item)\n close()\n}\n\nwatch(isOpen, async (opened) => {\n if (!opened) return\n await nextTick()\n await positionPanel()\n})\n</script>\n\n<template>\n <span ref=\"rootRef\" class=\"mint-action-menu\">\n <!-- A custom trigger must render one <button> and wire toggle + keydown to it. -->\n <slot name=\"trigger\" :open=\"isOpen\" :toggle=\"toggleMenu\" :keydown=\"handleTriggerKeydown\">\n <BaseButton\n variant=\"secondary\"\n size=\"sm\"\n :icon=\"Ellipsis\"\n :label=\"label\"\n :disabled=\"disabled\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"handleTriggerKeydown\"\n />\n </slot>\n </span>\n\n <Teleport to=\"body\">\n <div\n v-if=\"isOpen\"\n ref=\"panelRef\"\n class=\"mint-popover mint-action-menu__panel\"\n :style=\"panelStyle\"\n role=\"menu\"\n @keydown=\"handlePanelKeydown\"\n >\n <template v-for=\"(item, index) in items\" :key=\"item.id\">\n <div\n v-if=\"item.danger && index > 0 && !items[index - 1].danger\"\n class=\"mint-menu-separator\"\n role=\"separator\"\n />\n <a\n v-if=\"item.href !== undefined && !item.disabled\"\n :href=\"item.href\"\n :target=\"item.target\"\n :rel=\"item.target === '_blank' ? 'noopener noreferrer' : undefined\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n role=\"menuitem\"\n @click=\"handleSelect(item)\"\n >\n {{ item.label }}\n </a>\n <button\n v-else\n type=\"button\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n :role=\"item.checked === undefined ? 'menuitem' : 'menuitemradio'\"\n :aria-checked=\"item.checked\"\n :disabled=\"item.disabled\"\n @click=\"handleSelect(item)\"\n >\n <Check\n v-if=\"item.checked !== undefined\"\n class=\"mint-action-menu__check\"\n :class=\"{ 'mint-action-menu__check--off': !item.checked }\"\n :size=\"14\"\n aria-hidden=\"true\"\n />\n {{ item.label }}\n </button>\n </template>\n </div>\n </Teleport>\n</template>\n"],"mappings":"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"}
|