@zerodep-dev/vue-tsx-pro-ui 0.3.0 → 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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
2
2
|
import { type ButtonProps } from '../base/Button';
|
|
3
3
|
import { type ListboxProps } from '../input/Listbox';
|
|
4
4
|
import { type OpenChangeProps } from '../utils/dom/open-change';
|
package/dist/date/TimePicker.js
CHANGED
|
@@ -11,7 +11,7 @@ import { usePickerPopover } from "./picker-popover.js";
|
|
|
11
11
|
import { TimeField, toTime } from "./TimeField.js";
|
|
12
12
|
import { Fragment, computed, createVNode } from "vue";
|
|
13
13
|
import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
14
|
-
import
|
|
14
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
15
15
|
import { Clock } from "@lucide/icons";
|
|
16
16
|
import { Time, now } from "@internationalized/date";
|
|
17
17
|
//#region src/date/TimePicker.tsx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimePicker.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_computed","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/date/TimePicker.tsx"],"sourcesContent":["/**\n * 时间选择器:TimeField 加一个打开时间列表的按钮,按 step 列出可选的时间(同 Google 日历的时间下拉);可以直接键入,也可以点选。\n * 参考 Mantine TimePicker 的 presets、MUI 的 digital clock;列表是 Listbox(↑↓、Home / End、按数字跳转)。\n *\n * <Field label=\"开会时间\"><TimePicker _value={time} min=\"09:00\" max=\"18:00\" /></Field>\n * <TimePicker step={15} _value={time} aria-label=\"提醒时间\" />\n *\n * 值同 TimeField('HH:mm',或 Time)。列表从 min(默认 00:00)起每 step 分钟一项,到 max 为止,按语言的 12 / 24 小时制显示;\n * 不在列表里的时间(14:47)照样能键入;isTimeUnavailable 的时间在列表里不可用、键入时显示出错。\n * 列表下方“此刻”选当前时间(此刻不可选时不可用)。选好后关闭,焦点回到按钮;Esc、点外部关闭,分段里 Alt + ↓ 打开。\n *\n * 部件:同 TimeField,另有 Button(打开按钮)、Popover(弹层)、List(Listbox)、Now(“此刻”按钮)。\n */\nimport { Clock } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { now, Time } from '@internationalized/date';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { useLang } from '../config/context';\nimport { useFormat } from '../config/lang/format';\nimport { useFieldControl } from '../form/Field';\nimport { Listbox, type ListboxProps } from '../input/Listbox';\nimport type { ListboxOption } from '../input/list-state';\nimport { parseIsoTime, toIsoTime } from '../utils/data/date';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { mergePartProps, type PartProps } from '../utils/props';\nimport { useDateLocale } from './date-locale';\nimport { usePickerPopover, type PickerPopoverParts } from './picker-popover';\nimport { TimeField, toTime, type TimeFieldProps, type TimeInput } from './TimeField';\n\n/** 未声明的属性落到这组分段上(主元素);外壳用 propsRoot */\nexport interface TimePickerProps<V extends TimeInput = string>\n extends TimeFieldProps<V>, PickerPopoverParts, OpenChangeProps {\n /** 列表是否打开:父级可写 _open={x} */\n _open?: boolean;\n /** 列表里相邻两项相隔几分钟,默认 30 */\n step?: number;\n /** 时间列表的部件属性 */\n propsList?: Omit<Partial<ListboxProps>, 'items' | '_value' | 'onPick'>;\n /** “此刻”按钮的部件属性 */\n propsNow?: Omit<Partial<ButtonProps>, 'onClick'>;\n}\n\n/** TimePicker 的样式:popover、list、now */\nexport const timePickerStyles = css.create({\n popover: { display: 'flex', flexDirection: 'column', padding: '_xs' },\n // 弹层与输入框同宽,列表最多十来项高,其余滚动\n list: { maxHeight: '16em' },\n now: { marginTop: '_xs' },\n});\n\nconst minutesOf = (time: Time) => time.hour * 60 + time.minute;\n\n/** 时间选择器:分段输入 + 按步长列出的时间 */\nexport const TimePicker = _component(\n <V extends TimeInput>({\n _value: value = _bindable<V | null>(null),\n _open: open = _bindable(false),\n onOpenChange,\n step = 30,\n granularity = 'minute',\n valueType = 'iso',\n min,\n max,\n isTimeUnavailable,\n hourCycle,\n placement,\n id,\n disabled,\n readonly,\n invalid,\n required,\n propsRoot,\n propsButton,\n propsPopover,\n propsList,\n propsNow,\n onKeydown,\n ...rest\n }: TimePickerProps<V>) => {\n const lang = useLang();\n const format = useFormat();\n const locale = useDateLocale();\n // 输入由里面的 TimeField 接 Field;这里只读状态决定能不能打开面板\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }), {\n delegate: true,\n });\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n const picker = usePickerPopover(\n () => ({\n open,\n placement,\n matchWidth: true,\n editable: !control().disabled && !control().readonly,\n label: lang.timePickerOpen,\n size: rest.size,\n }),\n {\n toggle: setOpen,\n shown: (panel) => panel.querySelector<HTMLElement>('[role=\"listbox\"]')?.focus(),\n },\n );\n\n /** 列表的选项:min 到 max,每 step 分钟一项,按语言的小时制显示 */\n const options = _derived.by((): ListboxOption[] => {\n const first = minutesOf(toTime(min) ?? new Time(0, 0));\n const last = minutesOf(toTime(max) ?? new Time(23, 59));\n const result: ListboxOption[] = [];\n for (let minutes = first; minutes <= last; minutes += Math.max(step, 1)) {\n const time = new Time(Math.floor(minutes / 60), minutes % 60);\n const iso = toIsoTime(time);\n result.push({\n value: iso,\n label: format.date(iso, { timeStyle: 'short', hourCycle }),\n disabled: isTimeUnavailable?.(iso, time) ?? false,\n });\n }\n return result;\n });\n\n // 当前值正好是列表里的一项时高亮它(只比时分)\n const selected = _derived.by(() => {\n const time = toTime(value);\n return time ? toIsoTime(time) : undefined;\n });\n\n /** 写回:和当前值同一种类型(Time 或字符串),精确到秒时补 :00 */\n function write(time: Time, event?: Event) {\n const asTime = (value != null && typeof value !== 'string') || valueType === 'dateValue';\n value = (asTime ? time : toIsoTime(time, granularity === 'second')) as V;\n setOpen(false, 'select', event);\n }\n\n /** 此刻(精确到分) */\n const nowTime = () => {\n const current = now(locale.timeZone);\n return new Time(current.hour, current.minute);\n };\n /** 此刻能不能选:在 min–max 之内,不是不可选的时间 */\n function nowAvailable() {\n const time = nowTime();\n const low = toTime(min);\n const high = toTime(max);\n return !(\n (low != null && time.compare(low) < 0) ||\n (high != null && time.compare(high) > 0) ||\n (isTimeUnavailable?.(toIsoTime(time), time) ?? false)\n );\n }\n\n return () => (\n <>\n <TimeField\n {...rest}\n _value={value}\n granularity={granularity}\n valueType={valueType}\n min={min}\n max={max}\n isTimeUnavailable={isTimeUnavailable}\n hourCycle={hourCycle}\n id={id}\n disabled={disabled}\n readonly={readonly}\n invalid={invalid}\n required={required}\n onKeydown={(event) => {\n onKeydown?.(event);\n picker.onKeydown(event);\n }}\n propsRoot={mergePartProps<PartProps<'div'>>({}, propsRoot, { ref: picker.anchorRef })}\n suffix={picker.button(Clock, propsButton)}\n />\n {picker.panel(\n timePickerStyles.popover,\n propsPopover,\n open && [\n <Listbox\n {...mergePartProps<ListboxProps>(\n { sx: timePickerStyles.list, 'aria-label': lang.timePickerOpen, items: options },\n propsList,\n // 在 Field 里时 Listbox 默认取 Field 的控件 id:那是输入框的,列表要自己的 id\n {\n id: `${picker.id}-list`,\n items: options,\n _value: selected,\n onPick: (iso) => write(parseIsoTime(iso)!),\n required: true,\n },\n )}\n />,\n <Button\n {...mergePartProps<ButtonProps>(\n { sx: timePickerStyles.now, variant: 'ghost', size: 'sm', fullWidth: true },\n propsNow,\n {\n disabled: !nowAvailable(),\n onClick: (event: MouseEvent) => write(nowTime(), event),\n },\n )}\n >\n {lang.timePickerNow}\n </Button>,\n ],\n )}\n </>\n );\n },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimePicker.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_computed","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/date/TimePicker.tsx"],"sourcesContent":["/**\n * 时间选择器:TimeField 加一个打开时间列表的按钮,按 step 列出可选的时间(同 Google 日历的时间下拉);可以直接键入,也可以点选。\n * 参考 Mantine TimePicker 的 presets、MUI 的 digital clock;列表是 Listbox(↑↓、Home / End、按数字跳转)。\n *\n * <Field label=\"开会时间\"><TimePicker _value={time} min=\"09:00\" max=\"18:00\" /></Field>\n * <TimePicker step={15} _value={time} aria-label=\"提醒时间\" />\n *\n * 值同 TimeField('HH:mm',或 Time)。列表从 min(默认 00:00)起每 step 分钟一项,到 max 为止,按语言的 12 / 24 小时制显示;\n * 不在列表里的时间(14:47)照样能键入;isTimeUnavailable 的时间在列表里不可用、键入时显示出错。\n * 列表下方“此刻”选当前时间(此刻不可选时不可用)。选好后关闭,焦点回到按钮;Esc、点外部关闭,分段里 Alt + ↓ 打开。\n *\n * 部件:同 TimeField,另有 Button(打开按钮)、Popover(弹层)、List(Listbox)、Now(“此刻”按钮)。\n */\nimport { Clock } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { now, Time } from '@internationalized/date';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { useLang } from '../config/context';\nimport { useFormat } from '../config/lang/format';\nimport { useFieldControl } from '../form/Field';\nimport { Listbox, type ListboxProps } from '../input/Listbox';\nimport type { ListboxOption } from '../input/list-state';\nimport { parseIsoTime, toIsoTime } from '../utils/data/date';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { mergePartProps, type PartProps } from '../utils/props';\nimport { useDateLocale } from './date-locale';\nimport { usePickerPopover, type PickerPopoverParts } from './picker-popover';\nimport { TimeField, toTime, type TimeFieldProps, type TimeInput } from './TimeField';\n\n/** 未声明的属性落到这组分段上(主元素);外壳用 propsRoot */\nexport interface TimePickerProps<V extends TimeInput = string>\n extends TimeFieldProps<V>, PickerPopoverParts, OpenChangeProps {\n /** 列表是否打开:父级可写 _open={x} */\n _open?: boolean;\n /** 列表里相邻两项相隔几分钟,默认 30 */\n step?: number;\n /** 时间列表的部件属性 */\n propsList?: Omit<Partial<ListboxProps>, 'items' | '_value' | 'onPick'>;\n /** “此刻”按钮的部件属性 */\n propsNow?: Omit<Partial<ButtonProps>, 'onClick'>;\n}\n\n/** TimePicker 的样式:popover、list、now */\nexport const timePickerStyles = css.create({\n popover: { display: 'flex', flexDirection: 'column', padding: '_xs' },\n // 弹层与输入框同宽,列表最多十来项高,其余滚动\n list: { maxHeight: '16em' },\n now: { marginTop: '_xs' },\n});\n\nconst minutesOf = (time: Time) => time.hour * 60 + time.minute;\n\n/** 时间选择器:分段输入 + 按步长列出的时间 */\nexport const TimePicker = _component(\n <V extends TimeInput>({\n _value: value = _bindable<V | null>(null),\n _open: open = _bindable(false),\n onOpenChange,\n step = 30,\n granularity = 'minute',\n valueType = 'iso',\n min,\n max,\n isTimeUnavailable,\n hourCycle,\n placement,\n id,\n disabled,\n readonly,\n invalid,\n required,\n propsRoot,\n propsButton,\n propsPopover,\n propsList,\n propsNow,\n onKeydown,\n ...rest\n }: TimePickerProps<V>) => {\n const lang = useLang();\n const format = useFormat();\n const locale = useDateLocale();\n // 输入由里面的 TimeField 接 Field;这里只读状态决定能不能打开面板\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }), {\n delegate: true,\n });\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n const picker = usePickerPopover(\n () => ({\n open,\n placement,\n matchWidth: true,\n editable: !control().disabled && !control().readonly,\n label: lang.timePickerOpen,\n size: rest.size,\n }),\n {\n toggle: setOpen,\n shown: (panel) => panel.querySelector<HTMLElement>('[role=\"listbox\"]')?.focus(),\n },\n );\n\n /** 列表的选项:min 到 max,每 step 分钟一项,按语言的小时制显示 */\n const options = _derived.by((): ListboxOption[] => {\n const first = minutesOf(toTime(min) ?? new Time(0, 0));\n const last = minutesOf(toTime(max) ?? new Time(23, 59));\n const result: ListboxOption[] = [];\n for (let minutes = first; minutes <= last; minutes += Math.max(step, 1)) {\n const time = new Time(Math.floor(minutes / 60), minutes % 60);\n const iso = toIsoTime(time);\n result.push({\n value: iso,\n label: format.date(iso, { timeStyle: 'short', hourCycle }),\n disabled: isTimeUnavailable?.(iso, time) ?? false,\n });\n }\n return result;\n });\n\n // 当前值正好是列表里的一项时高亮它(只比时分)\n const selected = _derived.by(() => {\n const time = toTime(value);\n return time ? toIsoTime(time) : undefined;\n });\n\n /** 写回:和当前值同一种类型(Time 或字符串),精确到秒时补 :00 */\n function write(time: Time, event?: Event) {\n const asTime = (value != null && typeof value !== 'string') || valueType === 'dateValue';\n value = (asTime ? time : toIsoTime(time, granularity === 'second')) as V;\n setOpen(false, 'select', event);\n }\n\n /** 此刻(精确到分) */\n const nowTime = () => {\n const current = now(locale.timeZone);\n return new Time(current.hour, current.minute);\n };\n /** 此刻能不能选:在 min–max 之内,不是不可选的时间 */\n function nowAvailable() {\n const time = nowTime();\n const low = toTime(min);\n const high = toTime(max);\n return !(\n (low != null && time.compare(low) < 0) ||\n (high != null && time.compare(high) > 0) ||\n (isTimeUnavailable?.(toIsoTime(time), time) ?? false)\n );\n }\n\n return () => (\n <>\n <TimeField\n {...rest}\n _value={value}\n granularity={granularity}\n valueType={valueType}\n min={min}\n max={max}\n isTimeUnavailable={isTimeUnavailable}\n hourCycle={hourCycle}\n id={id}\n disabled={disabled}\n readonly={readonly}\n invalid={invalid}\n required={required}\n onKeydown={(event) => {\n onKeydown?.(event);\n picker.onKeydown(event);\n }}\n propsRoot={mergePartProps<PartProps<'div'>>({}, propsRoot, { ref: picker.anchorRef })}\n suffix={picker.button(Clock, propsButton)}\n />\n {picker.panel(\n timePickerStyles.popover,\n propsPopover,\n open && [\n <Listbox\n {...mergePartProps<ListboxProps>(\n { sx: timePickerStyles.list, 'aria-label': lang.timePickerOpen, items: options },\n propsList,\n // 在 Field 里时 Listbox 默认取 Field 的控件 id:那是输入框的,列表要自己的 id\n {\n id: `${picker.id}-list`,\n items: options,\n _value: selected,\n onPick: (iso) => write(parseIsoTime(iso)!),\n required: true,\n },\n )}\n />,\n <Button\n {...mergePartProps<ButtonProps>(\n { sx: timePickerStyles.now, variant: 'ghost', size: 'sm', fullWidth: true },\n propsNow,\n {\n disabled: !nowAvailable(),\n onClick: (event: MouseEvent) => write(nowTime(), event),\n },\n )}\n >\n {lang.timePickerNow}\n </Button>,\n ],\n )}\n </>\n );\n },\n);\n"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* {picker.panel(sx, propsPopover, open && <Calendar … />)}
|
|
12
12
|
*/
|
|
13
13
|
import { type VNodeChild } from 'vue';
|
|
14
|
-
import
|
|
14
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
15
15
|
import type { IconData } from '../base/Icon';
|
|
16
16
|
import { type IconButtonProps } from '../base/IconButton';
|
|
17
17
|
import { type FloatingPlacement } from '../utils/dom/floating';
|
|
@@ -8,7 +8,7 @@ import { anchoredPanelSx, useAnchoredPopover } from "../utils/dom/floating.js";
|
|
|
8
8
|
import { inputRecipe } from "../input/control.js";
|
|
9
9
|
import { createVNode, shallowRef, useId } from "vue";
|
|
10
10
|
import { mergeJsxProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
11
|
-
import
|
|
11
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
12
12
|
//#region src/date/picker-popover.tsx
|
|
13
13
|
/** 选择器上的打开按钮与弹层的部件属性 */
|
|
14
14
|
/** usePickerPopover 每次渲染读取的状态 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"picker-popover.js","names":["_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/date/picker-popover.tsx"],"sourcesContent":["/**\n * 日期、时间选择器共用的打开按钮与弹层(DatePicker、DateRangePicker、TimePicker),以及日历旁边的快捷选项:\n * 输入框外壳是定位的锚点,后缀里的按钮打开,弹层是 role=\"dialog\" 的原生 popover(Esc、点外部关闭);\n * 关闭时焦点还给按钮(外壳不可聚焦);分段里按 Alt + ↓ 打开(同原生 select)。在组件 setup 里调用。\n *\n * const picker = usePickerPopover(() => ({ open, editable, label: lang.datePickerOpen }), {\n * toggle: setOpen,\n * shown: (panel) => panel.querySelector('…')?.focus(),\n * });\n * <DateField propsRoot={{ ref: picker.anchorRef }} onKeydown={picker.onKeydown} suffix={picker.button(CalendarDays, propsButton)} />\n * {picker.panel(sx, propsPopover, open && <Calendar … />)}\n */\nimport { useId, type VNodeChild } from 'vue';\nimport
|
|
1
|
+
{"version":3,"file":"picker-popover.js","names":["_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/date/picker-popover.tsx"],"sourcesContent":["/**\n * 日期、时间选择器共用的打开按钮与弹层(DatePicker、DateRangePicker、TimePicker),以及日历旁边的快捷选项:\n * 输入框外壳是定位的锚点,后缀里的按钮打开,弹层是 role=\"dialog\" 的原生 popover(Esc、点外部关闭);\n * 关闭时焦点还给按钮(外壳不可聚焦);分段里按 Alt + ↓ 打开(同原生 select)。在组件 setup 里调用。\n *\n * const picker = usePickerPopover(() => ({ open, editable, label: lang.datePickerOpen }), {\n * toggle: setOpen,\n * shown: (panel) => panel.querySelector('…')?.focus(),\n * });\n * <DateField propsRoot={{ ref: picker.anchorRef }} onKeydown={picker.onKeydown} suffix={picker.button(CalendarDays, propsButton)} />\n * {picker.panel(sx, propsPopover, open && <Calendar … />)}\n */\nimport { useId, type VNodeChild } from 'vue';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Button } from '../base/Button';\nimport type { IconData } from '../base/Icon';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useRecipe } from '../config/styles';\nimport { inputRecipe } from '../input/control';\nimport { anchoredPanelSx, useAnchoredPopover, type FloatingPlacement } from '../utils/dom/floating';\nimport { focusFirst } from '../utils/dom/focus';\nimport type { SetOpen } from '../utils/dom/open-change';\nimport { toElement } from '../utils/dom/element';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport type { TextSize } from '../utils/style/typography';\n\n/** 选择器上的打开按钮与弹层的部件属性 */\nexport interface PickerPopoverParts {\n /** 弹出位置,默认 bottom-start;空间不够时自动翻转 */\n placement?: FloatingPlacement;\n /** 打开按钮的部件属性 */\n propsButton?: Omit<Partial<IconButtonProps>, 'onClick' | 'aria-expanded' | 'aria-controls'>;\n /** 弹层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover' | 'role'>;\n}\n\n/** usePickerPopover 每次渲染读取的状态 */\nexport interface PickerPopoverState {\n /** 是否打开 */\n open: boolean;\n /** 能不能打开:不可用、只读时按钮也不可用 */\n editable: boolean;\n /** 按钮与弹层的名称(“选择日期”) */\n label: string;\n /** 弹出位置 */\n placement?: FloatingPlacement;\n /** 弹层与输入框同宽(时间列表) */\n matchWidth?: boolean;\n /** 控件的字号档位:弹层渲染在顶层、不继承输入框的字号,按它设置 */\n size?: TextSize;\n}\n\n/** usePickerPopover 的回调 */\nexport interface PickerPopoverEvents {\n /** 打开或关闭(按钮、Alt + ↓、Esc、点外部):写回组件的 open 并通知 onOpenChange,一般是组件的 openSetter */\n toggle: SetOpen;\n /** 打开后、第一次定位完成时:把焦点交给弹层里合适的元素 */\n shown: (panel: HTMLElement) => void;\n}\n\n/** 选择器的打开按钮与弹层 */\nexport function usePickerPopover(read: () => PickerPopoverState, events: PickerPopoverEvents) {\n const id = useId();\n let anchor = _state.raw<HTMLElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n let trigger = _state.raw<HTMLElement | null>(null);\n // 打开按钮放在输入框外壳里:用外壳配方的 button 部件(带 styles.Input 的定制)\n const shell = useRecipe(inputRecipe);\n\n const { onToggle } = useAnchoredPopover(\n () => {\n const { open, placement = 'bottom-start', matchWidth } = read();\n return { open, anchor, panel, floating: { placement, matchWidth }, restoreFocus: trigger };\n },\n { close: (reason, event) => events.toggle(false, reason, event), shown: events.shown },\n );\n\n return {\n /** 弹层的 id(按钮的 aria-controls);弹层里的元素可以据此派生自己的 id */\n id,\n /** 输入框外壳(锚点):放进 propsRoot 的 ref */\n anchorRef: (element: unknown) => (anchor = toElement(element)),\n /** 输入框外壳:选完日期后把焦点交给其中的某一段 */\n get anchor() {\n return anchor;\n },\n /** 分段上的 keydown:Alt + ↓ 打开 */\n onKeydown: (event: KeyboardEvent) => {\n if (!event.altKey || event.key !== 'ArrowDown' || !read().editable) return;\n event.preventDefault();\n events.toggle(true, 'trigger', event);\n },\n /** 输入框后缀里的打开按钮 */\n button(icon: IconData, user?: PickerPopoverParts['propsButton']) {\n const { open, editable, label } = read();\n return (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n { ...shell().button, radius: 'full', icon, 'aria-label': label },\n user,\n {\n ref: (element: unknown) => (trigger = toElement(element)),\n disabled: !editable,\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n 'aria-controls': id,\n onClick: (event: MouseEvent) => events.toggle(!open, 'trigger', event),\n },\n )}\n />\n );\n },\n /** 弹层:内容只在打开时渲染(由调用方按 open 给) */\n panel(sx: css.SxStyles, user: PickerPopoverParts['propsPopover'], children: VNodeChild) {\n const { open, label, size } = read();\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [anchoredPanelSx(size), sx],\n 'aria-label': label,\n },\n user,\n { ref: _toRef(panel), id, popover: 'auto', role: 'dialog', onToggle },\n )}\n data-state={open ? 'open' : 'closed'}\n >\n {children}\n </div>\n );\n },\n };\n}\n\n/** 弹层里是日历时:焦点进日历当前的那一格(已选或今天),不是“上个月”按钮 */\nexport function focusCalendar(panel: HTMLElement): void {\n const cell = panel.querySelector<HTMLElement>('[role=\"grid\"] [tabindex=\"0\"]');\n if (cell) cell.focus();\n else focusFirst(panel);\n}\n\n/** 弹层里的一个快捷选项(“今天”“最近 7 天”) */\nexport interface PickerPreset {\n /** 列表里的 key */\n key: string;\n /** 按钮上的文字 */\n label: string;\n /** 当前值就是它:按钮按下(aria-pressed) */\n active: boolean;\n /** 超出可选范围:不可用 */\n disabled?: boolean;\n /** 点了 */\n onPick: () => void;\n}\n\n/** 快捷选项的样式:presets(一列,靠日历那边有分隔线)、preset(按钮文字靠左) */\nexport const pickerPresetStyles = css.create({\n presets: {\n display: 'flex',\n flexDirection: 'column',\n gap: '_xs',\n paddingInlineEnd: '_sm',\n borderInlineEndWidth: '_xs',\n borderInlineEndStyle: 'solid',\n borderInlineEndColor: '_borderMuted',\n },\n preset: { justifyContent: 'flex-start' },\n});\n\n/** 日历旁边的一列快捷选项(DatePicker、DateRangePicker 共用):一组按钮,当前值对应的那一项按下 */\nexport function renderPickerPresets(\n presets: readonly PickerPreset[],\n label: string,\n user?: PartProps<'div', 'role'>,\n): VNodeChild {\n if (presets.length === 0) return null;\n return (\n <div\n {...mergeAttrs<'div'>({ sx: pickerPresetStyles.presets }, user, {\n role: 'group',\n 'aria-label': label,\n })}\n >\n {presets.map((preset) => (\n <Button\n key={preset.key}\n sx={pickerPresetStyles.preset}\n size=\"sm\"\n variant={preset.active ? 'soft' : 'ghost'}\n tone=\"neutral\"\n aria-pressed={preset.active}\n disabled={preset.disabled}\n onClick={preset.onPick}\n >\n {preset.label}\n </Button>\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6DA,SAAgB,iBAAiB,MAAgC,QAA6B;CAC5F,MAAM,KAAK,MAAM;CACjB,IAAI,SAAMA,WAAkC,IAAI;CAChD,IAAI,QAAKA,WAAkC,IAAI;CAC/C,IAAI,UAAOA,WAAkC,IAAI;CAEjD,MAAM,QAAQ,UAAU,WAAW;CAEnC,MAAM,EAAE,aAAa,yBACb;EACJ,MAAM,EAAE,MAAM,YAAY,gBAAgB,eAAe,KAAK;EAC9D,OAAO;GAAE;GAAM,QAAM,OAAA;GAAE,OAAK,MAAA;GAAE,UAAU;IAAE;IAAW;GAAW;GAAG,cAAY,QAAA;EAAU;CAC3F,GACA;EAAE,QAAQ,QAAQ,UAAU,OAAO,OAAO,OAAO,QAAQ,KAAK;EAAG,OAAO,OAAO;CAAM,CACvF;CAEA,OAAO;;EAEL;;EAEA,YAAY,YAAsB,OAAA,QAAS,UAAU,OAAO;;EAE5D,IAAI,SAAS;GACX,OAAA,OAAA;EACF;;EAEA,YAAY,UAAyB;GACnC,IAAI,CAAC,MAAM,UAAU,MAAM,QAAQ,eAAe,CAAC,KAAK,CAAC,CAAC,UAAU;GACpE,MAAM,eAAe;GACrB,OAAO,OAAO,MAAM,WAAW,KAAK;EACtC;;EAEA,OAAO,MAAgB,MAA0C;GAC/D,MAAM,EAAE,MAAM,UAAU,UAAU,KAAK;GACvC,OAAAC,YAAA,YAEQ,eACF;IAAE,GAAG,MAAM,CAAC,CAAC;IAAQ,QAAQ;IAAQ;IAAM,cAAc;GAAM,GAC/D,MACA;IACE,MAAM,YAAsB,QAAA,QAAU,UAAU,OAAO;IACvD,UAAU,CAAC;IACX,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,UAAU,UAAsB,OAAO,OAAO,CAAC,MAAM,WAAW,KAAK;GACvE,CACF,GAAC,IAAA;EAGP;;EAEA,MAAM,IAAkB,MAA0C,UAAsB;GACtF,MAAM,EAAE,MAAM,OAAO,SAAS,KAAK;GACnC,OAAAA,YAAA,OAAAC,cAEQ,WACF;IACE,IAAI,CAAC,gBAAgB,IAAI,GAAG,EAAE;IAC9B,cAAc;GAChB,GACA,MACA;IAAE,KAAG;IAAiB;IAAI,SAAS;IAAQ,MAAM;IAAU;GAAS,CACtE,GAAC,EAAA,cACW,OAAO,SAAS,SAAQ,CAAA,GAAA,CAEnC,QAAQ,CAAA;EAGf;CACF;AACF;;AAGA,SAAgB,cAAc,OAA0B;CACtD,MAAM,OAAO,MAAM,cAA2B,kCAA8B;CAC5E,IAAI,MAAM,KAAK,MAAM;MAChB,WAAW,KAAK;AACvB;;;AAiBA,IAAa,qBAAqB,IAAI,OAAO;CAC3C,SAAS;EACP,SAAS;EACT,eAAe;EACf,KAAK;EACL,kBAAkB;EAClB,sBAAsB;EACtB,sBAAsB;EACtB,sBAAsB;CACxB;CACA,QAAQ,EAAE,gBAAgB,aAAa;AACzC,CAAC;;AAGD,SAAgB,oBACd,SACA,OACA,MACY;CACZ,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,OAAAD,YAAA,OAEQ,WAAkB,EAAE,IAAI,mBAAmB,QAAQ,GAAG,MAAM;EAC9D,MAAM;EACN,cAAc;CAChB,CAAC,GAAC,CAED,QAAQ,KAAK,WAAMA,YAAA,QAAA;EAAA,OAEX,OAAO;EAAG,MACX,mBAAmB;EAAM,QAAA;EAAA,WAEpB,OAAO,SAAS,SAAS;EAAO,QAAA;EAAA,gBAE3B,OAAO;EAAM,YACjB,OAAO;EAAQ,WAChB,OAAO;CAAM,GAAA,EAAA,eAAA,CAErB,OAAO,KAAK,EAAA,CAAA,CAEhB,CAAC,CAAA;AAGR"}
|
|
@@ -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 PartProps } from '../utils/props';
|
|
4
4
|
import type { StatusTone } from '../utils/style/tone-styles';
|
package/dist/diagram/Diagram.js
CHANGED
|
@@ -11,7 +11,7 @@ import { diagramMessages } from "./messages.js";
|
|
|
11
11
|
import { nearestSide, routeEdges, sidePoint, straightRoute } from "./route.js";
|
|
12
12
|
import { computed, createVNode, shallowRef } from "vue";
|
|
13
13
|
import { _component, bindable, childrenProp, createContext, mergeJsxProps, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
14
|
-
import
|
|
14
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
15
15
|
//#region src/diagram/Diagram.tsx
|
|
16
16
|
/** 画布上的一个节点:位置与大小(画布坐标),其余字段使用方自己用 */
|
|
17
17
|
/** 画布上的一条连线 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diagram.js","names":["_vtp_readonlyProp","_createVNode","_mergeProps","_vtp_childrenProp","_vtp_bindable","_vtp_restProps","_vtp_untrack","_vue_shallowRef","_vue_computed"],"sources":["../../src/diagram/Diagram.tsx"],"sourcesContent":["/**\n * 画布:在一块能平移、缩放的视口里摆放节点(HTML)与连线(SVG)。流程图、组织架构图、关系图都建在它上面:\n * 画布负责定位、视口、选择、拖动、连线与焦点;节点默认画成 DiagramNode(标题是 getNodeLabel),\n * 要别的样子时 children 给渲染函数,常见的是换 DiagramNode 的属性(说明、图标、色调、形状)。\n *\n * let selection = _state<DiagramSelection>({ nodes: [], edges: [] });\n * <Diagram nodes={nodes} edges={edges} getNodeLabel={(node) => node.name} selectable _selected={selection} fitView aria-label=\"组织架构\">\n * {(node) => <DiagramNode title={node.name} description={node.title} />}\n * </Diagram>\n *\n * - 视口(见 useDiagram):滚轮平移,按住 Ctrl / ⌘ 或触控板捏合缩放;拖动空白处平移,dragMode=\"select\" 时改为框选、\n * 按住空格再拖动才平移;视口有焦点时方向键平移、+ / − 缩放、0 回到适应内容。fitView 在第一次有尺寸时把内容放进视口。\n * - 选择(selectable):点节点或连线选中它,按住 Shift / Ctrl / ⌘ 再点加选或取消;按住 Shift 拖动空白处框选\n * (selectionMode:整个框住才算,或碰到就算),按住 Ctrl / ⌘ 时框到的加进原来的选择;点空白处、Esc 清空,\n * Ctrl / ⌘ + A 全选。_selected 双向绑定。\n * - 拖动(draggable):拖节点(选中的一起拖),snapToGrid 吸附网格,guides 与别的节点对齐时吸过去并画对齐线,\n * 拖到视口边上自动平移,Esc 取消;聚焦的节点按方向键挪一步(Shift 五步)。位置由使用方保存:松开后 onNodesMove 给出新位置。\n * - 连线(connectable):悬停或选中的节点四条边上出现端口,从端口拖到另一个节点上松开调用 onConnect;\n * 选中的连线两端出现把手,拖到别的节点上调用 onReconnect。canConnect 决定能不能连,不能连的节点不高亮。\n * - 连线的画法:points 是折线(排布、路由的结果),没给时按 routing 画:straight 是两个节点之间的直线,\n * orthogonal 是绕开节点的正交折线(routeEdges);拖动时相连的线按 routing 实时重画。终点画箭头,拐角是圆角;\n * 连线的 tone 改线与文字的颜色(退回、驳回用 danger),dashed 画虚线。backdrop 里放泳道 DiagramLanes。\n * - 键盘:节点(可选择时连线也是)按数组顺序用 Tab 聚焦,Enter / 空格选中;键盘聚焦到视口外的节点时自动平移过去。\n * 拖动、连线都有不用指针的做法:方向键挪节点,连线交给设计器的属性面板(WCAG 2.5.7)。\n * - overlay 里的内容(DiagramControls、DiagramMinimap、图例)浮在最上面、不随视口动,经 DiagramContext 拿到控制器。\n * 部件:Root(视口)、World(随视口平移缩放的一层)、Node(节点框)、Port(端口)、Edge(每条连线的 g)、EdgeText(连线上的文字)、\n * Marquee(框选框)、Guide(对齐线)。\n */\nimport { _component, createContext } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useMessages } from '../config/lang/messages';\nimport { t } from '../config/theme/tokens';\nimport { startMove } from '../utils/dom/move';\nimport { useResizeObserver } from '../utils/dom/resize';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\nimport { interactionTransitions } from '../utils/style/transitions';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport { diagramInternals, useDiagram, type DiagramController } from './controller';\nimport { DiagramNode } from './DiagramNode';\nimport {\n alignToGuides,\n arrowHead,\n boundsOf,\n polylineMidpoint,\n polylinePath,\n rectAt,\n rectContains,\n rectFromCorners,\n rectsIntersect,\n trimEnd,\n type DiagramGuide,\n type DiagramPoint,\n type DiagramRect,\n} from './geometry';\nimport { diagramMessages } from './messages';\nimport { nearestSide, routeEdges, sidePoint, straightRoute, type DiagramSide } from './route';\n\n/** 画布上的一个节点:位置与大小(画布坐标),其余字段使用方自己用 */\nexport interface DiagramNodeItem extends DiagramRect {\n /** 节点的标识:连线的 from、to 与选择里用它 */\n id: string;\n}\n\n/** 画布上的一条连线 */\nexport interface DiagramEdgeItem {\n /** 连线的标识 */\n id: string;\n /** 起点节点 */\n from: string;\n /** 终点节点 */\n to: string;\n /** 折线经过的点(画布坐标,含两端);不给时按 routing 画 */\n points?: readonly DiagramPoint[];\n /** 从起点的哪条边出去(routing=\"orthogonal\" 时用);不写时自动选 */\n fromSide?: DiagramSide;\n /** 从终点的哪条边进来;不写时自动选 */\n toSide?: DiagramSide;\n /** 连线文字的位置;不给时放在折线走到一半的地方 */\n labelAt?: DiagramPoint;\n /** 色调:线、箭头与连线文字的颜色(退回、驳回用 danger,走过的路径用 success),默认中性的灰 */\n tone?: StatusTone;\n /** 画成虚线:可选的、还没生效的连线 */\n dashed?: boolean;\n}\n\n/** 选中的节点与连线(标识) */\nexport interface DiagramSelection {\n /** 选中的节点 */\n readonly nodes: readonly string[];\n /** 选中的连线 */\n readonly edges: readonly string[];\n}\n\n/** 节点、连线渲染时的状态 */\nexport interface DiagramItemState {\n /** 已选中 */\n readonly selected: boolean;\n}\n\n/** 拖动结束后一个节点的新位置 */\nexport interface DiagramNodeMove {\n /** 节点的标识 */\n readonly id: string;\n /** 新的横坐标 */\n readonly x: number;\n /** 新的纵坐标 */\n readonly y: number;\n}\n\n/** 从端口拖出的一条新连线 */\nexport interface DiagramConnection {\n /** 起点节点 */\n readonly from: string;\n /** 终点节点 */\n readonly to: string;\n /** 从起点的哪条边出去 */\n readonly fromSide: DiagramSide;\n /** 从终点的哪条边进来(松开时离指针最近的边) */\n readonly toSide: DiagramSide;\n}\n\n/** 拖动连线的一端改接到别的节点 */\nexport interface DiagramReconnection {\n /** 连线的标识 */\n readonly edge: string;\n /** 改的是哪一端 */\n readonly end: 'from' | 'to';\n /** 改接到的节点 */\n readonly node: string;\n /** 从这个节点的哪条边进出 */\n readonly side: DiagramSide;\n}\n\n/** 拖动空白处做什么 */\nexport interface DiagramDragModes {\n /** 平移视口;按住 Shift 拖动是框选(看图为主:流程图、组织架构图) */\n pan: unknown;\n /** 框选;按住空格拖动、滚轮平移(编辑为主:设计器) */\n select: unknown;\n}\n\n/** 框选时怎样算选中 */\nexport interface DiagramSelectionModes {\n /** 整个在框里才选中 */\n full: unknown;\n /** 碰到框就选中 */\n partial: unknown;\n}\n\n/** 背景的网格 */\nexport interface DiagramGrids {\n /** 不画 */\n none: unknown;\n /** 点阵(设计器) */\n dots: unknown;\n /** 线格 */\n lines: unknown;\n}\n\n/** 没给折线的连线怎样画 */\nexport interface DiagramRoutings {\n /** 两个节点之间的直线,两端落在边框上 */\n straight: unknown;\n /** 绕开节点的正交折线(横竖两个方向,拐弯少,同一条边上的几条线排开) */\n orthogonal: unknown;\n}\n\n/** 未声明的属性落到视口(Root)上:aria-label 写画布画的是什么 */\nexport interface DiagramProps<\n N extends DiagramNodeItem,\n E extends DiagramEdgeItem,\n> extends PartProps<'div', 'role' | 'tabindex' | 'draggable'> {\n /** 节点:位置与大小由使用方给(排布的结果或用户摆的位置) */\n nodes: readonly N[];\n /** 连线 */\n edges?: readonly E[];\n /** 节点的内容:节点框(定位、选中、焦点)由画布画,里面画什么由这里给,内容拉伸到节点的大小。默认是标题为 getNodeLabel 的 DiagramNode */\n children?: (node: N, state: DiagramItemState) => VNodeChild;\n /** 节点的无障碍名称(读屏念的;连线的默认名称“从 A 到 B”也用它)。节点里画了文字时按同样的先后写进来(如“姓名,岗位”),语音控制才能按看得见的字找到它 */\n getNodeLabel: (node: N) => string;\n /** 连线的无障碍名称,默认“从 A 到 B” */\n getEdgeLabel?: (edge: E) => string;\n /** 连线上的文字(处理结果、条件);返回空时不画 */\n edgeText?: (edge: E, state: DiagramItemState) => VNodeChild;\n /**\n * 视口的高(数字是 px)\n * @default 360\n */\n height?: number | string;\n /** 控制器(useDiagram):画布外的按钮要缩放、适应内容时传进来;不传时画布自己建一个 */\n controller?: DiagramController;\n /** 节点与连线可以点选、框选 */\n selectable?: boolean;\n /** 选中的节点与连线:父级写 _selected={selection} 双向绑定 */\n _selected?: DiagramSelection;\n /** 拖动空白处做什么,默认 pan */\n dragMode?: keyof DiagramDragModes;\n /** 框选时怎样算选中,默认 full */\n selectionMode?: keyof DiagramSelectionModes;\n /** 背景的网格,默认 none */\n grid?: keyof DiagramGrids;\n /** 网格的间距(画布坐标),默认 20;snapToGrid 也按它吸附 */\n gridSize?: number;\n /** 第一次有尺寸时把全部内容放进视口(不超过原大);用户动过视口之前,尺寸变了也重新适应。默认 false:从原点、原大开始 */\n fitView?: boolean;\n /** 内容的范围(画布坐标):适应画布按它算。默认包住全部节点与连线;backdrop 比节点占得大时(泳道)写上它 */\n extent?: DiagramRect;\n /** 没给折线的连线怎样画,默认 straight;拖动时相连的线也按它重画 */\n routing?: keyof DiagramRoutings;\n /** 折线拐角的圆角半径,默认 6;0 为直角 */\n edgeRadius?: number;\n /** 节点可以拖动(可以按节点判断);松开后 onNodesMove 给出新位置 */\n draggable?: boolean | ((node: N) => boolean);\n /** 拖动、方向键挪动时吸附到网格(gridSize) */\n snapToGrid?: boolean;\n /** 拖动时与别的节点的边、中线对齐就吸过去并画对齐线,默认 true */\n guides?: boolean;\n /** 拖动或方向键挪动后节点的新位置:使用方写回自己的数据(顺带记一步撤销) */\n onNodesMove?: (moves: DiagramNodeMove[]) => void;\n /** 能从节点的端口拖出连线;选中的连线两端可以拖去改接 */\n connectable?: boolean;\n /** 能不能从 from 连到 to(拖动时只高亮能连的节点);默认除了自己都能连 */\n canConnect?: (from: N, to: N) => boolean;\n /** 从端口拖出连线、在另一个节点上松开 */\n onConnect?: (connection: DiagramConnection) => void;\n /** 拖动选中连线的一端、在别的节点上松开 */\n onReconnect?: (change: DiagramReconnection) => void;\n /** 画在连线下面、随视口平移缩放的内容(画布坐标的 HTML):泳道、分区、背景标注 */\n backdrop?: VNodeChild;\n /** 浮在最上面、不随视口动的内容(视口坐标):缩放按钮 DiagramControls、小地图 DiagramMinimap、图例 */\n overlay?: VNodeChild;\n /** 随视口平移缩放的那一层的部件属性 */\n propsWorld?: PartProps<'div'>;\n /** 节点框的部件属性,可以按节点计算 */\n propsNode?: PartProps<'div'> | ((node: N, state: DiagramItemState) => PartProps<'div'>);\n /** 端口的部件属性 */\n propsPort?: PartProps<'span'>;\n /** 连线(g)的部件属性,可以按连线计算(颜色、虚线用连线的 tone、dashed) */\n propsEdge?: PartProps<'g'> | ((edge: E, state: DiagramItemState) => PartProps<'g'>);\n /** 连线文字的部件属性,可以按连线计算 */\n propsEdgeText?: PartProps<'div'> | ((edge: E, state: DiagramItemState) => PartProps<'div'>);\n /** 框选框的部件属性 */\n propsMarquee?: PartProps<'div'>;\n /** 对齐线的部件属性 */\n propsGuide?: PartProps<'line'>;\n}\n\n/** 画布里的部件(DiagramControls、DiagramMinimap)取控制器 */\nexport const DiagramContext = createContext<DiagramController>('Diagram');\n\n/** 箭头的长度(画布坐标) */\nconst ARROW = 9;\n/** 网格的间距在屏幕上小于这么多 px 时放大四倍,缩得很小时不糊成一片 */\nconst MIN_GRID = 8;\n/** 对齐线吸附的距离(屏幕 px) */\nconst GUIDE_TOLERANCE = 6;\n/** 拖到离视口边多近开始自动平移(px) */\nconst EDGE_PAN = 32;\n/** 没吸附网格时方向键一次挪多少(画布坐标) */\nconst NUDGE = 8;\nconst NO_SELECTION: DiagramSelection = { nodes: [], edges: [] };\nconst SIDES: readonly DiagramSide[] = ['top', 'right', 'bottom', 'left'];\n\n/** Diagram 的样式 */\nexport const diagramStyles = css.create({\n root: {\n position: 'relative',\n overflow: 'hidden',\n backgroundColor: '_surface',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_border',\n borderRadius: '_md',\n fontSize: '_sm',\n color: '_text',\n // 画布上点选、框选、按着 Shift 加选时不选中文字(节点里要能选中复制的内容自己写 userSelect: 'text')\n userSelect: 'none',\n cursor: { default: 'grab', ':active': 'grabbing' },\n outlineStyle: { default: 'none', ':focus-visible': 'solid' },\n outlineWidth: '_sm',\n outlineColor: '_focusRing',\n outlineOffset: '_borderWidths.sm',\n },\n rootSelect: { cursor: 'default' },\n world: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: '0 0',\n // 画布坐标与方向无关:从右到左的页面里节点的位置不镜像,节点里的文字照常跟随页面\n direction: 'ltr',\n },\n edges: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 1,\n overflow: 'visible',\n pointerEvents: 'none',\n },\n // 对齐线、拖出来的连线、改接把手:画在节点上面,除了把手都不挡指针\n above: { zIndex: 3 },\n edge: {\n color: { default: '_borderStrong', _pressed: '_accent', ':focus-visible': '_accent' },\n strokeWidth: { default: 1.5, _pressed: 2.5, ':focus-visible': 2.5 },\n outlineStyle: 'none',\n },\n edgeSelectable: {\n cursor: 'pointer',\n // :hover 的优先级高过 aria-pressed:悬停在选中的线上时还要是强调色\n color: {\n default: '_borderStrong',\n ':hover': { default: '_textMuted', _pressed: '_accent' },\n _pressed: '_accent',\n ':focus-visible': '_accent',\n },\n },\n edgeDashed: { strokeDasharray: '6 4' },\n edgeLine: {\n fill: 'none',\n stroke: 'currentColor',\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n },\n edgeArrow: { fill: 'currentColor', stroke: 'none' },\n // 加粗的透明命中区域:细线也好点中\n edgeHit: { fill: 'none', stroke: 'transparent', strokeWidth: 14, pointerEvents: 'stroke' },\n edgeEnd: {\n fill: '_surface',\n stroke: '_accent',\n strokeWidth: 2,\n cursor: 'crosshair',\n pointerEvents: 'all',\n },\n preview: {\n color: '_accent',\n strokeWidth: 2,\n strokeDasharray: '6 4',\n },\n guide: { stroke: '_accent', strokeWidth: 1, strokeDasharray: '4 3' },\n edgeText: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 1,\n paddingInline: '4px',\n borderRadius: '_sm',\n fontSize: '0.85em',\n lineHeight: '_tight',\n whiteSpace: 'nowrap',\n color: '_textMuted',\n backgroundColor: '_surface',\n pointerEvents: 'none',\n },\n node: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 2,\n display: 'grid',\n boxSizing: 'border-box',\n // 选中、焦点的描边跟着节点的形状走(DiagramNode 的 shape)\n borderRadius: { default: '_md', ':has(> [data-diagram-shape=\"pill\"])': '_full' },\n outlineStyle: {\n default: 'none',\n _pressed: 'solid',\n ':focus-visible': 'solid',\n '[data-link-target]': 'dashed',\n },\n outlineWidth: '2px',\n outlineColor: { default: '_accent', ':focus-visible': '_focusRing' },\n outlineOffset: '3px',\n },\n nodeSelectable: { cursor: 'pointer' },\n nodeDraggable: { cursor: { default: 'grab', ':active': 'grabbing' } },\n nodeDragging: { cursor: 'grabbing', opacity: 0.9 },\n port: {\n position: 'absolute',\n width: '10px',\n height: '10px',\n boxSizing: 'border-box',\n borderRadius: '_full',\n borderWidth: '2px',\n borderStyle: 'solid',\n borderColor: '_accent',\n backgroundColor: '_surface',\n cursor: 'crosshair',\n transform: { default: 'translate(-50%, -50%)', ':hover': 'translate(-50%, -50%) scale(1.3)' },\n transition: `transform ${t.durations.sm} ${t.easings.standard}`,\n },\n portTop: { left: '50%', top: 0 },\n portRight: { left: '100%', top: '50%' },\n portBottom: { left: '50%', top: '100%' },\n portLeft: { left: 0, top: '50%' },\n marquee: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 3,\n pointerEvents: 'none',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_accent',\n borderRadius: '_xs',\n backgroundColor: `color-mix(in srgb, ${t.colors.accent} 10%, transparent)`,\n },\n overlay: { position: 'absolute', inset: 0, zIndex: 4, pointerEvents: 'none' },\n});\n\n/** 有色调的连线:选中、焦点时照样是强调色 */\nconst toned = (color: string) => ({\n color: { default: color, _pressed: '_accent', ':focus-visible': '_accent' },\n});\n\n/** 连线的色调(neutral 用默认的灰) */\nconst edgeToneStyles = css.create({\n neutral: {},\n accent: toned('_accent'),\n info: toned('_infoText'),\n success: toned('_successText'),\n warning: toned('_warningText'),\n danger: toned('_dangerText'),\n});\n\n/** 连线文字的色调 */\nconst edgeTextToneStyles = css.create({\n neutral: {},\n accent: { color: '_accentText' },\n info: { color: '_infoText' },\n success: { color: '_successText' },\n warning: { color: '_warningText' },\n danger: { color: '_dangerText' },\n});\n\nconst portStyles: Record<DiagramSide, typeof diagramStyles.portTop> = {\n top: diagramStyles.portTop,\n right: diagramStyles.portRight,\n bottom: diagramStyles.portBottom,\n left: diagramStyles.portLeft,\n};\n\n/** 网格的图案:点阵、线格 */\nconst gridImages: Record<keyof DiagramGrids, string> = {\n none: 'none',\n dots: `radial-gradient(circle, ${t.colors.borderStrong} 1px, transparent 1.5px)`,\n lines: `linear-gradient(${t.colors.borderMuted} 1px, transparent 1px), linear-gradient(90deg, ${t.colors.borderMuted} 1px, transparent 1px)`,\n};\n\n/** 随视口变的样式:平移缩放、网格、节点与文字的位置(值变化只改元素上的变量,画布不重新渲染) */\nexport const diagramDynamicStyles = css.create({\n world: (x: number, y: number, scale: number) => ({\n transform: `translate(${x}px, ${y}px) scale(${scale})`,\n }),\n grid: (kind: keyof DiagramGrids, x: number, y: number, scale: number, gridSize: number) => {\n const step = gridSize * scale < MIN_GRID ? gridSize * scale * 4 : gridSize * scale;\n return {\n backgroundImage: gridImages[kind],\n backgroundSize: `${step}px ${step}px`,\n backgroundPosition: `${x}px ${y}px`,\n };\n },\n box: (x: number, y: number, width: number, height: number) => ({\n transform: `translate(${x}px, ${y}px)`,\n width,\n height,\n }),\n at: (x: number, y: number) => ({ transform: `translate(${x}px, ${y}px) translate(-50%, -50%)` }),\n height: (height: number | string) => ({ height }),\n});\n\n/** 部件属性可以是对象,也可以按节点、连线计算 */\nfunction partOf<T, A extends unknown[]>(part: T | ((...args: A) => T) | undefined, ...args: A) {\n return typeof part === 'function' ? (part as (...args: A) => T)(...args) : part;\n}\n\n/** 按着加选键:Shift、Ctrl、⌘ */\nconst toggles = (event: MouseEvent | KeyboardEvent) =>\n event.shiftKey || event.ctrlKey || event.metaKey;\n\n/** 方向键 → 挪动的方向 */\nconst ARROWS: Record<string, readonly [number, number]> = {\n ArrowLeft: [-1, 0],\n ArrowRight: [1, 0],\n ArrowUp: [0, -1],\n ArrowDown: [0, 1],\n};\n\n/** 一条连线画出来的折线 */\ninterface Route<E> {\n edge: E;\n points: readonly DiagramPoint[];\n}\n\n/** 拖动中的节点:哪些在动、挪了多少、要画的对齐线 */\ninterface DragState {\n ids: ReadonlySet<string>;\n dx: number;\n dy: number;\n guides: DiagramGuide[];\n}\n\n/** 正在拖的连线:从哪一点到哪一点,指针下能连的节点 */\ninterface LinkState {\n from: DiagramPoint;\n to: DiagramPoint;\n target: string | null;\n}\n\n/**\n * 节点、连线视图收到的事件处理:画布在 setup 里建一次,传给每个视图的都是同一个对象,\n * 视图的 props 不因事件处理重新生成而变化(拖动、悬停时只有变了的节点与连线重新渲染)\n */\ninterface ItemActions {\n nodeDown(id: string, event: PointerEvent): void;\n nodeClick(id: string, event: MouseEvent): void;\n nodeKey(id: string, event: KeyboardEvent): void;\n nodeEnter(id: string): void;\n nodeLeave(id: string): void;\n portDown(id: string, side: DiagramSide, event: PointerEvent): void;\n edgeClick(id: string, event: MouseEvent): void;\n edgeKey(id: string, event: KeyboardEvent): void;\n endDown(id: string, end: 'from' | 'to', event: PointerEvent): void;\n focus(rect: DiagramRect, event: FocusEvent): void;\n}\n\n/** 节点视图的属性:位置单独给(拖动中只有动着的节点位置变),状态都是原始值,比较时不会每次都“变了” */\ninterface NodeViewProps {\n item: DiagramNodeItem;\n x: number;\n y: number;\n label: string;\n roleDescription: string;\n selected: boolean;\n selectable: boolean;\n focusable: boolean;\n movable: boolean;\n dragging: boolean;\n ports: boolean;\n linkTarget: boolean;\n render: (node: never, state: DiagramItemState) => VNodeChild;\n part?: PartProps<'div'> | ((node: never, state: DiagramItemState) => PartProps<'div'>);\n portPart?: PartProps<'span'>;\n actions: ItemActions;\n}\n\n/** 一个节点:节点框(定位、选中、焦点、拖动)、使用方画的内容、端口 */\nconst NodeView = _component(\n ({\n item,\n x,\n y,\n label,\n roleDescription,\n selected,\n selectable,\n focusable,\n movable,\n dragging,\n ports,\n linkTarget,\n render,\n part,\n portPart,\n actions,\n }: NodeViewProps) =>\n () => {\n const state: DiagramItemState = { selected };\n const id = item.id;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.node,\n selectable && diagramStyles.nodeSelectable,\n selectable && interactionTransitions.colors,\n movable && diagramStyles.nodeDraggable,\n dragging && diagramStyles.nodeDragging,\n diagramDynamicStyles.box(x, y, item.width, item.height),\n ],\n },\n partOf(part, item as never, state),\n {\n ...dataAttrs({\n 'data-diagram-item': 'node',\n 'data-node': id,\n 'data-link-target': linkTarget || undefined,\n }),\n 'aria-roledescription': roleDescription,\n 'aria-label': label,\n onPointerdown: (event: PointerEvent) => actions.nodeDown(id, event),\n onPointerenter: () => actions.nodeEnter(id),\n onPointerleave: () => actions.nodeLeave(id),\n ...(focusable\n ? {\n role: 'button',\n tabindex: 0,\n 'aria-pressed': selectable ? selected : undefined,\n onClick: (event: MouseEvent) => actions.nodeClick(id, event),\n onKeydown: (event: KeyboardEvent) => actions.nodeKey(id, event),\n onFocus: (event: FocusEvent) =>\n actions.focus({ x, y, width: item.width, height: item.height }, event),\n }\n : { role: 'img' }),\n },\n )}\n >\n {render(item as never, state)}\n {ports &&\n SIDES.map((side) => (\n <span\n key={side}\n {...mergeAttrs<'span'>({ sx: [diagramStyles.port, portStyles[side]] }, portPart, {\n ...dataAttrs({ 'data-diagram-port': side }),\n 'aria-hidden': 'true',\n onPointerdown: (event: PointerEvent) => actions.portDown(id, side, event),\n })}\n />\n ))}\n </div>\n );\n },\n);\n\n/** 连线视图的属性:折线的数组只在这条线真的变了时才换(不动的线一直是同一个数组) */\ninterface EdgeViewProps {\n item: DiagramEdgeItem;\n points: readonly DiagramPoint[];\n label: string;\n roleDescription: string;\n radius: number;\n selected: boolean;\n selectable: boolean;\n part?: PartProps<'g'> | ((edge: never, state: DiagramItemState) => PartProps<'g'>);\n actions: ItemActions;\n}\n\n/** 一条连线:加粗的透明命中区域、线、箭头(改接的把手画在节点上面那层,见 Diagram) */\nconst EdgeView = _component(\n ({\n item,\n points,\n label,\n roleDescription,\n radius,\n selected,\n selectable,\n part,\n actions,\n }: EdgeViewProps) =>\n () => {\n const state: DiagramItemState = { selected };\n const path = polylinePath(trimEnd(points, ARROW * 0.7), radius);\n return (\n <g\n {...mergeAttrs<'g'>(\n {\n sx: [\n diagramStyles.edge,\n selectable && diagramStyles.edgeSelectable,\n item.tone && edgeToneStyles[item.tone],\n item.dashed && diagramStyles.edgeDashed,\n ],\n },\n partOf(part, item as never, state),\n {\n ...dataAttrs({ 'data-diagram-item': 'edge', 'data-edge': item.id }),\n ...(selectable\n ? {\n role: 'button',\n tabindex: 0,\n 'aria-roledescription': roleDescription,\n 'aria-label': label,\n 'aria-pressed': selected,\n onClick: (event: MouseEvent) => actions.edgeClick(item.id, event),\n onKeydown: (event: KeyboardEvent) => actions.edgeKey(item.id, event),\n onFocus: (event: FocusEvent) => actions.focus(boundsOf([], points)!, event),\n }\n : {}),\n },\n )}\n >\n {selectable && <path d={path} {...css.attrs(diagramStyles.edgeHit)} />}\n <path d={path} {...css.attrs(diagramStyles.edgeLine)} />\n <polygon points={arrowHead(points, ARROW)} {...css.attrs(diagramStyles.edgeArrow)} />\n </g>\n );\n },\n);\n\n/** 连线文字视图的属性 */\ninterface EdgeTextViewProps {\n item: DiagramEdgeItem;\n x: number;\n y: number;\n selected: boolean;\n render: (edge: never, state: DiagramItemState) => VNodeChild;\n part?: PartProps<'div'> | ((edge: never, state: DiagramItemState) => PartProps<'div'>);\n}\n\n/** 连线上的文字(HTML,画在连线上面);渲染函数返回空时不画 */\nconst EdgeTextView = _component(\n ({ item, x, y, selected, render, part }: EdgeTextViewProps) =>\n () => {\n const state: DiagramItemState = { selected };\n const text = render(item as never, state);\n if (text == null || text === false || text === '') return null;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.edgeText,\n item.tone && edgeTextToneStyles[item.tone],\n diagramDynamicStyles.at(x, y),\n ],\n },\n partOf(part, item as never, state),\n { 'aria-hidden': 'true' },\n )}\n >\n {text}\n </div>\n );\n },\n);\n\n/** 画布 */\nexport const Diagram = _component(\n <N extends DiagramNodeItem, E extends DiagramEdgeItem>({\n nodes,\n edges = [],\n children,\n getNodeLabel,\n getEdgeLabel,\n edgeText,\n height = 360,\n controller,\n selectable = false,\n _selected: selected = _bindable<DiagramSelection>(NO_SELECTION),\n dragMode = 'pan',\n selectionMode = 'full',\n grid = 'none',\n gridSize = 20,\n fitView = false,\n extent,\n routing = 'straight',\n edgeRadius = 6,\n draggable = false,\n snapToGrid = false,\n guides = true,\n onNodesMove,\n connectable = false,\n canConnect,\n onConnect,\n onReconnect,\n backdrop,\n overlay,\n propsWorld,\n propsNode,\n propsPort,\n propsEdge,\n propsEdgeText,\n propsMarquee,\n propsGuide,\n ...rest\n }: DiagramProps<N, E>) => {\n const messages = useMessages('diagram', diagramMessages);\n // 控制器只在创建时取:换控制器要换一个画布\n const diagram = _untrack(controller) ?? useDiagram();\n const internal = diagramInternals(diagram);\n DiagramContext.provide(diagram);\n\n // 框选框(视口坐标)、拖动中的节点、拖出来的连线、指针下的节点\n let marquee = _state.raw<DiagramRect | null>(null);\n let drag = _state.raw<DragState | null>(null);\n let link = _state.raw<LinkState | null>(null);\n let hovered = _state.raw<string | null>(null);\n // 按着空格:拖动一律平移(框选模式里平移的办法)\n let space = false;\n // 用户自己动过视口之后,尺寸变化不再自动适应\n let moved = false;\n\n /** 没给 children 时的节点:标题是无障碍名称的 DiagramNode */\n const defaultNode = (node: N) => <DiagramNode title={getNodeLabel(node)} />;\n const nodeById = _derived(new Map(nodes.map((node) => [node.id, node])));\n const draggableOf = (node: N) =>\n typeof draggable === 'function' ? draggable(node) : draggable;\n /** 节点现在的位置:拖动中的按拖到的位置 */\n const placed = (node: N): N =>\n drag?.ids.has(node.id) ? { ...node, x: node.x + drag.dx, y: node.y + drag.dy } : node;\n\n /** 不拖动时每条连线的折线:给了 points 用它,没给时按 routing 画;两端的节点缺了不画 */\n const restingRoutes = _derived.by(() => {\n const automatic = edges.filter((edge) => !hasPoints(edge));\n const routed = routing === 'orthogonal' ? routeEdges(nodes, automatic) : undefined;\n return edges.flatMap((edge): Route<E>[] => {\n if (hasPoints(edge)) return [{ edge, points: edge.points }];\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!from || !to) return [];\n return [{ edge, points: routed?.get(edge.id) ?? straightRoute(from, to) }];\n });\n });\n /** 拖动中:与动着的节点相连的线按 routing 实时重画,别的线不动 */\n const routes = _derived.by(() => {\n if (!drag) return restingRoutes;\n const moving = drag.ids;\n const touches = (edge: E) => moving.has(edge.from) || moving.has(edge.to);\n const list = nodes.map(placed);\n const byId = new Map(list.map((node) => [node.id, node]));\n const touched = edges.filter(touches);\n const routed = routing === 'orthogonal' ? routeEdges(list, touched) : undefined;\n return restingRoutes.map((route): Route<E> => {\n if (!touches(route.edge)) return route;\n const from = byId.get(route.edge.from);\n const to = byId.get(route.edge.to);\n if (!from || !to) return route;\n return { edge: route.edge, points: routed?.get(route.edge.id) ?? straightRoute(from, to) };\n });\n });\n const bounds = _derived(\n boundsOf(\n nodes,\n restingRoutes.flatMap((route) => route.points),\n ),\n );\n const selectedNodes = _derived(new Set(selected.nodes));\n const selectedEdges = _derived(new Set(selected.edges));\n\n internal.content = () => extent ?? bounds;\n internal.nodes = () => nodes.map(placed);\n const root = () => internal.element.value;\n const inOverlay = (target: EventTarget | null) =>\n target instanceof Element && target.closest('[data-diagram-overlay]') !== null;\n /** 事件发生在空白处:不在节点、连线、浮层里 */\n const onBackground = (target: EventTarget | null) =>\n target instanceof Element && !target.closest('[data-diagram-item],[data-diagram-overlay]');\n /** 这次按下要框选:可选择、在空白处、按的是主键,拖动方式是框选或按着 Shift */\n const startsMarquee = (event: PointerEvent) =>\n selectable &&\n !space &&\n event.button === 0 &&\n onBackground(event.target) &&\n (dragMode === 'select' || event.shiftKey);\n\n /** 视口(平移缩放)要不要处理这个事件;处理了就算用户动过视口 */\n function handlesViewport(event: PointerEvent | WheelEvent | MouseEvent | KeyboardEvent) {\n if (inOverlay(event.target)) return false;\n // 视口自己的按键(方向键平移、+ − 缩放)只在焦点就在视口上时生效,节点上的按键留给节点\n const handles =\n event.type === 'wheel'\n ? true\n : event.type === 'keydown'\n ? event.target === root()\n : space ||\n (onBackground(event.target) &&\n !(\n event.type === 'pointerdown' &&\n (dragMode === 'select' || (event as PointerEvent).shiftKey)\n ));\n if (handles) moved = true;\n return handles;\n }\n internal.filter = handlesViewport;\n\n // 量视口的大小(小地图用);fitView 时第一次有尺寸就适应内容,用户没动过视口时尺寸变化也重新适应\n useResizeObserver(root, () => {\n const element = root();\n if (!element) return;\n internal.size.value = { width: element.clientWidth, height: element.clientHeight };\n if (fitView && !moved && element.clientWidth > 0) diagram.fit();\n });\n\n /** 点了一项:加选键按着时切换它,否则只选它 */\n function choose(kind: 'nodes' | 'edges', id: string, toggle: boolean) {\n if (!selectable) return;\n if (!toggle) {\n selected = { nodes: kind === 'nodes' ? [id] : [], edges: kind === 'edges' ? [id] : [] };\n return;\n }\n const list = selected[kind];\n selected = {\n ...selected,\n [kind]: list.includes(id) ? list.filter((item) => item !== id) : [...list, id],\n };\n }\n\n const clear = () => {\n if (selected.nodes.length || selected.edges.length) selected = NO_SELECTION;\n };\n const selectAll = () => {\n selected = {\n nodes: nodes.map((node) => node.id),\n edges: routes.map((route) => route.edge.id),\n };\n };\n\n /**\n * 拖到视口边上时自动平移:指针停着不动也继续移,每移一帧调 onPan 让拖着的东西跟上指针\n * (拖动按指针的画布坐标算,视口挪了画布坐标就变了)\n */\n function edgePan(onPan: () => void) {\n let frame = 0;\n let speed = { x: 0, y: 0 };\n const tick = () => {\n frame = 0;\n if (!speed.x && !speed.y) return;\n internal.view.panTo(diagram.x + speed.x, diagram.y + speed.y);\n onPan();\n frame = requestAnimationFrame(tick);\n };\n return {\n follow(point: { clientX: number; clientY: number }) {\n const box = root()?.getBoundingClientRect();\n if (!box) return;\n const near = (distance: number) =>\n distance < EDGE_PAN ? Math.ceil((EDGE_PAN - distance) / 3) : 0;\n speed = {\n x: near(point.clientX - box.left) - near(box.right - point.clientX),\n y: near(point.clientY - box.top) - near(box.bottom - point.clientY),\n };\n if ((speed.x || speed.y) && !frame) frame = requestAnimationFrame(tick);\n },\n stop() {\n speed = { x: 0, y: 0 };\n if (frame) cancelAnimationFrame(frame);\n frame = 0;\n },\n };\n }\n\n /** 拖动期间按 Esc 取消:在捕获阶段拦下,不让它再去清空选择 */\n function cancelOnEscape(cancel: () => void) {\n const onKey = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n event.preventDefault();\n event.stopPropagation();\n cancel();\n };\n window.addEventListener('keydown', onKey, true);\n return () => window.removeEventListener('keydown', onKey, true);\n }\n\n function startMarquee(event: PointerEvent) {\n const element = root();\n if (!element || !startsMarquee(event)) return;\n const box = element.getBoundingClientRect();\n const origin = { x: event.clientX - box.left, y: event.clientY - box.top };\n const additive = event.ctrlKey || event.metaKey || (dragMode === 'select' && event.shiftKey);\n const base = additive ? selected : NO_SELECTION;\n const covers = (area: DiagramRect, rect: DiagramRect) =>\n selectionMode === 'partial' ? rectsIntersect(area, rect) : rectContains(area, rect);\n startMove(event, {\n threshold: 3,\n onMove: (point) => {\n const screen = rectFromCorners(origin, {\n x: point.clientX - box.left,\n y: point.clientY - box.top,\n });\n marquee = screen;\n const { x, y, scale } = diagram;\n const area = {\n x: (screen.x - x) / scale,\n y: (screen.y - y) / scale,\n width: screen.width / scale,\n height: screen.height / scale,\n };\n const next = {\n nodes: union(\n base.nodes,\n nodes.filter((node) => covers(area, node)).map((node) => node.id),\n ),\n edges: union(\n base.edges,\n routes\n .filter((route) => covers(area, boundsOf([], route.points)!))\n .map((route) => route.edge.id),\n ),\n };\n // 框到的没变时不写:画布只在选择真的变了才重新渲染\n if (!sameIds(next.nodes, selected.nodes) || !sameIds(next.edges, selected.edges)) {\n selected = next;\n }\n },\n onEnd: () => (marquee = null),\n });\n }\n\n /** 按在节点上:拖动它(选中的一起拖);按在节点里的输入框、按钮、端口上时不拖 */\n function startDrag(node: N, event: PointerEvent) {\n if (event.button !== 0 || space || !draggableOf(node)) return;\n const target = event.target as Element;\n if (\n target.closest(\n '[data-diagram-port],input,textarea,select,button,a,[contenteditable=\"true\"]',\n )\n ) {\n return;\n }\n const additive = toggles(event);\n const ids = selectedNodes.has(node.id)\n ? selected.nodes\n : additive\n ? [...selected.nodes, node.id]\n : [node.id];\n const moving = ids.flatMap((id) => {\n const item = nodeById.get(id);\n return item && draggableOf(item) ? [item] : [];\n });\n const others = nodes.filter((item) => !ids.includes(item.id));\n const start = diagram.toDiagram(event.clientX, event.clientY);\n let pointer = { clientX: event.clientX, clientY: event.clientY };\n let begun = false;\n let release = () => {};\n\n // 以按住的节点为准吸附网格与对齐线,算出整组挪多少\n const update = () => {\n const now = diagram.toDiagram(pointer.clientX, pointer.clientY);\n let x = node.x + now.x - start.x;\n let y = node.y + now.y - start.y;\n if (snapToGrid) {\n x = Math.round(x / gridSize) * gridSize;\n y = Math.round(y / gridSize) * gridSize;\n }\n let lines: DiagramGuide[] = [];\n if (guides) {\n const aligned = alignToGuides({ ...node, x, y }, others, GUIDE_TOLERANCE / diagram.scale);\n ({ x, y } = aligned);\n lines = aligned.guides;\n }\n drag = {\n ids: new Set(moving.map((item) => item.id)),\n dx: x - node.x,\n dy: y - node.y,\n guides: lines,\n };\n };\n const pan = edgePan(update);\n const cancel = startMove(event, {\n threshold: 3,\n onMove: (point) => {\n pointer = point;\n if (!begun) {\n begun = true;\n // 拖一个没选中的节点:选中它(按着加选键时加进原来的选择)\n if (selectable && !selectedNodes.has(node.id)) {\n selected = { nodes: ids, edges: additive ? selected.edges : [] };\n }\n release = cancelOnEscape(() => cancel());\n }\n update();\n pan.follow(point);\n },\n onEnd: ({ moved: dragged, cancelled }) => {\n pan.stop();\n release();\n const result = drag;\n drag = null;\n if (!dragged || cancelled || !result || (result.dx === 0 && result.dy === 0)) return;\n onNodesMove?.(\n moving.map((item) => ({ id: item.id, x: item.x + result.dx, y: item.y + result.dy })),\n );\n },\n });\n }\n\n /**\n * 拖一条连线:从 anchor 拉出来,松开在能连的节点上时 done(节点, 离指针最近的边)。\n * fixed 是不动的那一端的节点(连到它自己不算);fixedIsSource 时它是起点、箭头在指针一端\n */\n function startLink(\n event: PointerEvent,\n anchor: DiagramPoint,\n fixed: N,\n fixedIsSource: boolean,\n done: (target: N, side: DiagramSide) => void,\n ) {\n if (event.button !== 0) return;\n event.stopPropagation();\n event.preventDefault();\n let pointer = { clientX: event.clientX, clientY: event.clientY };\n let release = () => {};\n let landing: { node: N; side: DiagramSide } | null = null;\n const allowed = (candidate: N) =>\n candidate.id !== fixed.id &&\n (canConnect?.(fixedIsSource ? fixed : candidate, fixedIsSource ? candidate : fixed) ??\n true);\n const update = () => {\n const point = diagram.toDiagram(pointer.clientX, pointer.clientY);\n const hit = rectAt(nodes, point);\n landing = hit && allowed(hit) ? { node: hit, side: nearestSide(hit, point) } : null;\n const end = landing ? sidePoint(landing.node, landing.side) : point;\n link = {\n from: fixedIsSource ? anchor : end,\n to: fixedIsSource ? end : anchor,\n target: landing?.node.id ?? null,\n };\n };\n const pan = edgePan(update);\n update();\n const cancel = startMove(event, {\n // 端口、改接把手拖动中会消失:捕获放在画布上;松开时的 click 也落在画布上,不能当成点空白处\n captureTarget: root() ?? undefined,\n swallowClick: true,\n onMove: (point) => {\n pointer = point;\n update();\n pan.follow(point);\n },\n onEnd: ({ cancelled }) => {\n pan.stop();\n release();\n link = null;\n if (!cancelled && landing) done(landing.node, landing.side);\n },\n });\n release = cancelOnEscape(() => cancel());\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (event.key === ' ' && event.target === root()) space = true;\n if (!selectable) return;\n if (event.key === 'Escape') clear();\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {\n event.preventDefault();\n selectAll();\n }\n }\n\n /** 节点上的方向键:挪动(选中的一起挪,Shift 五步) */\n function nudge(node: N, event: KeyboardEvent) {\n const arrow = ARROWS[event.key];\n if (!arrow || !onNodesMove || !draggableOf(node)) return;\n event.preventDefault();\n const step = (snapToGrid ? gridSize : NUDGE) * (event.shiftKey ? 5 : 1);\n const ids = selectedNodes.has(node.id) ? selected.nodes : [node.id];\n onNodesMove(\n ids.flatMap((id) => {\n const item = nodeById.get(id);\n return item && draggableOf(item)\n ? [{ id, x: item.x + arrow[0] * step, y: item.y + arrow[1] * step }]\n : [];\n }),\n );\n }\n\n /** Enter / 空格:选中(同点击) */\n function activates(event: KeyboardEvent) {\n if (event.key !== 'Enter' && event.key !== ' ') return false;\n event.preventDefault();\n return true;\n }\n\n const actions: ItemActions = {\n nodeDown(id, event) {\n const node = nodeById.get(id);\n if (node) startDrag(node, event);\n },\n nodeClick: (id, event) => choose('nodes', id, toggles(event)),\n nodeKey(id, event) {\n const node = nodeById.get(id);\n if (!node) return;\n if (activates(event)) choose('nodes', id, toggles(event));\n else nudge(node, event);\n },\n nodeEnter: (id) => (hovered = id),\n nodeLeave(id) {\n if (hovered === id) hovered = null;\n },\n portDown(id, side, event) {\n const node = nodeById.get(id);\n if (!node) return;\n startLink(event, sidePoint(node, side), node, true, (target, toSide) =>\n onConnect?.({ from: id, to: target.id, fromSide: side, toSide }),\n );\n },\n edgeClick: (id, event) => choose('edges', id, toggles(event)),\n edgeKey(id, event) {\n if (activates(event)) choose('edges', id, toggles(event));\n },\n endDown(id, end, event) {\n const route = routes.find((item) => item.edge.id === id);\n const from = route && nodeById.get(route.edge.from);\n const to = route && nodeById.get(route.edge.to);\n if (!route || !from || !to || !onReconnect) return;\n const { points } = route;\n // 拖的是终点:不动的是起点,箭头在指针一端;拖的是起点:反过来\n const anchor = end === 'to' ? points[0]! : points[points.length - 1]!;\n startLink(event, anchor, end === 'to' ? from : to, end === 'to', (target, side) =>\n onReconnect({ edge: id, end, node: target.id, side }),\n );\n },\n // 键盘把焦点移到视口外的节点、连线时平移过去(鼠标点到的本来就看得见)\n focus(rect, event) {\n if (event.target instanceof Element && event.target.matches(':focus-visible')) {\n diagram.reveal(rect);\n }\n },\n };\n\n return () => {\n const { view } = internal;\n const focusable = selectable || !!onNodesMove;\n // 选中的连线两端的改接把手:两端的节点都在时才能改接\n const ends =\n connectable && onReconnect && !drag && !link\n ? routes.filter(\n ({ edge }) =>\n selectedEdges.has(edge.id) && nodeById.has(edge.from) && nodeById.has(edge.to),\n )\n : [];\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.root,\n diagramDynamicStyles.height(height),\n dragMode === 'select' && diagramStyles.rootSelect,\n diagramDynamicStyles.grid(grid, diagram.x, diagram.y, diagram.scale, gridSize),\n ],\n },\n rest,\n {\n ...view.viewportProps,\n ref: (element: unknown) => (internal.element.value = element as HTMLElement | null),\n role: 'group',\n tabindex: 0,\n 'aria-roledescription': messages.canvas,\n onPointerdown: (event: PointerEvent) => {\n startMarquee(event);\n (view.viewportProps.onPointerdown as (event: PointerEvent) => void)(event);\n },\n onClick: (event: MouseEvent) => {\n if (selectable && onBackground(event.target)) clear();\n },\n onKeydown: (event: KeyboardEvent) => {\n onKeydown(event);\n (view.viewportProps.onKeydown as (event: KeyboardEvent) => void)(event);\n },\n onKeyup: (event: KeyboardEvent) => {\n if (event.key === ' ') space = false;\n },\n onBlur: () => (space = false),\n // 焦点移到视口外的节点时浏览器会滚动视口(overflow: hidden 也能被滚动),视口的位置只由平移决定\n onScroll: (event: Event) => {\n const element = event.currentTarget as HTMLElement;\n element.scrollTop = 0;\n element.scrollLeft = 0;\n },\n },\n )}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.world,\n diagramDynamicStyles.world(diagram.x, diagram.y, diagram.scale),\n ],\n },\n propsWorld,\n dataAttrs({ 'data-diagram-world': true }),\n )}\n >\n {backdrop}\n {nodes.map((node) => {\n const at = placed(node);\n const isSelected = selectedNodes.has(node.id);\n return (\n <NodeView\n key={node.id}\n item={node}\n x={at.x}\n y={at.y}\n label={getNodeLabel(node)}\n roleDescription={messages.node}\n selected={isSelected}\n selectable={selectable}\n focusable={focusable}\n movable={draggableOf(node)}\n dragging={drag?.ids.has(node.id) ?? false}\n ports={\n connectable &&\n !drag &&\n (hovered === node.id || isSelected || link?.target === node.id)\n }\n linkTarget={link?.target === node.id}\n render={(children ?? defaultNode) as NodeViewProps['render']}\n part={propsNode as NodeViewProps['part']}\n portPart={propsPort}\n actions={actions}\n />\n );\n })}\n <svg\n {...css.attrs(diagramStyles.edges)}\n width=\"1\"\n height=\"1\"\n aria-hidden={selectable ? undefined : 'true'}\n >\n {routes.map(({ edge, points }) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n const isSelected = selectedEdges.has(edge.id);\n return (\n <EdgeView\n key={edge.id}\n item={edge}\n points={points}\n label={\n getEdgeLabel?.(edge) ??\n messages.edgeBetween(\n from ? getNodeLabel(from) : edge.from,\n to ? getNodeLabel(to) : edge.to,\n )\n }\n roleDescription={messages.edge}\n radius={edgeRadius}\n selected={isSelected}\n selectable={selectable}\n part={propsEdge as EdgeViewProps['part']}\n actions={actions}\n />\n );\n })}\n </svg>\n {edgeText &&\n routes.map(({ edge, points }) => {\n const at = drag || !edge.labelAt ? polylineMidpoint(points) : edge.labelAt;\n return (\n <EdgeTextView\n key={edge.id}\n item={edge}\n x={at.x}\n y={at.y}\n selected={selectedEdges.has(edge.id)}\n render={edgeText as EdgeTextViewProps['render']}\n part={propsEdgeText as EdgeTextViewProps['part']}\n />\n );\n })}\n {(!!drag?.guides.length || !!link || ends.length > 0) && (\n <svg\n {...css.attrs(diagramStyles.edges, diagramStyles.above)}\n width=\"1\"\n height=\"1\"\n aria-hidden=\"true\"\n data-diagram-transient=\"\"\n >\n {drag?.guides.map((guide, index) => (\n <line\n key={index}\n {...mergeAttrs<'line'>({ sx: diagramStyles.guide }, propsGuide, {\n x1: guide.from.x,\n y1: guide.from.y,\n x2: guide.to.x,\n y2: guide.to.y,\n })}\n />\n ))}\n {ends.flatMap(({ edge, points }) =>\n (['from', 'to'] as const).map((end) => {\n const at = end === 'from' ? points[0]! : points[points.length - 1]!;\n return (\n <circle\n key={`${edge.id}:${end}`}\n cx={at.x}\n cy={at.y}\n r={5}\n {...css.attrs(diagramStyles.edgeEnd)}\n data-diagram-end={end}\n onPointerdown={(event: PointerEvent) =>\n actions.endDown(edge.id, end, event)\n }\n />\n );\n }),\n )}\n {link && (\n <g {...css.attrs(diagramStyles.preview)}>\n <path\n d={polylinePath(trimEnd([link.from, link.to], ARROW * 0.7))}\n {...css.attrs(diagramStyles.edgeLine)}\n />\n <polygon\n points={arrowHead([link.from, link.to], ARROW)}\n {...css.attrs(diagramStyles.edgeArrow)}\n />\n </g>\n )}\n </svg>\n )}\n </div>\n {marquee && (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.marquee,\n diagramDynamicStyles.box(marquee.x, marquee.y, marquee.width, marquee.height),\n ],\n },\n propsMarquee,\n )}\n />\n )}\n {overlay != null && (\n <div {...css.attrs(diagramStyles.overlay)} data-diagram-overlay=\"\">\n {overlay}\n </div>\n )}\n </div>\n );\n };\n },\n);\n\n/** 连线自己给了折线 */\nconst hasPoints = (\n edge: DiagramEdgeItem,\n): edge is DiagramEdgeItem & { points: readonly DiagramPoint[] } =>\n !!edge.points && edge.points.length >= 2;\n\n/** 两组标识合在一起,去掉重复 */\nconst union = (a: readonly string[], b: readonly string[]) => [...new Set([...a, ...b])];\n\n/** 两组标识是否相同(顺序无关) */\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false;\n const set = new Set(a);\n return b.every((id) => set.has(id));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Diagram.js","names":["_vtp_readonlyProp","_createVNode","_mergeProps","_vtp_childrenProp","_vtp_bindable","_vtp_restProps","_vtp_untrack","_vue_shallowRef","_vue_computed"],"sources":["../../src/diagram/Diagram.tsx"],"sourcesContent":["/**\n * 画布:在一块能平移、缩放的视口里摆放节点(HTML)与连线(SVG)。流程图、组织架构图、关系图都建在它上面:\n * 画布负责定位、视口、选择、拖动、连线与焦点;节点默认画成 DiagramNode(标题是 getNodeLabel),\n * 要别的样子时 children 给渲染函数,常见的是换 DiagramNode 的属性(说明、图标、色调、形状)。\n *\n * let selection = _state<DiagramSelection>({ nodes: [], edges: [] });\n * <Diagram nodes={nodes} edges={edges} getNodeLabel={(node) => node.name} selectable _selected={selection} fitView aria-label=\"组织架构\">\n * {(node) => <DiagramNode title={node.name} description={node.title} />}\n * </Diagram>\n *\n * - 视口(见 useDiagram):滚轮平移,按住 Ctrl / ⌘ 或触控板捏合缩放;拖动空白处平移,dragMode=\"select\" 时改为框选、\n * 按住空格再拖动才平移;视口有焦点时方向键平移、+ / − 缩放、0 回到适应内容。fitView 在第一次有尺寸时把内容放进视口。\n * - 选择(selectable):点节点或连线选中它,按住 Shift / Ctrl / ⌘ 再点加选或取消;按住 Shift 拖动空白处框选\n * (selectionMode:整个框住才算,或碰到就算),按住 Ctrl / ⌘ 时框到的加进原来的选择;点空白处、Esc 清空,\n * Ctrl / ⌘ + A 全选。_selected 双向绑定。\n * - 拖动(draggable):拖节点(选中的一起拖),snapToGrid 吸附网格,guides 与别的节点对齐时吸过去并画对齐线,\n * 拖到视口边上自动平移,Esc 取消;聚焦的节点按方向键挪一步(Shift 五步)。位置由使用方保存:松开后 onNodesMove 给出新位置。\n * - 连线(connectable):悬停或选中的节点四条边上出现端口,从端口拖到另一个节点上松开调用 onConnect;\n * 选中的连线两端出现把手,拖到别的节点上调用 onReconnect。canConnect 决定能不能连,不能连的节点不高亮。\n * - 连线的画法:points 是折线(排布、路由的结果),没给时按 routing 画:straight 是两个节点之间的直线,\n * orthogonal 是绕开节点的正交折线(routeEdges);拖动时相连的线按 routing 实时重画。终点画箭头,拐角是圆角;\n * 连线的 tone 改线与文字的颜色(退回、驳回用 danger),dashed 画虚线。backdrop 里放泳道 DiagramLanes。\n * - 键盘:节点(可选择时连线也是)按数组顺序用 Tab 聚焦,Enter / 空格选中;键盘聚焦到视口外的节点时自动平移过去。\n * 拖动、连线都有不用指针的做法:方向键挪节点,连线交给设计器的属性面板(WCAG 2.5.7)。\n * - overlay 里的内容(DiagramControls、DiagramMinimap、图例)浮在最上面、不随视口动,经 DiagramContext 拿到控制器。\n * 部件:Root(视口)、World(随视口平移缩放的一层)、Node(节点框)、Port(端口)、Edge(每条连线的 g)、EdgeText(连线上的文字)、\n * Marquee(框选框)、Guide(对齐线)。\n */\nimport { _component, createContext } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useMessages } from '../config/lang/messages';\nimport { t } from '../config/theme/tokens';\nimport { startMove } from '../utils/dom/move';\nimport { useResizeObserver } from '../utils/dom/resize';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\nimport { interactionTransitions } from '../utils/style/transitions';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport { diagramInternals, useDiagram, type DiagramController } from './controller';\nimport { DiagramNode } from './DiagramNode';\nimport {\n alignToGuides,\n arrowHead,\n boundsOf,\n polylineMidpoint,\n polylinePath,\n rectAt,\n rectContains,\n rectFromCorners,\n rectsIntersect,\n trimEnd,\n type DiagramGuide,\n type DiagramPoint,\n type DiagramRect,\n} from './geometry';\nimport { diagramMessages } from './messages';\nimport { nearestSide, routeEdges, sidePoint, straightRoute, type DiagramSide } from './route';\n\n/** 画布上的一个节点:位置与大小(画布坐标),其余字段使用方自己用 */\nexport interface DiagramNodeItem extends DiagramRect {\n /** 节点的标识:连线的 from、to 与选择里用它 */\n id: string;\n}\n\n/** 画布上的一条连线 */\nexport interface DiagramEdgeItem {\n /** 连线的标识 */\n id: string;\n /** 起点节点 */\n from: string;\n /** 终点节点 */\n to: string;\n /** 折线经过的点(画布坐标,含两端);不给时按 routing 画 */\n points?: readonly DiagramPoint[];\n /** 从起点的哪条边出去(routing=\"orthogonal\" 时用);不写时自动选 */\n fromSide?: DiagramSide;\n /** 从终点的哪条边进来;不写时自动选 */\n toSide?: DiagramSide;\n /** 连线文字的位置;不给时放在折线走到一半的地方 */\n labelAt?: DiagramPoint;\n /** 色调:线、箭头与连线文字的颜色(退回、驳回用 danger,走过的路径用 success),默认中性的灰 */\n tone?: StatusTone;\n /** 画成虚线:可选的、还没生效的连线 */\n dashed?: boolean;\n}\n\n/** 选中的节点与连线(标识) */\nexport interface DiagramSelection {\n /** 选中的节点 */\n readonly nodes: readonly string[];\n /** 选中的连线 */\n readonly edges: readonly string[];\n}\n\n/** 节点、连线渲染时的状态 */\nexport interface DiagramItemState {\n /** 已选中 */\n readonly selected: boolean;\n}\n\n/** 拖动结束后一个节点的新位置 */\nexport interface DiagramNodeMove {\n /** 节点的标识 */\n readonly id: string;\n /** 新的横坐标 */\n readonly x: number;\n /** 新的纵坐标 */\n readonly y: number;\n}\n\n/** 从端口拖出的一条新连线 */\nexport interface DiagramConnection {\n /** 起点节点 */\n readonly from: string;\n /** 终点节点 */\n readonly to: string;\n /** 从起点的哪条边出去 */\n readonly fromSide: DiagramSide;\n /** 从终点的哪条边进来(松开时离指针最近的边) */\n readonly toSide: DiagramSide;\n}\n\n/** 拖动连线的一端改接到别的节点 */\nexport interface DiagramReconnection {\n /** 连线的标识 */\n readonly edge: string;\n /** 改的是哪一端 */\n readonly end: 'from' | 'to';\n /** 改接到的节点 */\n readonly node: string;\n /** 从这个节点的哪条边进出 */\n readonly side: DiagramSide;\n}\n\n/** 拖动空白处做什么 */\nexport interface DiagramDragModes {\n /** 平移视口;按住 Shift 拖动是框选(看图为主:流程图、组织架构图) */\n pan: unknown;\n /** 框选;按住空格拖动、滚轮平移(编辑为主:设计器) */\n select: unknown;\n}\n\n/** 框选时怎样算选中 */\nexport interface DiagramSelectionModes {\n /** 整个在框里才选中 */\n full: unknown;\n /** 碰到框就选中 */\n partial: unknown;\n}\n\n/** 背景的网格 */\nexport interface DiagramGrids {\n /** 不画 */\n none: unknown;\n /** 点阵(设计器) */\n dots: unknown;\n /** 线格 */\n lines: unknown;\n}\n\n/** 没给折线的连线怎样画 */\nexport interface DiagramRoutings {\n /** 两个节点之间的直线,两端落在边框上 */\n straight: unknown;\n /** 绕开节点的正交折线(横竖两个方向,拐弯少,同一条边上的几条线排开) */\n orthogonal: unknown;\n}\n\n/** 未声明的属性落到视口(Root)上:aria-label 写画布画的是什么 */\nexport interface DiagramProps<\n N extends DiagramNodeItem,\n E extends DiagramEdgeItem,\n> extends PartProps<'div', 'role' | 'tabindex' | 'draggable'> {\n /** 节点:位置与大小由使用方给(排布的结果或用户摆的位置) */\n nodes: readonly N[];\n /** 连线 */\n edges?: readonly E[];\n /** 节点的内容:节点框(定位、选中、焦点)由画布画,里面画什么由这里给,内容拉伸到节点的大小。默认是标题为 getNodeLabel 的 DiagramNode */\n children?: (node: N, state: DiagramItemState) => VNodeChild;\n /** 节点的无障碍名称(读屏念的;连线的默认名称“从 A 到 B”也用它)。节点里画了文字时按同样的先后写进来(如“姓名,岗位”),语音控制才能按看得见的字找到它 */\n getNodeLabel: (node: N) => string;\n /** 连线的无障碍名称,默认“从 A 到 B” */\n getEdgeLabel?: (edge: E) => string;\n /** 连线上的文字(处理结果、条件);返回空时不画 */\n edgeText?: (edge: E, state: DiagramItemState) => VNodeChild;\n /**\n * 视口的高(数字是 px)\n * @default 360\n */\n height?: number | string;\n /** 控制器(useDiagram):画布外的按钮要缩放、适应内容时传进来;不传时画布自己建一个 */\n controller?: DiagramController;\n /** 节点与连线可以点选、框选 */\n selectable?: boolean;\n /** 选中的节点与连线:父级写 _selected={selection} 双向绑定 */\n _selected?: DiagramSelection;\n /** 拖动空白处做什么,默认 pan */\n dragMode?: keyof DiagramDragModes;\n /** 框选时怎样算选中,默认 full */\n selectionMode?: keyof DiagramSelectionModes;\n /** 背景的网格,默认 none */\n grid?: keyof DiagramGrids;\n /** 网格的间距(画布坐标),默认 20;snapToGrid 也按它吸附 */\n gridSize?: number;\n /** 第一次有尺寸时把全部内容放进视口(不超过原大);用户动过视口之前,尺寸变了也重新适应。默认 false:从原点、原大开始 */\n fitView?: boolean;\n /** 内容的范围(画布坐标):适应画布按它算。默认包住全部节点与连线;backdrop 比节点占得大时(泳道)写上它 */\n extent?: DiagramRect;\n /** 没给折线的连线怎样画,默认 straight;拖动时相连的线也按它重画 */\n routing?: keyof DiagramRoutings;\n /** 折线拐角的圆角半径,默认 6;0 为直角 */\n edgeRadius?: number;\n /** 节点可以拖动(可以按节点判断);松开后 onNodesMove 给出新位置 */\n draggable?: boolean | ((node: N) => boolean);\n /** 拖动、方向键挪动时吸附到网格(gridSize) */\n snapToGrid?: boolean;\n /** 拖动时与别的节点的边、中线对齐就吸过去并画对齐线,默认 true */\n guides?: boolean;\n /** 拖动或方向键挪动后节点的新位置:使用方写回自己的数据(顺带记一步撤销) */\n onNodesMove?: (moves: DiagramNodeMove[]) => void;\n /** 能从节点的端口拖出连线;选中的连线两端可以拖去改接 */\n connectable?: boolean;\n /** 能不能从 from 连到 to(拖动时只高亮能连的节点);默认除了自己都能连 */\n canConnect?: (from: N, to: N) => boolean;\n /** 从端口拖出连线、在另一个节点上松开 */\n onConnect?: (connection: DiagramConnection) => void;\n /** 拖动选中连线的一端、在别的节点上松开 */\n onReconnect?: (change: DiagramReconnection) => void;\n /** 画在连线下面、随视口平移缩放的内容(画布坐标的 HTML):泳道、分区、背景标注 */\n backdrop?: VNodeChild;\n /** 浮在最上面、不随视口动的内容(视口坐标):缩放按钮 DiagramControls、小地图 DiagramMinimap、图例 */\n overlay?: VNodeChild;\n /** 随视口平移缩放的那一层的部件属性 */\n propsWorld?: PartProps<'div'>;\n /** 节点框的部件属性,可以按节点计算 */\n propsNode?: PartProps<'div'> | ((node: N, state: DiagramItemState) => PartProps<'div'>);\n /** 端口的部件属性 */\n propsPort?: PartProps<'span'>;\n /** 连线(g)的部件属性,可以按连线计算(颜色、虚线用连线的 tone、dashed) */\n propsEdge?: PartProps<'g'> | ((edge: E, state: DiagramItemState) => PartProps<'g'>);\n /** 连线文字的部件属性,可以按连线计算 */\n propsEdgeText?: PartProps<'div'> | ((edge: E, state: DiagramItemState) => PartProps<'div'>);\n /** 框选框的部件属性 */\n propsMarquee?: PartProps<'div'>;\n /** 对齐线的部件属性 */\n propsGuide?: PartProps<'line'>;\n}\n\n/** 画布里的部件(DiagramControls、DiagramMinimap)取控制器 */\nexport const DiagramContext = createContext<DiagramController>('Diagram');\n\n/** 箭头的长度(画布坐标) */\nconst ARROW = 9;\n/** 网格的间距在屏幕上小于这么多 px 时放大四倍,缩得很小时不糊成一片 */\nconst MIN_GRID = 8;\n/** 对齐线吸附的距离(屏幕 px) */\nconst GUIDE_TOLERANCE = 6;\n/** 拖到离视口边多近开始自动平移(px) */\nconst EDGE_PAN = 32;\n/** 没吸附网格时方向键一次挪多少(画布坐标) */\nconst NUDGE = 8;\nconst NO_SELECTION: DiagramSelection = { nodes: [], edges: [] };\nconst SIDES: readonly DiagramSide[] = ['top', 'right', 'bottom', 'left'];\n\n/** Diagram 的样式 */\nexport const diagramStyles = css.create({\n root: {\n position: 'relative',\n overflow: 'hidden',\n backgroundColor: '_surface',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_border',\n borderRadius: '_md',\n fontSize: '_sm',\n color: '_text',\n // 画布上点选、框选、按着 Shift 加选时不选中文字(节点里要能选中复制的内容自己写 userSelect: 'text')\n userSelect: 'none',\n cursor: { default: 'grab', ':active': 'grabbing' },\n outlineStyle: { default: 'none', ':focus-visible': 'solid' },\n outlineWidth: '_sm',\n outlineColor: '_focusRing',\n outlineOffset: '_borderWidths.sm',\n },\n rootSelect: { cursor: 'default' },\n world: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: '0 0',\n // 画布坐标与方向无关:从右到左的页面里节点的位置不镜像,节点里的文字照常跟随页面\n direction: 'ltr',\n },\n edges: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 1,\n overflow: 'visible',\n pointerEvents: 'none',\n },\n // 对齐线、拖出来的连线、改接把手:画在节点上面,除了把手都不挡指针\n above: { zIndex: 3 },\n edge: {\n color: { default: '_borderStrong', _pressed: '_accent', ':focus-visible': '_accent' },\n strokeWidth: { default: 1.5, _pressed: 2.5, ':focus-visible': 2.5 },\n outlineStyle: 'none',\n },\n edgeSelectable: {\n cursor: 'pointer',\n // :hover 的优先级高过 aria-pressed:悬停在选中的线上时还要是强调色\n color: {\n default: '_borderStrong',\n ':hover': { default: '_textMuted', _pressed: '_accent' },\n _pressed: '_accent',\n ':focus-visible': '_accent',\n },\n },\n edgeDashed: { strokeDasharray: '6 4' },\n edgeLine: {\n fill: 'none',\n stroke: 'currentColor',\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n },\n edgeArrow: { fill: 'currentColor', stroke: 'none' },\n // 加粗的透明命中区域:细线也好点中\n edgeHit: { fill: 'none', stroke: 'transparent', strokeWidth: 14, pointerEvents: 'stroke' },\n edgeEnd: {\n fill: '_surface',\n stroke: '_accent',\n strokeWidth: 2,\n cursor: 'crosshair',\n pointerEvents: 'all',\n },\n preview: {\n color: '_accent',\n strokeWidth: 2,\n strokeDasharray: '6 4',\n },\n guide: { stroke: '_accent', strokeWidth: 1, strokeDasharray: '4 3' },\n edgeText: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 1,\n paddingInline: '4px',\n borderRadius: '_sm',\n fontSize: '0.85em',\n lineHeight: '_tight',\n whiteSpace: 'nowrap',\n color: '_textMuted',\n backgroundColor: '_surface',\n pointerEvents: 'none',\n },\n node: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 2,\n display: 'grid',\n boxSizing: 'border-box',\n // 选中、焦点的描边跟着节点的形状走(DiagramNode 的 shape)\n borderRadius: { default: '_md', ':has(> [data-diagram-shape=\"pill\"])': '_full' },\n outlineStyle: {\n default: 'none',\n _pressed: 'solid',\n ':focus-visible': 'solid',\n '[data-link-target]': 'dashed',\n },\n outlineWidth: '2px',\n outlineColor: { default: '_accent', ':focus-visible': '_focusRing' },\n outlineOffset: '3px',\n },\n nodeSelectable: { cursor: 'pointer' },\n nodeDraggable: { cursor: { default: 'grab', ':active': 'grabbing' } },\n nodeDragging: { cursor: 'grabbing', opacity: 0.9 },\n port: {\n position: 'absolute',\n width: '10px',\n height: '10px',\n boxSizing: 'border-box',\n borderRadius: '_full',\n borderWidth: '2px',\n borderStyle: 'solid',\n borderColor: '_accent',\n backgroundColor: '_surface',\n cursor: 'crosshair',\n transform: { default: 'translate(-50%, -50%)', ':hover': 'translate(-50%, -50%) scale(1.3)' },\n transition: `transform ${t.durations.sm} ${t.easings.standard}`,\n },\n portTop: { left: '50%', top: 0 },\n portRight: { left: '100%', top: '50%' },\n portBottom: { left: '50%', top: '100%' },\n portLeft: { left: 0, top: '50%' },\n marquee: {\n position: 'absolute',\n left: 0,\n top: 0,\n zIndex: 3,\n pointerEvents: 'none',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_accent',\n borderRadius: '_xs',\n backgroundColor: `color-mix(in srgb, ${t.colors.accent} 10%, transparent)`,\n },\n overlay: { position: 'absolute', inset: 0, zIndex: 4, pointerEvents: 'none' },\n});\n\n/** 有色调的连线:选中、焦点时照样是强调色 */\nconst toned = (color: string) => ({\n color: { default: color, _pressed: '_accent', ':focus-visible': '_accent' },\n});\n\n/** 连线的色调(neutral 用默认的灰) */\nconst edgeToneStyles = css.create({\n neutral: {},\n accent: toned('_accent'),\n info: toned('_infoText'),\n success: toned('_successText'),\n warning: toned('_warningText'),\n danger: toned('_dangerText'),\n});\n\n/** 连线文字的色调 */\nconst edgeTextToneStyles = css.create({\n neutral: {},\n accent: { color: '_accentText' },\n info: { color: '_infoText' },\n success: { color: '_successText' },\n warning: { color: '_warningText' },\n danger: { color: '_dangerText' },\n});\n\nconst portStyles: Record<DiagramSide, typeof diagramStyles.portTop> = {\n top: diagramStyles.portTop,\n right: diagramStyles.portRight,\n bottom: diagramStyles.portBottom,\n left: diagramStyles.portLeft,\n};\n\n/** 网格的图案:点阵、线格 */\nconst gridImages: Record<keyof DiagramGrids, string> = {\n none: 'none',\n dots: `radial-gradient(circle, ${t.colors.borderStrong} 1px, transparent 1.5px)`,\n lines: `linear-gradient(${t.colors.borderMuted} 1px, transparent 1px), linear-gradient(90deg, ${t.colors.borderMuted} 1px, transparent 1px)`,\n};\n\n/** 随视口变的样式:平移缩放、网格、节点与文字的位置(值变化只改元素上的变量,画布不重新渲染) */\nexport const diagramDynamicStyles = css.create({\n world: (x: number, y: number, scale: number) => ({\n transform: `translate(${x}px, ${y}px) scale(${scale})`,\n }),\n grid: (kind: keyof DiagramGrids, x: number, y: number, scale: number, gridSize: number) => {\n const step = gridSize * scale < MIN_GRID ? gridSize * scale * 4 : gridSize * scale;\n return {\n backgroundImage: gridImages[kind],\n backgroundSize: `${step}px ${step}px`,\n backgroundPosition: `${x}px ${y}px`,\n };\n },\n box: (x: number, y: number, width: number, height: number) => ({\n transform: `translate(${x}px, ${y}px)`,\n width,\n height,\n }),\n at: (x: number, y: number) => ({ transform: `translate(${x}px, ${y}px) translate(-50%, -50%)` }),\n height: (height: number | string) => ({ height }),\n});\n\n/** 部件属性可以是对象,也可以按节点、连线计算 */\nfunction partOf<T, A extends unknown[]>(part: T | ((...args: A) => T) | undefined, ...args: A) {\n return typeof part === 'function' ? (part as (...args: A) => T)(...args) : part;\n}\n\n/** 按着加选键:Shift、Ctrl、⌘ */\nconst toggles = (event: MouseEvent | KeyboardEvent) =>\n event.shiftKey || event.ctrlKey || event.metaKey;\n\n/** 方向键 → 挪动的方向 */\nconst ARROWS: Record<string, readonly [number, number]> = {\n ArrowLeft: [-1, 0],\n ArrowRight: [1, 0],\n ArrowUp: [0, -1],\n ArrowDown: [0, 1],\n};\n\n/** 一条连线画出来的折线 */\ninterface Route<E> {\n edge: E;\n points: readonly DiagramPoint[];\n}\n\n/** 拖动中的节点:哪些在动、挪了多少、要画的对齐线 */\ninterface DragState {\n ids: ReadonlySet<string>;\n dx: number;\n dy: number;\n guides: DiagramGuide[];\n}\n\n/** 正在拖的连线:从哪一点到哪一点,指针下能连的节点 */\ninterface LinkState {\n from: DiagramPoint;\n to: DiagramPoint;\n target: string | null;\n}\n\n/**\n * 节点、连线视图收到的事件处理:画布在 setup 里建一次,传给每个视图的都是同一个对象,\n * 视图的 props 不因事件处理重新生成而变化(拖动、悬停时只有变了的节点与连线重新渲染)\n */\ninterface ItemActions {\n nodeDown(id: string, event: PointerEvent): void;\n nodeClick(id: string, event: MouseEvent): void;\n nodeKey(id: string, event: KeyboardEvent): void;\n nodeEnter(id: string): void;\n nodeLeave(id: string): void;\n portDown(id: string, side: DiagramSide, event: PointerEvent): void;\n edgeClick(id: string, event: MouseEvent): void;\n edgeKey(id: string, event: KeyboardEvent): void;\n endDown(id: string, end: 'from' | 'to', event: PointerEvent): void;\n focus(rect: DiagramRect, event: FocusEvent): void;\n}\n\n/** 节点视图的属性:位置单独给(拖动中只有动着的节点位置变),状态都是原始值,比较时不会每次都“变了” */\ninterface NodeViewProps {\n item: DiagramNodeItem;\n x: number;\n y: number;\n label: string;\n roleDescription: string;\n selected: boolean;\n selectable: boolean;\n focusable: boolean;\n movable: boolean;\n dragging: boolean;\n ports: boolean;\n linkTarget: boolean;\n render: (node: never, state: DiagramItemState) => VNodeChild;\n part?: PartProps<'div'> | ((node: never, state: DiagramItemState) => PartProps<'div'>);\n portPart?: PartProps<'span'>;\n actions: ItemActions;\n}\n\n/** 一个节点:节点框(定位、选中、焦点、拖动)、使用方画的内容、端口 */\nconst NodeView = _component(\n ({\n item,\n x,\n y,\n label,\n roleDescription,\n selected,\n selectable,\n focusable,\n movable,\n dragging,\n ports,\n linkTarget,\n render,\n part,\n portPart,\n actions,\n }: NodeViewProps) =>\n () => {\n const state: DiagramItemState = { selected };\n const id = item.id;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.node,\n selectable && diagramStyles.nodeSelectable,\n selectable && interactionTransitions.colors,\n movable && diagramStyles.nodeDraggable,\n dragging && diagramStyles.nodeDragging,\n diagramDynamicStyles.box(x, y, item.width, item.height),\n ],\n },\n partOf(part, item as never, state),\n {\n ...dataAttrs({\n 'data-diagram-item': 'node',\n 'data-node': id,\n 'data-link-target': linkTarget || undefined,\n }),\n 'aria-roledescription': roleDescription,\n 'aria-label': label,\n onPointerdown: (event: PointerEvent) => actions.nodeDown(id, event),\n onPointerenter: () => actions.nodeEnter(id),\n onPointerleave: () => actions.nodeLeave(id),\n ...(focusable\n ? {\n role: 'button',\n tabindex: 0,\n 'aria-pressed': selectable ? selected : undefined,\n onClick: (event: MouseEvent) => actions.nodeClick(id, event),\n onKeydown: (event: KeyboardEvent) => actions.nodeKey(id, event),\n onFocus: (event: FocusEvent) =>\n actions.focus({ x, y, width: item.width, height: item.height }, event),\n }\n : { role: 'img' }),\n },\n )}\n >\n {render(item as never, state)}\n {ports &&\n SIDES.map((side) => (\n <span\n key={side}\n {...mergeAttrs<'span'>({ sx: [diagramStyles.port, portStyles[side]] }, portPart, {\n ...dataAttrs({ 'data-diagram-port': side }),\n 'aria-hidden': 'true',\n onPointerdown: (event: PointerEvent) => actions.portDown(id, side, event),\n })}\n />\n ))}\n </div>\n );\n },\n);\n\n/** 连线视图的属性:折线的数组只在这条线真的变了时才换(不动的线一直是同一个数组) */\ninterface EdgeViewProps {\n item: DiagramEdgeItem;\n points: readonly DiagramPoint[];\n label: string;\n roleDescription: string;\n radius: number;\n selected: boolean;\n selectable: boolean;\n part?: PartProps<'g'> | ((edge: never, state: DiagramItemState) => PartProps<'g'>);\n actions: ItemActions;\n}\n\n/** 一条连线:加粗的透明命中区域、线、箭头(改接的把手画在节点上面那层,见 Diagram) */\nconst EdgeView = _component(\n ({\n item,\n points,\n label,\n roleDescription,\n radius,\n selected,\n selectable,\n part,\n actions,\n }: EdgeViewProps) =>\n () => {\n const state: DiagramItemState = { selected };\n const path = polylinePath(trimEnd(points, ARROW * 0.7), radius);\n return (\n <g\n {...mergeAttrs<'g'>(\n {\n sx: [\n diagramStyles.edge,\n selectable && diagramStyles.edgeSelectable,\n item.tone && edgeToneStyles[item.tone],\n item.dashed && diagramStyles.edgeDashed,\n ],\n },\n partOf(part, item as never, state),\n {\n ...dataAttrs({ 'data-diagram-item': 'edge', 'data-edge': item.id }),\n ...(selectable\n ? {\n role: 'button',\n tabindex: 0,\n 'aria-roledescription': roleDescription,\n 'aria-label': label,\n 'aria-pressed': selected,\n onClick: (event: MouseEvent) => actions.edgeClick(item.id, event),\n onKeydown: (event: KeyboardEvent) => actions.edgeKey(item.id, event),\n onFocus: (event: FocusEvent) => actions.focus(boundsOf([], points)!, event),\n }\n : {}),\n },\n )}\n >\n {selectable && <path d={path} {...css.attrs(diagramStyles.edgeHit)} />}\n <path d={path} {...css.attrs(diagramStyles.edgeLine)} />\n <polygon points={arrowHead(points, ARROW)} {...css.attrs(diagramStyles.edgeArrow)} />\n </g>\n );\n },\n);\n\n/** 连线文字视图的属性 */\ninterface EdgeTextViewProps {\n item: DiagramEdgeItem;\n x: number;\n y: number;\n selected: boolean;\n render: (edge: never, state: DiagramItemState) => VNodeChild;\n part?: PartProps<'div'> | ((edge: never, state: DiagramItemState) => PartProps<'div'>);\n}\n\n/** 连线上的文字(HTML,画在连线上面);渲染函数返回空时不画 */\nconst EdgeTextView = _component(\n ({ item, x, y, selected, render, part }: EdgeTextViewProps) =>\n () => {\n const state: DiagramItemState = { selected };\n const text = render(item as never, state);\n if (text == null || text === false || text === '') return null;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.edgeText,\n item.tone && edgeTextToneStyles[item.tone],\n diagramDynamicStyles.at(x, y),\n ],\n },\n partOf(part, item as never, state),\n { 'aria-hidden': 'true' },\n )}\n >\n {text}\n </div>\n );\n },\n);\n\n/** 画布 */\nexport const Diagram = _component(\n <N extends DiagramNodeItem, E extends DiagramEdgeItem>({\n nodes,\n edges = [],\n children,\n getNodeLabel,\n getEdgeLabel,\n edgeText,\n height = 360,\n controller,\n selectable = false,\n _selected: selected = _bindable<DiagramSelection>(NO_SELECTION),\n dragMode = 'pan',\n selectionMode = 'full',\n grid = 'none',\n gridSize = 20,\n fitView = false,\n extent,\n routing = 'straight',\n edgeRadius = 6,\n draggable = false,\n snapToGrid = false,\n guides = true,\n onNodesMove,\n connectable = false,\n canConnect,\n onConnect,\n onReconnect,\n backdrop,\n overlay,\n propsWorld,\n propsNode,\n propsPort,\n propsEdge,\n propsEdgeText,\n propsMarquee,\n propsGuide,\n ...rest\n }: DiagramProps<N, E>) => {\n const messages = useMessages('diagram', diagramMessages);\n // 控制器只在创建时取:换控制器要换一个画布\n const diagram = _untrack(controller) ?? useDiagram();\n const internal = diagramInternals(diagram);\n DiagramContext.provide(diagram);\n\n // 框选框(视口坐标)、拖动中的节点、拖出来的连线、指针下的节点\n let marquee = _state.raw<DiagramRect | null>(null);\n let drag = _state.raw<DragState | null>(null);\n let link = _state.raw<LinkState | null>(null);\n let hovered = _state.raw<string | null>(null);\n // 按着空格:拖动一律平移(框选模式里平移的办法)\n let space = false;\n // 用户自己动过视口之后,尺寸变化不再自动适应\n let moved = false;\n\n /** 没给 children 时的节点:标题是无障碍名称的 DiagramNode */\n const defaultNode = (node: N) => <DiagramNode title={getNodeLabel(node)} />;\n const nodeById = _derived(new Map(nodes.map((node) => [node.id, node])));\n const draggableOf = (node: N) =>\n typeof draggable === 'function' ? draggable(node) : draggable;\n /** 节点现在的位置:拖动中的按拖到的位置 */\n const placed = (node: N): N =>\n drag?.ids.has(node.id) ? { ...node, x: node.x + drag.dx, y: node.y + drag.dy } : node;\n\n /** 不拖动时每条连线的折线:给了 points 用它,没给时按 routing 画;两端的节点缺了不画 */\n const restingRoutes = _derived.by(() => {\n const automatic = edges.filter((edge) => !hasPoints(edge));\n const routed = routing === 'orthogonal' ? routeEdges(nodes, automatic) : undefined;\n return edges.flatMap((edge): Route<E>[] => {\n if (hasPoints(edge)) return [{ edge, points: edge.points }];\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!from || !to) return [];\n return [{ edge, points: routed?.get(edge.id) ?? straightRoute(from, to) }];\n });\n });\n /** 拖动中:与动着的节点相连的线按 routing 实时重画,别的线不动 */\n const routes = _derived.by(() => {\n if (!drag) return restingRoutes;\n const moving = drag.ids;\n const touches = (edge: E) => moving.has(edge.from) || moving.has(edge.to);\n const list = nodes.map(placed);\n const byId = new Map(list.map((node) => [node.id, node]));\n const touched = edges.filter(touches);\n const routed = routing === 'orthogonal' ? routeEdges(list, touched) : undefined;\n return restingRoutes.map((route): Route<E> => {\n if (!touches(route.edge)) return route;\n const from = byId.get(route.edge.from);\n const to = byId.get(route.edge.to);\n if (!from || !to) return route;\n return { edge: route.edge, points: routed?.get(route.edge.id) ?? straightRoute(from, to) };\n });\n });\n const bounds = _derived(\n boundsOf(\n nodes,\n restingRoutes.flatMap((route) => route.points),\n ),\n );\n const selectedNodes = _derived(new Set(selected.nodes));\n const selectedEdges = _derived(new Set(selected.edges));\n\n internal.content = () => extent ?? bounds;\n internal.nodes = () => nodes.map(placed);\n const root = () => internal.element.value;\n const inOverlay = (target: EventTarget | null) =>\n target instanceof Element && target.closest('[data-diagram-overlay]') !== null;\n /** 事件发生在空白处:不在节点、连线、浮层里 */\n const onBackground = (target: EventTarget | null) =>\n target instanceof Element && !target.closest('[data-diagram-item],[data-diagram-overlay]');\n /** 这次按下要框选:可选择、在空白处、按的是主键,拖动方式是框选或按着 Shift */\n const startsMarquee = (event: PointerEvent) =>\n selectable &&\n !space &&\n event.button === 0 &&\n onBackground(event.target) &&\n (dragMode === 'select' || event.shiftKey);\n\n /** 视口(平移缩放)要不要处理这个事件;处理了就算用户动过视口 */\n function handlesViewport(event: PointerEvent | WheelEvent | MouseEvent | KeyboardEvent) {\n if (inOverlay(event.target)) return false;\n // 视口自己的按键(方向键平移、+ − 缩放)只在焦点就在视口上时生效,节点上的按键留给节点\n const handles =\n event.type === 'wheel'\n ? true\n : event.type === 'keydown'\n ? event.target === root()\n : space ||\n (onBackground(event.target) &&\n !(\n event.type === 'pointerdown' &&\n (dragMode === 'select' || (event as PointerEvent).shiftKey)\n ));\n if (handles) moved = true;\n return handles;\n }\n internal.filter = handlesViewport;\n\n // 量视口的大小(小地图用);fitView 时第一次有尺寸就适应内容,用户没动过视口时尺寸变化也重新适应\n useResizeObserver(root, () => {\n const element = root();\n if (!element) return;\n internal.size.value = { width: element.clientWidth, height: element.clientHeight };\n if (fitView && !moved && element.clientWidth > 0) diagram.fit();\n });\n\n /** 点了一项:加选键按着时切换它,否则只选它 */\n function choose(kind: 'nodes' | 'edges', id: string, toggle: boolean) {\n if (!selectable) return;\n if (!toggle) {\n selected = { nodes: kind === 'nodes' ? [id] : [], edges: kind === 'edges' ? [id] : [] };\n return;\n }\n const list = selected[kind];\n selected = {\n ...selected,\n [kind]: list.includes(id) ? list.filter((item) => item !== id) : [...list, id],\n };\n }\n\n const clear = () => {\n if (selected.nodes.length || selected.edges.length) selected = NO_SELECTION;\n };\n const selectAll = () => {\n selected = {\n nodes: nodes.map((node) => node.id),\n edges: routes.map((route) => route.edge.id),\n };\n };\n\n /**\n * 拖到视口边上时自动平移:指针停着不动也继续移,每移一帧调 onPan 让拖着的东西跟上指针\n * (拖动按指针的画布坐标算,视口挪了画布坐标就变了)\n */\n function edgePan(onPan: () => void) {\n let frame = 0;\n let speed = { x: 0, y: 0 };\n const tick = () => {\n frame = 0;\n if (!speed.x && !speed.y) return;\n internal.view.panTo(diagram.x + speed.x, diagram.y + speed.y);\n onPan();\n frame = requestAnimationFrame(tick);\n };\n return {\n follow(point: { clientX: number; clientY: number }) {\n const box = root()?.getBoundingClientRect();\n if (!box) return;\n const near = (distance: number) =>\n distance < EDGE_PAN ? Math.ceil((EDGE_PAN - distance) / 3) : 0;\n speed = {\n x: near(point.clientX - box.left) - near(box.right - point.clientX),\n y: near(point.clientY - box.top) - near(box.bottom - point.clientY),\n };\n if ((speed.x || speed.y) && !frame) frame = requestAnimationFrame(tick);\n },\n stop() {\n speed = { x: 0, y: 0 };\n if (frame) cancelAnimationFrame(frame);\n frame = 0;\n },\n };\n }\n\n /** 拖动期间按 Esc 取消:在捕获阶段拦下,不让它再去清空选择 */\n function cancelOnEscape(cancel: () => void) {\n const onKey = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n event.preventDefault();\n event.stopPropagation();\n cancel();\n };\n window.addEventListener('keydown', onKey, true);\n return () => window.removeEventListener('keydown', onKey, true);\n }\n\n function startMarquee(event: PointerEvent) {\n const element = root();\n if (!element || !startsMarquee(event)) return;\n const box = element.getBoundingClientRect();\n const origin = { x: event.clientX - box.left, y: event.clientY - box.top };\n const additive = event.ctrlKey || event.metaKey || (dragMode === 'select' && event.shiftKey);\n const base = additive ? selected : NO_SELECTION;\n const covers = (area: DiagramRect, rect: DiagramRect) =>\n selectionMode === 'partial' ? rectsIntersect(area, rect) : rectContains(area, rect);\n startMove(event, {\n threshold: 3,\n onMove: (point) => {\n const screen = rectFromCorners(origin, {\n x: point.clientX - box.left,\n y: point.clientY - box.top,\n });\n marquee = screen;\n const { x, y, scale } = diagram;\n const area = {\n x: (screen.x - x) / scale,\n y: (screen.y - y) / scale,\n width: screen.width / scale,\n height: screen.height / scale,\n };\n const next = {\n nodes: union(\n base.nodes,\n nodes.filter((node) => covers(area, node)).map((node) => node.id),\n ),\n edges: union(\n base.edges,\n routes\n .filter((route) => covers(area, boundsOf([], route.points)!))\n .map((route) => route.edge.id),\n ),\n };\n // 框到的没变时不写:画布只在选择真的变了才重新渲染\n if (!sameIds(next.nodes, selected.nodes) || !sameIds(next.edges, selected.edges)) {\n selected = next;\n }\n },\n onEnd: () => (marquee = null),\n });\n }\n\n /** 按在节点上:拖动它(选中的一起拖);按在节点里的输入框、按钮、端口上时不拖 */\n function startDrag(node: N, event: PointerEvent) {\n if (event.button !== 0 || space || !draggableOf(node)) return;\n const target = event.target as Element;\n if (\n target.closest(\n '[data-diagram-port],input,textarea,select,button,a,[contenteditable=\"true\"]',\n )\n ) {\n return;\n }\n const additive = toggles(event);\n const ids = selectedNodes.has(node.id)\n ? selected.nodes\n : additive\n ? [...selected.nodes, node.id]\n : [node.id];\n const moving = ids.flatMap((id) => {\n const item = nodeById.get(id);\n return item && draggableOf(item) ? [item] : [];\n });\n const others = nodes.filter((item) => !ids.includes(item.id));\n const start = diagram.toDiagram(event.clientX, event.clientY);\n let pointer = { clientX: event.clientX, clientY: event.clientY };\n let begun = false;\n let release = () => {};\n\n // 以按住的节点为准吸附网格与对齐线,算出整组挪多少\n const update = () => {\n const now = diagram.toDiagram(pointer.clientX, pointer.clientY);\n let x = node.x + now.x - start.x;\n let y = node.y + now.y - start.y;\n if (snapToGrid) {\n x = Math.round(x / gridSize) * gridSize;\n y = Math.round(y / gridSize) * gridSize;\n }\n let lines: DiagramGuide[] = [];\n if (guides) {\n const aligned = alignToGuides({ ...node, x, y }, others, GUIDE_TOLERANCE / diagram.scale);\n ({ x, y } = aligned);\n lines = aligned.guides;\n }\n drag = {\n ids: new Set(moving.map((item) => item.id)),\n dx: x - node.x,\n dy: y - node.y,\n guides: lines,\n };\n };\n const pan = edgePan(update);\n const cancel = startMove(event, {\n threshold: 3,\n onMove: (point) => {\n pointer = point;\n if (!begun) {\n begun = true;\n // 拖一个没选中的节点:选中它(按着加选键时加进原来的选择)\n if (selectable && !selectedNodes.has(node.id)) {\n selected = { nodes: ids, edges: additive ? selected.edges : [] };\n }\n release = cancelOnEscape(() => cancel());\n }\n update();\n pan.follow(point);\n },\n onEnd: ({ moved: dragged, cancelled }) => {\n pan.stop();\n release();\n const result = drag;\n drag = null;\n if (!dragged || cancelled || !result || (result.dx === 0 && result.dy === 0)) return;\n onNodesMove?.(\n moving.map((item) => ({ id: item.id, x: item.x + result.dx, y: item.y + result.dy })),\n );\n },\n });\n }\n\n /**\n * 拖一条连线:从 anchor 拉出来,松开在能连的节点上时 done(节点, 离指针最近的边)。\n * fixed 是不动的那一端的节点(连到它自己不算);fixedIsSource 时它是起点、箭头在指针一端\n */\n function startLink(\n event: PointerEvent,\n anchor: DiagramPoint,\n fixed: N,\n fixedIsSource: boolean,\n done: (target: N, side: DiagramSide) => void,\n ) {\n if (event.button !== 0) return;\n event.stopPropagation();\n event.preventDefault();\n let pointer = { clientX: event.clientX, clientY: event.clientY };\n let release = () => {};\n let landing: { node: N; side: DiagramSide } | null = null;\n const allowed = (candidate: N) =>\n candidate.id !== fixed.id &&\n (canConnect?.(fixedIsSource ? fixed : candidate, fixedIsSource ? candidate : fixed) ??\n true);\n const update = () => {\n const point = diagram.toDiagram(pointer.clientX, pointer.clientY);\n const hit = rectAt(nodes, point);\n landing = hit && allowed(hit) ? { node: hit, side: nearestSide(hit, point) } : null;\n const end = landing ? sidePoint(landing.node, landing.side) : point;\n link = {\n from: fixedIsSource ? anchor : end,\n to: fixedIsSource ? end : anchor,\n target: landing?.node.id ?? null,\n };\n };\n const pan = edgePan(update);\n update();\n const cancel = startMove(event, {\n // 端口、改接把手拖动中会消失:捕获放在画布上;松开时的 click 也落在画布上,不能当成点空白处\n captureTarget: root() ?? undefined,\n swallowClick: true,\n onMove: (point) => {\n pointer = point;\n update();\n pan.follow(point);\n },\n onEnd: ({ cancelled }) => {\n pan.stop();\n release();\n link = null;\n if (!cancelled && landing) done(landing.node, landing.side);\n },\n });\n release = cancelOnEscape(() => cancel());\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (event.key === ' ' && event.target === root()) space = true;\n if (!selectable) return;\n if (event.key === 'Escape') clear();\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {\n event.preventDefault();\n selectAll();\n }\n }\n\n /** 节点上的方向键:挪动(选中的一起挪,Shift 五步) */\n function nudge(node: N, event: KeyboardEvent) {\n const arrow = ARROWS[event.key];\n if (!arrow || !onNodesMove || !draggableOf(node)) return;\n event.preventDefault();\n const step = (snapToGrid ? gridSize : NUDGE) * (event.shiftKey ? 5 : 1);\n const ids = selectedNodes.has(node.id) ? selected.nodes : [node.id];\n onNodesMove(\n ids.flatMap((id) => {\n const item = nodeById.get(id);\n return item && draggableOf(item)\n ? [{ id, x: item.x + arrow[0] * step, y: item.y + arrow[1] * step }]\n : [];\n }),\n );\n }\n\n /** Enter / 空格:选中(同点击) */\n function activates(event: KeyboardEvent) {\n if (event.key !== 'Enter' && event.key !== ' ') return false;\n event.preventDefault();\n return true;\n }\n\n const actions: ItemActions = {\n nodeDown(id, event) {\n const node = nodeById.get(id);\n if (node) startDrag(node, event);\n },\n nodeClick: (id, event) => choose('nodes', id, toggles(event)),\n nodeKey(id, event) {\n const node = nodeById.get(id);\n if (!node) return;\n if (activates(event)) choose('nodes', id, toggles(event));\n else nudge(node, event);\n },\n nodeEnter: (id) => (hovered = id),\n nodeLeave(id) {\n if (hovered === id) hovered = null;\n },\n portDown(id, side, event) {\n const node = nodeById.get(id);\n if (!node) return;\n startLink(event, sidePoint(node, side), node, true, (target, toSide) =>\n onConnect?.({ from: id, to: target.id, fromSide: side, toSide }),\n );\n },\n edgeClick: (id, event) => choose('edges', id, toggles(event)),\n edgeKey(id, event) {\n if (activates(event)) choose('edges', id, toggles(event));\n },\n endDown(id, end, event) {\n const route = routes.find((item) => item.edge.id === id);\n const from = route && nodeById.get(route.edge.from);\n const to = route && nodeById.get(route.edge.to);\n if (!route || !from || !to || !onReconnect) return;\n const { points } = route;\n // 拖的是终点:不动的是起点,箭头在指针一端;拖的是起点:反过来\n const anchor = end === 'to' ? points[0]! : points[points.length - 1]!;\n startLink(event, anchor, end === 'to' ? from : to, end === 'to', (target, side) =>\n onReconnect({ edge: id, end, node: target.id, side }),\n );\n },\n // 键盘把焦点移到视口外的节点、连线时平移过去(鼠标点到的本来就看得见)\n focus(rect, event) {\n if (event.target instanceof Element && event.target.matches(':focus-visible')) {\n diagram.reveal(rect);\n }\n },\n };\n\n return () => {\n const { view } = internal;\n const focusable = selectable || !!onNodesMove;\n // 选中的连线两端的改接把手:两端的节点都在时才能改接\n const ends =\n connectable && onReconnect && !drag && !link\n ? routes.filter(\n ({ edge }) =>\n selectedEdges.has(edge.id) && nodeById.has(edge.from) && nodeById.has(edge.to),\n )\n : [];\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.root,\n diagramDynamicStyles.height(height),\n dragMode === 'select' && diagramStyles.rootSelect,\n diagramDynamicStyles.grid(grid, diagram.x, diagram.y, diagram.scale, gridSize),\n ],\n },\n rest,\n {\n ...view.viewportProps,\n ref: (element: unknown) => (internal.element.value = element as HTMLElement | null),\n role: 'group',\n tabindex: 0,\n 'aria-roledescription': messages.canvas,\n onPointerdown: (event: PointerEvent) => {\n startMarquee(event);\n (view.viewportProps.onPointerdown as (event: PointerEvent) => void)(event);\n },\n onClick: (event: MouseEvent) => {\n if (selectable && onBackground(event.target)) clear();\n },\n onKeydown: (event: KeyboardEvent) => {\n onKeydown(event);\n (view.viewportProps.onKeydown as (event: KeyboardEvent) => void)(event);\n },\n onKeyup: (event: KeyboardEvent) => {\n if (event.key === ' ') space = false;\n },\n onBlur: () => (space = false),\n // 焦点移到视口外的节点时浏览器会滚动视口(overflow: hidden 也能被滚动),视口的位置只由平移决定\n onScroll: (event: Event) => {\n const element = event.currentTarget as HTMLElement;\n element.scrollTop = 0;\n element.scrollLeft = 0;\n },\n },\n )}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.world,\n diagramDynamicStyles.world(diagram.x, diagram.y, diagram.scale),\n ],\n },\n propsWorld,\n dataAttrs({ 'data-diagram-world': true }),\n )}\n >\n {backdrop}\n {nodes.map((node) => {\n const at = placed(node);\n const isSelected = selectedNodes.has(node.id);\n return (\n <NodeView\n key={node.id}\n item={node}\n x={at.x}\n y={at.y}\n label={getNodeLabel(node)}\n roleDescription={messages.node}\n selected={isSelected}\n selectable={selectable}\n focusable={focusable}\n movable={draggableOf(node)}\n dragging={drag?.ids.has(node.id) ?? false}\n ports={\n connectable &&\n !drag &&\n (hovered === node.id || isSelected || link?.target === node.id)\n }\n linkTarget={link?.target === node.id}\n render={(children ?? defaultNode) as NodeViewProps['render']}\n part={propsNode as NodeViewProps['part']}\n portPart={propsPort}\n actions={actions}\n />\n );\n })}\n <svg\n {...css.attrs(diagramStyles.edges)}\n width=\"1\"\n height=\"1\"\n aria-hidden={selectable ? undefined : 'true'}\n >\n {routes.map(({ edge, points }) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n const isSelected = selectedEdges.has(edge.id);\n return (\n <EdgeView\n key={edge.id}\n item={edge}\n points={points}\n label={\n getEdgeLabel?.(edge) ??\n messages.edgeBetween(\n from ? getNodeLabel(from) : edge.from,\n to ? getNodeLabel(to) : edge.to,\n )\n }\n roleDescription={messages.edge}\n radius={edgeRadius}\n selected={isSelected}\n selectable={selectable}\n part={propsEdge as EdgeViewProps['part']}\n actions={actions}\n />\n );\n })}\n </svg>\n {edgeText &&\n routes.map(({ edge, points }) => {\n const at = drag || !edge.labelAt ? polylineMidpoint(points) : edge.labelAt;\n return (\n <EdgeTextView\n key={edge.id}\n item={edge}\n x={at.x}\n y={at.y}\n selected={selectedEdges.has(edge.id)}\n render={edgeText as EdgeTextViewProps['render']}\n part={propsEdgeText as EdgeTextViewProps['part']}\n />\n );\n })}\n {(!!drag?.guides.length || !!link || ends.length > 0) && (\n <svg\n {...css.attrs(diagramStyles.edges, diagramStyles.above)}\n width=\"1\"\n height=\"1\"\n aria-hidden=\"true\"\n data-diagram-transient=\"\"\n >\n {drag?.guides.map((guide, index) => (\n <line\n key={index}\n {...mergeAttrs<'line'>({ sx: diagramStyles.guide }, propsGuide, {\n x1: guide.from.x,\n y1: guide.from.y,\n x2: guide.to.x,\n y2: guide.to.y,\n })}\n />\n ))}\n {ends.flatMap(({ edge, points }) =>\n (['from', 'to'] as const).map((end) => {\n const at = end === 'from' ? points[0]! : points[points.length - 1]!;\n return (\n <circle\n key={`${edge.id}:${end}`}\n cx={at.x}\n cy={at.y}\n r={5}\n {...css.attrs(diagramStyles.edgeEnd)}\n data-diagram-end={end}\n onPointerdown={(event: PointerEvent) =>\n actions.endDown(edge.id, end, event)\n }\n />\n );\n }),\n )}\n {link && (\n <g {...css.attrs(diagramStyles.preview)}>\n <path\n d={polylinePath(trimEnd([link.from, link.to], ARROW * 0.7))}\n {...css.attrs(diagramStyles.edgeLine)}\n />\n <polygon\n points={arrowHead([link.from, link.to], ARROW)}\n {...css.attrs(diagramStyles.edgeArrow)}\n />\n </g>\n )}\n </svg>\n )}\n </div>\n {marquee && (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n diagramStyles.marquee,\n diagramDynamicStyles.box(marquee.x, marquee.y, marquee.width, marquee.height),\n ],\n },\n propsMarquee,\n )}\n />\n )}\n {overlay != null && (\n <div {...css.attrs(diagramStyles.overlay)} data-diagram-overlay=\"\">\n {overlay}\n </div>\n )}\n </div>\n );\n };\n },\n);\n\n/** 连线自己给了折线 */\nconst hasPoints = (\n edge: DiagramEdgeItem,\n): edge is DiagramEdgeItem & { points: readonly DiagramPoint[] } =>\n !!edge.points && edge.points.length >= 2;\n\n/** 两组标识合在一起,去掉重复 */\nconst union = (a: readonly string[], b: readonly string[]) => [...new Set([...a, ...b])];\n\n/** 两组标识是否相同(顺序无关) */\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false;\n const set = new Set(a);\n return b.every((id) => set.has(id));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyPA,IAAa,iBAAiB,cAAiC,SAAS;;AAGxE,IAAM,QAAQ;;AAEd,IAAM,WAAW;;AAEjB,IAAM,kBAAkB;;AAExB,IAAM,WAAW;;AAEjB,IAAM,QAAQ;AACd,IAAM,eAAiC;CAAE,OAAO,CAAA;CAAI,OAAO,CAAA;AAAG;AAC9D,IAAM,QAAgC;CAAC;CAAO;CAAS;CAAU;AAAM;;AAGvE,IAAa,gBAAgB,IAAI,OAAO;CACtC,MAAM;EACJ,UAAU;EACV,UAAU;EACV,iBAAiB;EACjB,aAAa;EACb,aAAa;EACb,aAAa;EACb,cAAc;EACd,UAAU;EACV,OAAO;EAEP,YAAY;EACZ,QAAQ;GAAE,SAAS;GAAQ,WAAW;EAAW;EACjD,cAAc;GAAE,SAAS;GAAQ,kBAAkB;EAAQ;EAC3D,cAAc;EACd,cAAc;EACd,eAAe;CACjB;CACA,YAAY,EAAE,QAAQ,UAAU;CAChC,OAAO;EACL,UAAU;EACV,MAAM;EACN,KAAK;EACL,OAAO;EACP,QAAQ;EACR,iBAAiB;EAEjB,WAAW;CACb;CACA,OAAO;EACL,UAAU;EACV,MAAM;EACN,KAAK;EACL,QAAQ;EACR,UAAU;EACV,eAAe;CACjB;CAEA,OAAO,EAAE,QAAQ,EAAE;CACnB,MAAM;EACJ,OAAO;GAAE,SAAS;GAAiB,UAAU;GAAW,kBAAkB;EAAU;EACpF,aAAa;GAAE,SAAS;GAAK,UAAU;GAAK,kBAAkB;EAAI;EAClE,cAAc;CAChB;CACA,gBAAgB;EACd,QAAQ;EAER,OAAO;GACL,SAAS;GACT,UAAU;IAAE,SAAS;IAAc,UAAU;GAAU;GACvD,UAAU;GACV,kBAAkB;EACpB;CACF;CACA,YAAY,EAAE,iBAAiB,MAAM;CACrC,UAAU;EACR,MAAM;EACN,QAAQ;EACR,eAAe;EACf,gBAAgB;CAClB;CACA,WAAW;EAAE,MAAM;EAAgB,QAAQ;CAAO;CAElD,SAAS;EAAE,MAAM;EAAQ,QAAQ;EAAe,aAAa;EAAI,eAAe;CAAS;CACzF,SAAS;EACP,MAAM;EACN,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,eAAe;CACjB;CACA,SAAS;EACP,OAAO;EACP,aAAa;EACb,iBAAiB;CACnB;CACA,OAAO;EAAE,QAAQ;EAAW,aAAa;EAAG,iBAAiB;CAAM;CACnE,UAAU;EACR,UAAU;EACV,MAAM;EACN,KAAK;EACL,QAAQ;EACR,eAAe;EACf,cAAc;EACd,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,OAAO;EACP,iBAAiB;EACjB,eAAe;CACjB;CACA,MAAM;EACJ,UAAU;EACV,MAAM;EACN,KAAK;EACL,QAAQ;EACR,SAAS;EACT,WAAW;EAEX,cAAc;GAAE,SAAS;GAAO,yCAAuC;EAAQ;EAC/E,cAAc;GACZ,SAAS;GACT,UAAU;GACV,kBAAkB;GAClB,sBAAsB;EACxB;EACA,cAAc;EACd,cAAc;GAAE,SAAS;GAAW,kBAAkB;EAAa;EACnE,eAAe;CACjB;CACA,gBAAgB,EAAE,QAAQ,UAAU;CACpC,eAAe,EAAE,QAAQ;EAAE,SAAS;EAAQ,WAAW;CAAW,EAAE;CACpE,cAAc;EAAE,QAAQ;EAAY,SAAS;CAAI;CACjD,MAAM;EACJ,UAAU;EACV,OAAO;EACP,QAAQ;EACR,WAAW;EACX,cAAc;EACd,aAAa;EACb,aAAa;EACb,aAAa;EACb,iBAAiB;EACjB,QAAQ;EACR,WAAW;GAAE,SAAS;GAAyB,UAAU;EAAmC;EAC5F,YAAY,aAAa,EAAE,UAAU,GAAE,GAAI,EAAE,QAAQ;CACvD;CACA,SAAS;EAAE,MAAM;EAAO,KAAK;CAAE;CAC/B,WAAW;EAAE,MAAM;EAAQ,KAAK;CAAM;CACtC,YAAY;EAAE,MAAM;EAAO,KAAK;CAAO;CACvC,UAAU;EAAE,MAAM;EAAG,KAAK;CAAM;CAChC,SAAS;EACP,UAAU;EACV,MAAM;EACN,KAAK;EACL,QAAQ;EACR,eAAe;EACf,aAAa;EACb,aAAa;EACb,aAAa;EACb,cAAc;EACd,iBAAiB,sBAAsB,EAAE,OAAO,OAAM;CACxD;CACA,SAAS;EAAE,UAAU;EAAY,OAAO;EAAG,QAAQ;EAAG,eAAe;CAAO;AAC9E,CAAC;;AAGD,IAAM,SAAS,WAAmB,EAChC,OAAO;CAAE,SAAS;CAAO,UAAU;CAAW,kBAAkB;AAAU,EAC5E;;AAGA,IAAM,iBAAiB,IAAI,OAAO;CAChC,SAAS,CAAC;CACV,QAAQ,MAAM,SAAS;CACvB,MAAM,MAAM,WAAW;CACvB,SAAS,MAAM,cAAc;CAC7B,SAAS,MAAM,cAAc;CAC7B,QAAQ,MAAM,aAAa;AAC7B,CAAC;;AAGD,IAAM,qBAAqB,IAAI,OAAO;CACpC,SAAS,CAAC;CACV,QAAQ,EAAE,OAAO,cAAc;CAC/B,MAAM,EAAE,OAAO,YAAY;CAC3B,SAAS,EAAE,OAAO,eAAe;CACjC,SAAS,EAAE,OAAO,eAAe;CACjC,QAAQ,EAAE,OAAO,cAAc;AACjC,CAAC;AAED,IAAM,aAAgE;CACpE,KAAK,cAAc;CACnB,OAAO,cAAc;CACrB,QAAQ,cAAc;CACtB,MAAM,cAAc;AACtB;;AAGA,IAAM,aAAiD;CACrD,MAAM;CACN,MAAM,2BAA2B,EAAE,OAAO,aAAY;CACtD,OAAO,mBAAmB,EAAE,OAAO,YAAW,iDAAkD,EAAE,OAAO,YAAW;AACtH;;AAGA,IAAa,uBAAuB,IAAI,OAAO;CAC7C,QAAQ,GAAW,GAAW,WAAmB,EAC/C,WAAW,aAAa,EAAC,MAAO,EAAC,YAAa,MAAK,GACrD;CACA,OAAO,MAA0B,GAAW,GAAW,OAAe,aAAqB;EACzF,MAAM,OAAO,WAAW,QAAQ,WAAW,WAAW,QAAQ,IAAI,WAAW;EAC7E,OAAO;GACL,iBAAiB,WAAW;GAC5B,gBAAgB,GAAG,KAAI,KAAM,KAAI;GACjC,oBAAoB,GAAG,EAAC,KAAM,EAAC;EACjC;CACF;CACA,MAAM,GAAW,GAAW,OAAe,YAAoB;EAC7D,WAAW,aAAa,EAAC,MAAO,EAAC;EACjC;EACA;CACF;CACA,KAAK,GAAW,OAAe,EAAE,WAAW,aAAa,EAAC,MAAO,EAAC,2BAA4B;CAC9F,SAAS,YAA6B,EAAE,OAAO;AACjD,CAAC;;AAGD,SAAS,OAA+B,MAA2C,GAAG,MAAS;CAC7F,OAAO,OAAO,SAAS,aAAc,KAA2B,GAAG,IAAI,IAAI;AAC7E;;AAGA,IAAM,WAAW,UACf,MAAM,YAAY,MAAM,WAAW,MAAM;;AAG3C,IAAM,SAAoD;CACxD,WAAW,CAAC,IAAI,CAAC;CACjB,YAAY,CAAC,GAAG,CAAC;CACjB,SAAS,CAAC,GAAG,EAAE;CACf,WAAW,CAAC,GAAG,CAAC;AAClB;;;;;;;;;;AA6DA,IAAM,WAAW,0BACf,QAAA,SAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,IAAAA,aAAA,QAAA,GAAA;CAAA,MAAA,IAAAA,aAAA,QAAA,GAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,kBAAAA,aAAA,QAAA,iBAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,aAkBQ;EACJ,MAAM,QAA0B,EAAE,UAAQ,SAAA,MAAC;EAC3C,MAAM,KAAK,KAAA,MAAK;EAChB,OAAAC,YAAA,OAEQ,WACF,EACE,IAAI;GACF,cAAc;GACd,WAAA,SAAc,cAAc;GAC5B,WAAA,SAAc,uBAAuB;GACrC,QAAA,SAAW,cAAc;GACzB,SAAA,SAAY,cAAc;GAAY,IAAA,KACtC,qBAAqB,WAAG;IAAA,EAAA;IAAA,EAAA;IAAO,KAAA,MAAK;IAAO,KAAA,MAAK;GAAM,GAAA,IAAA;EAAA,EAE1D,GACA,OAAM,KAAA,OAAA,KAAA,OAAsB,KAAK,GACjC;GACE,GAAG,UAAU;IACX,qBAAqB;IACrB,aAAa;IACb,oBAAoB,WAAA,SAAc,KAAA;GACpC,CAAC;GACD,wBAAsB,gBAAA;GACtB,cAAY,MAAA;GACZ,gBAAgB,UAAwB,QAAA,MAAQ,SAAS,IAAI,KAAK;GAClE,sBAAsB,QAAA,MAAQ,UAAU,EAAE;GAC1C,sBAAsB,QAAA,MAAQ,UAAU,EAAE;GAC1C,GAAI,UAAA,QACA;IACE,MAAM;IACN,UAAU;IACV,gBAAgB,WAAA,QAAA,SAAA,QAAwB,KAAA;IACxC,UAAU,UAAsB,QAAA,MAAQ,UAAU,IAAI,KAAK;IAC3D,YAAY,UAAyB,QAAA,MAAQ,QAAQ,IAAI,KAAK;IAC9D,UAAU,UACR,QAAA,MAAQ,MAAM;KAAE,GAAC,EAAA;KAAE,GAAC,EAAA;KAAE,OAAO,KAAA,MAAK;KAAO,QAAQ,KAAA,MAAK;IAAO,GAAG,KAAK;GACzE,IACA,EAAE,MAAM,MAAM;EACpB,CACF,GAAC,CAEA,OAAA,MAAA,KAAA,OAAsB,KAAK,GAC3B,MAAA,SACC,MAAM,KAAK,SAAIA,YAAA,QAAAC,cAAA,EAAA,OAEN,KAAI,GACL,WAAmB,EAAE,IAAI,CAAC,cAAc,MAAM,WAAW,KAAK,EAAE,GAAC,SAAA,OAAY;GAC/E,GAAG,UAAU,EAAE,qBAAqB,KAAK,CAAC;GAC1C,eAAe;GACf,gBAAgB,UAAwB,QAAA,MAAQ,SAAS,IAAI,MAAM,KAAK;EAC1E,CAAC,CAAC,GAAA,IAAA,CAEL,CAAC,CAAA;CAGV;AAAC,GAAA;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACL;;;AAgBA,IAAM,WAAW,0BACf,SAAA,UAAA;CAAA,MAAA,OAAAF,aAAA,SAAA,MAAA;CAAA,MAAA,SAAAA,aAAA,SAAA,QAAA;CAAA,MAAA,QAAAA,aAAA,SAAA,OAAA;CAAA,MAAA,kBAAAA,aAAA,SAAA,iBAAA;CAAA,MAAA,SAAAA,aAAA,SAAA,QAAA;CAAA,MAAA,WAAAA,aAAA,SAAA,UAAA;CAAA,MAAA,aAAAA,aAAA,SAAA,YAAA;CAAA,MAAA,OAAAA,aAAA,SAAA,MAAA;CAAA,MAAA,UAAAA,aAAA,SAAA,SAAA;CAAA,aAWQ;EACJ,MAAM,QAA0B,EAAE,UAAQ,SAAA,MAAC;EAC3C,MAAM,OAAO,aAAa,QAAO,OAAA,OAAS,QAAQ,EAAG,GAAC,OAAA,KAAQ;EAC9D,OAAAC,YAAA,KAEQ,WACF,EACE,IAAI;GACF,cAAc;GACd,WAAA,SAAc,cAAc;GAAc,IAAA,aAC1C,KAAA,MAAK,QAAQ,eAAe,KAAA,MAAK,OAAK,IAAA;GAAA,IAAA,aACtC,KAAA,MAAK,UAAU,cAAc,YAAU,IAAA;EAAA,EAE3C,GACA,OAAM,KAAA,OAAA,KAAA,OAAsB,KAAK,GACjC;GACE,GAAG,UAAU;IAAE,qBAAqB;IAAQ,aAAa,KAAA,MAAK;GAAG,CAAC;GAClE,GAAI,WAAA,QACA;IACE,MAAM;IACN,UAAU;IACV,wBAAsB,gBAAA;IACtB,cAAY,MAAA;IACZ,gBAAc,SAAA;IACd,UAAU,UAAsB,QAAA,MAAQ,UAAU,KAAA,MAAK,IAAI,KAAK;IAChE,YAAY,UAAyB,QAAA,MAAQ,QAAQ,KAAA,MAAK,IAAI,KAAK;IACnE,UAAU,UAAsB,QAAA,MAAQ,MAAM,SAAS,CAAA,GAAE,OAAA,KAAQ,GAAI,KAAK;GAC5E,IACA,CAAC;EACP,CACF,GAAC;GAEA,WAAA,SAAAA,YAAA,QAAAC,cAAA,EAAA,KAAuB,KAAI,GAAM,IAAI,MAAM,cAAc,OAAO,CAAC,GAAA,IAAA;GAAID,YAAA,QAAAC,cAAA,EAAA,KAC7D,KAAI,GAAM,IAAI,MAAM,cAAc,QAAQ,CAAC,GAAA,IAAA;GAAAD,YAAA,WAAAC,cAAA,EAAA,UACnC,UAAS,OAAA,OAAS,KAAK,EAAC,GAAM,IAAI,MAAM,cAAc,SAAS,CAAC,GAAA,IAAA;EAAA,CAAA;CAGvF;AAAC,GAAA;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACL;;;AAaA,IAAM,eAAe,0BACnB,SAAA,UAAA;CAAA,MAAA,OAAAF,aAAA,SAAA,MAAA;CAAA,MAAA,IAAAA,aAAA,SAAA,GAAA;CAAA,MAAA,IAAAA,aAAA,SAAA,GAAA;CAAA,MAAA,WAAAA,aAAA,SAAA,UAAA;CAAA,MAAA,SAAAA,aAAA,SAAA,QAAA;CAAA,MAAA,OAAAA,aAAA,SAAA,MAAA;CAAA,aACQ;EACJ,MAAM,QAA0B,EAAE,UAAQ,SAAA,MAAC;EAC3C,MAAM,OAAO,OAAA,MAAA,KAAA,OAAsB,KAAK;EACxC,IAAI,QAAQ,QAAQ,SAAS,SAAS,SAAS,IAAI,OAAO;EAC1D,OAAAC,YAAA,OAEQ,WACF,EACE,IAAI;GACF,cAAc;GAAQ,IAAA,aACtB,KAAA,MAAK,QAAQ,mBAAmB,KAAA,MAAK,OAAK,IAAA;GAAA,IAAA,KAC1C,qBAAqB,UAAE,CAAA,EAAA,OAAA,EAAA,KAAA,GAAA,IAAA;EAAA,EAE3B,GACA,OAAM,KAAA,OAAA,KAAA,OAAsB,KAAK,GACjC,EAAE,eAAe,OAAO,CAC1B,GAAC,CAEA,IAAI,CAAA;CAGX;AAAC,GAAA;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACL;;AAGA,IAAa,UAAU,0BACrB,SAAA,UAqC0B;CAAA,MAAA,QAAAD,aAAA,SAAA,OAAA;CAAA,MAAA,QAAAA,aAAA,SAAA,eAnChB,CAAA,CAAE;CAAA,MAAA,WAAAG,aAAA,OAAA;CAAA,MAAA,eAAAH,aAAA,SAAA,cAAA;CAAA,MAAA,eAAAA,aAAA,SAAA,cAAA;CAAA,MAAA,WAAAA,aAAA,SAAA,UAAA;CAAA,MAAA,SAAAA,aAAA,SAAA,UAKD,GAAG;CAAA,MAAA,aAAAA,aAAA,SAAA,YAAA;CAAA,MAAA,aAAAA,aAAA,SAAA,cAEC,KAAK;CAAA,MAAA,WAAAI,SAAA,SAAA,mBACgC,cAAY,MAAA,IAAA;CAAA,MAAA,WAAAJ,aAAA,SAAA,YACnD,KAAK;CAAA,MAAA,gBAAAA,aAAA,SAAA,iBACA,MAAM;CAAA,MAAA,OAAAA,aAAA,SAAA,QACf,MAAM;CAAA,MAAA,WAAAA,aAAA,SAAA,YACF,EAAE;CAAA,MAAA,UAAAA,aAAA,SAAA,WACH,KAAK;CAAA,MAAA,SAAAA,aAAA,SAAA,QAAA;CAAA,MAAA,UAAAA,aAAA,SAAA,WAEL,UAAU;CAAA,MAAA,aAAAA,aAAA,SAAA,cACP,CAAC;CAAA,MAAA,YAAAA,aAAA,SAAA,aACF,KAAK;CAAA,MAAA,aAAAA,aAAA,SAAA,cACJ,KAAK;CAAA,MAAA,SAAAA,aAAA,SAAA,UACT,IAAI;CAAA,MAAA,cAAAA,aAAA,SAAA,aAAA;CAAA,MAAA,cAAAA,aAAA,SAAA,eAEC,KAAK;CAAA,MAAA,aAAAA,aAAA,SAAA,YAAA;CAAA,MAAA,YAAAA,aAAA,SAAA,WAAA;CAAA,MAAA,cAAAA,aAAA,SAAA,aAAA;CAAA,MAAA,WAAAA,aAAA,SAAA,UAAA;CAAA,MAAA,UAAAA,aAAA,SAAA,SAAA;CAAA,MAAA,aAAAA,aAAA,SAAA,YAAA;CAAA,MAAA,YAAAA,aAAA,SAAA,WAAA;CAAA,MAAA,YAAAA,aAAA,SAAA,WAAA;CAAA,MAAA,YAAAA,aAAA,SAAA,WAAA;CAAA,MAAA,gBAAAA,aAAA,SAAA,eAAA;CAAA,MAAA,eAAAA,aAAA,SAAA,cAAA;CAAA,MAAA,aAAAA,aAAA,SAAA,YAAA;CAAA,MAahB,OAAIK,UAAA,SAAA,OAAA,KAAA;CAEP,MAAM,WAAW,YAAY,WAAW,eAAe;CAEvD,MAAM,UAAUC,cAAA,WAAA,KAAA,KAAwB,WAAW;CACnD,MAAM,WAAW,iBAAiB,OAAO;CACzC,eAAe,QAAQ,OAAO;CAG9B,IAAI,UAAOC,WAAkC,IAAI;CACjD,IAAI,OAAIA,WAAgC,IAAI;CAC5C,IAAI,OAAIA,WAAgC,IAAI;CAC5C,IAAI,UAAOA,WAA6B,IAAI;CAE5C,IAAI,QAAQ;CAEZ,IAAI,QAAQ;;CAGZ,MAAM,eAAe,SAAON,YAAA,aAAA,EAAA,SAAyB,aAAA,MAAa,IAAI,EAAC,GAAA,IAAA;CACvE,MAAM,WAAQO,eAAY,IAAI,IAAI,MAAA,MAAM,KAAK,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;CACvE,MAAM,eAAe,SACnB,OAAA,UAAA,UAAqB,aAAa,UAAA,MAAU,IAAI,IAAC,UAAA;;CAEnD,MAAM,UAAU,SACd,KAAA,OAAM,IAAI,IAAI,KAAK,EAAE,IAAI;EAAE,GAAG;EAAM,GAAG,KAAK,IAAI,KAAA,MAAK;EAAI,GAAG,KAAK,IAAI,KAAA,MAAK;CAAG,IAAI;;CAGnF,MAAM,gBAAaA,eAAqB;EACtC,MAAM,YAAY,MAAA,MAAM,QAAQ,SAAS,CAAC,UAAU,IAAI,CAAC;EACzD,MAAM,SAAS,QAAA,UAAY,eAAe,WAAU,MAAA,OAAQ,SAAS,IAAI,KAAA;EACzE,OAAO,MAAA,MAAM,SAAS,SAAqB;GACzC,IAAI,UAAU,IAAI,GAAG,OAAO,CAAC;IAAE;IAAM,QAAQ,KAAK;GAAO,CAAC;GAC1D,MAAM,OAAO,SAAA,MAAS,IAAI,KAAK,IAAI;GACnC,MAAM,KAAK,SAAA,MAAS,IAAI,KAAK,EAAE;GAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAA;GACzB,OAAO,CAAC;IAAE;IAAM,QAAQ,QAAQ,IAAI,KAAK,EAAE,KAAK,cAAc,MAAM,EAAE;GAAE,CAAC;EAC3E,CAAC;CACH,CAAC;;CAED,MAAM,SAAMA,eAAqB;EAC/B,IAAI,CAAA,KAAA,OAAO,OAAA,cAAA;EACX,MAAM,SAAS,KAAA,MAAK;EACpB,MAAM,WAAW,SAAY,OAAO,IAAI,KAAK,IAAI,KAAK,OAAO,IAAI,KAAK,EAAE;EACxE,MAAM,OAAO,MAAA,MAAM,IAAI,MAAM;EAC7B,MAAM,OAAO,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;EACxD,MAAM,UAAU,MAAA,MAAM,OAAO,OAAO;EACpC,MAAM,SAAS,QAAA,UAAY,eAAe,WAAW,MAAM,OAAO,IAAI,KAAA;EACtE,OAAO,cAAA,MAAc,KAAK,UAAoB;GAC5C,IAAI,CAAC,QAAQ,MAAM,IAAI,GAAG,OAAO;GACjC,MAAM,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI;GACrC,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,EAAE;GACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,OAAO;GACzB,OAAO;IAAE,MAAM,MAAM;IAAM,QAAQ,QAAQ,IAAI,MAAM,KAAK,EAAE,KAAK,cAAc,MAAM,EAAE;GAAE;EAC3F,CAAC;CACH,CAAC;CACD,MAAM,SAAMA,eACV,SAAQ,MAAA,OAEN,cAAA,MAAc,SAAS,UAAU,MAAM,MAAM,CAC/C,CAAC;CAEH,MAAM,gBAAaA,eAAY,IAAI,IAAI,SAAA,MAAS,KAAK,CAAC;CACtD,MAAM,gBAAaA,eAAY,IAAI,IAAI,SAAA,MAAS,KAAK,CAAC;CAEtD,SAAS,gBAAgB,OAAA,SAAA,OAAA;CACzB,SAAS,cAAc,MAAA,MAAM,IAAI,MAAM;CACvC,MAAM,aAAa,SAAS,QAAQ;CACpC,MAAM,aAAa,WACjB,kBAAkB,WAAW,OAAO,QAAQ,wBAAwB,MAAM;;CAE5E,MAAM,gBAAgB,WACpB,kBAAkB,WAAW,CAAC,OAAO,QAAQ,4CAA4C;;CAE3F,MAAM,iBAAiB,UACrB,WAAA,SACA,CAAC,SACD,MAAM,WAAW,KACjB,aAAa,MAAM,MAAM,MACxB,SAAA,UAAa,YAAY,MAAM;;CAGlC,SAAS,gBAAgB,OAA+D;EACtF,IAAI,UAAU,MAAM,MAAM,GAAG,OAAO;EAEpC,MAAM,UACJ,MAAM,SAAS,UACX,OACA,MAAM,SAAS,YACb,MAAM,WAAW,KAAK,IACtB,SACC,aAAa,MAAM,MAAM,KACxB,EACE,MAAM,SAAS,kBACd,SAAA,UAAa,YAAa,MAAuB;EAE9D,IAAI,SAAS,QAAQ;EACrB,OAAO;CACT;CACA,SAAS,SAAS;CAGlB,kBAAkB,YAAY;EAC5B,MAAM,UAAU,KAAK;EACrB,IAAI,CAAC,SAAS;EACd,SAAS,KAAK,QAAQ;GAAE,OAAO,QAAQ;GAAa,QAAQ,QAAQ;EAAa;EACjF,IAAI,QAAA,SAAW,CAAC,SAAS,QAAQ,cAAc,GAAG,QAAQ,IAAI;CAChE,CAAC;;CAGD,SAAS,OAAO,MAAyB,IAAY,QAAiB;EACpE,IAAI,CAAA,WAAA,OAAa;EACjB,IAAI,CAAC,QAAQ;GACX,SAAA,QAAW;IAAE,OAAO,SAAS,UAAU,CAAC,EAAE,IAAI,CAAA;IAAI,OAAO,SAAS,UAAU,CAAC,EAAE,IAAI,CAAA;GAAG;GACtF;EACF;EACA,MAAM,OAAO,SAAA,MAAS;EACtB,SAAA,QAAW;GACT,GAAA,SAAA;IACC,OAAO,KAAK,SAAS,EAAE,IAAI,KAAK,QAAQ,SAAS,SAAS,EAAE,IAAI,CAAC,GAAG,MAAM,EAAE;EAC/E;CACF;CAEA,MAAM,cAAc;EAClB,IAAI,SAAA,MAAS,MAAM,UAAU,SAAA,MAAS,MAAM,QAAQ,SAAA,QAAW;CACjE;CACA,MAAM,kBAAkB;EACtB,SAAA,QAAW;GACT,OAAO,MAAA,MAAM,KAAK,SAAS,KAAK,EAAE;GAClC,OAAO,OAAA,MAAO,KAAK,UAAU,MAAM,KAAK,EAAE;EAC5C;CACF;;;;;CAMA,SAAS,QAAQ,OAAmB;EAClC,IAAI,QAAQ;EACZ,IAAI,QAAQ;GAAE,GAAG;GAAG,GAAG;EAAE;EACzB,MAAM,aAAa;GACjB,QAAQ;GACR,IAAI,CAAC,MAAM,KAAK,CAAC,MAAM,GAAG;GAC1B,SAAS,KAAK,MAAM,QAAQ,IAAI,MAAM,GAAG,QAAQ,IAAI,MAAM,CAAC;GAC5D,MAAM;GACN,QAAQ,sBAAsB,IAAI;EACpC;EACA,OAAO;GACL,OAAO,OAA6C;IAClD,MAAM,MAAM,KAAK,CAAC,EAAE,sBAAsB;IAC1C,IAAI,CAAC,KAAK;IACV,MAAM,QAAQ,aACZ,WAAW,WAAW,KAAK,MAAM,WAAW,YAAY,CAAC,IAAI;IAC/D,QAAQ;KACN,GAAG,KAAK,MAAM,UAAU,IAAI,IAAI,IAAI,KAAK,IAAI,QAAQ,MAAM,OAAO;KAClE,GAAG,KAAK,MAAM,UAAU,IAAI,GAAG,IAAI,KAAK,IAAI,SAAS,MAAM,OAAO;IACpE;IACA,KAAK,MAAM,KAAK,MAAM,MAAM,CAAC,OAAO,QAAQ,sBAAsB,IAAI;GACxE;GACA,OAAO;IACL,QAAQ;KAAE,GAAG;KAAG,GAAG;IAAE;IACrB,IAAI,OAAO,qBAAqB,KAAK;IACrC,QAAQ;GACV;EACF;CACF;;CAGA,SAAS,eAAe,QAAoB;EAC1C,MAAM,SAAS,UAAyB;GACtC,IAAI,MAAM,QAAQ,UAAU;GAC5B,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,OAAO;EACT;EACA,OAAO,iBAAiB,WAAW,OAAO,IAAI;EAC9C,aAAa,OAAO,oBAAoB,WAAW,OAAO,IAAI;CAChE;CAEA,SAAS,aAAa,OAAqB;EACzC,MAAM,UAAU,KAAK;EACrB,IAAI,CAAC,WAAW,CAAC,cAAc,KAAK,GAAG;EACvC,MAAM,MAAM,QAAQ,sBAAsB;EAC1C,MAAM,SAAS;GAAE,GAAG,MAAM,UAAU,IAAI;GAAM,GAAG,MAAM,UAAU,IAAI;EAAI;EAEzE,MAAM,OADW,MAAM,WAAW,MAAM,WAAY,SAAA,UAAa,YAAY,MAAM,WAC9D,SAAA,QAAc;EACnC,MAAM,UAAU,MAAmB,SACjC,cAAA,UAAkB,YAAY,eAAe,MAAM,IAAI,IAAI,aAAa,MAAM,IAAI;EACpF,UAAU,OAAO;GACf,WAAW;GACX,SAAS,UAAU;IACjB,MAAM,SAAS,gBAAgB,QAAQ;KACrC,GAAG,MAAM,UAAU,IAAI;KACvB,GAAG,MAAM,UAAU,IAAI;IACzB,CAAC;IACD,QAAA,QAAU;IACV,MAAM,EAAE,GAAG,GAAG,UAAU;IACxB,MAAM,OAAO;KACX,IAAI,OAAO,IAAI,KAAK;KACpB,IAAI,OAAO,IAAI,KAAK;KACpB,OAAO,OAAO,QAAQ;KACtB,QAAQ,OAAO,SAAS;IAC1B;IACA,MAAM,OAAO;KACX,OAAO,MACL,KAAK,OACL,MAAA,MAAM,QAAQ,SAAS,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,KAAK,EAAE,CAClE;KACA,OAAO,MACL,KAAK,OACL,OAAA,MACG,QAAQ,UAAU,OAAO,MAAM,SAAS,CAAA,GAAI,MAAM,MAAM,CAAE,CAAC,CAAC,CAC5D,KAAK,UAAU,MAAM,KAAK,EAAE,CACjC;IACF;IAEA,IAAI,CAAC,QAAQ,KAAK,OAAO,SAAA,MAAS,KAAK,KAAK,CAAC,QAAQ,KAAK,OAAO,SAAA,MAAS,KAAK,GAC7E,SAAA,QAAW;GAEf;GACA,aAAc,QAAA,QAAU;EAC1B,CAAC;CACH;;CAGA,SAAS,UAAU,MAAS,OAAqB;EAC/C,IAAI,MAAM,WAAW,KAAK,SAAS,CAAC,YAAY,IAAI,GAAG;EAEvD,IADe,MAAM,OAEZ,QACL,+EACF,GAEA;EAEF,MAAM,WAAW,QAAQ,KAAK;EAC9B,MAAM,MAAM,cAAA,MAAc,IAAI,KAAK,EAAE,IACjC,SAAA,MAAS,QACT,WACE,CAAC,GAAG,SAAA,MAAS,OAAO,KAAK,EAAE,IAC3B,CAAC,KAAK,EAAE;EACd,MAAM,SAAS,IAAI,SAAS,OAAO;GACjC,MAAM,OAAO,SAAA,MAAS,IAAI,EAAE;GAC5B,OAAO,QAAQ,YAAY,IAAI,IAAI,CAAC,IAAI,IAAI,CAAA;EAC9C,CAAC;EACD,MAAM,SAAS,MAAA,MAAM,QAAQ,SAAS,CAAC,IAAI,SAAS,KAAK,EAAE,CAAC;EAC5D,MAAM,QAAQ,QAAQ,UAAU,MAAM,SAAS,MAAM,OAAO;EAC5D,IAAI,UAAU;GAAE,SAAS,MAAM;GAAS,SAAS,MAAM;EAAQ;EAC/D,IAAI,QAAQ;EACZ,IAAI,gBAAgB,CAAC;EAGrB,MAAM,eAAe;GACnB,MAAM,MAAM,QAAQ,UAAU,QAAQ,SAAS,QAAQ,OAAO;GAC9D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM;GAC/B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM;GAC/B,IAAA,WAAA,OAAgB;IACd,IAAI,KAAK,MAAM,IAAC,SAAA,KAAW,IAAC,SAAA;IAC5B,IAAI,KAAK,MAAM,IAAC,SAAA,KAAW,IAAC,SAAA;GAC9B;GACA,IAAI,QAAwB,CAAA;GAC5B,IAAA,OAAA,OAAY;IACV,MAAM,UAAU,cAAc;KAAE,GAAG;KAAM;KAAG;IAAE,GAAG,QAAQ,kBAAkB,QAAQ,KAAK;IACxF,CAAC,CAAE,GAAG,KAAM;IACZ,QAAQ,QAAQ;GAClB;GACA,KAAA,QAAO;IACL,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,KAAK,EAAE,CAAC;IAC1C,IAAI,IAAI,KAAK;IACb,IAAI,IAAI,KAAK;IACb,QAAQ;GACV;EACF;EACA,MAAM,MAAM,QAAQ,MAAM;EAC1B,MAAM,SAAS,UAAU,OAAO;GAC9B,WAAW;GACX,SAAS,UAAU;IACjB,UAAU;IACV,IAAI,CAAC,OAAO;KACV,QAAQ;KAER,IAAI,WAAA,SAAc,CAAC,cAAA,MAAc,IAAI,KAAK,EAAE,GAC1C,SAAA,QAAW;MAAE,OAAO;MAAK,OAAO,WAAW,SAAA,MAAS,QAAQ,CAAA;KAAG;KAEjE,UAAU,qBAAqB,OAAO,CAAC;IACzC;IACA,OAAO;IACP,IAAI,OAAO,KAAK;GAClB;GACA,QAAQ,EAAE,OAAO,SAAS,gBAAgB;IACxC,IAAI,KAAK;IACT,QAAQ;IACR,MAAM,SAAM,KAAA;IACZ,KAAA,QAAO;IACP,IAAI,CAAC,WAAW,aAAa,CAAC,UAAW,OAAO,OAAO,KAAK,OAAO,OAAO,GAAI;IAC9E,YAAA,QACE,OAAO,KAAK,UAAU;KAAE,IAAI,KAAK;KAAI,GAAG,KAAK,IAAI,OAAO;KAAI,GAAG,KAAK,IAAI,OAAO;IAAG,EAAE,CACtF;GACF;EACF,CAAC;CACH;;;;;CAMA,SAAS,UACP,OACA,QACA,OACA,eACA,MACA;EACA,IAAI,MAAM,WAAW,GAAG;EACxB,MAAM,gBAAgB;EACtB,MAAM,eAAe;EACrB,IAAI,UAAU;GAAE,SAAS,MAAM;GAAS,SAAS,MAAM;EAAQ;EAC/D,IAAI,gBAAgB,CAAC;EACrB,IAAI,UAAiD;EACrD,MAAM,WAAW,cACf,UAAU,OAAO,MAAM,OACtB,WAAA,QAAa,gBAAgB,QAAQ,WAAW,gBAAgB,YAAY,KAAK,KAChF;EACJ,MAAM,eAAe;GACnB,MAAM,QAAQ,QAAQ,UAAU,QAAQ,SAAS,QAAQ,OAAO;GAChE,MAAM,MAAM,OAAM,MAAA,OAAQ,KAAK;GAC/B,UAAU,OAAO,QAAQ,GAAG,IAAI;IAAE,MAAM;IAAK,MAAM,YAAY,KAAK,KAAK;GAAE,IAAI;GAC/E,MAAM,MAAM,UAAU,UAAU,QAAQ,MAAM,QAAQ,IAAI,IAAI;GAC9D,KAAA,QAAO;IACL,MAAM,gBAAgB,SAAS;IAC/B,IAAI,gBAAgB,MAAM;IAC1B,QAAQ,SAAS,KAAK,MAAM;GAC9B;EACF;EACA,MAAM,MAAM,QAAQ,MAAM;EAC1B,OAAO;EACP,MAAM,SAAS,UAAU,OAAO;GAE9B,eAAe,KAAK,KAAK,KAAA;GACzB,cAAc;GACd,SAAS,UAAU;IACjB,UAAU;IACV,OAAO;IACP,IAAI,OAAO,KAAK;GAClB;GACA,QAAQ,EAAE,gBAAgB;IACxB,IAAI,KAAK;IACT,QAAQ;IACR,KAAA,QAAO;IACP,IAAI,CAAC,aAAa,SAAS,KAAK,QAAQ,MAAM,QAAQ,IAAI;GAC5D;EACF,CAAC;EACD,UAAU,qBAAqB,OAAO,CAAC;CACzC;CAEA,SAAS,UAAU,OAAsB;EACvC,IAAI,MAAM,QAAQ,OAAO,MAAM,WAAW,KAAK,GAAG,QAAQ;EAC1D,IAAI,CAAA,WAAA,OAAa;EACjB,IAAI,MAAM,QAAQ,UAAU,MAAM;EAClC,KAAK,MAAM,WAAW,MAAM,YAAY,MAAM,IAAI,YAAY,MAAM,KAAK;GACvE,MAAM,eAAe;GACrB,UAAU;EACZ;CACF;;CAGA,SAAS,MAAM,MAAS,OAAsB;EAC5C,MAAM,QAAQ,OAAO,MAAM;EAC3B,IAAI,CAAC,SAAS,CAAA,YAAA,SAAgB,CAAC,YAAY,IAAI,GAAG;EAClD,MAAM,eAAe;EACrB,MAAM,QAAQ,WAAA,QAAA,SAAA,QAAwB,UAAU,MAAM,WAAW,IAAI;EACrE,MAAM,MAAM,cAAA,MAAc,IAAI,KAAK,EAAE,IAAI,SAAA,MAAS,QAAQ,CAAC,KAAK,EAAE;EAClE,YAAA,MACE,IAAI,SAAS,OAAO;GAClB,MAAM,OAAO,SAAA,MAAS,IAAI,EAAE;GAC5B,OAAO,QAAQ,YAAY,IAAI,IAC3B,CAAC;IAAE;IAAI,GAAG,KAAK,IAAI,MAAM,KAAK;IAAM,GAAG,KAAK,IAAI,MAAM,KAAK;GAAK,CAAC,IACjE,CAAA;EACN,CAAC,CACH;CACF;;CAGA,SAAS,UAAU,OAAsB;EACvC,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK,OAAO;EACvD,MAAM,eAAe;EACrB,OAAO;CACT;CAEA,MAAM,UAAuB;EAC3B,SAAS,IAAI,OAAO;GAClB,MAAM,OAAO,SAAA,MAAS,IAAI,EAAE;GAC5B,IAAI,MAAM,UAAU,MAAM,KAAK;EACjC;EACA,YAAY,IAAI,UAAU,OAAO,SAAS,IAAI,QAAQ,KAAK,CAAC;EAC5D,QAAQ,IAAI,OAAO;GACjB,MAAM,OAAO,SAAA,MAAS,IAAI,EAAE;GAC5B,IAAI,CAAC,MAAM;GACX,IAAI,UAAU,KAAK,GAAG,OAAO,SAAS,IAAI,QAAQ,KAAK,CAAC;QACnD,MAAM,MAAM,KAAK;EACxB;EACA,YAAY,OAAQ,QAAA,QAAU;EAC9B,UAAU,IAAI;GACZ,IAAI,QAAA,UAAY,IAAI,QAAA,QAAU;EAChC;EACA,SAAS,IAAI,MAAM,OAAO;GACxB,MAAM,OAAO,SAAA,MAAS,IAAI,EAAE;GAC5B,IAAI,CAAC,MAAM;GACX,UAAU,OAAO,UAAU,MAAM,IAAI,GAAG,MAAM,OAAO,QAAQ,WAC3D,UAAA,QAAY;IAAE,MAAM;IAAI,IAAI,OAAO;IAAI,UAAU;IAAM;GAAO,CAAC,CACjE;EACF;EACA,YAAY,IAAI,UAAU,OAAO,SAAS,IAAI,QAAQ,KAAK,CAAC;EAC5D,QAAQ,IAAI,OAAO;GACjB,IAAI,UAAU,KAAK,GAAG,OAAO,SAAS,IAAI,QAAQ,KAAK,CAAC;EAC1D;EACA,QAAQ,IAAI,KAAK,OAAO;GACtB,MAAM,QAAQ,OAAA,MAAO,MAAM,SAAS,KAAK,KAAK,OAAO,EAAE;GACvD,MAAM,OAAO,SAAS,SAAA,MAAS,IAAI,MAAM,KAAK,IAAI;GAClD,MAAM,KAAK,SAAS,SAAA,MAAS,IAAI,MAAM,KAAK,EAAE;GAC9C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAA,YAAA,OAAc;GAC5C,MAAM,EAAE,WAAW;GAGnB,UAAU,OADK,QAAQ,OAAO,OAAO,KAAM,OAAO,OAAO,SAAS,IACzC,QAAQ,OAAO,OAAO,IAAI,QAAQ,OAAO,QAAQ,SACxE,YAAA,MAAY;IAAE,MAAM;IAAI;IAAK,MAAM,OAAO;IAAI;GAAK,CAAC,CACtD;EACF;EAEA,MAAM,MAAM,OAAO;GACjB,IAAI,MAAM,kBAAkB,WAAW,MAAM,OAAO,QAAQ,gBAAgB,GAC1E,QAAQ,OAAO,IAAI;EAEvB;CACF;CAEA,aAAa;EACX,MAAM,EAAE,SAAS;EACjB,MAAM,YAAY,WAAA,SAAc,CAAC,CAAA,YAAA;EAEjC,MAAM,OACJ,YAAA,SAAA,YAAA,SAA8B,CAAA,KAAA,SAAS,CAAA,KAAA,QACnC,OAAA,MAAO,QACJ,EAAE,WACD,cAAA,MAAc,IAAI,KAAK,EAAE,KAAK,SAAA,MAAS,IAAI,KAAK,IAAI,KAAK,SAAA,MAAS,IAAI,KAAK,EAAE,CACjF,IACA,CAAA;EACN,OAAAP,YAAA,OAEQ,WACF,EACE,IAAI;GACF,cAAc;GAAI,IAAA,KAClB,qBAAqB,cAAM,CAAA,OAAA,KAAA,GAAA,IAAA;GAC3B,SAAA,UAAa,YAAY,cAAc;GAAU,IAAA,KACjD,qBAAqB,YAAI;IAAA,KAAA;IAAO,QAAQ;IAAG,QAAQ;IAAG,QAAQ;IAAK,SAAA;GAAA,GAAA,IAAA;EAAA,EAEvE,GACA,MACA;GACE,GAAG,KAAK;GACR,MAAM,YAAsB,SAAS,QAAQ,QAAQ;GACrD,MAAM;GACN,UAAU;GACV,wBAAwB,SAAS;GACjC,gBAAgB,UAAwB;IACtC,aAAa,KAAK;IACjB,KAAK,cAAc,cAAgD,KAAK;GAC3E;GACA,UAAU,UAAsB;IAC9B,IAAI,WAAA,SAAc,aAAa,MAAM,MAAM,GAAG,MAAM;GACtD;GACA,YAAY,UAAyB;IACnC,UAAU,KAAK;IACd,KAAK,cAAc,UAA6C,KAAK;GACxE;GACA,UAAU,UAAyB;IACjC,IAAI,MAAM,QAAQ,KAAK,QAAQ;GACjC;GACA,cAAe,QAAQ;GAEvB,WAAW,UAAiB;IAC1B,MAAM,UAAU,MAAM;IACtB,QAAQ,YAAY;IACpB,QAAQ,aAAa;GACvB;EACF,CACF,GAAC;GAAAA,YAAA,OAGK,WACF,EACE,IAAI,CACF,cAAc,OAAK,IAAA,KACnB,qBAAqB,aAAK;IAAC,QAAQ;IAAG,QAAQ;IAAG,QAAQ;GAAK,GAAA,IAAA,CAAA,EAElE,GAAC,WAAA,OAED,UAAU,EAAE,sBAAsB,KAAK,CAAC,CAC1C,GAAC;IAAA,SAAA;IAGA,MAAA,MAAM,KAAK,SAAS;KACnB,MAAM,KAAK,OAAO,IAAI;KACtB,MAAM,aAAa,cAAA,MAAc,IAAI,KAAK,EAAE;KAC5C,OAAAA,YAAA,UAAA;MAAA,OAES,KAAK;MAAE,QACN;MAAI,KACP,GAAG;MAAC,KACJ,GAAG;MAAC,SACA,aAAA,MAAa,IAAI;MAAC,mBACR,SAAS;MAAI,YACpB;MAAU,cAAA,WAAA;MAAA,aAET;MAAS,WACX,YAAY,IAAI;MAAC,YAChB,KAAA,OAAM,IAAI,IAAI,KAAK,EAAE,KAAK;MAAK,SAEvC,YAAA,SACA,CAAA,KAAA,UACC,QAAA,UAAY,KAAK,MAAM,cAAc,KAAA,OAAM,WAAW,KAAK;MAAG,cAErD,KAAA,OAAM,WAAW,KAAK;MAAE,UAC3B,SAAA,SAAY;MAAW,QAAA,UAAA;MAAA,YAAA,UAAA;MAAA,WAGvB;KAAO,GAAA,IAAA;IAGtB,CAAC;IAACA,YAAA,OAAAC,cAEI,IAAI,MAAM,cAAc,KAAK,GAAC;KAAA,SAAA;KAAA,UAAA;KAAA,eAGrB,WAAA,QAAa,KAAA,IAAY;IAAM,CAAA,GAAA,CAE3C,OAAA,MAAO,KAAK,EAAE,MAAM,aAAa;KAChC,MAAM,OAAO,SAAA,MAAS,IAAI,KAAK,IAAI;KACnC,MAAM,KAAK,SAAA,MAAS,IAAI,KAAK,EAAE;KAC/B,MAAM,aAAa,cAAA,MAAc,IAAI,KAAK,EAAE;KAC5C,OAAAD,YAAA,UAAA;MAAA,OAES,KAAK;MAAE,QACN;MAAI,UACF;MAAM,SAEZ,aAAA,QAAe,IAAI,KACnB,SAAS,YACP,OAAO,aAAA,MAAa,IAAI,IAAI,KAAK,MACjC,KAAK,aAAA,MAAa,EAAE,IAAI,KAAK,EAC/B;MAAC,mBAEc,SAAS;MAAI,UAAA,WAAA;MAAA,YAEpB;MAAU,cAAA,WAAA;MAAA,QAAA,UAAA;MAAA,WAGX;KAAO,GAAA,IAAA;IAGtB,CAAC,CAAC,CAAA;IAEH,SAAA,SACC,OAAA,MAAO,KAAK,EAAE,MAAM,aAAa;KAC/B,MAAM,KAAK,KAAA,SAAQ,CAAC,KAAK,UAAU,iBAAiB,MAAM,IAAI,KAAK;KACnE,OAAAA,YAAA,cAAA;MAAA,OAES,KAAK;MAAE,QACN;MAAI,KACP,GAAG;MAAC,KACJ,GAAG;MAAC,YACG,cAAA,MAAc,IAAI,KAAK,EAAE;MAAC,UAAA,SAAA;MAAA,QAAA,cAAA;KAAA,GAAA,IAAA;IAK1C,CAAC;KACD,CAAC,CAAC,KAAA,OAAM,OAAO,UAAU,CAAC,CAAA,KAAA,SAAS,KAAK,SAAS,MAACA,YAAA,OAAAC,cAE5C,IAAI,MAAM,cAAc,OAAO,cAAc,KAAK,GAAC;KAAA,SAAA;KAAA,UAAA;KAAA,eAAA;KAAA,0BAAA;IAAA,CAAA,GAAA;KAMtD,KAAA,OAAM,OAAO,KAAK,OAAO,UAAKD,YAAA,QAAAC,cAAA,EAAA,OAEtB,MAAK,GACN,WAAmB,EAAE,IAAI,cAAc,MAAM,GAAC,WAAA,OAAc;MAC9D,IAAI,MAAM,KAAK;MACf,IAAI,MAAM,KAAK;MACf,IAAI,MAAM,GAAG;MACb,IAAI,MAAM,GAAG;KACf,CAAC,CAAC,GAAA,IAAA,CAEL;KACA,KAAK,SAAS,EAAE,MAAM,aACpB,CAAC,QAAQ,IAAI,CAAC,CAAW,KAAK,QAAQ;MACrC,MAAM,KAAK,QAAQ,SAAS,OAAO,KAAM,OAAO,OAAO,SAAS;MAChE,OAAAD,YAAA,UAAAC,cAAA;OAAA,OAES,GAAG,KAAK,GAAE,GAAI;OAAK,MACpB,GAAG;OAAC,MACJ,GAAG;OAAC,KACL;MAAC,GACA,IAAI,MAAM,cAAc,OAAO,GAAC;OAAA,oBAClB;OAAG,kBACL,UACd,QAAQ,QAAQ,KAAK,IAAI,KAAK,KAAK;MAAC,CAAA,GAAA,IAAA;KAI5C,CAAC,CACH;KACC,KAAA,SAAAD,YAAA,KACQ,IAAI,MAAM,cAAc,OAAO,GAAC,CAAAA,YAAA,QAAAC,cAAA,EAAA,KAEhC,aAAa,QAAQ,CAAC,KAAA,MAAK,MAAM,KAAA,MAAK,EAAE,GAAG,QAAQ,EAAG,CAAC,EAAC,GACvD,IAAI,MAAM,cAAc,QAAQ,CAAC,GAAA,IAAA,GAAAD,YAAA,WAAAC,cAAA,EAAA,UAG7B,UAAU,CAAC,KAAA,MAAK,MAAM,KAAA,MAAK,EAAE,GAAG,KAAK,EAAC,GAC1C,IAAI,MAAM,cAAc,SAAS,CAAC,GAAA,IAAA,CAAA,CAAA;IAG3C,CAAA;GAEJ,CAAA;GAEF,QAAA,SAAAD,YAAA,OAEO,WACF,EACE,IAAI,CACF,cAAc,SAAO,IAAA,KACrB,qBAAqB,WAAG;IAAC,QAAA,MAAQ;IAAG,QAAA,MAAQ;IAAG,QAAA,MAAQ;IAAO,QAAA,MAAQ;GAAM,GAAA,IAAA,CAAA,EAEhF,GAAC,aAAA,KAEH,GAAC,IAAA;GAGJ,QAAA,SAAW,QAAIA,YAAA,OAAAC,cACL,IAAI,MAAM,cAAc,OAAO,GAAC,EAAA,wBAAA,GAAA,CAAA,GAAA,CAAA,QAAA,KAAA,CAAA;EAG1C,CAAA;CAGP;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH;;AAGA,IAAM,aACJ,SAEA,CAAC,CAAC,KAAK,UAAU,KAAK,OAAO,UAAU;;AAGzC,IAAM,SAAS,GAAsB,MAAyB,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;;AAGvF,SAAS,QAAQ,GAAsB,GAA+B;CACpE,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;CAClC,MAAM,MAAM,IAAI,IAAI,CAAC;CACrB,OAAO,EAAE,OAAO,OAAO,IAAI,IAAI,EAAE,CAAC;AACpC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
2
2
|
import { type ButtonProps } from '../base/Button';
|
|
3
3
|
import { type IconButtonProps } from '../base/IconButton';
|
|
4
4
|
import { type ToolbarProps } from '../navigation/Toolbar';
|
|
@@ -7,7 +7,7 @@ import { diagramMessages } from "./messages.js";
|
|
|
7
7
|
import { DiagramContext } from "./Diagram.js";
|
|
8
8
|
import { createTextVNode, createVNode } from "vue";
|
|
9
9
|
import { _component, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
10
|
-
import
|
|
10
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
11
11
|
import { Scan, ZoomIn, ZoomOut } from "@lucide/icons";
|
|
12
12
|
//#region src/diagram/DiagramControls.tsx
|
|
13
13
|
/**
|