dxd-style-code 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dxd-style-code.js +11974 -3725
- package/dist/dxd-style-code.umd.cjs +10 -1
- package/dist/style.css +1 -1
- package/package.json +14 -6
- package/src/components/atoms/DXAvatar/DXAvatar.stories.js +319 -0
- package/src/components/atoms/DXAvatar/DXAvatar.vue +167 -0
- package/src/components/atoms/DXAvatar/index.js +2 -0
- package/src/components/atoms/DXBackdrop/DXBackdrop.stories.js +341 -0
- package/src/components/atoms/DXBackdrop/DXBackdrop.vue +102 -0
- package/src/components/atoms/DXBackdrop/index.js +2 -0
- package/src/components/atoms/DXBadge/DXBadge.stories.js +239 -0
- package/src/components/atoms/DXBadge/DXBadge.vue +45 -0
- package/src/components/atoms/DXBadge/index.js +2 -0
- package/src/components/atoms/DXButton/DXButton.stories.js +178 -0
- package/src/components/atoms/DXButton/DXButton.vue +84 -0
- package/src/components/atoms/DXButton/index.js +2 -0
- package/src/components/atoms/DXCard/DXCard.stories.js +133 -0
- package/src/components/atoms/DXCard/DXCard.vue +46 -0
- package/src/components/atoms/DXCard/index.js +2 -0
- package/src/components/atoms/DXCheckbox/DXCheckbox.stories.js +294 -0
- package/src/components/atoms/DXCheckbox/DXCheckbox.vue +191 -0
- package/src/components/atoms/DXCheckbox/index.js +2 -0
- package/src/components/atoms/DXDivider/DXDivider.stories.js +135 -0
- package/src/components/atoms/DXDivider/DXDivider.vue +74 -0
- package/src/components/atoms/DXDivider/index.js +2 -0
- package/src/components/atoms/DXDropdownItem/DXDropdownItem.vue +116 -0
- package/src/components/atoms/DXDropdownItem/index.js +2 -0
- package/src/components/atoms/DXFormLabel/DXFormLabel.stories.js +194 -0
- package/src/components/atoms/DXFormLabel/DXFormLabel.vue +94 -0
- package/src/components/atoms/DXFormLabel/index.js +2 -0
- package/src/components/atoms/DXIcon/DXIcon.stories.js +156 -0
- package/src/components/atoms/DXIcon/DXIcon.vue +102 -0
- package/src/components/atoms/DXIcon/index.js +3 -0
- package/src/components/atoms/DXIconWrapper/DXIconWrapper.stories.js +237 -0
- package/src/components/atoms/DXIconWrapper/DXIconWrapper.vue +79 -0
- package/src/components/atoms/DXIconWrapper/index.js +2 -0
- package/src/components/atoms/DXInputAddon/DXInputAddon.stories.js +230 -0
- package/src/components/atoms/DXInputAddon/DXInputAddon.vue +64 -0
- package/src/components/atoms/DXInputAddon/index.js +2 -0
- package/src/components/atoms/DXLink/DXLink.stories.js +475 -0
- package/src/components/atoms/DXLink/DXLink.vue +229 -0
- package/src/components/atoms/DXLink/index.js +2 -0
- package/src/components/atoms/DXLoader/DXLoader.stories.js +280 -0
- package/src/components/atoms/DXLoader/DXLoader.vue +78 -0
- package/src/components/atoms/DXLoader/index.js +2 -0
- package/src/components/atoms/DXProgress/DXProgress.stories.js +312 -0
- package/src/components/atoms/DXProgress/DXProgress.vue +85 -0
- package/src/components/atoms/DXProgress/index.js +2 -0
- package/src/components/atoms/DXQuote/DXQuote.stories.js +255 -0
- package/src/components/atoms/DXQuote/DXQuote.vue +97 -0
- package/src/components/atoms/DXQuote/index.js +2 -0
- package/src/components/atoms/DXRadio/DXRadio.stories.js +277 -0
- package/src/components/atoms/DXRadio/DXRadio.vue +144 -0
- package/src/components/atoms/DXRadio/index.js +2 -0
- package/src/components/atoms/DXSkeleton/DXSkeleton.stories.js +50 -0
- package/src/components/atoms/DXSkeleton/DXSkeleton.vue +19 -0
- package/src/components/atoms/DXSkeleton/index.js +2 -0
- package/src/components/atoms/DXSlider/DXSlider.stories.js +522 -0
- package/src/components/atoms/DXSlider/DXSlider.vue +338 -0
- package/src/components/atoms/DXSlider/index.js +2 -0
- package/src/components/atoms/DXTags/DXTags.stories.js +206 -0
- package/src/components/atoms/DXTags/DXTags.vue +111 -0
- package/src/components/atoms/DXTags/index.js +2 -0
- package/src/components/atoms/DXToast/DXToast.stories.js +40 -0
- package/src/components/atoms/DXToast/DXToast.vue +32 -0
- package/src/components/atoms/DXToast/index.js +2 -0
- package/src/components/atoms/DXToggle/DXToggle.stories.js +143 -0
- package/src/components/atoms/DXToggle/DXToggle.vue +142 -0
- package/src/components/atoms/DXToggle/index.js +2 -0
- package/src/components/atoms/DXToggleButton/DXToggleButton.stories.js +513 -0
- package/src/components/atoms/DXToggleButton/DXToggleButton.vue +140 -0
- package/src/components/atoms/DXToggleButton/index.js +2 -0
- package/src/components/atoms/DXTooltip/DXTooltip.stories.js +243 -0
- package/src/components/atoms/DXTooltip/DXTooltip.vue +151 -0
- package/src/components/atoms/DXTooltip/index.js +2 -0
- package/src/components/atoms/index.js +24 -0
- package/src/components/index.js +20 -0
- package/src/components/layout/DXBox/DXBox.stories.js +238 -0
- package/src/components/layout/DXBox/DXBox.vue +198 -0
- package/src/components/layout/DXBox/index.js +2 -0
- package/src/components/layout/DXContainer/DXContainer.stories.js +147 -0
- package/src/components/layout/DXContainer/DXContainer.vue +83 -0
- package/src/components/layout/DXContainer/index.js +2 -0
- package/src/components/layout/DXFlex/DXFlex.stories.js +210 -0
- package/src/components/layout/DXFlex/DXFlex.vue +149 -0
- package/src/components/layout/DXFlex/index.js +2 -0
- package/src/components/layout/DXGrid/DXGrid.stories.js +238 -0
- package/src/components/layout/DXGrid/DXGrid.vue +167 -0
- package/src/components/layout/DXGrid/index.js +2 -0
- package/src/components/layout/DXSpacer/DXSpacer.stories.js +187 -0
- package/src/components/layout/DXSpacer/DXSpacer.vue +102 -0
- package/src/components/layout/DXSpacer/index.js +2 -0
- package/src/components/layout/DXStack/DXStack.stories.js +199 -0
- package/src/components/layout/DXStack/DXStack.vue +140 -0
- package/src/components/layout/DXStack/index.js +2 -0
- package/src/components/layout/index.js +8 -0
- package/src/components/molecules/DXActionButtons/DXActionButtons.stories.js +288 -0
- package/src/components/molecules/DXActionButtons/DXActionButtons.vue +106 -0
- package/src/components/molecules/DXActionButtons/index.js +2 -0
- package/src/components/molecules/DXAlert/DXAlert.stories.js +70 -0
- package/src/components/molecules/DXAlert/DXAlert.vue +116 -0
- package/src/components/molecules/DXAlert/index.js +2 -0
- package/src/components/molecules/DXBaseTable/DXBaseTable.stories.js +433 -0
- package/src/components/molecules/DXBaseTable/DXBaseTable.vue +459 -0
- package/src/components/molecules/DXBaseTable/index.js +4 -0
- package/src/components/molecules/DXBreadcrumb/DXBreadcrumb.stories.js +227 -0
- package/src/components/molecules/DXBreadcrumb/DXBreadcrumb.vue +96 -0
- package/src/components/molecules/DXBreadcrumb/index.js +2 -0
- package/src/components/molecules/DXButtonGroup/DXButtonGroup.stories.js +26 -0
- package/src/components/molecules/DXButtonGroup/DXButtonGroup.vue +78 -0
- package/src/components/molecules/DXButtonGroup/index.js +2 -0
- package/src/components/molecules/DXCloseButton/DXCloseButton.stories.js +53 -0
- package/src/components/molecules/DXCloseButton/DXCloseButton.vue +62 -0
- package/src/components/molecules/DXCloseButton/index.js +3 -0
- package/src/components/molecules/DXComboBox/DXComboBox.stories.js +62 -0
- package/src/components/molecules/DXComboBox/DXComboBox.vue +167 -0
- package/src/components/molecules/DXComboBox/index.js +2 -0
- package/src/components/molecules/DXCopyField/DXCopyField.stories.js +231 -0
- package/src/components/molecules/DXCopyField/DXCopyField.vue +75 -0
- package/src/components/molecules/DXCopyField/index.js +2 -0
- package/src/components/molecules/DXDataFilter/DXDataFilter.stories.js +275 -0
- package/src/components/molecules/DXDataFilter/DXDataFilter.vue +385 -0
- package/src/components/molecules/DXDataFilter/index.js +2 -0
- package/src/components/molecules/DXDatePicker/DXDatePicker.stories.js +42 -0
- package/src/components/molecules/DXDatePicker/DXDatePicker.vue +121 -0
- package/src/components/molecules/DXDatePicker/index.js +2 -0
- package/src/components/molecules/DXDropdownDivider/DXDropdownDivider.vue +30 -0
- package/src/components/molecules/DXDropdownDivider/index.js +2 -0
- package/src/components/molecules/DXFileUpload/DXFileUpload.stories.js +53 -0
- package/src/components/molecules/DXFileUpload/DXFileUpload.vue +199 -0
- package/src/components/molecules/DXFileUpload/index.js +2 -0
- package/src/components/molecules/DXFilterGroup/DXFilterGroup.stories.js +43 -0
- package/src/components/molecules/DXFilterGroup/DXFilterGroup.vue +43 -0
- package/src/components/molecules/DXFilterGroup/index.js +2 -0
- package/src/components/molecules/DXFormControl/DXFormControl.stories.js +69 -0
- package/src/components/molecules/DXFormControl/DXFormControl.vue +72 -0
- package/src/components/molecules/DXFormControl/index.js +2 -0
- package/src/components/molecules/DXInput/DXInput.stories.js +291 -0
- package/src/components/molecules/DXInput/DXInput.vue +156 -0
- package/src/components/molecules/DXInput/index.js +3 -0
- package/src/components/molecules/DXInputGroup/DXInputGroup.stories.js +228 -0
- package/src/components/molecules/DXInputGroup/DXInputGroup.vue +64 -0
- package/src/components/molecules/DXInputGroup/index.js +2 -0
- package/src/components/molecules/DXInputMask/DXInputMask.stories.js +53 -0
- package/src/components/molecules/DXInputMask/DXInputMask.vue +89 -0
- package/src/components/molecules/DXInputMask/index.js +2 -0
- package/src/components/molecules/DXMenu/DXMenu.stories.js +379 -0
- package/src/components/molecules/DXMenu/DXMenu.vue +331 -0
- package/src/components/molecules/DXMenu/README.md +479 -0
- package/src/components/molecules/DXMenu/index.js +2 -0
- package/src/components/molecules/DXPagination/DXPagination.stories.js +62 -0
- package/src/components/molecules/DXPagination/DXPagination.vue +123 -0
- package/src/components/molecules/DXPagination/index.js +2 -0
- package/src/components/molecules/DXPasswordInput/DXPasswordInput.stories.js +42 -0
- package/src/components/molecules/DXPasswordInput/DXPasswordInput.vue +74 -0
- package/src/components/molecules/DXPasswordInput/index.js +2 -0
- package/src/components/molecules/DXRadioCard/DXRadioCard.stories.js +60 -0
- package/src/components/molecules/DXRadioCard/DXRadioCard.vue +71 -0
- package/src/components/molecules/DXRadioCard/index.js +2 -0
- package/src/components/molecules/DXRadioGroup/DXRadioGroup.stories.js +297 -0
- package/src/components/molecules/DXRadioGroup/DXRadioGroup.vue +73 -0
- package/src/components/molecules/DXRadioGroup/index.js +2 -0
- package/src/components/molecules/DXRating/DXRating.stories.js +322 -0
- package/src/components/molecules/DXRating/DXRating.vue +402 -0
- package/src/components/molecules/DXRating/index.js +2 -0
- package/src/components/molecules/DXSearchBar/DXSearchBar.stories.js +357 -0
- package/src/components/molecules/DXSearchBar/DXSearchBar.vue +525 -0
- package/src/components/molecules/DXSearchBar/index.js +2 -0
- package/src/components/molecules/DXSearchSelect/DXSearchSelect.stories.js +50 -0
- package/src/components/molecules/DXSearchSelect/DXSearchSelect.vue +207 -0
- package/src/components/molecules/DXSearchSelect/index.js +2 -0
- package/src/components/molecules/DXSegmentedControl/DXSegmentedControl.stories.js +326 -0
- package/src/components/molecules/DXSegmentedControl/DXSegmentedControl.vue +116 -0
- package/src/components/molecules/DXSegmentedControl/index.js +2 -0
- package/src/components/molecules/DXSelect/DXSelect.stories.js +259 -0
- package/src/components/molecules/DXSelect/DXSelect.vue +149 -0
- package/src/components/molecules/DXSelect/index.js +3 -0
- package/src/components/molecules/DXStatCard/DXStatCard.stories.js +335 -0
- package/src/components/molecules/DXStatCard/DXStatCard.vue +309 -0
- package/src/components/molecules/DXStatCard/index.js +2 -0
- package/src/components/molecules/DXTableFiltersPanel/DXTableFiltersPanel.vue +72 -0
- package/src/components/molecules/DXTableFiltersPanel/index.js +7 -0
- package/src/components/molecules/DXTablePagination/DXTablePagination.stories.js +236 -0
- package/src/components/molecules/DXTablePagination/DXTablePagination.vue +93 -0
- package/src/components/molecules/DXTablePagination/index.js +2 -0
- package/src/components/molecules/DXTableToolbar/DXTableToolbar.stories.js +271 -0
- package/src/components/molecules/DXTableToolbar/DXTableToolbar.vue +102 -0
- package/src/components/molecules/DXTableToolbar/index.js +2 -0
- package/src/components/molecules/DXTextarea/DXTextarea.stories.js +239 -0
- package/src/components/molecules/DXTextarea/DXTextarea.vue +158 -0
- package/src/components/molecules/DXTextarea/index.js +3 -0
- package/src/components/molecules/DXTimePicker/DXTimePicker.stories.js +282 -0
- package/src/components/molecules/DXTimePicker/DXTimePicker.vue +640 -0
- package/src/components/molecules/DXTimePicker/index.js +2 -0
- package/src/components/molecules/DXValidationIcon/DXValidationIcon.stories.js +60 -0
- package/src/components/molecules/DXValidationIcon/DXValidationIcon.vue +53 -0
- package/src/components/molecules/DXValidationIcon/index.js +3 -0
- package/src/components/molecules/index.js +34 -0
- package/src/components/organisms/DXAccordion/DXAccordion.stories.js +33 -0
- package/src/components/organisms/DXAccordion/DXAccordion.vue +104 -0
- package/src/components/organisms/DXAccordion/index.js +2 -0
- package/src/components/organisms/DXAppLayout/DXAppLayout.stories.js +689 -0
- package/src/components/organisms/DXAppLayout/DXAppLayout.vue +460 -0
- package/src/components/organisms/DXAppLayout/index.js +2 -0
- package/src/components/organisms/DXAuthenticationForm/DXAuthenticationForm.stories.js +232 -0
- package/src/components/organisms/DXAuthenticationForm/DXAuthenticationForm.vue +458 -0
- package/src/components/organisms/DXAuthenticationForm/index.js +2 -0
- package/src/components/organisms/DXChartContainer/DXChartContainer.stories.js +286 -0
- package/src/components/organisms/DXChartContainer/DXChartContainer.vue +273 -0
- package/src/components/organisms/DXChartContainer/index.js +2 -0
- package/src/components/organisms/DXChatInterface/DXChatInterface.stories.js +164 -0
- package/src/components/organisms/DXChatInterface/DXChatInterface.vue +583 -0
- package/src/components/organisms/DXChatInterface/index.js +2 -0
- package/src/components/organisms/DXCommentSection/DXCommentSection.stories.js +173 -0
- package/src/components/organisms/DXCommentSection/DXCommentSection.vue +487 -0
- package/src/components/organisms/DXCommentSection/index.js +2 -0
- package/src/components/organisms/DXDashboardGrid/DXDashboardGrid.stories.js +331 -0
- package/src/components/organisms/DXDashboardGrid/DXDashboardGrid.vue +309 -0
- package/src/components/organisms/DXDashboardGrid/index.js +2 -0
- package/src/components/organisms/DXDashboardWidget/DXDashboardWidget.stories.js +271 -0
- package/src/components/organisms/DXDashboardWidget/DXDashboardWidget.vue +260 -0
- package/src/components/organisms/DXDashboardWidget/index.js +2 -0
- package/src/components/organisms/DXDataTable/DXDataTable.stories.js +247 -0
- package/src/components/organisms/DXDataTable/DXDataTable.vue +496 -0
- package/src/components/organisms/DXDataTable/index.js +2 -0
- package/src/components/organisms/DXDropdown/DXDropdown.stories.js +795 -0
- package/src/components/organisms/DXDropdown/DXDropdown.vue +238 -0
- package/src/components/organisms/DXDropdown/index.js +2 -0
- package/src/components/organisms/DXEmptyState/DXEmptyState.stories.js +37 -0
- package/src/components/organisms/DXEmptyState/DXEmptyState.vue +41 -0
- package/src/components/organisms/DXEmptyState/index.js +2 -0
- package/src/components/organisms/DXFormWizard/DXFormWizard.stories.js +378 -0
- package/src/components/organisms/DXFormWizard/DXFormWizard.vue +578 -0
- package/src/components/organisms/DXFormWizard/index.js +2 -0
- package/src/components/organisms/DXHeaderBar/DXHeaderBar.stories.js +448 -0
- package/src/components/organisms/DXHeaderBar/DXHeaderBar.vue +190 -0
- package/src/components/organisms/DXHeaderBar/index.js +2 -0
- package/src/components/organisms/DXMediaGallery/DXMediaGallery.stories.js +347 -0
- package/src/components/organisms/DXMediaGallery/DXMediaGallery.vue +422 -0
- package/src/components/organisms/DXMediaGallery/index.js +2 -0
- package/src/components/organisms/DXModal/DXModal.stories.js +138 -0
- package/src/components/organisms/DXModal/DXModal.vue +213 -0
- package/src/components/organisms/DXModal/index.js +2 -0
- package/src/components/organisms/DXNotificationCenter/DXNotificationCenter.stories.js +183 -0
- package/src/components/organisms/DXNotificationCenter/DXNotificationCenter.vue +566 -0
- package/src/components/organisms/DXNotificationCenter/index.js +2 -0
- package/src/components/organisms/DXReportGenerator/DXReportGenerator.stories.js +199 -0
- package/src/components/organisms/DXReportGenerator/DXReportGenerator.vue +344 -0
- package/src/components/organisms/DXReportGenerator/index.js +2 -0
- package/src/components/organisms/DXSettingsPanel/DXSettingsPanel.stories.js +245 -0
- package/src/components/organisms/DXSettingsPanel/DXSettingsPanel.vue +454 -0
- package/src/components/organisms/DXSettingsPanel/index.js +2 -0
- package/src/components/organisms/DXSidebar/DXSidebar.stories.js +316 -0
- package/src/components/organisms/DXSidebar/DXSidebar.vue +212 -0
- package/src/components/organisms/DXSidebar/index.js +2 -0
- package/src/components/organisms/DXSidebarMenu/DATA_STRUCTURE.md +299 -0
- package/src/components/organisms/DXSidebarMenu/DXSidebarMenu.stories.js +729 -0
- package/src/components/organisms/DXSidebarMenu/DXSidebarMenu.vue +257 -0
- package/src/components/organisms/DXSidebarMenu/DXSidebarMenuItem.vue +249 -0
- package/src/components/organisms/DXSidebarMenu/README.md +333 -0
- package/src/components/organisms/DXSidebarMenu/index.js +3 -0
- package/src/components/organisms/DXTable/DXTable.stories.js +550 -0
- package/src/components/organisms/DXTable/DXTable.vue +324 -0
- package/src/components/organisms/DXTable/index.js +2 -0
- package/src/components/organisms/DXTabs/DXTabs.stories.js +407 -0
- package/src/components/organisms/DXTabs/DXTabs.vue +301 -0
- package/src/components/organisms/DXTabs/index.js +2 -0
- package/src/components/organisms/DXUserProfileCard/DXUserProfileCard.stories.js +194 -0
- package/src/components/organisms/DXUserProfileCard/DXUserProfileCard.vue +403 -0
- package/src/components/organisms/DXUserProfileCard/index.js +2 -0
- package/src/components/organisms/DXWizard/DXWizard.stories.js +212 -0
- package/src/components/organisms/DXWizard/DXWizard.vue +615 -0
- package/src/components/organisms/DXWizard/index.js +2 -0
- package/src/components/organisms/index.js +25 -0
- package/src/components/typography/DXBlockquote/DXBlockquote.stories.js +33 -0
- package/src/components/typography/DXBlockquote/DXBlockquote.vue +44 -0
- package/src/components/typography/DXBlockquote/index.js +2 -0
- package/src/components/typography/DXCode/DXCode.stories.js +29 -0
- package/src/components/typography/DXCode/DXCode.vue +46 -0
- package/src/components/typography/DXCode/index.js +2 -0
- package/src/components/typography/DXHeading/DXHeading.stories.js +54 -0
- package/src/components/typography/DXHeading/DXHeading.vue +68 -0
- package/src/components/typography/DXHeading/index.js +2 -0
- package/src/components/typography/DXLabel/DXLabel.stories.js +40 -0
- package/src/components/typography/DXLabel/DXLabel.vue +49 -0
- package/src/components/typography/DXLabel/index.js +2 -0
- package/src/components/typography/DXList/DXList.stories.js +50 -0
- package/src/components/typography/DXList/DXList.vue +55 -0
- package/src/components/typography/DXList/index.js +2 -0
- package/src/components/typography/DXText/DXText.stories.js +47 -0
- package/src/components/typography/DXText/DXText.vue +67 -0
- package/src/components/typography/DXText/index.js +2 -0
- package/src/components/typography/index.js +8 -0
- package/src/components/utilities/DXAnimatePresence/DXAnimatePresence.stories.js +335 -0
- package/src/components/utilities/DXAnimatePresence/DXAnimatePresence.vue +207 -0
- package/src/components/utilities/DXAnimatePresence/index.js +2 -0
- package/src/components/utilities/DXBreakpointProvider/DXBreakpointProvider.stories.js +321 -0
- package/src/components/utilities/DXBreakpointProvider/DXBreakpointProvider.vue +158 -0
- package/src/components/utilities/DXBreakpointProvider/index.js +2 -0
- package/src/components/utilities/DXObserver/DXObserver.stories.js +324 -0
- package/src/components/utilities/DXObserver/DXObserver.vue +182 -0
- package/src/components/utilities/DXObserver/index.js +2 -0
- package/src/components/utilities/DXPortal/DXPortal.stories.js +267 -0
- package/src/components/utilities/DXPortal/DXPortal.vue +69 -0
- package/src/components/utilities/DXPortal/index.js +2 -0
- package/src/components/utilities/DXStaggeredAnimation/DXStaggeredAnimation.stories.js +339 -0
- package/src/components/utilities/DXStaggeredAnimation/DXStaggeredAnimation.vue +155 -0
- package/src/components/utilities/DXStaggeredAnimation/index.js +2 -0
- package/src/components/utilities/DXThemeProvider/DXThemeProvider.stories.js +327 -0
- package/src/components/utilities/DXThemeProvider/DXThemeProvider.vue +227 -0
- package/src/components/utilities/DXThemeProvider/index.js +2 -0
- package/src/components/utilities/DXTransitionGroup/DXTransitionGroup.stories.js +368 -0
- package/src/components/utilities/DXTransitionGroup/DXTransitionGroup.vue +212 -0
- package/src/components/utilities/DXTransitionGroup/index.js +2 -0
- package/src/components/utilities/index.js +9 -0
- package/src/composables/useAnimation.js +264 -0
- package/src/composables/useClassComposition.js +35 -0
- package/src/composables/useDataAttributes.js +83 -0
- package/src/composables/useMenu.js +88 -0
- package/src/composables/useSize.js +135 -0
- package/src/composables/useSpacing.js +37 -0
- package/src/composables/useTableColumns.js +88 -0
- package/src/composables/useTableData.js +82 -0
- package/src/composables/useTableFilter.js +158 -0
- package/src/composables/useTablePagination.js +89 -0
- package/src/composables/useTableSelection.js +77 -0
- package/src/composables/useTableSort.js +75 -0
- package/src/composables/useTabsScroll.js +88 -0
- package/src/composables/useVariant.js +700 -0
- package/src/index.js +86 -0
- package/src/styles/animations.css +171 -0
- package/src/styles/index.css +99 -0
- package/src/styles/tokens.js +123 -0
- package/src/utils/propTypes.js +77 -0
- package/src/utils/toggleButtonPresets.js +115 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="w-full" data-component="DXTimePicker" :data-format="format" :data-size="size">
|
|
3
|
+
<div class="relative">
|
|
4
|
+
<DXInput
|
|
5
|
+
:model-value="displayValue"
|
|
6
|
+
:placeholder="placeholder"
|
|
7
|
+
:disabled="disabled"
|
|
8
|
+
:size="size"
|
|
9
|
+
:error="error"
|
|
10
|
+
:helper="helper"
|
|
11
|
+
:label="label"
|
|
12
|
+
:required="required"
|
|
13
|
+
type="text"
|
|
14
|
+
:suffix-icon="ClockIcon"
|
|
15
|
+
@update:model-value="handleInput"
|
|
16
|
+
@blur="handleBlur"
|
|
17
|
+
@focus="handleFocus"
|
|
18
|
+
/>
|
|
19
|
+
|
|
20
|
+
<!-- Time Dropdown -->
|
|
21
|
+
<div
|
|
22
|
+
v-if="showDropdownState && !disabled"
|
|
23
|
+
v-click-outside="closeDropdown"
|
|
24
|
+
class="absolute z-50 mt-1 w-full bg-white border border-slate-200 rounded-xl shadow-lg max-h-64 overflow-y-auto"
|
|
25
|
+
>
|
|
26
|
+
<div class="p-2">
|
|
27
|
+
<!-- Hours -->
|
|
28
|
+
<div v-if="format === '12h'" class="grid grid-cols-12 gap-1 mb-2">
|
|
29
|
+
<button
|
|
30
|
+
v-for="hour in hours12"
|
|
31
|
+
:key="hour.value"
|
|
32
|
+
type="button"
|
|
33
|
+
:class="[
|
|
34
|
+
'px-3 py-2 text-sm rounded-lg transition-colors',
|
|
35
|
+
selectedHour === hour.value
|
|
36
|
+
? 'bg-slate-900 text-white'
|
|
37
|
+
: 'hover:bg-slate-100 text-slate-700',
|
|
38
|
+
]"
|
|
39
|
+
@click="selectHour(hour.value)"
|
|
40
|
+
>
|
|
41
|
+
{{ hour.label }}
|
|
42
|
+
</button>
|
|
43
|
+
</div>
|
|
44
|
+
<div v-else class="grid grid-cols-6 gap-1 mb-2">
|
|
45
|
+
<button
|
|
46
|
+
v-for="hour in hours24"
|
|
47
|
+
:key="hour"
|
|
48
|
+
type="button"
|
|
49
|
+
:class="[
|
|
50
|
+
'px-3 py-2 text-sm rounded-lg transition-colors',
|
|
51
|
+
selectedHour === hour
|
|
52
|
+
? 'bg-slate-900 text-white'
|
|
53
|
+
: 'hover:bg-slate-100 text-slate-700',
|
|
54
|
+
]"
|
|
55
|
+
@click="selectHour(hour)"
|
|
56
|
+
>
|
|
57
|
+
{{ String(hour).padStart(2, '0') }}
|
|
58
|
+
</button>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<!-- Minutes -->
|
|
62
|
+
<div class="grid grid-cols-6 gap-1 mb-2">
|
|
63
|
+
<button
|
|
64
|
+
v-for="minute in minutes"
|
|
65
|
+
:key="minute"
|
|
66
|
+
type="button"
|
|
67
|
+
:class="[
|
|
68
|
+
'px-3 py-2 text-sm rounded-lg transition-colors',
|
|
69
|
+
selectedMinute === minute
|
|
70
|
+
? 'bg-slate-900 text-white'
|
|
71
|
+
: 'hover:bg-slate-100 text-slate-700',
|
|
72
|
+
]"
|
|
73
|
+
@click="selectMinute(minute)"
|
|
74
|
+
>
|
|
75
|
+
{{ String(minute).padStart(2, '0') }}
|
|
76
|
+
</button>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- Seconds (if enabled) -->
|
|
80
|
+
<div v-if="showSeconds" class="grid grid-cols-6 gap-1">
|
|
81
|
+
<button
|
|
82
|
+
v-for="second in seconds"
|
|
83
|
+
:key="second"
|
|
84
|
+
type="button"
|
|
85
|
+
:class="[
|
|
86
|
+
'px-3 py-2 text-sm rounded-lg transition-colors',
|
|
87
|
+
selectedSecond === second
|
|
88
|
+
? 'bg-slate-900 text-white'
|
|
89
|
+
: 'hover:bg-slate-100 text-slate-700',
|
|
90
|
+
]"
|
|
91
|
+
@click="selectSecond(second)"
|
|
92
|
+
>
|
|
93
|
+
{{ String(second).padStart(2, '0') }}
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- AM/PM для 12h формата -->
|
|
98
|
+
<div v-if="format === '12h'" class="flex gap-2 mt-2 pt-2 border-t border-slate-200">
|
|
99
|
+
<button
|
|
100
|
+
type="button"
|
|
101
|
+
:class="[
|
|
102
|
+
'flex-1 px-3 py-2 text-sm rounded-lg transition-colors',
|
|
103
|
+
isAM
|
|
104
|
+
? 'bg-slate-900 text-white'
|
|
105
|
+
: 'bg-slate-100 text-slate-700 hover:bg-slate-200',
|
|
106
|
+
]"
|
|
107
|
+
@click="setAMPM(true)"
|
|
108
|
+
>
|
|
109
|
+
AM
|
|
110
|
+
</button>
|
|
111
|
+
<button
|
|
112
|
+
type="button"
|
|
113
|
+
:class="[
|
|
114
|
+
'flex-1 px-3 py-2 text-sm rounded-lg transition-colors',
|
|
115
|
+
!isAM
|
|
116
|
+
? 'bg-slate-900 text-white'
|
|
117
|
+
: 'bg-slate-100 text-slate-700 hover:bg-slate-200',
|
|
118
|
+
]"
|
|
119
|
+
@click="setAMPM(false)"
|
|
120
|
+
>
|
|
121
|
+
PM
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</template>
|
|
129
|
+
|
|
130
|
+
<script setup>
|
|
131
|
+
import { ref, computed, watch } from "vue";
|
|
132
|
+
import DXInput from "../DXInput/DXInput.vue";
|
|
133
|
+
import { ClockIcon } from "@heroicons/vue/24/outline";
|
|
134
|
+
|
|
135
|
+
const props = defineProps({
|
|
136
|
+
/** Значение времени (v-model) в формате HH:mm или HH:mm:ss */
|
|
137
|
+
modelValue: { type: String, default: null },
|
|
138
|
+
/** Формат времени: 12h | 24h */
|
|
139
|
+
format: { type: String, default: "24h", validator: (v) => ["12h", "24h"].includes(v) },
|
|
140
|
+
/** Показывать секунды */
|
|
141
|
+
showSeconds: { type: Boolean, default: false },
|
|
142
|
+
/** Placeholder */
|
|
143
|
+
placeholder: { type: String, default: "" },
|
|
144
|
+
/** Лейбл */
|
|
145
|
+
label: { type: String, default: "" },
|
|
146
|
+
/** Вспомогательный текст */
|
|
147
|
+
helper: { type: String, default: "" },
|
|
148
|
+
/** Текст ошибки */
|
|
149
|
+
error: { type: String, default: "" },
|
|
150
|
+
/** Обязательное поле */
|
|
151
|
+
required: { type: Boolean, default: false },
|
|
152
|
+
/** Отключенное состояние */
|
|
153
|
+
disabled: { type: Boolean, default: false },
|
|
154
|
+
/** Размер: xs | sm | md | lg | xl */
|
|
155
|
+
size: { type: String, default: "md" },
|
|
156
|
+
/** Минимальное время (HH:mm или HH:mm:ss) */
|
|
157
|
+
minTime: { type: String, default: null },
|
|
158
|
+
/** Максимальное время (HH:mm или HH:mm:ss) */
|
|
159
|
+
maxTime: { type: String, default: null },
|
|
160
|
+
/** Показывать dropdown для выбора */
|
|
161
|
+
showDropdown: { type: Boolean, default: true },
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const emit = defineEmits(["update:modelValue", "change", "blur", "focus"]);
|
|
165
|
+
|
|
166
|
+
const showDropdownState = ref(false);
|
|
167
|
+
const inputValue = ref("");
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Часы для 12-часового формата
|
|
171
|
+
*
|
|
172
|
+
* @description
|
|
173
|
+
* Генерирует массив часов для 12-часового формата (1-12) с метками.
|
|
174
|
+
*
|
|
175
|
+
* @returns {Array} Массив объектов { value, label }
|
|
176
|
+
*/
|
|
177
|
+
const hours12 = computed(() => {
|
|
178
|
+
return Array.from({ length: 12 }, (_, i) => ({
|
|
179
|
+
value: i + 1,
|
|
180
|
+
label: String(i + 1),
|
|
181
|
+
}));
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Часы для 24-часового формата
|
|
186
|
+
*
|
|
187
|
+
* @description
|
|
188
|
+
* Генерирует массив часов для 24-часового формата (0-23).
|
|
189
|
+
*
|
|
190
|
+
* @returns {Array} Массив чисел от 0 до 23
|
|
191
|
+
*/
|
|
192
|
+
const hours24 = computed(() => {
|
|
193
|
+
return Array.from({ length: 24 }, (_, i) => i);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Минуты
|
|
198
|
+
*
|
|
199
|
+
* @description
|
|
200
|
+
* Генерирует массив минут с шагом 5 (0, 5, 10, ..., 55).
|
|
201
|
+
*
|
|
202
|
+
* @returns {Array} Массив минут
|
|
203
|
+
*/
|
|
204
|
+
const minutes = computed(() => {
|
|
205
|
+
return Array.from({ length: 12 }, (_, i) => i * 5);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Секунды
|
|
210
|
+
*
|
|
211
|
+
* @description
|
|
212
|
+
* Генерирует массив секунд с шагом 5 (0, 5, 10, ..., 55).
|
|
213
|
+
*
|
|
214
|
+
* @returns {Array} Массив секунд
|
|
215
|
+
*/
|
|
216
|
+
const seconds = computed(() => {
|
|
217
|
+
return Array.from({ length: 12 }, (_, i) => i * 5);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Выбранный час
|
|
222
|
+
*
|
|
223
|
+
* @description
|
|
224
|
+
* Извлекает час из текущего значения времени.
|
|
225
|
+
* Для 12h формата возвращает час в диапазоне 1-12.
|
|
226
|
+
*
|
|
227
|
+
* @returns {number|null} Выбранный час или null
|
|
228
|
+
*/
|
|
229
|
+
const selectedHour = computed(() => {
|
|
230
|
+
if (!props.modelValue) return null;
|
|
231
|
+
const time = parseTime(props.modelValue);
|
|
232
|
+
if (!time) return null;
|
|
233
|
+
|
|
234
|
+
if (props.format === "12h") {
|
|
235
|
+
// Преобразуем 0-23 в 1-12 для отображения
|
|
236
|
+
if (time.hour === 0) return 12;
|
|
237
|
+
if (time.hour > 12) return time.hour - 12;
|
|
238
|
+
return time.hour;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return time.hour;
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Выбранная минута
|
|
246
|
+
*
|
|
247
|
+
* @description
|
|
248
|
+
* Извлекает минуту из текущего значения времени.
|
|
249
|
+
*
|
|
250
|
+
* @returns {number|null} Выбранная минута или null
|
|
251
|
+
*/
|
|
252
|
+
const selectedMinute = computed(() => {
|
|
253
|
+
if (!props.modelValue) return null;
|
|
254
|
+
const time = parseTime(props.modelValue);
|
|
255
|
+
if (!time) return null;
|
|
256
|
+
return time.minute;
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Выбранная секунда
|
|
261
|
+
*
|
|
262
|
+
* @description
|
|
263
|
+
* Извлекает секунду из текущего значения времени.
|
|
264
|
+
*
|
|
265
|
+
* @returns {number|null} Выбранная секунда или null
|
|
266
|
+
*/
|
|
267
|
+
const selectedSecond = computed(() => {
|
|
268
|
+
if (!props.modelValue) return null;
|
|
269
|
+
const time = parseTime(props.modelValue);
|
|
270
|
+
if (!time) return null;
|
|
271
|
+
return time.second || 0;
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Определяет, является ли время AM (для 12h формата)
|
|
276
|
+
*
|
|
277
|
+
* @description
|
|
278
|
+
* Для 12-часового формата определяет, является ли время до полудня (AM).
|
|
279
|
+
*
|
|
280
|
+
* @returns {boolean} true если AM, false если PM
|
|
281
|
+
*/
|
|
282
|
+
const isAM = computed(() => {
|
|
283
|
+
if (!props.modelValue || props.format !== "12h") return true;
|
|
284
|
+
const time = parseTime(props.modelValue);
|
|
285
|
+
if (!time) return true;
|
|
286
|
+
return time.hour < 12;
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Отображаемое значение времени
|
|
291
|
+
*
|
|
292
|
+
* @description
|
|
293
|
+
* Форматирует значение времени для отображения в input в зависимости от формата.
|
|
294
|
+
*
|
|
295
|
+
* @returns {string} Отформатированное время
|
|
296
|
+
*/
|
|
297
|
+
const displayValue = computed(() => {
|
|
298
|
+
if (!props.modelValue) return inputValue.value || "";
|
|
299
|
+
|
|
300
|
+
const time = parseTime(props.modelValue);
|
|
301
|
+
if (!time) return props.modelValue;
|
|
302
|
+
|
|
303
|
+
if (props.format === "12h") {
|
|
304
|
+
let hour = time.hour;
|
|
305
|
+
const ampm = hour >= 12 ? "PM" : "AM";
|
|
306
|
+
if (hour === 0) hour = 12;
|
|
307
|
+
else if (hour > 12) hour -= 12;
|
|
308
|
+
|
|
309
|
+
if (props.showSeconds) {
|
|
310
|
+
return `${String(hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}:${String(time.second || 0).padStart(2, "0")} ${ampm}`;
|
|
311
|
+
}
|
|
312
|
+
return `${String(hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")} ${ampm}`;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 24h format
|
|
316
|
+
if (props.showSeconds) {
|
|
317
|
+
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}:${String(time.second || 0).padStart(2, "0")}`;
|
|
318
|
+
}
|
|
319
|
+
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Парсит строку времени в объект
|
|
325
|
+
*
|
|
326
|
+
* @description
|
|
327
|
+
* Парсит строку времени в формате HH:mm или HH:mm:ss в объект с hour, minute, second.
|
|
328
|
+
* Поддерживает как 12h, так и 24h форматы.
|
|
329
|
+
*
|
|
330
|
+
* @param {string} timeStr - Строка времени
|
|
331
|
+
* @returns {Object|null} Объект { hour, minute, second } или null при ошибке
|
|
332
|
+
*/
|
|
333
|
+
function parseTime(timeStr) {
|
|
334
|
+
if (!timeStr) return null;
|
|
335
|
+
|
|
336
|
+
// Парсинг 12h формата (например, "02:30 PM")
|
|
337
|
+
if (props.format === "12h") {
|
|
338
|
+
const match12h = timeStr.match(/(\d{1,2}):(\d{2})(?::(\d{2}))?\s*(AM|PM)?/i);
|
|
339
|
+
if (match12h) {
|
|
340
|
+
let hour = parseInt(match12h[1], 10);
|
|
341
|
+
const minute = parseInt(match12h[2], 10);
|
|
342
|
+
const second = match12h[3] ? parseInt(match12h[3], 10) : 0;
|
|
343
|
+
const ampm = match12h[4]?.toUpperCase();
|
|
344
|
+
|
|
345
|
+
if (ampm === "PM" && hour !== 12) hour += 12;
|
|
346
|
+
if (ampm === "AM" && hour === 12) hour = 0;
|
|
347
|
+
|
|
348
|
+
return { hour, minute, second };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Парсинг 24h формата (например, "14:30" или "14:30:45")
|
|
353
|
+
const match24h = timeStr.match(/(\d{1,2}):(\d{2})(?::(\d{2}))?/);
|
|
354
|
+
if (match24h) {
|
|
355
|
+
const hour = parseInt(match24h[1], 10);
|
|
356
|
+
const minute = parseInt(match24h[2], 10);
|
|
357
|
+
const second = match24h[3] ? parseInt(match24h[3], 10) : 0;
|
|
358
|
+
|
|
359
|
+
if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59) {
|
|
360
|
+
return { hour, minute, second };
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Форматирует время в строку
|
|
369
|
+
*
|
|
370
|
+
* @description
|
|
371
|
+
* Форматирует объект времени в строку в зависимости от формата и настроек.
|
|
372
|
+
*
|
|
373
|
+
* @param {Object} time - Объект { hour, minute, second }
|
|
374
|
+
* @returns {string} Отформатированная строка времени
|
|
375
|
+
*/
|
|
376
|
+
function formatTime(time) {
|
|
377
|
+
if (!time) return "";
|
|
378
|
+
|
|
379
|
+
if (props.format === "12h") {
|
|
380
|
+
let hour = time.hour;
|
|
381
|
+
const ampm = hour >= 12 ? "PM" : "AM";
|
|
382
|
+
if (hour === 0) hour = 12;
|
|
383
|
+
else if (hour > 12) hour -= 12;
|
|
384
|
+
|
|
385
|
+
if (props.showSeconds) {
|
|
386
|
+
return `${String(hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}:${String(time.second || 0).padStart(2, "0")} ${ampm}`;
|
|
387
|
+
}
|
|
388
|
+
return `${String(hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")} ${ampm}`;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// 24h format
|
|
392
|
+
if (props.showSeconds) {
|
|
393
|
+
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}:${String(time.second || 0).padStart(2, "0")}`;
|
|
394
|
+
}
|
|
395
|
+
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Валидирует время
|
|
400
|
+
*
|
|
401
|
+
* @description
|
|
402
|
+
* Проверяет, что время находится в допустимом диапазоне (если указаны minTime/maxTime)
|
|
403
|
+
* и соответствует формату.
|
|
404
|
+
*
|
|
405
|
+
* @param {Object} time - Объект { hour, minute, second }
|
|
406
|
+
* @returns {boolean} true если время валидно
|
|
407
|
+
*/
|
|
408
|
+
function validateTime(time) {
|
|
409
|
+
if (!time) return false;
|
|
410
|
+
|
|
411
|
+
// Проверка диапазона
|
|
412
|
+
if (props.minTime) {
|
|
413
|
+
const min = parseTime(props.minTime);
|
|
414
|
+
if (min) {
|
|
415
|
+
const timeMinutes = time.hour * 60 + time.minute + (time.second || 0) / 60;
|
|
416
|
+
const minMinutes = min.hour * 60 + min.minute + (min.second || 0) / 60;
|
|
417
|
+
if (timeMinutes < minMinutes) return false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (props.maxTime) {
|
|
422
|
+
const max = parseTime(props.maxTime);
|
|
423
|
+
if (max) {
|
|
424
|
+
const timeMinutes = time.hour * 60 + time.minute + (time.second || 0) / 60;
|
|
425
|
+
const maxMinutes = max.hour * 60 + max.minute + (max.second || 0) / 60;
|
|
426
|
+
if (timeMinutes > maxMinutes) return false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Обработчик ввода времени
|
|
435
|
+
*
|
|
436
|
+
* @description
|
|
437
|
+
* Обрабатывает ручной ввод времени пользователем, парсит и валидирует значение.
|
|
438
|
+
*
|
|
439
|
+
* @param {string} value - Введенное значение
|
|
440
|
+
*/
|
|
441
|
+
function handleInput(value) {
|
|
442
|
+
inputValue.value = value;
|
|
443
|
+
const time = parseTime(value);
|
|
444
|
+
|
|
445
|
+
if (time && validateTime(time)) {
|
|
446
|
+
const formatted = formatTime(time);
|
|
447
|
+
emit("update:modelValue", formatted);
|
|
448
|
+
emit("change", formatted);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Выбор часа
|
|
454
|
+
*
|
|
455
|
+
* @description
|
|
456
|
+
* Устанавливает выбранный час и обновляет значение времени.
|
|
457
|
+
* Для 12h формата учитывает текущий период (AM/PM).
|
|
458
|
+
*
|
|
459
|
+
* @param {number} hour - Выбранный час (1-12 для 12h, 0-23 для 24h)
|
|
460
|
+
*/
|
|
461
|
+
function selectHour(hour) {
|
|
462
|
+
const currentTime = props.modelValue ? parseTime(props.modelValue) : { hour: 0, minute: 0, second: 0 };
|
|
463
|
+
let newHour = hour;
|
|
464
|
+
|
|
465
|
+
if (props.format === "12h") {
|
|
466
|
+
// Для 12h формата: hour это 1-12, нужно преобразовать в 0-23
|
|
467
|
+
if (hour === 12) {
|
|
468
|
+
newHour = isAM.value ? 0 : 12;
|
|
469
|
+
} else {
|
|
470
|
+
newHour = isAM.value ? hour : hour + 12;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const newTime = {
|
|
475
|
+
hour: newHour,
|
|
476
|
+
minute: currentTime?.minute || 0,
|
|
477
|
+
second: currentTime?.second || 0,
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
if (validateTime(newTime)) {
|
|
481
|
+
const formatted = formatTime(newTime);
|
|
482
|
+
emit("update:modelValue", formatted);
|
|
483
|
+
emit("change", formatted);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Выбор минуты
|
|
489
|
+
*
|
|
490
|
+
* @description
|
|
491
|
+
* Устанавливает выбранную минуту и обновляет значение времени.
|
|
492
|
+
*
|
|
493
|
+
* @param {number} minute - Выбранная минута
|
|
494
|
+
*/
|
|
495
|
+
function selectMinute(minute) {
|
|
496
|
+
const currentTime = props.modelValue ? parseTime(props.modelValue) : { hour: 0, minute: 0, second: 0 };
|
|
497
|
+
const newTime = {
|
|
498
|
+
hour: currentTime?.hour || 0,
|
|
499
|
+
minute,
|
|
500
|
+
second: currentTime?.second || 0,
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
if (validateTime(newTime)) {
|
|
504
|
+
const formatted = formatTime(newTime);
|
|
505
|
+
emit("update:modelValue", formatted);
|
|
506
|
+
emit("change", formatted);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Выбор секунды
|
|
512
|
+
*
|
|
513
|
+
* @description
|
|
514
|
+
* Устанавливает выбранную секунду и обновляет значение времени.
|
|
515
|
+
*
|
|
516
|
+
* @param {number} second - Выбранная секунда
|
|
517
|
+
*/
|
|
518
|
+
function selectSecond(second) {
|
|
519
|
+
const currentTime = props.modelValue ? parseTime(props.modelValue) : { hour: 0, minute: 0, second: 0 };
|
|
520
|
+
const newTime = {
|
|
521
|
+
hour: currentTime?.hour || 0,
|
|
522
|
+
minute: currentTime?.minute || 0,
|
|
523
|
+
second,
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
if (validateTime(newTime)) {
|
|
527
|
+
const formatted = formatTime(newTime);
|
|
528
|
+
emit("update:modelValue", formatted);
|
|
529
|
+
emit("change", formatted);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Установка AM/PM
|
|
535
|
+
*
|
|
536
|
+
* @description
|
|
537
|
+
* Устанавливает период дня (AM/PM) для 12-часового формата.
|
|
538
|
+
*
|
|
539
|
+
* @param {boolean} am - true для AM, false для PM
|
|
540
|
+
*/
|
|
541
|
+
function setAMPM(am) {
|
|
542
|
+
if (props.format !== "12h") return;
|
|
543
|
+
|
|
544
|
+
const currentTime = props.modelValue ? parseTime(props.modelValue) : { hour: 0, minute: 0, second: 0 };
|
|
545
|
+
if (!currentTime) return;
|
|
546
|
+
|
|
547
|
+
let hour = currentTime.hour;
|
|
548
|
+
if (am && hour >= 12) {
|
|
549
|
+
hour -= 12;
|
|
550
|
+
if (hour === 0) hour = 12;
|
|
551
|
+
} else if (!am && hour < 12) {
|
|
552
|
+
if (hour === 0) hour = 12;
|
|
553
|
+
hour += 12;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const newTime = { ...currentTime, hour };
|
|
557
|
+
if (validateTime(newTime)) {
|
|
558
|
+
const formatted = formatTime(newTime);
|
|
559
|
+
emit("update:modelValue", formatted);
|
|
560
|
+
emit("change", formatted);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Обработчик фокуса
|
|
566
|
+
*
|
|
567
|
+
* @description
|
|
568
|
+
* Открывает dropdown при фокусе на input (если showDropdown включен).
|
|
569
|
+
*
|
|
570
|
+
* @param {Event} event - Событие фокуса
|
|
571
|
+
*/
|
|
572
|
+
function handleFocus(event) {
|
|
573
|
+
if (props.showDropdown) {
|
|
574
|
+
showDropdownState.value = true;
|
|
575
|
+
}
|
|
576
|
+
emit("focus", event);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Обработчик blur
|
|
581
|
+
*
|
|
582
|
+
* @description
|
|
583
|
+
* Закрывает dropdown при потере фокуса и валидирует введенное значение.
|
|
584
|
+
*
|
|
585
|
+
* @param {Event} event - Событие blur
|
|
586
|
+
*/
|
|
587
|
+
function handleBlur(event) {
|
|
588
|
+
showDropdownState.value = false;
|
|
589
|
+
|
|
590
|
+
// Валидация при blur
|
|
591
|
+
if (inputValue.value) {
|
|
592
|
+
const time = parseTime(inputValue.value);
|
|
593
|
+
if (time && validateTime(time)) {
|
|
594
|
+
const formatted = formatTime(time);
|
|
595
|
+
emit("update:modelValue", formatted);
|
|
596
|
+
} else {
|
|
597
|
+
// Если значение невалидно, восстанавливаем предыдущее
|
|
598
|
+
inputValue.value = displayValue.value;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
emit("blur", event);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Закрытие dropdown
|
|
607
|
+
*
|
|
608
|
+
* @description
|
|
609
|
+
* Закрывает dropdown при клике вне компонента.
|
|
610
|
+
*/
|
|
611
|
+
function closeDropdown() {
|
|
612
|
+
showDropdownState.value = false;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Директива для клика вне элемента
|
|
616
|
+
const vClickOutside = {
|
|
617
|
+
mounted(el, binding) {
|
|
618
|
+
el.clickOutsideEvent = (event) => {
|
|
619
|
+
if (!(el === event.target || el.contains(event.target))) {
|
|
620
|
+
binding.value();
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
document.addEventListener("click", el.clickOutsideEvent);
|
|
624
|
+
},
|
|
625
|
+
unmounted(el) {
|
|
626
|
+
document.removeEventListener("click", el.clickOutsideEvent);
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// Синхронизация showDropdownState с prop showDropdown
|
|
631
|
+
watch(
|
|
632
|
+
() => props.showDropdown,
|
|
633
|
+
(newVal) => {
|
|
634
|
+
if (!newVal) {
|
|
635
|
+
showDropdownState.value = false;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
);
|
|
639
|
+
</script>
|
|
640
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import DXValidationIcon from './DXValidationIcon.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Molecules/DXValidationIcon',
|
|
5
|
+
component: DXValidationIcon,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
argTypes: {
|
|
8
|
+
state: {
|
|
9
|
+
control: 'select',
|
|
10
|
+
options: ['success', 'error', 'warning', 'info'],
|
|
11
|
+
},
|
|
12
|
+
size: {
|
|
13
|
+
control: 'select',
|
|
14
|
+
options: ['sm', 'md', 'lg'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const Default = {
|
|
20
|
+
args: {
|
|
21
|
+
state: 'success',
|
|
22
|
+
size: 'md',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const States = () => ({
|
|
27
|
+
components: { DXValidationIcon },
|
|
28
|
+
template: `
|
|
29
|
+
<div class="flex items-center gap-8">
|
|
30
|
+
<div class="text-center">
|
|
31
|
+
<DXValidationIcon state="success" size="lg" />
|
|
32
|
+
<p class="text-xs mt-2 text-slate-600">Success</p>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="text-center">
|
|
35
|
+
<DXValidationIcon state="error" size="lg" />
|
|
36
|
+
<p class="text-xs mt-2 text-slate-600">Error</p>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="text-center">
|
|
39
|
+
<DXValidationIcon state="warning" size="lg" />
|
|
40
|
+
<p class="text-xs mt-2 text-slate-600">Warning</p>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="text-center">
|
|
43
|
+
<DXValidationIcon state="info" size="lg" />
|
|
44
|
+
<p class="text-xs mt-2 text-slate-600">Info</p>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
`,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const Sizes = () => ({
|
|
51
|
+
components: { DXValidationIcon },
|
|
52
|
+
template: `
|
|
53
|
+
<div class="flex items-center gap-4">
|
|
54
|
+
<DXValidationIcon state="success" size="sm" />
|
|
55
|
+
<DXValidationIcon state="success" size="md" />
|
|
56
|
+
<DXValidationIcon state="success" size="lg" />
|
|
57
|
+
</div>
|
|
58
|
+
`,
|
|
59
|
+
});
|
|
60
|
+
|