@morscherlab/mint-sdk 1.4.0-beta.2 → 1.4.0-beta.20
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-CzLg0UaL.js} +40 -209
- package/dist/AlertBox-CzLg0UaL.js.map +1 -0
- package/dist/{AppSidebar-BmiiPfz9.js → AppSidebar-6oTT-gPO.js} +1249 -239
- package/dist/AppSidebar-6oTT-gPO.js.map +1 -0
- package/dist/{ConfirmDialog-CJ7hqYUP.js → ConfirmDialog-CSls2Nuv.js} +2 -2
- package/dist/{ConfirmDialog-CJ7hqYUP.js.map → ConfirmDialog-CSls2Nuv.js.map} +1 -1
- package/dist/ExperimentPopover-9l4QZlvQ.js +337 -0
- package/dist/ExperimentPopover-9l4QZlvQ.js.map +1 -0
- package/dist/{ExperimentSelectorModal-D-9z7cNx.js → ExperimentSelectorModal-pR5fK3pA.js} +244 -211
- package/dist/ExperimentSelectorModal-pR5fK3pA.js.map +1 -0
- package/dist/{SegmentedControl-DERBN-Xd.js → SegmentedControl-CJ7EAmOq.js} +2 -2
- package/dist/{SegmentedControl-DERBN-Xd.js.map → SegmentedControl-CJ7EAmOq.js.map} +1 -1
- package/dist/{SettingsModal-CSLE31yg.js → SettingsModal-Dyitgzfp.js} +28 -27
- package/dist/SettingsModal-Dyitgzfp.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__/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 +1 -1
- 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 +1 -1
- 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/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-DCUOx8ll.js} +2 -2
- package/dist/{controlSchemaModel-CP5-_nAj.js.map → controlSchemaModel-DCUOx8ll.js.map} +1 -1
- package/dist/{data-C2PwI_dn.js → data-DBnmeBZX.js} +179 -125
- package/dist/data-DBnmeBZX.js.map +1 -0
- package/dist/data.js +8 -8
- package/dist/{experiment-43OJtH7R.js → experiment-DyO54FQB.js} +25 -61
- package/dist/experiment-DyO54FQB.js.map +1 -0
- package/dist/{experimentStatus-BZmU4czV.js → experimentStatus-BFrKpHAH.js} +3 -3
- package/dist/{experimentStatus-BZmU4czV.js.map → experimentStatus-BFrKpHAH.js.map} +1 -1
- package/dist/index.js +20 -20
- package/dist/{install-DAID6c2-.js → install-qjELyNwc.js} +15 -14
- package/dist/{install-DAID6c2-.js.map → install-qjELyNwc.js.map} +1 -1
- package/dist/install.js +1 -1
- package/dist/{lab-DLwRl_Ql.js → lab-UyTbokQC.js} +136 -148
- package/dist/lab-UyTbokQC.js.map +1 -0
- package/dist/lab.js +4 -3
- package/dist/{records-BzTcxekG.js → records-CR_pYzIP.js} +533 -335
- package/dist/records-CR_pYzIP.js.map +1 -0
- package/dist/{runtime-D6gVat6r.js → runtime-CoHhBP10.js} +417 -54
- package/dist/runtime-CoHhBP10.js.map +1 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +7 -7
- package/dist/{shell-5ju97nOS.js → shell-BDuZf2zb.js} +10 -5
- package/dist/{shell-5ju97nOS.js.map → shell-BDuZf2zb.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 +2732 -2083
- 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-Bb2N4m40.js} +74 -4
- package/dist/useDropdownState-Bb2N4m40.js.map +1 -0
- package/dist/{useExperimentSamples-CxcnxZ8h.js → useExperimentSamples-Dno1fFMq.js} +4 -4
- package/dist/{useExperimentSamples-CxcnxZ8h.js.map → useExperimentSamples-Dno1fFMq.js.map} +1 -1
- package/dist/{useListReorder-CcbEYxX-.js → useListReorder-CQ9OCScc.js} +183 -351
- package/dist/useListReorder-CQ9OCScc.js.map +1 -0
- package/dist/{useRackEditor-BD5NIo5s.js → useRackEditor-wL3kPrRT.js} +73 -59
- package/dist/useRackEditor-wL3kPrRT.js.map +1 -0
- package/dist/useRealtime-C3whhVvb.js +508 -0
- package/dist/useRealtime-C3whhVvb.js.map +1 -0
- package/dist/useRequest-CDkrXNU7.js +244 -0
- package/dist/useRequest-CDkrXNU7.js.map +1 -0
- package/dist/utils/time.d.ts +7 -0
- package/package.json +1 -1
- package/src/__stories__/experiment-helpers.ts +3 -3
- 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/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/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/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__/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/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/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/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 +16 -40
- package/src/components/internal/DatePickerDateTimeInternal.vue +3 -13
- package/src/components/internal/DatePickerTimeInternal.vue +5 -8
- package/src/components/internal/OnboardingLayerInternal.vue +173 -0
- package/src/components/internal/ResourcePickerListInternal.vue +45 -85
- package/src/components/internal/SelectMultipleInternal.vue +182 -65
- package/src/components/internal/SelectSearchableInternal.vue +2 -3
- 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/useJobCenter.ts +188 -6
- package/src/composables/useOnboarding.ts +465 -0
- package/src/composables/usePluginWorkspace.ts +1 -1
- 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/adduct-text.css +13 -5
- package/src/styles/components/alert-box.css +39 -58
- package/src/styles/components/app-layout.css +7 -5
- 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 +80 -92
- package/src/styles/components/datetime-picker.css +31 -43
- 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 +4 -6
- 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 +12 -12
- 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 +36 -21
- package/src/styles/components/toast.css +12 -10
- package/src/styles/components/toggle.css +1 -11
- package/src/styles/components/tooltip.css +10 -9
- package/src/styles/components/unit-input.css +8 -7
- package/src/styles/components/well-plate.css +9 -2
- package/src/styles/index.css +1 -0
- package/src/styles/variables.css +241 -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/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
|
@@ -42,7 +42,6 @@ const {
|
|
|
42
42
|
weekDays,
|
|
43
43
|
monthYear,
|
|
44
44
|
calendarDays,
|
|
45
|
-
isDateDisabled,
|
|
46
45
|
formatDateValue,
|
|
47
46
|
setCurrentMonthFromDate,
|
|
48
47
|
prevMonth,
|
|
@@ -58,14 +57,7 @@ const selectedDate = computed(() => {
|
|
|
58
57
|
return isNaN(date.getTime()) ? null : date
|
|
59
58
|
})
|
|
60
59
|
|
|
61
|
-
const displayValue = computed(() =>
|
|
62
|
-
if (!selectedDate.value) return ''
|
|
63
|
-
return selectedDate.value.toLocaleDateString('en-US', {
|
|
64
|
-
year: 'numeric',
|
|
65
|
-
month: 'short',
|
|
66
|
-
day: 'numeric',
|
|
67
|
-
})
|
|
68
|
-
})
|
|
60
|
+
const displayValue = computed(() => (selectedDate.value ? formatDateValue(selectedDate.value) : ''))
|
|
69
61
|
|
|
70
62
|
function selectDate(day: CalendarGridDay) {
|
|
71
63
|
if (day.isDisabled || props.disabled) return
|
|
@@ -73,15 +65,6 @@ function selectDate(day: CalendarGridDay) {
|
|
|
73
65
|
close()
|
|
74
66
|
}
|
|
75
67
|
|
|
76
|
-
function goToToday() {
|
|
77
|
-
const today = new Date()
|
|
78
|
-
setCurrentMonthFromDate(today)
|
|
79
|
-
if (!isDateDisabled(today)) {
|
|
80
|
-
emit('update:modelValue', formatDateValue(today))
|
|
81
|
-
close()
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
68
|
function clear() {
|
|
86
69
|
emit('update:modelValue', undefined)
|
|
87
70
|
close()
|
|
@@ -167,6 +150,11 @@ onBeforeUnmount(stopPositioning)
|
|
|
167
150
|
<template>
|
|
168
151
|
<div ref="container" class="mint-date-picker">
|
|
169
152
|
<div class="mint-date-picker__input-wrapper">
|
|
153
|
+
<div class="mint-date-picker__icon">
|
|
154
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
155
|
+
<path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" />
|
|
156
|
+
</svg>
|
|
157
|
+
</div>
|
|
170
158
|
<input
|
|
171
159
|
ref="triggerRef"
|
|
172
160
|
type="text"
|
|
@@ -185,11 +173,17 @@ onBeforeUnmount(stopPositioning)
|
|
|
185
173
|
@click="toggleCalendar"
|
|
186
174
|
@keydown="handleTriggerKeydown"
|
|
187
175
|
/>
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
176
|
+
<button
|
|
177
|
+
v-if="clearable && modelValue && !disabled"
|
|
178
|
+
type="button"
|
|
179
|
+
class="mint-date-picker__clear-btn"
|
|
180
|
+
aria-label="Clear date"
|
|
181
|
+
@click.stop="clear"
|
|
182
|
+
>
|
|
183
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
184
|
+
<path d="M18 6 6 18" /><path d="m6 6 12 12" />
|
|
191
185
|
</svg>
|
|
192
|
-
</
|
|
186
|
+
</button>
|
|
193
187
|
</div>
|
|
194
188
|
|
|
195
189
|
<Teleport to="body">
|
|
@@ -218,24 +212,6 @@ onBeforeUnmount(stopPositioning)
|
|
|
218
212
|
@next-month="nextMonth"
|
|
219
213
|
@select="selectDate"
|
|
220
214
|
/>
|
|
221
|
-
|
|
222
|
-
<div class="mint-date-picker__footer">
|
|
223
|
-
<button
|
|
224
|
-
type="button"
|
|
225
|
-
class="mint-date-picker__footer-btn mint-date-picker__today-btn"
|
|
226
|
-
@click="goToToday"
|
|
227
|
-
>
|
|
228
|
-
Today
|
|
229
|
-
</button>
|
|
230
|
-
<button
|
|
231
|
-
v-if="clearable && modelValue"
|
|
232
|
-
type="button"
|
|
233
|
-
class="mint-date-picker__footer-btn mint-date-picker__clear-btn"
|
|
234
|
-
@click="clear"
|
|
235
|
-
>
|
|
236
|
-
Clear
|
|
237
|
-
</button>
|
|
238
|
-
</div>
|
|
239
215
|
</div>
|
|
240
216
|
</Transition>
|
|
241
217
|
</Teleport>
|
|
@@ -76,17 +76,12 @@ const selectedTimeStr = computed(() => {
|
|
|
76
76
|
|
|
77
77
|
const displayValue = computed(() => {
|
|
78
78
|
if (!selectedDate.value) return ''
|
|
79
|
-
const dateStr = selectedDate.value.toLocaleDateString(props.locale, {
|
|
80
|
-
year: 'numeric',
|
|
81
|
-
month: 'short',
|
|
82
|
-
day: 'numeric',
|
|
83
|
-
})
|
|
84
79
|
const timeStr = formatTime(
|
|
85
80
|
selectedDate.value.getHours(),
|
|
86
81
|
selectedDate.value.getMinutes(),
|
|
87
82
|
props.timeFormat,
|
|
88
83
|
)
|
|
89
|
-
return `${
|
|
84
|
+
return `${formatDateValue(selectedDate.value)} ${timeStr}`
|
|
90
85
|
})
|
|
91
86
|
|
|
92
87
|
// Time slots
|
|
@@ -198,8 +193,8 @@ watch(isOpen, async (opened) => {
|
|
|
198
193
|
<div ref="root" class="mint-datetime-picker">
|
|
199
194
|
<div class="mint-datetime-picker__input-wrapper">
|
|
200
195
|
<div class="mint-datetime-picker__icon-calendar">
|
|
201
|
-
<svg fill="none" stroke="currentColor"
|
|
202
|
-
<path
|
|
196
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
197
|
+
<path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" />
|
|
203
198
|
</svg>
|
|
204
199
|
</div>
|
|
205
200
|
<input
|
|
@@ -221,11 +216,6 @@ watch(isOpen, async (opened) => {
|
|
|
221
216
|
@click="toggleDropdown"
|
|
222
217
|
@keydown="handleTriggerKeydown"
|
|
223
218
|
/>
|
|
224
|
-
<div class="mint-datetime-picker__icon-clock">
|
|
225
|
-
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
226
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
227
|
-
</svg>
|
|
228
|
-
</div>
|
|
229
219
|
</div>
|
|
230
220
|
|
|
231
221
|
<Transition
|
|
@@ -210,6 +210,11 @@ watch(isOpen, (open) => {
|
|
|
210
210
|
<template>
|
|
211
211
|
<div ref="root" class="mint-time-picker" @keydown="handleKeydown">
|
|
212
212
|
<div class="mint-time-picker__input-wrapper">
|
|
213
|
+
<div class="mint-time-picker__icon">
|
|
214
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
215
|
+
<circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" />
|
|
216
|
+
</svg>
|
|
217
|
+
</div>
|
|
213
218
|
<input
|
|
214
219
|
ref="trigger"
|
|
215
220
|
type="text"
|
|
@@ -241,11 +246,6 @@ watch(isOpen, (open) => {
|
|
|
241
246
|
<path d="M18 6 6 18" /><path d="m6 6 12 12" />
|
|
242
247
|
</svg>
|
|
243
248
|
</button>
|
|
244
|
-
<div class="mint-time-picker__icon">
|
|
245
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
246
|
-
<circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" />
|
|
247
|
-
</svg>
|
|
248
|
-
</div>
|
|
249
249
|
</div>
|
|
250
250
|
|
|
251
251
|
<Transition
|
|
@@ -284,9 +284,6 @@ watch(isOpen, (open) => {
|
|
|
284
284
|
>
|
|
285
285
|
<span class="mint-time-picker__slot-time">{{ formatTimeSlot(slot, format) }}</span>
|
|
286
286
|
<span v-if="slotReason(slot)" class="mint-time-picker__slot-reason">{{ slotReason(slot) }}</span>
|
|
287
|
-
<svg class="mint-menu-item__check" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
288
|
-
<path d="M3.5 8.5l3 3 6-7" />
|
|
289
|
-
</svg>
|
|
290
287
|
</li>
|
|
291
288
|
</ul>
|
|
292
289
|
</div>
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The tour layer: a scrim with a hole over the anchor, the step card, and the
|
|
4
|
+
* what's-new dots. AppTopBar renders it when the app provides onboarding.
|
|
5
|
+
*/
|
|
6
|
+
import { computed, nextTick, onBeforeUnmount, ref, useId, watch } from 'vue'
|
|
7
|
+
import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom'
|
|
8
|
+
import { X } from 'lucide-vue-next'
|
|
9
|
+
import BaseButton from '../BaseButton.vue'
|
|
10
|
+
import { useEventListener } from '../../composables/useEventListener'
|
|
11
|
+
import type { OnboardingState } from '../../composables/useOnboarding'
|
|
12
|
+
|
|
13
|
+
const props = defineProps<{ state: OnboardingState }>()
|
|
14
|
+
|
|
15
|
+
// Space between the anchor and the edge of the hole.
|
|
16
|
+
const HOLE_PAD = 4
|
|
17
|
+
|
|
18
|
+
const active = computed(() => props.state.active.value)
|
|
19
|
+
const card = ref<HTMLElement | null>(null)
|
|
20
|
+
const hole = ref<DOMRect | null>(null)
|
|
21
|
+
const cardPosition = ref({ x: 0, y: 0 })
|
|
22
|
+
const titleId = useId()
|
|
23
|
+
let stopAutoUpdate: (() => void) | undefined
|
|
24
|
+
|
|
25
|
+
async function position() {
|
|
26
|
+
const current = active.value
|
|
27
|
+
if (!current || !card.value) return
|
|
28
|
+
hole.value = current.element.getBoundingClientRect()
|
|
29
|
+
const { x, y } = await computePosition(current.element, card.value, {
|
|
30
|
+
strategy: 'fixed',
|
|
31
|
+
placement: current.step.placement ?? 'bottom',
|
|
32
|
+
middleware: [offset(12), flip(), shift({ padding: 12 })],
|
|
33
|
+
})
|
|
34
|
+
// The step may have changed while the position was computed.
|
|
35
|
+
if (active.value === current) cardPosition.value = { x, y }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Focus goes back where it was when the run ends.
|
|
39
|
+
let returnFocus: HTMLElement | null = null
|
|
40
|
+
watch(active, async (current, previous) => {
|
|
41
|
+
stopAutoUpdate?.()
|
|
42
|
+
stopAutoUpdate = undefined
|
|
43
|
+
hole.value = null
|
|
44
|
+
if (current && !previous) returnFocus = document.activeElement as HTMLElement | null
|
|
45
|
+
if (!current) {
|
|
46
|
+
if (returnFocus?.isConnected) returnFocus.focus()
|
|
47
|
+
returnFocus = null
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
await nextTick()
|
|
51
|
+
if (!card.value || active.value !== current) return
|
|
52
|
+
current.element.scrollIntoView({ block: 'nearest', inline: 'nearest' })
|
|
53
|
+
stopAutoUpdate = autoUpdate(current.element, card.value, () => void position())
|
|
54
|
+
// A click step: the keyboard user presses the control itself.
|
|
55
|
+
if (current.step.advanceOn === 'click') current.element.focus()
|
|
56
|
+
// Otherwise the card itself: no focus ring on load, and Tab reaches Back and Next.
|
|
57
|
+
else card.value.focus()
|
|
58
|
+
}, { immediate: true })
|
|
59
|
+
onBeforeUnmount(() => stopAutoUpdate?.())
|
|
60
|
+
|
|
61
|
+
// The layer is its own focus trap: Tab cycles over the card's buttons (and the
|
|
62
|
+
// anchor on a click step), never the page behind; from the card itself Tab goes
|
|
63
|
+
// to the first stop and Shift+Tab to the last.
|
|
64
|
+
useEventListener(document, 'keydown', (event) => {
|
|
65
|
+
const current = active.value
|
|
66
|
+
if (!current || !card.value) return
|
|
67
|
+
// Keys belong to the tour only while focus is on its card, its anchor, or nowhere.
|
|
68
|
+
const focused = document.activeElement
|
|
69
|
+
if (focused && focused !== document.body && !card.value.contains(focused) && focused !== current.element) return
|
|
70
|
+
const onCard = focused === card.value
|
|
71
|
+
if (event.key === 'Escape') {
|
|
72
|
+
event.stopPropagation()
|
|
73
|
+
props.state.dismiss()
|
|
74
|
+
} else if (event.key === 'Tab') {
|
|
75
|
+
const buttons = [...card.value.querySelectorAll<HTMLElement>('button')]
|
|
76
|
+
const stops = current.step.advanceOn === 'click' ? [current.element, ...buttons] : buttons
|
|
77
|
+
const at = stops.indexOf(document.activeElement as HTMLElement)
|
|
78
|
+
const target = at === -1 ? (event.shiftKey ? stops.length - 1 : 0) : (at + (event.shiftKey ? -1 : 1) + stops.length) % stops.length
|
|
79
|
+
event.preventDefault()
|
|
80
|
+
stops[target].focus()
|
|
81
|
+
} else if (event.key === 'Enter' && onCard && current.step.advanceOn !== 'click') {
|
|
82
|
+
event.preventDefault()
|
|
83
|
+
props.state.next()
|
|
84
|
+
}
|
|
85
|
+
}, { capture: true })
|
|
86
|
+
|
|
87
|
+
const holeStyle = computed(() => hole.value && {
|
|
88
|
+
left: `${hole.value.left - HOLE_PAD}px`,
|
|
89
|
+
top: `${hole.value.top - HOLE_PAD}px`,
|
|
90
|
+
width: `${hole.value.width + 2 * HOLE_PAD}px`,
|
|
91
|
+
height: `${hole.value.height + 2 * HOLE_PAD}px`,
|
|
92
|
+
})
|
|
93
|
+
// advanceOn 'click': cut the hole out of the click blocker, so the anchor takes the click.
|
|
94
|
+
const blockerStyle = computed(() => {
|
|
95
|
+
const rect = hole.value
|
|
96
|
+
if (!rect || active.value?.step.advanceOn !== 'click') return undefined
|
|
97
|
+
const [x, y, w, h] = [rect.left - HOLE_PAD, rect.top - HOLE_PAD, rect.width + 2 * HOLE_PAD, rect.height + 2 * HOLE_PAD]
|
|
98
|
+
return { clipPath: `path(evenodd, 'M0 0H${window.innerWidth}V${window.innerHeight}H0Z M${x} ${y}h${w}v${h}h${-w}Z')` }
|
|
99
|
+
})
|
|
100
|
+
const isLast = computed(() => !!active.value && active.value.index === active.value.count - 1)
|
|
101
|
+
const nextLabel = computed(() => active.value?.news ? 'Got it' : isLast.value ? 'Done' : 'Next')
|
|
102
|
+
|
|
103
|
+
// What's-new dots: one on each element with unseen news, hidden while a card shows.
|
|
104
|
+
const dots = ref<Array<{ id: string; title: string; x: number; y: number }>>([])
|
|
105
|
+
let frame = 0
|
|
106
|
+
function placeDots() {
|
|
107
|
+
cancelAnimationFrame(frame)
|
|
108
|
+
frame = requestAnimationFrame(() => {
|
|
109
|
+
dots.value = active.value ? [] : props.state.news.value.flatMap((item) => {
|
|
110
|
+
if (!item.unseen) return []
|
|
111
|
+
const element = document.querySelector(`[data-onboarding="${CSS.escape(item.anchor)}"]`)
|
|
112
|
+
if (!element) return []
|
|
113
|
+
const rect = element.getBoundingClientRect()
|
|
114
|
+
return rect.width ? [{ id: item.id, title: item.title, x: rect.right, y: rect.top }] : []
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
const observer = new MutationObserver(placeDots)
|
|
119
|
+
watch(() => props.state.unseenNews.value > 0, (watching) => {
|
|
120
|
+
observer.disconnect()
|
|
121
|
+
if (watching) observer.observe(document.body, { childList: true, subtree: true })
|
|
122
|
+
placeDots()
|
|
123
|
+
}, { immediate: true })
|
|
124
|
+
watch(active, placeDots)
|
|
125
|
+
useEventListener(window, 'resize', placeDots)
|
|
126
|
+
useEventListener(window, 'scroll', placeDots, { capture: true, passive: true })
|
|
127
|
+
onBeforeUnmount(() => {
|
|
128
|
+
observer.disconnect()
|
|
129
|
+
cancelAnimationFrame(frame)
|
|
130
|
+
})
|
|
131
|
+
</script>
|
|
132
|
+
|
|
133
|
+
<template>
|
|
134
|
+
<Teleport to="body">
|
|
135
|
+
<button
|
|
136
|
+
v-for="dot in dots"
|
|
137
|
+
:key="dot.id"
|
|
138
|
+
type="button"
|
|
139
|
+
class="mint-onboarding__dot"
|
|
140
|
+
:style="{ left: `${dot.x}px`, top: `${dot.y}px` }"
|
|
141
|
+
:aria-label="`New: ${dot.title}`"
|
|
142
|
+
@click="state.showNews(dot.id)"
|
|
143
|
+
/>
|
|
144
|
+
<div v-if="active" class="mint-onboarding">
|
|
145
|
+
<div class="mint-onboarding__blocker" :style="blockerStyle" />
|
|
146
|
+
<div v-if="holeStyle" class="mint-onboarding__hole" :style="holeStyle" />
|
|
147
|
+
<div
|
|
148
|
+
ref="card"
|
|
149
|
+
class="mint-onboarding__card"
|
|
150
|
+
role="dialog"
|
|
151
|
+
aria-modal="true"
|
|
152
|
+
:aria-labelledby="titleId"
|
|
153
|
+
tabindex="-1"
|
|
154
|
+
:style="{ left: `${cardPosition.x}px`, top: `${cardPosition.y}px` }"
|
|
155
|
+
>
|
|
156
|
+
<button type="button" class="mint-onboarding__close" :aria-label="active.news ? 'Close' : 'Close tour'" @click="state.dismiss()">
|
|
157
|
+
<X :size="14" aria-hidden="true" />
|
|
158
|
+
</button>
|
|
159
|
+
<span v-if="active.count > 1" class="mint-onboarding__count">
|
|
160
|
+
<span aria-hidden="true">{{ active.index + 1 }} / {{ active.count }}</span>
|
|
161
|
+
<span class="mint-onboarding__sr">Step {{ active.index + 1 }} of {{ active.count }}</span>
|
|
162
|
+
</span>
|
|
163
|
+
<p :id="titleId" class="mint-onboarding__title">{{ active.step.title }}</p>
|
|
164
|
+
<p class="mint-onboarding__body">{{ active.step.body }}</p>
|
|
165
|
+
<div class="mint-onboarding__footer">
|
|
166
|
+
<span v-if="active.step.advanceOn === 'click'" class="mint-onboarding__hint">Click the highlighted control.</span>
|
|
167
|
+
<BaseButton v-if="active.index > 0" variant="ghost" size="sm" @click="state.back()">Back</BaseButton>
|
|
168
|
+
<BaseButton v-if="active.step.advanceOn !== 'click'" size="sm" @click="state.next()">{{ nextLabel }}</BaseButton>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</Teleport>
|
|
173
|
+
</template>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T">
|
|
2
2
|
/**
|
|
3
|
-
* Searchable
|
|
3
|
+
* Searchable single-select list shared by the experiment and
|
|
4
4
|
* artifact selector modals: two-line rows (title, then code + meta) with status and date
|
|
5
5
|
* in a right-hand column, a filled selected row, skeleton,
|
|
6
6
|
* error and empty states, and the combobox keyboard model (↑ ↓ Enter).
|
|
7
7
|
*/
|
|
8
|
-
import { computed, nextTick,
|
|
8
|
+
import { computed, nextTick, ref, useId, watch } from 'vue'
|
|
9
9
|
import BaseInput from '../BaseInput.vue'
|
|
10
10
|
import Skeleton from '../Skeleton.vue'
|
|
11
11
|
import EmptyState from '../EmptyState.vue'
|
|
@@ -26,8 +26,6 @@ export interface ResourcePickerRow {
|
|
|
26
26
|
const props = withDefaults(
|
|
27
27
|
defineProps<{
|
|
28
28
|
items: T[]
|
|
29
|
-
/** When set, rows render under collapsible group headers in this order. */
|
|
30
|
-
groups?: { label: string; items: T[] }[] | null
|
|
31
29
|
itemKey: (item: T) => string | number
|
|
32
30
|
describe: (item: T) => ResourcePickerRow
|
|
33
31
|
selectedKey?: string | number | null
|
|
@@ -39,9 +37,10 @@ const props = withDefaults(
|
|
|
39
37
|
error?: string | null
|
|
40
38
|
emptyTitle?: string
|
|
41
39
|
emptyDescription?: string
|
|
40
|
+
/** Focus the search field when the list mounts (the modal's focus trap honours `autofocus`). */
|
|
41
|
+
autofocusSearch?: boolean
|
|
42
42
|
}>(),
|
|
43
43
|
{
|
|
44
|
-
groups: null,
|
|
45
44
|
selectedKey: null,
|
|
46
45
|
placeholder: 'Search…',
|
|
47
46
|
loading: false,
|
|
@@ -57,50 +56,33 @@ const emit = defineEmits<{
|
|
|
57
56
|
defineSlots<{
|
|
58
57
|
/** Extra filters on the search row. */
|
|
59
58
|
filters?: () => unknown
|
|
60
|
-
/** A second filter row under the search. */
|
|
61
|
-
advanced?: () => unknown
|
|
62
59
|
/** Row controls before the check; keys pressed inside them never select the row. */
|
|
63
60
|
actions?: (props: { item: T }) => unknown
|
|
64
61
|
}>()
|
|
65
62
|
|
|
66
63
|
const listId = `mint-resource-picker-${useId().replace(/:/g, '')}`
|
|
67
|
-
const collapsed = reactive(new Set<string>())
|
|
68
64
|
const activeIndex = ref(-1)
|
|
69
65
|
const listRef = ref<HTMLElement | null>(null)
|
|
70
66
|
|
|
71
|
-
const
|
|
72
|
-
props.groups?.map((group) => ({
|
|
73
|
-
...group,
|
|
74
|
-
rows: collapsed.has(group.label) ? [] : group.items,
|
|
75
|
-
})),
|
|
76
|
-
)
|
|
77
|
-
/** Keyboard order: the rows on screen, top to bottom. */
|
|
78
|
-
const flat = computed(() =>
|
|
79
|
-
visibleGroups.value ? visibleGroups.value.flatMap((group) => group.rows) : props.items,
|
|
80
|
-
)
|
|
81
|
-
const indexByKey = computed(() => new Map(flat.value.map((item, i) => [props.itemKey(item), i])))
|
|
67
|
+
const indexByKey = computed(() => new Map(props.items.map((item, i) => [props.itemKey(item), i])))
|
|
82
68
|
const showList = computed(() => !props.loading && !props.error && props.items.length > 0)
|
|
83
69
|
|
|
84
70
|
function optionId(item: T): string {
|
|
85
71
|
return `${listId}-${props.itemKey(item)}`
|
|
86
72
|
}
|
|
87
73
|
const activeDescendant = computed(() => {
|
|
88
|
-
const item =
|
|
74
|
+
const item = props.items[activeIndex.value]
|
|
89
75
|
return item === undefined ? undefined : optionId(item)
|
|
90
76
|
})
|
|
91
77
|
|
|
92
78
|
function indexOf(item: T): number {
|
|
93
79
|
return indexByKey.value.get(props.itemKey(item)) ?? -1
|
|
94
80
|
}
|
|
95
|
-
function toggleGroup(label: string) {
|
|
96
|
-
if (collapsed.has(label)) collapsed.delete(label)
|
|
97
|
-
else collapsed.add(label)
|
|
98
|
-
}
|
|
99
81
|
function keydown(event: KeyboardEvent) {
|
|
100
|
-
// Keys belong to the search combobox; a focused
|
|
82
|
+
// Keys belong to the search combobox; a focused filter or row action keeps its own Enter.
|
|
101
83
|
const target = event.target as HTMLElement | null
|
|
102
84
|
if (target !== event.currentTarget && !target?.closest('.mint-resource-picker__search')) return
|
|
103
|
-
const rows =
|
|
85
|
+
const rows = props.items
|
|
104
86
|
if (!rows.length) return
|
|
105
87
|
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
106
88
|
event.preventDefault()
|
|
@@ -120,7 +102,7 @@ function keydown(event: KeyboardEvent) {
|
|
|
120
102
|
}
|
|
121
103
|
|
|
122
104
|
watch(
|
|
123
|
-
() =>
|
|
105
|
+
() => props.items,
|
|
124
106
|
() => {
|
|
125
107
|
activeIndex.value = -1
|
|
126
108
|
},
|
|
@@ -136,6 +118,7 @@ watch(
|
|
|
136
118
|
:placeholder="placeholder"
|
|
137
119
|
size="sm"
|
|
138
120
|
type="search"
|
|
121
|
+
:autofocus="autofocusSearch"
|
|
139
122
|
role="combobox"
|
|
140
123
|
:aria-label="`Search ${label.toLowerCase()}`"
|
|
141
124
|
:aria-expanded="showList"
|
|
@@ -151,7 +134,6 @@ watch(
|
|
|
151
134
|
</BaseInput>
|
|
152
135
|
<slot name="filters" />
|
|
153
136
|
</div>
|
|
154
|
-
<slot name="advanced" />
|
|
155
137
|
|
|
156
138
|
<div v-if="loading" class="mint-resource-picker__frame" aria-busy="true">
|
|
157
139
|
<div v-for="n in 4" :key="n" class="mint-resource-picker__skeleton-row">
|
|
@@ -174,64 +156,42 @@ watch(
|
|
|
174
156
|
role="listbox"
|
|
175
157
|
:aria-label="label"
|
|
176
158
|
>
|
|
177
|
-
<
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
159
|
+
<div
|
|
160
|
+
v-for="item in items"
|
|
161
|
+
:id="optionId(item)"
|
|
162
|
+
:key="itemKey(item)"
|
|
163
|
+
role="option"
|
|
164
|
+
:aria-selected="itemKey(item) === selectedKey"
|
|
165
|
+
class="mint-resource-picker__row"
|
|
166
|
+
:class="{
|
|
167
|
+
'mint-resource-picker__row--selected': itemKey(item) === selectedKey,
|
|
168
|
+
'mint-resource-picker__row--active': indexOf(item) === activeIndex,
|
|
169
|
+
}"
|
|
170
|
+
@click="emit('select', item)"
|
|
171
|
+
@mouseenter="activeIndex = indexOf(item)"
|
|
172
|
+
>
|
|
173
|
+
<span class="mint-resource-picker__text">
|
|
174
|
+
<span class="mint-resource-picker__title">{{ describe(item).title }}</span>
|
|
175
|
+
<span v-if="describe(item).code || describe(item).meta?.length" class="mint-resource-picker__meta"
|
|
176
|
+
><span v-if="describe(item).code" class="mint-resource-picker__code mint-exp-code mint-exp-code--sm">{{
|
|
177
|
+
describe(item).code
|
|
178
|
+
}}</span
|
|
179
|
+
><span v-if="describe(item).meta?.length">{{ describe(item).meta!.join(' · ') }}</span></span
|
|
192
180
|
>
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
<span
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
'mint-resource-picker__row--active': indexOf(item) === activeIndex,
|
|
208
|
-
}"
|
|
209
|
-
@click="emit('select', item)"
|
|
210
|
-
@mouseenter="activeIndex = indexOf(item)"
|
|
211
|
-
>
|
|
212
|
-
<span class="mint-resource-picker__text">
|
|
213
|
-
<span class="mint-resource-picker__title">{{ describe(item).title }}</span>
|
|
214
|
-
<span v-if="describe(item).code || describe(item).meta?.length" class="mint-resource-picker__meta"
|
|
215
|
-
><span v-if="describe(item).code" class="mint-resource-picker__code mint-exp-code mint-exp-code--sm">{{
|
|
216
|
-
describe(item).code
|
|
217
|
-
}}</span
|
|
218
|
-
><span v-if="describe(item).meta?.length">{{ describe(item).meta!.join(' · ') }}</span></span
|
|
219
|
-
>
|
|
220
|
-
</span>
|
|
221
|
-
<span v-if="describe(item).status || describe(item).date" class="mint-resource-picker__aside">
|
|
222
|
-
<span
|
|
223
|
-
v-if="describe(item).status"
|
|
224
|
-
class="mint-resource-picker__status"
|
|
225
|
-
:class="`mint-resource-picker__status--${describe(item).status!.tone}`"
|
|
226
|
-
>{{ describe(item).status!.label }}</span
|
|
227
|
-
>
|
|
228
|
-
<span v-if="describe(item).date" class="mint-resource-picker__date">{{ describe(item).date }}</span>
|
|
229
|
-
</span>
|
|
230
|
-
<span v-if="$slots.actions" class="mint-resource-picker__actions" @click.stop>
|
|
231
|
-
<slot name="actions" :item="item" />
|
|
232
|
-
</span>
|
|
233
|
-
</div>
|
|
234
|
-
</template>
|
|
181
|
+
</span>
|
|
182
|
+
<span v-if="describe(item).status || describe(item).date" class="mint-resource-picker__aside">
|
|
183
|
+
<span
|
|
184
|
+
v-if="describe(item).status"
|
|
185
|
+
class="mint-resource-picker__status"
|
|
186
|
+
:class="`mint-resource-picker__status--${describe(item).status!.tone}`"
|
|
187
|
+
>{{ describe(item).status!.label }}</span
|
|
188
|
+
>
|
|
189
|
+
<span v-if="describe(item).date" class="mint-resource-picker__date">{{ describe(item).date }}</span>
|
|
190
|
+
</span>
|
|
191
|
+
<span v-if="$slots.actions" class="mint-resource-picker__actions" @click.stop>
|
|
192
|
+
<slot name="actions" :item="item" />
|
|
193
|
+
</span>
|
|
194
|
+
</div>
|
|
235
195
|
</div>
|
|
236
196
|
</div>
|
|
237
197
|
</template>
|