@rotki/ui-library 3.0.0-beta.3 → 3.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -14
- package/dist/components/accordions/accordion/RuiAccordion.js.map +1 -1
- package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +1 -1
- package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/alerts/RuiAlert.js.map +1 -1
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatar.js.map +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatarGroup.js.map +1 -1
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cards/RuiCard.js.map +1 -1
- package/dist/components/cards/RuiCard.vue.d.ts +1 -1
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/RuiChip.js.map +1 -1
- package/dist/components/chips/RuiChip.vue.d.ts +1 -1
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorDisplay.js.map +1 -1
- package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorHue.js.map +1 -1
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue.d.ts +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +2 -2
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/divider/RuiDivider.js.map +1 -1
- package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue.d.ts +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/auto-complete-props.d.ts +2 -2
- package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +2 -2
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/field-defaults/RuiFieldDefaults.js.map +1 -1
- package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/field-label/RuiFieldLabel.js.map +1 -1
- package/dist/components/forms/field-label/RuiFieldLabel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +4 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +17 -8
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.js.map +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.js.map +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.d.ts +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +2 -2
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.vue.d.ts +1 -1
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/slider/RuiSliderTicks.js.map +1 -1
- package/dist/components/forms/slider/RuiSliderTicks.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +1 -2
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/icons/RuiIcon.js.map +1 -1
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +11 -10
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +57 -57
- package/dist/components/loaders/RuiSkeletonBase.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue.d.ts +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/logos/RuiLogo.js.map +1 -1
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.js.map +1 -1
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +1 -1
- package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue.d.ts +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/progress/RuiProgress.js.map +1 -1
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepper.js.map +1 -1
- package/dist/components/steppers/RuiStepper.vue.d.ts +1 -1
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiDataTable.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +11 -2
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +8 -3
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTable.js.map +1 -1
- package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableEmptyState.js.map +1 -1
- package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableErrorState.js.map +1 -1
- package/dist/components/tables/RuiTableErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableHead.js.map +1 -1
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableLoadingState.js.map +1 -1
- package/dist/components/tables/RuiTableLoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableAppendRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableAppendRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableAppendRow.vue.d.ts +26 -0
- package/dist/components/tables/data-table/RuiDataTableAppendRow.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/components/tables/data-table/RuiDataTableAppendRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +5 -1
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +18 -10
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableErrorRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableErrorRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +5 -1
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +144 -88
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/context.d.ts +1 -1
- package/dist/components/tables/data-table-styles.js +1 -1
- package/dist/components/tables/data-table-styles.js.map +1 -1
- package/dist/components/tabs/tab/RuiTab.js.map +1 -1
- package/dist/components/tabs/tab/RuiTab.vue.d.ts +1 -1
- package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.js.map +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +12 -8
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/floating.d.ts +1 -1
- package/dist/composables/icons.d.ts +1 -1
- package/dist/composables/icons.js +1 -7
- package/dist/composables/icons.js.map +1 -1
- package/dist/composables/tables/data-table/columns.d.ts +1 -1
- package/dist/composables/tables/data-table/grouping.d.ts +1 -1
- package/dist/composables/tables/data-table/page-scroll.d.ts +1 -1
- package/dist/composables/tables/data-table/pagination.d.ts +2 -2
- package/dist/composables/tables/data-table/sort.d.ts +2 -2
- package/dist/composables/tables/data-table/types.d.ts +2 -2
- package/dist/i18n/keys.d.ts +9 -0
- package/dist/i18n/keys.js +9 -0
- package/dist/i18n/keys.js.map +1 -1
- package/dist/icons/icons_1.d.ts +26 -26
- package/dist/icons/icons_1.js +348 -365
- package/dist/icons/icons_1.js.map +1 -1
- package/dist/icons/icons_2.d.ts +28 -28
- package/dist/icons/icons_2.js +434 -323
- package/dist/icons/icons_2.js.map +1 -1
- package/dist/icons/icons_3.d.ts +32 -32
- package/dist/icons/icons_3.js +334 -364
- package/dist/icons/icons_3.js.map +1 -1
- package/dist/icons/icons_4.d.ts +64 -64
- package/dist/icons/icons_4.js +769 -669
- package/dist/icons/icons_4.js.map +1 -1
- package/dist/icons/icons_5.d.ts +66 -9
- package/dist/icons/icons_5.js +693 -83
- package/dist/icons/icons_5.js.map +1 -1
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/index.js +108 -51
- package/dist/icons/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/style.css +22 -4
- package/dist/types/theme.d.ts +1 -1
- package/dist/utils/tv.d.ts +1 -1
- package/dist/vendor/@vueuse/core/dist/index.js +63 -55
- package/dist/vendor/@vueuse/core/dist/index.js.map +1 -1
- package/dist/vendor/@vueuse/shared/dist/index.js +4 -4
- package/dist/vendor/@vueuse/shared/dist/index.js.map +1 -1
- package/dist/web-types.json +88 -4
- package/package.json +26 -26
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTabs.js","names":[],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { tv } from '@/utils/tv';\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\n/**\n * The selected tab, defaulting to the first one. The default also narrows the\n * `update:modelValue` payload to `number | string`, so a consumer's handler\n * needs no undefined in its signature.\n */\nconst modelValue = defineModel<number | string>({ default: 0 });\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\n/**\n * The bar. The underline variant draws its 1px track as a `before` line along\n * the whole root, so the arrows sit on it too, and the 2px indicator, a layer\n * above, covers it under the active tab.\n */\nconst tabs = tv({\n slots: {\n root: '',\n arrow: 'flex shrink-0 items-center justify-center',\n // a tab stop only when it scrolls with every tab disabled (useKeyboardScroll)\n bar: 'no-scrollbar relative max-h-full overflow-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n wrapper: 'inline-flex max-w-none',\n indicator: 'pointer-events-none absolute',\n },\n variants: {\n variant: {\n [TabVariant.underline]: {\n root: `relative before:pointer-events-none before:absolute before:bg-rui-divider before:content-['']`,\n indicator: 'z-1 bg-rui-primary',\n },\n [TabVariant.segmented]: {\n // neutral-200, not 100: on a near-white page (`#fafafa`) the lighter track all but disappeared\n root: 'rounded-rui-panel bg-rui-neutral-200 p-0.5 dark:bg-rui-neutral-800',\n wrapper: 'gap-0.5',\n indicator: 'rounded-rui-control bg-rui-surface shadow-rui-control dark:bg-rui-neutral-700',\n },\n },\n layout: {\n [TabLayout.horizontal]: { root: 'flex h-fit', arrow: 'w-8' },\n [TabLayout.vertical]: { root: 'inline-flex flex-col', arrow: 'h-8 w-full', wrapper: 'flex-col w-full' },\n },\n indicatorPosition: {\n start: {},\n end: {},\n },\n color: {\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n wide: {\n true: { bar: 'w-full', wrapper: 'min-w-full' },\n false: {},\n },\n animated: {\n true: { indicator: 'transition-[left,top,width,height] duration-200 ease-out motion-reduce:transition-none' },\n false: {},\n },\n },\n compoundVariants: [\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end', class: { root: 'before:inset-x-0 before:bottom-0 before:h-px', indicator: 'bottom-0 h-0.5 rounded-t-full' } },\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'start', class: { root: 'before:inset-x-0 before:top-0 before:h-px', indicator: 'top-0 h-0.5 rounded-b-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'end', class: { root: 'before:inset-y-0 before:right-0 before:w-px', indicator: 'right-0 w-0.5 rounded-l-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'start', class: { root: 'before:inset-y-0 before:left-0 before:w-px', indicator: 'left-0 w-0.5 rounded-r-full' } },\n // the underline track spans its row, while a segmented control hugs its options unless it grows\n { variant: TabVariant.segmented, layout: TabLayout.horizontal, wide: false, class: { root: 'w-fit max-w-full' } },\n // `color` picks the underline's color; the segmented pill stays a neutral surface\n { variant: TabVariant.underline, color: 'secondary', class: { indicator: 'bg-rui-secondary' } },\n { variant: TabVariant.underline, color: 'error', class: { indicator: 'bg-rui-error' } },\n { variant: TabVariant.underline, color: 'warning', class: { indicator: 'bg-rui-warning' } },\n { variant: TabVariant.underline, color: 'info', class: { indicator: 'bg-rui-info' } },\n { variant: TabVariant.underline, color: 'success', class: { indicator: 'bg-rui-success' } },\n ],\n defaultVariants: { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end' },\n});\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabs>>(() => tabs({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"RuiTabs.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { tv } from '@/utils/tv';\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\n/**\n * The selected tab, defaulting to the first one. The default also narrows the\n * `update:modelValue` payload to `number | string`, so a consumer's handler\n * needs no undefined in its signature.\n */\nconst modelValue = defineModel<number | string>({ default: 0 });\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\n/**\n * The bar. The underline variant draws its 1px track as a `before` line along\n * the whole root, so the arrows sit on it too, and the 2px indicator, a layer\n * above, covers it under the active tab.\n */\nconst tabs = tv({\n slots: {\n root: '',\n arrow: 'flex shrink-0 items-center justify-center',\n // a tab stop only when it scrolls with every tab disabled (useKeyboardScroll)\n bar: 'no-scrollbar relative max-h-full overflow-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n wrapper: 'inline-flex max-w-none',\n indicator: 'pointer-events-none absolute',\n },\n variants: {\n variant: {\n [TabVariant.underline]: {\n root: `relative before:pointer-events-none before:absolute before:bg-rui-divider before:content-['']`,\n indicator: 'z-1 bg-rui-primary',\n },\n [TabVariant.segmented]: {\n // neutral-200, not 100: on a near-white page (`#fafafa`) the lighter track all but disappeared\n root: 'rounded-rui-panel bg-rui-neutral-200 p-0.5 dark:bg-rui-neutral-800',\n wrapper: 'gap-0.5',\n indicator: 'rounded-rui-control bg-rui-surface shadow-rui-control dark:bg-rui-neutral-700',\n },\n },\n layout: {\n [TabLayout.horizontal]: { root: 'flex h-fit', arrow: 'w-8' },\n [TabLayout.vertical]: { root: 'inline-flex flex-col', arrow: 'h-8 w-full', wrapper: 'flex-col w-full' },\n },\n indicatorPosition: {\n start: {},\n end: {},\n },\n color: {\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n wide: {\n true: { bar: 'w-full', wrapper: 'min-w-full' },\n false: {},\n },\n animated: {\n true: { indicator: 'transition-[left,top,width,height] duration-200 ease-out motion-reduce:transition-none' },\n false: {},\n },\n },\n compoundVariants: [\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end', class: { root: 'before:inset-x-0 before:bottom-0 before:h-px', indicator: 'bottom-0 h-0.5 rounded-t-full' } },\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'start', class: { root: 'before:inset-x-0 before:top-0 before:h-px', indicator: 'top-0 h-0.5 rounded-b-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'end', class: { root: 'before:inset-y-0 before:right-0 before:w-px', indicator: 'right-0 w-0.5 rounded-l-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'start', class: { root: 'before:inset-y-0 before:left-0 before:w-px', indicator: 'left-0 w-0.5 rounded-r-full' } },\n // the underline track spans its row, while a segmented control hugs its options unless it grows\n { variant: TabVariant.segmented, layout: TabLayout.horizontal, wide: false, class: { root: 'w-fit max-w-full' } },\n // `color` picks the underline's color; the segmented pill stays a neutral surface\n { variant: TabVariant.underline, color: 'secondary', class: { indicator: 'bg-rui-secondary' } },\n { variant: TabVariant.underline, color: 'error', class: { indicator: 'bg-rui-error' } },\n { variant: TabVariant.underline, color: 'warning', class: { indicator: 'bg-rui-warning' } },\n { variant: TabVariant.underline, color: 'info', class: { indicator: 'bg-rui-info' } },\n { variant: TabVariant.underline, color: 'success', class: { indicator: 'bg-rui-success' } },\n ],\n defaultVariants: { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end' },\n});\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabs>>(() => tabs({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTabs.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { tv } from '@/utils/tv';\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\n/**\n * The selected tab, defaulting to the first one. The default also narrows the\n * `update:modelValue` payload to `number | string`, so a consumer's handler\n * needs no undefined in its signature.\n */\nconst modelValue = defineModel<number | string>({ default: 0 });\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\n/**\n * The bar. The underline variant draws its 1px track as a `before` line along\n * the whole root, so the arrows sit on it too, and the 2px indicator, a layer\n * above, covers it under the active tab.\n */\nconst tabs = tv({\n slots: {\n root: '',\n arrow: 'flex shrink-0 items-center justify-center',\n // a tab stop only when it scrolls with every tab disabled (useKeyboardScroll)\n bar: 'no-scrollbar relative max-h-full overflow-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n wrapper: 'inline-flex max-w-none',\n indicator: 'pointer-events-none absolute',\n },\n variants: {\n variant: {\n [TabVariant.underline]: {\n root: `relative before:pointer-events-none before:absolute before:bg-rui-divider before:content-['']`,\n indicator: 'z-1 bg-rui-primary',\n },\n [TabVariant.segmented]: {\n // neutral-200, not 100: on a near-white page (`#fafafa`) the lighter track all but disappeared\n root: 'rounded-rui-panel bg-rui-neutral-200 p-0.5 dark:bg-rui-neutral-800',\n wrapper: 'gap-0.5',\n indicator: 'rounded-rui-control bg-rui-surface shadow-rui-control dark:bg-rui-neutral-700',\n },\n },\n layout: {\n [TabLayout.horizontal]: { root: 'flex h-fit', arrow: 'w-8' },\n [TabLayout.vertical]: { root: 'inline-flex flex-col', arrow: 'h-8 w-full', wrapper: 'flex-col w-full' },\n },\n indicatorPosition: {\n start: {},\n end: {},\n },\n color: {\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n wide: {\n true: { bar: 'w-full', wrapper: 'min-w-full' },\n false: {},\n },\n animated: {\n true: { indicator: 'transition-[left,top,width,height] duration-200 ease-out motion-reduce:transition-none' },\n false: {},\n },\n },\n compoundVariants: [\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end', class: { root: 'before:inset-x-0 before:bottom-0 before:h-px', indicator: 'bottom-0 h-0.5 rounded-t-full' } },\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'start', class: { root: 'before:inset-x-0 before:top-0 before:h-px', indicator: 'top-0 h-0.5 rounded-b-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'end', class: { root: 'before:inset-y-0 before:right-0 before:w-px', indicator: 'right-0 w-0.5 rounded-l-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'start', class: { root: 'before:inset-y-0 before:left-0 before:w-px', indicator: 'left-0 w-0.5 rounded-r-full' } },\n // the underline track spans its row, while a segmented control hugs its options unless it grows\n { variant: TabVariant.segmented, layout: TabLayout.horizontal, wide: false, class: { root: 'w-fit max-w-full' } },\n // `color` picks the underline's color; the segmented pill stays a neutral surface\n { variant: TabVariant.underline, color: 'secondary', class: { indicator: 'bg-rui-secondary' } },\n { variant: TabVariant.underline, color: 'error', class: { indicator: 'bg-rui-error' } },\n { variant: TabVariant.underline, color: 'warning', class: { indicator: 'bg-rui-warning' } },\n { variant: TabVariant.underline, color: 'info', class: { indicator: 'bg-rui-info' } },\n { variant: TabVariant.underline, color: 'success', class: { indicator: 'bg-rui-success' } },\n ],\n defaultVariants: { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end' },\n});\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabs>>(() => tabs({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RuiTabs.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_createVNode","RuiButton","_withCtx","RuiIcon","_createCommentVNode","_createElementVNode","_normalizeStyle","_Fragment","_renderList","_createBlock","_resolveDynamicComponent"],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { tv } from '@/utils/tv';\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\n/**\n * The selected tab, defaulting to the first one. The default also narrows the\n * `update:modelValue` payload to `number | string`, so a consumer's handler\n * needs no undefined in its signature.\n */\nconst modelValue = defineModel<number | string>({ default: 0 });\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\n/**\n * The bar. The underline variant draws its 1px track as a `before` line along\n * the whole root, so the arrows sit on it too, and the 2px indicator, a layer\n * above, covers it under the active tab.\n */\nconst tabs = tv({\n slots: {\n root: '',\n arrow: 'flex shrink-0 items-center justify-center',\n // a tab stop only when it scrolls with every tab disabled (useKeyboardScroll)\n bar: 'no-scrollbar relative max-h-full overflow-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n wrapper: 'inline-flex max-w-none',\n indicator: 'pointer-events-none absolute',\n },\n variants: {\n variant: {\n [TabVariant.underline]: {\n root: `relative before:pointer-events-none before:absolute before:bg-rui-divider before:content-['']`,\n indicator: 'z-1 bg-rui-primary',\n },\n [TabVariant.segmented]: {\n // neutral-200, not 100: on a near-white page (`#fafafa`) the lighter track all but disappeared\n root: 'rounded-rui-panel bg-rui-neutral-200 p-0.5 dark:bg-rui-neutral-800',\n wrapper: 'gap-0.5',\n indicator: 'rounded-rui-control bg-rui-surface shadow-rui-control dark:bg-rui-neutral-700',\n },\n },\n layout: {\n [TabLayout.horizontal]: { root: 'flex h-fit', arrow: 'w-8' },\n [TabLayout.vertical]: { root: 'inline-flex flex-col', arrow: 'h-8 w-full', wrapper: 'flex-col w-full' },\n },\n indicatorPosition: {\n start: {},\n end: {},\n },\n color: {\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n wide: {\n true: { bar: 'w-full', wrapper: 'min-w-full' },\n false: {},\n },\n animated: {\n true: { indicator: 'transition-[left,top,width,height] duration-200 ease-out motion-reduce:transition-none' },\n false: {},\n },\n },\n compoundVariants: [\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end', class: { root: 'before:inset-x-0 before:bottom-0 before:h-px', indicator: 'bottom-0 h-0.5 rounded-t-full' } },\n { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'start', class: { root: 'before:inset-x-0 before:top-0 before:h-px', indicator: 'top-0 h-0.5 rounded-b-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'end', class: { root: 'before:inset-y-0 before:right-0 before:w-px', indicator: 'right-0 w-0.5 rounded-l-full' } },\n { variant: TabVariant.underline, layout: TabLayout.vertical, indicatorPosition: 'start', class: { root: 'before:inset-y-0 before:left-0 before:w-px', indicator: 'left-0 w-0.5 rounded-r-full' } },\n // the underline track spans its row, while a segmented control hugs its options unless it grows\n { variant: TabVariant.segmented, layout: TabLayout.horizontal, wide: false, class: { root: 'w-fit max-w-full' } },\n // `color` picks the underline's color; the segmented pill stays a neutral surface\n { variant: TabVariant.underline, color: 'secondary', class: { indicator: 'bg-rui-secondary' } },\n { variant: TabVariant.underline, color: 'error', class: { indicator: 'bg-rui-error' } },\n { variant: TabVariant.underline, color: 'warning', class: { indicator: 'bg-rui-warning' } },\n { variant: TabVariant.underline, color: 'info', class: { indicator: 'bg-rui-info' } },\n { variant: TabVariant.underline, color: 'success', class: { indicator: 'bg-rui-success' } },\n ],\n defaultVariants: { variant: TabVariant.underline, layout: TabLayout.horizontal, indicatorPosition: 'end' },\n});\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabs>>(() => tabs({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCA,MAAM,aAAaA,SAA4B,SAAA,YAAe;EAY9D,MAAM,qBAAqB,IAAqB;EAChD,MAAM,MAAM,eAA+B,KAAK;EAChD,MAAM,UAAU,eAA+B,SAAS;EACxD,MAAM,cAAc,kBAAkB,GAAG;;;;;;EAOzC,MAAM,OAAO,GAAG;GACd,OAAO;IACL,MAAM;IACN,OAAO;IAEP,KAAK;IACL,SAAS;IACT,WAAW;GACb;GACA,UAAU;IACR,SAAS;MACN,WAAW,YAAY;MACtB,MAAM;MACN,WAAW;KACb;MACC,WAAW,YAAY;MAEtB,MAAM;MACN,SAAS;MACT,WAAW;KACb;IACF;IACA,QAAQ;MACL,UAAU,aAAa;MAAE,MAAM;MAAc,OAAO;KAAM;MAC1D,UAAU,WAAW;MAAE,MAAM;MAAwB,OAAO;MAAc,SAAS;KAAkB;IACxG;IACA,mBAAmB;KACjB,OAAO,CAAC;KACR,KAAK,CAAC;IACR;IACA,OAAO;KACL,SAAS,CAAC;KACV,WAAW,CAAC;KACZ,OAAO,CAAC;KACR,SAAS,CAAC;KACV,MAAM,CAAC;KACP,SAAS,CAAC;IACZ;IACA,MAAM;KACJ,MAAM;MAAE,KAAK;MAAU,SAAS;KAAa;KAC7C,OAAO,CAAC;IACV;IACA,UAAU;KACR,MAAM,EAAE,WAAW,yFAAyF;KAC5G,OAAO,CAAC;IACV;GACF;GACA,kBAAkB;IAChB;KAAE,SAAS,WAAW;KAAW,QAAQ,UAAU;KAAY,mBAAmB;KAAO,OAAO;MAAE,MAAM;MAAgD,WAAW;KAAgC;IAAE;IACrM;KAAE,SAAS,WAAW;KAAW,QAAQ,UAAU;KAAY,mBAAmB;KAAS,OAAO;MAAE,MAAM;MAA6C,WAAW;KAA6B;IAAE;IACjM;KAAE,SAAS,WAAW;KAAW,QAAQ,UAAU;KAAU,mBAAmB;KAAO,OAAO;MAAE,MAAM;MAA+C,WAAW;KAA+B;IAAE;IACjM;KAAE,SAAS,WAAW;KAAW,QAAQ,UAAU;KAAU,mBAAmB;KAAS,OAAO;MAAE,MAAM;MAA8C,WAAW;KAA8B;IAAE;IAEjM;KAAE,SAAS,WAAW;KAAW,QAAQ,UAAU;KAAY,MAAM;KAAO,OAAO,EAAE,MAAM,mBAAmB;IAAE;IAEhH;KAAE,SAAS,WAAW;KAAW,OAAO;KAAa,OAAO,EAAE,WAAW,mBAAmB;IAAE;IAC9F;KAAE,SAAS,WAAW;KAAW,OAAO;KAAS,OAAO,EAAE,WAAW,eAAe;IAAE;IACtF;KAAE,SAAS,WAAW;KAAW,OAAO;KAAW,OAAO,EAAE,WAAW,iBAAiB;IAAE;IAC1F;KAAE,SAAS,WAAW;KAAW,OAAO;KAAQ,OAAO,EAAE,WAAW,cAAc;IAAE;IACpF;KAAE,SAAS,WAAW;KAAW,OAAO;KAAW,OAAO,EAAE,WAAW,iBAAiB;IAAE;GAC5F;GACA,iBAAiB;IAAE,SAAS,WAAW;IAAW,QAAQ,UAAU;IAAY,mBAAmB;GAAM;EAC3G,CAAC;EAED,MAAM,QAAQ,SAAS;EAEvB,MAAM,EACJ,YACA,mBACA,mBACA,mBACA,mBACA,yBACE,aAAa;GAAE;GAAK;GAAS,gBAAgB,QAAA;EAAS,CAAC;EAE3D,MAAM,EAAE,cAAc,gBAAgB,cAAc,EAClD,qBAAqB,cAAc,IAAI,EACzC,CAAC;EAED,MAAM,EAAE,cAAc,eAAe;GAAE;GAAS,gBAAgB,QAAA;EAAS,CAAC;EAE1E,MAAM,EAAE,OAAO,gBAAgB,UAAU,QAAQ,oBAAoB,gBAAgB;GACnF;GACA;GACA,gBAAgB,QAAA;GAChB,eAAe,QAAA;EACjB,CAAC;EAED,MAAM,SAAS,eAA0B,QAAA,WAAW,UAAU,WAAW,UAAU,UAAU;EAC7F,MAAM,KAAK,eAAwC,KAAK;GACtD,SAAM,QAAA;GACN,QAAQ,IAAI,MAAM;GAClB,mBAAgB,QAAA;GAChB,OAAI,QAAA;GACJ,MAAM,QAAA,YAAY,QAAA;GAClB,UAAU,IAAI,QAAQ;EACxB,CAAC,CAAC;EAEF,MAAM,WAAW,eAA4B;GAG3C,MAAM,OAAO,gBAFO,MAAM,UAAU,KAAK,CAAC,CAEF;GAExC,MAAM,oBAAoB,IAAI,kBAAkB;GAChD,MAAM,iBAAiB;IACrB,OAAI,QAAA;IACJ,MAAG,QAAA;IACH,UAAO,QAAA;IACP,UAAO,QAAA;IACP,OAAI,QAAA;IACJ,mBAAgB,QAAA;IAChB,SAAM,QAAA;GACR;GAEA,OAAO,KAAK,KAAK,KAAK,UAAU;IAC9B,IAAI,WAAW,IAAI,OAAO,SAAS;IACnC,IAAI,IAAI,OAAO,SAAS,SAAS,IAAI,OAAO,IAC1C,WAAW,IAAI,MAAM;IAEvB,MAAM,SAAS,sBAAsB;IACrC,OAAO;KACL,GAAG;KACH,OAAO;MACL,OAAO;MACP;MACA,GAAG;MACH,GAAG,IAAI;KACT;IACF;GACF,CAAC;EACH,CAAC;;;;;;;;EASD,SAAS,gBAAgB,UAA4B;GACnD,OAAO,SAAS,SAAS,SAAS;IAChC,IAAI,KAAK,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,SAAS,GACnF,OAAO,gBAAgB,KAAK,SAAS,OAAO,OAAO,CAAC;IAEtD,OAAO,CAAC,IAAI;GACd,CAAC,CAAC,CAAC,KAAK;EACV;EAEA,SAAS,iBAAiB,eAAsC;GAC9D,IAAI,YAAY,aAAa;GAC7B,IAAI,oBAAoB,aAAa;EACvC;EAEA,SAAS,iBAAiB,OAAkD;GAC1E,OAAO;IACL,OAAO,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAA;IAC1F,IAAI,MAAM,MAAM,KAAA;IAChB,MAAM,OAAO,MAAM,SAAS,YAAY,MAAM,OAAO,KAAA;IACrD,OAAO,OAAO,MAAM,UAAU,YAAY,MAAM,QAAQ,KAAA;GAC1D;EACF;EAEA,SAAS,mBAAmB,UAAgD;GAC1E,MAAM,kBAAkB,IAAI,QAAQ,CAAC,CAAC,QAAO,UAAS,CAAC,MAAM,OAAO,QAAQ;GAC5E,IAAI,gBAAgB,WAAW,GAC7B,OAAO,KAAA;GAET,IAAI,SAA0B,IAAI,UAAU,KAAK;GACjD,gBAAgB,SAAS,OAAO,UAAU;IACxC,MAAM,WAAW,iBAAiB,MAAM,KAAK;IAC7C,IAAI,CAAC,YAAY,UAAU,KAAK,SAAS,OACvC,SAAS,SAAS;IAEpB,MAAM,WAAW,aAAa,SAAS,EAAE;IAEzC,IAAI,SAAS,SAAS,SAAS,YAAY,YAAY,UAAU,QAAQ,GACvE,SAAS;GACb,CAAC;GACD,OAAO;EACT;EAEA,SAAS,cAAc,WAAW,OAAa;GAC7C,MAAM,QAAQ,mBAAmB,QAAQ;GACzC,IAAI,UAAU,KAAA,GACZ,iBAAiB,KAAK;GAExB,qBAAqB;EACvB;EAEA,qBAAqB,IAAI,UAAU,IAAI,eAAe;GACpD,IAAI,oBAAoB,UAAU;EACpC,CAAC;EAED,MAAM,0BAA0B;GAC9B,qBAAqB;EACvB,CAAC;EAED,YAAY;GAAC,QAAA;GAAU,QAAA;GAAS,QAAA;GAAM,QAAA;EAAK,SAAS,SAAS,eAAe,GAAG,EAAE,OAAO,OAAO,CAAC;EAEhG,gBAAgB;GACd,IAAI,IAAI,UAAU,MAAM,KAAA,GACtB;GAEF,cAAc;EAChB,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBAgEM,OAAA;IA/DH,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA;IACd,iBAAe,QAAA,YAAY,KAAA;;IAGpBA,MAAA,UAAA,KADRH,UAAA,GAAAC,mBAeM,OAAA;;KAbH,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;IAEhBC,GAAAA,CAAAA,YAUYC,mBAAA;KATV,SAAQ;KACR,MAAA;KACA,MAAK;KACL,UAAS;KACT,cAAW;KACV,UAAUF,MAAA,iBAAA;KACV,SAAK,OAAA,OAAA,OAAA,MAAA,WAAEA,MAAA,iBAAA,CAAiB,CAAA;;KAEzB,SAAAG,cAAkE,CAAlEF,YAAkEG,iBAAA,EAAxD,MAAM,QAAA,WAAQ,kBAAA,kBAAA,GAAA,MAAA,GAAA,CAAA,MAAA,CAAA,CAAA,CAAA;;;IAG5BE,mBA2BM,OAAA;KA1BA,SAAA;KAAJ,KAAI;KACH,OAAKP,eAAEC,MAAA,EAAA,CAAE,CAAC,IAAG,CAAA;KACb,UAAUA,MAAA,WAAA;IAGHA,GAAAA,CAAAA,MAAA,cAAA,KADRH,UAAA,GAAAC,mBAME,QAAA;;KAJA,eAAY;KACZ,WAAQ;KACP,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA;KACnB,OAAKO,eAAEP,MAAA,cAAA,CAAc;IAExBM,GAAAA,MAAAA,CAAAA,KAAAA,mBAAAA,IAAAA,IAAAA,GAAAA,mBAcM,OAAA;KAbA,SAAA;KAAJ,KAAI;KACJ,MAAK;KACL,WAAQ;KACP,oBAAkB,QAAA,WAAQ,aAAgB,KAAA;KAC1C,OAAKP,eAAEC,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;KACjB,WAAO,OAAA,OAAA,OAAA,MAAA,WAAEA,MAAA,SAAA,CAAS,CAAC,MAAM;IAE1BH,GAAAA,EAAAA,UAAA,IAAA,GAAAC,mBAKEU,UAAA,MAAAC,WAHqBT,MAAA,QAAA,IAAb,OAAO,MAAC;KAFlB,OAAAH,UAAA,GAAAa,YAKEC,wBAJK,KAAK,GAAA;MAET,KAAK;MACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,iBAAiB,MAAM;;;IAK7BX,MAAA,UAAA,KADRH,UAAA,GAAAC,mBAeM,OAAA;;KAbH,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;IAEhBC,GAAAA,CAAAA,YAUYC,mBAAA;KATV,SAAQ;KACR,MAAA;KACA,MAAK;KACL,UAAS;KACT,cAAW;KACV,UAAUF,MAAA,iBAAA;KACV,SAAK,OAAA,OAAA,OAAA,MAAA,WAAEA,MAAA,iBAAA,CAAiB,CAAA;;KAEzB,SAAAG,cAAqE,CAArEF,YAAqEG,iBAAA,EAA3D,MAAM,QAAA,WAAQ,oBAAA,mBAAA,GAAA,MAAA,GAAA,CAAA,MAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTimePicker.js","names":[],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div :class=\"ui.time()\">\n <button\n type=\"button\"\n aria-label=\"Select hours\"\n :aria-pressed=\"editMode === 'hour'\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </button>\n <div :class=\"ui.separator()\">\n :\n </div>\n <button\n type=\"button\"\n aria-label=\"Select minutes\"\n :aria-pressed=\"editMode === 'minute'\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </button>\n <div\n v-if=\"showSecond\"\n :class=\"ui.separator()\"\n >\n :\n </div>\n <button\n v-if=\"showSecond\"\n type=\"button\"\n aria-label=\"Select seconds\"\n :aria-pressed=\"editMode === 'second'\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </button>\n\n <div\n v-if=\"showMillisecond\"\n :class=\"ui.separator({ class: 'text-lg' })\"\n >\n .\n </div>\n\n <button\n v-if=\"showMillisecond\"\n type=\"button\"\n aria-label=\"Select milliseconds\"\n :aria-pressed=\"editMode === 'millisecond'\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: 'text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </button>\n </div>\n <button\n type=\"button\"\n aria-label=\"Toggle AM/PM\"\n :class=\"ui.period()\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </button>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"RuiTimePicker.js","names":["_sfc_main"],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div :class=\"ui.time()\">\n <button\n type=\"button\"\n data-id=\"hour\"\n :aria-label=\"`${formatValue(displayHour)} hours`\"\n :aria-pressed=\"editMode === 'hour'\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </button>\n <div :class=\"ui.separator()\">\n :\n </div>\n <button\n type=\"button\"\n data-id=\"minute\"\n :aria-label=\"`${formatValue(selectedMinute)} minutes`\"\n :aria-pressed=\"editMode === 'minute'\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </button>\n <div\n v-if=\"showSecond\"\n :class=\"ui.separator()\"\n >\n :\n </div>\n <button\n v-if=\"showSecond\"\n type=\"button\"\n data-id=\"second\"\n :aria-label=\"`${formatValue(selectedSecond)} seconds`\"\n :aria-pressed=\"editMode === 'second'\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </button>\n\n <div\n v-if=\"showMillisecond\"\n :class=\"ui.separator({ class: 'text-lg' })\"\n >\n .\n </div>\n\n <button\n v-if=\"showMillisecond\"\n type=\"button\"\n data-id=\"millisecond\"\n :aria-label=\"`${formatValue(selectedMillisecond, 3)} milliseconds`\"\n :aria-pressed=\"editMode === 'millisecond'\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: 'text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </button>\n </div>\n <button\n type=\"button\"\n aria-label=\"Toggle AM/PM\"\n :class=\"ui.period()\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </button>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -4,10 +4,10 @@ import { timePickerStyles } from "./time-picker-styles.js";
|
|
|
4
4
|
import { TimeAccuracy } from "../../consts/time-accuracy.js";
|
|
5
5
|
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeModels, nextTick, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, toDisplayString, unref, useModel, useTemplateRef, watch } from "vue";
|
|
6
6
|
//#region src/components/time-picker/RuiTimePicker.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
-
var _hoisted_1 = ["aria-pressed"];
|
|
8
|
-
var _hoisted_2 = ["aria-pressed"];
|
|
9
|
-
var _hoisted_3 = ["aria-pressed"];
|
|
10
|
-
var _hoisted_4 = ["aria-pressed"];
|
|
7
|
+
var _hoisted_1 = ["aria-label", "aria-pressed"];
|
|
8
|
+
var _hoisted_2 = ["aria-label", "aria-pressed"];
|
|
9
|
+
var _hoisted_3 = ["aria-label", "aria-pressed"];
|
|
10
|
+
var _hoisted_4 = ["aria-label", "aria-pressed"];
|
|
11
11
|
var _hoisted_5 = ["aria-label"];
|
|
12
12
|
var _hoisted_6 = ["aria-selected", "onClick"];
|
|
13
13
|
var FULL_CIRCLE = 360;
|
|
@@ -297,7 +297,8 @@ var RuiTimePicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
297
297
|
}, [createElementVNode("div", { class: normalizeClass(unref(ui).digitalDisplay()) }, [createElementVNode("div", { class: normalizeClass(unref(ui).time()) }, [
|
|
298
298
|
createElementVNode("button", {
|
|
299
299
|
type: "button",
|
|
300
|
-
"
|
|
300
|
+
"data-id": "hour",
|
|
301
|
+
"aria-label": `${formatValue(displayHour.value)} hours`,
|
|
301
302
|
"aria-pressed": editMode.value === "hour",
|
|
302
303
|
class: normalizeClass(unref(ui).digit({ active: editMode.value === "hour" })),
|
|
303
304
|
onClick: _cache[0] || (_cache[0] = ($event) => editMode.value = "hour")
|
|
@@ -305,7 +306,8 @@ var RuiTimePicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
305
306
|
createElementVNode("div", { class: normalizeClass(unref(ui).separator()) }, " : ", 2),
|
|
306
307
|
createElementVNode("button", {
|
|
307
308
|
type: "button",
|
|
308
|
-
"
|
|
309
|
+
"data-id": "minute",
|
|
310
|
+
"aria-label": `${formatValue(selectedMinute.value)} minutes`,
|
|
309
311
|
"aria-pressed": editMode.value === "minute",
|
|
310
312
|
class: normalizeClass(unref(ui).digit({ active: editMode.value === "minute" })),
|
|
311
313
|
onClick: _cache[1] || (_cache[1] = ($event) => editMode.value = "minute")
|
|
@@ -317,7 +319,8 @@ var RuiTimePicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
317
319
|
showSecond.value ? (openBlock(), createElementBlock("button", {
|
|
318
320
|
key: 1,
|
|
319
321
|
type: "button",
|
|
320
|
-
"
|
|
322
|
+
"data-id": "second",
|
|
323
|
+
"aria-label": `${formatValue(selectedSecond.value)} seconds`,
|
|
321
324
|
"aria-pressed": editMode.value === "second",
|
|
322
325
|
class: normalizeClass(unref(ui).digit({ active: editMode.value === "second" })),
|
|
323
326
|
onClick: _cache[2] || (_cache[2] = ($event) => editMode.value = "second")
|
|
@@ -329,7 +332,8 @@ var RuiTimePicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
329
332
|
showMillisecond.value ? (openBlock(), createElementBlock("button", {
|
|
330
333
|
key: 3,
|
|
331
334
|
type: "button",
|
|
332
|
-
"
|
|
335
|
+
"data-id": "millisecond",
|
|
336
|
+
"aria-label": `${formatValue(selectedMillisecond.value, 3)} milliseconds`,
|
|
333
337
|
"aria-pressed": editMode.value === "millisecond",
|
|
334
338
|
class: normalizeClass(unref(ui).digit({
|
|
335
339
|
active: editMode.value === "millisecond",
|
package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTimePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div :class=\"ui.time()\">\n <button\n type=\"button\"\n aria-label=\"Select hours\"\n :aria-pressed=\"editMode === 'hour'\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </button>\n <div :class=\"ui.separator()\">\n :\n </div>\n <button\n type=\"button\"\n aria-label=\"Select minutes\"\n :aria-pressed=\"editMode === 'minute'\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </button>\n <div\n v-if=\"showSecond\"\n :class=\"ui.separator()\"\n >\n :\n </div>\n <button\n v-if=\"showSecond\"\n type=\"button\"\n aria-label=\"Select seconds\"\n :aria-pressed=\"editMode === 'second'\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </button>\n\n <div\n v-if=\"showMillisecond\"\n :class=\"ui.separator({ class: 'text-lg' })\"\n >\n .\n </div>\n\n <button\n v-if=\"showMillisecond\"\n type=\"button\"\n aria-label=\"Select milliseconds\"\n :aria-pressed=\"editMode === 'millisecond'\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: 'text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </button>\n </div>\n <button\n type=\"button\"\n aria-label=\"Toggle AM/PM\"\n :class=\"ui.period()\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </button>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RuiTimePicker.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","_normalizeStyle","_Fragment","_renderList"],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div :class=\"ui.time()\">\n <button\n type=\"button\"\n data-id=\"hour\"\n :aria-label=\"`${formatValue(displayHour)} hours`\"\n :aria-pressed=\"editMode === 'hour'\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </button>\n <div :class=\"ui.separator()\">\n :\n </div>\n <button\n type=\"button\"\n data-id=\"minute\"\n :aria-label=\"`${formatValue(selectedMinute)} minutes`\"\n :aria-pressed=\"editMode === 'minute'\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </button>\n <div\n v-if=\"showSecond\"\n :class=\"ui.separator()\"\n >\n :\n </div>\n <button\n v-if=\"showSecond\"\n type=\"button\"\n data-id=\"second\"\n :aria-label=\"`${formatValue(selectedSecond)} seconds`\"\n :aria-pressed=\"editMode === 'second'\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </button>\n\n <div\n v-if=\"showMillisecond\"\n :class=\"ui.separator({ class: 'text-lg' })\"\n >\n .\n </div>\n\n <button\n v-if=\"showMillisecond\"\n type=\"button\"\n data-id=\"millisecond\"\n :aria-label=\"`${formatValue(selectedMillisecond, 3)} milliseconds`\"\n :aria-pressed=\"editMode === 'millisecond'\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: 'text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </button>\n </div>\n <button\n type=\"button\"\n aria-label=\"Toggle AM/PM\"\n :class=\"ui.period()\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </button>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;AAyBA,IAAM,cAAc;AACpB,IAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAbrB,MAAM,aAAaA,SAA6B,SAAA,YAAmB;EAEnE,MAAM,eAAeA,SAA+B,SAAC,MAAM;EAC3D,MAAM,iBAAiBA,SAA+B,SAAC,QAAQ;EAC/D,MAAM,iBAAiBA,SAA+B,SAAC,QAAQ;EAC/D,MAAM,sBAAsBA,SAA+B,SAAC,aAAa;EACzE,MAAM,WAAWA,SAAgC,SAAC,WAAgC;EAIlF,MAAM,KAAK,iBAAiB;EAK5B,MAAM,oBAAyD;GAC7D,MAAM;GACN,QAAQ;GACR,QAAQ;GACR,aAAa;EACf;EAEA,MAAM,YAAiD;GACrD,MAAM;GACN,QAAQ;GACR,QAAQ;GACR,aAAa;EACf;EAEA,MAAM,aAAa,IAAa,KAAK;EACrC,MAAM,YAAY,eAAoD,WAAW;EAEjF,MAAM,aAAa,eACX,QAAA,aAAa,aAAa,UAAU,QAAA,aAAa,aAAa,WACtE;EACA,MAAM,kBAAkB,eAAwB,QAAA,aAAa,aAAa,WAAW;EAErF,MAAM,SAAS,eACb,UAAU,YAAY,KAAK,IAAI,YAAY,KAAK,eAAe,OAAO,IACxE;EAEA,MAAM,cAAc,eAAmC;GACrD,IAAI,CAAC,UAAU,YAAY,GACzB;GAGF,MAAM,OADY,IAAI,YACT,IAAY;GACzB,OAAO,SAAS,IAAI,eAAe;EACrC,CAAC;EAED,MAAM,cAAc,eAAmC;GACrD,MAAM,OAAO,IAAI,QAAQ;GACzB,IAAI,SAAS,QACX,OAAO,IAAI,WAAW;QAEnB,IAAI,SAAS,UAChB,OAAO,IAAI,cAAc;QAEtB,IAAI,SAAS,UAChB,OAAO,IAAI,cAAc;QAGzB,OAAO,IAAI,mBAAmB;EAElC,CAAC;EAED,MAAM,yBAAyB,eAAwB;GACrD,MAAM,OAAO,IAAI,QAAQ;GACzB,IAAI,SAAS,UAAU,CAAC,UAAU,WAAW,GAC3C,OAAO;QAEJ;IACH,MAAM,WAAW,UAAU;IAE3B,OADc,IAAI,WACX,IAAQ,aAAa;GAC9B;EACF,CAAC;EAED,MAAM,WAAW,gBAA4B;GAC3C,KAAK;GACL,MAAM;GACN,WAAW;EACb,EAAE;EAEF,MAAM,iBAAiB,eAA2B;GAChD,IAAI,CAAC,UAAU,WAAW,GACxB,OAAO,CAAC;GAMV,OAAO;IACL,QAAQ;IACR,KAAK;IACL,MAAM;IACN,iBAAiB;IACjB,WAAW,2BATQ,IAAI,WAEX,KAAgB,cADX,kBAAkB,IAAI,QAAQ,IAQH;IAC5C,QAAQ;GACV;EACF,CAAC;EAED,MAAM,uBAAuB,eAA2B;GACtD,IAAI,CAAC,UAAU,WAAW,GACxB,OAAO,CAAC;GAEV,MAAM,SAAS;GAKf,MAAM,UAJe,IAAI,WAEX,KAAgB,cADX,kBAAkB,IAAI,QAAQ,MAGxB,KAAK,KAAM;GAEpC,MAAM,IAAI,KAAK,WAAW,MAAM,IAAI,KAAK,IAAI,UAAU,KAAK,KAAK,CAAC;GAGlE,OAAO;IACL,UAAU;IACV,KAAK,GAJG,KAAK,WAAW,MAAM,IAAI,KAAK,IAAI,UAAU,KAAK,KAAK,CAAC,EAItD;IACV,MAAM,GAAG,EAAE;IACX,OAAO;IACP,QAAQ;IACR,cAAc;IACd,WAAW;IACX,QAAQ;GACV;EACF,CAAC;EAED,MAAM,eAAe,eAAyB;GAC5C,MAAM,OAAO,IAAI,QAAQ;GACzB,MAAM,WAAW,UAAU;GAC3B,MAAM,QAAQ,kBAAkB;GAChC,MAAM,UAAU,gBAAgB,OAAO,QAAQ;GAC/C,IAAI,SAAS,QACX,QAAQ,KAAK;GAEf,OAAO;EACT,CAAC;EAED,SAAS,gBAAoC;GAC3C,OAAO,UAAU,UAAU,IAAI,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,KAAA;EACxE;EAEA,SAAS,kBAAsC;GAC7C,OAAO,UAAU,UAAU,IAAI,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,WAAW,IAAI,KAAA;EAC1E;EAEA,SAAS,kBAAsC;GAE7C,OAAO,CADmC,aAAa,QAAQ,aAAa,WACrE,CAAA,CAAiB,SAAS,QAAA,QAAQ,KAAK,UAAU,UAAU,IAC9D,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,WAAW,IACrC,KAAA;EACN;EAEA,SAAS,uBAA2C;GAClD,OAAO,QAAA,aAAa,aAAa,eAAe,UAAU,UAAU,IAChE,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,gBAAgB,IAC1C,KAAA;EACN;EAEA,SAAS,gBAAgB,OAAe,UAA4B;GAClE,MAAM,UAAoB,CAAC;GAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK,UAC9B,QAAQ,KAAK,CAAC;GAEhB,OAAO;EACT;EAEA,SAAS,YAAY,OAAgB,UAAU,GAAW;GACxD,OAAO,UAAU,KAAA,IAAY,MAAM,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,IAAI,IAAI,OAAO,OAAO;EAC3F;EAEA,SAAS,YAAY,KAAyB;GAC5C,MAAM,SAAS;GAIf,MAAM,WAFQ,OAAO,cADF,kBAAkB,IAAI,QAAQ,MACA,MAExB,KAAK,KAAM;GACpC,MAAM,IAAI,KAAK,WAAW,MAAM,IAAI,KAAK,IAAI,OAAO;GAGpD,OAAO;IACL,KAAK,GAHG,KAAK,WAAW,MAAM,IAAI,KAAK,IAAI,OAAO,EAGxC;IACV,MAAM,GAAG,EAAE;IACX,WAAW;GACb;EACF;EAEA,SAAS,iBAAiB,KAAsB;GAC9C,IAAI,CAAC,UAAU,WAAW,GACxB,OAAO;GAET,MAAM,OAAO,IAAI,QAAQ;GACzB,IAAI,SAAS,QACX,OAAO,IAAI,WAAW,MAAM;QAEzB;IACH,MAAM,QAAQ,IAAI,WAAW;IAC7B,MAAM,WAAW,UAAU;IAC3B,OAAO,UAAU,OAAQ,QAAQ,aAAa,KAAK,UAAU;GAC/D;EACF;EAEA,SAAS,aAAmB;GAC1B,IAAI,CAAC,UAAU,YAAY,GACzB;GAEF,IAAI,IAAI,YAAY,IAAI,cACtB,IAAI,cAAc,IAAI,YAAY,IAAI,YAAY;QAGlD,IAAI,cAAc,IAAI,YAAY,IAAI,YAAY;GAGpD,iBAAiB;EACnB;EAEA,SAAS,UAAU,OAAsC;GACvD,MAAM,eAAe;GACrB,IAAI,YAAY,IAAI;GAEpB,IAAI,CAAC,UAAU,SAAS,GACtB;GAEF,MAAM,OAAO,IAAI,SAAS,CAAC,CAAC,sBAAsB;GAClD,MAAM,UAAU,KAAK,OAAO,KAAK,QAAQ;GACzC,MAAM,UAAU,KAAK,MAAM,KAAK,SAAS;GACzC,IAAI,QAAuB;GAE3B,MAAM,aAAa,SAAiB,YAA0B;IAC5D,MAAM,IAAI,UAAU;IACpB,MAAM,IAAI,UAAU;IAEpB,IAAI,QAAQ,KAAK,MAAM,GAAG,CAAC,KAAK,MAAM,KAAK,MAAM;IACjD,IAAI,QAAQ,GACV,SAAS;IAEX,MAAM,OAAO,IAAI,QAAQ;IACzB,MAAM,OACJ,KAAK,MAAM,SAAS,cAAc,kBAAkB,MAAM,IAAI,kBAAkB;IAClF,IAAI,SAAS,QAAQ;KACnB,IAAI,OAAO;KACX,IAAI,SAAS,GACX,OAAO;KAET,IAAI,IAAI,MAAM,MAAM,QAAQ,OAAO,cACjC,QAAQ;UAEL,IAAI,IAAI,MAAM,MAAM,QAAQ,SAAS,cACxC,OAAO;KAGT,IAAI,cAAc,IAAI;IACxB,OACK,IAAI,SAAS,UAChB,IAAI,gBAAgB,IAAI;SAErB,IAAI,SAAS,UAChB,IAAI,gBAAgB,IAAI;SAGxB,IAAI,qBAAqB,IAAI;IAG/B,iBAAiB;GACnB;GAEA,MAAM,cAAc,cAA6C;IAC/D,IAAI,CAAC,IAAI,UAAU,GACjB;IAEF,IAAI,UAAU,MACZ;IAEF,IAAI;IACJ,IAAI;IAEJ,IAAI,aAAa,WAAW;KAC1B,MAAM,QAAQ,UAAU,QAAQ;KAChC,OAAO,KAAK;KACZ,UAAU,MAAM;KAChB,UAAU,MAAM;IAClB,OACK;KACH,UAAU,UAAU;KACpB,UAAU,UAAU;IACtB;IAEA,QAAQ,4BAA4B;KAClC,UAAU,SAAS,OAAO;KAC1B,QAAQ;IACV,CAAC;GACH;GAEA,MAAM,kBAAwB;IAC5B,IAAI,UAAU,MAAM;KAClB,qBAAqB,KAAK;KAC1B,QAAQ;IACV;IACA,IAAI,YAAY,KAAK;IACrB,SAAS,oBAAoB,aAAa,UAAU;IACpD,SAAS,oBAAoB,aAAa,UAAU;IACpD,SAAS,oBAAoB,WAAW,SAAS;IACjD,SAAS,oBAAoB,YAAY,SAAS;IAElD,IAAI,IAAI,QAAQ,MAAM,QACpB,IAAI,UAAU,QAAQ;SAEnB,IAAI,IAAI,UAAU,KAAK,IAAI,QAAQ,MAAM,UAC5C,IAAI,UAAU,QAAQ;SAEnB,IAAI,IAAI,eAAe,KAAK,IAAI,QAAQ,MAAM,UACjD,IAAI,UAAU,aAAa;GAE/B;GAEA,SAAS,iBAAiB,aAAa,UAAU;GACjD,SAAS,iBAAiB,aAAa,UAAU;GACjD,SAAS,iBAAiB,WAAW,SAAS;GAC9C,SAAS,iBAAiB,YAAY,SAAS;GAG/C,MAAM,eAAe;GACrB,IAAI;GACJ,IAAI;GACJ,IAAI,aAAa,cAAc;IAC7B,MAAM,QAAQ,aAAa,QAAQ;IACnC,OAAO,KAAK;IACZ,UAAU,MAAM;IAChB,UAAU,MAAM;GAClB,OACK;IACH,UAAU,aAAa;IACvB,UAAU,aAAa;GACzB;GACA,UAAU,SAAS,OAAO;EAC5B;EAEA,SAAS,cAAc,KAAmB;GACxC,MAAM,OAAO,IAAI,QAAQ;GACzB,IAAI,SAAS,QAAQ;IACnB,IAAI,UAAU;IAEd,IAAI,IAAI,MAAM,MAAM,QAAQ,UAAU,cACpC,WAAW;IAGb,IAAI,cAAc,OAAO;IACzB,IAAI,UAAU,QAAQ;GACxB,OACK,IAAI,SAAS,UAAU;IAC1B,IAAI,gBAAgB,GAAG;IACvB,IAAI,IAAI,UAAU,GAChB,IAAI,UAAU,QAAQ;GAC1B,OACK,IAAI,SAAS,UAAU;IAC1B,IAAI,gBAAgB,GAAG;IACvB,IAAI,IAAI,eAAe,GACrB,IAAI,UAAU,aAAa;GAE/B,OACK,IAAI,SAAS,eAChB,IAAI,qBAAqB,GAAG;GAG9B,iBAAiB;EACnB;EAEA,SAAS,mBAAyB;GAChC,IAAI,EAAE,UAAU,YAAY,KAAK,UAAU,cAAc,IACvD;GAEF,eAAe;IACb,MAAM,OAAO,UAAU,UAAU,IAAI,IAAI,KAAK,IAAI,UAAU,CAAC,oBAAI,IAAI,KAAK;IAC1E,KAAK,SAAS,IAAI,YAAY,CAAC;IAC/B,KAAK,WAAW,IAAI,cAAc,CAAC;IACnC,KAAK,WAAW,IAAI,cAAc,KAAK,CAAC;IACxC,KAAK,gBAAgB,IAAI,mBAAmB,KAAK,CAAC;IAClD,IAAI,YAAY,IAAI;GACtB,CAAC;EACH;EAEA,MACE,kBACM;GACJ,IAAI,cAAc,cAAc,CAAC;GACjC,IAAI,gBAAgB,gBAAgB,CAAC;GACrC,IAAI,gBAAgB,gBAAgB,CAAC;GACrC,IAAI,qBAAqB,qBAAqB,CAAC;EACjD,CACF;EAEA,gBAAgB;GACd,IAAI,cAAc,cAAc,CAAC;GACjC,IAAI,gBAAgB,gBAAgB,CAAC;GACrC,IAAI,gBAAgB,gBAAgB,CAAC;GACrC,IAAI,qBAAqB,qBAAqB,CAAC;EACjD,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBAoHM,OAAA;IAnHJ,MAAK;IACL,cAAW;IACV,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,KAAI,EAAA,UAAA,CAAc,QAAA,WAAU,CAAA,CAAA;GAEvCC,GAAAA,CAAAA,mBAsEM,OAAA,EAtEA,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,eAAc,CAAA,EAAA,GAAA,CAC5BC,mBA4DM,OAAA,EA5DA,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA,EAAA,GAAA;IAClBC,mBASS,UAAA;KARP,MAAK;KACL,WAAQ;KACP,cAAU,GAAK,YAAY,YAAA,KAAW,EAAA;KACtC,gBAAc,SAAA,UAAQ;KACtB,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,MAAK,EAAA,QAAW,SAAA,UAAQ,OAAA,CAAA,CAAA;KAClC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,SAAA,QAAQ;IAEb,GAAAE,gBAAA,YAAY,YAAA,KAAW,CAAA,GAAA,IAAA,UAAA;IAE5BD,mBAEM,OAAA,EAFA,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA,EAAI,GAAA,OAE7B,CAAA;IACAC,mBASS,UAAA;KARP,MAAK;KACL,WAAQ;KACP,cAAU,GAAK,YAAY,eAAA,KAAc,EAAA;KACzC,gBAAc,SAAA,UAAQ;KACtB,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,MAAK,EAAA,QAAW,SAAA,UAAQ,SAAA,CAAA,CAAA;KAClC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,SAAA,QAAQ;IAEb,GAAAE,gBAAA,YAAY,eAAA,KAAc,CAAA,GAAA,IAAA,UAAA;IAGvB,WAAA,SADRL,UAAA,GAAAC,mBAKM,OAAA;;KAHH,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA;IACrB,GAAA,OAED,CAAA,KAAA,mBAAA,IAAA,IAAA;IAEQ,WAAA,SADRH,UAAA,GAAAC,mBAUS,UAAA;;KARP,MAAK;KACL,WAAQ;KACP,cAAU,GAAK,YAAY,eAAA,KAAc,EAAA;KACzC,gBAAc,SAAA,UAAQ;KACtB,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,MAAK,EAAA,QAAW,SAAA,UAAQ,SAAA,CAAA,CAAA;KAClC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,SAAA,QAAQ;IAEb,GAAAE,gBAAA,YAAY,eAAA,KAAc,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;IAIvB,gBAAA,SADRL,UAAA,GAAAC,mBAKM,OAAA;;KAHH,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,EAAA,OAAA,UAAA,CAAA,CAAA;IACrB,GAAA,OAED,CAAA,KAAA,mBAAA,IAAA,IAAA;IAGQ,gBAAA,SADRH,UAAA,GAAAC,mBAUS,UAAA;;KARP,MAAK;KACL,WAAQ;KACP,cAAU,GAAK,YAAY,oBAAA,OAAmB,CAAA,EAAA;KAC9C,gBAAc,SAAA,UAAQ;KACtB,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,MAAK;MAAA,QAAW,SAAA,UAAQ;MAAA,OAAA;KAAA,CAAA,CAAA;KAClC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,SAAA,QAAQ;IAEb,GAAAE,gBAAA,YAAY,oBAAA,OAAmB,CAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;GAGtCD,GAAAA,CAAAA,GAAAA,mBAOS,UAAA;IANP,MAAK;IACL,cAAW;IACV,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,OAAM,CAAA;IAChB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,WAAU;GAEf,GAAAE,gBAAA,OAAA,KAAM,GAAA,CAAA,CAAA,GAAA,CAAA,GAIbD,mBAsCM,OAAA;IArCA,SAAA;IAAJ,KAAI;IACJ,MAAK;IACJ,cAAU,UAAY,SAAA;IACtB,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA;IACnB,aAAS,OAAA,OAAA,OAAA,MAAA,WAAE,UAAU,MAAM;IAC3B,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,UAAU,MAAM;;IAE7BC,mBAGE,OAAA;KAFC,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA;KACnB,OAAKI,eAAE,SAAA,KAAQ;;IAGlBH,mBAGE,OAAA;KAFC,OAAKF,eAAEC,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA;KACnB,OAAKI,eAAE,eAAA,KAAc;;IAIhB,uBAAA,SADRP,UAAA,GAAAC,mBAIE,OAAA;;KAFC,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,gBAAe,CAAA;KACzB,OAAKI,eAAE,qBAAA,KAAoB;;KAG9BP,UAAA,IAAA,GAAAC,mBAaMO,UAAA,MAAAC,WAZU,aAAA,QAAP,QAAG;KADZ,OAAAT,UAAA,GAAAC,mBAaM,OAAA;MAXH,KAAG,OAAS;MACb,MAAK;MACJ,iBAAe,iBAAiB,GAAG;MACnC,OAAKC,eAAA,CAAcC,MAAA,EAAA,CAAE,CAAC,YAAW,EAAA,UAAa,iBAAiB,GAAG,EAAA,CAAA,GAAuB,OAAA,SAAA,MAAQ,GAAI,IAAI,SAAQ,CAAA,CAAG,SAAQ,GAAA,GAAA,GAAA,CAAA;MAI5H,OAAKI,eAAE,YAAY,GAAG,CAAA;MACtB,UAAK,WAAE,cAAc,GAAG;KAEtB,GAAAF,gBAAA,GAAG,GAAA,IAAA,UAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MaybeElement } from '../types/dom';
|
|
1
|
+
import type { MaybeElement } from '../types/dom.js';
|
|
2
2
|
import { type VirtualElement as FloatingVirtualElement } from '@floating-ui/dom';
|
|
3
3
|
import { type MaybeRefOrGetter, type Ref } from 'vue';
|
|
4
4
|
type VirtualElement = FloatingVirtualElement;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LuArrowDown, LuArrowLeft, LuArrowRight, LuArrowUp, LuCheck,
|
|
1
|
+
import { LuArrowDown, LuArrowLeft, LuArrowRight, LuArrowUp, LuCheck, LuChevronDown, LuChevronLeft, LuChevronRight, LuChevronUp, LuChevronsLeft, LuChevronsRight, LuChevronsUpDown, LuCircleAlert, LuCircleCheck, LuCircleX, LuClock } from "../icons/icons_1.js";
|
|
2
2
|
import { LuEllipsis, LuEye, LuEyeOff, LuInfo } from "../icons/icons_2.js";
|
|
3
3
|
import { LuTriangleAlert, LuX } from "../icons/icons_4.js";
|
|
4
4
|
import { assert } from "../utils/assert.js";
|
|
@@ -26,12 +26,6 @@ var requiredIcons = [
|
|
|
26
26
|
LuCheck,
|
|
27
27
|
LuCircleX,
|
|
28
28
|
LuCircleCheck,
|
|
29
|
-
LuCheckboxBlank,
|
|
30
|
-
LuCheckboxFill,
|
|
31
|
-
LuCheckboxIndeterminateFill,
|
|
32
|
-
LuCheckboxBlankCircle,
|
|
33
|
-
LuCheckboxBlankCircleFill,
|
|
34
|
-
LuRadioButtonFill,
|
|
35
29
|
LuClock
|
|
36
30
|
];
|
|
37
31
|
var IconsSymbol = Symbol.for("rui:icons");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","names":[],"sources":["../../src/composables/icons.ts"],"sourcesContent":["import type { InjectionKey } from 'vue';\nimport type { GeneratedIcon } from '@/types/icons';\nimport {\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuArrowUp,\n LuCheck,\n
|
|
1
|
+
{"version":3,"file":"icons.js","names":[],"sources":["../../src/composables/icons.ts"],"sourcesContent":["import type { InjectionKey } from 'vue';\nimport type { GeneratedIcon } from '@/types/icons';\nimport {\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuArrowUp,\n LuCheck,\n LuChevronDown,\n LuChevronLeft,\n LuChevronRight,\n LuChevronsLeft,\n LuChevronsRight,\n LuChevronsUpDown,\n LuChevronUp,\n LuCircleAlert,\n LuCircleCheck,\n LuCircleX,\n LuClock,\n LuEllipsis,\n LuEye,\n LuEyeOff,\n LuInfo,\n LuTriangleAlert,\n LuX,\n} from '@/icons';\nimport { assert } from '@/utils/assert';\n\nconst requiredIcons: GeneratedIcon[] = [\n LuChevronsUpDown,\n LuEllipsis,\n LuTriangleAlert,\n LuX,\n LuInfo,\n LuArrowUp,\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuChevronUp,\n LuChevronDown,\n LuChevronLeft,\n LuChevronRight,\n LuChevronsLeft,\n LuChevronsRight,\n LuCircleAlert,\n LuEye,\n LuEyeOff,\n LuCheck,\n LuCircleX,\n LuCircleCheck,\n LuClock,\n];\n\nexport interface IconsOptions {\n registeredIcons: GeneratedIcon[];\n}\n\nexport interface UseIconsReturn {\n registeredIcons: Readonly<Record<string, [string, Record<string, string>][]>>;\n}\n\nexport const IconsSymbol: InjectionKey<UseIconsReturn> = Symbol.for('rui:icons');\n\nexport function createIconDefaults(options?: Partial<IconsOptions>): UseIconsReturn {\n const iconsToAdd = options?.registeredIcons || [];\n return {\n registeredIcons: {\n ...Object.fromEntries(\n [\n ...requiredIcons,\n ...iconsToAdd,\n ].map(({ components, name }) => [name, components]),\n ),\n },\n };\n}\n\nexport function useIcons(): UseIconsReturn {\n const icons = inject(IconsSymbol);\n assert(icons, 'Could not find icons injection');\n return icons;\n}\n"],"mappings":";;;;;;AA4BA,IAAM,gBAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAUA,IAAa,cAA4C,OAAO,IAAI,WAAW;AAE/E,SAAgB,mBAAmB,SAAiD;CAClF,MAAM,aAAa,SAAS,mBAAmB,CAAC;CAChD,OAAO,EACL,iBAAiB,EACf,GAAG,OAAO,YACR,CACE,GAAG,eACH,GAAG,UACL,CAAC,CAAC,KAAK,EAAE,YAAY,WAAW,CAAC,MAAM,UAAU,CAAC,CACpD,EACF,EACF;AACF;AAEA,SAAgB,WAA2B;CACzC,MAAM,QAAQ,OAAO,WAAW;CAChC,OAAO,OAAO,gCAAgC;CAC9C,OAAO;AACT"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
-
import type { TableColumn, TableRowKey } from '../../../components/tables/RuiTableHead.vue';
|
|
2
|
+
import type { TableColumn, TableRowKey } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
3
|
export interface UseTableColumnsOptions<T extends object, IdType extends keyof T> {
|
|
4
4
|
/** Column definitions for the table. When omitted, columns are inferred from row data. */
|
|
5
5
|
cols: MaybeRefOrGetter<TableColumn<T>[] | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComputedRef, Ref } from 'vue';
|
|
2
|
-
import type { TableRowKey, TableRowKeyData } from '../../../components/tables/RuiTableHead.vue';
|
|
2
|
+
import type { TableRowKey, TableRowKeyData } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
3
|
import { type GroupedTableRow } from './types.js';
|
|
4
4
|
export interface UseTableGroupingOptions<T extends object, IdType extends keyof T> {
|
|
5
5
|
/** The property on each row used as the unique row identifier. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
-
import type { MaybeElementRef } from '../../../types/dom';
|
|
2
|
+
import type { MaybeElementRef } from '../../../types/dom.js';
|
|
3
3
|
export interface UsePageScrollReturn {
|
|
4
4
|
/** Scroll the table's top into view, if it has scrolled above the visible area. */
|
|
5
5
|
revealTableTop: () => Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComputedRef, DeepReadonly, Ref, ShallowRef } from 'vue';
|
|
2
|
-
import type { TableSortData } from '../../../components/tables/RuiTableHead.vue';
|
|
3
|
-
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue';
|
|
2
|
+
import type { TableSortData } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
|
+
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue.js';
|
|
4
4
|
import type { TableOptions as TableDefaultOptions } from '../../defaults/table.js';
|
|
5
5
|
import { type GroupedTableRow } from './types.js';
|
|
6
6
|
export interface UseTablePaginationOptions {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
-
import type { SortColumn, TableRowKey, TableSortData } from '../../../components/tables/RuiTableHead.vue';
|
|
3
|
-
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue';
|
|
2
|
+
import type { SortColumn, TableRowKey, TableSortData } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
|
+
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue.js';
|
|
4
4
|
import { SortDirection } from '../../../components/tables/table-props.js';
|
|
5
5
|
export interface UseTableSortOptions<T extends object> {
|
|
6
6
|
/** The data rows to sort. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TableSortData } from '../../../components/tables/RuiTableHead.vue';
|
|
2
|
-
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue';
|
|
1
|
+
import type { TableSortData } from '../../../components/tables/RuiTableHead.vue.js';
|
|
2
|
+
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue.js';
|
|
3
3
|
export interface TableOptions<T> {
|
|
4
4
|
pagination?: TablePaginationData;
|
|
5
5
|
sort?: TableSortData<T>;
|
package/dist/i18n/keys.d.ts
CHANGED
|
@@ -12,6 +12,15 @@ export declare const RUI_I18N_KEYS: {
|
|
|
12
12
|
readonly pasteUnreadable: "rui.date_time_picker.paste_unreadable";
|
|
13
13
|
readonly today: "rui.date_time_picker.today";
|
|
14
14
|
};
|
|
15
|
+
readonly fileUpload: {
|
|
16
|
+
readonly clickToUpload: "rui.file_upload.click_to_upload";
|
|
17
|
+
readonly dropPrefix: "rui.file_upload.drop_prefix";
|
|
18
|
+
readonly remove: "rui.file_upload.remove";
|
|
19
|
+
readonly replace: "rui.file_upload.replace";
|
|
20
|
+
readonly tooLarge: "rui.file_upload.too_large";
|
|
21
|
+
readonly tooMany: "rui.file_upload.too_many";
|
|
22
|
+
readonly wrongType: "rui.file_upload.wrong_type";
|
|
23
|
+
};
|
|
15
24
|
readonly timezoneSelect: {
|
|
16
25
|
readonly label: "rui.timezone_select.label";
|
|
17
26
|
};
|
package/dist/i18n/keys.js
CHANGED
|
@@ -13,6 +13,15 @@ var RUI_I18N_KEYS = {
|
|
|
13
13
|
pasteUnreadable: "rui.date_time_picker.paste_unreadable",
|
|
14
14
|
today: "rui.date_time_picker.today"
|
|
15
15
|
},
|
|
16
|
+
fileUpload: {
|
|
17
|
+
clickToUpload: "rui.file_upload.click_to_upload",
|
|
18
|
+
dropPrefix: "rui.file_upload.drop_prefix",
|
|
19
|
+
remove: "rui.file_upload.remove",
|
|
20
|
+
replace: "rui.file_upload.replace",
|
|
21
|
+
tooLarge: "rui.file_upload.too_large",
|
|
22
|
+
tooMany: "rui.file_upload.too_many",
|
|
23
|
+
wrongType: "rui.file_upload.wrong_type"
|
|
24
|
+
},
|
|
16
25
|
timezoneSelect: { label: "rui.timezone_select.label" }
|
|
17
26
|
};
|
|
18
27
|
function flattenKeys(obj) {
|
package/dist/i18n/keys.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","names":[],"sources":["../../src/i18n/keys.ts"],"sourcesContent":["export const RUI_I18N_KEYS = {\n dateTimePicker: {\n clear: 'rui.date_time_picker.clear',\n clearValue: 'rui.date_time_picker.clear_value',\n closeCalendar: 'rui.date_time_picker.close_calendar',\n dateAfterMax: 'rui.date_time_picker.date_after_max',\n dateBeforeMin: 'rui.date_time_picker.date_before_min',\n dateInFuture: 'rui.date_time_picker.date_in_future',\n label: 'rui.date_time_picker.label',\n now: 'rui.date_time_picker.now',\n openCalendar: 'rui.date_time_picker.open_calendar',\n pasteUnreadable: 'rui.date_time_picker.paste_unreadable',\n today: 'rui.date_time_picker.today',\n },\n timezoneSelect: {\n label: 'rui.timezone_select.label',\n },\n} as const;\n\nfunction flattenKeys(obj: Record<string, any>): string[] {\n return Object.values(obj).flatMap(value =>\n typeof value === 'string' ? [value] : flattenKeys(value),\n );\n}\n\n/**\n * Retrieves all translation keys available in the library.\n *\n * @returns the flattened translation keys\n */\nexport function translationKeys(): string[] {\n return flattenKeys(RUI_I18N_KEYS);\n}\n"],"mappings":";AAAA,IAAa,gBAAgB;CAC3B,gBAAgB;EACd,OAAO;EACP,YAAY;EACZ,eAAe;EACf,cAAc;EACd,eAAe;EACf,cAAc;EACd,OAAO;EACP,KAAK;EACL,cAAc;EACd,iBAAiB;EACjB,OAAO;CACT;CACA,gBAAgB,EACd,OAAO,4BACT;AACF;AAEA,SAAS,YAAY,KAAoC;CACvD,OAAO,OAAO,OAAO,GAAG,CAAC,CAAC,SAAQ,UAChC,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,YAAY,KAAK,CACzD;AACF;;;;;;AAOA,SAAgB,kBAA4B;CAC1C,OAAO,YAAY,aAAa;AAClC"}
|
|
1
|
+
{"version":3,"file":"keys.js","names":[],"sources":["../../src/i18n/keys.ts"],"sourcesContent":["export const RUI_I18N_KEYS = {\n dateTimePicker: {\n clear: 'rui.date_time_picker.clear',\n clearValue: 'rui.date_time_picker.clear_value',\n closeCalendar: 'rui.date_time_picker.close_calendar',\n dateAfterMax: 'rui.date_time_picker.date_after_max',\n dateBeforeMin: 'rui.date_time_picker.date_before_min',\n dateInFuture: 'rui.date_time_picker.date_in_future',\n label: 'rui.date_time_picker.label',\n now: 'rui.date_time_picker.now',\n openCalendar: 'rui.date_time_picker.open_calendar',\n pasteUnreadable: 'rui.date_time_picker.paste_unreadable',\n today: 'rui.date_time_picker.today',\n },\n fileUpload: {\n clickToUpload: 'rui.file_upload.click_to_upload',\n dropPrefix: 'rui.file_upload.drop_prefix',\n remove: 'rui.file_upload.remove',\n replace: 'rui.file_upload.replace',\n tooLarge: 'rui.file_upload.too_large',\n tooMany: 'rui.file_upload.too_many',\n wrongType: 'rui.file_upload.wrong_type',\n },\n timezoneSelect: {\n label: 'rui.timezone_select.label',\n },\n} as const;\n\nfunction flattenKeys(obj: Record<string, any>): string[] {\n return Object.values(obj).flatMap(value =>\n typeof value === 'string' ? [value] : flattenKeys(value),\n );\n}\n\n/**\n * Retrieves all translation keys available in the library.\n *\n * @returns the flattened translation keys\n */\nexport function translationKeys(): string[] {\n return flattenKeys(RUI_I18N_KEYS);\n}\n"],"mappings":";AAAA,IAAa,gBAAgB;CAC3B,gBAAgB;EACd,OAAO;EACP,YAAY;EACZ,eAAe;EACf,cAAc;EACd,eAAe;EACf,cAAc;EACd,OAAO;EACP,KAAK;EACL,cAAc;EACd,iBAAiB;EACjB,OAAO;CACT;CACA,YAAY;EACV,eAAe;EACf,YAAY;EACZ,QAAQ;EACR,SAAS;EACT,UAAU;EACV,SAAS;EACT,WAAW;CACb;CACA,gBAAgB,EACd,OAAO,4BACT;AACF;AAEA,SAAS,YAAY,KAAoC;CACvD,OAAO,OAAO,OAAO,GAAG,CAAC,CAAC,SAAQ,UAChC,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,YAAY,KAAK,CACzD;AACF;;;;;;AAOA,SAAgB,kBAA4B;CAC1C,OAAO,YAAY,aAAa;AAClC"}
|