@zerodep-dev/vue-tsx-pro-ui 0.3.1 → 0.3.2
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/Blockquote.d.ts +1 -1
- package/dist/base/Blockquote.js +1 -1
- package/dist/base/Blockquote.js.map +1 -1
- package/dist/base/ButtonGroup.d.ts +1 -1
- package/dist/base/ButtonGroup.js +1 -1
- package/dist/base/ButtonGroup.js.map +1 -1
- package/dist/base/Code.d.ts +1 -1
- package/dist/base/Code.js +1 -1
- package/dist/base/Code.js.map +1 -1
- package/dist/base/CodeBlock.d.ts +1 -1
- package/dist/base/CodeBlock.js +1 -1
- package/dist/base/CodeBlock.js.map +1 -1
- package/dist/base/CopyButton.d.ts +1 -1
- package/dist/base/CopyButton.js +1 -1
- package/dist/base/CopyButton.js.map +1 -1
- package/dist/base/Heading.d.ts +1 -1
- package/dist/base/Heading.js +1 -1
- package/dist/base/Heading.js.map +1 -1
- package/dist/base/Icon.d.ts +1 -1
- package/dist/base/Icon.js +1 -1
- package/dist/base/Icon.js.map +1 -1
- package/dist/base/Indicator.d.ts +1 -1
- package/dist/base/Indicator.js +1 -1
- package/dist/base/Indicator.js.map +1 -1
- package/dist/base/Kbd.d.ts +1 -1
- package/dist/base/Kbd.js +1 -1
- package/dist/base/Kbd.js.map +1 -1
- package/dist/base/Link.d.ts +1 -1
- package/dist/base/Link.js +1 -1
- package/dist/base/Link.js.map +1 -1
- package/dist/base/List.d.ts +1 -1
- package/dist/base/List.js +1 -1
- package/dist/base/List.js.map +1 -1
- package/dist/base/Mark.d.ts +1 -1
- package/dist/base/Mark.js +1 -1
- package/dist/base/Mark.js.map +1 -1
- package/dist/base/Spinner.d.ts +1 -1
- package/dist/base/Spinner.js +1 -1
- package/dist/base/Spinner.js.map +1 -1
- package/dist/base/StatusDot.d.ts +1 -1
- package/dist/base/StatusDot.js +1 -1
- package/dist/base/StatusDot.js.map +1 -1
- package/dist/base/Tag.d.ts +1 -1
- package/dist/base/Tag.js +1 -1
- package/dist/base/Tag.js.map +1 -1
- package/dist/base/Text.d.ts +1 -1
- package/dist/base/Text.js +1 -1
- package/dist/base/Text.js.map +1 -1
- package/dist/base/VisuallyHidden.d.ts +1 -1
- package/dist/base/VisuallyHidden.js +1 -1
- package/dist/base/VisuallyHidden.js.map +1 -1
- package/dist/base/badge-styles.d.ts +1 -1
- package/dist/base/badge-styles.js +1 -1
- package/dist/base/badge-styles.js.map +1 -1
- package/dist/base/button-core.d.ts +1 -1
- package/dist/base/button-core.js +1 -1
- package/dist/base/button-core.js.map +1 -1
- package/dist/charts/ChordChart.d.ts +1 -1
- package/dist/charts/ChordChart.js +1 -1
- package/dist/charts/ChordChart.js.map +1 -1
- package/dist/charts/DonutChart.d.ts +1 -1
- package/dist/charts/DonutChart.js +1 -1
- package/dist/charts/DonutChart.js.map +1 -1
- package/dist/charts/FunnelChart.d.ts +1 -1
- package/dist/charts/FunnelChart.js +1 -1
- package/dist/charts/FunnelChart.js.map +1 -1
- package/dist/charts/GraphChart.d.ts +1 -1
- package/dist/charts/GraphChart.js +1 -1
- package/dist/charts/GraphChart.js.map +1 -1
- package/dist/charts/MapChart.d.ts +1 -1
- package/dist/charts/MapChart.js +1 -1
- package/dist/charts/MapChart.js.map +1 -1
- package/dist/charts/RadarChart.d.ts +1 -1
- package/dist/charts/RadarChart.js +1 -1
- package/dist/charts/RadarChart.js.map +1 -1
- package/dist/charts/SankeyChart.d.ts +1 -1
- package/dist/charts/SankeyChart.js +1 -1
- package/dist/charts/SankeyChart.js.map +1 -1
- package/dist/charts/TreemapChart.d.ts +1 -1
- package/dist/charts/TreemapChart.js +1 -1
- package/dist/charts/TreemapChart.js.map +1 -1
- package/dist/charts/XYChart.d.ts +1 -1
- package/dist/charts/XYChart.js +1 -1
- package/dist/charts/XYChart.js.map +1 -1
- package/dist/charts/frame.d.ts +1 -1
- package/dist/charts/frame.js +1 -1
- package/dist/charts/frame.js.map +1 -1
- package/dist/code-editor/CodeEditor.js +1 -1
- package/dist/code-editor/CodeEditor.js.map +1 -1
- package/dist/config/Provider.d.ts +1 -1
- package/dist/config/Provider.js +1 -1
- package/dist/config/Provider.js.map +1 -1
- package/dist/config/createUi.d.ts +1 -1
- package/dist/config/createUi.js +1 -1
- package/dist/config/createUi.js.map +1 -1
- package/dist/config/theme/coffee.d.ts +1 -1
- package/dist/config/theme/coffee.js +1 -1
- package/dist/config/theme/coffee.js.map +1 -1
- package/dist/config/theme/cyberpunk.d.ts +1 -1
- package/dist/config/theme/cyberpunk.js +1 -1
- package/dist/config/theme/cyberpunk.js.map +1 -1
- package/dist/config/theme/dark.d.ts +1 -1
- package/dist/config/theme/dark.js +1 -1
- package/dist/config/theme/dark.js.map +1 -1
- package/dist/config/theme/festive.d.ts +1 -1
- package/dist/config/theme/festive.js +1 -1
- package/dist/config/theme/festive.js.map +1 -1
- package/dist/config/theme/forest.d.ts +1 -1
- package/dist/config/theme/forest.js +1 -1
- package/dist/config/theme/forest.js.map +1 -1
- package/dist/config/theme/high-contrast.d.ts +1 -1
- package/dist/config/theme/high-contrast.js +1 -1
- package/dist/config/theme/high-contrast.js.map +1 -1
- package/dist/config/theme/lemon.d.ts +1 -1
- package/dist/config/theme/lemon.js +1 -1
- package/dist/config/theme/lemon.js.map +1 -1
- package/dist/config/theme/light.d.ts +1 -1
- package/dist/config/theme/light.js +1 -1
- package/dist/config/theme/light.js.map +1 -1
- package/dist/config/theme/midnight.d.ts +1 -1
- package/dist/config/theme/midnight.js +1 -1
- package/dist/config/theme/midnight.js.map +1 -1
- package/dist/config/theme/ocean.d.ts +1 -1
- package/dist/config/theme/ocean.js +1 -1
- package/dist/config/theme/ocean.js.map +1 -1
- package/dist/config/theme/paper.d.ts +1 -1
- package/dist/config/theme/paper.js +1 -1
- package/dist/config/theme/paper.js.map +1 -1
- package/dist/config/theme/sakura.d.ts +1 -1
- package/dist/config/theme/sakura.js +1 -1
- package/dist/config/theme/sakura.js.map +1 -1
- package/dist/config/theme/theme.js +1 -1
- package/dist/config/theme/theme.js.map +1 -1
- package/dist/config/theme/tokens.d.ts +1 -1
- package/dist/config/theme/tokens.js +1 -1
- package/dist/config/theme/tokens.js.map +1 -1
- package/dist/date/CalendarBoard.d.ts +1 -1
- package/dist/date/CalendarBoard.js +1 -1
- package/dist/date/CalendarBoard.js.map +1 -1
- package/dist/date/CalendarView.d.ts +1 -1
- package/dist/date/CalendarView.js +1 -1
- package/dist/date/CalendarView.js.map +1 -1
- package/dist/date/Countdown.d.ts +1 -1
- package/dist/date/Countdown.js +1 -1
- package/dist/date/Countdown.js.map +1 -1
- package/dist/date/DatePicker.d.ts +1 -1
- package/dist/date/DatePicker.js +1 -1
- package/dist/date/DatePicker.js.map +1 -1
- package/dist/date/DateRangePicker.d.ts +1 -1
- package/dist/date/DateRangePicker.js +1 -1
- package/dist/date/DateRangePicker.js.map +1 -1
- package/dist/date/DateSegmentGroup.d.ts +1 -1
- package/dist/date/DateSegmentGroup.js +1 -1
- package/dist/date/DateSegmentGroup.js.map +1 -1
- package/dist/date/QuarterCalendar.js +1 -1
- package/dist/date/QuarterCalendar.js.map +1 -1
- package/dist/date/SegmentedField.d.ts +1 -1
- package/dist/date/SegmentedField.js +1 -1
- package/dist/date/SegmentedField.js.map +1 -1
- package/dist/date/TimePicker.d.ts +1 -1
- package/dist/date/TimePicker.js +1 -1
- package/dist/date/TimePicker.js.map +1 -1
- package/dist/date/picker-popover.d.ts +1 -1
- package/dist/date/picker-popover.js +1 -1
- package/dist/date/picker-popover.js.map +1 -1
- package/dist/diagram/Diagram.d.ts +1 -1
- package/dist/diagram/Diagram.js +1 -1
- package/dist/diagram/Diagram.js.map +1 -1
- package/dist/diagram/DiagramControls.d.ts +1 -1
- package/dist/diagram/DiagramControls.js +1 -1
- package/dist/diagram/DiagramControls.js.map +1 -1
- package/dist/diagram/DiagramLanes.d.ts +1 -1
- package/dist/diagram/DiagramLanes.js +1 -1
- package/dist/diagram/DiagramLanes.js.map +1 -1
- package/dist/diagram/DiagramMinimap.d.ts +1 -1
- package/dist/diagram/DiagramMinimap.js +1 -1
- package/dist/diagram/DiagramMinimap.js.map +1 -1
- package/dist/diagram/DiagramNode.d.ts +1 -1
- package/dist/diagram/DiagramNode.js +1 -1
- package/dist/diagram/DiagramNode.js.map +1 -1
- package/dist/display/Accordion.d.ts +1 -1
- package/dist/display/Accordion.js +1 -1
- package/dist/display/Accordion.js.map +1 -1
- package/dist/display/AnimatedNumber.d.ts +1 -1
- package/dist/display/AnimatedNumber.js +1 -1
- package/dist/display/AnimatedNumber.js.map +1 -1
- package/dist/display/Avatar.d.ts +1 -1
- package/dist/display/Avatar.js +1 -1
- package/dist/display/Avatar.js.map +1 -1
- package/dist/display/AvatarGroup.d.ts +1 -1
- package/dist/display/AvatarGroup.js +1 -1
- package/dist/display/AvatarGroup.js.map +1 -1
- package/dist/display/Card.d.ts +1 -1
- package/dist/display/Card.js +1 -1
- package/dist/display/Card.js.map +1 -1
- package/dist/display/Checklist.d.ts +1 -1
- package/dist/display/Checklist.js +1 -1
- package/dist/display/Checklist.js.map +1 -1
- package/dist/display/Collapse.d.ts +1 -1
- package/dist/display/Collapse.js +1 -1
- package/dist/display/Collapse.js.map +1 -1
- package/dist/display/Descriptions.d.ts +1 -1
- package/dist/display/Descriptions.js +1 -1
- package/dist/display/Descriptions.js.map +1 -1
- package/dist/display/Ellipsis.d.ts +1 -1
- package/dist/display/Ellipsis.js +1 -1
- package/dist/display/Ellipsis.js.map +1 -1
- package/dist/display/FieldCompare.d.ts +1 -1
- package/dist/display/FieldCompare.js +1 -1
- package/dist/display/FieldCompare.js.map +1 -1
- package/dist/display/Gauge.d.ts +1 -1
- package/dist/display/Gauge.js +1 -1
- package/dist/display/Gauge.js.map +1 -1
- package/dist/display/Image.d.ts +1 -1
- package/dist/display/Image.js +1 -1
- package/dist/display/Image.js.map +1 -1
- package/dist/display/ItemList.d.ts +1 -1
- package/dist/display/ItemList.js +1 -1
- package/dist/display/ItemList.js.map +1 -1
- package/dist/display/Marquee.d.ts +1 -1
- package/dist/display/Marquee.js +1 -1
- package/dist/display/Marquee.js.map +1 -1
- package/dist/display/ProportionBar.d.ts +1 -1
- package/dist/display/ProportionBar.js +1 -1
- package/dist/display/ProportionBar.js.map +1 -1
- package/dist/display/Sortable.d.ts +1 -1
- package/dist/display/Sortable.js +1 -1
- package/dist/display/Sortable.js.map +1 -1
- package/dist/display/Sparkline.d.ts +1 -1
- package/dist/display/Sparkline.js +1 -1
- package/dist/display/Sparkline.js.map +1 -1
- package/dist/display/Stat.d.ts +1 -1
- package/dist/display/Stat.js +1 -1
- package/dist/display/Stat.js.map +1 -1
- package/dist/display/Timeline.d.ts +1 -1
- package/dist/display/Timeline.js +1 -1
- package/dist/display/Timeline.js.map +1 -1
- package/dist/display/Tree.d.ts +1 -1
- package/dist/display/Tree.js +1 -1
- package/dist/display/Tree.js.map +1 -1
- package/dist/display/VirtualList.d.ts +1 -1
- package/dist/display/VirtualList.js +1 -1
- package/dist/display/VirtualList.js.map +1 -1
- package/dist/display/Watermark.d.ts +1 -1
- package/dist/display/Watermark.js +1 -1
- package/dist/display/Watermark.js.map +1 -1
- package/dist/docs-kit/CodeGroup.d.ts +1 -1
- package/dist/docs-kit/CodeGroup.js +1 -1
- package/dist/docs-kit/CodeGroup.js.map +1 -1
- package/dist/docs-kit/CodePreview.d.ts +1 -1
- package/dist/docs-kit/CodePreview.js +1 -1
- package/dist/docs-kit/CodePreview.js.map +1 -1
- package/dist/docs-kit/ColorSwatch.d.ts +1 -1
- package/dist/docs-kit/ColorSwatch.js +1 -1
- package/dist/docs-kit/ColorSwatch.js.map +1 -1
- package/dist/docs-kit/PropsTable.d.ts +1 -1
- package/dist/docs-kit/PropsTable.js +1 -1
- package/dist/docs-kit/PropsTable.js.map +1 -1
- package/dist/feedback/Alert.d.ts +1 -1
- package/dist/feedback/Alert.js +1 -1
- package/dist/feedback/Alert.js.map +1 -1
- package/dist/feedback/Banner.d.ts +1 -1
- package/dist/feedback/Banner.js +1 -1
- package/dist/feedback/Banner.js.map +1 -1
- package/dist/feedback/Empty.d.ts +1 -1
- package/dist/feedback/Empty.js +1 -1
- package/dist/feedback/Empty.js.map +1 -1
- package/dist/feedback/LoadingBar.d.ts +1 -1
- package/dist/feedback/LoadingBar.js +1 -1
- package/dist/feedback/LoadingBar.js.map +1 -1
- package/dist/feedback/LoadingOverlay.d.ts +1 -1
- package/dist/feedback/LoadingOverlay.js +1 -1
- package/dist/feedback/LoadingOverlay.js.map +1 -1
- package/dist/feedback/Progress.d.ts +1 -1
- package/dist/feedback/Progress.js +1 -1
- package/dist/feedback/Progress.js.map +1 -1
- package/dist/feedback/Result.d.ts +1 -1
- package/dist/feedback/Result.js +1 -1
- package/dist/feedback/Result.js.map +1 -1
- package/dist/feedback/Skeleton.d.ts +1 -1
- package/dist/feedback/Skeleton.js +1 -1
- package/dist/feedback/Skeleton.js.map +1 -1
- package/dist/feedback/SkeletonText.d.ts +1 -1
- package/dist/feedback/SkeletonText.js +1 -1
- package/dist/feedback/SkeletonText.js.map +1 -1
- package/dist/feedback/Toast.d.ts +1 -1
- package/dist/feedback/Toast.js +1 -1
- package/dist/feedback/Toast.js.map +1 -1
- package/dist/form/Field.d.ts +1 -1
- package/dist/form/Field.js +1 -1
- package/dist/form/Field.js.map +1 -1
- package/dist/form/FormErrorSummary.d.ts +1 -1
- package/dist/form/FormErrorSummary.js +1 -1
- package/dist/form/FormErrorSummary.js.map +1 -1
- package/dist/form/FormSection.d.ts +1 -1
- package/dist/form/FormSection.js +1 -1
- package/dist/form/FormSection.js.map +1 -1
- package/dist/form/schemas.d.ts +1 -1
- package/dist/form/schemas.js +1 -1
- package/dist/form/schemas.js.map +1 -1
- package/dist/input/Cascader.d.ts +1 -1
- package/dist/input/Cascader.js +1 -1
- package/dist/input/Cascader.js.map +1 -1
- package/dist/input/CharacterCount.d.ts +1 -1
- package/dist/input/CharacterCount.js +1 -1
- package/dist/input/CharacterCount.js.map +1 -1
- package/dist/input/Checkbox.d.ts +1 -1
- package/dist/input/Checkbox.js +1 -1
- package/dist/input/Checkbox.js.map +1 -1
- package/dist/input/ColorField.d.ts +1 -1
- package/dist/input/ColorField.js +1 -1
- package/dist/input/ColorField.js.map +1 -1
- package/dist/input/Combobox.d.ts +1 -1
- package/dist/input/Combobox.js +1 -1
- package/dist/input/Combobox.js.map +1 -1
- package/dist/input/ConditionBuilder.d.ts +1 -1
- package/dist/input/ConditionBuilder.js +1 -1
- package/dist/input/ConditionBuilder.js.map +1 -1
- package/dist/input/ControlGroup.d.ts +1 -1
- package/dist/input/ControlGroup.js +1 -1
- package/dist/input/ControlGroup.js.map +1 -1
- package/dist/input/FileDrop.d.ts +1 -1
- package/dist/input/FileDrop.js +1 -1
- package/dist/input/FileDrop.js.map +1 -1
- package/dist/input/ListPopover.d.ts +1 -1
- package/dist/input/ListPopover.js +1 -1
- package/dist/input/ListPopover.js.map +1 -1
- package/dist/input/Listbox.d.ts +1 -1
- package/dist/input/Listbox.js +1 -1
- package/dist/input/Listbox.js.map +1 -1
- package/dist/input/Mentions.d.ts +1 -1
- package/dist/input/Mentions.js +1 -1
- package/dist/input/Mentions.js.map +1 -1
- package/dist/input/NumberRangeField.d.ts +1 -1
- package/dist/input/NumberRangeField.js +1 -1
- package/dist/input/NumberRangeField.js.map +1 -1
- package/dist/input/OtpField.d.ts +1 -1
- package/dist/input/OtpField.js +1 -1
- package/dist/input/OtpField.js.map +1 -1
- package/dist/input/PeoplePicker.js +1 -1
- package/dist/input/PeoplePicker.js.map +1 -1
- package/dist/input/PeoplePickerPanel.d.ts +1 -1
- package/dist/input/PeoplePickerPanel.js +1 -1
- package/dist/input/PeoplePickerPanel.js.map +1 -1
- package/dist/input/Radio.d.ts +1 -1
- package/dist/input/Radio.js +1 -1
- package/dist/input/Radio.js.map +1 -1
- package/dist/input/Rating.d.ts +1 -1
- package/dist/input/Rating.js +1 -1
- package/dist/input/Rating.js.map +1 -1
- package/dist/input/Select.d.ts +1 -1
- package/dist/input/Select.js +1 -1
- package/dist/input/Select.js.map +1 -1
- package/dist/input/SelectedTags.d.ts +1 -1
- package/dist/input/SelectedTags.js +1 -1
- package/dist/input/SelectedTags.js.map +1 -1
- package/dist/input/Slider.d.ts +1 -1
- package/dist/input/Slider.js +1 -1
- package/dist/input/Slider.js.map +1 -1
- package/dist/input/Switch.d.ts +1 -1
- package/dist/input/Switch.js +1 -1
- package/dist/input/Switch.js.map +1 -1
- package/dist/input/TagsInput.d.ts +1 -1
- package/dist/input/TagsInput.js +1 -1
- package/dist/input/TagsInput.js.map +1 -1
- package/dist/input/Textarea.d.ts +1 -1
- package/dist/input/Textarea.js +1 -1
- package/dist/input/Textarea.js.map +1 -1
- package/dist/input/ToggleGroup.d.ts +1 -1
- package/dist/input/ToggleGroup.js +1 -1
- package/dist/input/ToggleGroup.js.map +1 -1
- package/dist/input/Transfer.d.ts +1 -1
- package/dist/input/Transfer.js +1 -1
- package/dist/input/Transfer.js.map +1 -1
- package/dist/input/TreeSelect.d.ts +1 -1
- package/dist/input/TreeSelect.js +1 -1
- package/dist/input/TreeSelect.js.map +1 -1
- package/dist/input/Upload.d.ts +1 -1
- package/dist/input/Upload.js +1 -1
- package/dist/input/Upload.js.map +1 -1
- package/dist/input/choice-styles.d.ts +1 -1
- package/dist/input/choice-styles.js +1 -1
- package/dist/input/choice-styles.js.map +1 -1
- package/dist/input/control.d.ts +1 -1
- package/dist/input/control.js +1 -1
- package/dist/input/control.js.map +1 -1
- package/dist/layout/Affix.d.ts +1 -1
- package/dist/layout/Affix.js +1 -1
- package/dist/layout/Affix.js.map +1 -1
- package/dist/layout/AsideLayout.d.ts +1 -1
- package/dist/layout/AsideLayout.js +1 -1
- package/dist/layout/AsideLayout.js.map +1 -1
- package/dist/layout/BackTop.d.ts +1 -1
- package/dist/layout/BackTop.js +1 -1
- package/dist/layout/BackTop.js.map +1 -1
- package/dist/layout/Container.d.ts +1 -1
- package/dist/layout/Container.js +1 -1
- package/dist/layout/Container.js.map +1 -1
- package/dist/layout/Flex.d.ts +1 -1
- package/dist/layout/Flex.js +1 -1
- package/dist/layout/Flex.js.map +1 -1
- package/dist/layout/Grid.d.ts +1 -1
- package/dist/layout/Grid.js +1 -1
- package/dist/layout/Grid.js.map +1 -1
- package/dist/layout/PageScrollbar.d.ts +1 -1
- package/dist/layout/PageScrollbar.js +1 -1
- package/dist/layout/PageScrollbar.js.map +1 -1
- package/dist/layout/Prose.d.ts +1 -1
- package/dist/layout/Prose.js +1 -1
- package/dist/layout/Prose.js.map +1 -1
- package/dist/layout/ResizeHandle.d.ts +1 -1
- package/dist/layout/ResizeHandle.js +1 -1
- package/dist/layout/ResizeHandle.js.map +1 -1
- package/dist/layout/ScrollArea.d.ts +1 -1
- package/dist/layout/ScrollArea.js +1 -1
- package/dist/layout/ScrollArea.js.map +1 -1
- package/dist/layout/Separator.d.ts +1 -1
- package/dist/layout/Separator.js +1 -1
- package/dist/layout/Separator.js.map +1 -1
- package/dist/layout/Splitter.d.ts +1 -1
- package/dist/layout/Splitter.js +1 -1
- package/dist/layout/Splitter.js.map +1 -1
- package/dist/layout/ViewportFill.d.ts +1 -1
- package/dist/layout/ViewportFill.js +1 -1
- package/dist/layout/ViewportFill.js.map +1 -1
- package/dist/navigation/Breadcrumbs.d.ts +1 -1
- package/dist/navigation/Breadcrumbs.js +1 -1
- package/dist/navigation/Breadcrumbs.js.map +1 -1
- package/dist/navigation/NavBar.d.ts +1 -1
- package/dist/navigation/NavBar.js +1 -1
- package/dist/navigation/NavBar.js.map +1 -1
- package/dist/navigation/NavList.d.ts +1 -1
- package/dist/navigation/NavList.js +1 -1
- package/dist/navigation/NavList.js.map +1 -1
- package/dist/navigation/PageJump.d.ts +1 -1
- package/dist/navigation/PageJump.js +1 -1
- package/dist/navigation/PageJump.js.map +1 -1
- package/dist/navigation/PageSizeSelect.d.ts +1 -1
- package/dist/navigation/PageSizeSelect.js +1 -1
- package/dist/navigation/PageSizeSelect.js.map +1 -1
- package/dist/navigation/Pager.d.ts +1 -1
- package/dist/navigation/Pager.js +1 -1
- package/dist/navigation/Pager.js.map +1 -1
- package/dist/navigation/Pagination.d.ts +1 -1
- package/dist/navigation/Pagination.js +1 -1
- package/dist/navigation/Pagination.js.map +1 -1
- package/dist/navigation/PaginationBar.d.ts +1 -1
- package/dist/navigation/PaginationBar.js +1 -1
- package/dist/navigation/PaginationBar.js.map +1 -1
- package/dist/navigation/SkipLink.d.ts +1 -1
- package/dist/navigation/SkipLink.js +1 -1
- package/dist/navigation/SkipLink.js.map +1 -1
- package/dist/navigation/Steps.d.ts +1 -1
- package/dist/navigation/Steps.js +1 -1
- package/dist/navigation/Steps.js.map +1 -1
- package/dist/navigation/TableOfContents.d.ts +1 -1
- package/dist/navigation/TableOfContents.js +1 -1
- package/dist/navigation/TableOfContents.js.map +1 -1
- package/dist/navigation/Tabs.d.ts +1 -1
- package/dist/navigation/Tabs.js +1 -1
- package/dist/navigation/Tabs.js.map +1 -1
- package/dist/navigation/Toolbar.d.ts +1 -1
- package/dist/navigation/Toolbar.js +1 -1
- package/dist/navigation/Toolbar.js.map +1 -1
- package/dist/overlay/CommandPalette.d.ts +1 -1
- package/dist/overlay/CommandPalette.js +1 -1
- package/dist/overlay/CommandPalette.js.map +1 -1
- package/dist/overlay/Dialog.d.ts +1 -1
- package/dist/overlay/Dialog.js +1 -1
- package/dist/overlay/Dialog.js.map +1 -1
- package/dist/overlay/Drawer.d.ts +1 -1
- package/dist/overlay/Drawer.js +1 -1
- package/dist/overlay/Drawer.js.map +1 -1
- package/dist/overlay/HoverCard.d.ts +1 -1
- package/dist/overlay/HoverCard.js +1 -1
- package/dist/overlay/HoverCard.js.map +1 -1
- package/dist/overlay/Lightbox.d.ts +1 -1
- package/dist/overlay/Lightbox.js +1 -1
- package/dist/overlay/Lightbox.js.map +1 -1
- package/dist/overlay/Menu.d.ts +1 -1
- package/dist/overlay/Menu.js +1 -1
- package/dist/overlay/Menu.js.map +1 -1
- package/dist/overlay/Popconfirm.d.ts +1 -1
- package/dist/overlay/Popconfirm.js +1 -1
- package/dist/overlay/Popconfirm.js.map +1 -1
- package/dist/overlay/Popover.d.ts +1 -1
- package/dist/overlay/Popover.js +1 -1
- package/dist/overlay/Popover.js.map +1 -1
- package/dist/overlay/Tooltip.d.ts +1 -1
- package/dist/overlay/Tooltip.js +1 -1
- package/dist/overlay/Tooltip.js.map +1 -1
- package/dist/overlay/Tour.d.ts +1 -1
- package/dist/overlay/Tour.js +1 -1
- package/dist/overlay/Tour.js.map +1 -1
- package/dist/patterns/ActionBar.d.ts +1 -1
- package/dist/patterns/ActionBar.js +1 -1
- package/dist/patterns/ActionBar.js.map +1 -1
- package/dist/patterns/AppShell.d.ts +1 -1
- package/dist/patterns/AppShell.js +1 -1
- package/dist/patterns/AppShell.js.map +1 -1
- package/dist/patterns/AuthLayout.d.ts +2 -2
- package/dist/patterns/AuthLayout.js +2 -2
- package/dist/patterns/AuthLayout.js.map +1 -1
- package/dist/patterns/CommentThread.d.ts +1 -1
- package/dist/patterns/CommentThread.js +1 -1
- package/dist/patterns/CommentThread.js.map +1 -1
- package/dist/patterns/DataImport.d.ts +1 -1
- package/dist/patterns/DataImport.js +1 -1
- package/dist/patterns/DataImport.js.map +1 -1
- package/dist/patterns/FilterBar.d.ts +1 -1
- package/dist/patterns/FilterBar.js +1 -1
- package/dist/patterns/FilterBar.js.map +1 -1
- package/dist/patterns/KanbanBoard.d.ts +1 -1
- package/dist/patterns/KanbanBoard.js +1 -1
- package/dist/patterns/KanbanBoard.js.map +1 -1
- package/dist/patterns/NotificationCenter.d.ts +1 -1
- package/dist/patterns/NotificationCenter.js +1 -1
- package/dist/patterns/NotificationCenter.js.map +1 -1
- package/dist/patterns/QueryTable.d.ts +1 -1
- package/dist/patterns/QueryTable.js +1 -1
- package/dist/patterns/QueryTable.js.map +1 -1
- package/dist/patterns/SlideCaptcha.d.ts +1 -1
- package/dist/patterns/SlideCaptcha.js +1 -1
- package/dist/patterns/SlideCaptcha.js.map +1 -1
- package/dist/patterns/StepsForm.d.ts +1 -1
- package/dist/patterns/StepsForm.js +1 -1
- package/dist/patterns/StepsForm.js.map +1 -1
- package/dist/table/ColumnHeaderActions.d.ts +1 -1
- package/dist/table/ColumnHeaderActions.js +1 -1
- package/dist/table/ColumnHeaderActions.js.map +1 -1
- package/dist/table/ColumnSettings.d.ts +1 -1
- package/dist/table/ColumnSettings.js +1 -1
- package/dist/table/ColumnSettings.js.map +1 -1
- package/dist/table/ColumnTable.d.ts +1 -1
- package/dist/table/ColumnTable.js +1 -1
- package/dist/table/ColumnTable.js.map +1 -1
- package/dist/table/DataTableView.d.ts +1 -1
- package/dist/table/DataTableView.js +1 -1
- package/dist/table/DataTableView.js.map +1 -1
- package/dist/table/PivotTable.d.ts +1 -1
- package/dist/table/PivotTable.js +1 -1
- package/dist/table/PivotTable.js.map +1 -1
- package/dist/table/SelectionBar.d.ts +1 -1
- package/dist/table/SelectionBar.js +1 -1
- package/dist/table/SelectionBar.js.map +1 -1
- package/dist/table/Table.d.ts +1 -1
- package/dist/table/Table.js +1 -1
- package/dist/table/Table.js.map +1 -1
- package/dist/table/TreeDataTable.d.ts +1 -1
- package/dist/table/TreeDataTable.js +1 -1
- package/dist/table/TreeDataTable.js.map +1 -1
- package/dist/table/table-styles.d.ts +1 -1
- package/dist/table/table-styles.js +1 -1
- package/dist/table/table-styles.js.map +1 -1
- package/dist/theme-customize/ThemeCustomizer.d.ts +1 -1
- package/dist/theme-customize/ThemeCustomizer.js +1 -1
- package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
- package/dist/theme-customize/ThemeThumbnail.d.ts +1 -1
- package/dist/theme-customize/ThemeThumbnail.js +1 -1
- package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
- package/dist/theme-customize/design-tokens.js +1 -1
- package/dist/theme-customize/design-tokens.js.map +1 -1
- package/dist/three/core/EffectSurface.d.ts +1 -1
- package/dist/three/core/EffectSurface.js +1 -1
- package/dist/three/core/EffectSurface.js.map +1 -1
- package/dist/three/core/ThreeCanvas.d.ts +1 -1
- package/dist/three/core/ThreeCanvas.js +1 -1
- package/dist/three/core/ThreeCanvas.js.map +1 -1
- package/dist/three/effects/Confetti.d.ts +1 -1
- package/dist/three/effects/Confetti.js +1 -1
- package/dist/three/effects/Confetti.js.map +1 -1
- package/dist/three/globe/Globe.d.ts +1 -1
- package/dist/three/globe/Globe.js +1 -1
- package/dist/three/globe/Globe.js.map +1 -1
- package/dist/three/model/ModelViewer.d.ts +1 -1
- package/dist/three/model/ModelViewer.js +1 -1
- package/dist/three/model/ModelViewer.js.map +1 -1
- package/dist/utils/dom/floating.d.ts +1 -1
- package/dist/utils/dom/floating.js +1 -1
- package/dist/utils/dom/floating.js.map +1 -1
- package/dist/utils/dom/ripple.d.ts +1 -1
- package/dist/utils/dom/ripple.js +1 -1
- package/dist/utils/dom/ripple.js.map +1 -1
- package/dist/utils/props.js +1 -1
- package/dist/utils/props.js.map +1 -1
- package/dist/utils/style/attached.d.ts +1 -1
- package/dist/utils/style/attached.js +1 -1
- package/dist/utils/style/attached.js.map +1 -1
- package/dist/utils/style/item-styles.d.ts +1 -1
- package/dist/utils/style/item-styles.js +1 -1
- package/dist/utils/style/item-styles.js.map +1 -1
- package/dist/utils/style/markers.d.ts +1 -1
- package/dist/utils/style/markers.js +1 -1
- package/dist/utils/style/markers.js.map +1 -1
- package/dist/utils/style/shimmer.d.ts +1 -1
- package/dist/utils/style/shimmer.js +1 -1
- package/dist/utils/style/shimmer.js.map +1 -1
- package/dist/utils/style/styles.d.ts +1 -1
- package/dist/utils/style/styles.js +1 -1
- package/dist/utils/style/styles.js.map +1 -1
- package/dist/utils/style/swatch-styles.d.ts +1 -1
- package/dist/utils/style/swatch-styles.js +1 -1
- package/dist/utils/style/swatch-styles.js.map +1 -1
- package/dist/utils/style/tone-styles.d.ts +1 -1
- package/dist/utils/style/tone-styles.js +1 -1
- package/dist/utils/style/tone-styles.js.map +1 -1
- package/dist/utils/style/transitions.d.ts +1 -1
- package/dist/utils/style/transitions.js +1 -1
- package/dist/utils/style/transitions.js.map +1 -1
- package/dist/utils/style/typography.d.ts +1 -1
- package/dist/utils/style/typography.js +1 -1
- package/dist/utils/style/typography.js.map +1 -1
- package/dist/utils/style/vars.d.ts +1 -1
- package/dist/utils/style/vars.js +1 -1
- package/dist/utils/style/vars.js.map +1 -1
- package/package.json +2 -2
package/dist/display/Stat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stat.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_mergeProps","_Fragment"],"sources":["../../src/display/Stat.tsx"],"sourcesContent":["/**\n * 统计数值(dl):指标名、数值与单位、可选的图标与环比变化。仪表盘顶部的一排卡片、详情页的关键指标。\n * 外观只是内容,放进 Card、Grid 里组合:\n *\n * <Card><Stat label=\"实际销售额\" value={910.36} unit=\"万元\" icon={Wallet} change={0.123} changeLabel=\"较上月\" /></Card>\n * <Stat label=\"测算销售\" value={a} format={wan} unit=\"万元\" footer={<><span>年度目标 2,000 万元</span><span>完成 81%</span></>}>\n * <Progress value={81} size=\"xs\" aria-label=\"年度目标完成度\" />\n * </Stat>\n *\n * 排版(参考 Ant Design Pro 的 ChartCard):第一行是图标与指标名、结束边是变化量;第二行是数值;\n * children 是数值下面占满整宽的补充内容(进度条、迷你图);footer 是底栏,上方一条分隔线,放两项时分别靠两端。\n * 卡片再宽,内容也铺满整行,不在中间留一大块空白。\n *\n * 一排几个指标用 StatGroup:按宽度换行,指标之间一条竖线(同一行里):\n *\n * <StatGroup><Stat label=\"超时\" value={10} tone=\"danger\" /><Stat label=\"待验收\" value={5} /></StatGroup>\n *\n * 数值变化时滚动过渡(AnimatedNumber),读屏只读终值;变化量按正负着色并带箭头,\n * 成本、耗时这类“越低越好”的指标写 invertChange。加载中(loading)数值与变化量换成扫光的骨架,指标名照常显示。\n */\nimport { TrendingDown, TrendingUp } from '@lucide/icons';\nimport { createContext, _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 { Icon, type IconData } from '../base/Icon';\nimport type { NumericFormat } from '../config/lang/format';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { shimmerStyles } from '../utils/style/shimmer';\nimport { toneStyles, type Tone } from '../utils/style/typography';\nimport type { NumericValue } from '../utils/data/numeric';\nimport { AnimatedNumber, type AnimatedNumberProps } from './AnimatedNumber';\nimport { t } from '../config/theme/tokens';\n\n/** 忙碌由组件按 loading 管理 */\nexport type StatManaged = 'aria-busy';\n\n/** 未声明的属性落到外层 dl 上 */\nexport interface StatProps extends PartProps<'dl', StatManaged> {\n /** 指标名 */\n label: VNodeChild;\n /** 数值:number、bigint、Decimal 按当前语言格式化并在变化时滚动;字符串原样显示(如“—”、“98.5%”) */\n value: NumericValue | string;\n /**\n * 数值的格式,如两位小数 `{ minimumFractionDigits: 2 }`、百分比 `{ style: 'percent' }`;\n * 值以元给出、按万元显示时写 `{ scale: 10_000, maximumFractionDigits: 2 }` 并配 `unit=\"万元\"`\n */\n format?: NumericFormat;\n /** 单位,跟在数值后面、字号小一档 */\n unit?: VNodeChild;\n /** 数值的色调:超时、缺漏这类要引起注意的数用 danger、warning;不写时是正文色 */\n tone?: Tone;\n /** 指标名前面的图标(装饰,对读屏隐藏) */\n icon?: IconData;\n /** 变化量(环比、同比):正数向上、负数向下;默认按百分比显示(0.12 → +12%) */\n change?: number;\n /** 变化量的格式,默认 `{ style: 'percent', maximumFractionDigits: 1, signDisplay: 'exceptZero' }` */\n changeFormat?: NumericFormat;\n /** 变化量后面的说明,如“较上月” */\n changeLabel?: VNodeChild;\n /** 下降是好事(成本、耗时、故障数):下降显示成功色、上升显示危险色 */\n invertChange?: boolean;\n /** 数值下面的补充说明(一行小字) */\n description?: VNodeChild;\n /** 底栏:上方一条分隔线;放两项时分别靠两端,如“年度目标 2,000 万元”与“完成 81%” */\n footer?: VNodeChild;\n /** 数值下面占满整宽的补充内容:进度条、迷你图 */\n children?: VNodeChild;\n /**\n * 加载中:数值与变化量换成扫光的骨架,带 aria-busy;很快完成时不闪\n * @default false\n */\n loading?: boolean;\n /** 指标名(dt)的部件属性 */\n propsLabel?: PartProps<'dt'>;\n /** 数值(dd)的部件属性 */\n propsValue?: PartProps<'dd'>;\n /** 图标外层的部件属性 */\n propsIcon?: PartProps<'span', 'aria-hidden'>;\n /** 数字本身(AnimatedNumber 或字符串值的 span)的部件属性 */\n propsNumber?: PartProps<'span', 'prefix'>;\n /** 单位的部件属性 */\n propsUnit?: PartProps<'span'>;\n /** 变化(dd)的部件属性 */\n propsChange?: PartProps<'dd'>;\n /** 变化后面的说明的部件属性 */\n propsChangeLabel?: PartProps<'span'>;\n /** 补充说明(dd)的部件属性 */\n propsDescription?: PartProps<'dd'>;\n /** 补充内容(dd,children 的外层)的部件属性 */\n propsBody?: PartProps<'dd'>;\n /** 底栏(dd)的部件属性 */\n propsFooter?: PartProps<'dd'>;\n}\n\nconst CHANGE_FORMAT: NumericFormat = {\n style: 'percent',\n maximumFractionDigits: 1,\n signDisplay: 'exceptZero',\n};\n\n/** 在 StatGroup 里:指标之间画竖线 */\nconst StatGroupContext = createContext<boolean>('StatGroup');\n\n/** Stat 的样式:root、label、icon、value、number、unit、change、description、body、footer、skeleton… */\nexport const statStyles = css.create({\n // 第一行是指标名与变化量(结束边),其余各占一整行。可换行的弹性布局而不是两列网格:\n // 卡片窄时变化量换到下一行,指标名不被挤成一字一行;DOM 顺序不变(读屏仍是名称、数值、变化量)\n root: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: '_sm',\n rowGap: '_xs',\n margin: 0,\n minWidth: 0,\n },\n // dt 里放图标与指标名:dl 的子元素只能是 dt、dd\n label: {\n order: 0,\n flexGrow: 1,\n display: 'flex',\n alignItems: 'center',\n gap: '_sm',\n minWidth: 0,\n margin: 0,\n color: '_textMuted',\n fontSize: '_sm',\n },\n icon: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n width: '1.75em',\n height: '1.75em',\n borderRadius: '_md',\n backgroundColor: '_accentSoft',\n color: '_accentText',\n },\n value: {\n order: 2,\n flexBasis: '100%',\n display: 'flex',\n alignItems: 'baseline',\n flexWrap: 'wrap',\n gap: '_xs',\n margin: 0,\n },\n number: {\n fontSize: '_xxl',\n fontWeight: '_bold',\n lineHeight: '_tight',\n color: '_text',\n fontVariantNumeric: 'tabular-nums',\n },\n unit: { color: '_textMuted', fontSize: '_xs' },\n // 变化量在指标名那一行的结束边\n change: {\n order: 1,\n display: 'flex',\n alignItems: 'center',\n gap: '_xs',\n fontSize: '_xs',\n margin: 0,\n whiteSpace: 'nowrap',\n },\n changeLabel: { color: '_textMuted' },\n description: { order: 3, flexBasis: '100%', color: '_textMuted', fontSize: '_xs', margin: 0 },\n body: { order: 3, flexBasis: '100%', margin: 0, minWidth: 0 },\n // 底栏:两项时分别靠两端,多了换行\n footer: {\n order: 3,\n flexBasis: '100%',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'baseline',\n justifyContent: 'space-between',\n columnGap: '_md',\n rowGap: '_xs',\n margin: 0,\n marginBlockStart: '_xs',\n paddingBlockStart: '_sm',\n borderBlockStartWidth: '_xs',\n borderBlockStartStyle: 'solid',\n borderBlockStartColor: '_borderMuted',\n color: '_textMuted',\n fontSize: '_xs',\n },\n // 骨架与数值、变化量同高:加载完换成内容时不跳\n numberSkeleton: { fontSize: '_xxl', width: '4em', height: '1.25em' },\n changeSkeleton: { width: '6em', height: '1.5em' },\n});\n\n/** 统计数值:指标名、数值与单位、图标、变化量 */\nexport const Stat = _component(\n ({\n label,\n value,\n format,\n unit,\n tone,\n icon,\n change,\n changeFormat = CHANGE_FORMAT,\n changeLabel,\n invertChange = false,\n description,\n footer,\n children,\n loading = false,\n propsLabel,\n propsValue,\n propsIcon,\n propsNumber,\n propsUnit,\n propsChange,\n propsChangeLabel,\n propsDescription,\n propsBody,\n propsFooter,\n ...rest\n }: StatProps) => {\n const grouped = StatGroupContext.inject(false);\n // 骨架防闪烁;aria-busy 按真实的 loading\n const skeleton = useDelayedLoading(() => loading);\n // 出现过骨架之后,换回数值时淡入(样式在切换的那一刻加上,动画才会播)\n let revealing = false;\n return () => {\n if (skeleton.value) revealing = true;\n const reveal = revealing && !skeleton.value && shimmerStyles.reveal;\n const direction = change === undefined || change === 0 ? 'flat' : change > 0 ? 'up' : 'down';\n const improved = invertChange ? direction === 'down' : direction === 'up';\n const changeTone = direction === 'flat' ? 'muted' : improved ? 'success' : 'danger';\n return (\n <dl\n {...mergeAttrs<'dl'>({ sx: [statStyles.root, grouped && statGroupStyles.item] }, rest, {\n 'aria-busy': loading || undefined,\n })}\n >\n <dt {...mergeAttrs<'dt'>({ sx: statStyles.label }, propsLabel)}>\n {icon && (\n <span\n {...mergeAttrs<'span'>({ sx: statStyles.icon }, propsIcon, { 'aria-hidden': true })}\n >\n <Icon icon={icon} />\n </span>\n )}\n <span>{label}</span>\n </dt>\n <dd {...mergeAttrs<'dd'>({ sx: [statStyles.value, reveal] }, propsValue)}>\n {skeleton.value ? (\n <Skeleton sx={statStyles.numberSkeleton} />\n ) : typeof value !== 'string' ? (\n <AnimatedNumber\n {...mergePartProps<AnimatedNumberProps>(\n { sx: [statStyles.number, tone && toneStyles[tone]], value },\n propsNumber,\n {\n value,\n format,\n },\n )}\n />\n ) : (\n <span\n {...mergeAttrs<'span'>(\n { sx: [statStyles.number, tone && toneStyles[tone]] },\n propsNumber,\n )}\n >\n {value}\n </span>\n )}\n {unit != null && !skeleton.value && (\n <span {...mergeAttrs<'span'>({ sx: statStyles.unit }, propsUnit)}>{unit}</span>\n )}\n </dd>\n {change !== undefined && (\n <dd\n {...mergeAttrs<'dd'>({ sx: [statStyles.change, reveal] }, propsChange)}\n data-trend={skeleton.value ? undefined : direction}\n >\n {skeleton.value ? (\n <Skeleton sx={statStyles.changeSkeleton} />\n ) : (\n <>\n <span {...css.attrs(toneStyles[changeTone])}>\n {direction !== 'flat' && (\n <Icon\n icon={direction === 'up' ? TrendingUp : TrendingDown}\n aria-hidden=\"true\"\n />\n )}{' '}\n <AnimatedNumber value={change} format={changeFormat} />\n </span>\n {changeLabel != null && (\n <span {...mergeAttrs<'span'>({ sx: statStyles.changeLabel }, propsChangeLabel)}>\n {changeLabel}\n </span>\n )}\n </>\n )}\n </dd>\n )}\n {hasContent(description) && (\n <dd {...mergeAttrs<'dd'>({ sx: statStyles.description }, propsDescription)}>\n {description}\n </dd>\n )}\n {hasContent(children) && (\n <dd {...mergeAttrs<'dd'>({ sx: statStyles.body }, propsBody)}>{children}</dd>\n )}\n {hasContent(footer) && (\n <dd {...mergeAttrs<'dd'>({ sx: statStyles.footer }, propsFooter)}>{footer}</dd>\n )}\n </dl>\n );\n };\n },\n);\n\n/** 未声明的属性落到外层 div 上 */\nexport interface StatGroupProps extends PartProps<'div'> {\n /**\n * 每个指标最窄多宽(CSS 长度):放不下就换行\n * @default '9rem'\n */\n minItemWidth?: string;\n /** Stat */\n children?: VNodeChild;\n}\n\n/** StatGroup 的样式:root、item */\nexport const statGroupStyles = css.create({\n // 每个指标的起始边一条竖线;整组往起始方向挪一条线的位置,每行第一个的竖线藏到外面(overflow 裁掉)\n root: { display: 'grid', rowGap: '_md', overflow: 'hidden' },\n item: {\n paddingInline: '_md',\n marginInlineStart: `calc(-1 * ${t.borderWidths.xs})`,\n borderInlineStartWidth: '_xs',\n borderInlineStartStyle: 'solid',\n borderInlineStartColor: '_borderMuted',\n },\n});\n\n/** StatGroup 的动态样式:列宽 */\nexport const statGroupDynamicStyles = css.create({\n columns: (min: string) => ({\n gridTemplateColumns: `repeat(auto-fit, minmax(min(${min}, 100%), 1fr))`,\n }),\n});\n\n/** 一排指标:按宽度换行,同一行里指标之间一条竖线 */\nexport const StatGroup = _component(\n ({ minItemWidth = '9rem', children, ...rest }: StatGroupProps) => {\n StatGroupContext.provide(true);\n return () => (\n <div\n {...mergeAttrs<'div'>(\n { sx: [statGroupStyles.root, statGroupDynamicStyles.columns(minItemWidth)] },\n rest,\n )}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Stat.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_mergeProps","_Fragment"],"sources":["../../src/display/Stat.tsx"],"sourcesContent":["/**\n * 统计数值(dl):指标名、数值与单位、可选的图标与环比变化。仪表盘顶部的一排卡片、详情页的关键指标。\n * 外观只是内容,放进 Card、Grid 里组合:\n *\n * <Card><Stat label=\"实际销售额\" value={910.36} unit=\"万元\" icon={Wallet} change={0.123} changeLabel=\"较上月\" /></Card>\n * <Stat label=\"测算销售\" value={a} format={wan} unit=\"万元\" footer={<><span>年度目标 2,000 万元</span><span>完成 81%</span></>}>\n * <Progress value={81} size=\"xs\" aria-label=\"年度目标完成度\" />\n * </Stat>\n *\n * 排版(参考 Ant Design Pro 的 ChartCard):第一行是图标与指标名、结束边是变化量;第二行是数值;\n * children 是数值下面占满整宽的补充内容(进度条、迷你图);footer 是底栏,上方一条分隔线,放两项时分别靠两端。\n * 卡片再宽,内容也铺满整行,不在中间留一大块空白。\n *\n * 一排几个指标用 StatGroup:按宽度换行,指标之间一条竖线(同一行里):\n *\n * <StatGroup><Stat label=\"超时\" value={10} tone=\"danger\" /><Stat label=\"待验收\" value={5} /></StatGroup>\n *\n * 数值变化时滚动过渡(AnimatedNumber),读屏只读终值;变化量按正负着色并带箭头,\n * 成本、耗时这类“越低越好”的指标写 invertChange。加载中(loading)数值与变化量换成扫光的骨架,指标名照常显示。\n */\nimport { TrendingDown, TrendingUp } from '@lucide/icons';\nimport { createContext, _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { Icon, type IconData } from '../base/Icon';\nimport type { NumericFormat } from '../config/lang/format';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { shimmerStyles } from '../utils/style/shimmer';\nimport { toneStyles, type Tone } from '../utils/style/typography';\nimport type { NumericValue } from '../utils/data/numeric';\nimport { AnimatedNumber, type AnimatedNumberProps } from './AnimatedNumber';\nimport { t } from '../config/theme/tokens';\n\n/** 忙碌由组件按 loading 管理 */\nexport type StatManaged = 'aria-busy';\n\n/** 未声明的属性落到外层 dl 上 */\nexport interface StatProps extends PartProps<'dl', StatManaged> {\n /** 指标名 */\n label: VNodeChild;\n /** 数值:number、bigint、Decimal 按当前语言格式化并在变化时滚动;字符串原样显示(如“—”、“98.5%”) */\n value: NumericValue | string;\n /**\n * 数值的格式,如两位小数 `{ minimumFractionDigits: 2 }`、百分比 `{ style: 'percent' }`;\n * 值以元给出、按万元显示时写 `{ scale: 10_000, maximumFractionDigits: 2 }` 并配 `unit=\"万元\"`\n */\n format?: NumericFormat;\n /** 单位,跟在数值后面、字号小一档 */\n unit?: VNodeChild;\n /** 数值的色调:超时、缺漏这类要引起注意的数用 danger、warning;不写时是正文色 */\n tone?: Tone;\n /** 指标名前面的图标(装饰,对读屏隐藏) */\n icon?: IconData;\n /** 变化量(环比、同比):正数向上、负数向下;默认按百分比显示(0.12 → +12%) */\n change?: number;\n /** 变化量的格式,默认 `{ style: 'percent', maximumFractionDigits: 1, signDisplay: 'exceptZero' }` */\n changeFormat?: NumericFormat;\n /** 变化量后面的说明,如“较上月” */\n changeLabel?: VNodeChild;\n /** 下降是好事(成本、耗时、故障数):下降显示成功色、上升显示危险色 */\n invertChange?: boolean;\n /** 数值下面的补充说明(一行小字) */\n description?: VNodeChild;\n /** 底栏:上方一条分隔线;放两项时分别靠两端,如“年度目标 2,000 万元”与“完成 81%” */\n footer?: VNodeChild;\n /** 数值下面占满整宽的补充内容:进度条、迷你图 */\n children?: VNodeChild;\n /**\n * 加载中:数值与变化量换成扫光的骨架,带 aria-busy;很快完成时不闪\n * @default false\n */\n loading?: boolean;\n /** 指标名(dt)的部件属性 */\n propsLabel?: PartProps<'dt'>;\n /** 数值(dd)的部件属性 */\n propsValue?: PartProps<'dd'>;\n /** 图标外层的部件属性 */\n propsIcon?: PartProps<'span', 'aria-hidden'>;\n /** 数字本身(AnimatedNumber 或字符串值的 span)的部件属性 */\n propsNumber?: PartProps<'span', 'prefix'>;\n /** 单位的部件属性 */\n propsUnit?: PartProps<'span'>;\n /** 变化(dd)的部件属性 */\n propsChange?: PartProps<'dd'>;\n /** 变化后面的说明的部件属性 */\n propsChangeLabel?: PartProps<'span'>;\n /** 补充说明(dd)的部件属性 */\n propsDescription?: PartProps<'dd'>;\n /** 补充内容(dd,children 的外层)的部件属性 */\n propsBody?: PartProps<'dd'>;\n /** 底栏(dd)的部件属性 */\n propsFooter?: PartProps<'dd'>;\n}\n\nconst CHANGE_FORMAT: NumericFormat = {\n style: 'percent',\n maximumFractionDigits: 1,\n signDisplay: 'exceptZero',\n};\n\n/** 在 StatGroup 里:指标之间画竖线 */\nconst StatGroupContext = createContext<boolean>('StatGroup');\n\n/** Stat 的样式:root、label、icon、value、number、unit、change、description、body、footer、skeleton… */\nexport const statStyles = css.create({\n // 第一行是指标名与变化量(结束边),其余各占一整行。可换行的弹性布局而不是两列网格:\n // 卡片窄时变化量换到下一行,指标名不被挤成一字一行;DOM 顺序不变(读屏仍是名称、数值、变化量)\n root: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: '_sm',\n rowGap: '_xs',\n margin: 0,\n minWidth: 0,\n },\n // dt 里放图标与指标名:dl 的子元素只能是 dt、dd\n label: {\n order: 0,\n flexGrow: 1,\n display: 'flex',\n alignItems: 'center',\n gap: '_sm',\n minWidth: 0,\n margin: 0,\n color: '_textMuted',\n fontSize: '_sm',\n },\n icon: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n width: '1.75em',\n height: '1.75em',\n borderRadius: '_md',\n backgroundColor: '_accentSoft',\n color: '_accentText',\n },\n value: {\n order: 2,\n flexBasis: '100%',\n display: 'flex',\n alignItems: 'baseline',\n flexWrap: 'wrap',\n gap: '_xs',\n margin: 0,\n },\n number: {\n fontSize: '_xxl',\n fontWeight: '_bold',\n lineHeight: '_tight',\n color: '_text',\n fontVariantNumeric: 'tabular-nums',\n },\n unit: { color: '_textMuted', fontSize: '_xs' },\n // 变化量在指标名那一行的结束边\n change: {\n order: 1,\n display: 'flex',\n alignItems: 'center',\n gap: '_xs',\n fontSize: '_xs',\n margin: 0,\n whiteSpace: 'nowrap',\n },\n changeLabel: { color: '_textMuted' },\n description: { order: 3, flexBasis: '100%', color: '_textMuted', fontSize: '_xs', margin: 0 },\n body: { order: 3, flexBasis: '100%', margin: 0, minWidth: 0 },\n // 底栏:两项时分别靠两端,多了换行\n footer: {\n order: 3,\n flexBasis: '100%',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'baseline',\n justifyContent: 'space-between',\n columnGap: '_md',\n rowGap: '_xs',\n margin: 0,\n marginBlockStart: '_xs',\n paddingBlockStart: '_sm',\n borderBlockStartWidth: '_xs',\n borderBlockStartStyle: 'solid',\n borderBlockStartColor: '_borderMuted',\n color: '_textMuted',\n fontSize: '_xs',\n },\n // 骨架与数值、变化量同高:加载完换成内容时不跳\n numberSkeleton: { fontSize: '_xxl', width: '4em', height: '1.25em' },\n changeSkeleton: { width: '6em', height: '1.5em' },\n});\n\n/** 统计数值:指标名、数值与单位、图标、变化量 */\nexport const Stat = _component(\n ({\n label,\n value,\n format,\n unit,\n tone,\n icon,\n change,\n changeFormat = CHANGE_FORMAT,\n changeLabel,\n invertChange = false,\n description,\n footer,\n children,\n loading = false,\n propsLabel,\n propsValue,\n propsIcon,\n propsNumber,\n propsUnit,\n propsChange,\n propsChangeLabel,\n propsDescription,\n propsBody,\n propsFooter,\n ...rest\n }: StatProps) => {\n const grouped = StatGroupContext.inject(false);\n // 骨架防闪烁;aria-busy 按真实的 loading\n const skeleton = useDelayedLoading(() => loading);\n // 出现过骨架之后,换回数值时淡入(样式在切换的那一刻加上,动画才会播)\n let revealing = false;\n return () => {\n if (skeleton.value) revealing = true;\n const reveal = revealing && !skeleton.value && shimmerStyles.reveal;\n const direction = change === undefined || change === 0 ? 'flat' : change > 0 ? 'up' : 'down';\n const improved = invertChange ? direction === 'down' : direction === 'up';\n const changeTone = direction === 'flat' ? 'muted' : improved ? 'success' : 'danger';\n return (\n <dl\n {...mergeAttrs<'dl'>({ sx: [statStyles.root, grouped && statGroupStyles.item] }, rest, {\n 'aria-busy': loading || undefined,\n })}\n >\n <dt {...mergeAttrs<'dt'>({ sx: statStyles.label }, propsLabel)}>\n {icon && (\n <span\n {...mergeAttrs<'span'>({ sx: statStyles.icon }, propsIcon, { 'aria-hidden': true })}\n >\n <Icon icon={icon} />\n </span>\n )}\n <span>{label}</span>\n </dt>\n <dd {...mergeAttrs<'dd'>({ sx: [statStyles.value, reveal] }, propsValue)}>\n {skeleton.value ? (\n <Skeleton sx={statStyles.numberSkeleton} />\n ) : typeof value !== 'string' ? (\n <AnimatedNumber\n {...mergePartProps<AnimatedNumberProps>(\n { sx: [statStyles.number, tone && toneStyles[tone]], value },\n propsNumber,\n {\n value,\n format,\n },\n )}\n />\n ) : (\n <span\n {...mergeAttrs<'span'>(\n { sx: [statStyles.number, tone && toneStyles[tone]] },\n propsNumber,\n )}\n >\n {value}\n </span>\n )}\n {unit != null && !skeleton.value && (\n <span {...mergeAttrs<'span'>({ sx: statStyles.unit }, propsUnit)}>{unit}</span>\n )}\n </dd>\n {change !== undefined && (\n <dd\n {...mergeAttrs<'dd'>({ sx: [statStyles.change, reveal] }, propsChange)}\n data-trend={skeleton.value ? undefined : direction}\n >\n {skeleton.value ? (\n <Skeleton sx={statStyles.changeSkeleton} />\n ) : (\n <>\n <span {...css.attrs(toneStyles[changeTone])}>\n {direction !== 'flat' && (\n <Icon\n icon={direction === 'up' ? TrendingUp : TrendingDown}\n aria-hidden=\"true\"\n />\n )}{' '}\n <AnimatedNumber value={change} format={changeFormat} />\n </span>\n {changeLabel != null && (\n <span {...mergeAttrs<'span'>({ sx: statStyles.changeLabel }, propsChangeLabel)}>\n {changeLabel}\n </span>\n )}\n </>\n )}\n </dd>\n )}\n {hasContent(description) && (\n <dd {...mergeAttrs<'dd'>({ sx: statStyles.description }, propsDescription)}>\n {description}\n </dd>\n )}\n {hasContent(children) && (\n <dd {...mergeAttrs<'dd'>({ sx: statStyles.body }, propsBody)}>{children}</dd>\n )}\n {hasContent(footer) && (\n <dd {...mergeAttrs<'dd'>({ sx: statStyles.footer }, propsFooter)}>{footer}</dd>\n )}\n </dl>\n );\n };\n },\n);\n\n/** 未声明的属性落到外层 div 上 */\nexport interface StatGroupProps extends PartProps<'div'> {\n /**\n * 每个指标最窄多宽(CSS 长度):放不下就换行\n * @default '9rem'\n */\n minItemWidth?: string;\n /** Stat */\n children?: VNodeChild;\n}\n\n/** StatGroup 的样式:root、item */\nexport const statGroupStyles = css.create({\n // 每个指标的起始边一条竖线;整组往起始方向挪一条线的位置,每行第一个的竖线藏到外面(overflow 裁掉)\n root: { display: 'grid', rowGap: '_md', overflow: 'hidden' },\n item: {\n paddingInline: '_md',\n marginInlineStart: `calc(-1 * ${t.borderWidths.xs})`,\n borderInlineStartWidth: '_xs',\n borderInlineStartStyle: 'solid',\n borderInlineStartColor: '_borderMuted',\n },\n});\n\n/** StatGroup 的动态样式:列宽 */\nexport const statGroupDynamicStyles = css.create({\n columns: (min: string) => ({\n gridTemplateColumns: `repeat(auto-fit, minmax(min(${min}, 100%), 1fr))`,\n }),\n});\n\n/** 一排指标:按宽度换行,同一行里指标之间一条竖线 */\nexport const StatGroup = _component(\n ({ minItemWidth = '9rem', children, ...rest }: StatGroupProps) => {\n StatGroupContext.provide(true);\n return () => (\n <div\n {...mergeAttrs<'div'>(\n { sx: [statGroupStyles.root, statGroupDynamicStyles.columns(minItemWidth)] },\n rest,\n )}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":"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"}
|
package/dist/display/Timeline.js
CHANGED
|
@@ -9,7 +9,7 @@ import { Avatar, initials } from "./Avatar.js";
|
|
|
9
9
|
import { Collapsible } from "./Collapsible.js";
|
|
10
10
|
import { createVNode } from "vue";
|
|
11
11
|
import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
12
|
-
import
|
|
12
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
13
13
|
import { ChevronDown, ChevronUp } from "@lucide/icons";
|
|
14
14
|
//#region src/display/Timeline.tsx
|
|
15
15
|
/** 时间线上的一项 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timeline.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/display/Timeline.tsx"],"sourcesContent":["/**\n * 时间线(ol):按时间排列的事件(订单进度、操作记录、版本历史)。每项一个节点(圆点或图标,带色调)+ 标题、时间、说明,\n * 节点之间连一条线;可以左右交替排布;还在进行中时最后一项显示加载指示(pending)。参考 Ant Design Timeline。\n *\n * <Timeline\n * items={[\n * { title: '已下单', time: '10-18 09:12' },\n * { title: '已发货', time: '10-18 15:40', tone: 'success', icon: Truck },\n * ]}\n * pending=\"正在派送\"\n * />\n *\n * items 按时间先后给;reverse 时新的在前(操作记录、流转记录常这样看),进行中的一项也在最前。\n * 流程的流转记录每条事件一项:actor 是处理人,处理结果按种类换 icon 与 tone。\n *\n * 操作记录:项写 actor(操作人,可以带 avatar 头像)显示在时间前面;description 里可以放 FieldCompare 列出改了哪些字段;\n * 长的内容(完整的字段对比、附件、原文)放 details,项里一个“查看详情”的按钮点开才显示。\n * 记录多时写 maxVisible:只显示最新的几项,其余收起在“展开其余 N 条”后面(按钮在旧的那一端,展开后变成“收起”)。\n *\n * 语义是有序列表;时间用 <time>(给了 dateTime 时写上机器可读的时间)。\n * 部件:Root(ol)、Item(li)、Rail(节点与连接线所在的列)、Marker、Line(连接线)、Content、Title、Meta(操作人与时间)、\n * Time、Description、Details(Collapsible)、Toggle(展开其余各项的按钮)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { SxStyles } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { ChevronDown, ChevronUp } from '@lucide/icons';\nimport type { VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { Icon, type IconData } from '../base/Icon';\nimport { Spinner } from '../base/Spinner';\nimport { useLang } from '../config/context';\nimport { Avatar, initials } from './Avatar';\nimport { Collapsible, type CollapsibleProps } from './Collapsible';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport { FlexOrderedList, type FlexProps } from '../layout/Flex';\n\n/** 时间线上的一项 */\nexport interface TimelineItem {\n /** 唯一的 key;不写时用位置 */\n key?: string;\n /** 标题 */\n title: VNodeChild;\n /** 时间(显示的文字) */\n time?: VNodeChild;\n /** 机器可读的时间(ISO 8601),写到 <time datetime> 上 */\n dateTime?: string;\n /** 说明:一段文字,或字段差异(FieldCompare layout=\"list\")这类内容 */\n description?: VNodeChild;\n /** 操作人:显示在时间前面 */\n actor?: VNodeChild;\n /** 操作人的头像地址;actor 是文字时没有图片也显示首字母 */\n avatar?: string;\n /** 收起的详情:项里一个“查看详情”的按钮,点开才显示 */\n details?: VNodeChild;\n /** 节点的图标;不写时是圆点 */\n icon?: IconData;\n /** 节点的色调,默认 neutral */\n tone?: StatusTone;\n}\n\n/** 未声明的属性落到 ol 上 */\nexport interface TimelineProps extends PartProps<'ol'> {\n /** 各项,按时间先后(旧的在前) */\n items: readonly TimelineItem[];\n /** 还在进行中:最后多一项,节点是加载指示,内容是它 */\n pending?: VNodeChild;\n /** 新的在前:倒过来显示(进行中的一项也在最前),ol 带 reversed */\n reverse?: boolean;\n /** 左右交替排布(时间在对侧);窄的容器里仍是单侧 */\n alternate?: boolean;\n /** 字号档位;不写时继承 */\n size?: TextSize;\n /** 最多显示几项(不算进行中的一项):只显示最新的这几项,其余收起在“展开其余 N 条”后面 */\n maxVisible?: number;\n /** 收起的各项展开了没有(可绑定) */\n _expanded?: boolean;\n /** 每一项(li)的部件属性,可以按项计算 */\n propsItem?: PartProps<'li'> | ((item: TimelineItem, index: number) => PartProps<'li'>);\n /** 节点与连接线所在的列的部件属性 */\n propsRail?: PartProps<'div'>;\n /** 节点的部件属性 */\n propsMarker?: PartProps<'span'>;\n /** 连接线的部件属性 */\n propsLine?: PartProps<'span'>;\n /** 内容(标题、时间、说明)的部件属性 */\n propsContent?: PartProps<'div'>;\n /** 标题的部件属性 */\n propsTitle?: PartProps<'div'>;\n /** 操作人与时间那一行的部件属性 */\n propsMeta?: PartProps<'div'>;\n /** 时间的部件属性 */\n propsTime?: PartProps<'time', 'datetime'>;\n /** 说明的部件属性 */\n propsDescription?: PartProps<'div'>;\n /** 详情(Collapsible)的部件属性 */\n propsDetails?: Partial<CollapsibleProps>;\n /** 展开其余各项的按钮的部件属性 */\n propsToggle?: Partial<ButtonProps>;\n}\n\n/** Timeline 的样式:root、item、marker、line、content、title、time、description 等 */\nexport const timelineStyles = css.create({\n // 竖排、去掉编号由 FlexOrderedList 给;交替排布按容器宽度切换\n root: { containerType: 'inline-size' },\n // 节点一列、内容一列;交替时三列:左内容、节点、右内容。\n // 每项是独立的 grid,节点列至少有图标节点那么宽,圆点、图标、加载指示混排时各项才对得齐\n item: { display: 'grid', gridTemplateColumns: 'minmax(1.5em, auto) 1fr', columnGap: '_md' },\n itemAlternate: {\n gridTemplateColumns: {\n default: '1fr minmax(1.5em, auto) 1fr',\n '@container (max-width: 32em)': 'minmax(1.5em, auto) 1fr',\n },\n },\n rail: { display: 'flex', flexDirection: 'column', alignItems: 'center' },\n marker: {\n boxSizing: 'border-box',\n flexShrink: 0,\n width: '0.75em',\n height: '0.75em',\n marginBlock: '0.375em',\n borderRadius: '_full',\n backgroundColor: 'currentColor',\n },\n // 有图标时节点大一些,图标描边用色调\n markerIcon: {\n display: 'grid',\n placeItems: 'center',\n width: '1.5em',\n height: '1.5em',\n marginBlock: 0,\n backgroundColor: '_surface',\n borderWidth: '_sm',\n borderStyle: 'solid',\n borderColor: 'currentColor',\n },\n pending: { marginBlock: '0.25em' },\n // 连到下一项的线;最后一项没有\n line: {\n flexGrow: 1,\n width: '_borderWidths.sm',\n minHeight: '1em',\n backgroundColor: '_borderMuted',\n },\n content: { minWidth: 0, paddingBlockEnd: '_lg', display: 'grid', gap: '_xs' },\n // 交替排布时偶数项的内容在节点左侧、靠右对齐\n contentEnd: {\n gridColumn: { default: '1', '@container (max-width: 32em)': '2' },\n gridRow: '1',\n textAlign: { default: 'end', '@container (max-width: 32em)': 'start' },\n },\n title: { fontWeight: '_semibold', color: '_text' },\n // 操作人与时间:一行,放不下时换行\n meta: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: '_sm',\n rowGap: '_xs',\n fontSize: '_sm',\n color: '_textMuted',\n },\n actor: { display: 'inline-flex', alignItems: 'center', gap: '_xs', color: '_text' },\n avatar: { width: '1.75em', height: '1.75em' },\n time: { fontSize: '_sm', color: '_textMuted' },\n // 交替排布时时间放在对侧(它自己占一格);窄的容器里不占格,改在内容里显示\n timeOpposite: {\n paddingBlockStart: '0.125em',\n display: { default: 'block', '@container (max-width: 32em)': 'none' },\n },\n timeInline: { display: { default: 'none', '@container (max-width: 32em)': 'block' } },\n description: { color: '_text' },\n // 详情按钮像链接,靠起始边;展开的内容与上面隔开一点\n detailsToggle: { justifySelf: 'start' },\n detailsContent: { paddingBlockStart: '_xs' },\n // 收起的那几项的位置:节点列是一段虚线,内容是按钮\n toggleLine: {\n flexGrow: 1,\n minHeight: '2em',\n borderInlineStartWidth: '_sm',\n borderInlineStartStyle: 'dashed',\n borderInlineStartColor: '_borderMuted',\n },\n toggleContent: { paddingBlockEnd: '_lg' },\n});\n\n/** Timeline 的样式:节点的色调 */\nexport const timelineToneStyles = css.create({\n neutral: { color: '_borderStrong' },\n accent: { color: '_accent' },\n info: { color: '_infoText' },\n success: { color: '_successText' },\n warning: { color: '_warningText' },\n danger: { color: '_dangerText' },\n});\n\n/** 时间线:节点 + 内容,节点之间连线 */\nexport const Timeline = _component(\n ({\n items,\n pending,\n alternate = false,\n size,\n reverse = false,\n maxVisible,\n _expanded: expanded = _bindable(false),\n propsItem,\n propsRail,\n propsMarker,\n propsLine,\n propsContent,\n propsTitle,\n propsMeta,\n propsTime,\n propsDescription,\n propsDetails,\n propsToggle,\n ...rest\n }: TimelineProps) => {\n const lang = useLang();\n\n /** 收起的那几项所在的位置:节点列一段虚线,内容是展开、收起的按钮 */\n const toggle = (hidden: number) => (\n <li key=\"toggle\" {...css.attrs(timelineStyles.item)}>\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.rail }, propsRail)}>\n <span {...css.attrs(timelineStyles.toggleLine)} aria-hidden=\"true\" />\n </div>\n <div {...css.attrs(timelineStyles.toggleContent)}>\n <Button\n {...mergePartProps<ButtonProps>(\n {\n variant: 'link',\n size: 'sm',\n iconEnd: expanded ? ChevronUp : ChevronDown,\n },\n propsToggle,\n { 'aria-expanded': expanded, onClick: () => (expanded = !expanded) },\n )}\n >\n {expanded ? lang.timelineShowLess : lang.timelineShowMore(hidden)}\n </Button>\n </div>\n </li>\n );\n\n return () => {\n const hidden =\n maxVisible !== undefined && items.length > maxVisible ? items.length - maxVisible : 0;\n const chronological: (TimelineItem & { pending?: true })[] = [\n ...(hidden > 0 && !expanded ? items.slice(hidden) : items),\n ...(hasContent(pending)\n ? [{ key: 'pending', title: pending, pending: true as const }]\n : []),\n ];\n const all = reverse ? chronological.toReversed() : chronological;\n // 按钮在旧的那一端:倒序时在最后,最后一项仍连线到它\n const toggleAtEnd = hidden > 0 && reverse;\n return (\n <FlexOrderedList\n {...mergePartProps<FlexProps<'ol'>>(\n { direction: 'column', sx: [timelineStyles.root, size && fontSizeStyles[size]] },\n rest,\n )}\n data-alternate={alternate || undefined}\n reversed={reverse || undefined}\n >\n {hidden > 0 && !reverse && toggle(hidden)}\n {all.map((item, index) => {\n const own = typeof propsItem === 'function' ? propsItem(item, index) : propsItem;\n const last = index === all.length - 1 && !toggleAtEnd;\n const end = alternate && index % 2 === 1;\n // 交替排布时时间放在对侧,占一格(没有时间也占,保持三列对齐);窄的容器里改在内容里显示\n const time = (sx: SxStyles) =>\n hasContent(item.time) ? (\n <time\n {...mergeAttrs<'time'>({ sx: [timelineStyles.time, sx] }, propsTime, {\n datetime: item.dateTime,\n })}\n >\n {item.time}\n </time>\n ) : (\n alternate && <span {...css.attrs(sx)} />\n );\n // 内容里的时间:交替排布时只在窄的容器里显示(宽时在对侧)\n const inlineTime = alternate\n ? hasContent(item.time) && time(timelineStyles.timeInline)\n : time(null);\n const marker = item.pending ? (\n <Spinner sx={[timelineStyles.pending, timelineToneStyles.accent]} />\n ) : (\n <span\n {...mergeAttrs<'span'>(\n {\n sx: [\n timelineStyles.marker,\n item.icon && timelineStyles.markerIcon,\n timelineToneStyles[item.tone ?? 'neutral'],\n ],\n },\n propsMarker,\n { 'aria-hidden': true },\n )}\n >\n {item.icon && <Icon icon={item.icon} />}\n </span>\n );\n return (\n <li\n key={item.key ?? index}\n {...mergeAttrs<'li'>(\n { sx: [timelineStyles.item, alternate && timelineStyles.itemAlternate] },\n own,\n )}\n data-state={item.pending ? 'pending' : undefined}\n aria-busy={item.pending || undefined}\n >\n {/* 交替排布:奇数项左侧放时间,偶数项右侧放时间 */}\n {alternate && !end && time(timelineStyles.timeOpposite)}\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.rail }, propsRail)}>\n {marker}\n {!last && (\n <span\n {...mergeAttrs<'span'>({ sx: timelineStyles.line }, propsLine, {\n 'aria-hidden': true,\n })}\n />\n )}\n </div>\n <div\n {...mergeAttrs<'div'>(\n { sx: [timelineStyles.content, end && timelineStyles.contentEnd] },\n propsContent,\n )}\n >\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.title }, propsTitle)}>\n {item.title}\n </div>\n {hasContent(item.actor) ? (\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.meta }, propsMeta)}>\n <span {...css.attrs(timelineStyles.actor)}>\n {(item.avatar || typeof item.actor === 'string') && (\n <Avatar\n src={item.avatar}\n fallback={\n typeof item.actor === 'string' ? initials(item.actor) : undefined\n }\n sx={timelineStyles.avatar}\n />\n )}\n {item.actor}\n </span>\n {inlineTime}\n </div>\n ) : (\n inlineTime\n )}\n {hasContent(item.description) && (\n <div\n {...mergeAttrs<'div'>({ sx: timelineStyles.description }, propsDescription)}\n >\n {item.description}\n </div>\n )}\n {hasContent(item.details) && (\n <Collapsible\n {...mergePartProps<Partial<CollapsibleProps>>(\n { lazy: true, propsContent: { sx: timelineStyles.detailsContent } },\n propsDetails,\n )}\n trigger={(props) => (\n <Button\n variant=\"link\"\n size=\"sm\"\n iconEnd={props['aria-expanded'] ? ChevronUp : ChevronDown}\n sx={timelineStyles.detailsToggle}\n {...props}\n >\n {lang.timelineDetails}\n </Button>\n )}\n >\n {item.details}\n </Collapsible>\n )}\n </div>\n {end && time(timelineStyles.timeOpposite)}\n </li>\n );\n })}\n {toggleAtEnd && toggle(hidden)}\n </FlexOrderedList>\n );\n };\n },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Timeline.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/display/Timeline.tsx"],"sourcesContent":["/**\n * 时间线(ol):按时间排列的事件(订单进度、操作记录、版本历史)。每项一个节点(圆点或图标,带色调)+ 标题、时间、说明,\n * 节点之间连一条线;可以左右交替排布;还在进行中时最后一项显示加载指示(pending)。参考 Ant Design Timeline。\n *\n * <Timeline\n * items={[\n * { title: '已下单', time: '10-18 09:12' },\n * { title: '已发货', time: '10-18 15:40', tone: 'success', icon: Truck },\n * ]}\n * pending=\"正在派送\"\n * />\n *\n * items 按时间先后给;reverse 时新的在前(操作记录、流转记录常这样看),进行中的一项也在最前。\n * 流程的流转记录每条事件一项:actor 是处理人,处理结果按种类换 icon 与 tone。\n *\n * 操作记录:项写 actor(操作人,可以带 avatar 头像)显示在时间前面;description 里可以放 FieldCompare 列出改了哪些字段;\n * 长的内容(完整的字段对比、附件、原文)放 details,项里一个“查看详情”的按钮点开才显示。\n * 记录多时写 maxVisible:只显示最新的几项,其余收起在“展开其余 N 条”后面(按钮在旧的那一端,展开后变成“收起”)。\n *\n * 语义是有序列表;时间用 <time>(给了 dateTime 时写上机器可读的时间)。\n * 部件:Root(ol)、Item(li)、Rail(节点与连接线所在的列)、Marker、Line(连接线)、Content、Title、Meta(操作人与时间)、\n * Time、Description、Details(Collapsible)、Toggle(展开其余各项的按钮)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { SxStyles } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { ChevronDown, ChevronUp } from '@lucide/icons';\nimport type { VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { Icon, type IconData } from '../base/Icon';\nimport { Spinner } from '../base/Spinner';\nimport { useLang } from '../config/context';\nimport { Avatar, initials } from './Avatar';\nimport { Collapsible, type CollapsibleProps } from './Collapsible';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport { FlexOrderedList, type FlexProps } from '../layout/Flex';\n\n/** 时间线上的一项 */\nexport interface TimelineItem {\n /** 唯一的 key;不写时用位置 */\n key?: string;\n /** 标题 */\n title: VNodeChild;\n /** 时间(显示的文字) */\n time?: VNodeChild;\n /** 机器可读的时间(ISO 8601),写到 <time datetime> 上 */\n dateTime?: string;\n /** 说明:一段文字,或字段差异(FieldCompare layout=\"list\")这类内容 */\n description?: VNodeChild;\n /** 操作人:显示在时间前面 */\n actor?: VNodeChild;\n /** 操作人的头像地址;actor 是文字时没有图片也显示首字母 */\n avatar?: string;\n /** 收起的详情:项里一个“查看详情”的按钮,点开才显示 */\n details?: VNodeChild;\n /** 节点的图标;不写时是圆点 */\n icon?: IconData;\n /** 节点的色调,默认 neutral */\n tone?: StatusTone;\n}\n\n/** 未声明的属性落到 ol 上 */\nexport interface TimelineProps extends PartProps<'ol'> {\n /** 各项,按时间先后(旧的在前) */\n items: readonly TimelineItem[];\n /** 还在进行中:最后多一项,节点是加载指示,内容是它 */\n pending?: VNodeChild;\n /** 新的在前:倒过来显示(进行中的一项也在最前),ol 带 reversed */\n reverse?: boolean;\n /** 左右交替排布(时间在对侧);窄的容器里仍是单侧 */\n alternate?: boolean;\n /** 字号档位;不写时继承 */\n size?: TextSize;\n /** 最多显示几项(不算进行中的一项):只显示最新的这几项,其余收起在“展开其余 N 条”后面 */\n maxVisible?: number;\n /** 收起的各项展开了没有(可绑定) */\n _expanded?: boolean;\n /** 每一项(li)的部件属性,可以按项计算 */\n propsItem?: PartProps<'li'> | ((item: TimelineItem, index: number) => PartProps<'li'>);\n /** 节点与连接线所在的列的部件属性 */\n propsRail?: PartProps<'div'>;\n /** 节点的部件属性 */\n propsMarker?: PartProps<'span'>;\n /** 连接线的部件属性 */\n propsLine?: PartProps<'span'>;\n /** 内容(标题、时间、说明)的部件属性 */\n propsContent?: PartProps<'div'>;\n /** 标题的部件属性 */\n propsTitle?: PartProps<'div'>;\n /** 操作人与时间那一行的部件属性 */\n propsMeta?: PartProps<'div'>;\n /** 时间的部件属性 */\n propsTime?: PartProps<'time', 'datetime'>;\n /** 说明的部件属性 */\n propsDescription?: PartProps<'div'>;\n /** 详情(Collapsible)的部件属性 */\n propsDetails?: Partial<CollapsibleProps>;\n /** 展开其余各项的按钮的部件属性 */\n propsToggle?: Partial<ButtonProps>;\n}\n\n/** Timeline 的样式:root、item、marker、line、content、title、time、description 等 */\nexport const timelineStyles = css.create({\n // 竖排、去掉编号由 FlexOrderedList 给;交替排布按容器宽度切换\n root: { containerType: 'inline-size' },\n // 节点一列、内容一列;交替时三列:左内容、节点、右内容。\n // 每项是独立的 grid,节点列至少有图标节点那么宽,圆点、图标、加载指示混排时各项才对得齐\n item: { display: 'grid', gridTemplateColumns: 'minmax(1.5em, auto) 1fr', columnGap: '_md' },\n itemAlternate: {\n gridTemplateColumns: {\n default: '1fr minmax(1.5em, auto) 1fr',\n '@container (max-width: 32em)': 'minmax(1.5em, auto) 1fr',\n },\n },\n rail: { display: 'flex', flexDirection: 'column', alignItems: 'center' },\n marker: {\n boxSizing: 'border-box',\n flexShrink: 0,\n width: '0.75em',\n height: '0.75em',\n marginBlock: '0.375em',\n borderRadius: '_full',\n backgroundColor: 'currentColor',\n },\n // 有图标时节点大一些,图标描边用色调\n markerIcon: {\n display: 'grid',\n placeItems: 'center',\n width: '1.5em',\n height: '1.5em',\n marginBlock: 0,\n backgroundColor: '_surface',\n borderWidth: '_sm',\n borderStyle: 'solid',\n borderColor: 'currentColor',\n },\n pending: { marginBlock: '0.25em' },\n // 连到下一项的线;最后一项没有\n line: {\n flexGrow: 1,\n width: '_borderWidths.sm',\n minHeight: '1em',\n backgroundColor: '_borderMuted',\n },\n content: { minWidth: 0, paddingBlockEnd: '_lg', display: 'grid', gap: '_xs' },\n // 交替排布时偶数项的内容在节点左侧、靠右对齐\n contentEnd: {\n gridColumn: { default: '1', '@container (max-width: 32em)': '2' },\n gridRow: '1',\n textAlign: { default: 'end', '@container (max-width: 32em)': 'start' },\n },\n title: { fontWeight: '_semibold', color: '_text' },\n // 操作人与时间:一行,放不下时换行\n meta: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: '_sm',\n rowGap: '_xs',\n fontSize: '_sm',\n color: '_textMuted',\n },\n actor: { display: 'inline-flex', alignItems: 'center', gap: '_xs', color: '_text' },\n avatar: { width: '1.75em', height: '1.75em' },\n time: { fontSize: '_sm', color: '_textMuted' },\n // 交替排布时时间放在对侧(它自己占一格);窄的容器里不占格,改在内容里显示\n timeOpposite: {\n paddingBlockStart: '0.125em',\n display: { default: 'block', '@container (max-width: 32em)': 'none' },\n },\n timeInline: { display: { default: 'none', '@container (max-width: 32em)': 'block' } },\n description: { color: '_text' },\n // 详情按钮像链接,靠起始边;展开的内容与上面隔开一点\n detailsToggle: { justifySelf: 'start' },\n detailsContent: { paddingBlockStart: '_xs' },\n // 收起的那几项的位置:节点列是一段虚线,内容是按钮\n toggleLine: {\n flexGrow: 1,\n minHeight: '2em',\n borderInlineStartWidth: '_sm',\n borderInlineStartStyle: 'dashed',\n borderInlineStartColor: '_borderMuted',\n },\n toggleContent: { paddingBlockEnd: '_lg' },\n});\n\n/** Timeline 的样式:节点的色调 */\nexport const timelineToneStyles = css.create({\n neutral: { color: '_borderStrong' },\n accent: { color: '_accent' },\n info: { color: '_infoText' },\n success: { color: '_successText' },\n warning: { color: '_warningText' },\n danger: { color: '_dangerText' },\n});\n\n/** 时间线:节点 + 内容,节点之间连线 */\nexport const Timeline = _component(\n ({\n items,\n pending,\n alternate = false,\n size,\n reverse = false,\n maxVisible,\n _expanded: expanded = _bindable(false),\n propsItem,\n propsRail,\n propsMarker,\n propsLine,\n propsContent,\n propsTitle,\n propsMeta,\n propsTime,\n propsDescription,\n propsDetails,\n propsToggle,\n ...rest\n }: TimelineProps) => {\n const lang = useLang();\n\n /** 收起的那几项所在的位置:节点列一段虚线,内容是展开、收起的按钮 */\n const toggle = (hidden: number) => (\n <li key=\"toggle\" {...css.attrs(timelineStyles.item)}>\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.rail }, propsRail)}>\n <span {...css.attrs(timelineStyles.toggleLine)} aria-hidden=\"true\" />\n </div>\n <div {...css.attrs(timelineStyles.toggleContent)}>\n <Button\n {...mergePartProps<ButtonProps>(\n {\n variant: 'link',\n size: 'sm',\n iconEnd: expanded ? ChevronUp : ChevronDown,\n },\n propsToggle,\n { 'aria-expanded': expanded, onClick: () => (expanded = !expanded) },\n )}\n >\n {expanded ? lang.timelineShowLess : lang.timelineShowMore(hidden)}\n </Button>\n </div>\n </li>\n );\n\n return () => {\n const hidden =\n maxVisible !== undefined && items.length > maxVisible ? items.length - maxVisible : 0;\n const chronological: (TimelineItem & { pending?: true })[] = [\n ...(hidden > 0 && !expanded ? items.slice(hidden) : items),\n ...(hasContent(pending)\n ? [{ key: 'pending', title: pending, pending: true as const }]\n : []),\n ];\n const all = reverse ? chronological.toReversed() : chronological;\n // 按钮在旧的那一端:倒序时在最后,最后一项仍连线到它\n const toggleAtEnd = hidden > 0 && reverse;\n return (\n <FlexOrderedList\n {...mergePartProps<FlexProps<'ol'>>(\n { direction: 'column', sx: [timelineStyles.root, size && fontSizeStyles[size]] },\n rest,\n )}\n data-alternate={alternate || undefined}\n reversed={reverse || undefined}\n >\n {hidden > 0 && !reverse && toggle(hidden)}\n {all.map((item, index) => {\n const own = typeof propsItem === 'function' ? propsItem(item, index) : propsItem;\n const last = index === all.length - 1 && !toggleAtEnd;\n const end = alternate && index % 2 === 1;\n // 交替排布时时间放在对侧,占一格(没有时间也占,保持三列对齐);窄的容器里改在内容里显示\n const time = (sx: SxStyles) =>\n hasContent(item.time) ? (\n <time\n {...mergeAttrs<'time'>({ sx: [timelineStyles.time, sx] }, propsTime, {\n datetime: item.dateTime,\n })}\n >\n {item.time}\n </time>\n ) : (\n alternate && <span {...css.attrs(sx)} />\n );\n // 内容里的时间:交替排布时只在窄的容器里显示(宽时在对侧)\n const inlineTime = alternate\n ? hasContent(item.time) && time(timelineStyles.timeInline)\n : time(null);\n const marker = item.pending ? (\n <Spinner sx={[timelineStyles.pending, timelineToneStyles.accent]} />\n ) : (\n <span\n {...mergeAttrs<'span'>(\n {\n sx: [\n timelineStyles.marker,\n item.icon && timelineStyles.markerIcon,\n timelineToneStyles[item.tone ?? 'neutral'],\n ],\n },\n propsMarker,\n { 'aria-hidden': true },\n )}\n >\n {item.icon && <Icon icon={item.icon} />}\n </span>\n );\n return (\n <li\n key={item.key ?? index}\n {...mergeAttrs<'li'>(\n { sx: [timelineStyles.item, alternate && timelineStyles.itemAlternate] },\n own,\n )}\n data-state={item.pending ? 'pending' : undefined}\n aria-busy={item.pending || undefined}\n >\n {/* 交替排布:奇数项左侧放时间,偶数项右侧放时间 */}\n {alternate && !end && time(timelineStyles.timeOpposite)}\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.rail }, propsRail)}>\n {marker}\n {!last && (\n <span\n {...mergeAttrs<'span'>({ sx: timelineStyles.line }, propsLine, {\n 'aria-hidden': true,\n })}\n />\n )}\n </div>\n <div\n {...mergeAttrs<'div'>(\n { sx: [timelineStyles.content, end && timelineStyles.contentEnd] },\n propsContent,\n )}\n >\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.title }, propsTitle)}>\n {item.title}\n </div>\n {hasContent(item.actor) ? (\n <div {...mergeAttrs<'div'>({ sx: timelineStyles.meta }, propsMeta)}>\n <span {...css.attrs(timelineStyles.actor)}>\n {(item.avatar || typeof item.actor === 'string') && (\n <Avatar\n src={item.avatar}\n fallback={\n typeof item.actor === 'string' ? initials(item.actor) : undefined\n }\n sx={timelineStyles.avatar}\n />\n )}\n {item.actor}\n </span>\n {inlineTime}\n </div>\n ) : (\n inlineTime\n )}\n {hasContent(item.description) && (\n <div\n {...mergeAttrs<'div'>({ sx: timelineStyles.description }, propsDescription)}\n >\n {item.description}\n </div>\n )}\n {hasContent(item.details) && (\n <Collapsible\n {...mergePartProps<Partial<CollapsibleProps>>(\n { lazy: true, propsContent: { sx: timelineStyles.detailsContent } },\n propsDetails,\n )}\n trigger={(props) => (\n <Button\n variant=\"link\"\n size=\"sm\"\n iconEnd={props['aria-expanded'] ? ChevronUp : ChevronDown}\n sx={timelineStyles.detailsToggle}\n {...props}\n >\n {lang.timelineDetails}\n </Button>\n )}\n >\n {item.details}\n </Collapsible>\n )}\n </div>\n {end && time(timelineStyles.timeOpposite)}\n </li>\n );\n })}\n {toggleAtEnd && toggle(hidden)}\n </FlexOrderedList>\n );\n };\n },\n);\n"],"mappings":"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"}
|
package/dist/display/Tree.d.ts
CHANGED
package/dist/display/Tree.js
CHANGED
|
@@ -25,7 +25,7 @@ import { defaultRangeExtractor } from "../utils/virtual/virtualizer.js";
|
|
|
25
25
|
import { useVirtualizer } from "../utils/virtual/use-virtualizer.js";
|
|
26
26
|
import { computed, createVNode, onScopeDispose, ref, shallowRef, useId, watch } from "vue";
|
|
27
27
|
import { _component, bindable, mergeJsxProps, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
28
|
-
import
|
|
28
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
29
29
|
import { Check, ChevronRight, Minus } from "@lucide/icons";
|
|
30
30
|
//#region src/display/Tree.tsx
|
|
31
31
|
/**
|
package/dist/display/Tree.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tree.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_shallowRef","_vue_ref","_vue_computed","_vtp_untrack","_createVNode","_mergeProps"],"sources":["../../src/display/Tree.tsx"],"sourcesContent":["/**\n * 树(WAI-ARIA Tree):可展开的层级列表(文件夹、组织架构、分类),可单选 / 多选、勾选(父子联动、半选)、懒加载子节点。\n * 数据驱动,始终虚拟滚动(上万个节点也只渲染看得见的几十个):\n *\n * <Tree\n * items={folders}\n * getKey={(node) => node.id}\n * getLabel={(node) => node.name}\n * getChildren={(node) => node.children}\n * _expanded={open}\n * selectionMode=\"single\"\n * _selected={current}\n * aria-label=\"目录\"\n * />\n *\n * - 键盘:焦点在树上,当前项经 aria-activedescendant 告诉读屏。↑↓ 移动,→ 展开 / 进入第一个子节点,← 收起 / 回到父节点,\n * Home / End,Enter 选中(没有选择时展开或收起),空格勾选(checkable 时)或选中,按字母跳到以它开头的节点。\n * - 勾选:checkable 时每项前有勾选框,_checked={keys} 是勾上的全部节点;勾上父节点会勾上它的子孙,\n * 子节点全勾上时父节点也勾上,只勾了一部分时父节点半选(aria-checked=\"mixed\")。\n * - 懒加载:hasChildren 说有子节点、getChildren 还没有时,展开会调用 loadChildren(加载中显示加载指示)。\n * - 节点平铺渲染(虚拟滚动没法嵌套 role=\"group\"),层级经 aria-level / aria-setsize / aria-posinset 告诉读屏。\n *\n * 展开状态与勾选联动见 utils/data/tree.ts(TreeDataTable 共用)。部件:Root(div,role=\"tree\")、\n * Row(虚拟滚动定位的一行,包着 Item)、Item(div,role=\"treeitem\")、Toggle(展开箭头)、\n * Checkbox(勾选框,只是外观,状态在 treeitem 的 aria-checked 上)、Label、ScrollArea(外层的滚动区域)。\n */\nimport { Check, ChevronRight, Minus } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { onScopeDispose, useId, watch, type VNodeChild } from 'vue';\nimport { Icon, type IconData } from '../base/Icon';\nimport { Spinner } from '../base/Spinner';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { t } from '../config/theme/tokens';\nimport { announce } from '../utils/dom/announcer';\nimport { startMove } from '../utils/dom/move';\nimport { Empty, type EmptyProps } from '../feedback/Empty';\nimport { Skeleton, type SkeletonProps, type SkeletonShapeProps } from '../feedback/Skeleton';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { SHIMMER_STAGGER } from '../utils/style/shimmer';\nimport { checkboxStyles } from '../input/Checkbox';\nimport { choiceInputStyles, choiceRecipe } from '../input/choice-styles';\nimport { useRecipe } from '../config/styles';\nimport { toneFillStyles } from '../utils/style/tone-styles';\nimport { inlineArrows, isRtl } from '../utils/dom/direction';\nimport { toggleSelection, type SelectionModes } from '../utils/data/selection';\nimport {\n checkStates,\n filterTree,\n flattenTree,\n indexTree,\n toggleChecked,\n useTreeExpansion,\n type CheckState,\n type TreeAccessors,\n type TreeMoveTarget,\n} from '../utils/data/tree';\nimport { createTypeahead } from '../utils/dom/typeahead';\nimport { mergeAttrs, mergePartProps, mergeProps, type PartProps } from '../utils/props';\nimport { ScrollArea, type ScrollAreaProps } from '../layout/ScrollArea';\nimport { itemStyles } from '../utils/style/item-styles';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { useVirtualizer } from '../utils/virtual/use-virtualizer';\nimport { defaultRangeExtractor } from '../utils/virtual/virtualizer';\nimport { disclosureStyles } from '../utils/style/transitions';\n\n/** 节点的渲染状态 */\nexport interface TreeItemRenderState {\n /** 层级,第一层为 0 */\n depth: number;\n /** 展开着 */\n expanded: boolean;\n /** 已选 */\n selected: boolean;\n /** 勾选状态(checkable 时) */\n checked: CheckState;\n /** 键盘所在的当前项 */\n active: boolean;\n}\n\n/** 一次移动:把 key 移到 target(交给 moveNode) */\nexport interface TreeMove<T> {\n /** 移动的节点的 key */\n key: string;\n /** 移动的节点 */\n node: T;\n /** 放到哪个节点下的第几位(按移走之后的同级算) */\n target: TreeMoveTarget;\n}\n\n/** 拖动时的落点:放在 key 这一项的前面、后面或里面 */\ninterface DropSpot {\n key: string;\n zone: 'before' | 'after' | 'inside';\n}\n\n/** 未声明的属性落到 div(role=\"tree\")上;aria-label 或 aria-labelledby 是树的名称 */\nexport interface TreeProps<T> extends PartProps<'div', 'role'> {\n /** 第一层的节点 */\n items: readonly T[];\n /** 节点的 key,整棵树里唯一 */\n getKey: (node: T) => string;\n /** 节点的文字:默认显示它,类型搜索也按它 */\n getLabel: (node: T) => string;\n /** 子节点;叶子或还没加载时返回 undefined / 空数组 */\n getChildren: (node: T) => readonly T[] | undefined;\n /** 有没有子节点(懒加载时子节点还没取回来也要能展开);不写时看 getChildren 是否非空 */\n hasChildren?: (node: T) => boolean;\n /** 展开一个还没有子节点的节点时调用:取回子节点并放进数据里;返回 Promise 时显示加载中 */\n loadChildren?: (node: T) => Promise<unknown> | void;\n /** 子节点加载失败(loadChildren 的 Promise 被拒绝):节点收回去,再展开会重试;不写时在控制台报错 */\n onLoadError?: (error: unknown, node: T) => void;\n /** 节点不可用:可以经过、展开,不能选中、勾选 */\n isDisabled?: (node: T) => boolean;\n /** 文字前的图标,可以按展开状态换(文件夹开 / 合) */\n getIcon?: (node: T, expanded: boolean) => IconData | undefined;\n /** 展开的节点:父级写 _expanded={keys} */\n _expanded?: string[];\n /** 选择方式;不写时不能选中 */\n selectionMode?: keyof SelectionModes;\n /** 选中的节点:父级写 _selected={keys} */\n _selected?: string[];\n /** 每项前显示勾选框,默认父子联动 */\n checkable?: boolean;\n /** 勾选父子不联动:每个节点各自勾选(权限树里“只给这一级”) */\n checkStrictly?: boolean;\n /** 勾上的节点(联动时含勾上的父节点与子孙):父级写 _checked={keys} */\n _checked?: string[];\n /** 正在取节点:还没有节点时显示骨架行,树带 aria-busy */\n loading?: boolean;\n /** 没有节点时显示的内容;默认是 Empty(文案取语言包) */\n empty?: VNodeChild;\n /** 每一层缩进多少(em),默认 1.25 */\n indent?: number;\n /** 每项的估计高度(px),默认 32;渲染后以实际高度为准 */\n estimateSize?: number;\n /**\n * 搜索过滤:字符串时按节点文字匹配(忽略大小写与重音,或 createUi 的 textMatcher),函数时自己判断。\n * 留下匹配的节点与它们的祖先并展开祖先,匹配的节点文字加粗;只看已加载的节点。清空后回到原来的展开状态\n */\n filter?: string | ((node: T) => boolean);\n /**\n * 拖动节点改变层级与顺序:放下(或 Alt + 方向键)时报告移动,用 moveNode 生成新数据交回 items;不写时不能拖。\n * 指针拖动只用鼠标、笔(触摸时照常滚动)\n */\n onMove?: (move: TreeMove<T>) => void;\n /** 能不能放到这里(如文件不能放进文件里);不写时都能放(放进自己和自己的子孙里除外) */\n canDrop?: (node: T, target: TreeMoveTarget) => boolean;\n /** 自定义文字部分的内容 */\n renderItem?: (node: T, state: TreeItemRenderState) => VNodeChild;\n /** 每一项的部件属性,可以按节点计算 */\n propsItem?:\n PartProps<'div', 'role' | 'id'> | ((node: T, state: TreeItemRenderState) => PartProps<'div'>);\n /** 每一行(虚拟滚动定位的容器,包着 treeitem)的部件属性 */\n propsRow?: PartProps<'div', 'role'>;\n /** 展开箭头的部件属性(只是外观,键盘与读屏走 treeitem) */\n propsToggle?: PartProps<'span', 'aria-hidden'>;\n /** 勾选框的部件属性(只是外观,状态在 treeitem 的 aria-checked 上) */\n propsCheckbox?: PartProps<'span', 'aria-hidden'>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n /** 默认空状态(Empty)的部件属性 */\n propsEmpty?: Partial<EmptyProps>;\n /** 加载中的骨架行的部件属性 */\n propsSkeleton?: SkeletonShapeProps;\n /** 外层滚动区域(ScrollArea)的部件属性:放进弹出层、弹性布局时给它 sx;树元素本身是它的视口 */\n propsScrollArea?: Partial<Omit<ScrollAreaProps, 'propsViewport'>>;\n}\n\n/** Tree 的样式:root、sizer、row、item、toggle、checkbox、label 等 */\nexport const treeStyles = css.create({\n // 树元素就是 ScrollArea 的视口(浮层滚动条);焦点与 aria-activedescendant 在它上面\n root: {\n position: 'relative',\n overscrollBehavior: 'contain',\n padding: '_xs',\n outlineStyle: 'none',\n },\n sizer: { position: 'relative', width: '_full' },\n skeleton: { display: 'block', height: '1em', marginBlock: '0.625em', marginInline: '_sm' },\n row: { position: 'absolute', top: 0, insetInline: 0, paddingBlock: '1px' },\n item: { gap: '_xs', minHeight: '_sizes.minTarget', paddingInlineStart: '_xs' },\n toggle: {\n display: 'grid',\n placeItems: 'center',\n flexShrink: 0,\n width: '1.5em',\n height: '1.5em',\n color: '_textMuted',\n },\n chevronOpen: { rotate: '90deg' },\n checkbox: { marginInlineEnd: '_xs' },\n checkMark: { width: '0.875em', height: '0.875em', color: '_accentContrast' },\n hidden: { visibility: 'hidden' },\n // 搜索时匹配的节点\n matched: { fontWeight: '_semibold' },\n // 拖动:被拖的那一项变淡;放进某一项里时它带品牌色的框;放在前后时画一条线\n dragging: { opacity: 0.5 },\n dropInside: {\n outlineStyle: 'solid',\n outlineWidth: '_borderWidths.sm',\n outlineColor: '_accent',\n outlineOffset: `calc(-1 * ${t.borderWidths.sm})`,\n backgroundColor: '_accentSoft',\n },\n dropLine: {\n position: 'absolute',\n insetInlineEnd: 0,\n height: '_borderWidths.sm',\n backgroundColor: '_accent',\n borderRadius: '_full',\n pointerEvents: 'none',\n },\n dropBefore: { top: `calc(-1 * ${t.borderWidths.xs})` },\n dropAfter: { bottom: `calc(-1 * ${t.borderWidths.xs})` },\n // 画线的那一项要作定位参照\n positioned: { position: 'relative' },\n});\n\n// 缩进与位置是任意值,用动态样式;单独一个 create,见 COMPONENTS.md §4\n/** Tree 的样式:indent(缩进)、y、height */\nexport const treeDynamicStyles = css.create({\n indent: (em: number) => ({ width: `${em}em`, flexShrink: 0 }),\n y: (px: number) => ({ transform: `translateY(${px}px)` }),\n height: (px: number) => ({ height: px }),\n width: (value: string) => ({ width: value }),\n // 落点线从这一层的缩进处开始\n lineStart: (em: number) => ({ insetInlineStart: `${em}em` }),\n});\n\n/** 加载中显示几行骨架 */\nconst SKELETON_ROWS = 4;\n\nconst ARIA_CHECKED: Record<CheckState, 'true' | 'false' | 'mixed'> = {\n checked: 'true',\n unchecked: 'false',\n indeterminate: 'mixed',\n};\n\n/** 树:可展开的层级列表,单选 / 多选、父子联动的勾选、懒加载、方向键导航、虚拟滚动 */\nexport const Tree = _component(\n <T,>({\n items,\n getKey,\n getLabel,\n getChildren,\n hasChildren,\n loadChildren,\n onLoadError,\n isDisabled,\n getIcon,\n _expanded: expanded = _bindable<string[]>([]),\n selectionMode,\n _selected: selected = _bindable<string[]>([]),\n checkable = false,\n checkStrictly = false,\n _checked: checked = _bindable<string[]>([]),\n loading = false,\n empty,\n indent = 1.25,\n estimateSize = 32,\n filter,\n onMove,\n canDrop,\n renderItem,\n propsItem,\n propsRow,\n propsToggle,\n propsCheckbox,\n propsLabel,\n propsEmpty,\n propsSkeleton,\n propsScrollArea,\n id,\n ...rest\n }: TreeProps<T>) => {\n const lang = useLang();\n // 骨架防闪烁:很快就取回来时不显示;aria-busy 按真实的 loading\n const indicator = useDelayedLoading(() => loading);\n const generatedId = useId();\n const prefix = () => id ?? generatedId;\n let root = _state.raw<HTMLElement | null>(null);\n let sizer = _state.raw<HTMLElement | null>(null);\n // 键盘所在的当前项;焦点在树上时才高亮\n let active = _state<string | undefined>(undefined);\n let focused = _state(false);\n const typeahead = createTypeahead();\n // 勾选框画成 Checkbox 的样子,跟着 styles.Choice 的定制\n const choice = useRecipe(choiceRecipe);\n\n const accessors = (): TreeAccessors<T> => ({\n getKey: (node) => getKey(node),\n getChildren,\n hasChildren,\n });\n\n // 搜索过滤:匹配的节点与祖先;为 null 时不过滤\n const textMatcher = useTextMatcher();\n const filtering = _derived.by(() => {\n const query = typeof filter === 'string' ? filter.trim() : filter;\n if (!query) return null;\n const match =\n typeof query === 'string' ? (node: T) => textMatcher()(getLabel(node), query) : query;\n return filterTree(items, accessors(), match);\n });\n // 过滤时的展开状态单独记:一开始展开匹配项的祖先,可以再收起;清空过滤后回到原来的 expanded\n let filterExpanded = _state<string[]>([]);\n watch(\n () => filtering,\n (result) => (filterExpanded = result ? [...result.expand] : []),\n { immediate: true },\n );\n const shownExpanded = () => (filtering ? filterExpanded : expanded);\n\n const expansion = useTreeExpansion<T>({\n expanded: shownExpanded,\n setExpanded: (keys) => (filtering ? (filterExpanded = keys) : (expanded = keys)),\n getChildren: (node) => getChildren(node),\n loadChildren: (node) => loadChildren?.(node),\n // 没给 onLoadError 时交给 useTreeExpansion 在控制台报错\n onLoadError: _untrack(onLoadError) && ((error, node) => onLoadError?.(error, node)),\n });\n\n const rows = _derived.by(() =>\n flattenTree(items, accessors(), new Set(shownExpanded()), { include: filtering?.include }),\n );\n const rowOf = _derived.by(() => new Map(rows.map((row, index) => [row.key, index])));\n // 勾选联动要看到折叠着的节点:只在联动勾选时建整棵树的索引\n const index = _derived.by(() =>\n checkable && !checkStrictly ? indexTree(items, accessors()) : null,\n );\n const states = _derived.by(() => (index ? checkStates(index, checked) : null));\n const checkedSet = _derived.by(() => new Set(checked));\n const selectedSet = _derived.by(() => new Set(selected));\n\n /** 当前项的行号;没有时 -1 */\n const activeRow = () => (active === undefined ? -1 : (rowOf.get(active) ?? -1));\n\n const virtual = useVirtualizer(() => {\n const current = rows;\n // 读一下当前项:它变了要重新算渲染范围(当前项总要渲染,aria-activedescendant 才指得到)\n const focusedRow = activeRow();\n // 先读出来:每一项都要调用一次估计高度,不要每次都经过 props 的响应式读取\n const size = estimateSize;\n return {\n count: current.length,\n scrollElement: root,\n list: sizer,\n estimateSize: () => size,\n getItemKey: (position: number) => current[position]!.key,\n overscan: 6,\n rangeExtractor: (range) => {\n const indices = defaultRangeExtractor(range);\n if (focusedRow >= 0 && !indices.includes(focusedRow)) {\n indices.push(focusedRow);\n indices.sort((a, b) => a - b);\n }\n return indices;\n },\n };\n });\n\n watch(\n () => active,\n () => {\n const position = activeRow();\n if (position >= 0) virtual.scrollToIndex(position, { align: 'auto' });\n },\n { flush: 'post' },\n );\n\n // 当前项所在的父节点被收起:当前项移到还看得见的最近祖先\n watch(\n () => rows,\n (next, previous) => {\n if (active === undefined || rowOf.has(active)) return;\n let parent = previous.find((row) => row.key === active)?.parent;\n while (parent !== undefined && !rowOf.has(parent)) {\n parent = previous.find((row) => row.key === parent)?.parent;\n }\n active = parent ?? next[0]?.key;\n },\n );\n\n const disabledAt = (position: number) => {\n const row = rows[position];\n return !row || (isDisabled?.(row.node) ?? false);\n };\n\n function select(position: number) {\n const row = rows[position];\n if (!row || !selectionMode || disabledAt(position)) return;\n selected = [...toggleSelection(selected, row.key, { mode: selectionMode })];\n }\n\n function check(position: number) {\n const row = rows[position];\n if (!row || !checkable || disabledAt(position)) return;\n checked = index\n ? toggleChecked(index, checked, row.key)\n : [...toggleSelection(checked, row.key, { mode: 'multiple' })];\n }\n\n function toggle(position: number) {\n const row = rows[position];\n if (row?.expandable)\n void expansion.setOpen(row.node, row.key, !expansion.isExpanded(row.key));\n }\n\n // —— 移动节点(onMove):指针拖动,或 Alt + 方向键 ——\n let dragging = _state<string | undefined>(undefined);\n let drop = _state.raw<DropSpot | null>(null);\n let expandTimer: ReturnType<typeof setTimeout> | undefined;\n let stopDrag: (() => void) | undefined;\n onScopeDispose(() => {\n clearTimeout(expandTimer);\n stopDrag?.();\n });\n\n const rowByKey = (key: string | undefined) =>\n key === undefined ? undefined : rows[rowOf.get(key) ?? -1];\n\n /** key 是不是 ancestor 自己或它的子孙(看得见的行里,祖先总是看得见的) */\n function isWithin(key: string, ancestor: string) {\n for (let at: string | undefined = key; at !== undefined; at = rowByKey(at)?.parent) {\n if (at === ancestor) return true;\n }\n return false;\n }\n\n /** 落点换算成移动的目标(按移走之后的同级算);放不下时 null */\n function targetOf(key: string, spot: DropSpot): TreeMoveTarget | null {\n const moving = rowByKey(key);\n const row = rowByKey(spot.key);\n if (!moving || !row || isWithin(spot.key, key)) return null;\n let target: TreeMoveTarget;\n if (spot.zone === 'inside') target = { parent: row.key, index: Number.MAX_SAFE_INTEGER };\n else {\n const offset = spot.zone === 'before' ? row.position - 1 : row.position;\n // 同一层里从前面移过来:移走之后,后面的都往前挪了一位\n const shift = moving.parent === row.parent && moving.position <= offset ? 1 : 0;\n target = { parent: row.parent, index: offset - shift };\n }\n return canDrop && !canDrop(moving.node, target) ? null : target;\n }\n\n /** 报告移动,并告诉读屏移到了哪里 */\n function emitMove(key: string, target: TreeMoveTarget) {\n const row = rowByKey(key);\n if (!row || !onMove) return;\n const parent = rowByKey(target.parent);\n // 移走之后的同级个数:同一层里移动时要去掉自己\n const count =\n (parent ? (getChildren(parent.node)?.length ?? 0) : items.length) -\n (row.parent === target.parent ? 1 : 0);\n onMove({ key, node: row.node, target });\n announce(\n lang.treeMoved(\n getLabel(row.node),\n parent && getLabel(parent.node),\n Math.min(target.index, count) + 1,\n ),\n );\n }\n\n /** 指针下的落点:一项的上四分之一放在它前面,下四分之一放在后面,中间放进它里面 */\n function spotAt(clientX: number, clientY: number): DropSpot | null {\n const element = document\n .elementFromPoint(clientX, clientY)\n ?.closest<HTMLElement>('[data-index]');\n if (!element || !root?.contains(element)) return null;\n const row = rows[Number(element.dataset.index)];\n if (!row) return null;\n const rect = element.getBoundingClientRect();\n const ratio = (clientY - rect.top) / rect.height;\n return { key: row.key, zone: ratio < 0.25 ? 'before' : ratio > 0.75 ? 'after' : 'inside' };\n }\n\n /** 拖到靠近上下边缘时滚动 */\n function autoScroll(clientY: number) {\n if (!root) return;\n const rect = root.getBoundingClientRect();\n if (clientY < rect.top + 32) root.scrollTop -= 12;\n else if (clientY > rect.bottom - 32) root.scrollTop += 12;\n }\n\n /** 拖到收起的节点里停一会儿:展开它,好放到更深的地方 */\n function scheduleExpand(spot: DropSpot | null) {\n clearTimeout(expandTimer);\n const row = spot?.zone === 'inside' ? rowByKey(spot.key) : undefined;\n if (!row?.expandable || expansion.isExpanded(row.key)) return;\n expandTimer = setTimeout(() => void expansion.setOpen(row.node, row.key, true), 600);\n }\n\n function onItemPointerdown(event: PointerEvent, key: string) {\n // 焦点留在树上\n event.preventDefault();\n // 触摸时照常滚动,不拖\n if (!onMove || event.pointerType === 'touch' || !root) return;\n stopDrag = startMove(event, {\n threshold: 4,\n // 虚拟滚动会换掉行元素:捕获在不动的树上\n captureTarget: root,\n onMove: ({ clientX, clientY }) => {\n dragging = key;\n // 先按当前的位置算落点,再滚动:滚动后指针下面换成了别的项\n const spot = spotAt(clientX, clientY);\n autoScroll(clientY);\n const next = spot && targetOf(key, spot) ? spot : null;\n if (next?.key === drop?.key && next?.zone === drop?.zone) return;\n drop = next;\n scheduleExpand(next);\n },\n onEnd: ({ moved, cancelled }) => {\n const spot = drop;\n dragging = undefined;\n drop = null;\n stopDrag = undefined;\n clearTimeout(expandTimer);\n if (!moved || cancelled || !spot) return;\n const target = targetOf(key, spot);\n if (target) emitMove(key, target);\n },\n });\n }\n\n /** Alt + ↑↓ 在同级里移动,Alt + → 放进上一个同级的最后,Alt + ← 移到父节点后面(从右到左时左右对调) */\n function moveByKey(event: KeyboardEvent): boolean {\n const row = rows[activeRow()];\n if (!row) return false;\n const { forward, backward } = inlineArrows(!!root && isRtl(root));\n let target: TreeMoveTarget | undefined;\n switch (event.key) {\n case 'ArrowUp':\n if (row.position > 1) target = { parent: row.parent, index: row.position - 2 };\n break;\n case 'ArrowDown':\n if (row.position < row.setSize) target = { parent: row.parent, index: row.position };\n break;\n case forward: {\n const previous = rows.find(\n (item) => item.parent === row.parent && item.position === row.position - 1,\n );\n if (!previous) break;\n target = { parent: previous.key, index: Number.MAX_SAFE_INTEGER };\n // 展开新的父节点:移过去之后还看得见\n void expansion.setOpen(previous.node, previous.key, true);\n break;\n }\n case backward: {\n const parent = rowByKey(row.parent);\n if (parent) target = { parent: parent.parent, index: parent.position };\n break;\n }\n default:\n return false;\n }\n if (target && (!canDrop || canDrop(row.node, target))) emitMove(row.key, target);\n return true;\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (event.altKey && onMove && !event.ctrlKey && !event.metaKey) {\n if (moveByKey(event)) event.preventDefault();\n return;\n }\n if (event.altKey || event.ctrlKey || event.metaKey || rows.length === 0) return;\n const position = Math.max(activeRow(), 0);\n const row = rows[position]!;\n const open = row.expandable && expansion.isExpanded(row.key);\n const { forward, backward } = inlineArrows(!!root && isRtl(root));\n const go = (target: number) => (active = rows[target]?.key ?? active);\n switch (event.key) {\n case 'ArrowDown':\n go(Math.min(position + 1, rows.length - 1));\n break;\n case 'ArrowUp':\n go(Math.max(position - 1, 0));\n break;\n case 'Home':\n go(0);\n break;\n case 'End':\n go(rows.length - 1);\n break;\n case forward:\n if (!row.expandable) break;\n if (!open) void expansion.setOpen(row.node, row.key, true);\n // 已展开:进入第一个子节点(子节点还没加载出来时不动)\n else if (rows[position + 1]?.parent === row.key) go(position + 1);\n break;\n case backward:\n if (open) void expansion.setOpen(row.node, row.key, false);\n else if (row.parent !== undefined) active = row.parent;\n break;\n case 'Enter':\n if (selectionMode) select(position);\n else toggle(position);\n break;\n case ' ':\n if (checkable) check(position);\n else select(position);\n break;\n default: {\n const found = typeahead.next(\n event.key,\n rows.map((item) => getLabel(item.node)),\n activeRow(),\n );\n if (found < 0) return;\n go(found);\n }\n }\n event.preventDefault();\n }\n\n function onFocus() {\n focused = true;\n if (active !== undefined && rowOf.has(active)) return;\n // 第一次进入:落在第一个已选的可见节点上,没有时落在第一项\n active = rows.find((row) => selectedSet.has(row.key))?.key ?? rows[0]?.key;\n }\n\n function renderRow(position: number) {\n const row = rows[position]!;\n const open = row.expandable && expansion.isExpanded(row.key);\n const disabled = disabledAt(position);\n const state: TreeItemRenderState = {\n depth: row.depth,\n expanded: open,\n selected: selectedSet.has(row.key),\n checked: states\n ? (states.get(row.key) ?? 'unchecked')\n : checkedSet.has(row.key)\n ? 'checked'\n : 'unchecked',\n active: active === row.key,\n };\n const own = typeof propsItem === 'function' ? propsItem(row.node, state) : propsItem;\n const icon = getIcon?.(row.node, open);\n const loading = expansion.isLoading(row.key);\n const marked = state.checked !== 'unchecked';\n const box = choice();\n const dropZone = drop?.key === row.key ? drop.zone : undefined;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n itemStyles.row,\n itemStyles.hoverable,\n treeStyles.item,\n focused && state.active && itemStyles.highlighted,\n state.selected && itemStyles.current,\n disabled && itemStyles.disabled,\n dragging === row.key && treeStyles.dragging,\n dropZone === 'inside' && treeStyles.dropInside,\n dropZone && dropZone !== 'inside' && treeStyles.positioned,\n ],\n },\n own,\n {\n id: `${prefix()}-${position}`,\n role: 'treeitem',\n 'aria-level': row.depth + 1,\n 'aria-setsize': row.setSize,\n 'aria-posinset': row.position,\n 'aria-expanded': row.expandable ? open : undefined,\n 'aria-selected': selectionMode ? state.selected : undefined,\n 'aria-checked': checkable ? ARIA_CHECKED[state.checked] : undefined,\n 'aria-disabled': disabled || undefined,\n 'aria-busy': loading || undefined,\n onPointerdown: (event: PointerEvent) => onItemPointerdown(event, row.key),\n onClick: () => {\n active = row.key;\n root?.focus({ preventScroll: true });\n if (selectionMode) select(position);\n else if (checkable) check(position);\n else toggle(position);\n },\n },\n )}\n data-state={state.selected ? 'selected' : undefined}\n data-active={state.active || undefined}\n data-disabled={disabled || undefined}\n >\n {row.depth > 0 && <span {...css.attrs(treeDynamicStyles.indent(row.depth * indent))} />}\n <span\n {...mergeAttrs<'span'>({ sx: treeStyles.toggle }, propsToggle, {\n 'aria-hidden': true,\n onClick: (event: MouseEvent) => {\n if (!row.expandable) return;\n event.stopPropagation();\n active = row.key;\n root?.focus({ preventScroll: true });\n toggle(position);\n },\n })}\n >\n {loading ? (\n <Spinner />\n ) : (\n row.expandable && (\n <Icon\n icon={ChevronRight}\n flipInRtl\n sx={[disclosureStyles.icon, open && treeStyles.chevronOpen]}\n />\n )\n )}\n </span>\n {checkable && (\n <span\n {...mergeAttrs<'span'>(\n // 勾选框的实底色取色调变量(同 Checkbox 的 choiceParts)\n { sx: [box.control.sx, toneFillStyles.accent, treeStyles.checkbox] },\n propsCheckbox,\n {\n 'aria-hidden': true,\n onClick: (event: MouseEvent) => {\n event.stopPropagation();\n active = row.key;\n root?.focus({ preventScroll: true });\n check(position);\n },\n },\n )}\n >\n <span\n {...css.attrs(\n box.input.sx,\n focusRingStyles.tight,\n checkboxStyles.box,\n marked && choiceInputStyles.checked,\n )}\n />\n <Icon\n icon={state.checked === 'indeterminate' ? Minus : Check}\n strokeWidth={3}\n sx={[box.indicator.sx, treeStyles.checkMark, !marked && treeStyles.hidden]}\n />\n </span>\n )}\n {icon && <Icon icon={icon} />}\n <span\n {...mergeAttrs<'span'>(\n { sx: [itemStyles.label, filtering?.matched.has(row.key) && treeStyles.matched] },\n propsLabel,\n )}\n >\n {renderItem ? renderItem(row.node, state) : getLabel(row.node)}\n </span>\n {dropZone && dropZone !== 'inside' && (\n <span\n aria-hidden=\"true\"\n {...css.attrs(\n treeStyles.dropLine,\n dropZone === 'before' ? treeStyles.dropBefore : treeStyles.dropAfter,\n treeDynamicStyles.lineStart(row.depth * indent + 1.75),\n )}\n />\n )}\n </div>\n );\n }\n\n /** 没有节点时:加载中是几行骨架,否则是空状态 */\n function renderPlaceholder() {\n if (loading) {\n if (!indicator.value) return null;\n return Array.from({ length: SKELETON_ROWS }, (_, row) => (\n <Skeleton\n key={row}\n {...mergePartProps<SkeletonProps>(\n {\n sx: [treeStyles.skeleton, treeDynamicStyles.width(`${85 - row * 15}%`)],\n delay: row * SHIMMER_STAGGER,\n },\n propsSkeleton,\n )}\n />\n ));\n }\n return (\n empty ?? (\n <Empty\n {...mergePartProps<EmptyProps>(\n {\n size: 'sm',\n icon: false,\n description: filtering ? lang.treeNoMatch : lang.treeEmpty,\n },\n propsEmpty,\n )}\n />\n )\n );\n }\n\n return () => {\n const position = activeRow();\n return (\n <ScrollArea\n {...mergePartProps<ScrollAreaProps>({}, propsScrollArea)}\n focusable={false}\n propsViewport={\n mergeProps<'div'>({ sx: [treeStyles.root, focusRingStyles.visible] }, rest, {\n ref: _toRef(root),\n id: prefix(),\n role: 'tree',\n tabindex: rows.length > 0 ? 0 : -1,\n 'aria-multiselectable': selectionMode === 'multiple' || undefined,\n 'aria-activedescendant': position >= 0 ? `${prefix()}-${position}` : undefined,\n 'aria-busy': loading || undefined,\n onFocus,\n onBlur: () => (focused = false),\n onKeydown,\n }) as PartProps<'div'>\n }\n >\n {rows.length === 0 && renderPlaceholder()}\n <div\n ref={_toRef(sizer)}\n role=\"presentation\"\n {...css.attrs(treeStyles.sizer, treeDynamicStyles.height(virtual.total))}\n >\n {virtual.items.map((item) => (\n <div\n key={item.key}\n {...mergeAttrs<'div'>({ sx: treeStyles.row }, propsRow, {\n ref: virtual.measure,\n role: 'presentation',\n sx: treeDynamicStyles.y(item.start),\n })}\n data-index={item.index}\n >\n {renderRow(item.index)}\n </div>\n ))}\n </div>\n </ScrollArea>\n );\n };\n },\n { name: 'Tree' },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tree.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_shallowRef","_vue_ref","_vue_computed","_vtp_untrack","_createVNode","_mergeProps"],"sources":["../../src/display/Tree.tsx"],"sourcesContent":["/**\n * 树(WAI-ARIA Tree):可展开的层级列表(文件夹、组织架构、分类),可单选 / 多选、勾选(父子联动、半选)、懒加载子节点。\n * 数据驱动,始终虚拟滚动(上万个节点也只渲染看得见的几十个):\n *\n * <Tree\n * items={folders}\n * getKey={(node) => node.id}\n * getLabel={(node) => node.name}\n * getChildren={(node) => node.children}\n * _expanded={open}\n * selectionMode=\"single\"\n * _selected={current}\n * aria-label=\"目录\"\n * />\n *\n * - 键盘:焦点在树上,当前项经 aria-activedescendant 告诉读屏。↑↓ 移动,→ 展开 / 进入第一个子节点,← 收起 / 回到父节点,\n * Home / End,Enter 选中(没有选择时展开或收起),空格勾选(checkable 时)或选中,按字母跳到以它开头的节点。\n * - 勾选:checkable 时每项前有勾选框,_checked={keys} 是勾上的全部节点;勾上父节点会勾上它的子孙,\n * 子节点全勾上时父节点也勾上,只勾了一部分时父节点半选(aria-checked=\"mixed\")。\n * - 懒加载:hasChildren 说有子节点、getChildren 还没有时,展开会调用 loadChildren(加载中显示加载指示)。\n * - 节点平铺渲染(虚拟滚动没法嵌套 role=\"group\"),层级经 aria-level / aria-setsize / aria-posinset 告诉读屏。\n *\n * 展开状态与勾选联动见 utils/data/tree.ts(TreeDataTable 共用)。部件:Root(div,role=\"tree\")、\n * Row(虚拟滚动定位的一行,包着 Item)、Item(div,role=\"treeitem\")、Toggle(展开箭头)、\n * Checkbox(勾选框,只是外观,状态在 treeitem 的 aria-checked 上)、Label、ScrollArea(外层的滚动区域)。\n */\nimport { Check, ChevronRight, Minus } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { onScopeDispose, useId, watch, type VNodeChild } from 'vue';\nimport { Icon, type IconData } from '../base/Icon';\nimport { Spinner } from '../base/Spinner';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { t } from '../config/theme/tokens';\nimport { announce } from '../utils/dom/announcer';\nimport { startMove } from '../utils/dom/move';\nimport { Empty, type EmptyProps } from '../feedback/Empty';\nimport { Skeleton, type SkeletonProps, type SkeletonShapeProps } from '../feedback/Skeleton';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { SHIMMER_STAGGER } from '../utils/style/shimmer';\nimport { checkboxStyles } from '../input/Checkbox';\nimport { choiceInputStyles, choiceRecipe } from '../input/choice-styles';\nimport { useRecipe } from '../config/styles';\nimport { toneFillStyles } from '../utils/style/tone-styles';\nimport { inlineArrows, isRtl } from '../utils/dom/direction';\nimport { toggleSelection, type SelectionModes } from '../utils/data/selection';\nimport {\n checkStates,\n filterTree,\n flattenTree,\n indexTree,\n toggleChecked,\n useTreeExpansion,\n type CheckState,\n type TreeAccessors,\n type TreeMoveTarget,\n} from '../utils/data/tree';\nimport { createTypeahead } from '../utils/dom/typeahead';\nimport { mergeAttrs, mergePartProps, mergeProps, type PartProps } from '../utils/props';\nimport { ScrollArea, type ScrollAreaProps } from '../layout/ScrollArea';\nimport { itemStyles } from '../utils/style/item-styles';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { useVirtualizer } from '../utils/virtual/use-virtualizer';\nimport { defaultRangeExtractor } from '../utils/virtual/virtualizer';\nimport { disclosureStyles } from '../utils/style/transitions';\n\n/** 节点的渲染状态 */\nexport interface TreeItemRenderState {\n /** 层级,第一层为 0 */\n depth: number;\n /** 展开着 */\n expanded: boolean;\n /** 已选 */\n selected: boolean;\n /** 勾选状态(checkable 时) */\n checked: CheckState;\n /** 键盘所在的当前项 */\n active: boolean;\n}\n\n/** 一次移动:把 key 移到 target(交给 moveNode) */\nexport interface TreeMove<T> {\n /** 移动的节点的 key */\n key: string;\n /** 移动的节点 */\n node: T;\n /** 放到哪个节点下的第几位(按移走之后的同级算) */\n target: TreeMoveTarget;\n}\n\n/** 拖动时的落点:放在 key 这一项的前面、后面或里面 */\ninterface DropSpot {\n key: string;\n zone: 'before' | 'after' | 'inside';\n}\n\n/** 未声明的属性落到 div(role=\"tree\")上;aria-label 或 aria-labelledby 是树的名称 */\nexport interface TreeProps<T> extends PartProps<'div', 'role'> {\n /** 第一层的节点 */\n items: readonly T[];\n /** 节点的 key,整棵树里唯一 */\n getKey: (node: T) => string;\n /** 节点的文字:默认显示它,类型搜索也按它 */\n getLabel: (node: T) => string;\n /** 子节点;叶子或还没加载时返回 undefined / 空数组 */\n getChildren: (node: T) => readonly T[] | undefined;\n /** 有没有子节点(懒加载时子节点还没取回来也要能展开);不写时看 getChildren 是否非空 */\n hasChildren?: (node: T) => boolean;\n /** 展开一个还没有子节点的节点时调用:取回子节点并放进数据里;返回 Promise 时显示加载中 */\n loadChildren?: (node: T) => Promise<unknown> | void;\n /** 子节点加载失败(loadChildren 的 Promise 被拒绝):节点收回去,再展开会重试;不写时在控制台报错 */\n onLoadError?: (error: unknown, node: T) => void;\n /** 节点不可用:可以经过、展开,不能选中、勾选 */\n isDisabled?: (node: T) => boolean;\n /** 文字前的图标,可以按展开状态换(文件夹开 / 合) */\n getIcon?: (node: T, expanded: boolean) => IconData | undefined;\n /** 展开的节点:父级写 _expanded={keys} */\n _expanded?: string[];\n /** 选择方式;不写时不能选中 */\n selectionMode?: keyof SelectionModes;\n /** 选中的节点:父级写 _selected={keys} */\n _selected?: string[];\n /** 每项前显示勾选框,默认父子联动 */\n checkable?: boolean;\n /** 勾选父子不联动:每个节点各自勾选(权限树里“只给这一级”) */\n checkStrictly?: boolean;\n /** 勾上的节点(联动时含勾上的父节点与子孙):父级写 _checked={keys} */\n _checked?: string[];\n /** 正在取节点:还没有节点时显示骨架行,树带 aria-busy */\n loading?: boolean;\n /** 没有节点时显示的内容;默认是 Empty(文案取语言包) */\n empty?: VNodeChild;\n /** 每一层缩进多少(em),默认 1.25 */\n indent?: number;\n /** 每项的估计高度(px),默认 32;渲染后以实际高度为准 */\n estimateSize?: number;\n /**\n * 搜索过滤:字符串时按节点文字匹配(忽略大小写与重音,或 createUi 的 textMatcher),函数时自己判断。\n * 留下匹配的节点与它们的祖先并展开祖先,匹配的节点文字加粗;只看已加载的节点。清空后回到原来的展开状态\n */\n filter?: string | ((node: T) => boolean);\n /**\n * 拖动节点改变层级与顺序:放下(或 Alt + 方向键)时报告移动,用 moveNode 生成新数据交回 items;不写时不能拖。\n * 指针拖动只用鼠标、笔(触摸时照常滚动)\n */\n onMove?: (move: TreeMove<T>) => void;\n /** 能不能放到这里(如文件不能放进文件里);不写时都能放(放进自己和自己的子孙里除外) */\n canDrop?: (node: T, target: TreeMoveTarget) => boolean;\n /** 自定义文字部分的内容 */\n renderItem?: (node: T, state: TreeItemRenderState) => VNodeChild;\n /** 每一项的部件属性,可以按节点计算 */\n propsItem?:\n PartProps<'div', 'role' | 'id'> | ((node: T, state: TreeItemRenderState) => PartProps<'div'>);\n /** 每一行(虚拟滚动定位的容器,包着 treeitem)的部件属性 */\n propsRow?: PartProps<'div', 'role'>;\n /** 展开箭头的部件属性(只是外观,键盘与读屏走 treeitem) */\n propsToggle?: PartProps<'span', 'aria-hidden'>;\n /** 勾选框的部件属性(只是外观,状态在 treeitem 的 aria-checked 上) */\n propsCheckbox?: PartProps<'span', 'aria-hidden'>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n /** 默认空状态(Empty)的部件属性 */\n propsEmpty?: Partial<EmptyProps>;\n /** 加载中的骨架行的部件属性 */\n propsSkeleton?: SkeletonShapeProps;\n /** 外层滚动区域(ScrollArea)的部件属性:放进弹出层、弹性布局时给它 sx;树元素本身是它的视口 */\n propsScrollArea?: Partial<Omit<ScrollAreaProps, 'propsViewport'>>;\n}\n\n/** Tree 的样式:root、sizer、row、item、toggle、checkbox、label 等 */\nexport const treeStyles = css.create({\n // 树元素就是 ScrollArea 的视口(浮层滚动条);焦点与 aria-activedescendant 在它上面\n root: {\n position: 'relative',\n overscrollBehavior: 'contain',\n padding: '_xs',\n outlineStyle: 'none',\n },\n sizer: { position: 'relative', width: '_full' },\n skeleton: { display: 'block', height: '1em', marginBlock: '0.625em', marginInline: '_sm' },\n row: { position: 'absolute', top: 0, insetInline: 0, paddingBlock: '1px' },\n item: { gap: '_xs', minHeight: '_sizes.minTarget', paddingInlineStart: '_xs' },\n toggle: {\n display: 'grid',\n placeItems: 'center',\n flexShrink: 0,\n width: '1.5em',\n height: '1.5em',\n color: '_textMuted',\n },\n chevronOpen: { rotate: '90deg' },\n checkbox: { marginInlineEnd: '_xs' },\n checkMark: { width: '0.875em', height: '0.875em', color: '_accentContrast' },\n hidden: { visibility: 'hidden' },\n // 搜索时匹配的节点\n matched: { fontWeight: '_semibold' },\n // 拖动:被拖的那一项变淡;放进某一项里时它带品牌色的框;放在前后时画一条线\n dragging: { opacity: 0.5 },\n dropInside: {\n outlineStyle: 'solid',\n outlineWidth: '_borderWidths.sm',\n outlineColor: '_accent',\n outlineOffset: `calc(-1 * ${t.borderWidths.sm})`,\n backgroundColor: '_accentSoft',\n },\n dropLine: {\n position: 'absolute',\n insetInlineEnd: 0,\n height: '_borderWidths.sm',\n backgroundColor: '_accent',\n borderRadius: '_full',\n pointerEvents: 'none',\n },\n dropBefore: { top: `calc(-1 * ${t.borderWidths.xs})` },\n dropAfter: { bottom: `calc(-1 * ${t.borderWidths.xs})` },\n // 画线的那一项要作定位参照\n positioned: { position: 'relative' },\n});\n\n// 缩进与位置是任意值,用动态样式;单独一个 create,见 COMPONENTS.md §4\n/** Tree 的样式:indent(缩进)、y、height */\nexport const treeDynamicStyles = css.create({\n indent: (em: number) => ({ width: `${em}em`, flexShrink: 0 }),\n y: (px: number) => ({ transform: `translateY(${px}px)` }),\n height: (px: number) => ({ height: px }),\n width: (value: string) => ({ width: value }),\n // 落点线从这一层的缩进处开始\n lineStart: (em: number) => ({ insetInlineStart: `${em}em` }),\n});\n\n/** 加载中显示几行骨架 */\nconst SKELETON_ROWS = 4;\n\nconst ARIA_CHECKED: Record<CheckState, 'true' | 'false' | 'mixed'> = {\n checked: 'true',\n unchecked: 'false',\n indeterminate: 'mixed',\n};\n\n/** 树:可展开的层级列表,单选 / 多选、父子联动的勾选、懒加载、方向键导航、虚拟滚动 */\nexport const Tree = _component(\n <T,>({\n items,\n getKey,\n getLabel,\n getChildren,\n hasChildren,\n loadChildren,\n onLoadError,\n isDisabled,\n getIcon,\n _expanded: expanded = _bindable<string[]>([]),\n selectionMode,\n _selected: selected = _bindable<string[]>([]),\n checkable = false,\n checkStrictly = false,\n _checked: checked = _bindable<string[]>([]),\n loading = false,\n empty,\n indent = 1.25,\n estimateSize = 32,\n filter,\n onMove,\n canDrop,\n renderItem,\n propsItem,\n propsRow,\n propsToggle,\n propsCheckbox,\n propsLabel,\n propsEmpty,\n propsSkeleton,\n propsScrollArea,\n id,\n ...rest\n }: TreeProps<T>) => {\n const lang = useLang();\n // 骨架防闪烁:很快就取回来时不显示;aria-busy 按真实的 loading\n const indicator = useDelayedLoading(() => loading);\n const generatedId = useId();\n const prefix = () => id ?? generatedId;\n let root = _state.raw<HTMLElement | null>(null);\n let sizer = _state.raw<HTMLElement | null>(null);\n // 键盘所在的当前项;焦点在树上时才高亮\n let active = _state<string | undefined>(undefined);\n let focused = _state(false);\n const typeahead = createTypeahead();\n // 勾选框画成 Checkbox 的样子,跟着 styles.Choice 的定制\n const choice = useRecipe(choiceRecipe);\n\n const accessors = (): TreeAccessors<T> => ({\n getKey: (node) => getKey(node),\n getChildren,\n hasChildren,\n });\n\n // 搜索过滤:匹配的节点与祖先;为 null 时不过滤\n const textMatcher = useTextMatcher();\n const filtering = _derived.by(() => {\n const query = typeof filter === 'string' ? filter.trim() : filter;\n if (!query) return null;\n const match =\n typeof query === 'string' ? (node: T) => textMatcher()(getLabel(node), query) : query;\n return filterTree(items, accessors(), match);\n });\n // 过滤时的展开状态单独记:一开始展开匹配项的祖先,可以再收起;清空过滤后回到原来的 expanded\n let filterExpanded = _state<string[]>([]);\n watch(\n () => filtering,\n (result) => (filterExpanded = result ? [...result.expand] : []),\n { immediate: true },\n );\n const shownExpanded = () => (filtering ? filterExpanded : expanded);\n\n const expansion = useTreeExpansion<T>({\n expanded: shownExpanded,\n setExpanded: (keys) => (filtering ? (filterExpanded = keys) : (expanded = keys)),\n getChildren: (node) => getChildren(node),\n loadChildren: (node) => loadChildren?.(node),\n // 没给 onLoadError 时交给 useTreeExpansion 在控制台报错\n onLoadError: _untrack(onLoadError) && ((error, node) => onLoadError?.(error, node)),\n });\n\n const rows = _derived.by(() =>\n flattenTree(items, accessors(), new Set(shownExpanded()), { include: filtering?.include }),\n );\n const rowOf = _derived.by(() => new Map(rows.map((row, index) => [row.key, index])));\n // 勾选联动要看到折叠着的节点:只在联动勾选时建整棵树的索引\n const index = _derived.by(() =>\n checkable && !checkStrictly ? indexTree(items, accessors()) : null,\n );\n const states = _derived.by(() => (index ? checkStates(index, checked) : null));\n const checkedSet = _derived.by(() => new Set(checked));\n const selectedSet = _derived.by(() => new Set(selected));\n\n /** 当前项的行号;没有时 -1 */\n const activeRow = () => (active === undefined ? -1 : (rowOf.get(active) ?? -1));\n\n const virtual = useVirtualizer(() => {\n const current = rows;\n // 读一下当前项:它变了要重新算渲染范围(当前项总要渲染,aria-activedescendant 才指得到)\n const focusedRow = activeRow();\n // 先读出来:每一项都要调用一次估计高度,不要每次都经过 props 的响应式读取\n const size = estimateSize;\n return {\n count: current.length,\n scrollElement: root,\n list: sizer,\n estimateSize: () => size,\n getItemKey: (position: number) => current[position]!.key,\n overscan: 6,\n rangeExtractor: (range) => {\n const indices = defaultRangeExtractor(range);\n if (focusedRow >= 0 && !indices.includes(focusedRow)) {\n indices.push(focusedRow);\n indices.sort((a, b) => a - b);\n }\n return indices;\n },\n };\n });\n\n watch(\n () => active,\n () => {\n const position = activeRow();\n if (position >= 0) virtual.scrollToIndex(position, { align: 'auto' });\n },\n { flush: 'post' },\n );\n\n // 当前项所在的父节点被收起:当前项移到还看得见的最近祖先\n watch(\n () => rows,\n (next, previous) => {\n if (active === undefined || rowOf.has(active)) return;\n let parent = previous.find((row) => row.key === active)?.parent;\n while (parent !== undefined && !rowOf.has(parent)) {\n parent = previous.find((row) => row.key === parent)?.parent;\n }\n active = parent ?? next[0]?.key;\n },\n );\n\n const disabledAt = (position: number) => {\n const row = rows[position];\n return !row || (isDisabled?.(row.node) ?? false);\n };\n\n function select(position: number) {\n const row = rows[position];\n if (!row || !selectionMode || disabledAt(position)) return;\n selected = [...toggleSelection(selected, row.key, { mode: selectionMode })];\n }\n\n function check(position: number) {\n const row = rows[position];\n if (!row || !checkable || disabledAt(position)) return;\n checked = index\n ? toggleChecked(index, checked, row.key)\n : [...toggleSelection(checked, row.key, { mode: 'multiple' })];\n }\n\n function toggle(position: number) {\n const row = rows[position];\n if (row?.expandable)\n void expansion.setOpen(row.node, row.key, !expansion.isExpanded(row.key));\n }\n\n // —— 移动节点(onMove):指针拖动,或 Alt + 方向键 ——\n let dragging = _state<string | undefined>(undefined);\n let drop = _state.raw<DropSpot | null>(null);\n let expandTimer: ReturnType<typeof setTimeout> | undefined;\n let stopDrag: (() => void) | undefined;\n onScopeDispose(() => {\n clearTimeout(expandTimer);\n stopDrag?.();\n });\n\n const rowByKey = (key: string | undefined) =>\n key === undefined ? undefined : rows[rowOf.get(key) ?? -1];\n\n /** key 是不是 ancestor 自己或它的子孙(看得见的行里,祖先总是看得见的) */\n function isWithin(key: string, ancestor: string) {\n for (let at: string | undefined = key; at !== undefined; at = rowByKey(at)?.parent) {\n if (at === ancestor) return true;\n }\n return false;\n }\n\n /** 落点换算成移动的目标(按移走之后的同级算);放不下时 null */\n function targetOf(key: string, spot: DropSpot): TreeMoveTarget | null {\n const moving = rowByKey(key);\n const row = rowByKey(spot.key);\n if (!moving || !row || isWithin(spot.key, key)) return null;\n let target: TreeMoveTarget;\n if (spot.zone === 'inside') target = { parent: row.key, index: Number.MAX_SAFE_INTEGER };\n else {\n const offset = spot.zone === 'before' ? row.position - 1 : row.position;\n // 同一层里从前面移过来:移走之后,后面的都往前挪了一位\n const shift = moving.parent === row.parent && moving.position <= offset ? 1 : 0;\n target = { parent: row.parent, index: offset - shift };\n }\n return canDrop && !canDrop(moving.node, target) ? null : target;\n }\n\n /** 报告移动,并告诉读屏移到了哪里 */\n function emitMove(key: string, target: TreeMoveTarget) {\n const row = rowByKey(key);\n if (!row || !onMove) return;\n const parent = rowByKey(target.parent);\n // 移走之后的同级个数:同一层里移动时要去掉自己\n const count =\n (parent ? (getChildren(parent.node)?.length ?? 0) : items.length) -\n (row.parent === target.parent ? 1 : 0);\n onMove({ key, node: row.node, target });\n announce(\n lang.treeMoved(\n getLabel(row.node),\n parent && getLabel(parent.node),\n Math.min(target.index, count) + 1,\n ),\n );\n }\n\n /** 指针下的落点:一项的上四分之一放在它前面,下四分之一放在后面,中间放进它里面 */\n function spotAt(clientX: number, clientY: number): DropSpot | null {\n const element = document\n .elementFromPoint(clientX, clientY)\n ?.closest<HTMLElement>('[data-index]');\n if (!element || !root?.contains(element)) return null;\n const row = rows[Number(element.dataset.index)];\n if (!row) return null;\n const rect = element.getBoundingClientRect();\n const ratio = (clientY - rect.top) / rect.height;\n return { key: row.key, zone: ratio < 0.25 ? 'before' : ratio > 0.75 ? 'after' : 'inside' };\n }\n\n /** 拖到靠近上下边缘时滚动 */\n function autoScroll(clientY: number) {\n if (!root) return;\n const rect = root.getBoundingClientRect();\n if (clientY < rect.top + 32) root.scrollTop -= 12;\n else if (clientY > rect.bottom - 32) root.scrollTop += 12;\n }\n\n /** 拖到收起的节点里停一会儿:展开它,好放到更深的地方 */\n function scheduleExpand(spot: DropSpot | null) {\n clearTimeout(expandTimer);\n const row = spot?.zone === 'inside' ? rowByKey(spot.key) : undefined;\n if (!row?.expandable || expansion.isExpanded(row.key)) return;\n expandTimer = setTimeout(() => void expansion.setOpen(row.node, row.key, true), 600);\n }\n\n function onItemPointerdown(event: PointerEvent, key: string) {\n // 焦点留在树上\n event.preventDefault();\n // 触摸时照常滚动,不拖\n if (!onMove || event.pointerType === 'touch' || !root) return;\n stopDrag = startMove(event, {\n threshold: 4,\n // 虚拟滚动会换掉行元素:捕获在不动的树上\n captureTarget: root,\n onMove: ({ clientX, clientY }) => {\n dragging = key;\n // 先按当前的位置算落点,再滚动:滚动后指针下面换成了别的项\n const spot = spotAt(clientX, clientY);\n autoScroll(clientY);\n const next = spot && targetOf(key, spot) ? spot : null;\n if (next?.key === drop?.key && next?.zone === drop?.zone) return;\n drop = next;\n scheduleExpand(next);\n },\n onEnd: ({ moved, cancelled }) => {\n const spot = drop;\n dragging = undefined;\n drop = null;\n stopDrag = undefined;\n clearTimeout(expandTimer);\n if (!moved || cancelled || !spot) return;\n const target = targetOf(key, spot);\n if (target) emitMove(key, target);\n },\n });\n }\n\n /** Alt + ↑↓ 在同级里移动,Alt + → 放进上一个同级的最后,Alt + ← 移到父节点后面(从右到左时左右对调) */\n function moveByKey(event: KeyboardEvent): boolean {\n const row = rows[activeRow()];\n if (!row) return false;\n const { forward, backward } = inlineArrows(!!root && isRtl(root));\n let target: TreeMoveTarget | undefined;\n switch (event.key) {\n case 'ArrowUp':\n if (row.position > 1) target = { parent: row.parent, index: row.position - 2 };\n break;\n case 'ArrowDown':\n if (row.position < row.setSize) target = { parent: row.parent, index: row.position };\n break;\n case forward: {\n const previous = rows.find(\n (item) => item.parent === row.parent && item.position === row.position - 1,\n );\n if (!previous) break;\n target = { parent: previous.key, index: Number.MAX_SAFE_INTEGER };\n // 展开新的父节点:移过去之后还看得见\n void expansion.setOpen(previous.node, previous.key, true);\n break;\n }\n case backward: {\n const parent = rowByKey(row.parent);\n if (parent) target = { parent: parent.parent, index: parent.position };\n break;\n }\n default:\n return false;\n }\n if (target && (!canDrop || canDrop(row.node, target))) emitMove(row.key, target);\n return true;\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (event.altKey && onMove && !event.ctrlKey && !event.metaKey) {\n if (moveByKey(event)) event.preventDefault();\n return;\n }\n if (event.altKey || event.ctrlKey || event.metaKey || rows.length === 0) return;\n const position = Math.max(activeRow(), 0);\n const row = rows[position]!;\n const open = row.expandable && expansion.isExpanded(row.key);\n const { forward, backward } = inlineArrows(!!root && isRtl(root));\n const go = (target: number) => (active = rows[target]?.key ?? active);\n switch (event.key) {\n case 'ArrowDown':\n go(Math.min(position + 1, rows.length - 1));\n break;\n case 'ArrowUp':\n go(Math.max(position - 1, 0));\n break;\n case 'Home':\n go(0);\n break;\n case 'End':\n go(rows.length - 1);\n break;\n case forward:\n if (!row.expandable) break;\n if (!open) void expansion.setOpen(row.node, row.key, true);\n // 已展开:进入第一个子节点(子节点还没加载出来时不动)\n else if (rows[position + 1]?.parent === row.key) go(position + 1);\n break;\n case backward:\n if (open) void expansion.setOpen(row.node, row.key, false);\n else if (row.parent !== undefined) active = row.parent;\n break;\n case 'Enter':\n if (selectionMode) select(position);\n else toggle(position);\n break;\n case ' ':\n if (checkable) check(position);\n else select(position);\n break;\n default: {\n const found = typeahead.next(\n event.key,\n rows.map((item) => getLabel(item.node)),\n activeRow(),\n );\n if (found < 0) return;\n go(found);\n }\n }\n event.preventDefault();\n }\n\n function onFocus() {\n focused = true;\n if (active !== undefined && rowOf.has(active)) return;\n // 第一次进入:落在第一个已选的可见节点上,没有时落在第一项\n active = rows.find((row) => selectedSet.has(row.key))?.key ?? rows[0]?.key;\n }\n\n function renderRow(position: number) {\n const row = rows[position]!;\n const open = row.expandable && expansion.isExpanded(row.key);\n const disabled = disabledAt(position);\n const state: TreeItemRenderState = {\n depth: row.depth,\n expanded: open,\n selected: selectedSet.has(row.key),\n checked: states\n ? (states.get(row.key) ?? 'unchecked')\n : checkedSet.has(row.key)\n ? 'checked'\n : 'unchecked',\n active: active === row.key,\n };\n const own = typeof propsItem === 'function' ? propsItem(row.node, state) : propsItem;\n const icon = getIcon?.(row.node, open);\n const loading = expansion.isLoading(row.key);\n const marked = state.checked !== 'unchecked';\n const box = choice();\n const dropZone = drop?.key === row.key ? drop.zone : undefined;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n itemStyles.row,\n itemStyles.hoverable,\n treeStyles.item,\n focused && state.active && itemStyles.highlighted,\n state.selected && itemStyles.current,\n disabled && itemStyles.disabled,\n dragging === row.key && treeStyles.dragging,\n dropZone === 'inside' && treeStyles.dropInside,\n dropZone && dropZone !== 'inside' && treeStyles.positioned,\n ],\n },\n own,\n {\n id: `${prefix()}-${position}`,\n role: 'treeitem',\n 'aria-level': row.depth + 1,\n 'aria-setsize': row.setSize,\n 'aria-posinset': row.position,\n 'aria-expanded': row.expandable ? open : undefined,\n 'aria-selected': selectionMode ? state.selected : undefined,\n 'aria-checked': checkable ? ARIA_CHECKED[state.checked] : undefined,\n 'aria-disabled': disabled || undefined,\n 'aria-busy': loading || undefined,\n onPointerdown: (event: PointerEvent) => onItemPointerdown(event, row.key),\n onClick: () => {\n active = row.key;\n root?.focus({ preventScroll: true });\n if (selectionMode) select(position);\n else if (checkable) check(position);\n else toggle(position);\n },\n },\n )}\n data-state={state.selected ? 'selected' : undefined}\n data-active={state.active || undefined}\n data-disabled={disabled || undefined}\n >\n {row.depth > 0 && <span {...css.attrs(treeDynamicStyles.indent(row.depth * indent))} />}\n <span\n {...mergeAttrs<'span'>({ sx: treeStyles.toggle }, propsToggle, {\n 'aria-hidden': true,\n onClick: (event: MouseEvent) => {\n if (!row.expandable) return;\n event.stopPropagation();\n active = row.key;\n root?.focus({ preventScroll: true });\n toggle(position);\n },\n })}\n >\n {loading ? (\n <Spinner />\n ) : (\n row.expandable && (\n <Icon\n icon={ChevronRight}\n flipInRtl\n sx={[disclosureStyles.icon, open && treeStyles.chevronOpen]}\n />\n )\n )}\n </span>\n {checkable && (\n <span\n {...mergeAttrs<'span'>(\n // 勾选框的实底色取色调变量(同 Checkbox 的 choiceParts)\n { sx: [box.control.sx, toneFillStyles.accent, treeStyles.checkbox] },\n propsCheckbox,\n {\n 'aria-hidden': true,\n onClick: (event: MouseEvent) => {\n event.stopPropagation();\n active = row.key;\n root?.focus({ preventScroll: true });\n check(position);\n },\n },\n )}\n >\n <span\n {...css.attrs(\n box.input.sx,\n focusRingStyles.tight,\n checkboxStyles.box,\n marked && choiceInputStyles.checked,\n )}\n />\n <Icon\n icon={state.checked === 'indeterminate' ? Minus : Check}\n strokeWidth={3}\n sx={[box.indicator.sx, treeStyles.checkMark, !marked && treeStyles.hidden]}\n />\n </span>\n )}\n {icon && <Icon icon={icon} />}\n <span\n {...mergeAttrs<'span'>(\n { sx: [itemStyles.label, filtering?.matched.has(row.key) && treeStyles.matched] },\n propsLabel,\n )}\n >\n {renderItem ? renderItem(row.node, state) : getLabel(row.node)}\n </span>\n {dropZone && dropZone !== 'inside' && (\n <span\n aria-hidden=\"true\"\n {...css.attrs(\n treeStyles.dropLine,\n dropZone === 'before' ? treeStyles.dropBefore : treeStyles.dropAfter,\n treeDynamicStyles.lineStart(row.depth * indent + 1.75),\n )}\n />\n )}\n </div>\n );\n }\n\n /** 没有节点时:加载中是几行骨架,否则是空状态 */\n function renderPlaceholder() {\n if (loading) {\n if (!indicator.value) return null;\n return Array.from({ length: SKELETON_ROWS }, (_, row) => (\n <Skeleton\n key={row}\n {...mergePartProps<SkeletonProps>(\n {\n sx: [treeStyles.skeleton, treeDynamicStyles.width(`${85 - row * 15}%`)],\n delay: row * SHIMMER_STAGGER,\n },\n propsSkeleton,\n )}\n />\n ));\n }\n return (\n empty ?? (\n <Empty\n {...mergePartProps<EmptyProps>(\n {\n size: 'sm',\n icon: false,\n description: filtering ? lang.treeNoMatch : lang.treeEmpty,\n },\n propsEmpty,\n )}\n />\n )\n );\n }\n\n return () => {\n const position = activeRow();\n return (\n <ScrollArea\n {...mergePartProps<ScrollAreaProps>({}, propsScrollArea)}\n focusable={false}\n propsViewport={\n mergeProps<'div'>({ sx: [treeStyles.root, focusRingStyles.visible] }, rest, {\n ref: _toRef(root),\n id: prefix(),\n role: 'tree',\n tabindex: rows.length > 0 ? 0 : -1,\n 'aria-multiselectable': selectionMode === 'multiple' || undefined,\n 'aria-activedescendant': position >= 0 ? `${prefix()}-${position}` : undefined,\n 'aria-busy': loading || undefined,\n onFocus,\n onBlur: () => (focused = false),\n onKeydown,\n }) as PartProps<'div'>\n }\n >\n {rows.length === 0 && renderPlaceholder()}\n <div\n ref={_toRef(sizer)}\n role=\"presentation\"\n {...css.attrs(treeStyles.sizer, treeDynamicStyles.height(virtual.total))}\n >\n {virtual.items.map((item) => (\n <div\n key={item.key}\n {...mergeAttrs<'div'>({ sx: treeStyles.row }, propsRow, {\n ref: virtual.measure,\n role: 'presentation',\n sx: treeDynamicStyles.y(item.start),\n })}\n data-index={item.index}\n >\n {renderRow(item.index)}\n </div>\n ))}\n </div>\n </ScrollArea>\n );\n };\n },\n { name: 'Tree' },\n);\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
2
2
|
import { type VNodeChild } from 'vue';
|
|
3
3
|
import { type SkeletonShapeProps } from '../feedback/Skeleton';
|
|
4
4
|
import { type PartProps } from '../utils/props';
|
|
@@ -9,7 +9,7 @@ import { Progress } from "../feedback/Progress.js";
|
|
|
9
9
|
import { useVirtualizer } from "../utils/virtual/use-virtualizer.js";
|
|
10
10
|
import { Fragment, createVNode, isVNode, shallowRef, watch } from "vue";
|
|
11
11
|
import { _component, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
12
|
-
import
|
|
12
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
13
13
|
//#region src/display/VirtualList.tsx
|
|
14
14
|
/** 跟着谁滚动 */
|
|
15
15
|
/** handle 拿到的方法 */
|