@zerodep-dev/vue-tsx-pro-ui 0.1.0 → 0.3.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/dist/base/Badge.js +3 -3
- package/dist/base/Badge.js.map +1 -1
- package/dist/base/Can.d.ts +12 -0
- package/dist/base/Can.js +20 -0
- package/dist/base/Can.js.map +1 -0
- package/dist/base/ClientOnly.d.ts +10 -0
- package/dist/base/ClientOnly.js +18 -0
- package/dist/base/ClientOnly.js.map +1 -0
- package/dist/base/CloseButton.js +3 -3
- package/dist/base/CloseButton.js.map +1 -1
- package/dist/base/CodeBlock.js +5 -5
- package/dist/base/CodeBlock.js.map +1 -1
- package/dist/base/CopyButton.js +3 -3
- package/dist/base/CopyButton.js.map +1 -1
- package/dist/base/Icon.js +3 -3
- package/dist/base/Icon.js.map +1 -1
- package/dist/base/Indicator.js +3 -3
- package/dist/base/Indicator.js.map +1 -1
- package/dist/base/StatusDot.js +3 -3
- package/dist/base/StatusDot.js.map +1 -1
- package/dist/base/Tag.js +5 -5
- package/dist/base/Tag.js.map +1 -1
- package/dist/base/button-core.js +4 -4
- package/dist/base/button-core.js.map +1 -1
- package/dist/charts/AreaChart.js +3 -3
- package/dist/charts/AreaChart.js.map +1 -1
- package/dist/charts/BarChart.js +3 -3
- package/dist/charts/BarChart.js.map +1 -1
- package/dist/charts/ChordChart.js +3 -3
- package/dist/charts/ChordChart.js.map +1 -1
- package/dist/charts/ComboChart.js +3 -3
- package/dist/charts/ComboChart.js.map +1 -1
- package/dist/charts/DonutChart.js +3 -3
- package/dist/charts/DonutChart.js.map +1 -1
- package/dist/charts/FunnelChart.js +5 -5
- package/dist/charts/FunnelChart.js.map +1 -1
- package/dist/charts/GraphChart.js +3 -3
- package/dist/charts/GraphChart.js.map +1 -1
- package/dist/charts/LineChart.js +3 -3
- package/dist/charts/LineChart.js.map +1 -1
- package/dist/charts/MapChart.js +7 -7
- package/dist/charts/MapChart.js.map +1 -1
- package/dist/charts/RadarChart.js +16 -15
- package/dist/charts/RadarChart.js.map +1 -1
- package/dist/charts/SankeyChart.js +3 -3
- package/dist/charts/SankeyChart.js.map +1 -1
- package/dist/charts/ScatterChart.js +3 -3
- package/dist/charts/ScatterChart.js.map +1 -1
- package/dist/charts/TimelineChart.js +6 -5
- package/dist/charts/TimelineChart.js.map +1 -1
- package/dist/charts/TreemapChart.js +3 -3
- package/dist/charts/TreemapChart.js.map +1 -1
- package/dist/charts/WaterfallChart.js +3 -3
- package/dist/charts/WaterfallChart.js.map +1 -1
- package/dist/charts/XYChart.js +9 -7
- package/dist/charts/XYChart.js.map +1 -1
- package/dist/charts/frame.js +10 -8
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/single.js +4 -3
- package/dist/charts/single.js.map +1 -1
- package/dist/code-editor/CodeEditor.d.ts +18 -0
- package/dist/code-editor/CodeEditor.js +57 -0
- package/dist/code-editor/CodeEditor.js.map +1 -0
- package/dist/code-editor/editor.d.ts +52 -0
- package/dist/code-editor/editor.js +225 -0
- package/dist/code-editor/editor.js.map +1 -0
- package/dist/code-editor/index.d.ts +9 -0
- package/dist/code-editor/index.js +3 -0
- package/dist/config/Provider.d.ts +3 -1
- package/dist/config/Provider.js +9 -4
- package/dist/config/Provider.js.map +1 -1
- package/dist/config/context.d.ts +18 -0
- package/dist/config/context.js +16 -1
- package/dist/config/context.js.map +1 -1
- package/dist/config/createUi.d.ts +20 -3
- package/dist/config/createUi.js +80 -49
- package/dist/config/createUi.js.map +1 -1
- package/dist/config/lang/en-US.js +21 -3
- package/dist/config/lang/en-US.js.map +1 -1
- package/dist/config/lang/format.d.ts +2 -1
- package/dist/config/lang/format.js +9 -2
- package/dist/config/lang/format.js.map +1 -1
- package/dist/config/lang/lang.d.ts +19 -6
- package/dist/config/lang/lang.js +11 -2
- package/dist/config/lang/lang.js.map +1 -1
- package/dist/config/lang/zh-CN.js +21 -3
- package/dist/config/lang/zh-CN.js.map +1 -1
- package/dist/config/layout/preference.d.ts +43 -0
- package/dist/config/layout/preference.js +108 -0
- package/dist/config/layout/preference.js.map +1 -0
- package/dist/date/Calendar.js +3 -3
- package/dist/date/Calendar.js.map +1 -1
- package/dist/date/CalendarBoard.js +9 -9
- package/dist/date/CalendarBoard.js.map +1 -1
- package/dist/date/CalendarView.js +7 -7
- package/dist/date/CalendarView.js.map +1 -1
- package/dist/date/DateField.js +3 -3
- package/dist/date/DateField.js.map +1 -1
- package/dist/date/DatePicker.js +5 -5
- package/dist/date/DatePicker.js.map +1 -1
- package/dist/date/DateRangePicker.js +5 -5
- package/dist/date/DateRangePicker.js.map +1 -1
- package/dist/date/DateSegmentGroup.js +5 -5
- package/dist/date/DateSegmentGroup.js.map +1 -1
- package/dist/date/QuarterCalendar.js +6 -6
- package/dist/date/QuarterCalendar.js.map +1 -1
- package/dist/date/RangeCalendar.js +3 -3
- package/dist/date/RangeCalendar.js.map +1 -1
- package/dist/date/SegmentedField.js +3 -3
- package/dist/date/SegmentedField.js.map +1 -1
- package/dist/date/TimeField.js +3 -3
- package/dist/date/TimeField.js.map +1 -1
- package/dist/date/TimePicker.js +4 -4
- package/dist/date/TimePicker.js.map +1 -1
- package/dist/date/date-segments.js +1 -1
- package/dist/date/date-segments.js.map +1 -1
- package/dist/date/picker-popover.js +3 -2
- package/dist/date/picker-popover.js.map +1 -1
- package/dist/diagram/Diagram.js +12 -12
- package/dist/diagram/Diagram.js.map +1 -1
- package/dist/diagram/DiagramLanes.js +3 -3
- package/dist/diagram/DiagramLanes.js.map +1 -1
- package/dist/diagram/DiagramMinimap.js +4 -4
- package/dist/diagram/DiagramMinimap.js.map +1 -1
- package/dist/diagram/index.d.ts +2 -1
- package/dist/diagram/index.js +2 -1
- package/dist/diagram/layout.d.ts +57 -0
- package/dist/diagram/layout.js +50 -0
- package/dist/diagram/layout.js.map +1 -0
- package/dist/display/Accordion.js +6 -6
- package/dist/display/Accordion.js.map +1 -1
- package/dist/display/AnimatedNumber.js +4 -4
- package/dist/display/AnimatedNumber.js.map +1 -1
- package/dist/display/Avatar.js +4 -4
- package/dist/display/Avatar.js.map +1 -1
- package/dist/display/Checklist.js +7 -7
- package/dist/display/Checklist.js.map +1 -1
- package/dist/display/Collapse.js +8 -5
- package/dist/display/Collapse.js.map +1 -1
- package/dist/display/Collapsible.js +3 -3
- package/dist/display/Collapsible.js.map +1 -1
- package/dist/display/Descriptions.js +5 -5
- package/dist/display/Descriptions.js.map +1 -1
- package/dist/display/Ellipsis.js +3 -3
- package/dist/display/Ellipsis.js.map +1 -1
- package/dist/display/FieldCompare.js +4 -4
- package/dist/display/FieldCompare.js.map +1 -1
- package/dist/display/Gauge.js +11 -11
- package/dist/display/Gauge.js.map +1 -1
- package/dist/display/Image.js +4 -4
- package/dist/display/Image.js.map +1 -1
- package/dist/display/Marquee.js +3 -3
- package/dist/display/Marquee.js.map +1 -1
- package/dist/display/ProportionBar.js +4 -4
- package/dist/display/ProportionBar.js.map +1 -1
- package/dist/display/Sortable.js +4 -4
- package/dist/display/Sortable.js.map +1 -1
- package/dist/display/Sparkline.js +6 -6
- package/dist/display/Sparkline.js.map +1 -1
- package/dist/display/Stat.js +3 -3
- package/dist/display/Stat.js.map +1 -1
- package/dist/display/Timeline.js +7 -7
- package/dist/display/Timeline.js.map +1 -1
- package/dist/display/Tree.js +10 -10
- package/dist/display/Tree.js.map +1 -1
- package/dist/display/VirtualList.js +7 -7
- package/dist/display/VirtualList.js.map +1 -1
- package/dist/display/Watermark.js +3 -3
- package/dist/display/Watermark.js.map +1 -1
- package/dist/docs-kit/CodeGroup.js +5 -5
- package/dist/docs-kit/CodeGroup.js.map +1 -1
- package/dist/docs-kit/CodePreview.js +6 -6
- package/dist/docs-kit/CodePreview.js.map +1 -1
- package/dist/docs-kit/PropsTable.js +4 -4
- package/dist/docs-kit/PropsTable.js.map +1 -1
- package/dist/feedback/Alert.js +5 -5
- package/dist/feedback/Alert.js.map +1 -1
- package/dist/feedback/Banner.js +5 -5
- package/dist/feedback/Banner.js.map +1 -1
- package/dist/feedback/Empty.js +4 -4
- package/dist/feedback/Empty.js.map +1 -1
- package/dist/feedback/LoadingBar.js +20 -13
- package/dist/feedback/LoadingBar.js.map +1 -1
- package/dist/feedback/LoadingOverlay.js +3 -3
- package/dist/feedback/LoadingOverlay.js.map +1 -1
- package/dist/feedback/Progress.js +14 -14
- package/dist/feedback/Progress.js.map +1 -1
- package/dist/feedback/Result.js +4 -4
- package/dist/feedback/Result.js.map +1 -1
- package/dist/feedback/SkeletonText.js +3 -3
- package/dist/feedback/SkeletonText.js.map +1 -1
- package/dist/feedback/Toast.js +6 -6
- package/dist/feedback/Toast.js.map +1 -1
- package/dist/form/Field.d.ts +7 -0
- package/dist/form/Field.js +20 -9
- package/dist/form/Field.js.map +1 -1
- package/dist/form/Form.js +3 -3
- package/dist/form/Form.js.map +1 -1
- package/dist/form/FormErrorSummary.js +3 -3
- package/dist/form/FormErrorSummary.js.map +1 -1
- package/dist/form/FormSection.js +6 -6
- package/dist/form/FormSection.js.map +1 -1
- package/dist/form/useForm.d.ts +4 -1
- package/dist/form/useForm.js +35 -13
- package/dist/form/useForm.js.map +1 -1
- package/dist/index.d.ts +18 -10
- package/dist/index.js +17 -9
- package/dist/input/Autocomplete.js +3 -3
- package/dist/input/Autocomplete.js.map +1 -1
- package/dist/input/Cascader.js +7 -7
- package/dist/input/Cascader.js.map +1 -1
- package/dist/input/CharacterCount.js +3 -3
- package/dist/input/CharacterCount.js.map +1 -1
- package/dist/input/Checkbox.js +5 -5
- package/dist/input/Checkbox.js.map +1 -1
- package/dist/input/ColorField.js +4 -4
- package/dist/input/ColorField.js.map +1 -1
- package/dist/input/Combobox.js +5 -5
- package/dist/input/Combobox.js.map +1 -1
- package/dist/input/ConditionBuilder.js +15 -14
- package/dist/input/ConditionBuilder.js.map +1 -1
- package/dist/input/FileDrop.js +3 -3
- package/dist/input/FileDrop.js.map +1 -1
- package/dist/input/Listbox.js +9 -9
- package/dist/input/Listbox.js.map +1 -1
- package/dist/input/Mentions.js +4 -4
- package/dist/input/Mentions.js.map +1 -1
- package/dist/input/NumberField.js +3 -3
- package/dist/input/NumberField.js.map +1 -1
- package/dist/input/NumberRangeField.js +5 -5
- package/dist/input/NumberRangeField.js.map +1 -1
- package/dist/input/OtpField.js +5 -5
- package/dist/input/OtpField.js.map +1 -1
- package/dist/input/PeoplePicker.js +6 -6
- package/dist/input/PeoplePicker.js.map +1 -1
- package/dist/input/PeoplePickerPanel.js +15 -15
- package/dist/input/PeoplePickerPanel.js.map +1 -1
- package/dist/input/Radio.js +4 -4
- package/dist/input/Radio.js.map +1 -1
- package/dist/input/Rating.js +5 -5
- package/dist/input/Rating.js.map +1 -1
- package/dist/input/Select.js +5 -5
- package/dist/input/Select.js.map +1 -1
- package/dist/input/SelectedTags.js +4 -4
- package/dist/input/SelectedTags.js.map +1 -1
- package/dist/input/Slider.js +6 -6
- package/dist/input/Slider.js.map +1 -1
- package/dist/input/Switch.js +3 -3
- package/dist/input/Switch.js.map +1 -1
- package/dist/input/TagsInput.js +5 -5
- package/dist/input/TagsInput.js.map +1 -1
- package/dist/input/TextField.js +5 -5
- package/dist/input/TextField.js.map +1 -1
- package/dist/input/Textarea.js +4 -4
- package/dist/input/Textarea.js.map +1 -1
- package/dist/input/ToggleGroup.js +4 -4
- package/dist/input/ToggleGroup.js.map +1 -1
- package/dist/input/Transfer.js +8 -8
- package/dist/input/Transfer.js.map +1 -1
- package/dist/input/TreeSelect.js +7 -7
- package/dist/input/TreeSelect.js.map +1 -1
- package/dist/input/Upload.js +10 -9
- package/dist/input/Upload.js.map +1 -1
- package/dist/input/condition.d.ts +1 -1
- package/dist/input/condition.js +32 -14
- package/dist/input/condition.js.map +1 -1
- package/dist/input/people.d.ts +15 -14
- package/dist/input/people.js +5 -5
- package/dist/input/people.js.map +1 -1
- package/dist/input/remote-items.d.ts +4 -2
- package/dist/input/remote-items.js +7 -2
- package/dist/input/remote-items.js.map +1 -1
- package/dist/layout/Affix.js +4 -4
- package/dist/layout/Affix.js.map +1 -1
- package/dist/layout/ResizeHandle.d.ts +6 -2
- package/dist/layout/ResizeHandle.js +32 -9
- package/dist/layout/ResizeHandle.js.map +1 -1
- package/dist/layout/ScrollArea.js +3 -3
- package/dist/layout/ScrollArea.js.map +1 -1
- package/dist/layout/Separator.js +3 -3
- package/dist/layout/Separator.js.map +1 -1
- package/dist/layout/Splitter.js +3 -3
- package/dist/layout/Splitter.js.map +1 -1
- package/dist/layout/ViewportFill.d.ts +2 -2
- package/dist/layout/ViewportFill.js +4 -4
- package/dist/layout/ViewportFill.js.map +1 -1
- package/dist/navigation/Breadcrumbs.js +4 -4
- package/dist/navigation/Breadcrumbs.js.map +1 -1
- package/dist/navigation/NavBar.js +6 -6
- package/dist/navigation/NavBar.js.map +1 -1
- package/dist/navigation/NavList.d.ts +1 -0
- package/dist/navigation/NavList.js +20 -12
- package/dist/navigation/NavList.js.map +1 -1
- package/dist/navigation/NavMenu.d.ts +27 -0
- package/dist/navigation/NavMenu.js +54 -0
- package/dist/navigation/NavMenu.js.map +1 -0
- package/dist/navigation/PageJump.js +3 -3
- package/dist/navigation/PageJump.js.map +1 -1
- package/dist/navigation/PageSizeSelect.js +4 -4
- package/dist/navigation/PageSizeSelect.js.map +1 -1
- package/dist/navigation/Pagination.js +6 -6
- package/dist/navigation/Pagination.js.map +1 -1
- package/dist/navigation/PaginationBar.js +5 -5
- package/dist/navigation/PaginationBar.js.map +1 -1
- package/dist/navigation/Steps.js +4 -4
- package/dist/navigation/Steps.js.map +1 -1
- package/dist/navigation/TableOfContents.js +5 -5
- package/dist/navigation/TableOfContents.js.map +1 -1
- package/dist/navigation/Tabs.js +7 -7
- package/dist/navigation/Tabs.js.map +1 -1
- package/dist/navigation/Toolbar.js +3 -3
- package/dist/navigation/Toolbar.js.map +1 -1
- package/dist/overlay/AlertDialog.js +4 -4
- package/dist/overlay/AlertDialog.js.map +1 -1
- package/dist/overlay/CommandPalette.js +4 -4
- package/dist/overlay/CommandPalette.js.map +1 -1
- package/dist/overlay/ContextMenu.js +3 -3
- package/dist/overlay/ContextMenu.js.map +1 -1
- package/dist/overlay/Dialog.js +4 -4
- package/dist/overlay/Dialog.js.map +1 -1
- package/dist/overlay/Drawer.js +5 -5
- package/dist/overlay/Drawer.js.map +1 -1
- package/dist/overlay/HoverCard.js +5 -3
- package/dist/overlay/HoverCard.js.map +1 -1
- package/dist/overlay/Lightbox.js +5 -5
- package/dist/overlay/Lightbox.js.map +1 -1
- package/dist/overlay/Menu.js +7 -7
- package/dist/overlay/Menu.js.map +1 -1
- package/dist/overlay/ModalCore.js +9 -9
- package/dist/overlay/ModalCore.js.map +1 -1
- package/dist/overlay/Popconfirm.js +6 -6
- package/dist/overlay/Popconfirm.js.map +1 -1
- package/dist/overlay/Popover.js +5 -3
- package/dist/overlay/Popover.js.map +1 -1
- package/dist/overlay/Tooltip.js +5 -3
- package/dist/overlay/Tooltip.js.map +1 -1
- package/dist/overlay/Tour.js +8 -8
- package/dist/overlay/Tour.js.map +1 -1
- package/dist/overlay/detached.d.ts +2 -0
- package/dist/overlay/detached.js +73 -42
- package/dist/overlay/detached.js.map +1 -1
- package/dist/patterns/ActionBar.js +3 -3
- package/dist/patterns/ActionBar.js.map +1 -1
- package/dist/patterns/AppShell.d.ts +28 -1
- package/dist/patterns/AppShell.js +158 -52
- package/dist/patterns/AppShell.js.map +1 -1
- package/dist/patterns/AuthLayout.d.ts +28 -0
- package/dist/patterns/AuthLayout.js +77 -0
- package/dist/patterns/AuthLayout.js.map +1 -0
- package/dist/patterns/CommentThread.js +9 -9
- package/dist/patterns/CommentThread.js.map +1 -1
- package/dist/patterns/DataImport.js +4 -4
- package/dist/patterns/DataImport.js.map +1 -1
- package/dist/patterns/DeadlineBadge.js +3 -3
- package/dist/patterns/DeadlineBadge.js.map +1 -1
- package/dist/patterns/FilterBar.d.ts +11 -1
- package/dist/patterns/FilterBar.js +39 -10
- package/dist/patterns/FilterBar.js.map +1 -1
- package/dist/patterns/FormDialog.d.ts +18 -0
- package/dist/patterns/FormDialog.js +46 -0
- package/dist/patterns/FormDialog.js.map +1 -0
- package/dist/patterns/KanbanBoard.js +8 -8
- package/dist/patterns/KanbanBoard.js.map +1 -1
- package/dist/patterns/LayoutSwitcher.d.ts +12 -0
- package/dist/patterns/LayoutSwitcher.js +79 -0
- package/dist/patterns/LayoutSwitcher.js.map +1 -0
- package/dist/patterns/NotificationCenter.js +8 -8
- package/dist/patterns/NotificationCenter.js.map +1 -1
- package/dist/patterns/PageTabs.d.ts +12 -7
- package/dist/patterns/PageTabs.js +41 -29
- package/dist/patterns/PageTabs.js.map +1 -1
- package/dist/patterns/QueryTable.d.ts +10 -1
- package/dist/patterns/QueryTable.js +128 -68
- package/dist/patterns/QueryTable.js.map +1 -1
- package/dist/patterns/SlideCaptcha.d.ts +80 -0
- package/dist/patterns/SlideCaptcha.js +354 -0
- package/dist/patterns/SlideCaptcha.js.map +1 -0
- package/dist/patterns/StepsForm.js +7 -7
- package/dist/patterns/StepsForm.js.map +1 -1
- package/dist/patterns/ThemeSwitcher.js +3 -3
- package/dist/patterns/ThemeSwitcher.js.map +1 -1
- package/dist/patterns/index.d.ts +7 -3
- package/dist/patterns/index.js +5 -1
- package/dist/patterns/messages.d.ts +39 -1
- package/dist/patterns/messages.js +40 -2
- package/dist/patterns/messages.js.map +1 -1
- package/dist/table/ColumnHeaderActions.js +3 -3
- package/dist/table/ColumnHeaderActions.js.map +1 -1
- package/dist/table/ColumnResizer.js +3 -3
- package/dist/table/ColumnResizer.js.map +1 -1
- package/dist/table/ColumnSettings.js +5 -5
- package/dist/table/ColumnSettings.js.map +1 -1
- package/dist/table/ColumnTable.js +8 -8
- package/dist/table/ColumnTable.js.map +1 -1
- package/dist/table/DataTable.js +8 -8
- package/dist/table/DataTable.js.map +1 -1
- package/dist/table/DataTableView.js +21 -21
- package/dist/table/DataTableView.js.map +1 -1
- package/dist/table/PivotTable.js +3 -3
- package/dist/table/PivotTable.js.map +1 -1
- package/dist/table/SelectionBar.js +4 -4
- package/dist/table/SelectionBar.js.map +1 -1
- package/dist/table/TreeDataTable.js +5 -5
- package/dist/table/TreeDataTable.js.map +1 -1
- package/dist/theme-customize/ThemeCustomizer.js +7 -6
- package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
- package/dist/theme-customize/ThemeThumbnail.js +3 -3
- package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
- package/dist/three/background/AuroraBackground.js +3 -3
- package/dist/three/background/AuroraBackground.js.map +1 -1
- package/dist/three/background/MeshGradient.js +3 -3
- package/dist/three/background/MeshGradient.js.map +1 -1
- package/dist/three/background/ShaderBackground.js +3 -3
- package/dist/three/background/ShaderBackground.js.map +1 -1
- package/dist/three/core/EffectSurface.js +3 -3
- package/dist/three/core/EffectSurface.js.map +1 -1
- package/dist/three/core/ThreeCanvas.js +4 -4
- package/dist/three/core/ThreeCanvas.js.map +1 -1
- package/dist/three/effects/Confetti.js +3 -3
- package/dist/three/effects/Confetti.js.map +1 -1
- package/dist/three/effects/ParticleField.js +3 -3
- package/dist/three/effects/ParticleField.js.map +1 -1
- package/dist/three/effects/WaveGrid.js +3 -3
- package/dist/three/effects/WaveGrid.js.map +1 -1
- package/dist/three/globe/Globe.js +3 -3
- package/dist/three/globe/Globe.js.map +1 -1
- package/dist/three/model/ModelViewer.js +3 -3
- package/dist/three/model/ModelViewer.js.map +1 -1
- package/dist/utils/data/clone.d.ts +8 -0
- package/dist/utils/data/clone.js +21 -0
- package/dist/utils/data/clone.js.map +1 -0
- package/dist/utils/data/date.d.ts +10 -0
- package/dist/utils/data/date.js +13 -1
- package/dist/utils/data/date.js.map +1 -1
- package/dist/utils/data/number.d.ts +5 -0
- package/dist/utils/data/number.js +8 -1
- package/dist/utils/data/number.js.map +1 -1
- package/dist/utils/data/numeric.d.ts +7 -0
- package/dist/utils/data/numeric.js +46 -1
- package/dist/utils/data/numeric.js.map +1 -1
- package/dist/utils/dom/download.d.ts +8 -1
- package/dist/utils/dom/download.js +19 -2
- package/dist/utils/dom/download.js.map +1 -1
- package/dist/utils/dom/element.d.ts +3 -1
- package/dist/utils/dom/element.js +8 -4
- package/dist/utils/dom/element.js.map +1 -1
- package/dist/utils/dom/fullscreen.d.ts +1 -1
- package/dist/utils/dom/fullscreen.js +12 -8
- package/dist/utils/dom/fullscreen.js.map +1 -1
- package/dist/utils/dom/mounted.d.ts +7 -0
- package/dist/utils/dom/mounted.js +16 -0
- package/dist/utils/dom/mounted.js.map +1 -0
- package/dist/utils/dom/overflow.js +2 -1
- package/dist/utils/dom/overflow.js.map +1 -1
- package/dist/utils/dom/pan-zoom.js +2 -1
- package/dist/utils/dom/pan-zoom.js.map +1 -1
- package/dist/utils/props.js +3 -13
- package/dist/utils/props.js.map +1 -1
- package/dist/utils/request/error-message.d.ts +17 -0
- package/dist/utils/request/error-message.js +50 -0
- package/dist/utils/request/error-message.js.map +1 -0
- package/dist/utils/request/http.d.ts +80 -4
- package/dist/utils/request/http.js +121 -24
- package/dist/utils/request/http.js.map +1 -1
- package/dist/utils/request/use-autosave.d.ts +35 -0
- package/dist/utils/request/use-autosave.js +69 -0
- package/dist/utils/request/use-autosave.js.map +1 -0
- package/dist/utils/request/use-request.js +4 -2
- package/dist/utils/request/use-request.js.map +1 -1
- package/package.json +57 -4
package/dist/overlay/Tooltip.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { mergeAttrs } from "../utils/props.js";
|
|
2
2
|
import { transitions } from "../utils/style/transitions.js";
|
|
3
|
+
import { useMounted } from "../utils/dom/mounted.js";
|
|
3
4
|
import { floatingStyles } from "../utils/dom/floating.js";
|
|
4
5
|
import { createHoverGroup } from "../utils/dom/hover-intent.js";
|
|
5
6
|
import { openSetter } from "../utils/dom/open-change.js";
|
|
6
7
|
import { useHoverLayer } from "../utils/dom/hover-layer.js";
|
|
7
|
-
import { Fragment, createVNode
|
|
8
|
-
import { _component, bindable, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
8
|
+
import { Fragment, createVNode } from "vue";
|
|
9
|
+
import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
9
10
|
import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
10
11
|
//#region src/overlay/Tooltip.tsx
|
|
11
12
|
/** 交给触发器的属性:展开到触发元素上(`{...props}`) */
|
|
@@ -41,6 +42,7 @@ var Tooltip = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
41
42
|
const propsArrow = readonlyProp(_props, "propsArrow");
|
|
42
43
|
const children = childrenProp(_props);
|
|
43
44
|
const rest = restProps(_props, _ctx, false);
|
|
45
|
+
const mounted = useMounted();
|
|
44
46
|
const layer = useHoverLayer(tooltips, () => ({
|
|
45
47
|
open: open.value,
|
|
46
48
|
disabled: disabled.value,
|
|
@@ -53,7 +55,7 @@ var Tooltip = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
53
55
|
ref: layer.anchorRef,
|
|
54
56
|
"aria-describedby": layer.id,
|
|
55
57
|
...layer.hover.trigger
|
|
56
|
-
}), createVNode("div",
|
|
58
|
+
}), mounted.value && createVNode("div", mergeJsxProps(mergeAttrs({ sx: [
|
|
57
59
|
floatingStyles.anchored,
|
|
58
60
|
tooltipStyles.panel,
|
|
59
61
|
transitions.fade,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/overlay/Tooltip.tsx"],"sourcesContent":["/**\n * 文字提示(role=\"tooltip\"):指针停在触发器上、或用键盘聚焦它时,显示一句简短说明(图标按钮的用途、快捷键)。\n * 参考 WAI-ARIA Tooltip 模式、Radix Tooltip、React Aria Tooltip:\n *\n * <Tooltip trigger={(props) => <IconButton {...props} icon={Copy} aria-label=\"复制\" />}>复制(Ctrl+C)</Tooltip>\n *\n * - 指针停留 delay 毫秒后显示;刚有提示关掉(skipDelay 内)时直接显示,在一排按钮上移动不用每次等;\n * - 键盘聚焦(:focus-visible)立即显示,失焦、Esc、按下触发器时隐藏;触屏不显示(没有悬停);\n * - 指针可以移到提示上而不消失(WCAG 1.4.13);同一时间只显示一个;\n * - 提示是对触发器的补充说明(aria-describedby):触发器自己要有名称,提示里不放可交互的内容。\n *\n * 用 popover=\"manual\" 渲染在顶层:它不是 auto,不会关掉正打开的菜单或弹出框。开关、定位、Esc 见 useHoverLayer(与 HoverCard 共用)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport {\n floatingStyles,\n type FloatingOptions,\n type FloatingPlacement,\n} from '../utils/dom/floating';\nimport { createHoverGroup } from '../utils/dom/hover-intent';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { useHoverLayer } from '../utils/dom/hover-layer';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { transitions } from '../utils/style/transitions';\n\n/** 交给触发器的属性:展开到触发元素上(`{...props}`) */\nexport interface TooltipTriggerProps {\n /** 取得触发器元素:定位的参照 */\n ref: (element: unknown) => void;\n /** 提示是对触发器的补充说明 */\n 'aria-describedby': string;\n /** 指针进入:等 delay 后显示 */\n onPointerenter: (event: PointerEvent) => void;\n /** 指针离开:稍后隐藏(可以移到提示上) */\n onPointerleave: (event: PointerEvent) => void;\n /** 按下(点击)触发器时隐藏 */\n onPointerdown: (event: PointerEvent) => void;\n /** 键盘聚焦时立即显示 */\n onFocus: (event: FocusEvent) => void;\n /** 失焦时隐藏 */\n onBlur: (event: FocusEvent) => void;\n}\n\n/** 未声明的属性落到提示的 div 上 */\nexport interface TooltipProps\n extends\n PartProps<'div', 'id' | 'popover' | 'role'>,\n Pick<FloatingOptions, 'offset'>,\n OpenChangeProps {\n /** 是否显示:父级可以写 _open={x} 控制或得知;一般不需要 */\n _open?: boolean;\n /** 显示位置,默认 top;空间不够时自动翻转 */\n placement?: FloatingPlacement;\n /** 指针停留多久后显示(毫秒),默认 500 */\n delay?: number;\n /** 不显示(触发器照常渲染) */\n disabled?: boolean;\n /** 显示指向触发器的箭头 */\n arrow?: boolean;\n /** 触发器:`(props) => <IconButton {...props} … />` */\n trigger: (props: TooltipTriggerProps) => VNodeChild;\n /** 箭头的部件属性 */\n propsArrow?: PartProps<'span'>;\n /** 提示文字 */\n children?: VNodeChild;\n}\n\n/** 指针离开后多久隐藏(毫秒):留出移到提示上的时间 */\nconst CLOSE_DELAY = 100;\n\n/** 所有提示一组:同一时间只显示一个,刚关掉一个时下一个不用等 delay */\nconst tooltips = createHoverGroup();\n\n/** Tooltip 的样式:panel */\nexport const tooltipStyles = css.create({\n panel: {\n boxSizing: 'border-box',\n maxWidth: 'min(20em, calc(100vw - 2em))',\n paddingBlock: '_xs',\n paddingInline: '_sm',\n borderWidth: 0,\n borderRadius: '_sm',\n backgroundColor: '_inverseSurface',\n color: '_inverseText',\n fontSize: '_sm',\n lineHeight: '_normal',\n overflowWrap: 'break-word',\n },\n});\n\n/** 文字提示:悬停或键盘聚焦时显示在触发器旁边 */\nexport const Tooltip = _component(\n ({\n _open: open = _bindable(false),\n onOpenChange,\n placement = 'top',\n offset,\n delay = 500,\n disabled = false,\n arrow = false,\n trigger,\n propsArrow,\n children,\n ...rest\n }: TooltipProps) => {\n const layer = useHoverLayer(\n tooltips,\n () => ({ open, disabled, placement, offset, delay, closeDelay: CLOSE_DELAY }),\n openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n ),\n );\n\n return () => (\n <>\n {trigger({\n ref: layer.anchorRef,\n 'aria-describedby': layer.id,\n ...layer.hover.trigger,\n })}\n <div\n
|
|
1
|
+
{"version":3,"file":"Tooltip.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/overlay/Tooltip.tsx"],"sourcesContent":["/**\n * 文字提示(role=\"tooltip\"):指针停在触发器上、或用键盘聚焦它时,显示一句简短说明(图标按钮的用途、快捷键)。\n * 参考 WAI-ARIA Tooltip 模式、Radix Tooltip、React Aria Tooltip:\n *\n * <Tooltip trigger={(props) => <IconButton {...props} icon={Copy} aria-label=\"复制\" />}>复制(Ctrl+C)</Tooltip>\n *\n * - 指针停留 delay 毫秒后显示;刚有提示关掉(skipDelay 内)时直接显示,在一排按钮上移动不用每次等;\n * - 键盘聚焦(:focus-visible)立即显示,失焦、Esc、按下触发器时隐藏;触屏不显示(没有悬停);\n * - 指针可以移到提示上而不消失(WCAG 1.4.13);同一时间只显示一个;\n * - 提示是对触发器的补充说明(aria-describedby):触发器自己要有名称,提示里不放可交互的内容。\n *\n * 用 popover=\"manual\" 渲染在顶层:它不是 auto,不会关掉正打开的菜单或弹出框。开关、定位、Esc 见 useHoverLayer(与 HoverCard 共用)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport {\n floatingStyles,\n type FloatingOptions,\n type FloatingPlacement,\n} from '../utils/dom/floating';\nimport { createHoverGroup } from '../utils/dom/hover-intent';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { useHoverLayer } from '../utils/dom/hover-layer';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { transitions } from '../utils/style/transitions';\nimport { useMounted } from '../utils/dom/mounted';\n\n/** 交给触发器的属性:展开到触发元素上(`{...props}`) */\nexport interface TooltipTriggerProps {\n /** 取得触发器元素:定位的参照 */\n ref: (element: unknown) => void;\n /** 提示是对触发器的补充说明 */\n 'aria-describedby': string;\n /** 指针进入:等 delay 后显示 */\n onPointerenter: (event: PointerEvent) => void;\n /** 指针离开:稍后隐藏(可以移到提示上) */\n onPointerleave: (event: PointerEvent) => void;\n /** 按下(点击)触发器时隐藏 */\n onPointerdown: (event: PointerEvent) => void;\n /** 键盘聚焦时立即显示 */\n onFocus: (event: FocusEvent) => void;\n /** 失焦时隐藏 */\n onBlur: (event: FocusEvent) => void;\n}\n\n/** 未声明的属性落到提示的 div 上 */\nexport interface TooltipProps\n extends\n PartProps<'div', 'id' | 'popover' | 'role'>,\n Pick<FloatingOptions, 'offset'>,\n OpenChangeProps {\n /** 是否显示:父级可以写 _open={x} 控制或得知;一般不需要 */\n _open?: boolean;\n /** 显示位置,默认 top;空间不够时自动翻转 */\n placement?: FloatingPlacement;\n /** 指针停留多久后显示(毫秒),默认 500 */\n delay?: number;\n /** 不显示(触发器照常渲染) */\n disabled?: boolean;\n /** 显示指向触发器的箭头 */\n arrow?: boolean;\n /** 触发器:`(props) => <IconButton {...props} … />` */\n trigger: (props: TooltipTriggerProps) => VNodeChild;\n /** 箭头的部件属性 */\n propsArrow?: PartProps<'span'>;\n /** 提示文字 */\n children?: VNodeChild;\n}\n\n/** 指针离开后多久隐藏(毫秒):留出移到提示上的时间 */\nconst CLOSE_DELAY = 100;\n\n/** 所有提示一组:同一时间只显示一个,刚关掉一个时下一个不用等 delay */\nconst tooltips = createHoverGroup();\n\n/** Tooltip 的样式:panel */\nexport const tooltipStyles = css.create({\n panel: {\n boxSizing: 'border-box',\n maxWidth: 'min(20em, calc(100vw - 2em))',\n paddingBlock: '_xs',\n paddingInline: '_sm',\n borderWidth: 0,\n borderRadius: '_sm',\n backgroundColor: '_inverseSurface',\n color: '_inverseText',\n fontSize: '_sm',\n lineHeight: '_normal',\n overflowWrap: 'break-word',\n },\n});\n\n/** 文字提示:悬停或键盘聚焦时显示在触发器旁边 */\nexport const Tooltip = _component(\n ({\n _open: open = _bindable(false),\n onOpenChange,\n placement = 'top',\n offset,\n delay = 500,\n disabled = false,\n arrow = false,\n trigger,\n propsArrow,\n children,\n ...rest\n }: TooltipProps) => {\n // 面板挂载后才渲染:关着时本来就看不见;服务端渲染时也不输出,触发器在 <p> 里时 <div> 不会把段落提前截断,水合对得上\n const mounted = useMounted();\n const layer = useHoverLayer(\n tooltips,\n () => ({ open, disabled, placement, offset, delay, closeDelay: CLOSE_DELAY }),\n openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n ),\n );\n\n return () => (\n <>\n {trigger({\n ref: layer.anchorRef,\n 'aria-describedby': layer.id,\n ...layer.hover.trigger,\n })}\n {mounted.value && (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n floatingStyles.anchored,\n tooltipStyles.panel,\n transitions.fade,\n arrow && floatingStyles.withArrow,\n ],\n },\n rest,\n {\n ref: layer.panelRef,\n id: layer.id,\n popover: 'manual',\n role: 'tooltip',\n // 指针移到提示上不消失,离开提示后再隐藏\n ...layer.hover.panel,\n },\n )}\n data-state={open && !disabled ? 'open' : 'closed'}\n >\n {children}\n {arrow && <span {...layer.arrowProps(propsArrow)} />}\n </div>\n )}\n </>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;AAuEA,IAAM,cAAc;;AAGpB,IAAM,WAAW,iBAAiB;;AAGlC,IAAa,gBAAgB,IAAI,OAAO,EACtC,OAAO;CACL,WAAW;CACX,UAAU;CACV,cAAc;CACd,eAAe;CACf,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,OAAO;CACP,UAAU;CACV,YAAY;CACZ,cAAc;AAChB,EACF,CAAC;;AAGD,IAAa,UAAU,0BACrB,QAAA,SAYoB;CAAA,MAAA,OAAAA,SAAA,QAAA,eAXM,OAAK,KAAA,IAAA;CAAA,MAAA,eAAAC,aAAA,QAAA,cAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,aAEjB,KAAK;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,SAET,GAAG;CAAA,MAAA,WAAAA,aAAA,QAAA,YACA,KAAK;CAAA,MAAA,QAAAA,aAAA,QAAA,SACR,KAAK;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAIV,OAAIC,UAAA,QAAA,MAAA,KAAA;CAGP,MAAM,UAAU,WAAW;CAC3B,MAAM,QAAQ,cACZ,iBACO;EAAE,MAAI,KAAA;EAAE,UAAQ,SAAA;EAAE,WAAS,UAAA;EAAE,QAAM,OAAA;EAAE,OAAK,MAAA;EAAE,YAAY;CAAY,IAC3E,iBACE,KAAA,QACC,SAAU,KAAA,QAAO,YAClB,aAAA,KACF,CACF;CAEA,aAAOC,YAAAC,UAAA,MAAA,CAEF,QAAA,MAAQ;EACP,KAAK,MAAM;EACX,oBAAoB,MAAM;EAC1B,GAAG,MAAM,MAAM;CACjB,CAAC,GACA,QAAQ,SAAKD,YAAA,OAAAE,cAEN,WACF,EACE,IAAI;EACF,eAAe;EACf,cAAc;EACd,YAAY;EACZ,MAAA,SAAS,eAAe;CAAS,EAErC,GACA,MACA;EACE,KAAK,MAAM;EACX,IAAI,MAAM;EACV,SAAS;EACT,MAAM;EAEN,GAAG,MAAM,MAAM;CACjB,CACF,GAAC,EAAA,cACW,KAAA,SAAQ,CAAA,SAAA,QAAY,SAAS,SAAQ,CAAA,GAAA,CAAA,SAAA,OAGhD,MAAA,SAAAF,YAAA,QAAmB,MAAM,WAAU,WAAA,KAAW,GAAC,IAAA,CAAI,CAAA,CAEvD,CAAA;AAGP,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
|
package/dist/overlay/Tour.js
CHANGED
|
@@ -11,8 +11,8 @@ import { Flex } from "../layout/Flex.js";
|
|
|
11
11
|
import { anchorFloating, floatingStyles } from "../utils/dom/floating.js";
|
|
12
12
|
import { openSetter } from "../utils/dom/open-change.js";
|
|
13
13
|
import { isEditable } from "../utils/dom/hotkeys.js";
|
|
14
|
-
import { createVNode,
|
|
15
|
-
import { _component, bindable, effect, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
14
|
+
import { createVNode, nextTick, onBeforeUnmount, ref, shallowRef, useId } from "vue";
|
|
15
|
+
import { _component, bindable, effect, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
16
16
|
import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
17
17
|
import { autoUpdate } from "@floating-ui/dom";
|
|
18
18
|
//#region src/overlay/Tour.tsx
|
|
@@ -215,7 +215,7 @@ var Tour = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
215
215
|
});
|
|
216
216
|
return () => {
|
|
217
217
|
const currentStep = step();
|
|
218
|
-
return createVNode("dialog",
|
|
218
|
+
return createVNode("dialog", mergeJsxProps(mergeAttrs({ sx: tourStyles.root }, rest, {
|
|
219
219
|
ref: dialog,
|
|
220
220
|
"aria-labelledby": titleId,
|
|
221
221
|
"aria-describedby": currentStep?.content != null ? contentId : void 0,
|
|
@@ -241,14 +241,14 @@ var Tour = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
241
241
|
sx: tourStyles.title
|
|
242
242
|
}, propsTitle.value, { id: titleId }), { default: () => [currentStep.title] }),
|
|
243
243
|
currentStep.content != null && createVNode("div", mergeAttrs({ sx: tourStyles.content }, propsContent.value, { id: contentId }), [currentStep.content]),
|
|
244
|
-
createVNode(Flex,
|
|
244
|
+
createVNode(Flex, mergeJsxProps(mergePartProps({
|
|
245
245
|
align: "center",
|
|
246
246
|
gap: "sm",
|
|
247
247
|
wrap: true,
|
|
248
248
|
sx: tourStyles.footer
|
|
249
249
|
}, propsFooter.value), { "key": "__site4" }), {
|
|
250
250
|
default: () => [
|
|
251
|
-
createVNode(Text$1,
|
|
251
|
+
createVNode(Text$1, mergeJsxProps(mergePartProps({
|
|
252
252
|
size: "sm",
|
|
253
253
|
tone: "muted",
|
|
254
254
|
sx: tourStyles.progress
|
|
@@ -256,7 +256,7 @@ var Tour = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
256
256
|
default: () => [lang.tourProgress(current.value + 1, steps.value.length)],
|
|
257
257
|
$stable: true
|
|
258
258
|
}),
|
|
259
|
-
!last() && createVNode(Button,
|
|
259
|
+
!last() && createVNode(Button, mergeJsxProps(mergePartProps({
|
|
260
260
|
variant: "ghost",
|
|
261
261
|
tone: "neutral",
|
|
262
262
|
size: "sm"
|
|
@@ -264,14 +264,14 @@ var Tour = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
264
264
|
default: () => [lang.tourSkip],
|
|
265
265
|
$stable: true
|
|
266
266
|
}),
|
|
267
|
-
current.value > 0 && createVNode(Button,
|
|
267
|
+
current.value > 0 && createVNode(Button, mergeJsxProps(mergePartProps({
|
|
268
268
|
variant: "outline",
|
|
269
269
|
size: "sm"
|
|
270
270
|
}, propsPrevious.value, { onClick: () => current.value-- }), { "key": "__site2" }), {
|
|
271
271
|
default: () => [lang.tourPrevious],
|
|
272
272
|
$stable: true
|
|
273
273
|
}),
|
|
274
|
-
createVNode(Button,
|
|
274
|
+
createVNode(Button, mergeJsxProps(mergePartProps({ size: "sm" }, propsNext.value, { onClick: next }), { "key": "__site3" }), {
|
|
275
275
|
default: () => [last() ? lang.tourFinish : lang.tourNext],
|
|
276
276
|
$stable: true
|
|
277
277
|
})
|
package/dist/overlay/Tour.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tour.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps","Text"],"sources":["../../src/overlay/Tour.tsx"],"sourcesContent":["/**\n * 新手引导(原生模态 dialog):一步一步高亮页面上的元素并说明。遮罩盖住整页,目标处镂空;步骤卡片贴着目标显示。\n *\n * <Tour\n * _open={touring}\n * _current={step}\n * steps={[\n * { target: '#search', title: '搜索', content: '按名称或编号查找订单' },\n * { target: () => exportButton, title: '导出', content: '导出为 Excel', placement: 'left' },\n * { title: '就这些', content: '随时可以在帮助菜单里重新查看' }, // 没有目标:卡片居中\n * ]}\n * />\n *\n * - 模态:背景 inert、Esc 关闭、焦点在卡片里循环,关闭后焦点回到打开前的位置(同 Dialog,见 Modal.tsx);\n * - 目标:选择器、元素或返回元素的函数;切换步骤时滚动到视口中间,滚动、缩放、目标大小变化时镂空与卡片跟着动;\n * 找不到目标时卡片居中、整页遮罩;\n * - 卡片:封面(可选的插图)、标题(dialog 的名称)、内容(描述)、步数、上一步 / 下一步(最后一步是“完成”)、跳过;\n * - 键盘:→ / ← 下一步 / 上一步(从右到左排版时反过来;焦点在输入框里时不处理),Esc 关闭;\n * - open、current 可受控;点“完成”时调用 onFinish,跳过或 Esc 时只关闭。\n *\n * 部件:Root(dialog,整屏透明)、Spotlight(镂空)、Panel(卡片)、Cover(封面)、Title、Content、Footer、\n * Progress(步数)、Skip(跳过)、Previous(上一步)、Next(下一步 / 完成)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { autoUpdate } from '@floating-ui/dom';\nimport { nextTick, onBeforeUnmount, useId, type VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { H2, type HeadingProps } from '../base/Heading';\nimport { Text, type TextProps } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { Flex, type FlexProps } from '../layout/Flex';\nimport { clamp } from '../utils/data/number';\nimport { isRtl } from '../utils/dom/direction';\nimport { isEditable } from '../utils/dom/hotkeys';\nimport { anchorFloating, floatingStyles, type FloatingPlacement } from '../utils/dom/floating';\nimport {\n openSetter,\n type OpenChangeDetails,\n type OpenChangeProps,\n type OpenChangeReasons,\n} from '../utils/dom/open-change';\nimport { openModalDialog } from '../utils/dom/overlay';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { t } from '../config/theme/tokens';\n\n/** 引导的一步 */\nexport interface TourStep {\n /** 高亮的目标:选择器、元素或返回元素的函数;不写(或找不到)时卡片居中 */\n target?: string | HTMLElement | (() => HTMLElement | null | undefined);\n /** 标题 */\n title: VNodeChild;\n /** 说明 */\n content?: VNodeChild;\n /** 标题上方的封面:插图、截图、短视频 */\n cover?: VNodeChild;\n /** 卡片在目标的哪一侧,默认 bottom;空间不够时翻转 */\n placement?: FloatingPlacement;\n}\n\n/** 打开、无障碍关联由组件管理;未声明的属性落到 dialog 上 */\nexport interface TourProps\n extends PartProps<'dialog', 'open' | 'aria-labelledby' | 'aria-describedby'>, OpenChangeProps {\n /** 各步 */\n steps: readonly TourStep[];\n /** 是否显示:父级写 _open={x} */\n _open?: boolean;\n /** 当前第几步,从 0 开始:父级写 _current={n} */\n _current?: number;\n /** 镂空比目标大出多少(px),默认 6 */\n padding?: number;\n /** 点了最后一步的“完成” */\n onFinish?: () => void;\n /** 镂空的部件属性 */\n propsSpotlight?: PartProps<'div'>;\n /** 卡片的部件属性 */\n propsPanel?: PartProps<'div'>;\n /** 封面的部件属性 */\n propsCover?: PartProps<'div'>;\n /** 标题(dialog 的名称)的部件属性 */\n propsTitle?: Omit<Partial<HeadingProps>, 'id'>;\n /** 说明(dialog 的描述)的部件属性 */\n propsContent?: PartProps<'div', 'id'>;\n /** 底部一行(步数与按钮)的部件属性 */\n propsFooter?: Partial<FlexProps>;\n /** 步数(第几步 / 共几步)的部件属性 */\n propsProgress?: Partial<TextProps>;\n /** 跳过按钮的部件属性;点击由组件管理 */\n propsSkip?: Omit<Partial<ButtonProps>, 'onClick'>;\n /** 上一步按钮的部件属性;点击由组件管理 */\n propsPrevious?: Omit<Partial<ButtonProps>, 'onClick'>;\n /** 下一步(最后一步是完成)按钮的部件属性;点击由组件管理,可以设 disabled(完成某个操作后才能继续) */\n propsNext?: Omit<Partial<ButtonProps>, 'onClick'>;\n}\n\n/** Tour 的样式:root、spotlight、dimmed、panel、cover、title、content、footer、progress */\nexport const tourStyles = css.create({\n // 整屏透明的 dialog:遮罩由镂空的阴影画,原生 ::backdrop 不用\n root: {\n position: 'fixed',\n inset: 0,\n width: '100%',\n height: '100%',\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n padding: 0,\n borderWidth: 0,\n backgroundColor: 'transparent',\n overflow: 'hidden',\n '::backdrop': { backgroundColor: 'transparent' },\n },\n // 一个盒子画成镂空:外面一圈巨大的阴影就是遮罩\n spotlight: {\n position: 'fixed',\n borderRadius: '_md',\n boxShadow: `0 0 0 100vmax ${t.colors.overlay}`,\n pointerEvents: 'none',\n transition: `left ${t.durations.md} ${t.easings.standard}, top ${t.durations.md} ${t.easings.standard}, width ${t.durations.md} ${t.easings.standard}, height ${t.durations.md} ${t.easings.standard}`,\n },\n // 没有目标:整页遮罩\n dimmed: { inset: 0, borderRadius: 0, backgroundColor: '_overlay', boxShadow: 'none' },\n panel: {\n display: 'grid',\n gap: '_sm',\n width: 'min(22rem, calc(100vw - 2rem))',\n padding: '_lg',\n lineHeight: '_normal',\n },\n centered: { left: '50%', top: '50%', transform: 'translate(-50%, -50%)' },\n // 封面贴着卡片的上、左、右边(盖住内边距),圆角随卡片\n cover: {\n display: 'grid',\n overflow: 'hidden',\n marginBlockStart: `calc(-1 * ${t.space.lg})`,\n marginInline: `calc(-1 * ${t.space.lg})`,\n marginBlockEnd: '_xs',\n borderStartStartRadius: 'inherit',\n borderStartEndRadius: 'inherit',\n },\n title: { margin: 0 },\n content: { color: '_textMuted' },\n footer: { marginBlockStart: '_xs' },\n progress: { marginInlineEnd: 'auto' },\n});\n\n// 镂空的位置是任意值,用动态样式;单独一个 create,见 COMPONENTS.md §4\n/** Tour 的样式:rect(镂空的位置与大小) */\nexport const tourDynamicStyles = css.create({\n rect: (left: number, top: number, width: number, height: number) => ({\n left,\n top,\n width,\n height,\n }),\n});\n\n/** 读出这一步的目标元素 */\nfunction resolveTarget(target: TourStep['target']): HTMLElement | null {\n if (!target) return null;\n if (typeof target === 'string') return document.querySelector<HTMLElement>(target);\n if (typeof target === 'function') return target() ?? null;\n return target;\n}\n\n/** 新手引导:遮罩镂空高亮目标,卡片说明,一步一步往下走 */\nexport const Tour = _component(\n ({\n steps,\n _open: open = _bindable(false),\n onOpenChange,\n _current: current = _bindable(0),\n padding = 6,\n onFinish,\n propsSpotlight,\n propsPanel,\n propsCover,\n propsTitle,\n propsContent,\n propsFooter,\n propsProgress,\n propsSkip,\n propsPrevious,\n propsNext,\n ...rest\n }: TourProps) => {\n const lang = useLang();\n const id = useId();\n const titleId = `${id}-title`;\n const contentId = `${id}-content`;\n let dialog = _state.raw<HTMLDialogElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n // 镂空的位置;没有目标时为 null(整页遮罩、卡片居中)\n let rect = _state<{ left: number; top: number; width: number; height: number } | null>(null);\n let release: (() => void) | undefined;\n let stopFollow: (() => void) | undefined;\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n // 这次关闭的原因:跳过是 close、完成是 confirm,没记下的是 Esc\n let closing: OpenChangeDetails | undefined;\n\n const step = () => steps[clamp(current, 0, steps.length - 1)];\n const last = () => current >= steps.length - 1;\n\n // 与对话框同一套模态行为(含锁定页面滚动:引导期间页面不跟着滚,目标由引导自己滚进视口)\n function show() {\n if (!dialog || dialog.open) return;\n release = openModalDialog(dialog);\n }\n\n /** 跟随这一步的目标:滚到视口中间,之后镂空与卡片随滚动、缩放、大小变化更新 */\n async function follow() {\n stopFollow?.();\n stopFollow = undefined;\n await nextTick();\n const target = resolveTarget(step()?.target);\n if (!panel) return;\n if (!target) {\n rect = null;\n // 上一步定位时写的内联位置清掉,卡片回到居中\n Object.assign(panel.style, { left: '', top: '', visibility: '', transformOrigin: '' });\n panel.focus({ preventScroll: true });\n return;\n }\n target.scrollIntoView({ block: 'center', inline: 'nearest' });\n const anchored = anchorFloating(target, panel, {\n placement: step()?.placement ?? 'bottom',\n offset: padding + 8,\n crossAxisFallback: true,\n });\n const stopSpotlight = autoUpdate(target, panel, () => {\n const box = target.getBoundingClientRect();\n rect = {\n left: box.left - padding,\n top: box.top - padding,\n width: box.width + padding * 2,\n height: box.height + padding * 2,\n };\n });\n stopFollow = () => {\n anchored.stop();\n stopSpotlight();\n };\n await anchored.ready;\n panel.focus({ preventScroll: true });\n }\n\n function close(reason: keyof OpenChangeReasons, event?: Event) {\n closing = { reason, event };\n dialog?.close();\n }\n\n // 不论以什么方式关闭(Esc、跳过、完成、open 改为 false),都会触发原生 close 事件\n function onClose() {\n stopFollow?.();\n stopFollow = undefined;\n release?.();\n release = undefined;\n const { reason, event } = closing ?? { reason: 'escape' };\n closing = undefined;\n setOpen(false, reason, event);\n }\n\n function next(event?: Event) {\n if (!last()) {\n current++;\n return;\n }\n close('confirm', event);\n onFinish?.();\n }\n\n /** → / ← 切换步骤(从右到左排版时反过来);焦点在可编辑的元素里时留给它,下一步按钮不可用时不前进 */\n function onKeydown(event: KeyboardEvent) {\n if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') return;\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n if (isEditable(event.target)) return;\n const forward = (event.key === 'ArrowRight') !== (panel !== null && isRtl(panel));\n if (forward && !propsNext?.disabled) next(event);\n else if (!forward && current > 0) current--;\n else return;\n event.preventDefault();\n }\n\n _effect(() => {\n if (open) show();\n else if (dialog?.open) dialog.close();\n });\n // 打开、换步骤时重新跟随目标\n _effect(() => {\n void current;\n if (open) void follow();\n });\n onBeforeUnmount(() => {\n stopFollow?.();\n release?.();\n });\n\n return () => {\n const currentStep = step();\n return (\n <dialog\n {...mergeAttrs<'dialog'>({ sx: tourStyles.root }, rest, {\n ref: _toRef(dialog),\n 'aria-labelledby': titleId,\n 'aria-describedby': currentStep?.content != null ? contentId : undefined,\n onClose,\n onKeydown,\n })}\n data-step={current}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n tourStyles.spotlight,\n rect\n ? tourDynamicStyles.rect(rect.left, rect.top, rect.width, rect.height)\n : tourStyles.dimmed,\n ],\n },\n propsSpotlight,\n { 'aria-hidden': true },\n )}\n />\n {currentStep && (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n floatingStyles.anchored,\n floatingStyles.surface,\n tourStyles.panel,\n !rect && tourStyles.centered,\n ],\n },\n propsPanel,\n { ref: _toRef(panel), tabindex: -1 },\n )}\n >\n {currentStep.cover != null && (\n <div {...mergeAttrs<'div'>({ sx: tourStyles.cover }, propsCover)}>\n {currentStep.cover}\n </div>\n )}\n <H2\n {...mergePartProps<HeadingProps>({ size: 'md', sx: tourStyles.title }, propsTitle, {\n id: titleId,\n })}\n >\n {currentStep.title}\n </H2>\n {currentStep.content != null && (\n <div\n {...mergeAttrs<'div'>({ sx: tourStyles.content }, propsContent, {\n id: contentId,\n })}\n >\n {currentStep.content}\n </div>\n )}\n <Flex\n {...mergePartProps<FlexProps>(\n { align: 'center', gap: 'sm', wrap: true, sx: tourStyles.footer },\n propsFooter,\n )}\n >\n <Text\n {...mergePartProps<TextProps>(\n { size: 'sm', tone: 'muted', sx: tourStyles.progress },\n propsProgress,\n )}\n >\n {lang.tourProgress(current + 1, steps.length)}\n </Text>\n {!last() && (\n <Button\n {...mergePartProps<ButtonProps>(\n { variant: 'ghost', tone: 'neutral', size: 'sm' },\n propsSkip,\n { onClick: (event: MouseEvent) => close('close', event) },\n )}\n >\n {lang.tourSkip}\n </Button>\n )}\n {current > 0 && (\n <Button\n {...mergePartProps<ButtonProps>(\n { variant: 'outline', size: 'sm' },\n propsPrevious,\n { onClick: () => current-- },\n )}\n >\n {lang.tourPrevious}\n </Button>\n )}\n <Button\n {...mergePartProps<ButtonProps>({ size: 'sm' }, propsNext, { onClick: next })}\n >\n {last() ? lang.tourFinish : lang.tourNext}\n </Button>\n </Flex>\n </div>\n )}\n </dialog>\n );\n };\n },\n { name: 'Tour' },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tour.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps","Text"],"sources":["../../src/overlay/Tour.tsx"],"sourcesContent":["/**\n * 新手引导(原生模态 dialog):一步一步高亮页面上的元素并说明。遮罩盖住整页,目标处镂空;步骤卡片贴着目标显示。\n *\n * <Tour\n * _open={touring}\n * _current={step}\n * steps={[\n * { target: '#search', title: '搜索', content: '按名称或编号查找订单' },\n * { target: () => exportButton, title: '导出', content: '导出为 Excel', placement: 'left' },\n * { title: '就这些', content: '随时可以在帮助菜单里重新查看' }, // 没有目标:卡片居中\n * ]}\n * />\n *\n * - 模态:背景 inert、Esc 关闭、焦点在卡片里循环,关闭后焦点回到打开前的位置(同 Dialog,见 Modal.tsx);\n * - 目标:选择器、元素或返回元素的函数;切换步骤时滚动到视口中间,滚动、缩放、目标大小变化时镂空与卡片跟着动;\n * 找不到目标时卡片居中、整页遮罩;\n * - 卡片:封面(可选的插图)、标题(dialog 的名称)、内容(描述)、步数、上一步 / 下一步(最后一步是“完成”)、跳过;\n * - 键盘:→ / ← 下一步 / 上一步(从右到左排版时反过来;焦点在输入框里时不处理),Esc 关闭;\n * - open、current 可受控;点“完成”时调用 onFinish,跳过或 Esc 时只关闭。\n *\n * 部件:Root(dialog,整屏透明)、Spotlight(镂空)、Panel(卡片)、Cover(封面)、Title、Content、Footer、\n * Progress(步数)、Skip(跳过)、Previous(上一步)、Next(下一步 / 完成)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { autoUpdate } from '@floating-ui/dom';\nimport { nextTick, onBeforeUnmount, useId, type VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { H2, type HeadingProps } from '../base/Heading';\nimport { Text, type TextProps } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { Flex, type FlexProps } from '../layout/Flex';\nimport { clamp } from '../utils/data/number';\nimport { isRtl } from '../utils/dom/direction';\nimport { isEditable } from '../utils/dom/hotkeys';\nimport { anchorFloating, floatingStyles, type FloatingPlacement } from '../utils/dom/floating';\nimport {\n openSetter,\n type OpenChangeDetails,\n type OpenChangeProps,\n type OpenChangeReasons,\n} from '../utils/dom/open-change';\nimport { openModalDialog } from '../utils/dom/overlay';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { t } from '../config/theme/tokens';\n\n/** 引导的一步 */\nexport interface TourStep {\n /** 高亮的目标:选择器、元素或返回元素的函数;不写(或找不到)时卡片居中 */\n target?: string | HTMLElement | (() => HTMLElement | null | undefined);\n /** 标题 */\n title: VNodeChild;\n /** 说明 */\n content?: VNodeChild;\n /** 标题上方的封面:插图、截图、短视频 */\n cover?: VNodeChild;\n /** 卡片在目标的哪一侧,默认 bottom;空间不够时翻转 */\n placement?: FloatingPlacement;\n}\n\n/** 打开、无障碍关联由组件管理;未声明的属性落到 dialog 上 */\nexport interface TourProps\n extends PartProps<'dialog', 'open' | 'aria-labelledby' | 'aria-describedby'>, OpenChangeProps {\n /** 各步 */\n steps: readonly TourStep[];\n /** 是否显示:父级写 _open={x} */\n _open?: boolean;\n /** 当前第几步,从 0 开始:父级写 _current={n} */\n _current?: number;\n /** 镂空比目标大出多少(px),默认 6 */\n padding?: number;\n /** 点了最后一步的“完成” */\n onFinish?: () => void;\n /** 镂空的部件属性 */\n propsSpotlight?: PartProps<'div'>;\n /** 卡片的部件属性 */\n propsPanel?: PartProps<'div'>;\n /** 封面的部件属性 */\n propsCover?: PartProps<'div'>;\n /** 标题(dialog 的名称)的部件属性 */\n propsTitle?: Omit<Partial<HeadingProps>, 'id'>;\n /** 说明(dialog 的描述)的部件属性 */\n propsContent?: PartProps<'div', 'id'>;\n /** 底部一行(步数与按钮)的部件属性 */\n propsFooter?: Partial<FlexProps>;\n /** 步数(第几步 / 共几步)的部件属性 */\n propsProgress?: Partial<TextProps>;\n /** 跳过按钮的部件属性;点击由组件管理 */\n propsSkip?: Omit<Partial<ButtonProps>, 'onClick'>;\n /** 上一步按钮的部件属性;点击由组件管理 */\n propsPrevious?: Omit<Partial<ButtonProps>, 'onClick'>;\n /** 下一步(最后一步是完成)按钮的部件属性;点击由组件管理,可以设 disabled(完成某个操作后才能继续) */\n propsNext?: Omit<Partial<ButtonProps>, 'onClick'>;\n}\n\n/** Tour 的样式:root、spotlight、dimmed、panel、cover、title、content、footer、progress */\nexport const tourStyles = css.create({\n // 整屏透明的 dialog:遮罩由镂空的阴影画,原生 ::backdrop 不用\n root: {\n position: 'fixed',\n inset: 0,\n width: '100%',\n height: '100%',\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n padding: 0,\n borderWidth: 0,\n backgroundColor: 'transparent',\n overflow: 'hidden',\n '::backdrop': { backgroundColor: 'transparent' },\n },\n // 一个盒子画成镂空:外面一圈巨大的阴影就是遮罩\n spotlight: {\n position: 'fixed',\n borderRadius: '_md',\n boxShadow: `0 0 0 100vmax ${t.colors.overlay}`,\n pointerEvents: 'none',\n transition: `left ${t.durations.md} ${t.easings.standard}, top ${t.durations.md} ${t.easings.standard}, width ${t.durations.md} ${t.easings.standard}, height ${t.durations.md} ${t.easings.standard}`,\n },\n // 没有目标:整页遮罩\n dimmed: { inset: 0, borderRadius: 0, backgroundColor: '_overlay', boxShadow: 'none' },\n panel: {\n display: 'grid',\n gap: '_sm',\n width: 'min(22rem, calc(100vw - 2rem))',\n padding: '_lg',\n lineHeight: '_normal',\n },\n centered: { left: '50%', top: '50%', transform: 'translate(-50%, -50%)' },\n // 封面贴着卡片的上、左、右边(盖住内边距),圆角随卡片\n cover: {\n display: 'grid',\n overflow: 'hidden',\n marginBlockStart: `calc(-1 * ${t.space.lg})`,\n marginInline: `calc(-1 * ${t.space.lg})`,\n marginBlockEnd: '_xs',\n borderStartStartRadius: 'inherit',\n borderStartEndRadius: 'inherit',\n },\n title: { margin: 0 },\n content: { color: '_textMuted' },\n footer: { marginBlockStart: '_xs' },\n progress: { marginInlineEnd: 'auto' },\n});\n\n// 镂空的位置是任意值,用动态样式;单独一个 create,见 COMPONENTS.md §4\n/** Tour 的样式:rect(镂空的位置与大小) */\nexport const tourDynamicStyles = css.create({\n rect: (left: number, top: number, width: number, height: number) => ({\n left,\n top,\n width,\n height,\n }),\n});\n\n/** 读出这一步的目标元素 */\nfunction resolveTarget(target: TourStep['target']): HTMLElement | null {\n if (!target) return null;\n if (typeof target === 'string') return document.querySelector<HTMLElement>(target);\n if (typeof target === 'function') return target() ?? null;\n return target;\n}\n\n/** 新手引导:遮罩镂空高亮目标,卡片说明,一步一步往下走 */\nexport const Tour = _component(\n ({\n steps,\n _open: open = _bindable(false),\n onOpenChange,\n _current: current = _bindable(0),\n padding = 6,\n onFinish,\n propsSpotlight,\n propsPanel,\n propsCover,\n propsTitle,\n propsContent,\n propsFooter,\n propsProgress,\n propsSkip,\n propsPrevious,\n propsNext,\n ...rest\n }: TourProps) => {\n const lang = useLang();\n const id = useId();\n const titleId = `${id}-title`;\n const contentId = `${id}-content`;\n let dialog = _state.raw<HTMLDialogElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n // 镂空的位置;没有目标时为 null(整页遮罩、卡片居中)\n let rect = _state<{ left: number; top: number; width: number; height: number } | null>(null);\n let release: (() => void) | undefined;\n let stopFollow: (() => void) | undefined;\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n // 这次关闭的原因:跳过是 close、完成是 confirm,没记下的是 Esc\n let closing: OpenChangeDetails | undefined;\n\n const step = () => steps[clamp(current, 0, steps.length - 1)];\n const last = () => current >= steps.length - 1;\n\n // 与对话框同一套模态行为(含锁定页面滚动:引导期间页面不跟着滚,目标由引导自己滚进视口)\n function show() {\n if (!dialog || dialog.open) return;\n release = openModalDialog(dialog);\n }\n\n /** 跟随这一步的目标:滚到视口中间,之后镂空与卡片随滚动、缩放、大小变化更新 */\n async function follow() {\n stopFollow?.();\n stopFollow = undefined;\n await nextTick();\n const target = resolveTarget(step()?.target);\n if (!panel) return;\n if (!target) {\n rect = null;\n // 上一步定位时写的内联位置清掉,卡片回到居中\n Object.assign(panel.style, { left: '', top: '', visibility: '', transformOrigin: '' });\n panel.focus({ preventScroll: true });\n return;\n }\n target.scrollIntoView({ block: 'center', inline: 'nearest' });\n const anchored = anchorFloating(target, panel, {\n placement: step()?.placement ?? 'bottom',\n offset: padding + 8,\n crossAxisFallback: true,\n });\n const stopSpotlight = autoUpdate(target, panel, () => {\n const box = target.getBoundingClientRect();\n rect = {\n left: box.left - padding,\n top: box.top - padding,\n width: box.width + padding * 2,\n height: box.height + padding * 2,\n };\n });\n stopFollow = () => {\n anchored.stop();\n stopSpotlight();\n };\n await anchored.ready;\n panel.focus({ preventScroll: true });\n }\n\n function close(reason: keyof OpenChangeReasons, event?: Event) {\n closing = { reason, event };\n dialog?.close();\n }\n\n // 不论以什么方式关闭(Esc、跳过、完成、open 改为 false),都会触发原生 close 事件\n function onClose() {\n stopFollow?.();\n stopFollow = undefined;\n release?.();\n release = undefined;\n const { reason, event } = closing ?? { reason: 'escape' };\n closing = undefined;\n setOpen(false, reason, event);\n }\n\n function next(event?: Event) {\n if (!last()) {\n current++;\n return;\n }\n close('confirm', event);\n onFinish?.();\n }\n\n /** → / ← 切换步骤(从右到左排版时反过来);焦点在可编辑的元素里时留给它,下一步按钮不可用时不前进 */\n function onKeydown(event: KeyboardEvent) {\n if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') return;\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n if (isEditable(event.target)) return;\n const forward = (event.key === 'ArrowRight') !== (panel !== null && isRtl(panel));\n if (forward && !propsNext?.disabled) next(event);\n else if (!forward && current > 0) current--;\n else return;\n event.preventDefault();\n }\n\n _effect(() => {\n if (open) show();\n else if (dialog?.open) dialog.close();\n });\n // 打开、换步骤时重新跟随目标\n _effect(() => {\n void current;\n if (open) void follow();\n });\n onBeforeUnmount(() => {\n stopFollow?.();\n release?.();\n });\n\n return () => {\n const currentStep = step();\n return (\n <dialog\n {...mergeAttrs<'dialog'>({ sx: tourStyles.root }, rest, {\n ref: _toRef(dialog),\n 'aria-labelledby': titleId,\n 'aria-describedby': currentStep?.content != null ? contentId : undefined,\n onClose,\n onKeydown,\n })}\n data-step={current}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n tourStyles.spotlight,\n rect\n ? tourDynamicStyles.rect(rect.left, rect.top, rect.width, rect.height)\n : tourStyles.dimmed,\n ],\n },\n propsSpotlight,\n { 'aria-hidden': true },\n )}\n />\n {currentStep && (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n floatingStyles.anchored,\n floatingStyles.surface,\n tourStyles.panel,\n !rect && tourStyles.centered,\n ],\n },\n propsPanel,\n { ref: _toRef(panel), tabindex: -1 },\n )}\n >\n {currentStep.cover != null && (\n <div {...mergeAttrs<'div'>({ sx: tourStyles.cover }, propsCover)}>\n {currentStep.cover}\n </div>\n )}\n <H2\n {...mergePartProps<HeadingProps>({ size: 'md', sx: tourStyles.title }, propsTitle, {\n id: titleId,\n })}\n >\n {currentStep.title}\n </H2>\n {currentStep.content != null && (\n <div\n {...mergeAttrs<'div'>({ sx: tourStyles.content }, propsContent, {\n id: contentId,\n })}\n >\n {currentStep.content}\n </div>\n )}\n <Flex\n {...mergePartProps<FlexProps>(\n { align: 'center', gap: 'sm', wrap: true, sx: tourStyles.footer },\n propsFooter,\n )}\n >\n <Text\n {...mergePartProps<TextProps>(\n { size: 'sm', tone: 'muted', sx: tourStyles.progress },\n propsProgress,\n )}\n >\n {lang.tourProgress(current + 1, steps.length)}\n </Text>\n {!last() && (\n <Button\n {...mergePartProps<ButtonProps>(\n { variant: 'ghost', tone: 'neutral', size: 'sm' },\n propsSkip,\n { onClick: (event: MouseEvent) => close('close', event) },\n )}\n >\n {lang.tourSkip}\n </Button>\n )}\n {current > 0 && (\n <Button\n {...mergePartProps<ButtonProps>(\n { variant: 'outline', size: 'sm' },\n propsPrevious,\n { onClick: () => current-- },\n )}\n >\n {lang.tourPrevious}\n </Button>\n )}\n <Button\n {...mergePartProps<ButtonProps>({ size: 'sm' }, propsNext, { onClick: next })}\n >\n {last() ? lang.tourFinish : lang.tourNext}\n </Button>\n </Flex>\n </div>\n )}\n </dialog>\n );\n };\n },\n { name: 'Tour' },\n);\n"],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ export interface DetachedDialogHost {
|
|
|
7
7
|
/** 对话框关上了(原生 close 事件里调用):等离场过渡播完卸载 */
|
|
8
8
|
closed: () => void;
|
|
9
9
|
}
|
|
10
|
+
/** 在 setup 里调用,返回 renderDetached(content, container):渲染到组件树之外的元素里,调用的组件卸载时一起卸载 */
|
|
11
|
+
export declare function useDetachedRender(): (content: VNodeChild | null, container: Element) => void;
|
|
10
12
|
/** 在 setup 里调用,返回 mount(content):把对话框渲染到组件树之外 */
|
|
11
13
|
export declare function useDetachedDialog(): (content: (host: DetachedDialogHost) => VNodeChild) => void;
|
|
12
14
|
/** 命令式浮层(useDialog、useDrawer)的选项:浮层的属性(_open 由句柄管理),content 是正文 */
|
package/dist/overlay/detached.js
CHANGED
|
@@ -1,55 +1,86 @@
|
|
|
1
1
|
import { ConfigContext, useConfig } from "../config/context.js";
|
|
2
2
|
import { afterTransitions } from "../utils/style/transitions.js";
|
|
3
3
|
import { ConfigScope } from "../config/Provider.js";
|
|
4
|
-
import { createVNode, getCurrentInstance,
|
|
5
|
-
import { _component } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
4
|
+
import { createVNode, getCurrentInstance, getCurrentScope, h, onScopeDispose, render, shallowRef } from "vue";
|
|
5
|
+
import { _component, readonlyProp } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
6
6
|
//#region src/overlay/detached.tsx
|
|
7
|
-
/**
|
|
8
|
-
* 命令式的对话框(useConfirm、useFormDialog、useDialog、useDrawer)共用的挂载:对话框渲染到 body 末尾、组件树之外,
|
|
9
|
-
* 沿用调用处的配置(主题、语言、默认值,经 ConfigScope)与应用上下文(全局组件);关上后等离场过渡播完再卸载。
|
|
10
|
-
*
|
|
11
|
-
* const mount = useDetachedDialog(); // setup 里
|
|
12
|
-
* mount((host) => <Dialog _open={host.open} onClose={host.closed}>…</Dialog>);
|
|
13
|
-
*
|
|
14
|
-
* useDetachedOverlay 在它上面加一层句柄(close、update、closed),useDialog、useDrawer 用它。
|
|
15
|
-
*/
|
|
16
7
|
/** 交给对话框内容的控制:开着没有、关上了 */
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
/** 组件树之外的根:提供调用处的配置,内容包在 ConfigScope 里(主题变量、语言) */
|
|
9
|
+
var DetachedRoot = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
10
|
+
const config = readonlyProp(_props, "config");
|
|
11
|
+
const content = readonlyProp(_props, "content");
|
|
12
|
+
ConfigContext.provide(config.value);
|
|
13
|
+
return () => createVNode(ConfigScope, { "key": "__site0" }, {
|
|
14
|
+
default: () => [content.value()],
|
|
15
|
+
$stable: true
|
|
16
|
+
});
|
|
17
|
+
}, {
|
|
18
|
+
name: "DetachedRoot",
|
|
19
|
+
props: ["config", "content"]
|
|
20
|
+
});
|
|
21
|
+
/** 调用处的配置与应用上下文(在 setup 里取),交给组件树之外的根 */
|
|
22
|
+
function captureContext() {
|
|
23
|
+
return {
|
|
24
|
+
config: useConfig(),
|
|
25
|
+
appContext: getCurrentInstance()?.appContext ?? null
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function renderInto(container, { config, appContext }, content) {
|
|
29
|
+
const vnode = h(DetachedRoot, {
|
|
30
|
+
config,
|
|
31
|
+
content
|
|
32
|
+
});
|
|
33
|
+
vnode.appContext = appContext;
|
|
34
|
+
render(vnode, container);
|
|
35
|
+
}
|
|
36
|
+
/** 在 setup 里调用,返回 renderDetached(content, container):渲染到组件树之外的元素里,调用的组件卸载时一起卸载 */
|
|
37
|
+
function useDetachedRender() {
|
|
38
|
+
const context = captureContext();
|
|
39
|
+
const containers = /* @__PURE__ */ new Set();
|
|
40
|
+
if (getCurrentScope()) onScopeDispose(() => {
|
|
41
|
+
for (const container of containers) render(null, container);
|
|
42
|
+
containers.clear();
|
|
43
|
+
});
|
|
44
|
+
return (content, container) => {
|
|
45
|
+
if (content == null) {
|
|
46
|
+
containers.delete(container);
|
|
47
|
+
render(null, container);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
containers.add(container);
|
|
51
|
+
renderInto(container, context, () => content);
|
|
52
|
+
};
|
|
19
53
|
}
|
|
20
54
|
/** 在 setup 里调用,返回 mount(content):把对话框渲染到组件树之外 */
|
|
21
55
|
function useDetachedDialog() {
|
|
22
|
-
const
|
|
23
|
-
|
|
56
|
+
const context = captureContext();
|
|
57
|
+
/** 开着的对话框:调用的组件卸载时关上 */
|
|
58
|
+
const live = /* @__PURE__ */ new Set();
|
|
59
|
+
if (getCurrentScope()) onScopeDispose(() => {
|
|
60
|
+
for (const host of live) host.open = false;
|
|
61
|
+
});
|
|
24
62
|
return (content) => {
|
|
25
63
|
const container = document.createElement("div");
|
|
26
64
|
document.body.append(container);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return () => {
|
|
47
|
-
let _slot;
|
|
48
|
-
return createVNode(ConfigScope, null, _isSlot(_slot = content(host)) ? _slot : { default: () => [_slot] });
|
|
49
|
-
};
|
|
50
|
-
}, { name: "DetachedDialog" }));
|
|
51
|
-
vnode.appContext = appContext;
|
|
52
|
-
render(vnode, container);
|
|
65
|
+
const open = shallowRef(true);
|
|
66
|
+
const host = {
|
|
67
|
+
get open() {
|
|
68
|
+
return open.value;
|
|
69
|
+
},
|
|
70
|
+
set open(value) {
|
|
71
|
+
open.value = value;
|
|
72
|
+
},
|
|
73
|
+
closed() {
|
|
74
|
+
live.delete(host);
|
|
75
|
+
const dialog = container.querySelector("dialog");
|
|
76
|
+
(dialog ? afterTransitions(dialog) : Promise.resolve()).then(() => {
|
|
77
|
+
render(null, container);
|
|
78
|
+
container.remove();
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
live.add(host);
|
|
83
|
+
renderInto(container, context, () => content(host));
|
|
53
84
|
};
|
|
54
85
|
}
|
|
55
86
|
/** 命令式浮层(useDialog、useDrawer)的选项:浮层的属性(_open 由句柄管理),content 是正文 */
|
|
@@ -104,6 +135,6 @@ function useDetachedOverlay(renderOverlay) {
|
|
|
104
135
|
};
|
|
105
136
|
}
|
|
106
137
|
//#endregion
|
|
107
|
-
export { useDetachedDialog, useDetachedOverlay };
|
|
138
|
+
export { useDetachedDialog, useDetachedOverlay, useDetachedRender };
|
|
108
139
|
|
|
109
140
|
//# sourceMappingURL=detached.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detached.js","names":["
|
|
1
|
+
{"version":3,"file":"detached.js","names":["_vtp_readonlyProp","_createVNode"],"sources":["../../src/overlay/detached.tsx"],"sourcesContent":["/**\n * 渲染到组件树之外:沿用调用处的配置(主题、语言、默认值,经 ConfigScope)与应用上下文(全局组件),\n * 生命周期跟着调用的组件——它卸载时一起收掉,不留孤儿。\n *\n * const renderDetached = useDetachedRender(); // setup 里;第三方库管的元素(图表的提示框)\n * renderDetached(<Tip />, element); // 再调一次换内容,传 null 卸载;组件卸载时自动卸载\n *\n * const mount = useDetachedDialog(); // setup 里;命令式的对话框(useConfirm、useFormDialog)\n * mount((host) => <Dialog _open={host.open} onClose={host.closed}>…</Dialog>);\n *\n * 对话框渲染到 body 末尾,关上后等离场过渡播完再卸载;调用的组件卸载时(例如切换了路由)把开着的对话框关上,\n * 照常走关闭的流程,等着结果的 `await confirm()` 也拿到结果。\n * useDetachedOverlay 在 useDetachedDialog 上面加一层句柄(close、update、closed),useDialog、useDrawer 用它。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport {\n getCurrentInstance,\n getCurrentScope,\n h,\n onScopeDispose,\n render,\n shallowRef,\n type AppContext,\n type VNodeChild,\n} from 'vue';\nimport { ConfigContext, useConfig, type UiConfig } from '../config/context';\nimport { ConfigScope } from '../config/Provider';\nimport type { OpenChangeProps, OpenChangeReasons } from '../utils/dom/open-change';\nimport { afterTransitions } from '../utils/style/transitions';\n\n/** 交给对话框内容的控制:开着没有、关上了 */\nexport interface DetachedDialogHost {\n /** 对话框开着:对话框写 _open={host.open},改成 false 就关上 */\n open: boolean;\n /** 对话框关上了(原生 close 事件里调用):等离场过渡播完卸载 */\n closed: () => void;\n}\n\n/** 组件树之外的根:提供调用处的配置,内容包在 ConfigScope 里(主题变量、语言) */\nconst DetachedRoot = _component(\n ({ config, content }: { config: UiConfig; content: () => VNodeChild }) => {\n ConfigContext.provide(config);\n return () => <ConfigScope>{content()}</ConfigScope>;\n },\n);\n\n/** 调用处的配置与应用上下文(在 setup 里取),交给组件树之外的根 */\nfunction captureContext() {\n return { config: useConfig(), appContext: getCurrentInstance()?.appContext ?? null };\n}\n\nfunction renderInto(\n container: Element,\n { config, appContext }: { config: UiConfig; appContext: AppContext | null },\n content: () => VNodeChild,\n) {\n const vnode = h(DetachedRoot, { config, content });\n vnode.appContext = appContext;\n render(vnode, container);\n}\n\n/** 在 setup 里调用,返回 renderDetached(content, container):渲染到组件树之外的元素里,调用的组件卸载时一起卸载 */\nexport function useDetachedRender(): (content: VNodeChild | null, container: Element) => void {\n const context = captureContext();\n const containers = new Set<Element>();\n if (getCurrentScope()) {\n onScopeDispose(() => {\n for (const container of containers) render(null, container);\n containers.clear();\n });\n }\n return (content, container) => {\n if (content == null) {\n containers.delete(container);\n render(null, container);\n return;\n }\n containers.add(container);\n renderInto(container, context, () => content);\n };\n}\n\n/** 在 setup 里调用,返回 mount(content):把对话框渲染到组件树之外 */\nexport function useDetachedDialog(): (content: (host: DetachedDialogHost) => VNodeChild) => void {\n const context = captureContext();\n /** 开着的对话框:调用的组件卸载时关上 */\n const live = new Set<DetachedDialogHost>();\n if (getCurrentScope()) {\n onScopeDispose(() => {\n for (const host of live) host.open = false;\n });\n }\n\n return (content) => {\n const container = document.createElement('div');\n document.body.append(container);\n const open = shallowRef(true);\n const host: DetachedDialogHost = {\n get open() {\n return open.value;\n },\n set open(value) {\n open.value = value;\n },\n closed() {\n live.delete(host);\n const dialog = container.querySelector('dialog');\n void (dialog ? afterTransitions(dialog) : Promise.resolve()).then(() => {\n render(null, container);\n container.remove();\n });\n },\n };\n live.add(host);\n renderInto(container, context, () => content(host));\n };\n}\n\n/** 命令式浮层(useDialog、useDrawer)的选项:浮层的属性(_open 由句柄管理),content 是正文 */\nexport type DetachedOverlayOptions<P> = Omit<P, '_open' | 'children'> & {\n /** 正文;给函数时拿到句柄,正文里的按钮可以自己关上、改标题 */\n content?: VNodeChild | ((handle: DetachedOverlayHandle<P>) => VNodeChild);\n};\n\n/** useDialog().open、useDrawer().open 返回的句柄;方法不依赖 this,可以直接传出去(onSaved={handle.close}) */\nexport interface DetachedOverlayHandle<P> {\n /** 关上(onOpenChange 的原因是 imperative);已经关上时什么也不做 */\n readonly close: () => void;\n /** 改属性(标题、宽度、确认按钮的文字、正文……),没写的保持不变 */\n readonly update: (patch: Partial<DetachedOverlayOptions<P>>) => void;\n /** 关上之后 resolve,得到关上的原因:确认是 confirm,Esc、遮罩、关闭按钮、close() 各是 escape、outside、close、imperative */\n readonly closed: Promise<keyof OpenChangeReasons>;\n}\n\n/** 原生 dialog 的 close 事件 */\ntype DialogCloseEvent = Event & { currentTarget: HTMLDialogElement };\n\n/** 浮层要支持的:onOpenChange 报告原因,onClose 落到原生 dialog 上 */\ninterface DetachedOverlayProps extends OpenChangeProps {\n onClose?: (event: DialogCloseEvent) => void;\n}\n\n/**\n * 命令式浮层:在 setup 里调用,返回 open(options)。renderOverlay 把属性、开关与正文交给具体的浮层(Dialog、Drawer):\n *\n * useDetachedOverlay<DialogProps>((props, host, children) => <Dialog {...props} _open={host.open}>{children}</Dialog>);\n */\nexport function useDetachedOverlay<P extends DetachedOverlayProps>(\n renderOverlay: (\n props: Omit<P, '_open' | 'children'>,\n host: DetachedDialogHost,\n children: VNodeChild,\n ) => VNodeChild,\n): (options: DetachedOverlayOptions<P>) => DetachedOverlayHandle<P> {\n const mount = useDetachedDialog();\n return (options) => {\n const state = shallowRef(options);\n let host: DetachedDialogHost | undefined;\n let reason: keyof OpenChangeReasons = 'imperative';\n let resolveClosed!: (reason: keyof OpenChangeReasons) => void;\n const handle: DetachedOverlayHandle<P> = {\n close: () => {\n if (!host?.open) return;\n reason = 'imperative';\n host.open = false;\n state.value.onOpenChange?.(false, { reason });\n },\n update: (patch) => {\n state.value = { ...state.value, ...patch };\n },\n closed: new Promise((resolve) => (resolveClosed = resolve)),\n };\n mount((current) => {\n host = current;\n const { content, onOpenChange, onClose, ...props } = state.value;\n const overlayProps = {\n ...props,\n onOpenChange: (open, details) => {\n if (!open) reason = details.reason;\n onOpenChange?.(open, details);\n },\n onClose: (event: DialogCloseEvent) => {\n onClose?.(event);\n // 原生 close 事件先到这里、后到浮层自己(它在那里报告原因):等它报告完再 resolve\n queueMicrotask(() => resolveClosed(reason));\n current.closed();\n },\n } as Omit<P, '_open' | 'children'> & DetachedOverlayProps;\n return renderOverlay(\n overlayProps,\n current,\n typeof content === 'function' ? content(handle) : content,\n );\n });\n options.onOpenChange?.(true, { reason: 'imperative' });\n return handle;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t } from "../config/theme/tokens.js";
|
|
2
2
|
import { hasContent, mergeAttrs } from "../utils/props.js";
|
|
3
3
|
import { useIntersectionObserver } from "../utils/dom/intersection.js";
|
|
4
|
-
import { createVNode,
|
|
5
|
-
import { _component, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
4
|
+
import { createVNode, ref, shallowRef } from "vue";
|
|
5
|
+
import { _component, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
6
6
|
import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
7
7
|
//#region src/patterns/ActionBar.tsx
|
|
8
8
|
/** 未声明的属性落到外层 div 上 */
|
|
@@ -55,7 +55,7 @@ var ActionBar = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
|
55
55
|
let root = shallowRef(null);
|
|
56
56
|
let stuck = ref(false);
|
|
57
57
|
useIntersectionObserver(() => sticky.value ? root.value : null, ([entry]) => stuck.value = !!entry && entry.isIntersecting && entry.intersectionRatio < 1, () => ({ threshold: [0, 1] }));
|
|
58
|
-
return () => createVNode("div",
|
|
58
|
+
return () => createVNode("div", mergeJsxProps(mergeAttrs({ sx: [
|
|
59
59
|
actionBarStyles.root,
|
|
60
60
|
sticky.value && actionBarStyles.sticky,
|
|
61
61
|
sticky.value && stuck.value && actionBarStyles.stuck
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionBar.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/patterns/ActionBar.tsx"],"sourcesContent":["/**\n * 吸底的操作栏(div):长表单、详情页底部的“取消 / 保存草稿 / 提交”,滚动时一直贴在滚动区域的底边,不用滚到底才能提交。\n *\n * <ActionBar start={form.dirty ? '有未保存的改动' : undefined}>\n * <Button variant=\"ghost\" tone=\"neutral\">取消</Button>\n * <Button type=\"submit\" loading={form.submitting}>提交</Button>\n * </ActionBar>\n *\n * 放在要跟着滚动的内容的最后(表单里、卡片里、页面主区里都行):position: sticky 贴着最近的滚动容器的底边。\n * 下面还有被盖住的内容时(贴在底边、还没滚到它原本的位置)带阴影、data-stuck,提示还能往下滚;滚到底时与内容平齐。\n * start 是起始边的说明(未保存的改动、校验汇总),children 是结束边的按钮。\n *\n * 部件:Root(div)、Start(div)、Actions(div)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useIntersectionObserver } from '../utils/dom/intersection';\nimport { hasContent, mergeAttrs, type PartProps } from '../utils/props';\nimport { t } from '../config/theme/tokens';\n\n/** 未声明的属性落到外层 div 上 */\nexport interface ActionBarProps extends PartProps<'div'> {\n /** 起始边的内容:未保存的改动、已选几项、校验汇总 */\n start?: VNodeChild;\n /**\n * 贴在滚动区域的底边,默认 true;false 时是普通的一行(如对话框里已经固定的底栏)\n * @default true\n */\n sticky?: boolean;\n /** 起始边内容的部件属性 */\n propsStart?: PartProps<'div'>;\n /** 按钮区的部件属性 */\n propsActions?: PartProps<'div'>;\n /** 按钮:靠结束边排开 */\n children?: VNodeChild;\n}\n\n/** ActionBar 的样式:root、sticky、stuck、start、actions */\nexport const actionBarStyles = css.create({\n root: {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: '_md',\n paddingBlock: '_md',\n paddingInline: '_lg',\n borderBlockStartWidth: '_xs',\n borderBlockStartStyle: 'solid',\n borderBlockStartColor: '_borderMuted',\n backgroundColor: '_surface',\n transition: `box-shadow ${t.durations.md} ${t.easings.standard}`,\n },\n // 往下多出一条线宽:贴着底边时有 1px 在滚动区域外,交叉比例小于 1,据此判断“盖着下面的内容”\n sticky: { position: 'sticky', insetBlockEnd: `calc(-1 * ${t.borderWidths.xs})`, zIndex: 1 },\n // 盖着下面的内容:阴影提示还能往下滚\n stuck: { boxShadow: '_md', borderBlockStartColor: '_border' },\n // 说明文字比所在文字小一档(0.93em ≈ 默认字号下的 sm)\n start: { flexGrow: 1, minWidth: 0, color: '_textMuted', fontSize: '0.93em' },\n actions: {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: '_sm',\n marginInlineStart: 'auto',\n },\n});\n\n/** 吸底的操作栏:起始边的说明、结束边的按钮;盖着下面的内容时带阴影 */\nexport const ActionBar = _component(\n ({ start, sticky = true, propsStart, propsActions, children, ...rest }: ActionBarProps) => {\n let root = _state.raw<HTMLElement | null>(null);\n let stuck = _state(false);\n\n // 贴着底边时栏有一条线宽露在滚动区域外(见 sticky 样式):没有完整可见就是盖着下面的内容\n useIntersectionObserver(\n () => (sticky ? root : null),\n ([entry]) => (stuck = !!entry && entry.isIntersecting && entry.intersectionRatio < 1),\n () => ({ threshold: [0, 1] }),\n );\n\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n actionBarStyles.root,\n sticky && actionBarStyles.sticky,\n sticky && stuck && actionBarStyles.stuck,\n ],\n },\n rest,\n { ref: _toRef(root) },\n )}\n data-stuck={(sticky && stuck) || undefined}\n >\n {hasContent(start) && (\n <div {...mergeAttrs<'div'>({ sx: actionBarStyles.start }, propsStart)}>{start}</div>\n )}\n <div {...mergeAttrs<'div'>({ sx: actionBarStyles.actions }, propsActions)}>{children}</div>\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;AAuCA,IAAa,kBAAkB,IAAI,OAAO;CACxC,MAAM;EACJ,SAAS;EACT,YAAY;EACZ,UAAU;EACV,KAAK;EACL,cAAc;EACd,eAAe;EACf,uBAAuB;EACvB,uBAAuB;EACvB,uBAAuB;EACvB,iBAAiB;EACjB,YAAY,cAAc,EAAE,UAAU,GAAE,GAAI,EAAE,QAAQ;CACxD;CAEA,QAAQ;EAAE,UAAU;EAAU,eAAe,aAAa,EAAE,aAAa,GAAE;EAAK,QAAQ;CAAE;CAE1F,OAAO;EAAE,WAAW;EAAO,uBAAuB;CAAU;CAE5D,OAAO;EAAE,UAAU;EAAG,UAAU;EAAG,OAAO;EAAc,UAAU;CAAS;CAC3E,SAAS;EACP,SAAS;EACT,YAAY;EACZ,UAAU;EACV,KAAK;EACL,mBAAmB;CACrB;AACF,CAAC;;AAGD,IAAa,YAAY,0BACvB,QAAA,SAA2F;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,UAAxE,IAAI;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAAyC,OAAIC,UAAA,QAAA,MAAA,KAAA;CAClE,IAAI,OAAIC,WAAkC,IAAI;CAC9C,IAAI,QAAKC,IAAU,KAAK;CAGxB,8BACS,OAAA,QAAA,KAAA,QAAgB,OACtB,CAAC,WAAY,MAAA,QAAQ,CAAC,CAAC,SAAS,MAAM,kBAAkB,MAAM,oBAAoB,UAC5E,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAC7B;CAEA,aAAOC,YAAA,OAAAC,
|
|
1
|
+
{"version":3,"file":"ActionBar.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/patterns/ActionBar.tsx"],"sourcesContent":["/**\n * 吸底的操作栏(div):长表单、详情页底部的“取消 / 保存草稿 / 提交”,滚动时一直贴在滚动区域的底边,不用滚到底才能提交。\n *\n * <ActionBar start={form.dirty ? '有未保存的改动' : undefined}>\n * <Button variant=\"ghost\" tone=\"neutral\">取消</Button>\n * <Button type=\"submit\" loading={form.submitting}>提交</Button>\n * </ActionBar>\n *\n * 放在要跟着滚动的内容的最后(表单里、卡片里、页面主区里都行):position: sticky 贴着最近的滚动容器的底边。\n * 下面还有被盖住的内容时(贴在底边、还没滚到它原本的位置)带阴影、data-stuck,提示还能往下滚;滚到底时与内容平齐。\n * start 是起始边的说明(未保存的改动、校验汇总),children 是结束边的按钮。\n *\n * 部件:Root(div)、Start(div)、Actions(div)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useIntersectionObserver } from '../utils/dom/intersection';\nimport { hasContent, mergeAttrs, type PartProps } from '../utils/props';\nimport { t } from '../config/theme/tokens';\n\n/** 未声明的属性落到外层 div 上 */\nexport interface ActionBarProps extends PartProps<'div'> {\n /** 起始边的内容:未保存的改动、已选几项、校验汇总 */\n start?: VNodeChild;\n /**\n * 贴在滚动区域的底边,默认 true;false 时是普通的一行(如对话框里已经固定的底栏)\n * @default true\n */\n sticky?: boolean;\n /** 起始边内容的部件属性 */\n propsStart?: PartProps<'div'>;\n /** 按钮区的部件属性 */\n propsActions?: PartProps<'div'>;\n /** 按钮:靠结束边排开 */\n children?: VNodeChild;\n}\n\n/** ActionBar 的样式:root、sticky、stuck、start、actions */\nexport const actionBarStyles = css.create({\n root: {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: '_md',\n paddingBlock: '_md',\n paddingInline: '_lg',\n borderBlockStartWidth: '_xs',\n borderBlockStartStyle: 'solid',\n borderBlockStartColor: '_borderMuted',\n backgroundColor: '_surface',\n transition: `box-shadow ${t.durations.md} ${t.easings.standard}`,\n },\n // 往下多出一条线宽:贴着底边时有 1px 在滚动区域外,交叉比例小于 1,据此判断“盖着下面的内容”\n sticky: { position: 'sticky', insetBlockEnd: `calc(-1 * ${t.borderWidths.xs})`, zIndex: 1 },\n // 盖着下面的内容:阴影提示还能往下滚\n stuck: { boxShadow: '_md', borderBlockStartColor: '_border' },\n // 说明文字比所在文字小一档(0.93em ≈ 默认字号下的 sm)\n start: { flexGrow: 1, minWidth: 0, color: '_textMuted', fontSize: '0.93em' },\n actions: {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: '_sm',\n marginInlineStart: 'auto',\n },\n});\n\n/** 吸底的操作栏:起始边的说明、结束边的按钮;盖着下面的内容时带阴影 */\nexport const ActionBar = _component(\n ({ start, sticky = true, propsStart, propsActions, children, ...rest }: ActionBarProps) => {\n let root = _state.raw<HTMLElement | null>(null);\n let stuck = _state(false);\n\n // 贴着底边时栏有一条线宽露在滚动区域外(见 sticky 样式):没有完整可见就是盖着下面的内容\n useIntersectionObserver(\n () => (sticky ? root : null),\n ([entry]) => (stuck = !!entry && entry.isIntersecting && entry.intersectionRatio < 1),\n () => ({ threshold: [0, 1] }),\n );\n\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n actionBarStyles.root,\n sticky && actionBarStyles.sticky,\n sticky && stuck && actionBarStyles.stuck,\n ],\n },\n rest,\n { ref: _toRef(root) },\n )}\n data-stuck={(sticky && stuck) || undefined}\n >\n {hasContent(start) && (\n <div {...mergeAttrs<'div'>({ sx: actionBarStyles.start }, propsStart)}>{start}</div>\n )}\n <div {...mergeAttrs<'div'>({ sx: actionBarStyles.actions }, propsActions)}>{children}</div>\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;AAuCA,IAAa,kBAAkB,IAAI,OAAO;CACxC,MAAM;EACJ,SAAS;EACT,YAAY;EACZ,UAAU;EACV,KAAK;EACL,cAAc;EACd,eAAe;EACf,uBAAuB;EACvB,uBAAuB;EACvB,uBAAuB;EACvB,iBAAiB;EACjB,YAAY,cAAc,EAAE,UAAU,GAAE,GAAI,EAAE,QAAQ;CACxD;CAEA,QAAQ;EAAE,UAAU;EAAU,eAAe,aAAa,EAAE,aAAa,GAAE;EAAK,QAAQ;CAAE;CAE1F,OAAO;EAAE,WAAW;EAAO,uBAAuB;CAAU;CAE5D,OAAO;EAAE,UAAU;EAAG,UAAU;EAAG,OAAO;EAAc,UAAU;CAAS;CAC3E,SAAS;EACP,SAAS;EACT,YAAY;EACZ,UAAU;EACV,KAAK;EACL,mBAAmB;CACrB;AACF,CAAC;;AAGD,IAAa,YAAY,0BACvB,QAAA,SAA2F;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,UAAxE,IAAI;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAAyC,OAAIC,UAAA,QAAA,MAAA,KAAA;CAClE,IAAI,OAAIC,WAAkC,IAAI;CAC9C,IAAI,QAAKC,IAAU,KAAK;CAGxB,8BACS,OAAA,QAAA,KAAA,QAAgB,OACtB,CAAC,WAAY,MAAA,QAAQ,CAAC,CAAC,SAAS,MAAM,kBAAkB,MAAM,oBAAoB,UAC5E,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAC7B;CAEA,aAAOC,YAAA,OAAAC,cAEC,WACF,EACE,IAAI;EACF,gBAAgB;EAChB,OAAA,SAAU,gBAAgB;EAC1B,OAAA,SAAA,MAAA,SAAmB,gBAAgB;CAAK,EAE5C,GACA,MACA,EAAE,KAAG,KAAe,CACtB,GAAC,EAAA,cACY,OAAA,SAAA,MAAA,SAAoB,KAAA,EAAS,CAAA,GAAA,CAEzC,WAAU,MAAA,KAAM,KAACD,YAAA,OACP,WAAkB,EAAE,IAAI,gBAAgB,MAAM,GAAC,WAAA,KAAY,GAAC,CAAA,MAAA,KAAA,CAAA,GACtEA,YAAA,OACQ,WAAkB,EAAE,IAAI,gBAAgB,QAAQ,GAAC,aAAA,KAAc,GAAC,CAAA,SAAA,KAAA,CAAA,CAAA,CAAA;AAG/E,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
|
|
@@ -7,6 +7,7 @@ import { type ResizeHandleProps } from '../layout/ResizeHandle';
|
|
|
7
7
|
import { type ScrollAreaProps } from '../layout/ScrollArea';
|
|
8
8
|
import { type DrawerProps } from '../overlay/Drawer';
|
|
9
9
|
import { type PartProps } from '../utils/props';
|
|
10
|
+
import type { LayoutPreference } from '../config/layout/preference';
|
|
10
11
|
/** 左侧栏的形式 */
|
|
11
12
|
export interface AppShellSidebarModes {
|
|
12
13
|
/** 宽屏时占一列、窄屏时收进抽屉(默认) */
|
|
@@ -14,6 +15,17 @@ export interface AppShellSidebarModes {
|
|
|
14
15
|
/** 各宽度都是盖在页面上面的抽屉,不占正文的位置,可以收起、拖动宽度 */
|
|
15
16
|
overlay: unknown;
|
|
16
17
|
}
|
|
18
|
+
/** 抽屉式侧栏从哪一边滑出(sidebarMode="overlay") */
|
|
19
|
+
export interface AppShellSidebarSides {
|
|
20
|
+
/** 起始边(左,从右到左排版时是右):默认 */
|
|
21
|
+
start: unknown;
|
|
22
|
+
/** 结束边(右,从右到左排版时是左):“菜单”在顶栏结束边 */
|
|
23
|
+
end: unknown;
|
|
24
|
+
/** 顶栏下面,盖满宽度,导航的小节排成多列 */
|
|
25
|
+
top: unknown;
|
|
26
|
+
/** 窗口底部,盖满宽度,导航的小节排成多列 */
|
|
27
|
+
bottom: unknown;
|
|
28
|
+
}
|
|
17
29
|
/** 未声明的属性落到外层 div 上 */
|
|
18
30
|
export interface AppShellProps extends PartProps<'div'> {
|
|
19
31
|
/** 顶栏起始边的品牌(标志与产品名):有侧栏时这一格与侧栏同宽,侧栏的竖线延伸到顶 */
|
|
@@ -36,6 +48,13 @@ export interface AppShellProps extends PartProps<'div'> {
|
|
|
36
48
|
_sidebarCollapsed?: boolean;
|
|
37
49
|
/** 左侧栏的形式,默认 docked */
|
|
38
50
|
sidebarMode?: keyof AppShellSidebarModes;
|
|
51
|
+
/** 抽屉式侧栏从哪一边滑出,默认 start;只在 overlay 时有效 */
|
|
52
|
+
sidebarSide?: keyof AppShellSidebarSides;
|
|
53
|
+
/**
|
|
54
|
+
* 用户选的布局(createLayoutPreference 的结果):侧栏的形式、方向、开关与尺寸从它读、写回它并存盘,
|
|
55
|
+
* 写了它,sidebarMode、sidebarSide、_sidebarOpen、_sidebarWidth、_sidebarHeight、_sidebarCollapsed 就不再起作用
|
|
56
|
+
*/
|
|
57
|
+
layout?: LayoutPreference;
|
|
39
58
|
/** 侧栏抽屉是否打开(docked 时只在窄屏有抽屉):父级可以写 _sidebarOpen={x} */
|
|
40
59
|
_sidebarOpen?: boolean;
|
|
41
60
|
/**
|
|
@@ -43,6 +62,8 @@ export interface AppShellProps extends PartProps<'div'> {
|
|
|
43
62
|
* 父级写 _sidebarWidth={x} 记住拖动后的宽度
|
|
44
63
|
*/
|
|
45
64
|
_sidebarWidth?: number;
|
|
65
|
+
/** 上下两侧抽屉的高度(px),默认 320,范围 96–640:父级写 _sidebarHeight={x} 记住拖动后的高度 */
|
|
66
|
+
_sidebarHeight?: number;
|
|
46
67
|
/** 页面最前面的“跳到正文”链接,默认 true */
|
|
47
68
|
skipLink?: boolean;
|
|
48
69
|
/** 整页用浮层滚动条(PageScrollbar:不占宽度,滚动时出现),默认 true */
|
|
@@ -117,8 +138,12 @@ export declare const appShellStyles: Readonly<{
|
|
|
117
138
|
menuButton: css.CompiledStyles;
|
|
118
139
|
nav: css.CompiledStyles;
|
|
119
140
|
overlay: css.CompiledStyles;
|
|
141
|
+
overlayBottom: css.CompiledStyles;
|
|
142
|
+
overlayEnd: css.CompiledStyles;
|
|
120
143
|
overlayOpen: css.CompiledStyles;
|
|
121
144
|
overlayScroll: css.CompiledStyles;
|
|
145
|
+
overlayStart: css.CompiledStyles;
|
|
146
|
+
overlayTop: css.CompiledStyles;
|
|
122
147
|
rail: css.CompiledStyles;
|
|
123
148
|
railScroll: css.CompiledStyles;
|
|
124
149
|
railViewport: css.CompiledStyles;
|
|
@@ -126,6 +151,7 @@ export declare const appShellStyles: Readonly<{
|
|
|
126
151
|
sidebar: css.CompiledStyles;
|
|
127
152
|
sidebarColumn: css.CompiledStyles;
|
|
128
153
|
sidebarContent: css.CompiledStyles;
|
|
154
|
+
sidebarContentColumns: css.CompiledStyles;
|
|
129
155
|
sidebarContentCompact: css.CompiledStyles;
|
|
130
156
|
sidebarScroll: css.CompiledStyles;
|
|
131
157
|
tabs: css.CompiledStyles;
|
|
@@ -136,9 +162,10 @@ export declare const appShellStyles: Readonly<{
|
|
|
136
162
|
withSidebar: css.CompiledStyles;
|
|
137
163
|
withSidebarCollapsed: css.CompiledStyles;
|
|
138
164
|
}>;
|
|
139
|
-
/** AppShell
|
|
165
|
+
/** AppShell 的动态样式:抽屉的宽度与高度、宽屏时品牌格的宽度(px) */
|
|
140
166
|
export declare const appShellDynamicStyles: Readonly<{
|
|
141
167
|
readonly width: (px: number) => Readonly<[css.CompiledStyles, css.InlineStyles]>;
|
|
168
|
+
readonly height: (px: number) => Readonly<[css.CompiledStyles, css.InlineStyles]>;
|
|
142
169
|
readonly brandWidth: (px: number) => Readonly<[css.CompiledStyles, css.InlineStyles]>;
|
|
143
170
|
}>;
|
|
144
171
|
/** 应用外壳:粘性顶栏、左侧栏、正文、右侧栏;窄屏时左侧栏收进抽屉 */
|