dxd-style-code 0.1.7 → 0.1.8
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 +13 -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/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,479 @@
|
|
|
1
|
+
# DXMenu
|
|
2
|
+
|
|
3
|
+
Встраиваемый компонент меню для размещения в карточках и контейнерах. Поддерживает вертикальное и горизонтальное направление, вложенные элементы, иконки, счетчики, поиск и компактный режим.
|
|
4
|
+
|
|
5
|
+
## Отличия от DXSidebarMenu
|
|
6
|
+
|
|
7
|
+
| Характеристика | DXMenu | DXSidebarMenu |
|
|
8
|
+
|----------------|--------|---------------|
|
|
9
|
+
| **Назначение** | Встраиваемое меню в карточках | Полноэкранная боковая панель |
|
|
10
|
+
| **Размеры** | `w-full h-full` (100% контейнера) | Фиксированная ширина (sm/md/lg) |
|
|
11
|
+
| **Скругления** | `rounded-xl` (всегда) | Без скруглений |
|
|
12
|
+
| **Бордер** | `border` (со всех сторон) | `border-r` (только справа) |
|
|
13
|
+
| **Тень** | Без тени | `shadow-sm` |
|
|
14
|
+
| **Fixed position** | Не поддерживается | Поддерживается |
|
|
15
|
+
| **Width prop** | Не поддерживается | sm / md / lg / full |
|
|
16
|
+
|
|
17
|
+
## Возможности
|
|
18
|
+
|
|
19
|
+
- ✅ **Два направления** - вертикальное (по умолчанию) и горизонтальное (navbar)
|
|
20
|
+
- ✅ **Активное состояние** - автоматическое выделение активного пункта меню
|
|
21
|
+
- ✅ **Переключение между страницами** - поддержка `router-link` и обычных ссылок
|
|
22
|
+
- ✅ **Иконки** - поддержка HeroIcons и любых Vue компонентов
|
|
23
|
+
- ✅ **Счетчики (badges)** - отображение количества уведомлений/элементов
|
|
24
|
+
- ✅ **Вложенное меню** - поддержка подменю с анимацией (dropdown для horizontal)
|
|
25
|
+
- ✅ **Компактный режим** - сворачивание до иконок (только vertical)
|
|
26
|
+
- ✅ **Поиск** - фильтрация пунктов меню
|
|
27
|
+
- ✅ **Секции** - группировка элементов с заголовками
|
|
28
|
+
- ✅ **Кастомизация** - слоты для header и footer
|
|
29
|
+
- ✅ **Адаптивность** - занимает 100% ширины и высоты контейнера
|
|
30
|
+
|
|
31
|
+
## Использование
|
|
32
|
+
|
|
33
|
+
### Базовый пример
|
|
34
|
+
|
|
35
|
+
```vue
|
|
36
|
+
<template>
|
|
37
|
+
<DXMenu
|
|
38
|
+
title="Навигация"
|
|
39
|
+
:sections="menuSections"
|
|
40
|
+
:activeItem="currentPage"
|
|
41
|
+
class="w-80 h-96"
|
|
42
|
+
@item-click="handleNavigation"
|
|
43
|
+
/>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script setup>
|
|
47
|
+
import { ref } from 'vue';
|
|
48
|
+
import { DXMenu } from 'dxd-style-code';
|
|
49
|
+
import { HomeIcon, UsersIcon, Cog6ToothIcon } from '@heroicons/vue/24/outline';
|
|
50
|
+
|
|
51
|
+
const currentPage = ref('/home');
|
|
52
|
+
|
|
53
|
+
const menuSections = [
|
|
54
|
+
{
|
|
55
|
+
items: [
|
|
56
|
+
{
|
|
57
|
+
id: 'home',
|
|
58
|
+
label: 'Главная',
|
|
59
|
+
icon: HomeIcon,
|
|
60
|
+
to: '/home',
|
|
61
|
+
badge: '5',
|
|
62
|
+
badgeVariant: 'danger'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'users',
|
|
66
|
+
label: 'Пользователи',
|
|
67
|
+
icon: UsersIcon,
|
|
68
|
+
to: '/users',
|
|
69
|
+
badge: '12'
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
title: 'Настройки',
|
|
75
|
+
items: [
|
|
76
|
+
{
|
|
77
|
+
id: 'settings',
|
|
78
|
+
label: 'Настройки',
|
|
79
|
+
icon: Cog6ToothIcon,
|
|
80
|
+
children: [
|
|
81
|
+
{ id: 'profile', label: 'Профиль', to: '/settings/profile' },
|
|
82
|
+
{ id: 'security', label: 'Безопасность', to: '/settings/security' },
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
const handleNavigation = (item) => {
|
|
90
|
+
currentPage.value = item.to || item.id;
|
|
91
|
+
};
|
|
92
|
+
</script>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### С поиском и компактным режимом
|
|
96
|
+
|
|
97
|
+
```vue
|
|
98
|
+
<template>
|
|
99
|
+
<DXMenu
|
|
100
|
+
title="Меню"
|
|
101
|
+
:sections="menuSections"
|
|
102
|
+
:activeItem="currentPage"
|
|
103
|
+
:compact="isCompact"
|
|
104
|
+
searchable
|
|
105
|
+
collapsible
|
|
106
|
+
class="w-80 h-96"
|
|
107
|
+
@update:compact="isCompact = $event"
|
|
108
|
+
@item-click="handleNavigation"
|
|
109
|
+
/>
|
|
110
|
+
</template>
|
|
111
|
+
|
|
112
|
+
<script setup>
|
|
113
|
+
import { ref } from 'vue';
|
|
114
|
+
|
|
115
|
+
const isCompact = ref(false);
|
|
116
|
+
const currentPage = ref('/home');
|
|
117
|
+
</script>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### С кастомным header и footer
|
|
121
|
+
|
|
122
|
+
```vue
|
|
123
|
+
<template>
|
|
124
|
+
<DXMenu
|
|
125
|
+
:sections="menuSections"
|
|
126
|
+
:activeItem="currentPage"
|
|
127
|
+
class="w-96 h-[500px]"
|
|
128
|
+
>
|
|
129
|
+
<template #header>
|
|
130
|
+
<div class="flex items-center gap-3">
|
|
131
|
+
<div class="w-10 h-10 rounded-xl bg-blue-500 flex items-center justify-center text-white font-bold">
|
|
132
|
+
A
|
|
133
|
+
</div>
|
|
134
|
+
<div>
|
|
135
|
+
<h2 class="text-sm font-bold">Admin Panel</h2>
|
|
136
|
+
<p class="text-xs text-slate-500">v2.0.0</p>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</template>
|
|
140
|
+
|
|
141
|
+
<template #footer>
|
|
142
|
+
<DXButton variant="ghost" block @click="logout">
|
|
143
|
+
Выйти
|
|
144
|
+
</DXButton>
|
|
145
|
+
</template>
|
|
146
|
+
</DXMenu>
|
|
147
|
+
</template>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### С настройкой варианта и padding
|
|
151
|
+
|
|
152
|
+
```vue
|
|
153
|
+
<template>
|
|
154
|
+
<!-- Elevated вариант с большой тенью -->
|
|
155
|
+
<DXMenu
|
|
156
|
+
title="Меню"
|
|
157
|
+
:sections="menuSections"
|
|
158
|
+
:activeItem="currentPage"
|
|
159
|
+
cardVariant="elevated"
|
|
160
|
+
cardPadding="md"
|
|
161
|
+
class="w-80 h-96"
|
|
162
|
+
/>
|
|
163
|
+
|
|
164
|
+
<!-- Bordered вариант с толстым бордером -->
|
|
165
|
+
<DXMenu
|
|
166
|
+
:sections="menuSections"
|
|
167
|
+
cardVariant="bordered"
|
|
168
|
+
class="w-80 h-96"
|
|
169
|
+
/>
|
|
170
|
+
|
|
171
|
+
<!-- Flat вариант без бордера и тени -->
|
|
172
|
+
<DXMenu
|
|
173
|
+
:sections="menuSections"
|
|
174
|
+
cardVariant="flat"
|
|
175
|
+
class="w-80 h-96"
|
|
176
|
+
/>
|
|
177
|
+
</template>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Управление header
|
|
181
|
+
|
|
182
|
+
```vue
|
|
183
|
+
<!-- Без header -->
|
|
184
|
+
<DXMenu
|
|
185
|
+
:sections="sections"
|
|
186
|
+
:showHeader="false"
|
|
187
|
+
class="w-80 h-96"
|
|
188
|
+
/>
|
|
189
|
+
|
|
190
|
+
<!-- С компактным header -->
|
|
191
|
+
<DXMenu
|
|
192
|
+
title="Меню"
|
|
193
|
+
:sections="sections"
|
|
194
|
+
headerSize="sm"
|
|
195
|
+
class="w-80 h-96"
|
|
196
|
+
/>
|
|
197
|
+
|
|
198
|
+
<!-- С большим header -->
|
|
199
|
+
<DXMenu
|
|
200
|
+
title="Большой заголовок"
|
|
201
|
+
:sections="sections"
|
|
202
|
+
headerSize="lg"
|
|
203
|
+
class="w-80 h-96"
|
|
204
|
+
/>
|
|
205
|
+
|
|
206
|
+
<!-- Автоматическое скрытие header -->
|
|
207
|
+
<!-- Header не отображается, так как нет title, слота header и collapsible=false -->
|
|
208
|
+
<DXMenu
|
|
209
|
+
:sections="sections"
|
|
210
|
+
:collapsible="false"
|
|
211
|
+
class="w-80 h-96"
|
|
212
|
+
/>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Горизонтальное меню
|
|
216
|
+
|
|
217
|
+
```vue
|
|
218
|
+
<!-- Базовое горизонтальное меню -->
|
|
219
|
+
<DXMenu
|
|
220
|
+
title="Навигация"
|
|
221
|
+
:sections="sections"
|
|
222
|
+
:activeItem="currentPage"
|
|
223
|
+
direction="horizontal"
|
|
224
|
+
class="w-full"
|
|
225
|
+
@item-click="handleNavigation"
|
|
226
|
+
/>
|
|
227
|
+
|
|
228
|
+
<!-- Горизонтальное меню с поиском -->
|
|
229
|
+
<DXMenu
|
|
230
|
+
title="Меню"
|
|
231
|
+
:sections="sections"
|
|
232
|
+
:activeItem="currentPage"
|
|
233
|
+
direction="horizontal"
|
|
234
|
+
searchable
|
|
235
|
+
class="w-full"
|
|
236
|
+
/>
|
|
237
|
+
|
|
238
|
+
<!-- Navbar стиль (без header) -->
|
|
239
|
+
<DXMenu
|
|
240
|
+
:sections="sections"
|
|
241
|
+
:activeItem="currentPage"
|
|
242
|
+
direction="horizontal"
|
|
243
|
+
:showHeader="false"
|
|
244
|
+
cardVariant="flat"
|
|
245
|
+
class="w-full"
|
|
246
|
+
/>
|
|
247
|
+
|
|
248
|
+
<!-- Горизонтальное меню с submenu (через dropdown) -->
|
|
249
|
+
<DXMenu
|
|
250
|
+
title="Панель управления"
|
|
251
|
+
:sections="sectionsWithSubmenu"
|
|
252
|
+
:activeItem="currentPage"
|
|
253
|
+
direction="horizontal"
|
|
254
|
+
class="w-full"
|
|
255
|
+
/>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Props
|
|
259
|
+
|
|
260
|
+
| Prop | Type | Default | Описание |
|
|
261
|
+
|------|------|---------|----------|
|
|
262
|
+
| `direction` | String | `'vertical'` | Направление: vertical, horizontal |
|
|
263
|
+
| `title` | String | `''` | Заголовок меню |
|
|
264
|
+
| `sections` | Array | required | Массив секций меню |
|
|
265
|
+
| `activeItem` | String | `''` | ID или path активного элемента |
|
|
266
|
+
| `compact` | Boolean | `false` | Компактный режим (только vertical) |
|
|
267
|
+
| `collapsible` | Boolean | `false` | Можно ли сворачивать (только vertical) |
|
|
268
|
+
| `searchable` | Boolean | `false` | Показывать поиск |
|
|
269
|
+
| `showHeader` | Boolean | `undefined` | Показывать header (undefined = автоматически) |
|
|
270
|
+
| `headerSize` | String | `'md'` | Размер header: sm, md, lg (только vertical) |
|
|
271
|
+
| `cardPadding` | String | `'none'` | Padding карточки: none, sm, md, lg |
|
|
272
|
+
| `cardVariant` | String | `'default'` | Вариант карточки: default, bordered, elevated, flat |
|
|
273
|
+
|
|
274
|
+
## Структура данных sections
|
|
275
|
+
|
|
276
|
+
```javascript
|
|
277
|
+
const sections = [
|
|
278
|
+
{
|
|
279
|
+
title: 'Название секции', // опционально
|
|
280
|
+
items: [
|
|
281
|
+
{
|
|
282
|
+
id: 'unique-id', // уникальный идентификатор
|
|
283
|
+
label: 'Пункт меню', // текст
|
|
284
|
+
icon: IconComponent, // Vue компонент иконки
|
|
285
|
+
to: '/path', // для router-link
|
|
286
|
+
href: 'https://...', // для обычной ссылки
|
|
287
|
+
badge: '5', // счетчик
|
|
288
|
+
badgeVariant: 'danger', // вариант badge: info, success, warning, danger
|
|
289
|
+
disabled: false, // отключить элемент
|
|
290
|
+
children: [ // подменю
|
|
291
|
+
{
|
|
292
|
+
id: 'child-id',
|
|
293
|
+
label: 'Подпункт',
|
|
294
|
+
to: '/path/child',
|
|
295
|
+
badge: '2'
|
|
296
|
+
}
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}
|
|
301
|
+
];
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Events
|
|
305
|
+
|
|
306
|
+
| Event | Payload | Описание |
|
|
307
|
+
|-------|---------|----------|
|
|
308
|
+
| `item-click` | `(item, event)` | Клик по элементу меню |
|
|
309
|
+
| `update:compact` | `boolean` | Изменение компактного режима |
|
|
310
|
+
|
|
311
|
+
## Slots
|
|
312
|
+
|
|
313
|
+
| Slot | Описание |
|
|
314
|
+
|------|----------|
|
|
315
|
+
| `header` | Кастомный заголовок меню |
|
|
316
|
+
| `footer` | Контент в футере меню |
|
|
317
|
+
|
|
318
|
+
## Примеры использования
|
|
319
|
+
|
|
320
|
+
### Dashboard панель
|
|
321
|
+
|
|
322
|
+
```vue
|
|
323
|
+
<DXMenu
|
|
324
|
+
:sections="dashboardSections"
|
|
325
|
+
:activeItem="currentPage"
|
|
326
|
+
searchable
|
|
327
|
+
class="w-80 h-96"
|
|
328
|
+
>
|
|
329
|
+
<template #header>
|
|
330
|
+
<div class="flex items-center gap-3">
|
|
331
|
+
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-bold">
|
|
332
|
+
D
|
|
333
|
+
</div>
|
|
334
|
+
<div>
|
|
335
|
+
<h2 class="text-sm font-bold">Dashboard</h2>
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
</template>
|
|
339
|
+
</DXMenu>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Компактное меню
|
|
343
|
+
|
|
344
|
+
```vue
|
|
345
|
+
<DXMenu
|
|
346
|
+
:sections="sections"
|
|
347
|
+
:activeItem="currentPage"
|
|
348
|
+
:compact="true"
|
|
349
|
+
class="w-24 h-96"
|
|
350
|
+
/>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### С Vue Router
|
|
354
|
+
|
|
355
|
+
```vue
|
|
356
|
+
<script setup>
|
|
357
|
+
import { useRoute } from 'vue-router';
|
|
358
|
+
import { computed } from 'vue';
|
|
359
|
+
|
|
360
|
+
const route = useRoute();
|
|
361
|
+
const currentPage = computed(() => route.path);
|
|
362
|
+
|
|
363
|
+
const handleNavigation = (item) => {
|
|
364
|
+
// router.push автоматически сработает через router-link
|
|
365
|
+
console.log('Navigating to:', item.to);
|
|
366
|
+
};
|
|
367
|
+
</script>
|
|
368
|
+
|
|
369
|
+
<template>
|
|
370
|
+
<DXMenu
|
|
371
|
+
:sections="sections"
|
|
372
|
+
:activeItem="currentPage"
|
|
373
|
+
class="w-80 h-96"
|
|
374
|
+
@item-click="handleNavigation"
|
|
375
|
+
/>
|
|
376
|
+
</template>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Стилизация
|
|
380
|
+
|
|
381
|
+
Компонент использует `DXCard` внутри и Tailwind CSS классы, полностью адаптируется под вашу тему. Активные элементы выделяются темным фоном с тенью.
|
|
382
|
+
|
|
383
|
+
### Управление стилями карточки:
|
|
384
|
+
|
|
385
|
+
**`cardVariant`** - вариант оформления:
|
|
386
|
+
- `default` - тонкий бордер `border-slate-100` + тень `shadow-sm`
|
|
387
|
+
- `bordered` - толстый бордер `border-2 border-slate-200`, без тени
|
|
388
|
+
- `elevated` - светлый бордер `border-slate-50` + большая тень `shadow-lg`
|
|
389
|
+
- `flat` - без бордера и тени
|
|
390
|
+
|
|
391
|
+
**`cardPadding`** - внутренние отступы:
|
|
392
|
+
- `none` - без отступов
|
|
393
|
+
- `sm` - `p-3`
|
|
394
|
+
- `md` - `p-5`
|
|
395
|
+
- `lg` - `p-8`
|
|
396
|
+
|
|
397
|
+
**`class`** - дополнительные классы для размеров (w-80, h-96 и т.д.)
|
|
398
|
+
|
|
399
|
+
### Автоматические стили от DXCard:
|
|
400
|
+
- `rounded-2xl` - скругленные углы
|
|
401
|
+
- `bg-white` - белый фон
|
|
402
|
+
|
|
403
|
+
## Accessibility
|
|
404
|
+
|
|
405
|
+
- Семантический HTML (`<nav>`, `<button>`, `<a>`)
|
|
406
|
+
- ARIA атрибуты для состояний
|
|
407
|
+
- Поддержка клавиатурной навигации
|
|
408
|
+
- Правильные role атрибуты
|
|
409
|
+
|
|
410
|
+
## Композиция
|
|
411
|
+
|
|
412
|
+
`DXMenu` использует [`DXCard`](../../atoms/DXCard/README.md) внутри как базовый контейнер, что обеспечивает:
|
|
413
|
+
- Единое оформление карточек во всем приложении
|
|
414
|
+
- Управление тенью, padding, вариантами через props
|
|
415
|
+
- Не нужно оборачивать в DXCard вручную
|
|
416
|
+
- Автоматическое применение стилей карточки (rounded, border, overflow)
|
|
417
|
+
|
|
418
|
+
Также использует общий composable `useMenu` с `DXSidebarMenu`, что обеспечивает:
|
|
419
|
+
- Единую бизнес-логику
|
|
420
|
+
- Одинаковое поведение
|
|
421
|
+
- Легкую поддержку
|
|
422
|
+
|
|
423
|
+
## Когда использовать DXMenu vs DXSidebarMenu
|
|
424
|
+
|
|
425
|
+
**Используйте DXMenu когда:**
|
|
426
|
+
- Нужно встроить меню в карточку или контейнер
|
|
427
|
+
- Требуется горизонтальная навигация (navbar)
|
|
428
|
+
- Меню является частью layout, а не отдельной панелью
|
|
429
|
+
- Требуется адаптивность к размерам контейнера
|
|
430
|
+
- Нужны скругленные углы и бордер со всех сторон
|
|
431
|
+
|
|
432
|
+
**Используйте DXSidebarMenu когда:**
|
|
433
|
+
- Нужна полноэкранная боковая панель
|
|
434
|
+
- Требуется фиксированная позиция (fixed)
|
|
435
|
+
- Меню должно быть отдельным layout элементом
|
|
436
|
+
- Нужна тень и бордер только справа
|
|
437
|
+
- Только вертикальное направление
|
|
438
|
+
|
|
439
|
+
## Особенности горизонтального режима
|
|
440
|
+
|
|
441
|
+
### Автоматические изменения в `direction="horizontal"`:
|
|
442
|
+
|
|
443
|
+
1. **Layout меняется на горизонтальный**:
|
|
444
|
+
- Items располагаются в строку (`flex-row`)
|
|
445
|
+
- Автоматический горизонтальный скролл (`overflow-x-auto`)
|
|
446
|
+
|
|
447
|
+
2. **Header в одну строку**:
|
|
448
|
+
- Title, Search и Toggle размещаются в одну строку
|
|
449
|
+
- Search inline с классом `max-w-xs`
|
|
450
|
+
|
|
451
|
+
3. **Submenu через Dropdown**:
|
|
452
|
+
- Вместо встроенного submenu используется `DXDropdown`
|
|
453
|
+
- Submenu открывается вниз как dropdown
|
|
454
|
+
|
|
455
|
+
4. **Отключаются некоторые фичи**:
|
|
456
|
+
- Section titles не отображаются
|
|
457
|
+
- Footer не отображается
|
|
458
|
+
- Compact режим недоступен
|
|
459
|
+
|
|
460
|
+
5. **Стили элементов меняются**:
|
|
461
|
+
- Меньше padding: `px-3 py-2` вместо `px-4 py-2.5`
|
|
462
|
+
- Меньше gap: `gap-2` вместо `gap-3`
|
|
463
|
+
- Класс `whitespace-nowrap` для предотвращения переноса
|
|
464
|
+
|
|
465
|
+
### Navbar стиль:
|
|
466
|
+
|
|
467
|
+
Для создания navbar используйте:
|
|
468
|
+
```vue
|
|
469
|
+
<DXMenu
|
|
470
|
+
:sections="sections"
|
|
471
|
+
direction="horizontal"
|
|
472
|
+
:showHeader="false"
|
|
473
|
+
cardVariant="flat"
|
|
474
|
+
class="w-full"
|
|
475
|
+
/>
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Это создаст чистую горизонтальную навигацию без header и без бордера/тени.
|
|
479
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import DXPagination from './DXPagination.vue';
|
|
2
|
+
import { ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Molecules/DXPagination',
|
|
6
|
+
component: DXPagination,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
argTypes: {
|
|
9
|
+
size: { control: { type: 'select' }, options: ['sm', 'md', 'lg'] },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const Default = {
|
|
14
|
+
render: () => ({
|
|
15
|
+
components: { DXPagination },
|
|
16
|
+
setup() {
|
|
17
|
+
const page = ref(1);
|
|
18
|
+
return { page };
|
|
19
|
+
},
|
|
20
|
+
template: '<DXPagination v-model="page" :total-pages="10" />',
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const MiddlePage = {
|
|
25
|
+
render: () => ({
|
|
26
|
+
components: { DXPagination },
|
|
27
|
+
setup() {
|
|
28
|
+
const page = ref(5);
|
|
29
|
+
return { page };
|
|
30
|
+
},
|
|
31
|
+
template: '<DXPagination v-model="page" :total-pages="10" />',
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const ManyPages = {
|
|
36
|
+
render: () => ({
|
|
37
|
+
components: { DXPagination },
|
|
38
|
+
setup() {
|
|
39
|
+
const page = ref(15);
|
|
40
|
+
return { page };
|
|
41
|
+
},
|
|
42
|
+
template: '<DXPagination v-model="page" :total-pages="50" />',
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const Sizes = {
|
|
47
|
+
render: () => ({
|
|
48
|
+
components: { DXPagination },
|
|
49
|
+
setup() {
|
|
50
|
+
const page = ref(1);
|
|
51
|
+
return { page };
|
|
52
|
+
},
|
|
53
|
+
template: `
|
|
54
|
+
<div class="space-y-4">
|
|
55
|
+
<DXPagination v-model="page" :total-pages="10" size="sm" />
|
|
56
|
+
<DXPagination v-model="page" :total-pages="10" size="md" />
|
|
57
|
+
<DXPagination v-model="page" :total-pages="10" size="lg" />
|
|
58
|
+
</div>
|
|
59
|
+
`,
|
|
60
|
+
}),
|
|
61
|
+
};
|
|
62
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<nav class="flex items-center gap-1" aria-label="Pagination" data-component="DXPagination">
|
|
3
|
+
<!-- Previous -->
|
|
4
|
+
<button
|
|
5
|
+
type="button"
|
|
6
|
+
:disabled="modelValue <= 1"
|
|
7
|
+
:class="[navButtonClasses, modelValue <= 1 && 'opacity-50 cursor-not-allowed']"
|
|
8
|
+
@click="goTo(modelValue - 1)"
|
|
9
|
+
aria-label="Предыдущая"
|
|
10
|
+
>
|
|
11
|
+
<DXIcon :icon="ChevronLeftIcon" size="sm" animation="none" />
|
|
12
|
+
</button>
|
|
13
|
+
|
|
14
|
+
<!-- Pages -->
|
|
15
|
+
<template v-for="page in visiblePages" :key="page">
|
|
16
|
+
<span v-if="page === '...'" class="px-2 text-slate-400">...</span>
|
|
17
|
+
<button
|
|
18
|
+
v-else
|
|
19
|
+
type="button"
|
|
20
|
+
:class="[pageButtonClasses, page === modelValue && activeClasses]"
|
|
21
|
+
:aria-current="page === modelValue ? 'page' : undefined"
|
|
22
|
+
@click="goTo(page)"
|
|
23
|
+
>
|
|
24
|
+
{{ page }}
|
|
25
|
+
</button>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<!-- Next -->
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
:disabled="modelValue >= totalPages"
|
|
32
|
+
:class="[navButtonClasses, modelValue >= totalPages && 'opacity-50 cursor-not-allowed']"
|
|
33
|
+
@click="goTo(modelValue + 1)"
|
|
34
|
+
aria-label="Следующая"
|
|
35
|
+
>
|
|
36
|
+
<DXIcon :icon="ChevronRightIcon" size="sm" animation="none" />
|
|
37
|
+
</button>
|
|
38
|
+
</nav>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup>
|
|
42
|
+
import { computed } from "vue";
|
|
43
|
+
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/vue/24/outline";
|
|
44
|
+
import DXIcon from "../../atoms/DXIcon/DXIcon.vue";
|
|
45
|
+
|
|
46
|
+
const props = defineProps({
|
|
47
|
+
/** Текущая страница (v-model) */
|
|
48
|
+
modelValue: { type: Number, default: 1 },
|
|
49
|
+
/** Всего страниц */
|
|
50
|
+
totalPages: { type: Number, required: true },
|
|
51
|
+
/** Сколько страниц показывать вокруг текущей */
|
|
52
|
+
siblingCount: { type: Number, default: 1 },
|
|
53
|
+
/** Размер: sm | md | lg */
|
|
54
|
+
size: { type: String, default: "md" },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
58
|
+
|
|
59
|
+
const goTo = (page) => {
|
|
60
|
+
if (page >= 1 && page <= props.totalPages) {
|
|
61
|
+
emit("update:modelValue", page);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const visiblePages = computed(() => {
|
|
66
|
+
const current = props.modelValue;
|
|
67
|
+
const total = props.totalPages;
|
|
68
|
+
const siblings = props.siblingCount;
|
|
69
|
+
|
|
70
|
+
const pages = [];
|
|
71
|
+
|
|
72
|
+
// Always show first page
|
|
73
|
+
pages.push(1);
|
|
74
|
+
|
|
75
|
+
// Calculate range around current
|
|
76
|
+
const leftSibling = Math.max(2, current - siblings);
|
|
77
|
+
const rightSibling = Math.min(total - 1, current + siblings);
|
|
78
|
+
|
|
79
|
+
// Add ellipsis after first if needed
|
|
80
|
+
if (leftSibling > 2) {
|
|
81
|
+
pages.push("...");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Add pages around current
|
|
85
|
+
for (let i = leftSibling; i <= rightSibling; i++) {
|
|
86
|
+
if (i !== 1 && i !== total) {
|
|
87
|
+
pages.push(i);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Add ellipsis before last if needed
|
|
92
|
+
if (rightSibling < total - 1) {
|
|
93
|
+
pages.push("...");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Always show last page if more than 1
|
|
97
|
+
if (total > 1) {
|
|
98
|
+
pages.push(total);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return pages;
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const sizeClasses = {
|
|
105
|
+
sm: "h-7 min-w-7 text-xs",
|
|
106
|
+
md: "h-9 min-w-9 text-sm",
|
|
107
|
+
lg: "h-11 min-w-11 text-base",
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const navButtonClasses = computed(() => [
|
|
111
|
+
"inline-flex items-center justify-center rounded-lg border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 hover:border-slate-300 transition-colors",
|
|
112
|
+
sizeClasses[props.size] || sizeClasses.md,
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
const pageButtonClasses = computed(() => [
|
|
116
|
+
"inline-flex items-center justify-center rounded-lg font-medium transition-colors",
|
|
117
|
+
sizeClasses[props.size] || sizeClasses.md,
|
|
118
|
+
"text-slate-600 hover:bg-slate-100",
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
const activeClasses = "bg-slate-900 text-white hover:bg-slate-800";
|
|
122
|
+
</script>
|
|
123
|
+
|