@mindlogic-ai/logician-ui 2.0.0-alpha.0
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/LICENSE +21 -0
- package/README.md +234 -0
- package/USAGE.md +299 -0
- package/dist/Markdown-2D5K42BY.js +16 -0
- package/dist/Markdown-2D5K42BY.js.map +1 -0
- package/dist/Markdown-AZBXO5ZP.css +29 -0
- package/dist/Markdown-AZBXO5ZP.css.map +1 -0
- package/dist/Markdown-RJJEQN4R.mjs +3 -0
- package/dist/Markdown-RJJEQN4R.mjs.map +1 -0
- package/dist/analytics-GNSHP7X3.svg +1 -0
- package/dist/bulb-24SQINQB.svg +1 -0
- package/dist/chat-TLRFEUAS.svg +1 -0
- package/dist/chunk-5FHXD7KR.js +1735 -0
- package/dist/chunk-5FHXD7KR.js.map +1 -0
- package/dist/chunk-WSOHBA2C.mjs +1693 -0
- package/dist/chunk-WSOHBA2C.mjs.map +1 -0
- package/dist/edit-RWL72JNM.svg +1 -0
- package/dist/face-55KPDCH4.svg +1 -0
- package/dist/filled-analytics-RBC7KWND.svg +1 -0
- package/dist/filled-bulb-RC7E2WSM.svg +1 -0
- package/dist/filled-chat-A6J44Q7A.svg +1 -0
- package/dist/filled-edit-NKKWFSTW.svg +1 -0
- package/dist/filled-face-UML5C3LB.svg +1 -0
- package/dist/filled-layout-HBVCSDFO.svg +1 -0
- package/dist/index.css +51 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +964 -0
- package/dist/index.d.ts +964 -0
- package/dist/index.js +5600 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5401 -0
- package/dist/index.mjs.map +1 -0
- package/dist/language-VBJ24OPV.svg +1 -0
- package/dist/layout-NDDSWNNV.svg +1 -0
- package/dist/pending-NF7NSBYO.svg +1 -0
- package/dist/receipt-MNLQIFCO.svg +1 -0
- package/dist/sparkles-EOEGVL6G.svg +1 -0
- package/dist/store-3RQPBJWG.svg +1 -0
- package/dist/store_active-SAOAGVKC.svg +1 -0
- package/dist/studio-LYPUIEFA.svg +1 -0
- package/dist/studio_active-BC6O66OI.svg +1 -0
- package/dist/vertical-ellipsis-3G4WEOCW.svg +1 -0
- package/package.json +138 -0
- package/src/components/Accordion/Accordion.stories.tsx +41 -0
- package/src/components/Accordion/Accordion.tsx +14 -0
- package/src/components/Accordion/AccordionButton.tsx +40 -0
- package/src/components/Accordion/AccordionItem.tsx +17 -0
- package/src/components/Accordion/index.ts +4 -0
- package/src/components/Alert/Alert.stories.tsx +38 -0
- package/src/components/Alert/Alert.styles.ts +19 -0
- package/src/components/Alert/Alert.tsx +41 -0
- package/src/components/Alert/Alert.types.ts +5 -0
- package/src/components/Alert/index.ts +1 -0
- package/src/components/AutowidthInput/AutowidthInput.stories.tsx +23 -0
- package/src/components/AutowidthInput/AutowidthInput.tsx +47 -0
- package/src/components/AutowidthInput/index.ts +1 -0
- package/src/components/Avatar/Avatar.stories.tsx +23 -0
- package/src/components/Avatar/Avatar.tsx +19 -0
- package/src/components/Avatar/index.tsx +1 -0
- package/src/components/Badge/Badge.stories.tsx +23 -0
- package/src/components/Badge/Badge.styles.ts +11 -0
- package/src/components/Badge/Badge.tsx +26 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Banner/Banner.stories.tsx +37 -0
- package/src/components/Banner/Banner.styles.ts +79 -0
- package/src/components/Banner/Banner.tsx +68 -0
- package/src/components/Banner/Banner.types.ts +6 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +14 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +19 -0
- package/src/components/Breadcrumb/Breadcrumb.types.ts +3 -0
- package/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.tsx +12 -0
- package/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.types.ts +3 -0
- package/src/components/Breadcrumb/BreadcrumbItem/index.ts +2 -0
- package/src/components/Breadcrumb/BreadcrumbLink/BreadcrumbLink.tsx +30 -0
- package/src/components/Breadcrumb/BreadcrumbLink/BreadcrumbLink.types.ts +3 -0
- package/src/components/Breadcrumb/BreadcrumbLink/index.ts +2 -0
- package/src/components/Breadcrumb/index.ts +3 -0
- package/src/components/Button/Button.stories.tsx +52 -0
- package/src/components/Button/Button.styles.ts +59 -0
- package/src/components/Button/Button.tsx +43 -0
- package/src/components/Button/Button.types.ts +13 -0
- package/src/components/Button/index.tsx +3 -0
- package/src/components/Card/Card.stories.tsx +24 -0
- package/src/components/Card/Card.styles.ts +30 -0
- package/src/components/Card/Card.tsx +29 -0
- package/src/components/Card/Card.types.ts +8 -0
- package/src/components/Card/index.ts +2 -0
- package/src/components/Carousel/Carousel.stories.tsx +159 -0
- package/src/components/Carousel/Carousel.tsx +160 -0
- package/src/components/Carousel/Carousel.types.ts +22 -0
- package/src/components/Carousel/index.ts +1 -0
- package/src/components/CarouselModal/CarouselModal.stories.tsx +53 -0
- package/src/components/CarouselModal/CarouselModal.tsx +106 -0
- package/src/components/CarouselModal/CarouselModal.types.ts +16 -0
- package/src/components/CarouselModal/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +16 -0
- package/src/components/Checkbox/Checkbox.tsx +29 -0
- package/src/components/Checkbox/Checkbox.types.ts +3 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/Chip/Chip.stories.tsx +44 -0
- package/src/components/Chip/Chip.styles.ts +114 -0
- package/src/components/Chip/Chip.tsx +23 -0
- package/src/components/Chip/Chip.types.ts +14 -0
- package/src/components/Chip/index.ts +2 -0
- package/src/components/ChipButton/Chip.types.ts +4 -0
- package/src/components/ChipButton/ChipButton.tsx +25 -0
- package/src/components/ChipButton/index.ts +1 -0
- package/src/components/Code/Code.stories.tsx +28 -0
- package/src/components/Code/Code.tsx +160 -0
- package/src/components/Code/Code.types.ts +40 -0
- package/src/components/Code/_components/CopyButton.tsx +48 -0
- package/src/components/Code/index.ts +1 -0
- package/src/components/CodeTabs/CodeTabs.stories.tsx +51 -0
- package/src/components/CodeTabs/CodeTabs.tsx +98 -0
- package/src/components/CodeTabs/CodeTabs.types.ts +17 -0
- package/src/components/CodeTabs/index.ts +1 -0
- package/src/components/Container/Container.stories.tsx +28 -0
- package/src/components/Container/Container.tsx +21 -0
- package/src/components/Container/index.ts +1 -0
- package/src/components/Container/useContainerSize.ts +47 -0
- package/src/components/CopyableCode/CopyableCode.stories.tsx +26 -0
- package/src/components/CopyableCode/CopyableCode.tsx +58 -0
- package/src/components/CopyableCode/CopyableCode.types.ts +7 -0
- package/src/components/CopyableCode/index.ts +2 -0
- package/src/components/CrossPageToasts/CrossPageToasts.tsx +33 -0
- package/src/components/CrossPageToasts/index.ts +1 -0
- package/src/components/DataField/DataField.stories.tsx +61 -0
- package/src/components/DataField/DataField.styles.ts +33 -0
- package/src/components/DataField/DataField.tsx +141 -0
- package/src/components/DataField/DataField.types.ts +18 -0
- package/src/components/DataField/index.ts +1 -0
- package/src/components/DatePicker/RangeDatePicker.stories.tsx +45 -0
- package/src/components/DatePicker/RangeDatePicker.tsx +74 -0
- package/src/components/DatePicker/SingleDatePicker.stories.tsx +31 -0
- package/src/components/DatePicker/SingleDatePicker.tsx +72 -0
- package/src/components/DatePicker/index.ts +2 -0
- package/src/components/FileInput/FileInput.stories.tsx +28 -0
- package/src/components/FileInput/FileInput.tsx +117 -0
- package/src/components/FileInput/FileInput.types.ts +14 -0
- package/src/components/FileInput/index.ts +2 -0
- package/src/components/FileItem/FileItem.stories.tsx +27 -0
- package/src/components/FileItem/FileItem.tsx +134 -0
- package/src/components/FileItem/FileItem.types.ts +11 -0
- package/src/components/FileItem/index.ts +1 -0
- package/src/components/FileList/FileList.stories.tsx +65 -0
- package/src/components/FileList/FileList.tsx +97 -0
- package/src/components/FileList/FileList.types.ts +18 -0
- package/src/components/FileList/index.tsx +1 -0
- package/src/components/FormControl/FormControl.stories.tsx +16 -0
- package/src/components/FormControl/FormControl.tsx +12 -0
- package/src/components/FormControl/FormControl.types.ts +3 -0
- package/src/components/FormControl/index.ts +2 -0
- package/src/components/FormLabel/FormLabel.tsx +5 -0
- package/src/components/FormLabel/index.ts +1 -0
- package/src/components/GuideCue/GuideCue.stories.tsx +57 -0
- package/src/components/GuideCue/GuideCue.tsx +231 -0
- package/src/components/GuideCue/GuideCueContext.tsx +70 -0
- package/src/components/GuideCue/index.ts +2 -0
- package/src/components/Icon/Icon.stories.tsx +77 -0
- package/src/components/Icon/Icon.styles.ts +6 -0
- package/src/components/Icon/Icon.tsx +73 -0
- package/src/components/Icon/Icon.types.ts +10 -0
- package/src/components/Icon/IconMap.ts +290 -0
- package/src/components/Icon/icons/analytics.svg +1 -0
- package/src/components/Icon/icons/bulb.svg +1 -0
- package/src/components/Icon/icons/chat.svg +1 -0
- package/src/components/Icon/icons/edit.svg +1 -0
- package/src/components/Icon/icons/face.svg +1 -0
- package/src/components/Icon/icons/filled-analytics.svg +1 -0
- package/src/components/Icon/icons/filled-bulb.svg +1 -0
- package/src/components/Icon/icons/filled-chat.svg +1 -0
- package/src/components/Icon/icons/filled-edit.svg +1 -0
- package/src/components/Icon/icons/filled-face.svg +1 -0
- package/src/components/Icon/icons/filled-layout.svg +1 -0
- package/src/components/Icon/icons/language.svg +1 -0
- package/src/components/Icon/icons/layout.svg +1 -0
- package/src/components/Icon/icons/pending.svg +1 -0
- package/src/components/Icon/icons/receipt.svg +1 -0
- package/src/components/Icon/icons/sparkles.svg +1 -0
- package/src/components/Icon/icons/store.svg +1 -0
- package/src/components/Icon/icons/store_active.svg +1 -0
- package/src/components/Icon/icons/studio.svg +1 -0
- package/src/components/Icon/icons/studio_active.svg +1 -0
- package/src/components/Icon/icons/vertical-ellipsis.svg +1 -0
- package/src/components/Icon/index.tsx +3 -0
- package/src/components/IconButton/IconButton.stories.tsx +51 -0
- package/src/components/IconButton/IconButton.styles.ts +52 -0
- package/src/components/IconButton/IconButton.tsx +36 -0
- package/src/components/IconButton/IconButton.types.ts +12 -0
- package/src/components/IconButton/index.tsx +1 -0
- package/src/components/InfoSprinkle/InfoSprinkle.stories.tsx +25 -0
- package/src/components/InfoSprinkle/InfoSprinkle.tsx +48 -0
- package/src/components/InfoSprinkle/index.ts +1 -0
- package/src/components/InlineCode/InlineCode.tsx +18 -0
- package/src/components/InlineCode/index.ts +1 -0
- package/src/components/Input/Input.stories.tsx +55 -0
- package/src/components/Input/Input.tsx +358 -0
- package/src/components/Input/Input.types.ts +19 -0
- package/src/components/Input/index.tsx +2 -0
- package/src/components/LineGraph/LineGraph.stories.tsx +98 -0
- package/src/components/LineGraph/LineGraph.tsx +88 -0
- package/src/components/LineGraph/LineGraph.types.ts +41 -0
- package/src/components/LineGraph/index.ts +1 -0
- package/src/components/Link/Link.styles.ts +13 -0
- package/src/components/Link/Link.tsx +93 -0
- package/src/components/Link/index.ts +1 -0
- package/src/components/Loaders/PageLoader.stories.tsx +29 -0
- package/src/components/Loaders/PageLoader.tsx +30 -0
- package/src/components/Loaders/SectionLoader.stories.tsx +26 -0
- package/src/components/Loaders/SectionLoader.tsx +30 -0
- package/src/components/Loaders/index.ts +1 -0
- package/src/components/MDXEditor/MDXEditor.css +21 -0
- package/src/components/MDXEditor/MDXEditor.stories.tsx +45 -0
- package/src/components/MDXEditor/MDXEditor.tsx +189 -0
- package/src/components/MDXEditor/MDXEditor.types.ts +6 -0
- package/src/components/MDXEditor/index.ts +1 -0
- package/src/components/Markdown/Markdown.module.css +30 -0
- package/src/components/Markdown/Markdown.tsx +133 -0
- package/src/components/Markdown/Markdown.types.ts +5 -0
- package/src/components/Markdown/index.ts +2 -0
- package/src/components/Masonry/Masonry.stories.tsx +288 -0
- package/src/components/Masonry/Masonry.tsx +187 -0
- package/src/components/Masonry/Masonry.types.ts +18 -0
- package/src/components/Masonry/index.ts +2 -0
- package/src/components/MaxLengthIndicator/MaxLengthIndicator.stories.tsx +26 -0
- package/src/components/MaxLengthIndicator/MaxLengthIndicator.tsx +25 -0
- package/src/components/MaxLengthIndicator/index.tsx +1 -0
- package/src/components/Menu/Menu.stories.tsx +186 -0
- package/src/components/Menu/MenuButton.tsx +8 -0
- package/src/components/Menu/MenuButton.types.ts +23 -0
- package/src/components/Menu/MenuItem.tsx +35 -0
- package/src/components/Menu/MenuItem.types.ts +13 -0
- package/src/components/Menu/MenuList.tsx +19 -0
- package/src/components/Menu/index.ts +7 -0
- package/src/components/Modal/Modal.stories.tsx +83 -0
- package/src/components/Modal/Modal.styles.ts +14 -0
- package/src/components/Modal/Modal.tsx +14 -0
- package/src/components/Modal/Modal.types.ts +3 -0
- package/src/components/Modal/ModalBody.tsx +9 -0
- package/src/components/Modal/ModalCloseButton.tsx +18 -0
- package/src/components/Modal/ModalContent/ModalContent.tsx +8 -0
- package/src/components/Modal/ModalContent/ModalContent.types.ts +3 -0
- package/src/components/Modal/ModalContent/index.ts +1 -0
- package/src/components/Modal/ModalFooter/ModalFooter.module.css +3 -0
- package/src/components/Modal/ModalFooter/ModalFooter.tsx +20 -0
- package/src/components/Modal/ModalFooter/index.ts +1 -0
- package/src/components/Modal/ModalHeader.tsx +9 -0
- package/src/components/Modal/ModalOverlay.tsx +9 -0
- package/src/components/Modal/index.tsx +8 -0
- package/src/components/MonthRangePicker/MonthButton/MonthButton.tsx +105 -0
- package/src/components/MonthRangePicker/MonthButton/MonthButton.types.ts +42 -0
- package/src/components/MonthRangePicker/MonthButton/index.ts +2 -0
- package/src/components/MonthRangePicker/MonthRangePicker.stories.tsx +164 -0
- package/src/components/MonthRangePicker/MonthRangePicker.tsx +274 -0
- package/src/components/MonthRangePicker/MonthRangePicker.types.ts +38 -0
- package/src/components/MonthRangePicker/_utils/hasEnabledMonthsInYear.ts +15 -0
- package/src/components/MonthRangePicker/_utils/index.ts +6 -0
- package/src/components/MonthRangePicker/_utils/isMonthDisabled.ts +20 -0
- package/src/components/MonthRangePicker/_utils/isMonthInPreviewRange.ts +32 -0
- package/src/components/MonthRangePicker/_utils/isMonthInRange.ts +17 -0
- package/src/components/MonthRangePicker/_utils/isMonthSelected.ts +19 -0
- package/src/components/MonthRangePicker/_utils/isSelectionStart.ts +12 -0
- package/src/components/MonthRangePicker/constants.ts +63 -0
- package/src/components/MonthRangePicker/index.ts +2 -0
- package/src/components/Pagination/Pagination.stories.tsx +51 -0
- package/src/components/Pagination/Pagination.tsx +150 -0
- package/src/components/Pagination/Pagination.types.ts +12 -0
- package/src/components/Pagination/index.tsx +1 -0
- package/src/components/PasswordInput/PasswordInput.stories.tsx +16 -0
- package/src/components/PasswordInput/PasswordInput.tsx +42 -0
- package/src/components/PasswordInput/PasswordInput.types.ts +11 -0
- package/src/components/PasswordInput/index.ts +1 -0
- package/src/components/PinInput/PinInput.stories.tsx +26 -0
- package/src/components/PinInput/PinInput.tsx +53 -0
- package/src/components/PinInput/PinInput.types.ts +27 -0
- package/src/components/PinInput/index.tsx +2 -0
- package/src/components/ProgressBar/ProgressBar.stories.tsx +18 -0
- package/src/components/ProgressBar/ProgressBar.styles.ts +4 -0
- package/src/components/ProgressBar/ProgressBar.tsx +27 -0
- package/src/components/ProgressBar/ProgressBar.types.ts +4 -0
- package/src/components/ProgressBar/index.ts +1 -0
- package/src/components/RadialProgress/RadialProgress.stories.tsx +272 -0
- package/src/components/RadialProgress/RadialProgress.tsx +232 -0
- package/src/components/RadialProgress/RadialProgress.types.ts +27 -0
- package/src/components/RadialProgress/index.ts +2 -0
- package/src/components/Radio/Radio.stories.tsx +226 -0
- package/src/components/Radio/Radio.tsx +35 -0
- package/src/components/Radio/Radio.types.ts +21 -0
- package/src/components/Radio/RadioGroup.tsx +26 -0
- package/src/components/Radio/index.ts +3 -0
- package/src/components/SeeMoreButton/SeeMoreButton.stories.tsx +48 -0
- package/src/components/SeeMoreButton/SeeMoreButton.styles.ts +11 -0
- package/src/components/SeeMoreButton/SeeMoreButton.tsx +34 -0
- package/src/components/SeeMoreButton/SeeMoreButton.types.ts +6 -0
- package/src/components/SeeMoreButton/index.tsx +1 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +96 -0
- package/src/components/SegmentedControl/SegmentedControl.styles.ts +28 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +89 -0
- package/src/components/SegmentedControl/SegmentedControl.types.ts +15 -0
- package/src/components/SegmentedControl/index.ts +2 -0
- package/src/components/SegmentedProgressBar/ProgressSegment.tsx +18 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBar.stories.tsx +228 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBar.tsx +25 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBar.types.ts +11 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBarContext.tsx +24 -0
- package/src/components/SegmentedProgressBar/index.ts +3 -0
- package/src/components/Select/MenuList/MenuList.tsx +87 -0
- package/src/components/Select/MenuList/MenuList.types.ts +21 -0
- package/src/components/Select/MenuList/VirtualizedMenuList.tsx +140 -0
- package/src/components/Select/MenuList/VirtualizedMenuListContext.tsx +35 -0
- package/src/components/Select/MenuList/index.ts +3 -0
- package/src/components/Select/Select.stories.tsx +70 -0
- package/src/components/Select/Select.styles.ts +102 -0
- package/src/components/Select/Select.tsx +204 -0
- package/src/components/Select/Select.types.ts +18 -0
- package/src/components/Select/_utils/resolveStyle.ts +21 -0
- package/src/components/Select/index.ts +1 -0
- package/src/components/Slider/Slider.stories.tsx +75 -0
- package/src/components/Slider/Slider.tsx +12 -0
- package/src/components/Slider/Slider.types.ts +3 -0
- package/src/components/Slider/SliderFilledTrack/SliderFilledTrack.tsx +14 -0
- package/src/components/Slider/SliderFilledTrack/SliderFilledTrack.types.ts +3 -0
- package/src/components/Slider/SliderFilledTrack/index.ts +2 -0
- package/src/components/Slider/SliderMark/SliderMark.tsx +12 -0
- package/src/components/Slider/SliderMark/SliderMark.types.ts +3 -0
- package/src/components/Slider/SliderMark/index.ts +2 -0
- package/src/components/Slider/SliderThumb/SliderThumb.tsx +22 -0
- package/src/components/Slider/SliderThumb/SliderThumb.types.ts +3 -0
- package/src/components/Slider/SliderThumb/index.ts +2 -0
- package/src/components/Slider/SliderTrack/SliderTrack.tsx +12 -0
- package/src/components/Slider/SliderTrack/SliderTrack.types.ts +3 -0
- package/src/components/Slider/SliderTrack/index.ts +2 -0
- package/src/components/Slider/index.ts +5 -0
- package/src/components/Spinner/Spinner.stories.tsx +16 -0
- package/src/components/Spinner/Spinner.tsx +20 -0
- package/src/components/Spinner/Spinner.types.ts +3 -0
- package/src/components/Spinner/index.ts +2 -0
- package/src/components/Switch/Switch.stories.tsx +63 -0
- package/src/components/Switch/Switch.tsx +8 -0
- package/src/components/Switch/index.ts +1 -0
- package/src/components/Table/ExpandingTr/ExpandingTr.tsx +31 -0
- package/src/components/Table/ExpandingTr/ExpandingTr.types.ts +9 -0
- package/src/components/Table/ExpandingTr/index.ts +2 -0
- package/src/components/Table/Table.stories.tsx +326 -0
- package/src/components/Table/Table.styles.ts +48 -0
- package/src/components/Table/Table.tsx +9 -0
- package/src/components/Table/Table.types.ts +16 -0
- package/src/components/Table/TableContainer.tsx +55 -0
- package/src/components/Table/TableContext.tsx +187 -0
- package/src/components/Table/Tbody.tsx +12 -0
- package/src/components/Table/Td.tsx +138 -0
- package/src/components/Table/Th.tsx +154 -0
- package/src/components/Table/Thead.tsx +5 -0
- package/src/components/Table/Tr.tsx +5 -0
- package/src/components/Table/index.tsx +8 -0
- package/src/components/Tabs/Tab/Tab.styles.ts +35 -0
- package/src/components/Tabs/Tab/Tab.tsx +67 -0
- package/src/components/Tabs/Tab/index.ts +1 -0
- package/src/components/Tabs/TabList/TabList.styles.ts +11 -0
- package/src/components/Tabs/TabList/TabList.tsx +19 -0
- package/src/components/Tabs/TabList/index.ts +1 -0
- package/src/components/Tabs/TabPanel.tsx +5 -0
- package/src/components/Tabs/TabPanels.tsx +5 -0
- package/src/components/Tabs/Tabs.stories.tsx +45 -0
- package/src/components/Tabs/Tabs.tsx +65 -0
- package/src/components/Tabs/Tabs.types.ts +19 -0
- package/src/components/Tabs/TabsContext.tsx +162 -0
- package/src/components/Tabs/index.tsx +5 -0
- package/src/components/Tag/Tag.stories.tsx +28 -0
- package/src/components/Tag/Tag.styles.ts +12 -0
- package/src/components/Tag/Tag.tsx +23 -0
- package/src/components/Tag/Tag.types.ts +5 -0
- package/src/components/Tag/TagCloseButton/TagCloseButton.tsx +12 -0
- package/src/components/Tag/TagCloseButton/TagCloseButton.types.ts +3 -0
- package/src/components/Tag/TagCloseButton/index.ts +2 -0
- package/src/components/Tag/TagLabel/TagLabel.tsx +12 -0
- package/src/components/Tag/TagLabel/TagLabel.types.ts +3 -0
- package/src/components/Tag/TagLabel/index.ts +2 -0
- package/src/components/Tag/TagLeftIcon/TagLeftIcon.tsx +12 -0
- package/src/components/Tag/TagLeftIcon/TagLeftIcon.types.ts +3 -0
- package/src/components/Tag/TagLeftIcon/index.ts +2 -0
- package/src/components/Tag/TagRightIcon/TagRightIcon.tsx +12 -0
- package/src/components/Tag/TagRightIcon/TagRightIcon.types.ts +3 -0
- package/src/components/Tag/TagRightIcon/index.ts +2 -0
- package/src/components/Tag/index.ts +5 -0
- package/src/components/Textarea/Textarea.tsx +56 -0
- package/src/components/Textarea/adjustHeight.tsx +9 -0
- package/src/components/Textarea/index.ts +1 -0
- package/src/components/Toast/Toast.stories.tsx +49 -0
- package/src/components/Toast/Toast.styles.ts +19 -0
- package/src/components/Toast/Toast.tsx +38 -0
- package/src/components/Toast/Toast.types.ts +22 -0
- package/src/components/Toast/ToastIcon/ToastIcon.tsx +26 -0
- package/src/components/Toast/ToastIcon/index.ts +0 -0
- package/src/components/Toast/index.ts +2 -0
- package/src/components/Toast/useToast.tsx +65 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +97 -0
- package/src/components/Tooltip/Tooltip.tsx +22 -0
- package/src/components/Tooltip/Tooltip.types.ts +3 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/Typography/H1.tsx +17 -0
- package/src/components/Typography/H2.tsx +17 -0
- package/src/components/Typography/H3.tsx +17 -0
- package/src/components/Typography/H4.tsx +17 -0
- package/src/components/Typography/H5.tsx +17 -0
- package/src/components/Typography/Link.tsx +49 -0
- package/src/components/Typography/Subtext.tsx +17 -0
- package/src/components/Typography/Subtitle.tsx +18 -0
- package/src/components/Typography/Text.tsx +22 -0
- package/src/components/Typography/Typography.stories.tsx +54 -0
- package/src/components/Typography/Typography.types.ts +3 -0
- package/src/components/Typography/index.ts +26 -0
- package/src/components/UrlInput/UrlInput.stories.tsx +66 -0
- package/src/components/UrlInput/UrlInput.tsx +47 -0
- package/src/components/UrlInput/index.tsx +1 -0
- package/src/hooks/useLocale.ts +11 -0
- package/src/hooks/useTranslate.ts +57 -0
- package/src/index.ts +96 -0
- package/src/theme/Palette.stories.tsx +171 -0
- package/src/theme/colors.ts +64 -0
- package/src/theme/font.ts +23 -0
- package/src/theme/global.ts +30 -0
- package/src/theme/index.ts +49 -0
- package/src/translations/Defaults.translations.json +100 -0
- package/src/types/css-modules.d.ts +0 -0
- package/src/types/svg.d.ts +15 -0
- package/src/utils/findKeyByValue.ts +17 -0
- package/src/utils/formatDateByLocale.ts +36 -0
- package/src/utils/formatFileSize.ts +14 -0
- package/src/utils/formatNumber.ts +29 -0
- package/src/utils/formatTextForMarkdown.ts +3 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Box, VStack } from '@chakra-ui/react';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
import { addMonths, subMonths } from 'date-fns';
|
|
5
|
+
|
|
6
|
+
import { Text } from '@/components/Typography';
|
|
7
|
+
|
|
8
|
+
import { MonthRangePicker } from './MonthRangePicker';
|
|
9
|
+
import { MonthRange } from './MonthRangePicker.types';
|
|
10
|
+
|
|
11
|
+
const meta: Meta<typeof MonthRangePicker> = {
|
|
12
|
+
title: 'Components/MonthRangePicker',
|
|
13
|
+
component: MonthRangePicker,
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: 'centered',
|
|
16
|
+
},
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
argTypes: {
|
|
19
|
+
selectedRange: {
|
|
20
|
+
control: false,
|
|
21
|
+
},
|
|
22
|
+
onChange: {
|
|
23
|
+
control: false,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
decorators: [
|
|
27
|
+
(Story, context) => {
|
|
28
|
+
const [selectedRange, setSelectedRange] = useState<MonthRange | null>(
|
|
29
|
+
context.parameters?.initialRange || null
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<VStack spacing={4} align="start" width="400px">
|
|
34
|
+
{context.parameters?.additionalContent}
|
|
35
|
+
<Story
|
|
36
|
+
args={{
|
|
37
|
+
...context.args,
|
|
38
|
+
selectedRange,
|
|
39
|
+
onChange: setSelectedRange,
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
{selectedRange && (
|
|
43
|
+
<Box
|
|
44
|
+
p={3}
|
|
45
|
+
bg="green.50"
|
|
46
|
+
borderRadius="md"
|
|
47
|
+
width="100%"
|
|
48
|
+
border="1px solid"
|
|
49
|
+
borderColor="green.200"
|
|
50
|
+
>
|
|
51
|
+
<Text fontSize="sm" fontWeight="semibold" color="green.700">
|
|
52
|
+
✓ Range Selected:
|
|
53
|
+
</Text>
|
|
54
|
+
<Text fontSize="sm" color="green.600">
|
|
55
|
+
{selectedRange.startMonth.toLocaleDateString()}
|
|
56
|
+
{selectedRange.endMonth ? (
|
|
57
|
+
<> - {selectedRange.endMonth.toLocaleDateString()}</>
|
|
58
|
+
) : (
|
|
59
|
+
' - (selecting...)'
|
|
60
|
+
)}
|
|
61
|
+
</Text>
|
|
62
|
+
</Box>
|
|
63
|
+
)}
|
|
64
|
+
</VStack>
|
|
65
|
+
);
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default meta;
|
|
71
|
+
type Story = StoryObj<typeof MonthRangePicker>;
|
|
72
|
+
|
|
73
|
+
export const Default: Story = {};
|
|
74
|
+
|
|
75
|
+
export const WithInitialValue: Story = {
|
|
76
|
+
parameters: {
|
|
77
|
+
initialRange: {
|
|
78
|
+
startMonth: subMonths(new Date(), 2),
|
|
79
|
+
endMonth: addMonths(new Date(), 1),
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const WithConstraints: Story = {
|
|
85
|
+
args: {
|
|
86
|
+
minMonth: subMonths(new Date(), 6),
|
|
87
|
+
maxMonth: addMonths(new Date(), 6),
|
|
88
|
+
},
|
|
89
|
+
parameters: {
|
|
90
|
+
additionalContent: (
|
|
91
|
+
<Box>
|
|
92
|
+
<Text fontSize="md" fontWeight="semibold" mb={2}>
|
|
93
|
+
With Date Constraints
|
|
94
|
+
</Text>
|
|
95
|
+
<Text fontSize="sm" color="gray.600" mb={4}>
|
|
96
|
+
Only allows selection 6 months before/after current date
|
|
97
|
+
</Text>
|
|
98
|
+
</Box>
|
|
99
|
+
),
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const Disabled: Story = {
|
|
104
|
+
args: {
|
|
105
|
+
disabled: true,
|
|
106
|
+
},
|
|
107
|
+
parameters: {
|
|
108
|
+
additionalContent: (
|
|
109
|
+
<Box>
|
|
110
|
+
<Text fontSize="md" fontWeight="semibold" mb={2}>
|
|
111
|
+
Disabled State
|
|
112
|
+
</Text>
|
|
113
|
+
<Text fontSize="sm" color="gray.600" mb={4}>
|
|
114
|
+
The picker is disabled and cannot be interacted with
|
|
115
|
+
</Text>
|
|
116
|
+
</Box>
|
|
117
|
+
),
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const CustomFormat: Story = {
|
|
122
|
+
args: {
|
|
123
|
+
format: 'MMMM yyyy',
|
|
124
|
+
placeholder: 'Select month range (full month names)',
|
|
125
|
+
},
|
|
126
|
+
parameters: {
|
|
127
|
+
additionalContent: (
|
|
128
|
+
<Box>
|
|
129
|
+
<Text fontSize="md" fontWeight="semibold" mb={2}>
|
|
130
|
+
Custom Date Format
|
|
131
|
+
</Text>
|
|
132
|
+
<Text fontSize="sm" color="gray.600" mb={4}>
|
|
133
|
+
Uses full month names (MMMM yyyy) instead of abbreviated
|
|
134
|
+
</Text>
|
|
135
|
+
</Box>
|
|
136
|
+
),
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const CrossYearSelection: Story = {
|
|
141
|
+
parameters: {
|
|
142
|
+
additionalContent: (
|
|
143
|
+
<Box>
|
|
144
|
+
<Text fontSize="md" fontWeight="semibold" mb={2}>
|
|
145
|
+
Cross-Year Range Selection
|
|
146
|
+
</Text>
|
|
147
|
+
<Text fontSize="sm" color="gray.600" mb={4}>
|
|
148
|
+
Demonstrates selecting ranges across different years with immediate
|
|
149
|
+
feedback.
|
|
150
|
+
</Text>
|
|
151
|
+
<Box fontSize="sm" color="gray.700">
|
|
152
|
+
<Text>
|
|
153
|
+
• Click a month to start selection (shows immediately in input)
|
|
154
|
+
</Text>
|
|
155
|
+
<Text>
|
|
156
|
+
• Use year navigation arrows to navigate to different years
|
|
157
|
+
</Text>
|
|
158
|
+
<Text>• Click a month in another year to complete the range</Text>
|
|
159
|
+
<Text>• Try selecting from Dec 2024 to Mar 2025</Text>
|
|
160
|
+
</Box>
|
|
161
|
+
</Box>
|
|
162
|
+
),
|
|
163
|
+
},
|
|
164
|
+
};
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
4
|
+
import {
|
|
5
|
+
Box,
|
|
6
|
+
Button,
|
|
7
|
+
Grid,
|
|
8
|
+
HStack,
|
|
9
|
+
Input,
|
|
10
|
+
InputGroup,
|
|
11
|
+
InputLeftElement,
|
|
12
|
+
Popover,
|
|
13
|
+
PopoverBody,
|
|
14
|
+
PopoverContent,
|
|
15
|
+
PopoverTrigger,
|
|
16
|
+
Portal,
|
|
17
|
+
useDisclosure,
|
|
18
|
+
VStack,
|
|
19
|
+
} from '@chakra-ui/react';
|
|
20
|
+
import { format, isAfter, isSameMonth } from 'date-fns';
|
|
21
|
+
|
|
22
|
+
import { Text } from '@/components/Typography';
|
|
23
|
+
import useLocale from '@/hooks/useLocale';
|
|
24
|
+
import { useTranslate } from '@/hooks/useTranslate';
|
|
25
|
+
|
|
26
|
+
import { Icon } from '../Icon';
|
|
27
|
+
import { hasEnabledMonthsInYear, isMonthDisabled } from './_utils';
|
|
28
|
+
import {
|
|
29
|
+
getDateFnsLocale,
|
|
30
|
+
getDefaultDateFormat,
|
|
31
|
+
getMonthNames,
|
|
32
|
+
} from './constants';
|
|
33
|
+
import { MonthButton } from './MonthButton/MonthButton';
|
|
34
|
+
import { MonthRange, MonthRangePickerProps } from './MonthRangePicker.types';
|
|
35
|
+
|
|
36
|
+
export const MonthRangePicker: React.FC<MonthRangePickerProps> = ({
|
|
37
|
+
selectedRange,
|
|
38
|
+
onChange,
|
|
39
|
+
minMonth,
|
|
40
|
+
maxMonth,
|
|
41
|
+
disabled = false,
|
|
42
|
+
placeholder,
|
|
43
|
+
format: dateFormat, // Remove default here, will be set dynamically
|
|
44
|
+
usePortal = true,
|
|
45
|
+
popoverProps,
|
|
46
|
+
name,
|
|
47
|
+
...boxProps
|
|
48
|
+
}) => {
|
|
49
|
+
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
50
|
+
const { language: locale } = useLocale();
|
|
51
|
+
const translate = useTranslate();
|
|
52
|
+
|
|
53
|
+
const [currentYear, setCurrentYear] = useState(() =>
|
|
54
|
+
new Date().getFullYear()
|
|
55
|
+
);
|
|
56
|
+
const [selectionStart, setSelectionStart] = useState<Date | null>(null);
|
|
57
|
+
const [hoveredMonth, setHoveredMonth] = useState<{
|
|
58
|
+
month: number;
|
|
59
|
+
year: number;
|
|
60
|
+
} | null>(null);
|
|
61
|
+
|
|
62
|
+
// Get localized month names, date-fns locale, and default format
|
|
63
|
+
const monthNames = useMemo(() => getMonthNames(locale), [locale]);
|
|
64
|
+
const dateFnsLocale = useMemo(() => getDateFnsLocale(locale), [locale]);
|
|
65
|
+
const effectiveDateFormat = useMemo(
|
|
66
|
+
() => dateFormat || getDefaultDateFormat(locale),
|
|
67
|
+
[dateFormat, locale]
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Use translated placeholder if not provided
|
|
71
|
+
const effectivePlaceholder =
|
|
72
|
+
placeholder || (translate('month_range_placeholder') as string);
|
|
73
|
+
|
|
74
|
+
const displayValue = useMemo(() => {
|
|
75
|
+
// If we have a complete range, show start - end
|
|
76
|
+
if (selectedRange?.endMonth) {
|
|
77
|
+
const start = format(selectedRange.startMonth, effectiveDateFormat, {
|
|
78
|
+
locale: dateFnsLocale,
|
|
79
|
+
});
|
|
80
|
+
const end = format(selectedRange.endMonth, effectiveDateFormat, {
|
|
81
|
+
locale: dateFnsLocale,
|
|
82
|
+
});
|
|
83
|
+
return `${start} - ${end}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// If we have a partial range (selectedRange with only startMonth) or selection start, show just the start date
|
|
87
|
+
if (selectedRange?.startMonth || selectionStart) {
|
|
88
|
+
const startDate = selectedRange?.startMonth || selectionStart;
|
|
89
|
+
if (startDate) {
|
|
90
|
+
const start = format(startDate, effectiveDateFormat, {
|
|
91
|
+
locale: dateFnsLocale,
|
|
92
|
+
});
|
|
93
|
+
return `${start} -`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// No selection at all
|
|
98
|
+
return '';
|
|
99
|
+
}, [selectedRange, selectionStart, effectiveDateFormat, dateFnsLocale]);
|
|
100
|
+
|
|
101
|
+
// Check if navigation to previous/next year is possible
|
|
102
|
+
const canNavigateToPrevYear = useMemo(() => {
|
|
103
|
+
return hasEnabledMonthsInYear(currentYear - 1, minMonth, maxMonth);
|
|
104
|
+
}, [currentYear, minMonth, maxMonth]);
|
|
105
|
+
|
|
106
|
+
const canNavigateToNextYear = useMemo(() => {
|
|
107
|
+
return hasEnabledMonthsInYear(currentYear + 1, minMonth, maxMonth);
|
|
108
|
+
}, [currentYear, minMonth, maxMonth]);
|
|
109
|
+
|
|
110
|
+
const handleYearChange = useCallback(
|
|
111
|
+
(direction: 'prev' | 'next') => {
|
|
112
|
+
const targetYear =
|
|
113
|
+
direction === 'prev' ? currentYear - 1 : currentYear + 1;
|
|
114
|
+
|
|
115
|
+
// Only navigate if the target year has enabled months
|
|
116
|
+
if (hasEnabledMonthsInYear(targetYear, minMonth, maxMonth)) {
|
|
117
|
+
setCurrentYear(targetYear);
|
|
118
|
+
// Keep selectionStart to allow cross-year range selection
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
[currentYear, minMonth, maxMonth]
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const handleMonthClick = useCallback(
|
|
125
|
+
(month: number, year: number) => {
|
|
126
|
+
if (isMonthDisabled(month, year, minMonth, maxMonth)) return;
|
|
127
|
+
|
|
128
|
+
const clickedMonth = new Date(year, month, 1);
|
|
129
|
+
|
|
130
|
+
if (!selectionStart) {
|
|
131
|
+
// If there's an existing complete range, clear it and start fresh
|
|
132
|
+
if (selectedRange) {
|
|
133
|
+
onChange?.(null);
|
|
134
|
+
}
|
|
135
|
+
// Start new selection and notify parent with partial range
|
|
136
|
+
setSelectionStart(clickedMonth);
|
|
137
|
+
// Call onChange with partial range to update parent state
|
|
138
|
+
onChange?.({ startMonth: clickedMonth, endMonth: null });
|
|
139
|
+
} else {
|
|
140
|
+
// Complete the selection
|
|
141
|
+
const startMonth = selectionStart;
|
|
142
|
+
const endMonth = clickedMonth;
|
|
143
|
+
|
|
144
|
+
if (isSameMonth(startMonth, endMonth)) {
|
|
145
|
+
// Same month selected, create single-month range
|
|
146
|
+
onChange?.({
|
|
147
|
+
startMonth,
|
|
148
|
+
endMonth,
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
// Different months, ensure proper order
|
|
152
|
+
const range: MonthRange = isAfter(startMonth, endMonth)
|
|
153
|
+
? { startMonth: endMonth, endMonth: startMonth }
|
|
154
|
+
: { startMonth, endMonth };
|
|
155
|
+
|
|
156
|
+
onChange?.(range);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
setSelectionStart(null);
|
|
160
|
+
onClose();
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
[selectionStart, selectedRange, onChange, onClose, minMonth, maxMonth]
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
const handleMonthHover = useCallback((month: number, year: number) => {
|
|
167
|
+
setHoveredMonth({ month, year });
|
|
168
|
+
}, []);
|
|
169
|
+
|
|
170
|
+
const handleMonthHoverLeave = useCallback(() => {
|
|
171
|
+
setHoveredMonth(null);
|
|
172
|
+
}, []);
|
|
173
|
+
|
|
174
|
+
const handleClear = useCallback(() => {
|
|
175
|
+
onChange?.(null);
|
|
176
|
+
setSelectionStart(null);
|
|
177
|
+
}, [onChange]);
|
|
178
|
+
|
|
179
|
+
const popoverContent = (
|
|
180
|
+
<PopoverContent width="320px">
|
|
181
|
+
<PopoverBody>
|
|
182
|
+
<VStack spacing={4} align="stretch">
|
|
183
|
+
{/* Year Navigation */}
|
|
184
|
+
<HStack justify="space-between" align="center">
|
|
185
|
+
<Button
|
|
186
|
+
size="sm"
|
|
187
|
+
variant="ghost"
|
|
188
|
+
onClick={() => handleYearChange('prev')}
|
|
189
|
+
disabled={!canNavigateToPrevYear}
|
|
190
|
+
opacity={!canNavigateToPrevYear ? 0.4 : 1}
|
|
191
|
+
>
|
|
192
|
+
<Icon icon="IoIosArrowBack" />
|
|
193
|
+
</Button>
|
|
194
|
+
|
|
195
|
+
<Text fontWeight="semibold" fontSize="lg">
|
|
196
|
+
{currentYear}
|
|
197
|
+
</Text>
|
|
198
|
+
|
|
199
|
+
<Button
|
|
200
|
+
size="sm"
|
|
201
|
+
variant="ghost"
|
|
202
|
+
onClick={() => handleYearChange('next')}
|
|
203
|
+
disabled={!canNavigateToNextYear}
|
|
204
|
+
opacity={!canNavigateToNextYear ? 0.4 : 1}
|
|
205
|
+
>
|
|
206
|
+
<Icon icon="IoChevronForward" />
|
|
207
|
+
</Button>
|
|
208
|
+
</HStack>
|
|
209
|
+
|
|
210
|
+
{/* Months Grid */}
|
|
211
|
+
<Grid templateColumns="repeat(3, 1fr)" gap={2}>
|
|
212
|
+
{monthNames.map((monthName, monthIndex) => (
|
|
213
|
+
<MonthButton
|
|
214
|
+
key={monthIndex}
|
|
215
|
+
month={monthIndex}
|
|
216
|
+
year={currentYear}
|
|
217
|
+
monthName={monthName}
|
|
218
|
+
selectedRange={selectedRange}
|
|
219
|
+
selectionStart={selectionStart}
|
|
220
|
+
hoveredMonth={hoveredMonth}
|
|
221
|
+
minMonth={minMonth}
|
|
222
|
+
maxMonth={maxMonth}
|
|
223
|
+
onClick={handleMonthClick}
|
|
224
|
+
onMouseEnter={handleMonthHover}
|
|
225
|
+
onMouseLeave={handleMonthHoverLeave}
|
|
226
|
+
/>
|
|
227
|
+
))}
|
|
228
|
+
</Grid>
|
|
229
|
+
|
|
230
|
+
{/* Action Buttons */}
|
|
231
|
+
<HStack spacing={2} justify="flex-end">
|
|
232
|
+
<Button size="sm" variant="ghost" onClick={handleClear}>
|
|
233
|
+
{translate('clear')}
|
|
234
|
+
</Button>
|
|
235
|
+
</HStack>
|
|
236
|
+
</VStack>
|
|
237
|
+
</PopoverBody>
|
|
238
|
+
</PopoverContent>
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<Box {...boxProps}>
|
|
243
|
+
<Popover
|
|
244
|
+
isOpen={isOpen}
|
|
245
|
+
onOpen={onOpen}
|
|
246
|
+
onClose={onClose}
|
|
247
|
+
placement="bottom-start"
|
|
248
|
+
{...popoverProps}
|
|
249
|
+
>
|
|
250
|
+
<PopoverTrigger>
|
|
251
|
+
<InputGroup>
|
|
252
|
+
<InputLeftElement>
|
|
253
|
+
<Icon
|
|
254
|
+
icon="MdOutlineCalendarToday"
|
|
255
|
+
boxSize="xs"
|
|
256
|
+
color="gray.800"
|
|
257
|
+
/>
|
|
258
|
+
</InputLeftElement>
|
|
259
|
+
<Input
|
|
260
|
+
name={name}
|
|
261
|
+
value={displayValue}
|
|
262
|
+
placeholder={effectivePlaceholder}
|
|
263
|
+
readOnly
|
|
264
|
+
disabled={disabled}
|
|
265
|
+
cursor={disabled ? 'not-allowed' : 'pointer'}
|
|
266
|
+
onClick={disabled ? undefined : onOpen}
|
|
267
|
+
/>
|
|
268
|
+
</InputGroup>
|
|
269
|
+
</PopoverTrigger>
|
|
270
|
+
{usePortal ? <Portal>{popoverContent}</Portal> : popoverContent}
|
|
271
|
+
</Popover>
|
|
272
|
+
</Box>
|
|
273
|
+
);
|
|
274
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BoxProps, PopoverProps } from '@chakra-ui/react';
|
|
2
|
+
|
|
3
|
+
export interface MonthRange {
|
|
4
|
+
startMonth: Date;
|
|
5
|
+
endMonth: Date | null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface MonthRangePickerProps extends Omit<BoxProps, 'onChange'> {
|
|
9
|
+
/** The selected month range */
|
|
10
|
+
selectedRange?: MonthRange | null;
|
|
11
|
+
|
|
12
|
+
/** Callback when the month range changes */
|
|
13
|
+
onChange?: (range: MonthRange | null) => void;
|
|
14
|
+
|
|
15
|
+
/** Minimum selectable month */
|
|
16
|
+
minMonth?: Date;
|
|
17
|
+
|
|
18
|
+
/** Maximum selectable month */
|
|
19
|
+
maxMonth?: Date;
|
|
20
|
+
|
|
21
|
+
/** Whether the picker is disabled */
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
|
|
24
|
+
/** Placeholder text for the input */
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
|
|
27
|
+
/** Format for displaying the selected range */
|
|
28
|
+
format?: string;
|
|
29
|
+
|
|
30
|
+
/** Whether to use portal for the popover */
|
|
31
|
+
usePortal?: boolean;
|
|
32
|
+
|
|
33
|
+
/** Props for the popover */
|
|
34
|
+
popoverProps?: Partial<PopoverProps>;
|
|
35
|
+
|
|
36
|
+
/** Name attribute for form usage */
|
|
37
|
+
name?: string;
|
|
38
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isMonthDisabled } from './isMonthDisabled';
|
|
2
|
+
|
|
3
|
+
export const hasEnabledMonthsInYear = (
|
|
4
|
+
year: number,
|
|
5
|
+
minMonth?: Date,
|
|
6
|
+
maxMonth?: Date
|
|
7
|
+
): boolean => {
|
|
8
|
+
// Check all 12 months (0-11) to see if any are enabled
|
|
9
|
+
for (let month = 0; month < 12; month++) {
|
|
10
|
+
if (!isMonthDisabled(month, year, minMonth, maxMonth)) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { hasEnabledMonthsInYear } from './hasEnabledMonthsInYear';
|
|
2
|
+
export { isMonthDisabled } from './isMonthDisabled';
|
|
3
|
+
export { isMonthInPreviewRange } from './isMonthInPreviewRange';
|
|
4
|
+
export { isMonthInRange } from './isMonthInRange';
|
|
5
|
+
export { isMonthSelected } from './isMonthSelected';
|
|
6
|
+
export { isSelectionStart } from './isSelectionStart';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isAfter, isBefore, startOfMonth } from 'date-fns';
|
|
2
|
+
|
|
3
|
+
export const isMonthDisabled = (
|
|
4
|
+
month: number,
|
|
5
|
+
year: number,
|
|
6
|
+
minMonth?: Date,
|
|
7
|
+
maxMonth?: Date
|
|
8
|
+
): boolean => {
|
|
9
|
+
const monthDate = new Date(year, month, 1);
|
|
10
|
+
|
|
11
|
+
if (minMonth && isBefore(monthDate, startOfMonth(minMonth))) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (maxMonth && isAfter(monthDate, startOfMonth(maxMonth))) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { isAfter, isBefore, isSameMonth } from 'date-fns';
|
|
2
|
+
|
|
3
|
+
export const isMonthInPreviewRange = (
|
|
4
|
+
month: number,
|
|
5
|
+
year: number,
|
|
6
|
+
selectionStart: Date | null,
|
|
7
|
+
hoveredMonth: { month: number; year: number } | null
|
|
8
|
+
): boolean => {
|
|
9
|
+
if (!selectionStart || !hoveredMonth) return false;
|
|
10
|
+
|
|
11
|
+
const monthDate = new Date(year, month, 1);
|
|
12
|
+
const hoveredDate = new Date(hoveredMonth.year, hoveredMonth.month, 1);
|
|
13
|
+
|
|
14
|
+
// Don't highlight if hovering the same month as selection start
|
|
15
|
+
if (
|
|
16
|
+
isSameMonth(monthDate, selectionStart) ||
|
|
17
|
+
isSameMonth(monthDate, hoveredDate)
|
|
18
|
+
) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Determine range boundaries (start could be before or after hovered)
|
|
23
|
+
const rangeStart = isBefore(selectionStart, hoveredDate)
|
|
24
|
+
? selectionStart
|
|
25
|
+
: hoveredDate;
|
|
26
|
+
const rangeEnd = isAfter(selectionStart, hoveredDate)
|
|
27
|
+
? selectionStart
|
|
28
|
+
: hoveredDate;
|
|
29
|
+
|
|
30
|
+
// Check if month is between start and end (exclusive)
|
|
31
|
+
return isAfter(monthDate, rangeStart) && isBefore(monthDate, rangeEnd);
|
|
32
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { startOfMonth } from 'date-fns';
|
|
2
|
+
|
|
3
|
+
import { MonthRange } from '../MonthRangePicker.types';
|
|
4
|
+
|
|
5
|
+
export const isMonthInRange = (
|
|
6
|
+
month: number,
|
|
7
|
+
year: number,
|
|
8
|
+
selectedRange?: MonthRange | null
|
|
9
|
+
): boolean => {
|
|
10
|
+
if (!selectedRange || !selectedRange.endMonth) return false;
|
|
11
|
+
|
|
12
|
+
const monthDate = new Date(year, month, 1);
|
|
13
|
+
const start = startOfMonth(selectedRange.startMonth);
|
|
14
|
+
const end = startOfMonth(selectedRange.endMonth);
|
|
15
|
+
|
|
16
|
+
return monthDate >= start && monthDate <= end;
|
|
17
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { isSameMonth } from 'date-fns';
|
|
2
|
+
|
|
3
|
+
import { MonthRange } from '../MonthRangePicker.types';
|
|
4
|
+
|
|
5
|
+
export const isMonthSelected = (
|
|
6
|
+
month: number,
|
|
7
|
+
year: number,
|
|
8
|
+
selectedRange?: MonthRange | null
|
|
9
|
+
): boolean => {
|
|
10
|
+
if (!selectedRange) return false;
|
|
11
|
+
|
|
12
|
+
const monthDate = new Date(year, month, 1);
|
|
13
|
+
return (
|
|
14
|
+
isSameMonth(monthDate, selectedRange.startMonth) ||
|
|
15
|
+
(selectedRange.endMonth
|
|
16
|
+
? isSameMonth(monthDate, selectedRange.endMonth)
|
|
17
|
+
: false)
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isSameMonth } from 'date-fns';
|
|
2
|
+
|
|
3
|
+
export const isSelectionStart = (
|
|
4
|
+
month: number,
|
|
5
|
+
year: number,
|
|
6
|
+
selectionStart?: Date | null
|
|
7
|
+
): boolean => {
|
|
8
|
+
if (!selectionStart) return false;
|
|
9
|
+
|
|
10
|
+
const monthDate = new Date(year, month, 1);
|
|
11
|
+
return isSameMonth(monthDate, selectionStart);
|
|
12
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { format } from 'date-fns';
|
|
2
|
+
import { enUS, es, ja, ko, zhCN } from 'date-fns/locale';
|
|
3
|
+
|
|
4
|
+
// Map language codes to date-fns locales
|
|
5
|
+
const LOCALE_MAP = {
|
|
6
|
+
ko: ko,
|
|
7
|
+
en: enUS,
|
|
8
|
+
zh: zhCN,
|
|
9
|
+
ja: ja,
|
|
10
|
+
es: es,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
// Map language codes to culturally appropriate date formats
|
|
14
|
+
const DEFAULT_FORMAT_MAP = {
|
|
15
|
+
ko: 'yyyy년 MMM', // 2024년 3월
|
|
16
|
+
en: 'MMM yyyy', // Mar 2024
|
|
17
|
+
zh: 'yyyy年MMM', // 2024年3月
|
|
18
|
+
ja: 'yyyy年MMM', // 2024年3月
|
|
19
|
+
es: 'MMM yyyy', // mar 2024
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get the default date format for a given locale
|
|
24
|
+
* @param language Language code (ko, en, zh, ja, es)
|
|
25
|
+
* @returns Appropriate date format string for the locale
|
|
26
|
+
*/
|
|
27
|
+
export const getDefaultDateFormat = (language: string = 'en'): string => {
|
|
28
|
+
return (
|
|
29
|
+
DEFAULT_FORMAT_MAP[language as keyof typeof DEFAULT_FORMAT_MAP] ||
|
|
30
|
+
DEFAULT_FORMAT_MAP.en
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generate month names for the given locale
|
|
36
|
+
* @param language Language code (ko, en, zh, ja, es)
|
|
37
|
+
* @param monthFormat Format string for month names (default: 'MMM' for abbreviated)
|
|
38
|
+
* @returns Array of month names in the specified locale
|
|
39
|
+
*/
|
|
40
|
+
export const getMonthNames = (
|
|
41
|
+
language: string = 'en',
|
|
42
|
+
monthFormat: string = 'MMM'
|
|
43
|
+
): string[] => {
|
|
44
|
+
const locale =
|
|
45
|
+
LOCALE_MAP[language as keyof typeof LOCALE_MAP] || LOCALE_MAP.en;
|
|
46
|
+
|
|
47
|
+
return Array.from({ length: 12 }, (_, monthIndex) => {
|
|
48
|
+
const date = new Date(2024, monthIndex, 1); // Use 2024 as a reference year
|
|
49
|
+
return format(date, monthFormat, { locale });
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get date-fns locale object for the given language
|
|
55
|
+
* @param language Language code (ko, en, zh, ja, es)
|
|
56
|
+
* @returns date-fns locale object
|
|
57
|
+
*/
|
|
58
|
+
export const getDateFnsLocale = (language: string = 'en') => {
|
|
59
|
+
return LOCALE_MAP[language as keyof typeof LOCALE_MAP] || LOCALE_MAP.en;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Legacy export for backward compatibility (English abbreviated months)
|
|
63
|
+
export const MONTHS = getMonthNames('en', 'MMM');
|