dou-ui 0.1.0-alpha.2 → 0.1.0-alpha.3
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/components/button/button.js.map +1 -1
- package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/button/button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar-view/calendar-view.js.map +1 -1
- package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cascader/cascader.js.map +1 -1
- package/dist/components/cascader/cascader.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/cascader/cascader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-artifact/chat-artifact.js.map +1 -1
- package/dist/components/chat-artifact/chat-artifact.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/components/chat-artifact/chat-artifact.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-attachments/chat-attachments.js.map +1 -1
- package/dist/components/chat-attachments/chat-attachments.vue_vue_type_script_setup_true_lang.js +11 -2
- package/dist/components/chat-attachments/chat-attachments.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-attachments/chat-attachments2.js.map +1 -1
- package/dist/components/chat-confirm/chat-confirm.js.map +1 -1
- package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js +38 -14
- package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/chat-context-meter/chat-context-meter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-context-meter/chat-context-meter2.js.map +1 -1
- package/dist/components/chat-message/chat-message.js.map +1 -1
- package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js +88 -33
- package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-message/chat-message2.js.map +1 -1
- package/dist/components/chat-message/style.js +5 -0
- package/dist/components/chat-plan/chat-plan.js +9 -4
- package/dist/components/chat-plan/chat-plan.js.map +1 -1
- package/dist/components/chat-plan/chat-plan.vue_vue_type_script_setup_true_lang.js +64 -32
- package/dist/components/chat-plan/chat-plan.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-plan/chat-plan2.js +6 -0
- package/dist/components/chat-plan/chat-plan2.js.map +1 -0
- package/dist/components/chat-plan/index.js +1 -1
- package/dist/components/chat-plan/style.js +1 -0
- package/dist/components/chat-reasoning/chat-reasoning.js.map +1 -1
- package/dist/components/chat-reasoning/chat-reasoning.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/chat-reasoning/chat-reasoning.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-sources/chat-citation.js.map +1 -1
- package/dist/components/chat-sources/chat-citation.vue_vue_type_script_setup_true_lang.js +52 -14
- package/dist/components/chat-sources/chat-citation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-sources/chat-sources.js.map +1 -1
- package/dist/components/chat-sources/chat-sources.vue_vue_type_script_setup_true_lang.js +6 -4
- package/dist/components/chat-sources/chat-sources.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-sources/chat-sources2.js.map +1 -1
- package/dist/components/chat-sources/index.js +1 -1
- package/dist/components/chat-steps/chat-steps.js +9 -4
- package/dist/components/chat-steps/chat-steps.js.map +1 -1
- package/dist/components/chat-steps/chat-steps.vue_vue_type_script_setup_true_lang.js +20 -13
- package/dist/components/chat-steps/chat-steps.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-steps/chat-steps2.js +6 -0
- package/dist/components/chat-steps/chat-steps2.js.map +1 -0
- package/dist/components/chat-steps/index.js +1 -1
- package/dist/components/chat-steps/style.js +1 -0
- package/dist/components/chat-tool-call/chat-tool-call.js.map +1 -1
- package/dist/components/chat-tool-call/chat-tool-call.vue_vue_type_script_setup_true_lang.js +38 -12
- package/dist/components/chat-tool-call/chat-tool-call.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-tool-call/chat-tool-call2.js.map +1 -1
- package/dist/components/chat-tool-call/style.js +1 -0
- package/dist/components/code-block/code-block.js.map +1 -1
- package/dist/components/code-block/code-block.vue_vue_type_script_setup_true_lang.js +37 -5
- package/dist/components/code-block/code-block.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/collapse/collapse-item.js.map +1 -1
- package/dist/components/collapse/collapse-item.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/collapse/collapse-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/collapse/collapse-transition.js +3 -1
- package/dist/components/collapse/collapse-transition.js.map +1 -1
- package/dist/components/collapse/index.js +1 -2
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/color-mode/color-mode-button.js.map +1 -1
- package/dist/components/color-mode/color-mode-button.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-mode/color-mode-button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-mode/color-mode-select.js.map +1 -1
- package/dist/components/color-mode/color-mode-select.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-mode/color-mode-select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-mode/color-mode-switch.js.map +1 -1
- package/dist/components/color-mode/color-mode-switch.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-mode/color-mode-switch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-panel/color-panel.js.map +1 -1
- package/dist/components/color-panel/color-panel.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/color-panel/color-panel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/color-picker/color-picker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-picker/color-picker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/comment-thread/comment-thread.js.map +1 -1
- package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js +15 -15
- package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/comment-thread/style.js +2 -0
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context-menu.vue_vue_type_script_setup_true_lang.js +26 -11
- package/dist/components/context-menu/context-menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/context-menu/index.js +2 -0
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/copy-button/copy-button.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/descriptions/descriptions.js.map +1 -1
- package/dist/components/descriptions/descriptions.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/descriptions/descriptions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/descriptions/descriptions2.js.map +1 -1
- package/dist/components/dropdown/dropdown-button.js.map +1 -1
- package/dist/components/dropdown/dropdown-button.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/dropdown/dropdown-button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-group.js +6 -0
- package/dist/components/dropdown/dropdown-group.js.map +1 -0
- package/dist/components/dropdown/dropdown-group.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/dropdown/dropdown-group.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/dropdown/dropdown-item.js.map +1 -1
- package/dist/components/dropdown/dropdown-item.vue_vue_type_script_setup_true_lang.js +31 -9
- package/dist/components/dropdown/dropdown-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-items.js.map +1 -1
- package/dist/components/dropdown/dropdown-items.vue_vue_type_script_setup_true_lang.js +77 -52
- package/dist/components/dropdown/dropdown-items.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-radio-group.js.map +1 -1
- package/dist/components/dropdown/dropdown-radio-group.vue_vue_type_script_setup_true_lang.js +23 -5
- package/dist/components/dropdown/dropdown-radio-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown-sub.js.map +1 -1
- package/dist/components/dropdown/dropdown-sub.vue_vue_type_script_setup_true_lang.js +5 -4
- package/dist/components/dropdown/dropdown-sub.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/dropdown.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/dropdown/dropdown.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dropdown/dropdown2.js.map +1 -1
- package/dist/components/dropdown/index.js +4 -5
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown/item-components.js +11 -0
- package/dist/components/dropdown/item-components.js.map +1 -0
- package/dist/components/dropdown/menu-entries.js +14 -0
- package/dist/components/dropdown/menu-entries.js.map +1 -0
- package/dist/components/dropdown/menu-keys.js +1 -1
- package/dist/components/dropdown/menu-keys.js.map +1 -1
- package/dist/components/ellipsis/ellipsis.js.map +1 -1
- package/dist/components/ellipsis/ellipsis.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/ellipsis/ellipsis.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.vue_vue_type_script_setup_true_lang.js +10 -10
- package/dist/components/image-cropper/image-cropper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/infinite-scroll/infinite-scroll.js.map +1 -1
- package/dist/components/infinite-scroll/infinite-scroll.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/infinite-scroll/infinite-scroll.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/input-date/segment-field.js.map +1 -1
- package/dist/components/input-date/segment-field.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/input-date/segment-field.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/input-date/style.js +1 -0
- package/dist/components/input-time/style.js +1 -0
- package/dist/components/layout/layout-aside-trigger.js.map +1 -1
- package/dist/components/layout/layout-aside-trigger.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/layout/layout-aside-trigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/layout-aside.js.map +1 -1
- package/dist/components/layout/layout-aside.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/layout/layout-aside.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/layout-footer.js.map +1 -1
- package/dist/components/layout/layout-footer.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/layout/layout-footer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/layout.js.map +1 -1
- package/dist/components/markdown/index.js +9 -0
- package/dist/components/markdown/index.js.map +1 -0
- package/dist/components/markdown/markdown.js +6 -0
- package/dist/components/markdown/markdown.js.map +1 -0
- package/dist/components/markdown/markdown.vue_vue_type_script_setup_true_lang.js +225 -0
- package/dist/components/markdown/markdown.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/markdown/parse-block.js +577 -0
- package/dist/components/markdown/parse-block.js.map +1 -0
- package/dist/components/markdown/parse-inline.js +626 -0
- package/dist/components/markdown/parse-inline.js.map +1 -0
- package/dist/components/markdown/parser.js +308 -0
- package/dist/components/markdown/parser.js.map +1 -0
- package/dist/components/markdown/render.js +424 -0
- package/dist/components/markdown/render.js.map +1 -0
- package/dist/components/markdown/style.d.ts +1 -0
- package/dist/components/markdown/style.js +10 -0
- package/dist/components/markdown/url.js +16 -0
- package/dist/components/markdown/url.js.map +1 -0
- package/dist/components/menu/menu-item.js.map +1 -1
- package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-list.js.map +1 -1
- package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-popup.js.map +1 -1
- package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js +33 -21
- package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu.js +16 -13
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu2.js.map +1 -1
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/node-graph/layout.js +136 -31
- package/dist/components/node-graph/layout.js.map +1 -1
- package/dist/components/node-graph/node-graph-legend.js.map +1 -1
- package/dist/components/node-graph/node-graph-legend.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/node-graph/node-graph-legend.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/node-graph/node-graph.js.map +1 -1
- package/dist/components/node-graph/node-graph.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/node-graph/node-graph.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/pagination/pagination-gap.js.map +1 -1
- package/dist/components/pagination/pagination-gap.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/pagination/pagination-gap.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/pagination/pagination.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/pagination/pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/popconfirm/index.js +2 -0
- package/dist/components/popconfirm/index.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/popconfirm/popconfirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/popover/index.js +2 -0
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/popover/popover.vue_vue_type_script_setup_true_lang.js +12 -5
- package/dist/components/popover/popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/progress-group/progress-group.js.map +1 -1
- package/dist/components/progress-group/progress-group.vue_vue_type_script_setup_true_lang.js +11 -4
- package/dist/components/progress-group/progress-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/qrcode/qrcode.js.map +1 -1
- package/dist/components/qrcode/qrcode.vue_vue_type_script_setup_true_lang.js +10 -2
- package/dist/components/qrcode/qrcode.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/select/select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/slider/slider.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/slider/slider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/status-dot/index.js +7 -0
- package/dist/components/status-dot/index.js.map +1 -0
- package/dist/components/status-dot/status-dot.js +26 -0
- package/dist/components/status-dot/status-dot.js.map +1 -0
- package/dist/components/status-dot/status-dot.vue_vue_type_script_lang.js +43 -0
- package/dist/components/status-dot/status-dot.vue_vue_type_script_lang.js.map +1 -0
- package/dist/components/status-dot/status-dot2.js +6 -0
- package/dist/components/status-dot/status-dot2.js.map +1 -0
- package/dist/components/status-dot/style.d.ts +1 -0
- package/dist/components/status-dot/style.js +2 -0
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/steps/steps.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/steps/steps.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js +19 -14
- package/dist/components/table/table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-panel.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/tabs/tab-panel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tabs/tabs.vue_vue_type_script_setup_true_lang.js +117 -47
- package/dist/components/tabs/tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs2.js.map +1 -1
- package/dist/components/tag/tag.js.map +1 -1
- package/dist/components/tag/tag.vue_vue_type_script_setup_true_lang.js +21 -4
- package/dist/components/tag/tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/timeline/style.js +1 -0
- package/dist/components/timeline/timeline-item.js.map +1 -1
- package/dist/components/timeline/timeline-item.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/timeline/timeline-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tooltip/index.js +2 -0
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tooltip/tooltip.vue_vue_type_script_setup_true_lang.js +55 -8
- package/dist/components/tooltip/tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/tour/tour.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/tour/tour.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/transfer/transfer-list.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tree/tree.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/tree-select/tree-select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/upload/upload.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/upload/upload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/upload/upload2.js.map +1 -1
- package/dist/components/user/user.js.map +1 -1
- package/dist/components/user/user.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/user/user.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/use-popup.js +30 -5
- package/dist/composables/use-popup.js.map +1 -1
- package/dist/index.js +23 -17
- package/dist/index.js.map +1 -1
- package/dist/locale/en.js +13 -8
- package/dist/locale/en.js.map +1 -1
- package/dist/locale/zh-cn.js +13 -8
- package/dist/locale/zh-cn.js.map +1 -1
- package/dist/locale/zh-tw.js +13 -8
- package/dist/locale/zh-tw.js.map +1 -1
- package/dist/plugin.js +21 -14
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/components/button/button.d.ts +5 -1
- package/dist/types/components/calendar-view/calendar-view.d.ts +6 -0
- package/dist/types/components/calendar-view/calendar-view.vue.d.ts +1 -0
- package/dist/types/components/calendar-view/index.d.ts +3 -0
- package/dist/types/components/chat-artifact/chat-artifact.d.ts +2 -1
- package/dist/types/components/chat-attachments/chat-attachments.d.ts +2 -2
- package/dist/types/components/chat-confirm/chat-confirm.d.ts +7 -2
- package/dist/types/components/chat-list/index.d.ts +3 -3
- package/dist/types/components/chat-message/chat-message.d.ts +26 -3
- package/dist/types/components/chat-message/chat-message.vue.d.ts +4 -3
- package/dist/types/components/chat-message/index.d.ts +7 -4
- package/dist/types/components/chat-plan/chat-plan.d.ts +19 -2
- package/dist/types/components/chat-plan/chat-plan.vue.d.ts +2 -0
- package/dist/types/components/chat-plan/index.d.ts +6 -0
- package/dist/types/components/chat-sources/chat-sources.d.ts +6 -1
- package/dist/types/components/chat-steps/chat-steps.d.ts +10 -4
- package/dist/types/components/chat-steps/chat-steps.vue.d.ts +1 -1
- package/dist/types/components/chat-steps/index.d.ts +3 -3
- package/dist/types/components/chat-tool-call/chat-tool-call.d.ts +12 -3
- package/dist/types/components/chat-tool-call/chat-tool-call.vue.d.ts +1 -0
- package/dist/types/components/chat-tool-call/index.d.ts +3 -0
- package/dist/types/components/checkbox/index.d.ts +5 -5
- package/dist/types/components/code-block/code-block.d.ts +11 -0
- package/dist/types/components/code-block/code-block.vue.d.ts +3 -1
- package/dist/types/components/code-block/index.d.ts +9 -3
- package/dist/types/components/collapse/collapse-transition.d.ts +2 -7
- package/dist/types/components/collapse/collapse.vue.d.ts +1 -1
- package/dist/types/components/collapse/index.d.ts +5 -6
- package/dist/types/components/context-menu/context-menu.d.ts +37 -4
- package/dist/types/components/context-menu/context-menu.vue.d.ts +2 -0
- package/dist/types/components/context-menu/index.d.ts +5 -0
- package/dist/types/components/copy-button/copy-button.vue.d.ts +1 -1
- package/dist/types/components/copy-button/index.d.ts +1 -1
- package/dist/types/components/descriptions/descriptions.d.ts +9 -1
- package/dist/types/components/descriptions/descriptions.vue.d.ts +1 -0
- package/dist/types/components/descriptions/index.d.ts +3 -0
- package/dist/types/components/dropdown/dropdown-group.vue.d.ts +13 -0
- package/dist/types/components/dropdown/dropdown-items.vue.d.ts +2 -2
- package/dist/types/components/dropdown/dropdown-radio-group.vue.d.ts +8 -4
- package/dist/types/components/dropdown/dropdown.d.ts +28 -6
- package/dist/types/components/dropdown/dropdown.vue.d.ts +1 -1
- package/dist/types/components/dropdown/index.d.ts +10 -81
- package/dist/types/components/dropdown/item-components.d.ts +103 -0
- package/dist/types/components/dropdown/menu-entries.d.ts +4 -0
- package/dist/types/components/index.d.ts +2 -0
- package/dist/types/components/layout/index.d.ts +12 -6
- package/dist/types/components/layout/layout-aside.vue.d.ts +1 -1
- package/dist/types/components/layout/layout-footer.vue.d.ts +4 -2
- package/dist/types/components/layout/layout.d.ts +4 -0
- package/dist/types/components/markdown/index.d.ts +58 -0
- package/dist/types/components/markdown/markdown.d.ts +251 -0
- package/dist/types/components/markdown/markdown.vue.d.ts +22 -0
- package/dist/types/components/markdown/parse-block.d.ts +61 -0
- package/dist/types/components/markdown/parse-inline.d.ts +19 -0
- package/dist/types/components/markdown/parser.d.ts +22 -0
- package/dist/types/components/markdown/render.d.ts +84 -0
- package/dist/types/components/markdown/url.d.ts +10 -0
- package/dist/types/components/masonry/index.d.ts +3 -3
- package/dist/types/components/menu/index.d.ts +8 -3
- package/dist/types/components/menu/menu.d.ts +16 -5
- package/dist/types/components/menu/menu.vue.d.ts +3 -1
- package/dist/types/components/menubar/menubar.d.ts +1 -1
- package/dist/types/components/node-graph/layout.d.ts +16 -0
- package/dist/types/components/node-graph/node-graph.d.ts +1 -1
- package/dist/types/components/popover/index.d.ts +3 -3
- package/dist/types/components/popover/popover.vue.d.ts +1 -1
- package/dist/types/components/progress-group/index.d.ts +3 -0
- package/dist/types/components/progress-group/progress-group.d.ts +7 -0
- package/dist/types/components/progress-group/progress-group.vue.d.ts +1 -0
- package/dist/types/components/qrcode/index.d.ts +3 -0
- package/dist/types/components/qrcode/qrcode.d.ts +5 -0
- package/dist/types/components/qrcode/qrcode.vue.d.ts +1 -0
- package/dist/types/components/sortable/index.d.ts +3 -3
- package/dist/types/components/status-dot/index.d.ts +51 -0
- package/dist/types/components/status-dot/status-dot.d.ts +46 -0
- package/dist/types/components/status-dot/status-dot.vue.d.ts +46 -0
- package/dist/types/components/steps/steps.d.ts +1 -1
- package/dist/types/components/switch/index.d.ts +3 -3
- package/dist/types/components/table/index.d.ts +4 -3
- package/dist/types/components/table/table.d.ts +6 -1
- package/dist/types/components/tabs/index.d.ts +3 -0
- package/dist/types/components/tabs/tabs.d.ts +16 -3
- package/dist/types/components/tabs/tabs.vue.d.ts +1 -0
- package/dist/types/components/timeline/index.d.ts +3 -3
- package/dist/types/components/timeline/timeline-item.vue.d.ts +1 -1
- package/dist/types/components/virtual-list/index.d.ts +3 -3
- package/dist/types/composables/use-popup.d.ts +15 -5
- package/dist/types/locale/types.d.ts +18 -7
- package/dist/types/utils/only-child.d.ts +3 -1
- package/dist/types/utils/pointer.d.ts +5 -0
- package/dist/types/utils/safe-url.d.ts +14 -0
- package/dist/types/utils/status-check.d.ts +8 -0
- package/dist/utils/install.js +5 -0
- package/dist/utils/install.js.map +1 -1
- package/dist/utils/only-child.js +56 -5
- package/dist/utils/only-child.js.map +1 -1
- package/dist/utils/pointer.js +6 -1
- package/dist/utils/pointer.js.map +1 -1
- package/dist/utils/safe-url.js +57 -0
- package/dist/utils/safe-url.js.map +1 -0
- package/dist/utils/status-check.js +27 -0
- package/dist/utils/status-check.js.map +1 -0
- package/package.json +3 -3
package/dist/components/calendar-view/calendar-view.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar-view.vue_vue_type_script_setup_true_lang.js","names":["TimeGridComponent","_useModel","_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_toDisplayString","_renderSlot","_createBlock","_createCommentVNode","_createVNode","_Fragment","_renderList","_createTextVNode","_createSlots","_withCtx","_normalizeProps","_guardReactiveProps","_mergeProps","_withModifiers","_normalizeStyle"],"sources":["../../../src/components/calendar-view/calendar-view.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ContextMenuItem } from '../context-menu/context-menu'\nimport { ChevronLeftIcon, ChevronRightIcon, TrashIcon } from '@dou-ui/icons'\nimport {\n computed,\n getCurrentInstance,\n nextTick,\n onBeforeUnmount,\n ref,\n shallowRef,\n triggerRef,\n useTemplateRef,\n watch,\n} from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { holdPointer } from '../../utils/pointer'\nimport type { PointerHold } from '../../utils/pointer'\nimport { useLocale } from '../config-provider/use-config'\nimport { DouContextMenu } from '../context-menu'\nimport {\n addDays,\n addMonths,\n daysInMonth,\n parts,\n today,\n toDateString,\n weekday,\n} from '../date-picker/date'\nimport { DouSegmentedControl } from '../segmented-control'\nimport type {\n CalendarChange,\n CalendarDay,\n CalendarEvent,\n CalendarMenuTarget,\n CalendarMove,\n CalendarRange,\n CalendarViewExpose,\n CalendarViewMode,\n CalendarViewProps,\n CalendarViewSlots,\n} from './calendar-view'\nimport {\n dayIndex,\n endOf,\n formatStamp,\n formatTime,\n moveEvent,\n sameTime,\n stampsOf,\n toStamp,\n} from './editing'\nimport TimeGridComponent from './time-grid.vue'\nimport type { HTMLAttributes } from 'vue'\nimport type { WithAttributes } from '../../utils/install'\nimport { visibleRange } from './range'\nimport { segmentOn, spanOf } from './time-layout'\nimport type { EventSpan } from './time-layout'\n\n// 让模板里也能写这个组件转交的原生属性\nconst TimeGrid = TimeGridComponent as WithAttributes<typeof TimeGridComponent, HTMLAttributes>\n\ndefineOptions({ name: 'DouCalendarView' })\n\nconst props = withDefaults(defineProps<CalendarViewProps>(), {\n maxEvents: 3,\n hours: () => [0, 24],\n scrollTime: '08:00',\n snap: 15,\n menu: true,\n})\nconst model = defineModel<string | null>()\nconst month = defineModel<string>('month')\nconst view = defineModel<CalendarViewMode>('view', { default: 'month' })\nconst events = defineModel<CalendarEvent[]>('events', { default: () => [] })\nconst emit = defineEmits<{\n select: [date: string]\n eventClick: [event: CalendarEvent]\n timeClick: [start: string]\n change: [change: CalendarChange]\n create: [range: CalendarRange]\n eventContextmenu: [event: CalendarEvent, nativeEvent: MouseEvent]\n rangeChange: [range: CalendarRange]\n}>()\nconst slots = defineSlots<CalendarViewSlots>()\n\nconst ns = useNamespace('calendar-view')\nconst { t, locale } = useLocale()\n\nconst weekStart = computed(() => props.weekStart ?? locale.value.region.weekStart)\nconst todayValue = today()\n\n/** The day the keyboard is on; its month is the one shown. */\nconst cursor = ref(model.value || (month.value ? `${month.value}-01` : todayValue))\nconst shown = computed(() => cursor.value.slice(0, 7))\n\nwatch(shown, (value) => {\n if (value !== month.value) month.value = value\n})\nwatch(month, (value) => {\n if (value && value !== shown.value) cursor.value = `${value}-01`\n})\nwatch(model, (value) => {\n if (value && value.slice(0, 7) !== shown.value) cursor.value = value\n})\n\nconst asDate = (date: string) => {\n const { year, month: m, day } = parts(date)\n const value = new Date(Date.UTC(2000, m - 1, day))\n value.setUTCFullYear(year)\n return value\n}\nconst formatter = (options: Intl.DateTimeFormatOptions) =>\n new Intl.DateTimeFormat(locale.value.name, { timeZone: 'UTC', ...options })\n\nconst fullDate = computed(() => formatter({ dateStyle: 'full' }))\nconst title = computed(() => {\n if (view.value === 'day') return fullDate.value.format(asDate(cursor.value))\n if (view.value === 'week') {\n // Composed by hand: some locales fall back to all-numeric dates in formatRange.\n const first = weekDays.value[0]!.date\n const last = weekDays.value.at(-1)!.date\n const full = formatter({ year: 'numeric', month: 'short', day: 'numeric' })\n const end =\n first.slice(0, 4) === last.slice(0, 4) ? formatter({ month: 'short', day: 'numeric' }) : full\n return `${full.format(asDate(first))} – ${end.format(asDate(last))}`\n }\n return formatter({ year: 'numeric', month: 'long' }).format(asDate(`${shown.value}-01`))\n})\nconst weekdays = computed(() => {\n const short = formatter({ weekday: 'short' })\n const long = formatter({ weekday: 'long' })\n // 2024-01-07 is a Sunday.\n return Array.from({ length: 7 }, (_, index) => {\n const date = asDate(toDateString(2024, 1, 7 + ((weekStart.value + index) % 7)))\n return { short: short.format(date), long: long.format(date) }\n })\n})\n\ntype Surface = 'time' | 'day'\ninterface Drag {\n /** `press` is a finger resting where nothing can be dragged: letting go opens the menu. */\n kind: 'move' | 'resize' | 'create' | 'press'\n surface: Surface\n event: CalendarEvent | null\n span: EventSpan | null\n /** Where the press began: the day and, on the time axis, minutes since midnight. */\n origin: { date: string; minutes: number }\n pointerId: number\n touch: boolean\n x0: number\n y0: number\n x: number\n y: number\n started: boolean\n /** The event at its new time, while moving or resizing. */\n draft: CalendarEvent | null\n /** The stretch being drawn, while creating. */\n range: CalendarRange | null\n refusal: string | null\n /** What a resting finger opens the menu on. */\n target: CalendarMenuTarget | null\n}\n\nconst drag = shallowRef<Drag | null>(null)\nconst dragged = computed(() => (drag.value?.started && drag.value.draft) || null)\nconst drawing = computed(() => (drag.value?.started && drag.value.range) || null)\nconst refused = computed(() => !!(drag.value?.started && drag.value.refusal))\n\n/** The events as shown: the one being dragged at its new time. */\nconst shownEvents = computed(() => {\n const d = drag.value\n if (!d?.started || !d.event || !d.draft) return events.value\n return events.value.map((event) => (event === d.event ? d.draft! : event))\n})\n\n/** Where each event falls; events whose `start` can't be read are left out. */\nconst spans = computed(() => {\n const map = new Map<CalendarEvent, EventSpan>()\n for (const event of shownEvents.value) {\n const span = spanOf(event)\n if (span) map.set(event, span)\n }\n return map\n})\n\n// Events that can't be read are left out; say so once per event while developing.\nconst warned = new WeakSet<CalendarEvent>()\nwatch(\n events,\n (list) => {\n // the app's bundler replaces this, as for Vue's own warnings\n if (process.env.NODE_ENV === 'production') return\n for (const event of list) {\n if (spans.value.has(event) || warned.has(event)) continue\n warned.add(event)\n console.warn(\n `[dou-ui] CalendarView event \"${event.id}\" has a start that can't be read: \"${event.start}\". Use YYYY-MM-DD or YYYY-MM-DD HH:mm.`,\n )\n }\n },\n { immediate: true },\n)\n\n/**\n * Events that run over several days first, so their bars tend to line up\n * from day to day, then the other all-day ones, then timed ones by when\n * they start on the day.\n */\nconst startOn = (event: CalendarEvent, date: string) => {\n // the event being dragged comes first, so it never folds into \"+N\"\n if (event === dragged.value) return -3\n const span = spans.value.get(event)!\n if (span.from !== span.to) return -2\n return span.start === null ? -1 : segmentOn(span, date).start\n}\n\n/** Events by day, a span listed on every day it covers. */\nconst byDay = computed(() => {\n const map = new Map<string, CalendarEvent[]>()\n for (const span of spans.value.values()) {\n for (let date = span.from, guard = 0; date <= span.to && guard < 366; guard++) {\n const list = map.get(date) ?? []\n list.push(span.event)\n map.set(date, list)\n date = addDays(date, 1)\n }\n }\n for (const [date, list] of map)\n // oxlint-disable-next-line unicorn/no-array-sort -- sorts the lists built above\n list.sort((a, b) => startOn(a, date) - startOn(b, date))\n return map\n})\n\nconst weeks = computed<CalendarDay[][]>(() => {\n const first = `${shown.value}-01`\n const offset = (weekday(first) - weekStart.value + 7) % 7\n const start = addDays(first, -offset)\n return Array.from({ length: 6 }, (_row, row) =>\n Array.from({ length: 7 }, (_column, column) => {\n const date = addDays(start, row * 7 + column)\n return {\n date,\n day: parts(date).day,\n outside: date.slice(0, 7) !== shown.value,\n today: date === todayValue,\n selected: date === model.value,\n disabled: !!props.disabledDate?.(date),\n events: byDay.value.get(date) ?? [],\n }\n }),\n )\n})\n\nconst dayOf = (date: string): CalendarDay => ({\n date,\n day: parts(date).day,\n outside: false,\n today: date === todayValue,\n selected: date === model.value,\n disabled: !!props.disabledDate?.(date),\n events: byDay.value.get(date) ?? [],\n})\n\n/** The days on the time axis: the cursor's week, or the cursor alone. */\nconst weekDays = computed<CalendarDay[]>(() => {\n if (view.value === 'day') return [dayOf(cursor.value)]\n const start = addDays(cursor.value, -((weekday(cursor.value) - weekStart.value + 7) % 7))\n return Array.from({ length: 7 }, (_, index) => dayOf(addDays(start, index)))\n})\n\n/** The days on screen, first to last, whatever the view. */\nconst visible = computed(() => visibleRange(cursor.value, view.value, weekStart.value))\nwatch(\n () => `${visible.value.start}/${visible.value.end}`,\n () => emit('rangeChange', { ...visible.value }),\n { immediate: true },\n)\n\n/** The agenda: the days of the month shown that have events, each with its events. */\nconst agenda = computed(() => {\n if (view.value !== 'agenda') return []\n const first = `${shown.value}-01`\n const { year, month: m } = parts(first)\n return Array.from({ length: daysInMonth(year, m) }, (_, index) =>\n dayOf(addDays(first, index)),\n ).filter((day) => day.events.length)\n})\n\n/** When an event takes place on one day of the agenda. */\nfunction agendaTime(event: CalendarEvent, date: string) {\n const span = spans.value.get(event)!\n if (span.start === null) return t('calendarView.allDay')\n const { start, end } = segmentOn(span, date)\n return `${timeText(start)}–${timeText(end)}`\n}\n\nconst viewOptions = computed(() =>\n (props.views ?? []).map((value) => ({ value, label: t(`calendarView.${value}`) })),\n)\n\n/** A timed event starts with its time in a month cell, on its first day. */\nconst monthTime = (event: CalendarEvent, date: string) => {\n const span = spans.value.get(event)!\n if (span.start === null || span.from !== date) return ''\n return `${String(Math.floor(span.start / 60)).padStart(2, '0')}:${String(span.start % 60).padStart(2, '0')}`\n}\n\nconst isStart = (event: CalendarEvent, date: string) => spans.value.get(event)!.from === date\n/** Whether the day opens a row, where a running span shows its title again. */\nconst weekStarts = (date: string) => (weekday(date) - weekStart.value + 7) % 7 === 0\nconst isEnd = (event: CalendarEvent, date: string) => spans.value.get(event)!.to <= date\n\n/** Whether a day is inside the stretch being drawn. */\nconst inDrawing = (date: string) =>\n !!drawing.value && drawing.value.start <= date && date <= drawing.value.end.slice(0, 10)\n/** An all-day event can have its last day dragged, from the day it ends on. */\nconst resizable = (event: CalendarEvent, date: string) =>\n !!props.editable &&\n !event.locked &&\n spans.value.get(event)!.start === null &&\n spans.value.get(event)!.to === date\n/** The agenda moves events by day only: up and down there walk the list. */\nconst keyShortcuts = computed(() =>\n view.value === 'agenda'\n ? 'Alt+ArrowLeft Alt+ArrowRight Alt+Shift+ArrowLeft Alt+Shift+ArrowRight Delete Backspace Shift+F10'\n : 'Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown Alt+Shift+ArrowLeft Alt+Shift+ArrowRight Alt+Shift+ArrowUp Alt+Shift+ArrowDown Delete Backspace Shift+F10',\n)\n\n/* choosing and moving */\n\nconst gridRef = useTemplateRef<HTMLElement>('grid')\n\nconst rootRef = useTemplateRef<HTMLElement>('root')\n\nasync function focusCursor() {\n await nextTick()\n ;(gridRef.value ?? rootRef.value)\n ?.querySelector<HTMLElement>(`[data-date=\"${cursor.value}\"]`)\n ?.focus({ preventScroll: true })\n}\n\nfunction choose(day: CalendarDay) {\n if (day.disabled) return\n cursor.value = day.date\n model.value = day.date\n emit('select', day.date)\n}\n\nconst weekdayOf = (date: string) => formatter({ weekday: 'short' }).format(asDate(date))\n\nfunction step(direction: 1 | -1) {\n if (view.value === 'week') cursor.value = addDays(cursor.value, direction * 7)\n else if (view.value === 'day') cursor.value = addDays(cursor.value, direction)\n else cursor.value = addMonths(cursor.value, direction)\n}\n\nconst stepLabels = computed(() =>\n view.value === 'week'\n ? [t('calendarView.prevWeek'), t('calendarView.nextWeek')]\n : view.value === 'day'\n ? [t('calendarView.prevDay'), t('calendarView.nextDay')]\n : [t('datePicker.prevMonth'), t('datePicker.nextMonth')],\n)\n\nfunction goToday() {\n cursor.value = todayValue\n}\n\n/** Left and right move between the days at the head of the week view. */\nfunction onTimeKeydown(event: KeyboardEvent) {\n if (view.value !== 'week' || !(event.target as HTMLElement).dataset.date) return\n const moves: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1 }\n const move = moves[event.key]\n if (!move) return\n event.preventDefault()\n const days = weekDays.value\n const index = days.findIndex((day) => day.date === cursor.value) + move\n if (index < 0 || index >= days.length) return\n cursor.value = days[index]!.date\n void focusCursor()\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const date = cursor.value\n const column = (weekday(date) - weekStart.value + 7) % 7\n const keys: Record<string, () => string> = {\n ArrowLeft: () => addDays(date, -1),\n ArrowRight: () => addDays(date, 1),\n ArrowUp: () => addDays(date, -7),\n ArrowDown: () => addDays(date, 7),\n Home: () => addDays(date, -column),\n End: () => addDays(date, 6 - column),\n PageUp: () => addMonths(date, event.shiftKey ? -12 : -1),\n PageDown: () => addMonths(date, event.shiftKey ? 12 : 1),\n }\n const next = keys[event.key]?.()\n if (next) {\n event.preventDefault()\n cursor.value = next\n void focusCursor()\n return\n }\n if (event.key === 'Enter' || event.key === ' ') {\n if ((event.target as HTMLElement).closest('button')) return\n event.preventDefault()\n const day = weeks.value.flat().find((cell) => cell.date === date)\n if (day) choose(day)\n }\n}\n\nfunction dayLabel(day: CalendarDay) {\n const date = fullDate.value.format(asDate(day.date))\n if (!day.events.length) return date\n return t('calendarView.dayWithEvents', { date, count: day.events.length })\n}\n\n/* editing: dragging, drawing, the menu and the keys */\n\nconst LONG_PRESS = 300\nconst THRESHOLD = { mouse: 3, touch: 6 }\n/** How close to the top or bottom of the time axis a drag starts scrolling it, in px. */\nconst EDGE = 32\n\nconst live = ref('')\nfunction announce(text: string) {\n // the same text twice in a row is read again\n live.value = live.value === text ? `${text} ` : text\n}\n\nlet hold: PointerHold | null = null\nlet pressTimer: ReturnType<typeof setTimeout> | undefined\nlet frame = 0\n/** Beside the pointer while dragging: the new time, or why it can't go there. */\nconst tip = computed(() => {\n const d = drag.value\n if (!d?.started || d.kind === 'press') return ''\n if (d.refusal) return d.refusal\n if (d.draft) return rangeText(d.draft)\n return d.range ? rangeText({ id: '', title: '', ...d.range }) : ''\n})\n\n/** Where the pointer is, kept apart from the drag so the tip follows it between snaps. */\nconst pointer = ref({ x: 0, y: 0 })\n/**\n * Beside the pointer, where it stays in view: on its left once past the\n * middle of the window, and above it for a finger, which would cover it,\n * or near the bottom of the window.\n */\nconst tipStyle = computed(() => {\n const d = drag.value\n if (!d || typeof window === 'undefined') return {}\n const { x, y } = pointer.value\n const left = x > window.innerWidth / 2\n const above = d.touch || y + 16 + 40 > window.innerHeight\n return {\n left: `${left ? x - 12 : x + 12}px`,\n top: `${above ? y - (d.touch ? 40 : 16) : y + 16}px`,\n transform: `translate(${left ? '-100%' : '0'}, ${above ? '-100%' : '0'})`,\n }\n})\n\n/** A drag ended a moment ago: the click that follows it is not a click. */\nlet swallow = false\n/** When a finger last went down; the browser's own long-press menu is ignored after it. */\nlet touchedAt = 0\n\nconst byId = (id: string | undefined) => events.value.find((event) => event.id === id)\nconst canEdit = (event: CalendarEvent) => !!props.editable && !event.locked\n\nconst dayFormat = computed(() => formatter({ month: 'short', day: 'numeric' }))\nconst clock = computed(() =>\n formatter({\n hour: 'numeric',\n minute: '2-digit',\n hourCycle: /A/.test(locale.value.region.time) ? 'h12' : 'h23',\n }),\n)\nconst timeText = (minutes: number) => clock.value.format(new Date(Date.UTC(2000, 0, 1, 0, minutes)))\n\n/** When an event takes place, as read out after a change. */\nfunction rangeText(event: CalendarEvent) {\n const span = spanOf(event)\n if (!span) return ''\n const from = dayFormat.value.format(asDate(span.from))\n const to = dayFormat.value.format(asDate(span.to))\n if (span.start === null) return span.from === span.to ? from : `${from} – ${to}`\n if (span.from === span.to) return `${from} ${timeText(span.start)}–${timeText(span.end!)}`\n return `${from} ${timeText(span.start)} – ${to} ${timeText(span.end!)}`\n}\n\n/**\n * The day and time under a point. The nearest column or day is taken when\n * the point is off to the side, so a drag past the edge stays on the last\n * day; on the time axis the time is kept inside the hours shown.\n */\nfunction pointAt(surface: Surface, x: number, y: number) {\n const cells = rootRef.value?.querySelectorAll<HTMLElement>(`[data-drop=\"${surface}\"]`) ?? []\n let best: { cell: HTMLElement; rect: DOMRect } | null = null\n let distance = Infinity\n for (const cell of cells) {\n const rect = cell.getBoundingClientRect()\n const dx = Math.max(rect.left - x, 0, x - rect.right)\n const dy = surface === 'time' ? 0 : Math.max(rect.top - y, 0, y - rect.bottom)\n if (dx * dx + dy * dy < distance) {\n distance = dx * dx + dy * dy\n best = { cell, rect }\n }\n }\n if (!best) return null\n const date = best.cell.dataset.date!\n if (surface === 'day') return { date, minutes: 0 }\n const from = Number(best.cell.dataset.from)\n const to = Number(best.cell.dataset.to)\n const ratio = best.rect.height ? (y - best.rect.top) / best.rect.height : 0\n return { date, minutes: Math.min(to, Math.max(from, from + ratio * (to - from))) }\n}\n\n/** `null` when the change may be made, else why not. */\nfunction refusalOf(kind: CalendarMove['kind'], event: CalendarEvent | null, next: CalendarRange) {\n const span = spanOf({ id: '', title: '', start: next.start, end: next.end })\n if (span && props.disabledDate) {\n for (let date = span.from, guard = 0; date <= span.to && guard < 366; guard++) {\n if (props.disabledDate(date)) return t('calendarView.disabledDay')\n date = addDays(date, 1)\n }\n }\n if (!props.canMove) return null\n const answer = props.canMove({ kind, event, start: next.start, end: next.end }, events.value)\n if (answer === true) return null\n return typeof answer === 'string' && answer ? answer : t('calendarView.refused')\n}\n\nconst DAY = 24 * 60\n/** The minutes the time axis covers, as the time grid draws it. */\nconst axis = computed(() => {\n const from = Math.max(0, Math.min(23, Math.floor(props.hours[0])))\n const to = Math.max(from + 1, Math.min(24, Math.ceil(props.hours[1])))\n return { from: from * 60, to: to * 60 }\n})\n\n/**\n * Where a timed event moved on the time axis starts: an event that sits\n * within one day stays inside the hours shown, so it is never written to a\n * time the axis can't show. One that runs over midnight moves freely.\n */\nfunction fitHours(span: EventSpan, start: number) {\n const { from, to } = axis.value\n const length = stampsOf(span).end - stampsOf(span).start\n if (span.from !== span.to || length > to - from) return start\n const day = Math.floor(start / DAY)\n return day * DAY + Math.min(Math.max(start - day * DAY, from), to - length)\n}\n\nconst roundTo = (value: number, by: number) => Math.round(value / by) * by\nconst floorTo = (value: number, by: number) => Math.floor(value / by) * by\n\n/** Work out what the drag would change, with the pointer where it is now. */\nfunction update(d: Drag) {\n const point = pointAt(d.surface, d.x, d.y)\n if (!point || d.kind === 'press') return\n const snap = Math.max(1, Math.round(props.snap))\n let draft: CalendarEvent | null = null\n let range: CalendarRange | null = null\n if (d.surface === 'time') {\n const now = toStamp(point.date, point.minutes)\n const origin = toStamp(d.origin.date, d.origin.minutes)\n if (d.kind === 'create') {\n const a = floorTo(origin, snap)\n const b = floorTo(now, snap)\n range = { start: formatStamp(Math.min(a, b)), end: formatStamp(Math.max(a, b) + snap) }\n } else {\n const { start } = stampsOf(d.span!)\n if (d.kind === 'move') {\n const next = fitHours(d.span!, roundTo(start + now - origin, snap))\n draft = moveEvent(d.event!, d.span!, { minutes: next - start })\n } else {\n draft = { ...d.event!, end: formatStamp(Math.max(start + snap, roundTo(now, snap))) }\n }\n }\n } else {\n const days = dayIndex(point.date) - dayIndex(d.origin.date)\n if (d.kind === 'create') {\n const [a, b] = [d.origin.date, point.date]\n range = a <= b ? { start: a, end: b } : { start: b, end: a }\n } else if (d.kind === 'move') {\n draft = moveEvent(d.event!, d.span!, { days })\n } else {\n draft = { ...d.event!, end: point.date < d.span!.from ? d.span!.from : point.date }\n }\n }\n if (draft) {\n if (d.draft && sameTime(d.draft, draft)) return\n d.draft = draft\n d.refusal = sameTime(draft, d.event!)\n ? null\n : refusalOf(d.kind, d.event, { start: draft.start, end: endOf(draft) })\n } else if (range) {\n if (d.range?.start === range.start && d.range.end === range.end) return\n d.range = range\n d.refusal = refusalOf('create', null, range)\n }\n triggerRef(drag)\n}\n\n/** The menu target under a pointer or a key press. */\nfunction targetOf(el: HTMLElement, x: number, y: number): CalendarMenuTarget | null {\n const chip = el.closest<HTMLElement>('[data-event-id]')\n const event = chip && byId(chip.dataset.eventId)\n if (event) return { kind: 'event', event }\n const cell = el.closest<HTMLElement>('[data-drop]')\n if (!cell) return null\n if (cell.dataset.drop === 'day') return { kind: 'day', date: cell.dataset.date! }\n const point = pointAt('time', x, y)\n if (!point) return null\n const minutes = Math.min(\n floorTo(point.minutes, Math.max(1, props.snap)),\n Number(cell.dataset.to) - props.snap,\n )\n return { kind: 'time', start: `${point.date} ${formatTime(Math.max(0, minutes))}` }\n}\n\nfunction onPointerDown(event: PointerEvent) {\n if (event.button !== 0 || drag.value) return\n const el = event.target as HTMLElement\n const touch = event.pointerType !== 'mouse'\n const chip = el.closest<HTMLElement>('[data-event-id]')\n const item = chip ? byId(chip.dataset.eventId) : undefined\n const cell = el.closest<HTMLElement>('[data-drop]')\n if (!cell) {\n // the agenda has nothing to drag: a finger resting on an event opens its menu\n const day = el.closest<HTMLElement>('[data-agenda-date]')?.dataset.agendaDate\n if (touch && item && day) {\n startDrag(event, {\n kind: 'press',\n surface: 'day',\n event: item,\n span: spans.value.get(item) ?? null,\n origin: { date: day, minutes: 0 },\n target: { kind: 'event', event: item },\n })\n }\n return\n }\n const surface = cell.dataset.drop as Surface\n let kind: Drag['kind']\n if (item) {\n const span = spans.value.get(item)\n if (!span) return\n if (!canEdit(item)) kind = 'press'\n else if (el.closest('[data-resize]')) kind = 'resize'\n else kind = 'move'\n } else {\n if (chip || el.closest('button, a, input')) return\n if (cell.matches('.is-disabled')) kind = 'press'\n else kind = props.editable ? 'create' : 'press'\n }\n // a mouse has its own menu button; only a finger needs the resting press\n if (kind === 'press' && !touch) return\n const origin = pointAt(surface, event.clientX, event.clientY)\n if (!origin) return\n startDrag(event, {\n kind,\n surface,\n event: item ?? null,\n span: item ? spans.value.get(item)! : null,\n origin,\n target: targetOf(el, event.clientX, event.clientY),\n })\n}\n\n/** Starts following a pointer that went down; a finger picks up after a short rest. */\nfunction startDrag(\n event: PointerEvent,\n start: Pick<Drag, 'kind' | 'surface' | 'event' | 'span' | 'origin' | 'target'>,\n) {\n const touch = event.pointerType !== 'mouse'\n if (touch) touchedAt = Date.now()\n drag.value = {\n ...start,\n pointerId: event.pointerId,\n touch,\n x0: event.clientX,\n y0: event.clientY,\n x: event.clientX,\n y: event.clientY,\n started: false,\n draft: null,\n range: null,\n refusal: null,\n }\n pointer.value = { x: event.clientX, y: event.clientY }\n hold = holdPointer(event, rootRef.value)\n window.addEventListener('pointermove', onDragMove)\n window.addEventListener('pointerup', onDragEnd)\n window.addEventListener('pointercancel', stopDrag)\n window.addEventListener('keydown', onDragKey, true)\n // switching away mid-drag drops it\n window.addEventListener('blur', stopDrag)\n document.addEventListener('visibilitychange', stopDrag)\n // a finger picks an event up after a short rest; moving sooner scrolls instead\n if (touch) {\n const d = drag.value\n pressTimer = setTimeout(() => {\n if (drag.value !== d) return\n begin(d)\n navigator.vibrate?.(8)\n }, LONG_PRESS)\n }\n}\n\nfunction begin(d: Drag) {\n d.started = true\n hold?.grab()\n if (d.kind !== 'press') {\n update(d)\n if (d.surface === 'time') frame = requestAnimationFrame(autoScroll)\n }\n triggerRef(drag)\n}\n\nfunction onDragMove(event: PointerEvent) {\n const d = drag.value\n if (!d || event.pointerId !== d.pointerId) return\n d.x = event.clientX\n d.y = event.clientY\n pointer.value = { x: d.x, y: d.y }\n const far = Math.hypot(d.x - d.x0, d.y - d.y0) > THRESHOLD[d.touch ? 'touch' : 'mouse']\n if (!d.started) {\n // a finger that moves before resting scrolls the page\n if (d.touch) return void (far && stopDrag())\n if (far) begin(d)\n return\n }\n if (d.kind === 'press') return\n update(d)\n}\n\nfunction onDragEnd(event: PointerEvent) {\n const d = drag.value\n if (!d || event.pointerId !== d.pointerId) return\n const still = Math.hypot(d.x - d.x0, d.y - d.y0) <= THRESHOLD.touch\n stopDrag()\n if (!d.started) return\n swallow = true\n setTimeout(() => (swallow = false))\n // a finger rested and let go without moving: the menu\n if (d.touch && still) {\n if (d.target && menuAllowed(d.target, event.clientX, event.clientY))\n showMenu(d.target, event.clientX, event.clientY)\n return\n }\n if (d.refusal) return announce(d.refusal)\n if (d.kind === 'create' && d.range) emit('create', { ...d.range })\n else if ((d.kind === 'move' || d.kind === 'resize') && d.draft && !sameTime(d.draft, d.event!))\n commit(d.kind, d.event!, d.draft)\n}\n\nfunction stopDrag() {\n clearTimeout(pressTimer)\n cancelAnimationFrame(frame)\n hold?.release()\n hold = null\n window.removeEventListener('pointermove', onDragMove)\n window.removeEventListener('pointerup', onDragEnd)\n window.removeEventListener('pointercancel', stopDrag)\n window.removeEventListener('keydown', onDragKey, true)\n window.removeEventListener('blur', stopDrag)\n if (typeof document !== 'undefined') document.removeEventListener('visibilitychange', stopDrag)\n drag.value = null\n}\n\nfunction onDragKey(event: KeyboardEvent) {\n if (event.key !== 'Escape') return\n event.preventDefault()\n event.stopPropagation()\n if (drag.value?.started) {\n swallow = true\n setTimeout(() => (swallow = false))\n }\n stopDrag()\n}\n\n/** Auto-scroll speed in px per frame, `gap` px from the edge. */\nconst speed = (gap: number) => (gap < EDGE ? Math.ceil(((EDGE - gap) / EDGE) * 12) : 0)\n\n/** Scrolls the time axis while a drag rests near its top or bottom. */\nfunction autoScroll() {\n const d = drag.value\n const el = rootRef.value?.querySelector<HTMLElement>(`.${ns.e('scroller')}`)\n if (!d?.started || !el) return\n const rect = el.getBoundingClientRect()\n const dy = speed(d.y - rect.top) ? -speed(d.y - rect.top) : speed(rect.bottom - d.y)\n if (dy) {\n const before = el.scrollTop\n el.scrollTop += dy\n if (el.scrollTop !== before) update(d)\n }\n frame = requestAnimationFrame(autoScroll)\n}\n\nfunction onClickCapture(event: MouseEvent) {\n if (!swallow) return\n event.stopPropagation()\n event.preventDefault()\n}\n\n/** Writes the new version of an event, then keeps the keyboard and the view on it. */\nfunction commit(kind: 'move' | 'resize', previous: CalendarEvent, next: CalendarEvent) {\n events.value = events.value.map((event) => (event === previous ? next : event))\n emit('change', { kind, event: next, previous })\n announce(t('calendarView.changed', { title: next.title, range: rangeText(next) }))\n}\n\nfunction remove(event: CalendarEvent) {\n events.value = events.value.filter((item) => item !== event)\n emit('change', { kind: 'remove', event })\n announce(t('calendarView.removed', { title: event.title }))\n}\n\n/** The element of an event on screen. */\nconst chipOf = (id: string | undefined) =>\n id ? rootRef.value?.querySelector<HTMLElement>(`[data-event-id=\"${CSS.escape(id)}\"]`) : null\n\n/**\n * Removes an event from the keyboard, then puts the keyboard on the next\n * event of the same day, or the one before, or else on the day itself.\n */\nasync function removeByKey(item: CalendarEvent, chip: HTMLElement) {\n const siblings = [...(chip.parentElement?.querySelectorAll<HTMLElement>('[data-event-id]') ?? [])]\n const index = siblings.indexOf(chip)\n // oxlint-disable-next-line unicorn/no-array-reverse -- reverses a fresh slice\n const near = [...siblings.slice(index + 1), ...siblings.slice(0, index).reverse()]\n .map((el) => el.dataset.eventId!)\n .find((id) => id !== item.id)\n const holder = chip.closest<HTMLElement>('[data-date], [data-agenda-date]')\n const day = holder?.dataset.date ?? holder?.dataset.agendaDate\n // in the agenda a day without events goes away: fall back to the next day's first event, or the one before's\n const listed = chip.closest<HTMLElement>('[data-agenda-date]')\n const neighbour = (listed?.nextElementSibling ?? listed?.previousElementSibling) as\n HTMLElement | null | undefined\n const fallback = neighbour?.querySelector<HTMLElement>('[data-event-id]')?.dataset.eventId\n remove(item)\n await nextTick()\n const next = chipOf(near) ?? chipOf(fallback)\n if (next) return next.focus()\n if (day) cursor.value = day\n void focusCursor()\n}\n\n/* the menu */\n\nconst menuRef = useTemplateRef<InstanceType<typeof DouContextMenu>>('menu')\nconst menuOpen = ref(false)\nconst menuItems = shallowRef<ContextMenuItem[]>([])\n\n/**\n * Sends `eventContextmenu` before an event's menu opens; `false` when the\n * app kept it closed. A resting finger or the menu key has no browser event\n * of its own, so it gets a stand-in.\n */\nfunction menuAllowed(target: CalendarMenuTarget, x: number, y: number, native?: MouseEvent) {\n if (target.kind !== 'event') return true\n const event =\n native ?? new MouseEvent('contextmenu', { cancelable: true, clientX: x, clientY: y })\n emit('eventContextmenu', target.event, event)\n return !event.defaultPrevented\n}\n\n/** Opens the menu for a target; `false` when it would be empty. */\nfunction showMenu(target: CalendarMenuTarget, x: number, y: number) {\n const items = [...(props.contextMenu?.(target) ?? [])]\n if (props.menu && target.kind === 'event' && canEdit(target.event)) {\n items.push({\n key: '\\0delete',\n label: t('calendarView.deleteEvent'),\n icon: TrashIcon,\n shortcut: 'Delete',\n tone: 'danger',\n divided: items.length > 0,\n run: () => remove(target.event),\n })\n }\n if (!items.length) return false\n menuItems.value = items\n menuRef.value?.open(x, y)\n return true\n}\n\nfunction onContextmenu(event: MouseEvent) {\n // a finger's long press opens the menu itself, when it lets go\n if (Date.now() - touchedAt < 1000) return event.preventDefault()\n const target = targetOf(event.target as HTMLElement, event.clientX, event.clientY)\n if (!target) return\n if (!menuAllowed(target, event.clientX, event.clientY, event)) return\n if (showMenu(target, event.clientX, event.clientY)) event.preventDefault()\n}\n\n/* keys on an event */\n\n/**\n * Puts the keyboard back on an event after a change; when the app stored it\n * under a new id, e.g. one occurrence of a series, on the day it went to.\n */\nasync function focusEvent(id: string) {\n await nextTick()\n const chip = chipOf(id)\n if (chip) chip.focus()\n else void focusCursor()\n}\n\n/**\n * On a focused event: the menu key opens its menu, `Delete` removes it,\n * `Alt` with the arrows moves it and `Alt` + `Shift` with the arrows moves\n * its end. Left and right go by a day; up and down by `snap` on the time\n * axis, or by a week in the month.\n */\nfunction onEventKeydown(event: KeyboardEvent) {\n const chip = (event.target as HTMLElement).closest<HTMLElement>('[data-event-id]')\n const item = chip && byId(chip.dataset.eventId)\n if (!item) return\n const done = () => {\n event.preventDefault()\n event.stopPropagation()\n }\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n const rect = chip.getBoundingClientRect()\n const target = { kind: 'event', event: item } as const\n if (!menuAllowed(target, rect.left, rect.bottom)) return done()\n if (showMenu(target, rect.left, rect.bottom)) done()\n return\n }\n if (!canEdit(item)) return\n if (event.key === 'Delete' || event.key === 'Backspace') {\n done()\n removeByKey(item, chip)\n return\n }\n const span = spans.value.get(item)\n if (!event.altKey || !span) return\n const timed = span.start !== null\n const onAxis = timed && view.value !== 'month' && view.value !== 'agenda'\n const snap = Math.max(1, Math.round(props.snap))\n const keys: Record<string, { days?: number; minutes?: number }> = {\n ArrowLeft: { days: -1 },\n ArrowRight: { days: 1 },\n ArrowUp: onAxis ? { minutes: -snap } : view.value === 'month' ? { days: -7 } : {},\n ArrowDown: onAxis ? { minutes: snap } : view.value === 'month' ? { days: 7 } : {},\n }\n const by = keys[event.key]\n if (!by || (!by.days && !by.minutes)) return\n done()\n let next: CalendarEvent\n let kind: 'move' | 'resize' = 'move'\n if (event.shiftKey) {\n kind = 'resize'\n if (timed) {\n const { start, end } = stampsOf(span)\n const delta = (by.days ?? 0) * DAY + (by.minutes ?? 0)\n let last = Math.max(start + snap, end + delta)\n // an event within one day on the time axis ends by the end of the hours shown\n if (onAxis && span.from === span.to) {\n const day = Math.floor(start / DAY)\n last = Math.min(last, day * DAY + axis.value.to)\n }\n next = { ...item, end: formatStamp(last) }\n } else {\n const last = addDays(span.to, by.days ?? 0)\n next = { ...item, end: last < span.from ? span.from : last }\n }\n } else if (onAxis) {\n const { start } = stampsOf(span)\n const at = fitHours(span, start + (by.days ?? 0) * DAY + (by.minutes ?? 0))\n next = moveEvent(item, span, { minutes: at - start })\n } else {\n next = moveEvent(item, span, by)\n }\n if (sameTime(next, item)) return\n const refusal = refusalOf(kind, item, { start: next.start, end: endOf(next) })\n if (refusal) return announce(refusal)\n commit(kind, item, next)\n const placed = spanOf(next)\n if (placed) cursor.value = kind === 'resize' ? placed.to : placed.from\n void focusEvent(next.id)\n}\n\nonBeforeUnmount(stopDrag)\n\n// Editing without anywhere to write the change: each drop springs back. Say so once while developing.\nconst instance = getCurrentInstance()\nwatch(\n () => props.editable,\n (editable) => {\n if (process.env.NODE_ENV === 'production' || !editable) return\n const bound = instance?.vnode.props ?? {}\n const has = (...names: string[]) => names.some((name) => name in bound)\n if (has('events') && !has('onUpdate:events', 'onChange')) {\n console.warn(\n '[dou-ui] CalendarView is editable but nothing receives the changes, so they spring back. Bind v-model:events, or listen to change.',\n )\n }\n },\n { immediate: true },\n)\n\ndefineExpose<CalendarViewExpose>({\n show: (date) => (cursor.value = date.length === 7 ? `${date}-01` : date),\n focus: () => void focusCursor(),\n})\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[\n ns.b(),\n ns.m(view),\n ns.is('editable', !!editable),\n ns.is('dragging', !!drag?.started && drag.kind !== 'press'),\n drag?.started && drag.kind !== 'press' ? `is-dragging-${drag.kind}` : '',\n ]\"\n @pointerdown=\"onPointerDown\"\n @contextmenu=\"onContextmenu\"\n @click.capture=\"onClickCapture\"\n @keydown.capture=\"onEventKeydown\"\n >\n <div :class=\"ns.e('header')\">\n <h2 :class=\"ns.e('title')\" aria-live=\"polite\">{{ title }}</h2>\n <div :class=\"ns.e('nav')\">\n <slot name=\"extra\" />\n <DouSegmentedControl\n v-if=\"viewOptions.length > 1\"\n v-model=\"view\"\n :options=\"viewOptions\"\n size=\"sm\"\n />\n <button type=\"button\" :class=\"ns.e('today')\" @click=\"goToday\">\n {{ t('datePicker.today') }}\n </button>\n <button type=\"button\" :class=\"ns.e('step')\" :aria-label=\"stepLabels[0]\" @click=\"step(-1)\">\n <ChevronLeftIcon />\n </button>\n <button type=\"button\" :class=\"ns.e('step')\" :aria-label=\"stepLabels[1]\" @click=\"step(1)\">\n <ChevronRightIcon />\n </button>\n </div>\n </div>\n <div\n v-if=\"view === 'agenda'\"\n ref=\"grid\"\n role=\"list\"\n :class=\"ns.e('agenda')\"\n :aria-label=\"title\"\n >\n <p v-if=\"!agenda.length\" :class=\"ns.e('agenda-empty')\">{{ t('calendarView.empty') }}</p>\n <div\n v-for=\"day in agenda\"\n :key=\"day.date\"\n role=\"listitem\"\n :data-agenda-date=\"day.date\"\n :class=\"[ns.e('agenda-day'), ns.is('today', day.today), ns.is('selected', day.selected)]\"\n >\n <button\n type=\"button\"\n :class=\"ns.e('agenda-date')\"\n :data-date=\"day.date\"\n :disabled=\"day.disabled\"\n :aria-label=\"dayLabel(day)\"\n :aria-current=\"day.today ? 'date' : undefined\"\n :aria-pressed=\"day.selected\"\n @click=\"choose(day)\"\n >\n <span :class=\"ns.e('number')\">{{ day.day }}</span>\n <span :class=\"ns.e('agenda-weekday')\">{{ weekdayOf(day.date) }}</span>\n </button>\n <div :class=\"ns.e('agenda-events')\">\n <button\n v-for=\"event in day.events\"\n :key=\"event.id\"\n type=\"button\"\n :data-event-id=\"event.id\"\n :class=\"[\n ns.e('agenda-event'),\n `${ns.e('event')}--${event.tone ?? 'primary'}`,\n ns.is('locked', !!editable && !!event.locked),\n ]\"\n :aria-keyshortcuts=\"editable && !event.locked ? keyShortcuts : undefined\"\n @click=\"emit('eventClick', event)\"\n >\n <span :class=\"ns.e('agenda-time')\">{{ agendaTime(event, day.date) }}</span>\n <span :class=\"ns.e('agenda-title')\">\n <slot name=\"event\" :event=\"event\" :day=\"day\">{{ event.title }}</slot>\n </span>\n </button>\n </div>\n </div>\n </div>\n <TimeGrid\n v-else-if=\"view !== 'month'\"\n :days=\"weekDays\"\n :spans=\"spans\"\n :hours=\"hours\"\n :scroll-time=\"scrollTime\"\n :cursor=\"cursor\"\n :as-date=\"asDate\"\n :editable=\"!!editable\"\n :dragged=\"dragged\"\n :refused=\"refused\"\n :drawing=\"drawing\"\n :snap=\"snap\"\n @choose=\"choose\"\n @event-click=\"emit('eventClick', $event)\"\n @time-click=\"emit('timeClick', $event)\"\n @keydown=\"onTimeKeydown\"\n >\n <template v-if=\"slots.event\" #event=\"scope\">\n <slot name=\"event\" v-bind=\"scope\" />\n </template>\n </TimeGrid>\n <div\n v-else\n ref=\"grid\"\n role=\"grid\"\n :class=\"ns.e('grid')\"\n :aria-label=\"title\"\n @keydown=\"onKeydown\"\n >\n <div role=\"row\" :class=\"ns.e('weekdays')\">\n <div\n v-for=\"weekdayName in weekdays\"\n :key=\"weekdayName.long\"\n role=\"columnheader\"\n :class=\"ns.e('weekday')\"\n :aria-label=\"weekdayName.long\"\n >\n {{ weekdayName.short }}\n </div>\n </div>\n <div v-for=\"(week, row) in weeks\" :key=\"row\" role=\"row\" :class=\"ns.e('week')\">\n <div\n v-for=\"day in week\"\n :key=\"day.date\"\n role=\"gridcell\"\n data-drop=\"day\"\n :data-date=\"day.date\"\n :tabindex=\"day.date === cursor ? 0 : -1\"\n :aria-selected=\"day.selected\"\n :aria-disabled=\"day.disabled || undefined\"\n :aria-current=\"day.today ? 'date' : undefined\"\n :aria-label=\"dayLabel(day)\"\n :class=\"[\n ns.e('day'),\n ns.is('outside', day.outside),\n ns.is('today', day.today),\n ns.is('selected', day.selected),\n ns.is('disabled', day.disabled),\n ns.is('drawing', inDrawing(day.date)),\n ns.is('refused', inDrawing(day.date) && refused),\n ]\"\n @click=\"choose(day)\"\n >\n <span :class=\"ns.e('number')\">{{ day.day }}</span>\n <div :class=\"ns.e('content')\">\n <slot name=\"cell\" v-bind=\"day\">\n <button\n v-for=\"event in day.events.slice(0, maxEvents)\"\n :key=\"event.id\"\n type=\"button\"\n :data-event-id=\"event.id\"\n :tabindex=\"day.date === cursor ? 0 : -1\"\n :class=\"[\n ns.e('event'),\n `${ns.e('event')}--${event.tone ?? 'primary'}`,\n ns.is('start', isStart(event, day.date)),\n ns.is('continued', !isStart(event, day.date) && !weekStarts(day.date)),\n ns.is('end', isEnd(event, day.date)),\n ns.is('locked', !!editable && !!event.locked),\n ns.is('dragging', event === dragged),\n ns.is('refused', event === dragged && refused),\n ]\"\n :title=\"event.title\"\n :aria-keyshortcuts=\"editable && !event.locked ? keyShortcuts : undefined\"\n @click.stop=\"emit('eventClick', event)\"\n >\n <slot name=\"event\" :event=\"event\" :day=\"day\"\n ><span v-if=\"monthTime(event, day.date)\" :class=\"ns.e('event-clock')\">{{\n monthTime(event, day.date)\n }}</span\n >{{ event.title }}</slot\n ><span\n v-if=\"resizable(event, day.date)\"\n :class=\"[ns.e('resize'), `${ns.e('resize')}--x`]\"\n data-resize\n aria-hidden=\"true\"\n />\n </button>\n <span v-if=\"day.events.length > maxEvents\" :class=\"ns.e('more')\">\n {{ t('calendarView.more', { count: day.events.length - maxEvents }) }}\n </span>\n </slot>\n </div>\n </div>\n </div>\n </div>\n <span :class=\"ns.e('live')\" aria-live=\"polite\">{{ live }}</span>\n <div\n v-if=\"tip\"\n :class=\"[ns.e('tip'), ns.is('refused', refused)]\"\n :style=\"tipStyle\"\n aria-hidden=\"true\"\n >\n {{ tip }}\n </div>\n <!-- The calendar opens the menu itself; the empty anchor only gives it a place in the page. -->\n <DouContextMenu ref=\"menu\" v-model:open=\"menuOpen\" :items=\"menuItems\">\n <span :class=\"ns.e('menu-anchor')\" aria-hidden=\"true\" />\n </DouContextMenu>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"calendar-view.vue_vue_type_script_setup_true_lang.js","names":["TimeGridComponent","_useModel","_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_toDisplayString","_renderSlot","_createBlock","_createCommentVNode","_createVNode","_Fragment","_renderList","_createTextVNode","_createSlots","_withCtx","_normalizeProps","_guardReactiveProps","_mergeProps","_withModifiers","_normalizeStyle"],"sources":["../../../src/components/calendar-view/calendar-view.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ContextMenuItem } from '../context-menu/context-menu'\nimport { ChevronLeftIcon, ChevronRightIcon, TrashIcon } from '@dou-ui/icons'\nimport {\n computed,\n getCurrentInstance,\n nextTick,\n onBeforeUnmount,\n ref,\n shallowRef,\n triggerRef,\n useTemplateRef,\n watch,\n} from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { holdPointer } from '../../utils/pointer'\nimport type { PointerHold } from '../../utils/pointer'\nimport { useLocale } from '../config-provider/use-config'\nimport { DouContextMenu } from '../context-menu'\nimport {\n addDays,\n addMonths,\n daysInMonth,\n parts,\n today,\n toDateString,\n weekday,\n} from '../date-picker/date'\nimport { DouSegmentedControl } from '../segmented-control'\nimport type {\n CalendarChange,\n CalendarDay,\n CalendarEvent,\n CalendarMenuTarget,\n CalendarMove,\n CalendarRange,\n CalendarViewExpose,\n CalendarViewMode,\n CalendarViewProps,\n CalendarViewSlots,\n} from './calendar-view'\nimport {\n dayIndex,\n endOf,\n formatStamp,\n formatTime,\n moveEvent,\n sameTime,\n stampsOf,\n toStamp,\n} from './editing'\nimport TimeGridComponent from './time-grid.vue'\nimport type { HTMLAttributes } from 'vue'\nimport type { WithAttributes } from '../../utils/install'\nimport { visibleRange } from './range'\nimport { segmentOn, spanOf } from './time-layout'\nimport type { EventSpan } from './time-layout'\n\n// 让模板里也能写这个组件转交的原生属性\nconst TimeGrid = TimeGridComponent as WithAttributes<typeof TimeGridComponent, HTMLAttributes>\n\ndefineOptions({ name: 'DouCalendarView' })\n\nconst props = withDefaults(defineProps<CalendarViewProps>(), {\n maxEvents: 3,\n hours: () => [0, 24],\n scrollTime: '08:00',\n snap: 15,\n menu: true,\n bordered: true,\n})\nconst model = defineModel<string | null>()\nconst month = defineModel<string>('month')\nconst view = defineModel<CalendarViewMode>('view', { default: 'month' })\nconst events = defineModel<CalendarEvent[]>('events', { default: () => [] })\nconst emit = defineEmits<{\n select: [date: string]\n eventClick: [event: CalendarEvent]\n timeClick: [start: string]\n change: [change: CalendarChange]\n create: [range: CalendarRange]\n eventContextmenu: [event: CalendarEvent, nativeEvent: MouseEvent]\n rangeChange: [range: CalendarRange]\n}>()\nconst slots = defineSlots<CalendarViewSlots>()\n\nconst ns = useNamespace('calendar-view')\nconst { t, locale } = useLocale()\n\nconst weekStart = computed(() => props.weekStart ?? locale.value.region.weekStart)\nconst todayValue = today()\n\n/** The day the keyboard is on; its month is the one shown. */\nconst cursor = ref(model.value || (month.value ? `${month.value}-01` : todayValue))\nconst shown = computed(() => cursor.value.slice(0, 7))\n\nwatch(shown, (value) => {\n if (value !== month.value) month.value = value\n})\nwatch(month, (value) => {\n if (value && value !== shown.value) cursor.value = `${value}-01`\n})\nwatch(model, (value) => {\n if (value && value.slice(0, 7) !== shown.value) cursor.value = value\n})\n\nconst asDate = (date: string) => {\n const { year, month: m, day } = parts(date)\n const value = new Date(Date.UTC(2000, m - 1, day))\n value.setUTCFullYear(year)\n return value\n}\nconst formatter = (options: Intl.DateTimeFormatOptions) =>\n new Intl.DateTimeFormat(locale.value.name, { timeZone: 'UTC', ...options })\n\nconst fullDate = computed(() => formatter({ dateStyle: 'full' }))\nconst title = computed(() => {\n if (view.value === 'day') return fullDate.value.format(asDate(cursor.value))\n if (view.value === 'week') {\n // Composed by hand: some locales fall back to all-numeric dates in formatRange.\n const first = weekDays.value[0]!.date\n const last = weekDays.value.at(-1)!.date\n const full = formatter({ year: 'numeric', month: 'short', day: 'numeric' })\n const end =\n first.slice(0, 4) === last.slice(0, 4) ? formatter({ month: 'short', day: 'numeric' }) : full\n return `${full.format(asDate(first))} – ${end.format(asDate(last))}`\n }\n return formatter({ year: 'numeric', month: 'long' }).format(asDate(`${shown.value}-01`))\n})\nconst weekdays = computed(() => {\n const short = formatter({ weekday: 'short' })\n const long = formatter({ weekday: 'long' })\n // 2024-01-07 is a Sunday.\n return Array.from({ length: 7 }, (_, index) => {\n const date = asDate(toDateString(2024, 1, 7 + ((weekStart.value + index) % 7)))\n return { short: short.format(date), long: long.format(date) }\n })\n})\n\ntype Surface = 'time' | 'day'\ninterface Drag {\n /** `press` is a finger resting where nothing can be dragged: letting go opens the menu. */\n kind: 'move' | 'resize' | 'create' | 'press'\n surface: Surface\n event: CalendarEvent | null\n span: EventSpan | null\n /** Where the press began: the day and, on the time axis, minutes since midnight. */\n origin: { date: string; minutes: number }\n pointerId: number\n touch: boolean\n x0: number\n y0: number\n x: number\n y: number\n started: boolean\n /** The event at its new time, while moving or resizing. */\n draft: CalendarEvent | null\n /** The stretch being drawn, while creating. */\n range: CalendarRange | null\n refusal: string | null\n /** What a resting finger opens the menu on. */\n target: CalendarMenuTarget | null\n}\n\nconst drag = shallowRef<Drag | null>(null)\nconst dragged = computed(() => (drag.value?.started && drag.value.draft) || null)\nconst drawing = computed(() => (drag.value?.started && drag.value.range) || null)\nconst refused = computed(() => !!(drag.value?.started && drag.value.refusal))\n\n/** The events as shown: the one being dragged at its new time. */\nconst shownEvents = computed(() => {\n const d = drag.value\n if (!d?.started || !d.event || !d.draft) return events.value\n return events.value.map((event) => (event === d.event ? d.draft! : event))\n})\n\n/** Where each event falls; events whose `start` can't be read are left out. */\nconst spans = computed(() => {\n const map = new Map<CalendarEvent, EventSpan>()\n for (const event of shownEvents.value) {\n const span = spanOf(event)\n if (span) map.set(event, span)\n }\n return map\n})\n\n// Events that can't be read are left out; say so once per event while developing.\nconst warned = new WeakSet<CalendarEvent>()\nwatch(\n events,\n (list) => {\n // the app's bundler replaces this, as for Vue's own warnings\n if (process.env.NODE_ENV === 'production') return\n for (const event of list) {\n if (spans.value.has(event) || warned.has(event)) continue\n warned.add(event)\n console.warn(\n `[dou-ui] CalendarView event \"${event.id}\" has a start that can't be read: \"${event.start}\". Use YYYY-MM-DD or YYYY-MM-DD HH:mm.`,\n )\n }\n },\n { immediate: true },\n)\n\n/**\n * Events that run over several days first, so their bars tend to line up\n * from day to day, then the other all-day ones, then timed ones by when\n * they start on the day.\n */\nconst startOn = (event: CalendarEvent, date: string) => {\n // the event being dragged comes first, so it never folds into \"+N\"\n if (event === dragged.value) return -3\n const span = spans.value.get(event)!\n if (span.from !== span.to) return -2\n return span.start === null ? -1 : segmentOn(span, date).start\n}\n\n/** Events by day, a span listed on every day it covers. */\nconst byDay = computed(() => {\n const map = new Map<string, CalendarEvent[]>()\n for (const span of spans.value.values()) {\n for (let date = span.from, guard = 0; date <= span.to && guard < 366; guard++) {\n const list = map.get(date) ?? []\n list.push(span.event)\n map.set(date, list)\n date = addDays(date, 1)\n }\n }\n for (const [date, list] of map)\n // oxlint-disable-next-line unicorn/no-array-sort -- sorts the lists built above\n list.sort((a, b) => startOn(a, date) - startOn(b, date))\n return map\n})\n\nconst weeks = computed<CalendarDay[][]>(() => {\n const first = `${shown.value}-01`\n const offset = (weekday(first) - weekStart.value + 7) % 7\n const start = addDays(first, -offset)\n return Array.from({ length: 6 }, (_row, row) =>\n Array.from({ length: 7 }, (_column, column) => {\n const date = addDays(start, row * 7 + column)\n return {\n date,\n day: parts(date).day,\n outside: date.slice(0, 7) !== shown.value,\n today: date === todayValue,\n selected: date === model.value,\n disabled: !!props.disabledDate?.(date),\n events: byDay.value.get(date) ?? [],\n }\n }),\n )\n})\n\nconst dayOf = (date: string): CalendarDay => ({\n date,\n day: parts(date).day,\n outside: false,\n today: date === todayValue,\n selected: date === model.value,\n disabled: !!props.disabledDate?.(date),\n events: byDay.value.get(date) ?? [],\n})\n\n/** The days on the time axis: the cursor's week, or the cursor alone. */\nconst weekDays = computed<CalendarDay[]>(() => {\n if (view.value === 'day') return [dayOf(cursor.value)]\n const start = addDays(cursor.value, -((weekday(cursor.value) - weekStart.value + 7) % 7))\n return Array.from({ length: 7 }, (_, index) => dayOf(addDays(start, index)))\n})\n\n/** The days on screen, first to last, whatever the view. */\nconst visible = computed(() => visibleRange(cursor.value, view.value, weekStart.value))\nwatch(\n () => `${visible.value.start}/${visible.value.end}`,\n () => emit('rangeChange', { ...visible.value }),\n { immediate: true },\n)\n\n/** The agenda: the days of the month shown that have events, each with its events. */\nconst agenda = computed(() => {\n if (view.value !== 'agenda') return []\n const first = `${shown.value}-01`\n const { year, month: m } = parts(first)\n return Array.from({ length: daysInMonth(year, m) }, (_, index) =>\n dayOf(addDays(first, index)),\n ).filter((day) => day.events.length)\n})\n\n/** When an event takes place on one day of the agenda. */\nfunction agendaTime(event: CalendarEvent, date: string) {\n const span = spans.value.get(event)!\n if (span.start === null) return t('calendarView.allDay')\n const { start, end } = segmentOn(span, date)\n return `${timeText(start)}–${timeText(end)}`\n}\n\nconst viewOptions = computed(() =>\n (props.views ?? []).map((value) => ({ value, label: t(`calendarView.${value}`) })),\n)\n\n/** A timed event starts with its time in a month cell, on its first day. */\nconst monthTime = (event: CalendarEvent, date: string) => {\n const span = spans.value.get(event)!\n if (span.start === null || span.from !== date) return ''\n return `${String(Math.floor(span.start / 60)).padStart(2, '0')}:${String(span.start % 60).padStart(2, '0')}`\n}\n\nconst isStart = (event: CalendarEvent, date: string) => spans.value.get(event)!.from === date\n/** Whether the day opens a row, where a running span shows its title again. */\nconst weekStarts = (date: string) => (weekday(date) - weekStart.value + 7) % 7 === 0\nconst isEnd = (event: CalendarEvent, date: string) => spans.value.get(event)!.to <= date\n\n/** Whether a day is inside the stretch being drawn. */\nconst inDrawing = (date: string) =>\n !!drawing.value && drawing.value.start <= date && date <= drawing.value.end.slice(0, 10)\n/** An all-day event can have its last day dragged, from the day it ends on. */\nconst resizable = (event: CalendarEvent, date: string) =>\n !!props.editable &&\n !event.locked &&\n spans.value.get(event)!.start === null &&\n spans.value.get(event)!.to === date\n/** The agenda moves events by day only: up and down there walk the list. */\nconst keyShortcuts = computed(() =>\n view.value === 'agenda'\n ? 'Alt+ArrowLeft Alt+ArrowRight Alt+Shift+ArrowLeft Alt+Shift+ArrowRight Delete Backspace Shift+F10'\n : 'Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown Alt+Shift+ArrowLeft Alt+Shift+ArrowRight Alt+Shift+ArrowUp Alt+Shift+ArrowDown Delete Backspace Shift+F10',\n)\n\n/* choosing and moving */\n\nconst gridRef = useTemplateRef<HTMLElement>('grid')\n\nconst rootRef = useTemplateRef<HTMLElement>('root')\n\nasync function focusCursor() {\n await nextTick()\n ;(gridRef.value ?? rootRef.value)\n ?.querySelector<HTMLElement>(`[data-date=\"${cursor.value}\"]`)\n ?.focus({ preventScroll: true })\n}\n\nfunction choose(day: CalendarDay) {\n if (day.disabled) return\n cursor.value = day.date\n model.value = day.date\n emit('select', day.date)\n}\n\nconst weekdayOf = (date: string) => formatter({ weekday: 'short' }).format(asDate(date))\n\nfunction step(direction: 1 | -1) {\n if (view.value === 'week') cursor.value = addDays(cursor.value, direction * 7)\n else if (view.value === 'day') cursor.value = addDays(cursor.value, direction)\n else cursor.value = addMonths(cursor.value, direction)\n}\n\nconst stepLabels = computed(() =>\n view.value === 'week'\n ? [t('calendarView.prevWeek'), t('calendarView.nextWeek')]\n : view.value === 'day'\n ? [t('calendarView.prevDay'), t('calendarView.nextDay')]\n : [t('datePicker.prevMonth'), t('datePicker.nextMonth')],\n)\n\nfunction goToday() {\n cursor.value = todayValue\n}\n\n/** Left and right move between the days at the head of the week view. */\nfunction onTimeKeydown(event: KeyboardEvent) {\n if (view.value !== 'week' || !(event.target as HTMLElement).dataset.date) return\n const moves: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1 }\n const move = moves[event.key]\n if (!move) return\n event.preventDefault()\n const days = weekDays.value\n const index = days.findIndex((day) => day.date === cursor.value) + move\n if (index < 0 || index >= days.length) return\n cursor.value = days[index]!.date\n void focusCursor()\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const date = cursor.value\n const column = (weekday(date) - weekStart.value + 7) % 7\n const keys: Record<string, () => string> = {\n ArrowLeft: () => addDays(date, -1),\n ArrowRight: () => addDays(date, 1),\n ArrowUp: () => addDays(date, -7),\n ArrowDown: () => addDays(date, 7),\n Home: () => addDays(date, -column),\n End: () => addDays(date, 6 - column),\n PageUp: () => addMonths(date, event.shiftKey ? -12 : -1),\n PageDown: () => addMonths(date, event.shiftKey ? 12 : 1),\n }\n const next = keys[event.key]?.()\n if (next) {\n event.preventDefault()\n cursor.value = next\n void focusCursor()\n return\n }\n if (event.key === 'Enter' || event.key === ' ') {\n if ((event.target as HTMLElement).closest('button')) return\n event.preventDefault()\n const day = weeks.value.flat().find((cell) => cell.date === date)\n if (day) choose(day)\n }\n}\n\nfunction dayLabel(day: CalendarDay) {\n const date = fullDate.value.format(asDate(day.date))\n if (!day.events.length) return date\n return t('calendarView.dayWithEvents', { date, count: day.events.length })\n}\n\n/* editing: dragging, drawing, the menu and the keys */\n\nconst LONG_PRESS = 300\nconst THRESHOLD = { mouse: 3, touch: 6 }\n/** How close to the top or bottom of the time axis a drag starts scrolling it, in px. */\nconst EDGE = 32\n\nconst live = ref('')\nfunction announce(text: string) {\n // the same text twice in a row is read again\n live.value = live.value === text ? `${text} ` : text\n}\n\nlet hold: PointerHold | null = null\nlet pressTimer: ReturnType<typeof setTimeout> | undefined\nlet frame = 0\n/** Beside the pointer while dragging: the new time, or why it can't go there. */\nconst tip = computed(() => {\n const d = drag.value\n if (!d?.started || d.kind === 'press') return ''\n if (d.refusal) return d.refusal\n if (d.draft) return rangeText(d.draft)\n return d.range ? rangeText({ id: '', title: '', ...d.range }) : ''\n})\n\n/** Where the pointer is, kept apart from the drag so the tip follows it between snaps. */\nconst pointer = ref({ x: 0, y: 0 })\n/**\n * Beside the pointer, where it stays in view: on its left once past the\n * middle of the window, and above it for a finger, which would cover it,\n * or near the bottom of the window.\n */\nconst tipStyle = computed(() => {\n const d = drag.value\n if (!d || typeof window === 'undefined') return {}\n const { x, y } = pointer.value\n const left = x > window.innerWidth / 2\n const above = d.touch || y + 16 + 40 > window.innerHeight\n return {\n left: `${left ? x - 12 : x + 12}px`,\n top: `${above ? y - (d.touch ? 40 : 16) : y + 16}px`,\n transform: `translate(${left ? '-100%' : '0'}, ${above ? '-100%' : '0'})`,\n }\n})\n\n/** A drag ended a moment ago: the click that follows it is not a click. */\nlet swallow = false\n/** When a finger last went down; the browser's own long-press menu is ignored after it. */\nlet touchedAt = 0\n\nconst byId = (id: string | undefined) => events.value.find((event) => event.id === id)\nconst canEdit = (event: CalendarEvent) => !!props.editable && !event.locked\n\nconst dayFormat = computed(() => formatter({ month: 'short', day: 'numeric' }))\nconst clock = computed(() =>\n formatter({\n hour: 'numeric',\n minute: '2-digit',\n hourCycle: /A/.test(locale.value.region.time) ? 'h12' : 'h23',\n }),\n)\nconst timeText = (minutes: number) => clock.value.format(new Date(Date.UTC(2000, 0, 1, 0, minutes)))\n\n/** When an event takes place, as read out after a change. */\nfunction rangeText(event: CalendarEvent) {\n const span = spanOf(event)\n if (!span) return ''\n const from = dayFormat.value.format(asDate(span.from))\n const to = dayFormat.value.format(asDate(span.to))\n if (span.start === null) return span.from === span.to ? from : `${from} – ${to}`\n if (span.from === span.to) return `${from} ${timeText(span.start)}–${timeText(span.end!)}`\n return `${from} ${timeText(span.start)} – ${to} ${timeText(span.end!)}`\n}\n\n/**\n * The day and time under a point. The nearest column or day is taken when\n * the point is off to the side, so a drag past the edge stays on the last\n * day; on the time axis the time is kept inside the hours shown.\n */\nfunction pointAt(surface: Surface, x: number, y: number) {\n const cells = rootRef.value?.querySelectorAll<HTMLElement>(`[data-drop=\"${surface}\"]`) ?? []\n let best: { cell: HTMLElement; rect: DOMRect } | null = null\n let distance = Infinity\n for (const cell of cells) {\n const rect = cell.getBoundingClientRect()\n const dx = Math.max(rect.left - x, 0, x - rect.right)\n const dy = surface === 'time' ? 0 : Math.max(rect.top - y, 0, y - rect.bottom)\n if (dx * dx + dy * dy < distance) {\n distance = dx * dx + dy * dy\n best = { cell, rect }\n }\n }\n if (!best) return null\n const date = best.cell.dataset.date!\n if (surface === 'day') return { date, minutes: 0 }\n const from = Number(best.cell.dataset.from)\n const to = Number(best.cell.dataset.to)\n const ratio = best.rect.height ? (y - best.rect.top) / best.rect.height : 0\n return { date, minutes: Math.min(to, Math.max(from, from + ratio * (to - from))) }\n}\n\n/** `null` when the change may be made, else why not. */\nfunction refusalOf(kind: CalendarMove['kind'], event: CalendarEvent | null, next: CalendarRange) {\n const span = spanOf({ id: '', title: '', start: next.start, end: next.end })\n if (span && props.disabledDate) {\n for (let date = span.from, guard = 0; date <= span.to && guard < 366; guard++) {\n if (props.disabledDate(date)) return t('calendarView.disabledDay')\n date = addDays(date, 1)\n }\n }\n if (!props.canMove) return null\n const answer = props.canMove({ kind, event, start: next.start, end: next.end }, events.value)\n if (answer === true) return null\n return typeof answer === 'string' && answer ? answer : t('calendarView.refused')\n}\n\nconst DAY = 24 * 60\n/** The minutes the time axis covers, as the time grid draws it. */\nconst axis = computed(() => {\n const from = Math.max(0, Math.min(23, Math.floor(props.hours[0])))\n const to = Math.max(from + 1, Math.min(24, Math.ceil(props.hours[1])))\n return { from: from * 60, to: to * 60 }\n})\n\n/**\n * Where a timed event moved on the time axis starts: an event that sits\n * within one day stays inside the hours shown, so it is never written to a\n * time the axis can't show. One that runs over midnight moves freely.\n */\nfunction fitHours(span: EventSpan, start: number) {\n const { from, to } = axis.value\n const length = stampsOf(span).end - stampsOf(span).start\n if (span.from !== span.to || length > to - from) return start\n const day = Math.floor(start / DAY)\n return day * DAY + Math.min(Math.max(start - day * DAY, from), to - length)\n}\n\nconst roundTo = (value: number, by: number) => Math.round(value / by) * by\nconst floorTo = (value: number, by: number) => Math.floor(value / by) * by\n\n/** Work out what the drag would change, with the pointer where it is now. */\nfunction update(d: Drag) {\n const point = pointAt(d.surface, d.x, d.y)\n if (!point || d.kind === 'press') return\n const snap = Math.max(1, Math.round(props.snap))\n let draft: CalendarEvent | null = null\n let range: CalendarRange | null = null\n if (d.surface === 'time') {\n const now = toStamp(point.date, point.minutes)\n const origin = toStamp(d.origin.date, d.origin.minutes)\n if (d.kind === 'create') {\n const a = floorTo(origin, snap)\n const b = floorTo(now, snap)\n range = { start: formatStamp(Math.min(a, b)), end: formatStamp(Math.max(a, b) + snap) }\n } else {\n const { start } = stampsOf(d.span!)\n if (d.kind === 'move') {\n const next = fitHours(d.span!, roundTo(start + now - origin, snap))\n draft = moveEvent(d.event!, d.span!, { minutes: next - start })\n } else {\n draft = { ...d.event!, end: formatStamp(Math.max(start + snap, roundTo(now, snap))) }\n }\n }\n } else {\n const days = dayIndex(point.date) - dayIndex(d.origin.date)\n if (d.kind === 'create') {\n const [a, b] = [d.origin.date, point.date]\n range = a <= b ? { start: a, end: b } : { start: b, end: a }\n } else if (d.kind === 'move') {\n draft = moveEvent(d.event!, d.span!, { days })\n } else {\n draft = { ...d.event!, end: point.date < d.span!.from ? d.span!.from : point.date }\n }\n }\n if (draft) {\n if (d.draft && sameTime(d.draft, draft)) return\n d.draft = draft\n d.refusal = sameTime(draft, d.event!)\n ? null\n : refusalOf(d.kind, d.event, { start: draft.start, end: endOf(draft) })\n } else if (range) {\n if (d.range?.start === range.start && d.range.end === range.end) return\n d.range = range\n d.refusal = refusalOf('create', null, range)\n }\n triggerRef(drag)\n}\n\n/** The menu target under a pointer or a key press. */\nfunction targetOf(el: HTMLElement, x: number, y: number): CalendarMenuTarget | null {\n const chip = el.closest<HTMLElement>('[data-event-id]')\n const event = chip && byId(chip.dataset.eventId)\n if (event) return { kind: 'event', event }\n const cell = el.closest<HTMLElement>('[data-drop]')\n if (!cell) return null\n if (cell.dataset.drop === 'day') return { kind: 'day', date: cell.dataset.date! }\n const point = pointAt('time', x, y)\n if (!point) return null\n const minutes = Math.min(\n floorTo(point.minutes, Math.max(1, props.snap)),\n Number(cell.dataset.to) - props.snap,\n )\n return { kind: 'time', start: `${point.date} ${formatTime(Math.max(0, minutes))}` }\n}\n\nfunction onPointerDown(event: PointerEvent) {\n if (event.button !== 0 || drag.value) return\n const el = event.target as HTMLElement\n const touch = event.pointerType !== 'mouse'\n const chip = el.closest<HTMLElement>('[data-event-id]')\n const item = chip ? byId(chip.dataset.eventId) : undefined\n const cell = el.closest<HTMLElement>('[data-drop]')\n if (!cell) {\n // the agenda has nothing to drag: a finger resting on an event opens its menu\n const day = el.closest<HTMLElement>('[data-agenda-date]')?.dataset.agendaDate\n if (touch && item && day) {\n startDrag(event, {\n kind: 'press',\n surface: 'day',\n event: item,\n span: spans.value.get(item) ?? null,\n origin: { date: day, minutes: 0 },\n target: { kind: 'event', event: item },\n })\n }\n return\n }\n const surface = cell.dataset.drop as Surface\n let kind: Drag['kind']\n if (item) {\n const span = spans.value.get(item)\n if (!span) return\n if (!canEdit(item)) kind = 'press'\n else if (el.closest('[data-resize]')) kind = 'resize'\n else kind = 'move'\n } else {\n if (chip || el.closest('button, a, input')) return\n if (cell.matches('.is-disabled')) kind = 'press'\n else kind = props.editable ? 'create' : 'press'\n }\n // a mouse has its own menu button; only a finger needs the resting press\n if (kind === 'press' && !touch) return\n const origin = pointAt(surface, event.clientX, event.clientY)\n if (!origin) return\n startDrag(event, {\n kind,\n surface,\n event: item ?? null,\n span: item ? spans.value.get(item)! : null,\n origin,\n target: targetOf(el, event.clientX, event.clientY),\n })\n}\n\n/** Starts following a pointer that went down; a finger picks up after a short rest. */\nfunction startDrag(\n event: PointerEvent,\n start: Pick<Drag, 'kind' | 'surface' | 'event' | 'span' | 'origin' | 'target'>,\n) {\n const touch = event.pointerType !== 'mouse'\n if (touch) touchedAt = Date.now()\n drag.value = {\n ...start,\n pointerId: event.pointerId,\n touch,\n x0: event.clientX,\n y0: event.clientY,\n x: event.clientX,\n y: event.clientY,\n started: false,\n draft: null,\n range: null,\n refusal: null,\n }\n pointer.value = { x: event.clientX, y: event.clientY }\n hold = holdPointer(event, rootRef.value)\n window.addEventListener('pointermove', onDragMove)\n window.addEventListener('pointerup', onDragEnd)\n window.addEventListener('pointercancel', stopDrag)\n window.addEventListener('keydown', onDragKey, true)\n // switching away mid-drag drops it\n window.addEventListener('blur', stopDrag)\n document.addEventListener('visibilitychange', stopDrag)\n // a finger picks an event up after a short rest; moving sooner scrolls instead\n if (touch) {\n const d = drag.value\n pressTimer = setTimeout(() => {\n if (drag.value !== d) return\n begin(d)\n navigator.vibrate?.(8)\n }, LONG_PRESS)\n }\n}\n\nfunction begin(d: Drag) {\n d.started = true\n hold?.grab()\n if (d.kind !== 'press') {\n update(d)\n if (d.surface === 'time') frame = requestAnimationFrame(autoScroll)\n }\n triggerRef(drag)\n}\n\nfunction onDragMove(event: PointerEvent) {\n const d = drag.value\n if (!d || event.pointerId !== d.pointerId) return\n d.x = event.clientX\n d.y = event.clientY\n pointer.value = { x: d.x, y: d.y }\n const far = Math.hypot(d.x - d.x0, d.y - d.y0) > THRESHOLD[d.touch ? 'touch' : 'mouse']\n if (!d.started) {\n // a finger that moves before resting scrolls the page\n if (d.touch) return void (far && stopDrag())\n if (far) begin(d)\n return\n }\n if (d.kind === 'press') return\n update(d)\n}\n\nfunction onDragEnd(event: PointerEvent) {\n const d = drag.value\n if (!d || event.pointerId !== d.pointerId) return\n const still = Math.hypot(d.x - d.x0, d.y - d.y0) <= THRESHOLD.touch\n stopDrag()\n if (!d.started) return\n swallow = true\n setTimeout(() => (swallow = false))\n // a finger rested and let go without moving: the menu\n if (d.touch && still) {\n if (d.target && menuAllowed(d.target, event.clientX, event.clientY))\n showMenu(d.target, event.clientX, event.clientY)\n return\n }\n if (d.refusal) return announce(d.refusal)\n if (d.kind === 'create' && d.range) emit('create', { ...d.range })\n else if ((d.kind === 'move' || d.kind === 'resize') && d.draft && !sameTime(d.draft, d.event!))\n commit(d.kind, d.event!, d.draft)\n}\n\nfunction stopDrag() {\n clearTimeout(pressTimer)\n cancelAnimationFrame(frame)\n hold?.release()\n hold = null\n window.removeEventListener('pointermove', onDragMove)\n window.removeEventListener('pointerup', onDragEnd)\n window.removeEventListener('pointercancel', stopDrag)\n window.removeEventListener('keydown', onDragKey, true)\n window.removeEventListener('blur', stopDrag)\n if (typeof document !== 'undefined') document.removeEventListener('visibilitychange', stopDrag)\n drag.value = null\n}\n\nfunction onDragKey(event: KeyboardEvent) {\n if (event.key !== 'Escape') return\n event.preventDefault()\n event.stopPropagation()\n if (drag.value?.started) {\n swallow = true\n setTimeout(() => (swallow = false))\n }\n stopDrag()\n}\n\n/** Auto-scroll speed in px per frame, `gap` px from the edge. */\nconst speed = (gap: number) => (gap < EDGE ? Math.ceil(((EDGE - gap) / EDGE) * 12) : 0)\n\n/** Scrolls the time axis while a drag rests near its top or bottom. */\nfunction autoScroll() {\n const d = drag.value\n const el = rootRef.value?.querySelector<HTMLElement>(`.${ns.e('scroller')}`)\n if (!d?.started || !el) return\n const rect = el.getBoundingClientRect()\n const dy = speed(d.y - rect.top) ? -speed(d.y - rect.top) : speed(rect.bottom - d.y)\n if (dy) {\n const before = el.scrollTop\n el.scrollTop += dy\n if (el.scrollTop !== before) update(d)\n }\n frame = requestAnimationFrame(autoScroll)\n}\n\nfunction onClickCapture(event: MouseEvent) {\n if (!swallow) return\n event.stopPropagation()\n event.preventDefault()\n}\n\n/** Writes the new version of an event, then keeps the keyboard and the view on it. */\nfunction commit(kind: 'move' | 'resize', previous: CalendarEvent, next: CalendarEvent) {\n events.value = events.value.map((event) => (event === previous ? next : event))\n emit('change', { kind, event: next, previous })\n announce(t('calendarView.changed', { title: next.title, range: rangeText(next) }))\n}\n\nfunction remove(event: CalendarEvent) {\n events.value = events.value.filter((item) => item !== event)\n emit('change', { kind: 'remove', event })\n announce(t('calendarView.removed', { title: event.title }))\n}\n\n/** The element of an event on screen. */\nconst chipOf = (id: string | undefined) =>\n id ? rootRef.value?.querySelector<HTMLElement>(`[data-event-id=\"${CSS.escape(id)}\"]`) : null\n\n/**\n * Removes an event from the keyboard, then puts the keyboard on the next\n * event of the same day, or the one before, or else on the day itself.\n */\nasync function removeByKey(item: CalendarEvent, chip: HTMLElement) {\n const siblings = [...(chip.parentElement?.querySelectorAll<HTMLElement>('[data-event-id]') ?? [])]\n const index = siblings.indexOf(chip)\n // oxlint-disable-next-line unicorn/no-array-reverse -- reverses a fresh slice\n const near = [...siblings.slice(index + 1), ...siblings.slice(0, index).reverse()]\n .map((el) => el.dataset.eventId!)\n .find((id) => id !== item.id)\n const holder = chip.closest<HTMLElement>('[data-date], [data-agenda-date]')\n const day = holder?.dataset.date ?? holder?.dataset.agendaDate\n // in the agenda a day without events goes away: fall back to the next day's first event, or the one before's\n const listed = chip.closest<HTMLElement>('[data-agenda-date]')\n const neighbour = (listed?.nextElementSibling ?? listed?.previousElementSibling) as\n HTMLElement | null | undefined\n const fallback = neighbour?.querySelector<HTMLElement>('[data-event-id]')?.dataset.eventId\n remove(item)\n await nextTick()\n const next = chipOf(near) ?? chipOf(fallback)\n if (next) return next.focus()\n if (day) cursor.value = day\n void focusCursor()\n}\n\n/* the menu */\n\nconst menuRef = useTemplateRef<InstanceType<typeof DouContextMenu>>('menu')\nconst menuOpen = ref(false)\nconst menuItems = shallowRef<ContextMenuItem[]>([])\n\n/**\n * Sends `eventContextmenu` before an event's menu opens; `false` when the\n * app kept it closed. A resting finger or the menu key has no browser event\n * of its own, so it gets a stand-in.\n */\nfunction menuAllowed(target: CalendarMenuTarget, x: number, y: number, native?: MouseEvent) {\n if (target.kind !== 'event') return true\n const event =\n native ?? new MouseEvent('contextmenu', { cancelable: true, clientX: x, clientY: y })\n emit('eventContextmenu', target.event, event)\n return !event.defaultPrevented\n}\n\n/** Opens the menu for a target; `false` when it would be empty. */\nfunction showMenu(target: CalendarMenuTarget, x: number, y: number) {\n const items = [...(props.contextMenu?.(target) ?? [])]\n if (props.menu && target.kind === 'event' && canEdit(target.event)) {\n items.push({\n key: '\\0delete',\n label: t('calendarView.deleteEvent'),\n icon: TrashIcon,\n shortcut: 'Delete',\n tone: 'danger',\n divided: items.length > 0,\n run: () => remove(target.event),\n })\n }\n if (!items.length) return false\n menuItems.value = items\n menuRef.value?.open(x, y)\n return true\n}\n\nfunction onContextmenu(event: MouseEvent) {\n // a finger's long press opens the menu itself, when it lets go\n if (Date.now() - touchedAt < 1000) return event.preventDefault()\n const target = targetOf(event.target as HTMLElement, event.clientX, event.clientY)\n if (!target) return\n if (!menuAllowed(target, event.clientX, event.clientY, event)) return\n if (showMenu(target, event.clientX, event.clientY)) event.preventDefault()\n}\n\n/* keys on an event */\n\n/**\n * Puts the keyboard back on an event after a change; when the app stored it\n * under a new id, e.g. one occurrence of a series, on the day it went to.\n */\nasync function focusEvent(id: string) {\n await nextTick()\n const chip = chipOf(id)\n if (chip) chip.focus()\n else void focusCursor()\n}\n\n/**\n * On a focused event: the menu key opens its menu, `Delete` removes it,\n * `Alt` with the arrows moves it and `Alt` + `Shift` with the arrows moves\n * its end. Left and right go by a day; up and down by `snap` on the time\n * axis, or by a week in the month.\n */\nfunction onEventKeydown(event: KeyboardEvent) {\n const chip = (event.target as HTMLElement).closest<HTMLElement>('[data-event-id]')\n const item = chip && byId(chip.dataset.eventId)\n if (!item) return\n const done = () => {\n event.preventDefault()\n event.stopPropagation()\n }\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n const rect = chip.getBoundingClientRect()\n const target = { kind: 'event', event: item } as const\n if (!menuAllowed(target, rect.left, rect.bottom)) return done()\n if (showMenu(target, rect.left, rect.bottom)) done()\n return\n }\n if (!canEdit(item)) return\n if (event.key === 'Delete' || event.key === 'Backspace') {\n done()\n removeByKey(item, chip)\n return\n }\n const span = spans.value.get(item)\n if (!event.altKey || !span) return\n const timed = span.start !== null\n const onAxis = timed && view.value !== 'month' && view.value !== 'agenda'\n const snap = Math.max(1, Math.round(props.snap))\n const keys: Record<string, { days?: number; minutes?: number }> = {\n ArrowLeft: { days: -1 },\n ArrowRight: { days: 1 },\n ArrowUp: onAxis ? { minutes: -snap } : view.value === 'month' ? { days: -7 } : {},\n ArrowDown: onAxis ? { minutes: snap } : view.value === 'month' ? { days: 7 } : {},\n }\n const by = keys[event.key]\n if (!by || (!by.days && !by.minutes)) return\n done()\n let next: CalendarEvent\n let kind: 'move' | 'resize' = 'move'\n if (event.shiftKey) {\n kind = 'resize'\n if (timed) {\n const { start, end } = stampsOf(span)\n const delta = (by.days ?? 0) * DAY + (by.minutes ?? 0)\n let last = Math.max(start + snap, end + delta)\n // an event within one day on the time axis ends by the end of the hours shown\n if (onAxis && span.from === span.to) {\n const day = Math.floor(start / DAY)\n last = Math.min(last, day * DAY + axis.value.to)\n }\n next = { ...item, end: formatStamp(last) }\n } else {\n const last = addDays(span.to, by.days ?? 0)\n next = { ...item, end: last < span.from ? span.from : last }\n }\n } else if (onAxis) {\n const { start } = stampsOf(span)\n const at = fitHours(span, start + (by.days ?? 0) * DAY + (by.minutes ?? 0))\n next = moveEvent(item, span, { minutes: at - start })\n } else {\n next = moveEvent(item, span, by)\n }\n if (sameTime(next, item)) return\n const refusal = refusalOf(kind, item, { start: next.start, end: endOf(next) })\n if (refusal) return announce(refusal)\n commit(kind, item, next)\n const placed = spanOf(next)\n if (placed) cursor.value = kind === 'resize' ? placed.to : placed.from\n void focusEvent(next.id)\n}\n\nonBeforeUnmount(stopDrag)\n\n// Editing without anywhere to write the change: each drop springs back. Say so once while developing.\nconst instance = getCurrentInstance()\nwatch(\n () => props.editable,\n (editable) => {\n if (process.env.NODE_ENV === 'production' || !editable) return\n const bound = instance?.vnode.props ?? {}\n const has = (...names: string[]) => names.some((name) => name in bound)\n if (has('events') && !has('onUpdate:events', 'onChange')) {\n console.warn(\n '[dou-ui] CalendarView is editable but nothing receives the changes, so they spring back. Bind v-model:events, or listen to change.',\n )\n }\n },\n { immediate: true },\n)\n\ndefineExpose<CalendarViewExpose>({\n show: (date) => (cursor.value = date.length === 7 ? `${date}-01` : date),\n focus: () => void focusCursor(),\n})\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[\n ns.b(),\n ns.m(view),\n ns.is('editable', !!editable),\n ns.is('bordered', bordered),\n ns.is('dragging', !!drag?.started && drag.kind !== 'press'),\n drag?.started && drag.kind !== 'press' ? `is-dragging-${drag.kind}` : '',\n ]\"\n @pointerdown=\"onPointerDown\"\n @contextmenu=\"onContextmenu\"\n @click.capture=\"onClickCapture\"\n @keydown.capture=\"onEventKeydown\"\n >\n <div :class=\"ns.e('header')\">\n <h2 :class=\"ns.e('title')\" aria-live=\"polite\">{{ title }}</h2>\n <div :class=\"ns.e('nav')\">\n <slot name=\"extra\" />\n <DouSegmentedControl\n v-if=\"viewOptions.length > 1\"\n v-model=\"view\"\n :options=\"viewOptions\"\n size=\"sm\"\n />\n <button type=\"button\" :class=\"ns.e('today')\" @click=\"goToday\">\n {{ t('datePicker.today') }}\n </button>\n <button type=\"button\" :class=\"ns.e('step')\" :aria-label=\"stepLabels[0]\" @click=\"step(-1)\">\n <ChevronLeftIcon />\n </button>\n <button type=\"button\" :class=\"ns.e('step')\" :aria-label=\"stepLabels[1]\" @click=\"step(1)\">\n <ChevronRightIcon />\n </button>\n </div>\n </div>\n <div\n v-if=\"view === 'agenda'\"\n ref=\"grid\"\n role=\"list\"\n :class=\"ns.e('agenda')\"\n :aria-label=\"title\"\n >\n <p v-if=\"!agenda.length\" :class=\"ns.e('agenda-empty')\">{{ t('calendarView.empty') }}</p>\n <div\n v-for=\"day in agenda\"\n :key=\"day.date\"\n role=\"listitem\"\n :data-agenda-date=\"day.date\"\n :class=\"[ns.e('agenda-day'), ns.is('today', day.today), ns.is('selected', day.selected)]\"\n >\n <button\n type=\"button\"\n :class=\"ns.e('agenda-date')\"\n :data-date=\"day.date\"\n :disabled=\"day.disabled\"\n :aria-label=\"dayLabel(day)\"\n :aria-current=\"day.today ? 'date' : undefined\"\n :aria-pressed=\"day.selected\"\n @click=\"choose(day)\"\n >\n <span :class=\"ns.e('number')\">{{ day.day }}</span>\n <span :class=\"ns.e('agenda-weekday')\">{{ weekdayOf(day.date) }}</span>\n </button>\n <div :class=\"ns.e('agenda-events')\">\n <button\n v-for=\"event in day.events\"\n :key=\"event.id\"\n type=\"button\"\n :data-event-id=\"event.id\"\n :class=\"[\n ns.e('agenda-event'),\n `${ns.e('event')}--${event.tone ?? 'primary'}`,\n ns.is('locked', !!editable && !!event.locked),\n ]\"\n :aria-keyshortcuts=\"editable && !event.locked ? keyShortcuts : undefined\"\n @click=\"emit('eventClick', event)\"\n >\n <span :class=\"ns.e('agenda-time')\">{{ agendaTime(event, day.date) }}</span>\n <span :class=\"ns.e('agenda-title')\">\n <slot name=\"event\" :event=\"event\" :day=\"day\">{{ event.title }}</slot>\n </span>\n </button>\n </div>\n </div>\n </div>\n <TimeGrid\n v-else-if=\"view !== 'month'\"\n :days=\"weekDays\"\n :spans=\"spans\"\n :hours=\"hours\"\n :scroll-time=\"scrollTime\"\n :cursor=\"cursor\"\n :as-date=\"asDate\"\n :editable=\"!!editable\"\n :dragged=\"dragged\"\n :refused=\"refused\"\n :drawing=\"drawing\"\n :snap=\"snap\"\n @choose=\"choose\"\n @event-click=\"emit('eventClick', $event)\"\n @time-click=\"emit('timeClick', $event)\"\n @keydown=\"onTimeKeydown\"\n >\n <template v-if=\"slots.event\" #event=\"scope\">\n <slot name=\"event\" v-bind=\"scope\" />\n </template>\n </TimeGrid>\n <div\n v-else\n ref=\"grid\"\n role=\"grid\"\n :class=\"ns.e('grid')\"\n :aria-label=\"title\"\n @keydown=\"onKeydown\"\n >\n <div role=\"row\" :class=\"ns.e('weekdays')\">\n <div\n v-for=\"weekdayName in weekdays\"\n :key=\"weekdayName.long\"\n role=\"columnheader\"\n :class=\"ns.e('weekday')\"\n :aria-label=\"weekdayName.long\"\n >\n {{ weekdayName.short }}\n </div>\n </div>\n <div v-for=\"(week, row) in weeks\" :key=\"row\" role=\"row\" :class=\"ns.e('week')\">\n <div\n v-for=\"day in week\"\n :key=\"day.date\"\n role=\"gridcell\"\n data-drop=\"day\"\n :data-date=\"day.date\"\n :tabindex=\"day.date === cursor ? 0 : -1\"\n :aria-selected=\"day.selected\"\n :aria-disabled=\"day.disabled || undefined\"\n :aria-current=\"day.today ? 'date' : undefined\"\n :aria-label=\"dayLabel(day)\"\n :class=\"[\n ns.e('day'),\n ns.is('outside', day.outside),\n ns.is('today', day.today),\n ns.is('selected', day.selected),\n ns.is('disabled', day.disabled),\n ns.is('drawing', inDrawing(day.date)),\n ns.is('refused', inDrawing(day.date) && refused),\n ]\"\n @click=\"choose(day)\"\n >\n <span :class=\"ns.e('number')\">{{ day.day }}</span>\n <div :class=\"ns.e('content')\">\n <slot name=\"cell\" v-bind=\"day\">\n <button\n v-for=\"event in day.events.slice(0, maxEvents)\"\n :key=\"event.id\"\n type=\"button\"\n :data-event-id=\"event.id\"\n :tabindex=\"day.date === cursor ? 0 : -1\"\n :class=\"[\n ns.e('event'),\n `${ns.e('event')}--${event.tone ?? 'primary'}`,\n ns.is('start', isStart(event, day.date)),\n ns.is('continued', !isStart(event, day.date) && !weekStarts(day.date)),\n ns.is('end', isEnd(event, day.date)),\n ns.is('locked', !!editable && !!event.locked),\n ns.is('dragging', event === dragged),\n ns.is('refused', event === dragged && refused),\n ]\"\n :title=\"event.title\"\n :aria-keyshortcuts=\"editable && !event.locked ? keyShortcuts : undefined\"\n @click.stop=\"emit('eventClick', event)\"\n >\n <slot name=\"event\" :event=\"event\" :day=\"day\"\n ><span v-if=\"monthTime(event, day.date)\" :class=\"ns.e('event-clock')\">{{\n monthTime(event, day.date)\n }}</span\n >{{ event.title }}</slot\n ><span\n v-if=\"resizable(event, day.date)\"\n :class=\"[ns.e('resize'), `${ns.e('resize')}--x`]\"\n data-resize\n aria-hidden=\"true\"\n />\n </button>\n <span v-if=\"day.events.length > maxEvents\" :class=\"ns.e('more')\">\n {{ t('calendarView.more', { count: day.events.length - maxEvents }) }}\n </span>\n </slot>\n </div>\n </div>\n </div>\n </div>\n <span :class=\"ns.e('live')\" aria-live=\"polite\">{{ live }}</span>\n <div\n v-if=\"tip\"\n :class=\"[ns.e('tip'), ns.is('refused', refused)]\"\n :style=\"tipStyle\"\n aria-hidden=\"true\"\n >\n {{ tip }}\n </div>\n <!-- The calendar opens the menu itself; the empty anchor only gives it a place in the page. -->\n <DouContextMenu ref=\"menu\" v-model:open=\"menuOpen\" :items=\"menuItems\">\n <span :class=\"ns.e('menu-anchor')\" aria-hidden=\"true\" />\n </DouContextMenu>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cascader.js","names":["_sfc_main"],"sources":["../../../src/components/cascader/cascader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n CheckIcon,\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n CloseIcon,\n} from '@dou-ui/icons'\nimport { computed, nextTick, reactive, ref, useId, useTemplateRef, watch } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport { usePopup } from '../../composables/use-popup'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNarrowViewport } from '../../utils/media'\nimport { useNamespace } from '../../utils/namespace'\nimport { shouldVirtualize, visibleWindow } from '../../utils/virtual'\nimport { OnlyChild } from '../../utils/only-child'\nimport { useLocale } from '../config-provider/use-config'\nimport { useFormDisabled, useFormItem, useFormReadonly, useFormSize } from '../form/use-form-item'\nimport DouCheckbox from '../checkbox/checkbox.vue'\nimport { DouSpinner } from '../spinner'\nimport { DouTag } from '../tag'\nimport type {\n CascaderExpose,\n CascaderOption,\n CascaderProps,\n CascaderSlots,\n CascaderValue,\n} from './cascader'\nimport { useTeleport } from '../../utils/teleport'\n\ndefineOptions({ name: 'DouCascader', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<CascaderProps>(), {\n options: () => [],\n changeOnSelect: false,\n expandTrigger: 'click',\n filterable: false,\n separator: ' / ',\n showLastOnly: false,\n multiple: false,\n checkStrictly: false,\n disabled: false,\n invalid: false,\n clearable: false,\n placement: 'bottom-start',\n teleport: undefined,\n})\nconst teleportTarget = useTeleport(() => props.teleport)\nconst model = defineModel<CascaderValue[] | CascaderValue[][] | null>()\nconst emit = defineEmits<{\n change: [\n value: CascaderValue[] | CascaderValue[][] | null,\n path: CascaderOption[] | CascaderOption[][],\n ]\n}>()\nconst slots = defineSlots<CascaderSlots>()\n\nconst ns = useNamespace('cascader')\nconst { t } = useLocale()\nconst { formItem } = useFormItem()\nif (!props.filterable) formItem?.markGroup()\nconst size = useFormSize(() => props.size)\nconst disabled = useFormDisabled(() => props.disabled)\nconst readonly = useFormReadonly(() => props.readonly)\n// Read-only keeps the field focusable but never opens or changes it.\nconst locked = computed(() => disabled.value || readonly.value)\nconst invalid = computed(() => props.invalid || !!formItem?.invalid.value)\n\nconst id = `dou-cascader-${useId()}`\nconst listboxId = (level: number) => `${id}-list-${level}`\nconst keyOf = (path: CascaderValue[]) => path.map(String).join('\\u0000')\nconst optionId = (path: CascaderValue[]) =>\n `${id}-option-${path.map((value) => String(value).replace(/[^\\w-]/g, '_')).join('-')}`\nconst labelOf = (option: CascaderOption) => option.label ?? String(option.value)\n\n/* the tree, with the branches loaded so far */\n\nconst loaded = reactive(new Map<string, CascaderOption[]>())\nconst loading = reactive(new Set<string>())\n\nconst childrenOf = (option: CascaderOption, path: CascaderValue[]) =>\n option.children ?? loaded.get(keyOf(path))\nconst isLeaf = (option: CascaderOption, path: CascaderValue[]) => {\n const children = childrenOf(option, path)\n if (children) return children.length === 0\n return !props.load || !!option.leaf\n}\n\n/** The options along a path of values, as far as they are known. */\nfunction resolve(values: CascaderValue[]): CascaderOption[] {\n const found: CascaderOption[] = []\n let level: CascaderOption[] | undefined = props.options\n for (const [index, value] of values.entries()) {\n const option: CascaderOption | undefined = level?.find((item) => item.value === value)\n if (!option) break\n found.push(option)\n level = childrenOf(option, values.slice(0, index + 1))\n }\n return found\n}\n\nasync function ensure(option: CascaderOption, path: CascaderValue[]) {\n const key = keyOf(path)\n if (!props.load || option.children || option.leaf || loaded.has(key) || loading.has(key)) return\n loading.add(key)\n try {\n loaded.set(key, await props.load(option, resolve(path)))\n } catch {\n // leave it unloaded so opening it again retries\n } finally {\n loading.delete(key)\n }\n}\n\n/* the open columns: the chain of options under the pointer or cursor */\n\nconst expanded = ref<CascaderValue[]>([])\nconst columns = computed(() => {\n const list: { options: CascaderOption[]; path: CascaderValue[] }[] = [\n { options: props.options, path: [] },\n ]\n const chain = resolve(expanded.value)\n for (const [index, option] of chain.entries()) {\n const path = expanded.value.slice(0, index + 1)\n const children = childrenOf(option, path)\n if (children?.length || loading.has(keyOf(path))) list.push({ options: children ?? [], path })\n }\n return list\n})\n\n// On a phone the columns do not fit side by side: show the deepest one, with\n// the way back up above it.\nconst narrow = useNarrowViewport()\nconst backTrail = computed(() => resolve(expanded.value).map(labelOf).join(props.separator))\nfunction goUp() {\n if (!expanded.value.length) return\n active.value = expanded.value\n expanded.value = expanded.value.slice(0, -1)\n}\n\n// The highlighted option, as a path of values. Focus stays in the field.\nconst active = ref<CascaderValue[]>([])\n\n/** The single path, or nothing with `multiple`. */\nconst single = computed<CascaderValue[]>(() =>\n props.multiple || !model.value ? [] : (model.value as CascaderValue[]),\n)\nconst selectedPath = computed(() => resolve(single.value))\nconst isOnSelected = (path: CascaderValue[]) => {\n if (props.multiple) return checkState(path) === 'on'\n const value = single.value\n return (\n value.length > 0 &&\n path.length <= value.length &&\n path.every((item, index) => value[index] === item)\n )\n}\n\n/* checking, with `multiple` */\n\nconst checkedPaths = computed<CascaderValue[][]>(() =>\n props.multiple && Array.isArray(model.value)\n ? (model.value as unknown[]).filter((item): item is CascaderValue[] => Array.isArray(item))\n : [],\n)\nconst checkedKeys = computed(() => new Set(checkedPaths.value.map(keyOf)))\nconst isUnder = (path: CascaderValue[], parent: CascaderValue[]) =>\n path.length >= parent.length && parent.every((value, index) => path[index] === value)\n\n/** The paths a check of this option stands for: its leaves as far as they are known. */\nfunction leavesUnder(option: CascaderOption, path: CascaderValue[]): CascaderValue[][] {\n const children = childrenOf(option, path)\n if (isLeaf(option, path) || !children) return [path]\n return children\n .filter((child) => !child.disabled)\n .flatMap((child) => leavesUnder(child, [...path, child.value]))\n}\n\n// Every proper prefix of a checked path, so \"partly checked\" is one lookup.\nconst checkedPrefixes = computed(() => {\n const set = new Set<string>()\n for (const path of checkedPaths.value) {\n for (let length = 1; length < path.length; length++) set.add(keyOf(path.slice(0, length)))\n }\n return set\n})\n\n/** The check state of an option already resolved from `path`. */\nfunction stateOf(option: CascaderOption, path: CascaderValue[], key = keyOf(path)) {\n if (checkedKeys.value.has(key)) return 'on'\n if (props.checkStrictly) return 'off'\n if (!checkedPrefixes.value.has(key)) return 'off'\n const leaves = leavesUnder(option, path)\n const count = leaves.filter((leaf) => checkedKeys.value.has(keyOf(leaf))).length\n if (count && count === leaves.length && !isLeaf(option, path)) return 'on'\n return 'some'\n}\n\nfunction checkState(path: CascaderValue[]): 'on' | 'off' | 'some' {\n if (checkedKeys.value.has(keyOf(path))) return 'on'\n const chain = resolve(path)\n const option = chain.at(-1)\n if (!option || chain.length !== path.length) return 'off'\n return stateOf(option, path)\n}\n\nasync function toggleCheck(option: CascaderOption, path: CascaderValue[]) {\n if (option.disabled) return\n const on = checkState(path) === 'on'\n if (props.checkStrictly) {\n commit(\n on\n ? checkedPaths.value.filter((item) => keyOf(item) !== keyOf(path))\n : [...checkedPaths.value, path],\n )\n return\n }\n await ensure(option, path)\n const rest = checkedPaths.value.filter((item) => !isUnder(item, path))\n commit(on ? rest : [...rest, ...leavesUnder(option, path)])\n}\n\nfunction removePath(path: CascaderValue[]) {\n if (locked.value) return\n commit(checkedPaths.value.filter((item) => keyOf(item) !== keyOf(path)))\n}\n\n/* what each open column shows, worked out once per change rather than per render */\n\ninterface Row {\n index: number\n option: CascaderOption\n path: CascaderValue[]\n key: string\n id: string\n leaf: boolean\n state: 'on' | 'off' | 'some'\n selected: boolean\n}\nconst columnRows = computed(() =>\n columns.value.map((column) =>\n column.options.map((option, index): Row => {\n const path = [...column.path, option.value]\n const key = keyOf(path)\n const state = props.multiple ? stateOf(option, path, key) : 'off'\n return {\n index,\n option,\n path,\n key,\n id: optionId(path),\n leaf: isLeaf(option, path),\n state,\n selected: props.multiple ? state === 'on' : isOnSelected(path),\n }\n }),\n ),\n)\nconst activeKey = computed(() => keyOf(active.value))\n\n// Long columns render only the options in view, with spacers for the rest.\nconst ROW = 32\nconst VIEWPORT = 280\nconst INSET = 4\nconst columnScroll = ref<number[]>([])\nconst isVirtualColumn = (level: number) =>\n shouldVirtualize(undefined, columnRows.value[level]?.length ?? 0)\nfunction columnWindow(level: number) {\n const list = columnRows.value[level] ?? []\n if (!isVirtualColumn(level)) return { rows: list, before: 0, after: 0 }\n const scrollTop = Math.max(0, (columnScroll.value[level] ?? 0) - INSET)\n const { from, to } = visibleWindow(list.length, scrollTop, VIEWPORT, ROW)\n return { rows: list.slice(from, to), before: from * ROW, after: (list.length - to) * ROW }\n}\n// A virtual column sizes to the widest options rendered so far, so it\n// does not jitter as different options scroll into view.\nfunction onColumnScroll(level: number, event: Event) {\n const el = event.target as HTMLElement\n columnScroll.value[level] = el.scrollTop\n if (isVirtualColumn(level)) {\n void nextTick(() => {\n el.style.minWidth = `${Math.max(parseFloat(el.style.minWidth) || 0, el.offsetWidth)}px`\n })\n }\n}\nconst windows = computed(() => columnRows.value.map((_, level) => columnWindow(level)))\nwatch(\n () => columns.value.map((column) => keyOf(column.path)).join('\\u0001'),\n () => (columnScroll.value = columnScroll.value.slice(0, columns.value.length)),\n)\n\n/* search */\n\nconst query = ref('')\ninterface Match {\n path: CascaderOption[]\n values: CascaderValue[]\n label: string\n}\nconst matches = computed<Match[]>(() => {\n const text = query.value.trim().toLowerCase()\n if (!props.filterable || !text) return []\n const result: Match[] = []\n const walk = (options: CascaderOption[], trail: CascaderOption[], values: CascaderValue[]) => {\n for (const option of options) {\n if (option.disabled) continue\n const path = [...trail, option]\n const keys = [...values, option.value]\n const label = path.map(labelOf).join(props.separator)\n const leaf = isLeaf(option, keys)\n const pickable = leaf || props.changeOnSelect || (props.multiple && props.checkStrictly)\n if (pickable && label.toLowerCase().includes(text)) result.push({ path, values: keys, label })\n const children = childrenOf(option, keys)\n if (children) walk(children, path, keys)\n }\n }\n walk(props.options, [], [])\n return result\n})\nconst searching = computed(() => props.filterable && !!query.value.trim())\nconst activeMatch = ref(-1)\n// Only a different list of matches moves the highlight back to the top.\nwatch(\n () => matches.value.map((match) => match.values.map(String).join('\\u0001')).join('\\u0000'),\n () => (activeMatch.value = matches.value.length ? 0 : -1),\n)\n\n/* the popup */\n\nconst open = ref(false)\nconst popup = usePopup({\n open,\n trigger: 'manual',\n closeOnOutside: true,\n disabled: locked,\n placement: () => props.placement,\n offset: 4,\n})\nconst { triggerRef, panelRef, rendered, theme, placement, panelStyle } = popup\n\nfunction show() {\n if (locked.value || open.value) return\n open.value = true\n const chosen = props.multiple ? (checkedPaths.value[0] ?? []) : single.value\n expanded.value = chosen.slice(0, -1)\n active.value = chosen.length ? [...chosen] : firstEnabled([])\n}\nfunction hide() {\n open.value = false\n query.value = ''\n}\nwatch(open, (value) => {\n if (!value) query.value = ''\n})\n\nwatch(active, async (path) => {\n await nextTick()\n const level = path.length - 1\n if (level >= 0 && isVirtualColumn(level)) {\n // The option may not be rendered: scroll its column by its row instead.\n const column = panelRef.value?.querySelector<HTMLElement>(`#${CSS.escape(listboxId(level))}`)\n const at = columnRows.value[level]!.findIndex((row) => row.key === keyOf(path))\n if (!column || at < 0) return\n const top = at * ROW + INSET\n let target = column.scrollTop\n if (top < target) target = top - INSET\n else if (top + ROW > target + column.clientHeight)\n target = top + ROW - column.clientHeight + INSET\n column.scrollTop = Math.max(0, target)\n columnScroll.value[level] = column.scrollTop\n return\n }\n panelRef.value?.querySelector(`#${CSS.escape(optionId(path))}`)?.scrollIntoView?.({\n block: 'nearest',\n })\n})\n\nfunction optionsAt(parent: CascaderValue[]) {\n if (!parent.length) return props.options\n const chain = resolve(parent)\n const last = chain.at(-1)\n return chain.length === parent.length && last ? (childrenOf(last, parent) ?? []) : []\n}\nfunction firstEnabled(parent: CascaderValue[]) {\n const option = optionsAt(parent).find((item) => !item.disabled)\n return option ? [...parent, option.value] : []\n}\n\nfunction commit(values: CascaderValue[] | CascaderValue[][] | null) {\n model.value = values\n if (props.multiple) {\n const list = (values ?? []) as CascaderValue[][]\n emit('change', values, list.map(resolve))\n } else emit('change', values, values ? resolve(values as CascaderValue[]) : [])\n formItem?.trigger('change')\n}\n\n/** Open an option's column; `choose` also picks it when that is allowed. */\nasync function activate(option: CascaderOption, path: CascaderValue[], choose: boolean) {\n if (option.disabled) return\n active.value = path\n const parent = path.slice(0, -1)\n expanded.value = path\n await ensure(option, path)\n if (isLeaf(option, path)) {\n expanded.value = parent\n if (choose) {\n commit(path)\n hide()\n focus()\n }\n return\n }\n if (choose && props.changeOnSelect) commit(path)\n}\n\nfunction onOptionClick(option: CascaderOption, path: CascaderValue[]) {\n if (props.multiple && isLeaf(option, path)) {\n active.value = path\n expanded.value = path.slice(0, -1)\n void toggleCheck(option, path)\n } else void activate(option, path, !props.multiple)\n}\nfunction onOptionHover(option: CascaderOption, path: CascaderValue[]) {\n if (option.disabled) return\n active.value = path\n if (props.expandTrigger === 'hover' && !isLeaf(option, path)) void activate(option, path, false)\n}\n\nfunction chooseMatch(match: Match | undefined) {\n if (!match) return\n if (props.multiple) return void toggleCheck(match.path.at(-1)!, match.values)\n commit(match.values)\n hide()\n focus()\n}\n\nfunction clear() {\n commit(props.multiple ? [] : null)\n hide()\n focus()\n}\n\nconst fieldRef = useTemplateRef<HTMLElement>('field')\nconst inputRef = useTemplateRef<HTMLInputElement>('input')\nconst combobox = () => (props.filterable ? inputRef.value : fieldRef.value)\nfunction focus() {\n combobox()?.focus()\n}\n\nfunction moveWithin(step: 1 | -1 | 'first' | 'last') {\n const parent = active.value.slice(0, -1)\n const list = optionsAt(parent).filter((option) => !option.disabled)\n if (!list.length) return\n const at = list.findIndex((option) => option.value === active.value.at(-1))\n const index =\n step === 'first'\n ? 0\n : step === 'last'\n ? list.length - 1\n : (at + step + list.length) % list.length\n const path = [...parent, list[index]!.value]\n active.value = path\n // keep the next column in step with the cursor\n expanded.value = parent\n}\n\nasync function enter(choose: boolean) {\n const chain = resolve(active.value)\n const option = chain.at(-1)\n if (!option || chain.length !== active.value.length) return\n const path = [...active.value]\n await activate(option, path, choose)\n if (!isLeaf(option, path) && !choose) {\n const next = firstEnabled(path)\n if (next.length) active.value = next\n }\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (locked.value || isComposing(event)) return\n if (searching.value) {\n const count = matches.value.length\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault()\n if (count)\n activeMatch.value =\n (activeMatch.value + (event.key === 'ArrowDown' ? 1 : -1) + count) % count\n return\n case 'Enter':\n event.preventDefault()\n chooseMatch(matches.value[activeMatch.value])\n return\n case 'Tab':\n hide()\n }\n return\n }\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault()\n if (!open.value) show()\n else moveWithin(event.key === 'ArrowDown' ? 1 : -1)\n return\n case 'Home':\n case 'End':\n if (!open.value || props.filterable) return\n event.preventDefault()\n moveWithin(event.key === 'Home' ? 'first' : 'last')\n return\n case 'ArrowRight':\n if (!open.value) return\n event.preventDefault()\n void enter(false)\n return\n case 'ArrowLeft':\n if (!open.value || active.value.length < 2) return\n event.preventDefault()\n active.value = active.value.slice(0, -1)\n expanded.value = active.value.slice(0, -1)\n return\n case 'Enter':\n case ' ':\n if (event.key === ' ' && props.filterable) return\n event.preventDefault()\n if (!open.value) show()\n else if (props.multiple) {\n const option = resolve(active.value).at(-1)\n if (option && resolve(active.value).length === active.value.length)\n void toggleCheck(option, [...active.value])\n } else void enter(true)\n return\n case 'Backspace':\n if (props.multiple && props.filterable && !query.value && checkedPaths.value.length)\n removePath(checkedPaths.value.at(-1)!)\n return\n case 'Tab':\n hide()\n }\n}\n\nfunction onFieldMousedown(event: MouseEvent) {\n if (locked.value) return\n const target = event.target as HTMLElement\n if (target.closest('button')) return\n if (target !== inputRef.value) event.preventDefault()\n focus()\n if (open.value && target !== inputRef.value) hide()\n else show()\n}\n\nfunction onBlur(event: FocusEvent) {\n const next = event.relatedTarget\n if (next instanceof Node && (fieldRef.value?.contains(next) || panelRef.value?.contains(next))) {\n return\n }\n hide()\n formItem?.trigger('blur')\n}\n\nconst pathLabel = (path: CascaderOption[]) =>\n props.showLastOnly ? labelOf(path.at(-1)!) : path.map(labelOf).join(props.separator)\nconst tags = computed(() =>\n checkedPaths.value.map((values) => {\n const path = resolve(values)\n return {\n values,\n label:\n path.length === values.length ? pathLabel(path) : values.map(String).join(props.separator),\n }\n }),\n)\nconst shownTags = computed(() =>\n props.maxTagCount === undefined\n ? tags.value\n : tags.value.slice(0, Math.max(0, props.maxTagCount)),\n)\nconst hiddenTags = computed(() => tags.value.slice(shownTags.value.length))\n\nconst display = computed(() => {\n const path = selectedPath.value\n if (!path.length) return ''\n return props.showLastOnly ? labelOf(path.at(-1)!) : path.map(labelOf).join(props.separator)\n})\nconst placeholderText = computed(() => props.placeholder ?? t('cascader.placeholder'))\n\nconst activeDescendant = computed(() => {\n if (!open.value) return undefined\n if (searching.value)\n return activeMatch.value >= 0 ? `${id}-match-${activeMatch.value}` : undefined\n return active.value.length ? optionId(active.value) : undefined\n})\n\nconst comboboxAttrs = computed<HTMLAttributes>(() => ({\n role: 'combobox',\n 'aria-haspopup': 'listbox',\n 'aria-expanded': open.value,\n 'aria-controls': rendered.value\n ? searching.value\n ? `${id}-matches`\n : listboxId(Math.max(0, active.value.length - 1))\n : undefined,\n 'aria-activedescendant': activeDescendant.value,\n 'aria-invalid': invalid.value || undefined,\n 'aria-required': formItem?.required.value || undefined,\n 'aria-describedby': formItem?.describedBy.value,\n}))\n\nconst showClear = computed(() => props.clearable && !locked.value && !!model.value?.length)\nconst inputPlaceholder = computed(() => {\n if (props.multiple) return tags.value.length ? '' : placeholderText.value\n return display.value || placeholderText.value\n})\n\ndefineExpose<CascaderExpose>({ focus, blur: () => combobox()?.blur() })\n</script>\n\n<template>\n <OnlyChild ref=\"triggerRef\">\n <div\n ref=\"field\"\n v-bind=\"{ ...$attrs, ...(filterable ? {} : comboboxAttrs) }\"\n :class=\"[\n ns.b(),\n 'dou-picker',\n `dou-picker--${size}`,\n ns.is('open', open),\n ns.is('multiple', multiple),\n ns.is('has-tags', tags.length > 0),\n ns.is('disabled', disabled),\n ns.is('readonly', readonly),\n ns.is('invalid', invalid),\n ]\"\n :id=\"filterable ? undefined : formItem?.inputId\"\n :aria-labelledby=\"filterable ? undefined : formItem?.labelId\"\n :tabindex=\"filterable || disabled ? undefined : 0\"\n @mousedown=\"onFieldMousedown\"\n @keydown=\"filterable ? undefined : onKeydown($event)\"\n @focusout=\"onBlur\"\n >\n <div v-if=\"multiple\" :class=\"ns.e('tags')\">\n <DouTag\n v-for=\"tag in shownTags\"\n :key=\"keyOf(tag.values)\"\n :size=\"size\"\n :closable=\"!locked\"\n @close=\"removePath(tag.values)\"\n >\n {{ tag.label }}\n </DouTag>\n <DouTag\n v-if=\"hiddenTags.length\"\n :size=\"size\"\n :class=\"ns.e('tag-more')\"\n :title=\"hiddenTags.map((tag) => tag.label).join('、')\"\n >\n +{{ hiddenTags.length }}\n </DouTag>\n <input\n v-if=\"filterable\"\n ref=\"input\"\n v-model=\"query\"\n v-bind=\"comboboxAttrs\"\n :id=\"formItem?.inputId\"\n class=\"dou-picker__input\"\n :class=\"ns.e('input')\"\n type=\"text\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n :placeholder=\"inputPlaceholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n @input=\"show\"\n @keydown=\"onKeydown\"\n />\n <span v-else-if=\"!tags.length\" class=\"dou-picker__placeholder\">{{ placeholderText }}</span>\n </div>\n <input\n v-else-if=\"filterable\"\n ref=\"input\"\n v-model=\"query\"\n v-bind=\"comboboxAttrs\"\n :id=\"formItem?.inputId\"\n class=\"dou-picker__input\"\n type=\"text\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n :placeholder=\"display || placeholderText\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :class=\"ns.is('has-value', !!display)\"\n @input=\"show\"\n @keydown=\"onKeydown\"\n />\n <span v-else-if=\"display\" class=\"dou-picker__value\">{{ display }}</span>\n <span v-else class=\"dou-picker__placeholder\">{{ placeholderText }}</span>\n <button\n v-if=\"showClear\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"dou-picker__clear\"\n :aria-label=\"t('cascader.clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <CloseIcon />\n </button>\n <ChevronDownIcon class=\"dou-picker__arrow\" />\n </div>\n </OnlyChild>\n <Teleport v-if=\"rendered\" :to=\"teleportTarget.to\" :disabled=\"teleportTarget.disabled\">\n <Transition appear name=\"dou-floating\">\n <div\n v-show=\"open\"\n ref=\"panelRef\"\n :class=\"[ns.e('panel'), 'dou-picker-panel', 'dou-floating']\"\n :style=\"panelStyle\"\n :data-placement=\"placement\"\n :data-dou-theme=\"theme\"\n @mousedown.prevent\n >\n <ul\n v-if=\"searching\"\n :id=\"`${id}-matches`\"\n role=\"listbox\"\n :class=\"[ns.e('column'), ns.e('matches')]\"\n >\n <li\n v-for=\"(match, index) in matches\"\n :id=\"`${id}-match-${index}`\"\n :key=\"keyOf(match.values)\"\n role=\"option\"\n :aria-selected=\"\n multiple ? stateOf(match.path.at(-1)!, match.values) === 'on' : index === activeMatch\n \"\n :class=\"[ns.e('option'), ns.is('active', index === activeMatch)]\"\n @click=\"chooseMatch(match)\"\n @mousemove=\"activeMatch = index\"\n >\n <DouCheckbox\n v-if=\"multiple\"\n :model-value=\"stateOf(match.path.at(-1)!, match.values) === 'on'\"\n size=\"sm\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :class=\"ns.e('checkbox')\"\n @click.stop\n @update:model-value=\"chooseMatch(match)\"\n />\n <span :class=\"ns.e('label')\">{{ match.label }}</span>\n </li>\n <li v-if=\"!matches.length\" role=\"presentation\" :class=\"ns.e('empty')\">\n <slot name=\"empty\">{{ t('cascader.empty') }}</slot>\n </li>\n </ul>\n <div v-else :class=\"[ns.e('columns'), ns.is('narrow', narrow)]\">\n <button\n v-if=\"narrow && columns.length > 1\"\n type=\"button\"\n tabindex=\"-1\"\n :class=\"ns.e('back')\"\n :aria-label=\"t('cascader.back')\"\n @click=\"goUp\"\n >\n <ChevronLeftIcon :class=\"ns.e('back-icon')\" />\n <span :class=\"ns.e('trail')\">{{ backTrail }}</span>\n </button>\n <ul\n v-for=\"(column, level) in columns\"\n v-show=\"!narrow || level === columns.length - 1\"\n :id=\"listboxId(level)\"\n :key=\"keyOf(column.path)\"\n role=\"listbox\"\n :class=\"ns.e('column')\"\n :aria-multiselectable=\"multiple || undefined\"\n :aria-busy=\"loading.has(keyOf(column.path)) || undefined\"\n @scroll=\"onColumnScroll(level, $event)\"\n >\n <li\n v-if=\"windows[level]!.before\"\n role=\"presentation\"\n :style=\"{ height: `${windows[level]!.before}px` }\"\n />\n <li\n v-for=\"{ index, option, path, key, id: rowId, leaf, state, selected } in windows[\n level\n ]!.rows\"\n :id=\"rowId\"\n :key=\"String(option.value)\"\n role=\"option\"\n :aria-selected=\"selected\"\n :aria-setsize=\"\n windows[level]!.rows.length < columnRows[level]!.length\n ? columnRows[level]!.length\n : undefined\n \"\n :aria-posinset=\"\n windows[level]!.rows.length < columnRows[level]!.length ? index + 1 : undefined\n \"\n :aria-disabled=\"option.disabled || undefined\"\n :aria-expanded=\"leaf ? undefined : expanded[level] === option.value\"\n :class=\"[\n ns.e('option'),\n ns.is('active', activeKey === key),\n ns.is('expanded', expanded[level] === option.value),\n ns.is('selected', selected),\n ns.is('disabled', !!option.disabled),\n ]\"\n @click=\"onOptionClick(option, path)\"\n @mouseenter=\"onOptionHover(option, path)\"\n >\n <DouCheckbox\n v-if=\"multiple\"\n :model-value=\"state === 'on'\"\n :indeterminate=\"state === 'some'\"\n :disabled=\"!!option.disabled\"\n size=\"sm\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :class=\"ns.e('checkbox')\"\n @click.stop\n @update:model-value=\"toggleCheck(option, path)\"\n />\n <span :class=\"ns.e('label')\">\n <slot name=\"option\" :option=\"option\" :level=\"level\">{{ labelOf(option) }}</slot>\n </span>\n <DouSpinner v-if=\"loading.has(key)\" size=\"sm\" :class=\"ns.e('suffix')\" />\n <ChevronRightIcon v-else-if=\"!leaf\" :class=\"ns.e('suffix')\" />\n <CheckIcon\n v-else-if=\"!multiple && selected\"\n :class=\"[ns.e('suffix'), ns.e('check')]\"\n />\n </li>\n <li\n v-if=\"windows[level]!.after\"\n role=\"presentation\"\n :style=\"{ height: `${windows[level]!.after}px` }\"\n />\n <li\n v-if=\"!column.options.length && !loading.has(keyOf(column.path))\"\n role=\"presentation\"\n :class=\"ns.e('empty')\"\n >\n <slot name=\"empty\">{{ t('cascader.empty') }}</slot>\n </li>\n </ul>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"cascader.js","names":["_sfc_main"],"sources":["../../../src/components/cascader/cascader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n CheckIcon,\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n CloseIcon,\n} from '@dou-ui/icons'\nimport { computed, nextTick, reactive, ref, useId, useTemplateRef, watch } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport { usePopup } from '../../composables/use-popup'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNarrowViewport } from '../../utils/media'\nimport { useNamespace } from '../../utils/namespace'\nimport { shouldVirtualize, visibleWindow } from '../../utils/virtual'\nimport { OnlyChild } from '../../utils/only-child'\nimport { useLocale } from '../config-provider/use-config'\nimport { useFormDisabled, useFormItem, useFormReadonly, useFormSize } from '../form/use-form-item'\nimport { DouCheckbox } from '../checkbox'\nimport { DouSpinner } from '../spinner'\nimport { DouTag } from '../tag'\nimport type {\n CascaderExpose,\n CascaderOption,\n CascaderProps,\n CascaderSlots,\n CascaderValue,\n} from './cascader'\nimport { useTeleport } from '../../utils/teleport'\n\ndefineOptions({ name: 'DouCascader', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<CascaderProps>(), {\n options: () => [],\n changeOnSelect: false,\n expandTrigger: 'click',\n filterable: false,\n separator: ' / ',\n showLastOnly: false,\n multiple: false,\n checkStrictly: false,\n disabled: false,\n invalid: false,\n clearable: false,\n placement: 'bottom-start',\n teleport: undefined,\n})\nconst teleportTarget = useTeleport(() => props.teleport)\nconst model = defineModel<CascaderValue[] | CascaderValue[][] | null>()\nconst emit = defineEmits<{\n change: [\n value: CascaderValue[] | CascaderValue[][] | null,\n path: CascaderOption[] | CascaderOption[][],\n ]\n}>()\nconst slots = defineSlots<CascaderSlots>()\n\nconst ns = useNamespace('cascader')\nconst { t } = useLocale()\nconst { formItem } = useFormItem()\nif (!props.filterable) formItem?.markGroup()\nconst size = useFormSize(() => props.size)\nconst disabled = useFormDisabled(() => props.disabled)\nconst readonly = useFormReadonly(() => props.readonly)\n// Read-only keeps the field focusable but never opens or changes it.\nconst locked = computed(() => disabled.value || readonly.value)\nconst invalid = computed(() => props.invalid || !!formItem?.invalid.value)\n\nconst id = `dou-cascader-${useId()}`\nconst listboxId = (level: number) => `${id}-list-${level}`\nconst keyOf = (path: CascaderValue[]) => path.map(String).join('\\u0000')\nconst optionId = (path: CascaderValue[]) =>\n `${id}-option-${path.map((value) => String(value).replace(/[^\\w-]/g, '_')).join('-')}`\nconst labelOf = (option: CascaderOption) => option.label ?? String(option.value)\n\n/* the tree, with the branches loaded so far */\n\nconst loaded = reactive(new Map<string, CascaderOption[]>())\nconst loading = reactive(new Set<string>())\n\nconst childrenOf = (option: CascaderOption, path: CascaderValue[]) =>\n option.children ?? loaded.get(keyOf(path))\nconst isLeaf = (option: CascaderOption, path: CascaderValue[]) => {\n const children = childrenOf(option, path)\n if (children) return children.length === 0\n return !props.load || !!option.leaf\n}\n\n/** The options along a path of values, as far as they are known. */\nfunction resolve(values: CascaderValue[]): CascaderOption[] {\n const found: CascaderOption[] = []\n let level: CascaderOption[] | undefined = props.options\n for (const [index, value] of values.entries()) {\n const option: CascaderOption | undefined = level?.find((item) => item.value === value)\n if (!option) break\n found.push(option)\n level = childrenOf(option, values.slice(0, index + 1))\n }\n return found\n}\n\nasync function ensure(option: CascaderOption, path: CascaderValue[]) {\n const key = keyOf(path)\n if (!props.load || option.children || option.leaf || loaded.has(key) || loading.has(key)) return\n loading.add(key)\n try {\n loaded.set(key, await props.load(option, resolve(path)))\n } catch {\n // leave it unloaded so opening it again retries\n } finally {\n loading.delete(key)\n }\n}\n\n/* the open columns: the chain of options under the pointer or cursor */\n\nconst expanded = ref<CascaderValue[]>([])\nconst columns = computed(() => {\n const list: { options: CascaderOption[]; path: CascaderValue[] }[] = [\n { options: props.options, path: [] },\n ]\n const chain = resolve(expanded.value)\n for (const [index, option] of chain.entries()) {\n const path = expanded.value.slice(0, index + 1)\n const children = childrenOf(option, path)\n if (children?.length || loading.has(keyOf(path))) list.push({ options: children ?? [], path })\n }\n return list\n})\n\n// On a phone the columns do not fit side by side: show the deepest one, with\n// the way back up above it.\nconst narrow = useNarrowViewport()\nconst backTrail = computed(() => resolve(expanded.value).map(labelOf).join(props.separator))\nfunction goUp() {\n if (!expanded.value.length) return\n active.value = expanded.value\n expanded.value = expanded.value.slice(0, -1)\n}\n\n// The highlighted option, as a path of values. Focus stays in the field.\nconst active = ref<CascaderValue[]>([])\n\n/** The single path, or nothing with `multiple`. */\nconst single = computed<CascaderValue[]>(() =>\n props.multiple || !model.value ? [] : (model.value as CascaderValue[]),\n)\nconst selectedPath = computed(() => resolve(single.value))\nconst isOnSelected = (path: CascaderValue[]) => {\n if (props.multiple) return checkState(path) === 'on'\n const value = single.value\n return (\n value.length > 0 &&\n path.length <= value.length &&\n path.every((item, index) => value[index] === item)\n )\n}\n\n/* checking, with `multiple` */\n\nconst checkedPaths = computed<CascaderValue[][]>(() =>\n props.multiple && Array.isArray(model.value)\n ? (model.value as unknown[]).filter((item): item is CascaderValue[] => Array.isArray(item))\n : [],\n)\nconst checkedKeys = computed(() => new Set(checkedPaths.value.map(keyOf)))\nconst isUnder = (path: CascaderValue[], parent: CascaderValue[]) =>\n path.length >= parent.length && parent.every((value, index) => path[index] === value)\n\n/** The paths a check of this option stands for: its leaves as far as they are known. */\nfunction leavesUnder(option: CascaderOption, path: CascaderValue[]): CascaderValue[][] {\n const children = childrenOf(option, path)\n if (isLeaf(option, path) || !children) return [path]\n return children\n .filter((child) => !child.disabled)\n .flatMap((child) => leavesUnder(child, [...path, child.value]))\n}\n\n// Every proper prefix of a checked path, so \"partly checked\" is one lookup.\nconst checkedPrefixes = computed(() => {\n const set = new Set<string>()\n for (const path of checkedPaths.value) {\n for (let length = 1; length < path.length; length++) set.add(keyOf(path.slice(0, length)))\n }\n return set\n})\n\n/** The check state of an option already resolved from `path`. */\nfunction stateOf(option: CascaderOption, path: CascaderValue[], key = keyOf(path)) {\n if (checkedKeys.value.has(key)) return 'on'\n if (props.checkStrictly) return 'off'\n if (!checkedPrefixes.value.has(key)) return 'off'\n const leaves = leavesUnder(option, path)\n const count = leaves.filter((leaf) => checkedKeys.value.has(keyOf(leaf))).length\n if (count && count === leaves.length && !isLeaf(option, path)) return 'on'\n return 'some'\n}\n\nfunction checkState(path: CascaderValue[]): 'on' | 'off' | 'some' {\n if (checkedKeys.value.has(keyOf(path))) return 'on'\n const chain = resolve(path)\n const option = chain.at(-1)\n if (!option || chain.length !== path.length) return 'off'\n return stateOf(option, path)\n}\n\nasync function toggleCheck(option: CascaderOption, path: CascaderValue[]) {\n if (option.disabled) return\n const on = checkState(path) === 'on'\n if (props.checkStrictly) {\n commit(\n on\n ? checkedPaths.value.filter((item) => keyOf(item) !== keyOf(path))\n : [...checkedPaths.value, path],\n )\n return\n }\n await ensure(option, path)\n const rest = checkedPaths.value.filter((item) => !isUnder(item, path))\n commit(on ? rest : [...rest, ...leavesUnder(option, path)])\n}\n\nfunction removePath(path: CascaderValue[]) {\n if (locked.value) return\n commit(checkedPaths.value.filter((item) => keyOf(item) !== keyOf(path)))\n}\n\n/* what each open column shows, worked out once per change rather than per render */\n\ninterface Row {\n index: number\n option: CascaderOption\n path: CascaderValue[]\n key: string\n id: string\n leaf: boolean\n state: 'on' | 'off' | 'some'\n selected: boolean\n}\nconst columnRows = computed(() =>\n columns.value.map((column) =>\n column.options.map((option, index): Row => {\n const path = [...column.path, option.value]\n const key = keyOf(path)\n const state = props.multiple ? stateOf(option, path, key) : 'off'\n return {\n index,\n option,\n path,\n key,\n id: optionId(path),\n leaf: isLeaf(option, path),\n state,\n selected: props.multiple ? state === 'on' : isOnSelected(path),\n }\n }),\n ),\n)\nconst activeKey = computed(() => keyOf(active.value))\n\n// Long columns render only the options in view, with spacers for the rest.\nconst ROW = 32\nconst VIEWPORT = 280\nconst INSET = 4\nconst columnScroll = ref<number[]>([])\nconst isVirtualColumn = (level: number) =>\n shouldVirtualize(undefined, columnRows.value[level]?.length ?? 0)\nfunction columnWindow(level: number) {\n const list = columnRows.value[level] ?? []\n if (!isVirtualColumn(level)) return { rows: list, before: 0, after: 0 }\n const scrollTop = Math.max(0, (columnScroll.value[level] ?? 0) - INSET)\n const { from, to } = visibleWindow(list.length, scrollTop, VIEWPORT, ROW)\n return { rows: list.slice(from, to), before: from * ROW, after: (list.length - to) * ROW }\n}\n// A virtual column sizes to the widest options rendered so far, so it\n// does not jitter as different options scroll into view.\nfunction onColumnScroll(level: number, event: Event) {\n const el = event.target as HTMLElement\n columnScroll.value[level] = el.scrollTop\n if (isVirtualColumn(level)) {\n void nextTick(() => {\n el.style.minWidth = `${Math.max(parseFloat(el.style.minWidth) || 0, el.offsetWidth)}px`\n })\n }\n}\nconst windows = computed(() => columnRows.value.map((_, level) => columnWindow(level)))\nwatch(\n () => columns.value.map((column) => keyOf(column.path)).join('\\u0001'),\n () => (columnScroll.value = columnScroll.value.slice(0, columns.value.length)),\n)\n\n/* search */\n\nconst query = ref('')\ninterface Match {\n path: CascaderOption[]\n values: CascaderValue[]\n label: string\n}\nconst matches = computed<Match[]>(() => {\n const text = query.value.trim().toLowerCase()\n if (!props.filterable || !text) return []\n const result: Match[] = []\n const walk = (options: CascaderOption[], trail: CascaderOption[], values: CascaderValue[]) => {\n for (const option of options) {\n if (option.disabled) continue\n const path = [...trail, option]\n const keys = [...values, option.value]\n const label = path.map(labelOf).join(props.separator)\n const leaf = isLeaf(option, keys)\n const pickable = leaf || props.changeOnSelect || (props.multiple && props.checkStrictly)\n if (pickable && label.toLowerCase().includes(text)) result.push({ path, values: keys, label })\n const children = childrenOf(option, keys)\n if (children) walk(children, path, keys)\n }\n }\n walk(props.options, [], [])\n return result\n})\nconst searching = computed(() => props.filterable && !!query.value.trim())\nconst activeMatch = ref(-1)\n// Only a different list of matches moves the highlight back to the top.\nwatch(\n () => matches.value.map((match) => match.values.map(String).join('\\u0001')).join('\\u0000'),\n () => (activeMatch.value = matches.value.length ? 0 : -1),\n)\n\n/* the popup */\n\nconst open = ref(false)\nconst popup = usePopup({\n open,\n trigger: 'manual',\n closeOnOutside: true,\n disabled: locked,\n placement: () => props.placement,\n offset: 4,\n})\nconst { triggerRef, panelRef, rendered, theme, placement, panelStyle } = popup\n\nfunction show() {\n if (locked.value || open.value) return\n open.value = true\n const chosen = props.multiple ? (checkedPaths.value[0] ?? []) : single.value\n expanded.value = chosen.slice(0, -1)\n active.value = chosen.length ? [...chosen] : firstEnabled([])\n}\nfunction hide() {\n open.value = false\n query.value = ''\n}\nwatch(open, (value) => {\n if (!value) query.value = ''\n})\n\nwatch(active, async (path) => {\n await nextTick()\n const level = path.length - 1\n if (level >= 0 && isVirtualColumn(level)) {\n // The option may not be rendered: scroll its column by its row instead.\n const column = panelRef.value?.querySelector<HTMLElement>(`#${CSS.escape(listboxId(level))}`)\n const at = columnRows.value[level]!.findIndex((row) => row.key === keyOf(path))\n if (!column || at < 0) return\n const top = at * ROW + INSET\n let target = column.scrollTop\n if (top < target) target = top - INSET\n else if (top + ROW > target + column.clientHeight)\n target = top + ROW - column.clientHeight + INSET\n column.scrollTop = Math.max(0, target)\n columnScroll.value[level] = column.scrollTop\n return\n }\n panelRef.value?.querySelector(`#${CSS.escape(optionId(path))}`)?.scrollIntoView?.({\n block: 'nearest',\n })\n})\n\nfunction optionsAt(parent: CascaderValue[]) {\n if (!parent.length) return props.options\n const chain = resolve(parent)\n const last = chain.at(-1)\n return chain.length === parent.length && last ? (childrenOf(last, parent) ?? []) : []\n}\nfunction firstEnabled(parent: CascaderValue[]) {\n const option = optionsAt(parent).find((item) => !item.disabled)\n return option ? [...parent, option.value] : []\n}\n\nfunction commit(values: CascaderValue[] | CascaderValue[][] | null) {\n model.value = values\n if (props.multiple) {\n const list = (values ?? []) as CascaderValue[][]\n emit('change', values, list.map(resolve))\n } else emit('change', values, values ? resolve(values as CascaderValue[]) : [])\n formItem?.trigger('change')\n}\n\n/** Open an option's column; `choose` also picks it when that is allowed. */\nasync function activate(option: CascaderOption, path: CascaderValue[], choose: boolean) {\n if (option.disabled) return\n active.value = path\n const parent = path.slice(0, -1)\n expanded.value = path\n await ensure(option, path)\n if (isLeaf(option, path)) {\n expanded.value = parent\n if (choose) {\n commit(path)\n hide()\n focus()\n }\n return\n }\n if (choose && props.changeOnSelect) commit(path)\n}\n\nfunction onOptionClick(option: CascaderOption, path: CascaderValue[]) {\n if (props.multiple && isLeaf(option, path)) {\n active.value = path\n expanded.value = path.slice(0, -1)\n void toggleCheck(option, path)\n } else void activate(option, path, !props.multiple)\n}\nfunction onOptionHover(option: CascaderOption, path: CascaderValue[]) {\n if (option.disabled) return\n active.value = path\n if (props.expandTrigger === 'hover' && !isLeaf(option, path)) void activate(option, path, false)\n}\n\nfunction chooseMatch(match: Match | undefined) {\n if (!match) return\n if (props.multiple) return void toggleCheck(match.path.at(-1)!, match.values)\n commit(match.values)\n hide()\n focus()\n}\n\nfunction clear() {\n commit(props.multiple ? [] : null)\n hide()\n focus()\n}\n\nconst fieldRef = useTemplateRef<HTMLElement>('field')\nconst inputRef = useTemplateRef<HTMLInputElement>('input')\nconst combobox = () => (props.filterable ? inputRef.value : fieldRef.value)\nfunction focus() {\n combobox()?.focus()\n}\n\nfunction moveWithin(step: 1 | -1 | 'first' | 'last') {\n const parent = active.value.slice(0, -1)\n const list = optionsAt(parent).filter((option) => !option.disabled)\n if (!list.length) return\n const at = list.findIndex((option) => option.value === active.value.at(-1))\n const index =\n step === 'first'\n ? 0\n : step === 'last'\n ? list.length - 1\n : (at + step + list.length) % list.length\n const path = [...parent, list[index]!.value]\n active.value = path\n // keep the next column in step with the cursor\n expanded.value = parent\n}\n\nasync function enter(choose: boolean) {\n const chain = resolve(active.value)\n const option = chain.at(-1)\n if (!option || chain.length !== active.value.length) return\n const path = [...active.value]\n await activate(option, path, choose)\n if (!isLeaf(option, path) && !choose) {\n const next = firstEnabled(path)\n if (next.length) active.value = next\n }\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (locked.value || isComposing(event)) return\n if (searching.value) {\n const count = matches.value.length\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault()\n if (count)\n activeMatch.value =\n (activeMatch.value + (event.key === 'ArrowDown' ? 1 : -1) + count) % count\n return\n case 'Enter':\n event.preventDefault()\n chooseMatch(matches.value[activeMatch.value])\n return\n case 'Tab':\n hide()\n }\n return\n }\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault()\n if (!open.value) show()\n else moveWithin(event.key === 'ArrowDown' ? 1 : -1)\n return\n case 'Home':\n case 'End':\n if (!open.value || props.filterable) return\n event.preventDefault()\n moveWithin(event.key === 'Home' ? 'first' : 'last')\n return\n case 'ArrowRight':\n if (!open.value) return\n event.preventDefault()\n void enter(false)\n return\n case 'ArrowLeft':\n if (!open.value || active.value.length < 2) return\n event.preventDefault()\n active.value = active.value.slice(0, -1)\n expanded.value = active.value.slice(0, -1)\n return\n case 'Enter':\n case ' ':\n if (event.key === ' ' && props.filterable) return\n event.preventDefault()\n if (!open.value) show()\n else if (props.multiple) {\n const option = resolve(active.value).at(-1)\n if (option && resolve(active.value).length === active.value.length)\n void toggleCheck(option, [...active.value])\n } else void enter(true)\n return\n case 'Backspace':\n if (props.multiple && props.filterable && !query.value && checkedPaths.value.length)\n removePath(checkedPaths.value.at(-1)!)\n return\n case 'Tab':\n hide()\n }\n}\n\nfunction onFieldMousedown(event: MouseEvent) {\n if (locked.value) return\n const target = event.target as HTMLElement\n if (target.closest('button')) return\n if (target !== inputRef.value) event.preventDefault()\n focus()\n if (open.value && target !== inputRef.value) hide()\n else show()\n}\n\nfunction onBlur(event: FocusEvent) {\n const next = event.relatedTarget\n if (next instanceof Node && (fieldRef.value?.contains(next) || panelRef.value?.contains(next))) {\n return\n }\n hide()\n formItem?.trigger('blur')\n}\n\nconst pathLabel = (path: CascaderOption[]) =>\n props.showLastOnly ? labelOf(path.at(-1)!) : path.map(labelOf).join(props.separator)\nconst tags = computed(() =>\n checkedPaths.value.map((values) => {\n const path = resolve(values)\n return {\n values,\n label:\n path.length === values.length ? pathLabel(path) : values.map(String).join(props.separator),\n }\n }),\n)\nconst shownTags = computed(() =>\n props.maxTagCount === undefined\n ? tags.value\n : tags.value.slice(0, Math.max(0, props.maxTagCount)),\n)\nconst hiddenTags = computed(() => tags.value.slice(shownTags.value.length))\n\nconst display = computed(() => {\n const path = selectedPath.value\n if (!path.length) return ''\n return props.showLastOnly ? labelOf(path.at(-1)!) : path.map(labelOf).join(props.separator)\n})\nconst placeholderText = computed(() => props.placeholder ?? t('cascader.placeholder'))\n\nconst activeDescendant = computed(() => {\n if (!open.value) return undefined\n if (searching.value)\n return activeMatch.value >= 0 ? `${id}-match-${activeMatch.value}` : undefined\n return active.value.length ? optionId(active.value) : undefined\n})\n\nconst comboboxAttrs = computed<HTMLAttributes>(() => ({\n role: 'combobox',\n 'aria-haspopup': 'listbox',\n 'aria-expanded': open.value,\n 'aria-controls': rendered.value\n ? searching.value\n ? `${id}-matches`\n : listboxId(Math.max(0, active.value.length - 1))\n : undefined,\n 'aria-activedescendant': activeDescendant.value,\n 'aria-invalid': invalid.value || undefined,\n 'aria-required': formItem?.required.value || undefined,\n 'aria-describedby': formItem?.describedBy.value,\n}))\n\nconst showClear = computed(() => props.clearable && !locked.value && !!model.value?.length)\nconst inputPlaceholder = computed(() => {\n if (props.multiple) return tags.value.length ? '' : placeholderText.value\n return display.value || placeholderText.value\n})\n\ndefineExpose<CascaderExpose>({ focus, blur: () => combobox()?.blur() })\n</script>\n\n<template>\n <OnlyChild ref=\"triggerRef\">\n <div\n ref=\"field\"\n v-bind=\"{ ...$attrs, ...(filterable ? {} : comboboxAttrs) }\"\n :class=\"[\n ns.b(),\n 'dou-picker',\n `dou-picker--${size}`,\n ns.is('open', open),\n ns.is('multiple', multiple),\n ns.is('has-tags', tags.length > 0),\n ns.is('disabled', disabled),\n ns.is('readonly', readonly),\n ns.is('invalid', invalid),\n ]\"\n :id=\"filterable ? undefined : formItem?.inputId\"\n :aria-labelledby=\"filterable ? undefined : formItem?.labelId\"\n :tabindex=\"filterable || disabled ? undefined : 0\"\n @mousedown=\"onFieldMousedown\"\n @keydown=\"filterable ? undefined : onKeydown($event)\"\n @focusout=\"onBlur\"\n >\n <div v-if=\"multiple\" :class=\"ns.e('tags')\">\n <DouTag\n v-for=\"tag in shownTags\"\n :key=\"keyOf(tag.values)\"\n :size=\"size\"\n :closable=\"!locked\"\n @close=\"removePath(tag.values)\"\n >\n {{ tag.label }}\n </DouTag>\n <DouTag\n v-if=\"hiddenTags.length\"\n :size=\"size\"\n :class=\"ns.e('tag-more')\"\n :title=\"hiddenTags.map((tag) => tag.label).join('、')\"\n >\n +{{ hiddenTags.length }}\n </DouTag>\n <input\n v-if=\"filterable\"\n ref=\"input\"\n v-model=\"query\"\n v-bind=\"comboboxAttrs\"\n :id=\"formItem?.inputId\"\n class=\"dou-picker__input\"\n :class=\"ns.e('input')\"\n type=\"text\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n :placeholder=\"inputPlaceholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n @input=\"show\"\n @keydown=\"onKeydown\"\n />\n <span v-else-if=\"!tags.length\" class=\"dou-picker__placeholder\">{{ placeholderText }}</span>\n </div>\n <input\n v-else-if=\"filterable\"\n ref=\"input\"\n v-model=\"query\"\n v-bind=\"comboboxAttrs\"\n :id=\"formItem?.inputId\"\n class=\"dou-picker__input\"\n type=\"text\"\n autocomplete=\"off\"\n aria-autocomplete=\"list\"\n :placeholder=\"display || placeholderText\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :class=\"ns.is('has-value', !!display)\"\n @input=\"show\"\n @keydown=\"onKeydown\"\n />\n <span v-else-if=\"display\" class=\"dou-picker__value\">{{ display }}</span>\n <span v-else class=\"dou-picker__placeholder\">{{ placeholderText }}</span>\n <button\n v-if=\"showClear\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"dou-picker__clear\"\n :aria-label=\"t('cascader.clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <CloseIcon />\n </button>\n <ChevronDownIcon class=\"dou-picker__arrow\" />\n </div>\n </OnlyChild>\n <Teleport v-if=\"rendered\" :to=\"teleportTarget.to\" :disabled=\"teleportTarget.disabled\">\n <Transition appear name=\"dou-floating\">\n <div\n v-show=\"open\"\n ref=\"panelRef\"\n :class=\"[ns.e('panel'), 'dou-picker-panel', 'dou-floating']\"\n :style=\"panelStyle\"\n :data-placement=\"placement\"\n :data-dou-theme=\"theme\"\n @mousedown.prevent\n >\n <ul\n v-if=\"searching\"\n :id=\"`${id}-matches`\"\n role=\"listbox\"\n :class=\"[ns.e('column'), ns.e('matches')]\"\n >\n <li\n v-for=\"(match, index) in matches\"\n :id=\"`${id}-match-${index}`\"\n :key=\"keyOf(match.values)\"\n role=\"option\"\n :aria-selected=\"\n multiple ? stateOf(match.path.at(-1)!, match.values) === 'on' : index === activeMatch\n \"\n :class=\"[ns.e('option'), ns.is('active', index === activeMatch)]\"\n @click=\"chooseMatch(match)\"\n @mousemove=\"activeMatch = index\"\n >\n <DouCheckbox\n v-if=\"multiple\"\n :model-value=\"stateOf(match.path.at(-1)!, match.values) === 'on'\"\n size=\"sm\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :class=\"ns.e('checkbox')\"\n @click.stop\n @update:model-value=\"chooseMatch(match)\"\n />\n <span :class=\"ns.e('label')\">{{ match.label }}</span>\n </li>\n <li v-if=\"!matches.length\" role=\"presentation\" :class=\"ns.e('empty')\">\n <slot name=\"empty\">{{ t('cascader.empty') }}</slot>\n </li>\n </ul>\n <div v-else :class=\"[ns.e('columns'), ns.is('narrow', narrow)]\">\n <button\n v-if=\"narrow && columns.length > 1\"\n type=\"button\"\n tabindex=\"-1\"\n :class=\"ns.e('back')\"\n :aria-label=\"t('cascader.back')\"\n @click=\"goUp\"\n >\n <ChevronLeftIcon :class=\"ns.e('back-icon')\" />\n <span :class=\"ns.e('trail')\">{{ backTrail }}</span>\n </button>\n <ul\n v-for=\"(column, level) in columns\"\n v-show=\"!narrow || level === columns.length - 1\"\n :id=\"listboxId(level)\"\n :key=\"keyOf(column.path)\"\n role=\"listbox\"\n :class=\"ns.e('column')\"\n :aria-multiselectable=\"multiple || undefined\"\n :aria-busy=\"loading.has(keyOf(column.path)) || undefined\"\n @scroll=\"onColumnScroll(level, $event)\"\n >\n <li\n v-if=\"windows[level]!.before\"\n role=\"presentation\"\n :style=\"{ height: `${windows[level]!.before}px` }\"\n />\n <li\n v-for=\"{ index, option, path, key, id: rowId, leaf, state, selected } in windows[\n level\n ]!.rows\"\n :id=\"rowId\"\n :key=\"String(option.value)\"\n role=\"option\"\n :aria-selected=\"selected\"\n :aria-setsize=\"\n windows[level]!.rows.length < columnRows[level]!.length\n ? columnRows[level]!.length\n : undefined\n \"\n :aria-posinset=\"\n windows[level]!.rows.length < columnRows[level]!.length ? index + 1 : undefined\n \"\n :aria-disabled=\"option.disabled || undefined\"\n :aria-expanded=\"leaf ? undefined : expanded[level] === option.value\"\n :class=\"[\n ns.e('option'),\n ns.is('active', activeKey === key),\n ns.is('expanded', expanded[level] === option.value),\n ns.is('selected', selected),\n ns.is('disabled', !!option.disabled),\n ]\"\n @click=\"onOptionClick(option, path)\"\n @mouseenter=\"onOptionHover(option, path)\"\n >\n <DouCheckbox\n v-if=\"multiple\"\n :model-value=\"state === 'on'\"\n :indeterminate=\"state === 'some'\"\n :disabled=\"!!option.disabled\"\n size=\"sm\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :class=\"ns.e('checkbox')\"\n @click.stop\n @update:model-value=\"toggleCheck(option, path)\"\n />\n <span :class=\"ns.e('label')\">\n <slot name=\"option\" :option=\"option\" :level=\"level\">{{ labelOf(option) }}</slot>\n </span>\n <DouSpinner v-if=\"loading.has(key)\" size=\"sm\" :class=\"ns.e('suffix')\" />\n <ChevronRightIcon v-else-if=\"!leaf\" :class=\"ns.e('suffix')\" />\n <CheckIcon\n v-else-if=\"!multiple && selected\"\n :class=\"[ns.e('suffix'), ns.e('check')]\"\n />\n </li>\n <li\n v-if=\"windows[level]!.after\"\n role=\"presentation\"\n :style=\"{ height: `${windows[level]!.after}px` }\"\n />\n <li\n v-if=\"!column.options.length && !loading.has(keyOf(column.path))\"\n role=\"presentation\"\n :class=\"ns.e('empty')\"\n >\n <slot name=\"empty\">{{ t('cascader.empty') }}</slot>\n </li>\n </ul>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n"],"mappings":""}
|
|
@@ -8,7 +8,7 @@ import { useFormDisabled, useFormItem, useFormReadonly, useFormSize } from "../f
|
|
|
8
8
|
import { DouSpinner } from "../spinner/index.js";
|
|
9
9
|
import { useTeleport } from "../../utils/teleport.js";
|
|
10
10
|
import { useNarrowViewport } from "../../utils/media.js";
|
|
11
|
-
import
|
|
11
|
+
import { DouCheckbox } from "../checkbox/index.js";
|
|
12
12
|
import { DouTag } from "../tag/index.js";
|
|
13
13
|
import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, reactive, ref, renderList, renderSlot, toDisplayString, unref, useId, useModel, useSlots, useTemplateRef, vModelText, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
14
14
|
import { CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, CloseIcon } from "@dou-ui/icons";
|
|
@@ -700,7 +700,7 @@ var cascader_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
700
700
|
class: normalizeClass([unref(ns).e("option"), unref(ns).is("active", index === activeMatch.value)]),
|
|
701
701
|
onClick: ($event) => chooseMatch(match),
|
|
702
702
|
onMousemove: ($event) => activeMatch.value = index
|
|
703
|
-
}, [__props.multiple ? (openBlock(), createBlock(
|
|
703
|
+
}, [__props.multiple ? (openBlock(), createBlock(unref(DouCheckbox), {
|
|
704
704
|
key: 0,
|
|
705
705
|
"model-value": stateOf(match.path.at(-1), match.values) === "on",
|
|
706
706
|
size: "sm",
|
|
@@ -763,7 +763,7 @@ var cascader_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
763
763
|
onClick: ($event) => onOptionClick(option, path),
|
|
764
764
|
onMouseenter: ($event) => onOptionHover(option, path)
|
|
765
765
|
}, [
|
|
766
|
-
__props.multiple ? (openBlock(), createBlock(
|
|
766
|
+
__props.multiple ? (openBlock(), createBlock(unref(DouCheckbox), {
|
|
767
767
|
key: 0,
|
|
768
768
|
"model-value": state === "on",
|
|
769
769
|
indeterminate: state === "some",
|