plass-ui 0.0.1 → 1.0.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/dist/components/accordion/PlAccordion.d.ts +98 -0
- package/dist/components/accordion/PlAccordion.js +131 -0
- package/dist/components/accordion/index.d.ts +2 -0
- package/dist/components/accordion/index.js +1 -0
- package/dist/components/alert/PlAlert.d.ts +50 -0
- package/dist/components/alert/PlAlert.js +109 -0
- package/dist/components/alert/index.d.ts +2 -0
- package/dist/components/alert/index.js +1 -0
- package/dist/components/animate-appear/PlAnimateAppear.d.ts +55 -0
- package/dist/components/animate-appear/PlAnimateAppear.js +71 -0
- package/dist/components/animate-appear/index.d.ts +2 -0
- package/dist/components/animate-appear/index.js +1 -0
- package/dist/components/animate-blink/PlAnimateBlink.d.ts +30 -0
- package/dist/components/animate-blink/PlAnimateBlink.js +47 -0
- package/dist/components/animate-blink/index.d.ts +2 -0
- package/dist/components/animate-blink/index.js +1 -0
- package/dist/components/animate-fade/PlAnimateFade.d.ts +35 -0
- package/dist/components/animate-fade/PlAnimateFade.js +48 -0
- package/dist/components/animate-fade/index.d.ts +2 -0
- package/dist/components/animate-fade/index.js +1 -0
- package/dist/components/animate-grow/PlAnimateGrow.d.ts +45 -0
- package/dist/components/animate-grow/PlAnimateGrow.js +49 -0
- package/dist/components/animate-grow/index.d.ts +2 -0
- package/dist/components/animate-grow/index.js +1 -0
- package/dist/components/animate-headline/PlAnimateHeadline.d.ts +55 -0
- package/dist/components/animate-headline/PlAnimateHeadline.js +120 -0
- package/dist/components/animate-headline/index.d.ts +2 -0
- package/dist/components/animate-headline/index.js +1 -0
- package/dist/components/animate-lighting/PlAnimateLighting.d.ts +67 -0
- package/dist/components/animate-lighting/PlAnimateLighting.js +65 -0
- package/dist/components/animate-lighting/index.d.ts +2 -0
- package/dist/components/animate-lighting/index.js +1 -0
- package/dist/components/animate-marquee/PlAnimateMarquee.d.ts +65 -0
- package/dist/components/animate-marquee/PlAnimateMarquee.js +94 -0
- package/dist/components/animate-marquee/index.d.ts +2 -0
- package/dist/components/animate-marquee/index.js +1 -0
- package/dist/components/animate-rotate/PlAnimateRotate.d.ts +52 -0
- package/dist/components/animate-rotate/PlAnimateRotate.js +50 -0
- package/dist/components/animate-rotate/index.d.ts +2 -0
- package/dist/components/animate-rotate/index.js +1 -0
- package/dist/components/animate-slide/PlAnimateSlide.d.ts +47 -0
- package/dist/components/animate-slide/PlAnimateSlide.js +49 -0
- package/dist/components/animate-slide/index.d.ts +2 -0
- package/dist/components/animate-slide/index.js +1 -0
- package/dist/components/animate-typing/PlAnimateTyping.d.ts +56 -0
- package/dist/components/animate-typing/PlAnimateTyping.js +177 -0
- package/dist/components/animate-typing/index.d.ts +2 -0
- package/dist/components/animate-typing/index.js +1 -0
- package/dist/components/animate-zoom/PlAnimateZoom.d.ts +37 -0
- package/dist/components/animate-zoom/PlAnimateZoom.js +45 -0
- package/dist/components/animate-zoom/index.d.ts +2 -0
- package/dist/components/animate-zoom/index.js +1 -0
- package/dist/components/aspect-ratio/PlAspectRatio.d.ts +64 -0
- package/dist/components/aspect-ratio/PlAspectRatio.js +58 -0
- package/dist/components/aspect-ratio/index.d.ts +2 -0
- package/dist/components/aspect-ratio/index.js +1 -0
- package/dist/components/avatar/PlAvatar.d.ts +102 -0
- package/dist/components/avatar/PlAvatar.js +121 -0
- package/dist/components/avatar/index.d.ts +2 -0
- package/dist/components/avatar/index.js +1 -0
- package/dist/components/badge/PlBadge.d.ts +86 -0
- package/dist/components/badge/PlBadge.js +168 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/badge/index.js +1 -0
- package/dist/components/blockquote/PlBlockquote.d.ts +64 -0
- package/dist/components/blockquote/PlBlockquote.js +112 -0
- package/dist/components/blockquote/index.d.ts +2 -0
- package/dist/components/blockquote/index.js +1 -0
- package/dist/components/bottom-navigation/PlBottomNavigation.d.ts +111 -0
- package/dist/components/bottom-navigation/PlBottomNavigation.js +141 -0
- package/dist/components/bottom-navigation/index.d.ts +2 -0
- package/dist/components/bottom-navigation/index.js +1 -0
- package/dist/components/box/PlBox.d.ts +50 -0
- package/dist/components/box/PlBox.js +46 -0
- package/dist/components/box/index.d.ts +2 -0
- package/dist/components/box/index.js +1 -0
- package/dist/components/breadcrumb/PlBreadcrumb.d.ts +138 -0
- package/dist/components/breadcrumb/PlBreadcrumb.js +201 -0
- package/dist/components/breadcrumb/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.js +1 -0
- package/dist/components/button/{Button.d.ts → PlButton.d.ts} +3 -3
- package/dist/components/button/PlButton.js +196 -0
- package/dist/components/button/index.d.ts +2 -2
- package/dist/components/button/index.js +1 -1
- package/dist/components/button-group/PlButtonGroup.d.ts +32 -0
- package/dist/components/button-group/PlButtonGroup.js +64 -0
- package/dist/components/button-group/index.d.ts +2 -0
- package/dist/components/button-group/index.js +1 -0
- package/dist/components/card/PlCard.d.ts +81 -0
- package/dist/components/card/PlCard.js +102 -0
- package/dist/components/card/index.d.ts +2 -0
- package/dist/components/card/index.js +1 -0
- package/dist/components/carousel/PlCarousel.d.ts +78 -0
- package/dist/components/carousel/PlCarousel.js +177 -0
- package/dist/components/carousel/index.d.ts +2 -0
- package/dist/components/carousel/index.js +1 -0
- package/dist/components/chat-bubble/PlChatBubble.d.ts +127 -0
- package/dist/components/chat-bubble/PlChatBubble.js +206 -0
- package/dist/components/chat-bubble/index.d.ts +2 -0
- package/dist/components/chat-bubble/index.js +1 -0
- package/dist/components/checkbox/PlCheckbox.d.ts +39 -0
- package/dist/components/checkbox/PlCheckbox.js +100 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/checkbox/index.js +1 -0
- package/dist/components/chip/PlChip.d.ts +55 -0
- package/dist/components/chip/PlChip.js +144 -0
- package/dist/components/chip/index.d.ts +2 -0
- package/dist/components/chip/index.js +1 -0
- package/dist/components/collapsible/PlCollapsible.d.ts +84 -0
- package/dist/components/collapsible/PlCollapsible.js +65 -0
- package/dist/components/collapsible/index.d.ts +2 -0
- package/dist/components/collapsible/index.js +1 -0
- package/dist/components/combobox/PlCombobox.d.ts +140 -0
- package/dist/components/combobox/PlCombobox.js +199 -0
- package/dist/components/combobox/index.d.ts +2 -0
- package/dist/components/combobox/index.js +1 -0
- package/dist/components/container/PlContainer.d.ts +66 -0
- package/dist/components/container/PlContainer.js +47 -0
- package/dist/components/container/index.d.ts +2 -0
- package/dist/components/container/index.js +1 -0
- package/dist/components/date-picker/PlDatePicker.d.ts +73 -0
- package/dist/components/date-picker/PlDatePicker.js +87 -0
- package/dist/components/date-picker/index.d.ts +2 -0
- package/dist/components/date-picker/index.js +1 -0
- package/dist/components/date-range-picker/PlDateRangePicker.d.ts +91 -0
- package/dist/components/date-range-picker/PlDateRangePicker.js +152 -0
- package/dist/components/date-range-picker/index.d.ts +2 -0
- package/dist/components/date-range-picker/index.js +1 -0
- package/dist/components/date-time-picker/PlDateTimePicker.d.ts +74 -0
- package/dist/components/date-time-picker/PlDateTimePicker.js +106 -0
- package/dist/components/date-time-picker/index.d.ts +2 -0
- package/dist/components/date-time-picker/index.js +1 -0
- package/dist/components/divider/PlDivider.d.ts +73 -0
- package/dist/components/divider/PlDivider.js +107 -0
- package/dist/components/divider/index.d.ts +2 -0
- package/dist/components/divider/index.js +1 -0
- package/dist/components/drawer/PlDrawer.d.ts +144 -0
- package/dist/components/drawer/PlDrawer.js +190 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/file-picker/PlFilePicker.d.ts +105 -0
- package/dist/components/file-picker/PlFilePicker.js +274 -0
- package/dist/components/file-picker/index.d.ts +2 -0
- package/dist/components/file-picker/index.js +1 -0
- package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.d.ts +118 -0
- package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +291 -0
- package/dist/components/floating-bottom-navigation/index.d.ts +2 -0
- package/dist/components/floating-bottom-navigation/index.js +1 -0
- package/dist/components/grid/PlGrid.d.ts +67 -0
- package/dist/components/grid/PlGrid.js +51 -0
- package/dist/components/grid/PlGridItem.d.ts +50 -0
- package/dist/components/grid/PlGridItem.js +34 -0
- package/dist/components/grid/index.d.ts +4 -0
- package/dist/components/grid/index.js +2 -0
- package/dist/components/highlight/PlHighlight.d.ts +90 -0
- package/dist/components/highlight/PlHighlight.js +185 -0
- package/dist/components/highlight/index.d.ts +2 -0
- package/dist/components/highlight/index.js +1 -0
- package/dist/components/hot-keys/PlHotKeys.d.ts +93 -0
- package/dist/components/hot-keys/PlHotKeys.js +294 -0
- package/dist/components/hot-keys/index.d.ts +2 -0
- package/dist/components/hot-keys/index.js +1 -0
- package/dist/components/icon/PlIcon.d.ts +62 -0
- package/dist/components/icon/PlIcon.js +58 -0
- package/dist/components/icon/index.d.ts +2 -0
- package/dist/components/icon/index.js +1 -0
- package/dist/components/icon-button/PlIconButton.d.ts +39 -0
- package/dist/components/icon-button/PlIconButton.js +37 -0
- package/dist/components/icon-button/index.d.ts +2 -0
- package/dist/components/icon-button/index.js +1 -0
- package/dist/components/list/PlList.d.ts +82 -0
- package/dist/components/list/PlList.js +160 -0
- package/dist/components/list/index.d.ts +2 -0
- package/dist/components/list/index.js +1 -0
- package/dist/components/menu/PlMenu.d.ts +210 -0
- package/dist/components/menu/PlMenu.js +209 -0
- package/dist/components/menu/index.d.ts +2 -0
- package/dist/components/menu/index.js +1 -0
- package/dist/components/modal/PlModal.d.ts +112 -0
- package/dist/components/modal/PlModal.js +150 -0
- package/dist/components/modal/index.d.ts +2 -0
- package/dist/components/modal/index.js +1 -0
- package/dist/components/number-field/PlNumberField.d.ts +133 -0
- package/dist/components/number-field/PlNumberField.js +111 -0
- package/dist/components/number-field/index.d.ts +2 -0
- package/dist/components/number-field/index.js +1 -0
- package/dist/components/otp-field/PlOtpField.d.ts +82 -0
- package/dist/components/otp-field/PlOtpField.js +109 -0
- package/dist/components/otp-field/index.d.ts +2 -0
- package/dist/components/otp-field/index.js +1 -0
- package/dist/components/overlay/PlOverlay.d.ts +96 -0
- package/dist/components/overlay/PlOverlay.js +77 -0
- package/dist/components/overlay/index.d.ts +2 -0
- package/dist/components/overlay/index.js +1 -0
- package/dist/components/pagination/PlPagination.d.ts +88 -0
- package/dist/components/pagination/PlPagination.js +159 -0
- package/dist/components/pagination/index.d.ts +2 -0
- package/dist/components/pagination/index.js +1 -0
- package/dist/components/panes/PlPanes.d.ts +79 -0
- package/dist/components/panes/PlPanes.js +324 -0
- package/dist/components/panes/index.d.ts +2 -0
- package/dist/components/panes/index.js +1 -0
- package/dist/components/pill/PlPill.d.ts +81 -0
- package/dist/components/pill/PlPill.js +154 -0
- package/dist/components/pill/index.d.ts +2 -0
- package/dist/components/pill/index.js +1 -0
- package/dist/components/popover/PlPopover.d.ts +107 -0
- package/dist/components/popover/PlPopover.js +113 -0
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/index.js +1 -0
- package/dist/components/progress-box/PlProgressBox.d.ts +32 -0
- package/dist/components/progress-box/PlProgressBox.js +34 -0
- package/dist/components/progress-box/index.d.ts +2 -0
- package/dist/components/progress-box/index.js +1 -0
- package/dist/components/progress-circular/PlProgressCircular.d.ts +22 -0
- package/dist/components/progress-circular/PlProgressCircular.js +47 -0
- package/dist/components/progress-circular/index.d.ts +2 -0
- package/dist/components/progress-circular/index.js +1 -0
- package/dist/components/progress-linear/PlProgressLinear.d.ts +31 -0
- package/dist/components/progress-linear/PlProgressLinear.js +40 -0
- package/dist/components/progress-linear/index.d.ts +2 -0
- package/dist/components/progress-linear/index.js +1 -0
- package/dist/components/radio-group/PlRadioGroup.d.ts +54 -0
- package/dist/components/radio-group/PlRadioGroup.js +99 -0
- package/dist/components/radio-group/index.d.ts +2 -0
- package/dist/components/radio-group/index.js +1 -0
- package/dist/components/rating/PlRating.d.ts +90 -0
- package/dist/components/rating/PlRating.js +101 -0
- package/dist/components/rating/index.d.ts +2 -0
- package/dist/components/rating/index.js +1 -0
- package/dist/components/scroll-zone/PlScrollZone.d.ts +132 -0
- package/dist/components/scroll-zone/PlScrollZone.js +411 -0
- package/dist/components/scroll-zone/index.d.ts +2 -0
- package/dist/components/scroll-zone/index.js +1 -0
- package/dist/components/segmented-button/PlSegmentedButton.d.ts +79 -0
- package/dist/components/segmented-button/PlSegmentedButton.js +206 -0
- package/dist/components/segmented-button/index.d.ts +2 -0
- package/dist/components/segmented-button/index.js +1 -0
- package/dist/components/select/PlSelect.d.ts +77 -0
- package/dist/components/select/PlSelect.js +115 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/index.js +1 -0
- package/dist/components/skeleton/PlSkeleton.d.ts +73 -0
- package/dist/components/skeleton/PlSkeleton.js +142 -0
- package/dist/components/skeleton/index.d.ts +2 -0
- package/dist/components/skeleton/index.js +1 -0
- package/dist/components/slider/PlSlider.d.ts +44 -0
- package/dist/components/slider/PlSlider.js +132 -0
- package/dist/components/slider/index.d.ts +2 -0
- package/dist/components/slider/index.js +1 -0
- package/dist/components/spoiler/PlSpoiler.d.ts +84 -0
- package/dist/components/spoiler/PlSpoiler.js +74 -0
- package/dist/components/spoiler/index.d.ts +2 -0
- package/dist/components/spoiler/index.js +1 -0
- package/dist/components/switch/PlSwitch.d.ts +42 -0
- package/dist/components/switch/PlSwitch.js +131 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.js +1 -0
- package/dist/components/table/PlTable.d.ts +112 -0
- package/dist/components/table/PlTable.js +210 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/index.js +1 -0
- package/dist/components/tabs/PlTabs.d.ts +94 -0
- package/dist/components/tabs/PlTabs.js +182 -0
- package/dist/components/tabs/index.d.ts +2 -0
- package/dist/components/tabs/index.js +1 -0
- package/dist/components/text-field/{TextField.d.ts → PlTextField.d.ts} +5 -5
- package/dist/components/text-field/PlTextField.js +126 -0
- package/dist/components/text-field/index.d.ts +2 -2
- package/dist/components/text-field/index.js +1 -1
- package/dist/components/text-link/PlTextLink.d.ts +80 -0
- package/dist/components/text-link/PlTextLink.js +136 -0
- package/dist/components/text-link/index.d.ts +2 -0
- package/dist/components/text-link/index.js +1 -0
- package/dist/components/time-picker/PlTimePicker.d.ts +88 -0
- package/dist/components/time-picker/PlTimePicker.js +97 -0
- package/dist/components/time-picker/index.d.ts +2 -0
- package/dist/components/time-picker/index.js +1 -0
- package/dist/components/timeline/PlTimeline.d.ts +98 -0
- package/dist/components/timeline/PlTimeline.js +207 -0
- package/dist/components/timeline/index.d.ts +2 -0
- package/dist/components/timeline/index.js +1 -0
- package/dist/components/toast/PlToast.d.ts +122 -0
- package/dist/components/toast/PlToast.js +174 -0
- package/dist/components/toast/index.d.ts +2 -0
- package/dist/components/toast/index.js +1 -0
- package/dist/components/toolbar/PlToolbar.d.ts +68 -0
- package/dist/components/toolbar/PlToolbar.js +65 -0
- package/dist/components/toolbar/index.d.ts +2 -0
- package/dist/components/toolbar/index.js +1 -0
- package/dist/components/tooltip/PlTooltip.d.ts +92 -0
- package/dist/components/tooltip/PlTooltip.js +117 -0
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/components/tooltip/index.js +1 -0
- package/dist/components/typography/PlTypography.d.ts +66 -0
- package/dist/components/typography/PlTypography.js +143 -0
- package/dist/components/typography/index.d.ts +2 -0
- package/dist/components/typography/index.js +1 -0
- package/dist/css/accordion.css +2 -0
- package/dist/css/alert.css +2 -0
- package/dist/css/animate-appear.css +2 -0
- package/dist/css/animate-blink.css +2 -0
- package/dist/css/animate-fade.css +2 -0
- package/dist/css/animate-grow.css +2 -0
- package/dist/css/animate-headline.css +2 -0
- package/dist/css/animate-lighting.css +2 -0
- package/dist/css/animate-marquee.css +2 -0
- package/dist/css/animate-rotate.css +2 -0
- package/dist/css/animate-slide.css +2 -0
- package/dist/css/animate-typing.css +2 -0
- package/dist/css/animate-zoom.css +2 -0
- package/dist/css/aspect-ratio.css +2 -0
- package/dist/css/avatar.css +2 -0
- package/dist/css/badge.css +2 -0
- package/dist/css/base.css +4 -0
- package/dist/css/blockquote.css +2 -0
- package/dist/css/bottom-navigation.css +2 -0
- package/dist/css/box.css +2 -0
- package/dist/css/breadcrumb.css +2 -0
- package/dist/css/button-group.css +2 -0
- package/dist/css/button.css +2 -0
- package/dist/css/card.css +2 -0
- package/dist/css/carousel.css +2 -0
- package/dist/css/chat-bubble.css +2 -0
- package/dist/css/checkbox.css +2 -0
- package/dist/css/chip.css +2 -0
- package/dist/css/collapsible.css +2 -0
- package/dist/css/combobox.css +2 -0
- package/dist/css/container.css +2 -0
- package/dist/css/date-picker.css +2 -0
- package/dist/css/date-range-picker.css +2 -0
- package/dist/css/date-time-picker.css +2 -0
- package/dist/css/divider.css +2 -0
- package/dist/css/drawer.css +2 -0
- package/dist/css/file-picker.css +2 -0
- package/dist/css/floating-bottom-navigation.css +2 -0
- package/dist/css/grid.css +2 -0
- package/dist/css/highlight.css +2 -0
- package/dist/css/hot-keys.css +2 -0
- package/dist/css/icon-button.css +2 -0
- package/dist/css/icon.css +2 -0
- package/dist/css/list.css +2 -0
- package/dist/css/menu.css +2 -0
- package/dist/css/modal.css +2 -0
- package/dist/css/number-field.css +2 -0
- package/dist/css/otp-field.css +2 -0
- package/dist/css/overlay.css +2 -0
- package/dist/css/pagination.css +2 -0
- package/dist/css/panes.css +2 -0
- package/dist/css/pill.css +2 -0
- package/dist/css/popover.css +2 -0
- package/dist/css/progress-box.css +2 -0
- package/dist/css/progress-circular.css +2 -0
- package/dist/css/progress-linear.css +2 -0
- package/dist/css/radio-group.css +2 -0
- package/dist/css/rating.css +2 -0
- package/dist/css/scroll-zone.css +2 -0
- package/dist/css/segmented-button.css +2 -0
- package/dist/css/select.css +2 -0
- package/dist/css/skeleton.css +2 -0
- package/dist/css/slider.css +2 -0
- package/dist/css/spoiler.css +2 -0
- package/dist/css/switch.css +2 -0
- package/dist/css/table.css +2 -0
- package/dist/css/tabs.css +2 -0
- package/dist/css/text-field.css +2 -0
- package/dist/css/text-link.css +2 -0
- package/dist/css/time-picker.css +2 -0
- package/dist/css/timeline.css +2 -0
- package/dist/css/toast.css +2 -0
- package/dist/css/toolbar.css +2 -0
- package/dist/css/tooltip.css +2 -0
- package/dist/css/typography.css +2 -0
- package/dist/index.d.ts +75 -3
- package/dist/index.js +75 -1
- package/dist/internal/animate.d.ts +161 -0
- package/dist/internal/animate.js +318 -0
- package/dist/internal/button-group.d.ts +27 -0
- package/dist/internal/button-group.js +19 -0
- package/dist/internal/calendar.d.ts +148 -0
- package/dist/internal/calendar.js +501 -0
- package/dist/internal/date.d.ts +173 -0
- package/dist/internal/date.js +353 -0
- package/dist/internal/format.d.ts +24 -0
- package/dist/internal/format.js +41 -0
- package/dist/internal/grid.d.ts +67 -0
- package/dist/internal/grid.js +143 -0
- package/dist/internal/icons.d.ts +86 -1
- package/dist/internal/icons.js +138 -1
- package/dist/internal/menu.d.ts +20 -0
- package/dist/internal/menu.js +18 -0
- package/dist/internal/picker.d.ts +118 -0
- package/dist/internal/picker.js +139 -0
- package/dist/internal/progress.d.ts +145 -0
- package/dist/internal/progress.js +167 -0
- package/dist/internal/sizer.d.ts +32 -0
- package/dist/internal/sizer.js +35 -0
- package/dist/internal/styles.d.ts +198 -8
- package/dist/internal/styles.js +636 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +899 -125
- package/dist/tokens.css +1275 -0
- package/dist/types.d.ts +150 -8
- package/dist/types.js +1 -1
- package/package.json +31 -27
- package/README.md +0 -111
- package/dist/components/button/Button.js +0 -1
- package/dist/components/text-field/TextField.js +0 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { PlButton } from '../button/PlButton.js';
|
|
4
|
+
import { Calendar, usePickerLabels } from '../../internal/calendar.js';
|
|
5
|
+
import { CalendarIcon } from '../../internal/icons.js';
|
|
6
|
+
import { PickerFooter, PickerShell } from '../../internal/picker.js';
|
|
7
|
+
import { displaySamples, formatDate, isDayOutside, isValidDate, localeWeekStart, mergeDateAndTime, startOfDay, startOfMonth, toISODate, today, withPlaceholder } from '../../internal/date.js';
|
|
8
|
+
import { cx } from '../../internal/styles.js';
|
|
9
|
+
/**
|
|
10
|
+
* One day, chosen from a calendar.
|
|
11
|
+
*
|
|
12
|
+
* The trigger is a `PlTextField`'s shell wearing a calendar glyph, on purpose
|
|
13
|
+
* and for the reason a `PlSelect`'s is: a form where the date field is a
|
|
14
|
+
* different height, radius or material from the fields around it is a form that
|
|
15
|
+
* looks assembled.
|
|
16
|
+
*
|
|
17
|
+
* What the calendar is actually for is the header. A picker that only steps a
|
|
18
|
+
* month at a time puts a birthday thirty years back a hundred and eighty clicks
|
|
19
|
+
* away, so the month name and the year are each a button that opens a grid of
|
|
20
|
+
* its own — twelve months, then twelve years at a time. Any month of the year on
|
|
21
|
+
* screen is two clicks; any year at all is three.
|
|
22
|
+
*
|
|
23
|
+
* There is no typing into the trigger. Parsing a date out of free text is
|
|
24
|
+
* locale-dependent in a way that cannot be done honestly without a date library,
|
|
25
|
+
* and a field that understands `27/7/26` in one browser and not in the next is
|
|
26
|
+
* worse than one that never claimed to.
|
|
27
|
+
*/
|
|
28
|
+
export const PlDatePicker = /* @__PURE__ */ React.forwardRef(function PlDatePicker({ value: valueProp, defaultValue, onValueChange, open: openProp, defaultOpen, onOpenChange, defaultMonth, minDate, maxDate, shouldDisableDate, locale, weekStartsOn, format = { dateStyle: 'medium' }, placeholder, clearable = false, showTodayButton = true, closeOnSelect = true, labels: labelOverrides, name, size = 'md', color = 'primary', readOnly = false, disabled = false, startIcon, ...shell }, ref) {
|
|
29
|
+
const labels = usePickerLabels(labelOverrides);
|
|
30
|
+
const firstDay = weekStartsOn ?? localeWeekStart(locale);
|
|
31
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue ?? null);
|
|
32
|
+
// `null` is a value a controlled picker legitimately holds — an emptied one —
|
|
33
|
+
// so the test is against `undefined` and never against falsiness.
|
|
34
|
+
const value = valueProp !== undefined ? valueProp : uncontrolledValue;
|
|
35
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
|
|
36
|
+
const open = openProp ?? uncontrolledOpen;
|
|
37
|
+
const [month, setMonth] = React.useState(() => startOfMonth(isValidDate(value) ? value : (defaultMonth ?? today())));
|
|
38
|
+
// Opening puts the calendar back on the chosen day. Without this, a picker
|
|
39
|
+
// left on 2019 while browsing stays there the next time it is opened, which
|
|
40
|
+
// reads as the control having forgotten its own value.
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
if (open) {
|
|
43
|
+
setMonth(startOfMonth(isValidDate(value) ? value : (defaultMonth ?? today())));
|
|
44
|
+
}
|
|
45
|
+
// Only when the popup opens — following `value` here would drag the
|
|
46
|
+
// calendar out from under someone typing into a form elsewhere.
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, [open]);
|
|
49
|
+
const setOpen = (next) => {
|
|
50
|
+
// A read-only picker does not open. What it holds is something to read, and
|
|
51
|
+
// a calendar whose every cell was inert would be a menu of nothing.
|
|
52
|
+
if (next && (readOnly || disabled)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (openProp === undefined) {
|
|
56
|
+
setUncontrolledOpen(next);
|
|
57
|
+
}
|
|
58
|
+
onOpenChange?.(next);
|
|
59
|
+
};
|
|
60
|
+
const commit = (next) => {
|
|
61
|
+
if (valueProp === undefined) {
|
|
62
|
+
setUncontrolledValue(next);
|
|
63
|
+
}
|
|
64
|
+
onValueChange?.(next);
|
|
65
|
+
};
|
|
66
|
+
const select = (date) => {
|
|
67
|
+
// The day changes; the time of day, if the value had one, does not. A
|
|
68
|
+
// picker bound to a field that also carries a time should not silently
|
|
69
|
+
// reset it to midnight every time the day is corrected.
|
|
70
|
+
const next = isValidDate(value) ? mergeDateAndTime(date, value) : startOfDay(date);
|
|
71
|
+
commit(next);
|
|
72
|
+
setMonth(startOfMonth(next));
|
|
73
|
+
if (closeOnSelect) {
|
|
74
|
+
setOpen(false);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const now = today();
|
|
78
|
+
const todayBlocked = isDayOutside(now, minDate, maxDate) || (shouldDisableDate?.(now) ?? false);
|
|
79
|
+
const hasFooter = showTodayButton || clearable;
|
|
80
|
+
// Holds the trigger open at the width of the longest date it could show, so
|
|
81
|
+
// choosing the 1st after the 28th does not shrink the field.
|
|
82
|
+
const samples = React.useMemo(() => withPlaceholder(displaySamples(locale, format), placeholder), [locale, format, placeholder]);
|
|
83
|
+
return (_jsx(PickerShell, { ...shell, size: size, color: color, readOnly: readOnly, disabled: disabled, triggerRef: ref, startIcon: startIcon ?? _jsx(CalendarIcon, {}), display: isValidDate(value) ? formatDate(value, locale, format) : (placeholder ?? ''), samples: samples, empty: !isValidDate(value), clearable: clearable, onClear: () => commit(null), open: open, onOpenChange: setOpen, labels: labels, hiddenValues: name ? [{ name, value: isValidDate(value) ? toISODate(value) : '' }] : undefined, children: _jsxs("div", { className: cx('flex flex-col', hasFooter && 'gap-1.5'), children: [_jsx(Calendar, { size: size, color: color, locale: locale, weekStartsOn: firstDay, month: month, onMonthChange: setMonth, selected: [value], onSelect: select, minDate: minDate, maxDate: maxDate, shouldDisableDate: shouldDisableDate, labels: labels, autoFocus: true }), hasFooter ? (_jsxs(PickerFooter, { size: size, children: [clearable ? (_jsx(PlButton, { variant: "ghost", size: size, color: color, density: "compact", onClick: () => {
|
|
84
|
+
commit(null);
|
|
85
|
+
setOpen(false);
|
|
86
|
+
}, children: labels.clear })) : null, showTodayButton ? (_jsx(PlButton, { variant: "ghost", size: size, color: color, density: "compact", disabled: todayBlocked, onClick: () => select(now), children: labels.today })) : null] })) : null] }) }));
|
|
87
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PlDatePicker } from './PlDatePicker.js';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type PlassPickerLabels } from '../../internal/calendar.js';
|
|
3
|
+
import { type PlassPickerShellProps } from '../../internal/picker.js';
|
|
4
|
+
import type { PlassWeekday } from '../../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Two ends, either of which may be missing.
|
|
7
|
+
*
|
|
8
|
+
* An object rather than a `[Date, Date]` tuple, and rather than two props. A
|
|
9
|
+
* range is one value — it is chosen in one gesture, cleared in one gesture and
|
|
10
|
+
* validated as a whole — and the two names are what stop a caller writing the
|
|
11
|
+
* end into the start. Half a range is a real state: it is what the picker holds
|
|
12
|
+
* between the first click and the second.
|
|
13
|
+
*/
|
|
14
|
+
export interface PlDateRange {
|
|
15
|
+
start: Date | null;
|
|
16
|
+
end: Date | null;
|
|
17
|
+
}
|
|
18
|
+
/** A named range offered as a shortcut beside the calendars. */
|
|
19
|
+
export interface PlDateRangePreset {
|
|
20
|
+
label: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* The range it stands for. A function when it depends on today, which is
|
|
23
|
+
* almost always — "the last 7 days" computed at module scope is a range that
|
|
24
|
+
* would be wrong for anyone who left the tab open overnight.
|
|
25
|
+
*/
|
|
26
|
+
value: PlDateRange | (() => PlDateRange);
|
|
27
|
+
}
|
|
28
|
+
export interface PlDateRangePickerProps extends PlassPickerShellProps {
|
|
29
|
+
/** The chosen range. Use with `onValueChange` for a controlled picker. */
|
|
30
|
+
value?: PlDateRange | null;
|
|
31
|
+
defaultValue?: PlDateRange | null;
|
|
32
|
+
/** Always called with an object. A cleared range is `{ start: null, end: null }`. */
|
|
33
|
+
onValueChange?: (value: PlDateRange) => void;
|
|
34
|
+
open?: boolean;
|
|
35
|
+
defaultOpen?: boolean;
|
|
36
|
+
onOpenChange?: (open: boolean) => void;
|
|
37
|
+
/** Which month the left calendar opens on when there is no value. */
|
|
38
|
+
defaultMonth?: Date;
|
|
39
|
+
/** The earliest day that may be chosen. Day-granular — the time is ignored. */
|
|
40
|
+
minDate?: Date | null;
|
|
41
|
+
/** The latest day that may be chosen. */
|
|
42
|
+
maxDate?: Date | null;
|
|
43
|
+
/** Blocks individual days that are inside the range but still not available. */
|
|
44
|
+
shouldDisableDate?: (date: Date) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* BCP 47 tag deciding the month and weekday names, the order of the header's
|
|
47
|
+
* two buttons, and how the trigger writes the dates. Defaults to the browser's.
|
|
48
|
+
*/
|
|
49
|
+
locale?: string;
|
|
50
|
+
/** Which day the week starts on. Defaults to whatever the locale says. */
|
|
51
|
+
weekStartsOn?: PlassWeekday;
|
|
52
|
+
/** @default { dateStyle: 'medium' } */
|
|
53
|
+
format?: Intl.DateTimeFormatOptions;
|
|
54
|
+
/**
|
|
55
|
+
* How many months are on screen at once. Two is the default because a range
|
|
56
|
+
* that crosses a month boundary is the ordinary case, not the exception.
|
|
57
|
+
* @default 2
|
|
58
|
+
*/
|
|
59
|
+
monthCount?: 1 | 2;
|
|
60
|
+
/** Shown in each half of the trigger while that end is unchosen. */
|
|
61
|
+
startPlaceholder?: React.ReactNode;
|
|
62
|
+
endPlaceholder?: React.ReactNode;
|
|
63
|
+
/** Shortcuts listed beside the calendars — "Last 7 days", "This month". */
|
|
64
|
+
presets?: readonly PlDateRangePreset[];
|
|
65
|
+
/** Offers the × that empties the control. @default false */
|
|
66
|
+
clearable?: boolean;
|
|
67
|
+
/** Closes the popup once both ends are chosen. @default true */
|
|
68
|
+
closeOnSelect?: boolean;
|
|
69
|
+
/** The strings the picker says. Every one has an English default. */
|
|
70
|
+
labels?: Partial<PlassPickerLabels>;
|
|
71
|
+
/**
|
|
72
|
+
* Identifies the field when a form is submitted. Two hidden inputs of the
|
|
73
|
+
* same name, so the two ends arrive as `FormData.getAll(name)`.
|
|
74
|
+
*/
|
|
75
|
+
name?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A span between two days.
|
|
79
|
+
*
|
|
80
|
+
* Two months side by side, because a range that crosses a month boundary is the
|
|
81
|
+
* ordinary case and a one-month picker makes it a two-step navigation problem.
|
|
82
|
+
* The two panels are one calendar in two halves: the left one has no forward
|
|
83
|
+
* stepper, the right one has no back stepper, and either header's month and year
|
|
84
|
+
* buttons move both.
|
|
85
|
+
*
|
|
86
|
+
* The band between the ends is drawn as the pointer moves, before the second
|
|
87
|
+
* click lands. That preview is the whole affordance — without it the first click
|
|
88
|
+
* has no visible consequence and the control looks broken for the second or so
|
|
89
|
+
* between the two.
|
|
90
|
+
*/
|
|
91
|
+
export declare const PlDateRangePicker: React.ForwardRefExoticComponent<PlDateRangePickerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { PlButton } from '../button/PlButton.js';
|
|
4
|
+
import { Calendar, usePickerLabels } from '../../internal/calendar.js';
|
|
5
|
+
import { ArrowRightIcon, CalendarIcon } from '../../internal/icons.js';
|
|
6
|
+
import { PickerFooter, PickerShell } from '../../internal/picker.js';
|
|
7
|
+
import { WidthSizer } from '../../internal/sizer.js';
|
|
8
|
+
import { addMonths, compareDay, displaySamples, formatDate, isValidDate, localeWeekStart, startOfDay, startOfMonth, toISODate, today, withPlaceholder } from '../../internal/date.js';
|
|
9
|
+
import { cx, gapClasses, metaTextClasses } from '../../internal/styles.js';
|
|
10
|
+
const EMPTY = { start: null, end: null };
|
|
11
|
+
/**
|
|
12
|
+
* A span between two days.
|
|
13
|
+
*
|
|
14
|
+
* Two months side by side, because a range that crosses a month boundary is the
|
|
15
|
+
* ordinary case and a one-month picker makes it a two-step navigation problem.
|
|
16
|
+
* The two panels are one calendar in two halves: the left one has no forward
|
|
17
|
+
* stepper, the right one has no back stepper, and either header's month and year
|
|
18
|
+
* buttons move both.
|
|
19
|
+
*
|
|
20
|
+
* The band between the ends is drawn as the pointer moves, before the second
|
|
21
|
+
* click lands. That preview is the whole affordance — without it the first click
|
|
22
|
+
* has no visible consequence and the control looks broken for the second or so
|
|
23
|
+
* between the two.
|
|
24
|
+
*/
|
|
25
|
+
export const PlDateRangePicker = /* @__PURE__ */ React.forwardRef(function PlDateRangePicker({ value: valueProp, defaultValue, onValueChange, open: openProp, defaultOpen, onOpenChange, defaultMonth, minDate, maxDate, shouldDisableDate, locale, weekStartsOn, format = { dateStyle: 'medium' }, monthCount = 2, startPlaceholder, endPlaceholder, presets, clearable = false, closeOnSelect = true, labels: labelOverrides, name, size = 'md', color = 'primary', readOnly = false, disabled = false, startIcon, ...shell }, ref) {
|
|
26
|
+
const labels = usePickerLabels(labelOverrides);
|
|
27
|
+
const firstDay = weekStartsOn ?? localeWeekStart(locale);
|
|
28
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue ?? EMPTY);
|
|
29
|
+
const value = valueProp !== undefined ? (valueProp ?? EMPTY) : uncontrolledValue;
|
|
30
|
+
const start = isValidDate(value.start) ? value.start : null;
|
|
31
|
+
const end = isValidDate(value.end) ? value.end : null;
|
|
32
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
|
|
33
|
+
const open = openProp ?? uncontrolledOpen;
|
|
34
|
+
// The first of the two clicks. Held here rather than in `value` so a
|
|
35
|
+
// controlled caller is never handed a range with only one end — half a
|
|
36
|
+
// selection is this component's business, not the form's.
|
|
37
|
+
const [anchor, setAnchor] = React.useState(null);
|
|
38
|
+
const [preview, setPreview] = React.useState(null);
|
|
39
|
+
const [month, setMonth] = React.useState(() => startOfMonth(start ?? defaultMonth ?? today()));
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
if (open) {
|
|
42
|
+
setMonth(startOfMonth(start ?? defaultMonth ?? today()));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// An abandoned half-selection does not survive the popup closing.
|
|
46
|
+
setAnchor(null);
|
|
47
|
+
setPreview(null);
|
|
48
|
+
}
|
|
49
|
+
// Only when the popup opens — following `start` here would drag the calendar
|
|
50
|
+
// out from under someone typing into a form elsewhere.
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, [open]);
|
|
53
|
+
const setOpen = (next) => {
|
|
54
|
+
if (next && (readOnly || disabled)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (openProp === undefined) {
|
|
58
|
+
setUncontrolledOpen(next);
|
|
59
|
+
}
|
|
60
|
+
onOpenChange?.(next);
|
|
61
|
+
};
|
|
62
|
+
const commit = (next) => {
|
|
63
|
+
if (valueProp === undefined) {
|
|
64
|
+
setUncontrolledValue(next);
|
|
65
|
+
}
|
|
66
|
+
onValueChange?.(next);
|
|
67
|
+
};
|
|
68
|
+
const select = (date) => {
|
|
69
|
+
const day = startOfDay(date);
|
|
70
|
+
// The first click of a new selection — either there is no anchor, or the
|
|
71
|
+
// range is already complete and this click starts over.
|
|
72
|
+
if (anchor === null) {
|
|
73
|
+
setAnchor(day);
|
|
74
|
+
setPreview(day);
|
|
75
|
+
commit({ start: day, end: null });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// The second. Clicking backwards is not a mistake to be rejected, it is the
|
|
79
|
+
// same range typed in the other order.
|
|
80
|
+
const [from, to] = compareDay(day, anchor) < 0 ? [day, anchor] : [anchor, day];
|
|
81
|
+
setAnchor(null);
|
|
82
|
+
setPreview(null);
|
|
83
|
+
commit({ start: from, end: to });
|
|
84
|
+
if (closeOnSelect) {
|
|
85
|
+
setOpen(false);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const applyPreset = (preset) => {
|
|
89
|
+
const range = typeof preset.value === 'function' ? preset.value() : preset.value;
|
|
90
|
+
setAnchor(null);
|
|
91
|
+
setPreview(null);
|
|
92
|
+
commit(range);
|
|
93
|
+
if (isValidDate(range.start)) {
|
|
94
|
+
setMonth(startOfMonth(range.start));
|
|
95
|
+
}
|
|
96
|
+
if (closeOnSelect) {
|
|
97
|
+
setOpen(false);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
// What the band is drawn between: the finished range, or the anchor and
|
|
101
|
+
// whatever the pointer is currently over.
|
|
102
|
+
const bandStart = anchor ?? start;
|
|
103
|
+
const bandEnd = anchor !== null ? preview : end;
|
|
104
|
+
const write = (date, fallback) => isValidDate(date) ? (formatDate(date, locale, format)) : (_jsx("span", { className: "text-(--plass-muted-fg)", children: fallback ?? '' }));
|
|
105
|
+
const secondMonth = addMonths(month, 1);
|
|
106
|
+
const twoUp = monthCount === 2;
|
|
107
|
+
// Every date either half could show, so neither end of the trigger changes
|
|
108
|
+
// width as the range is filled in.
|
|
109
|
+
const dateSamples = React.useMemo(() => displaySamples(locale, format), [locale, format]);
|
|
110
|
+
// Which end the next click will fill. The trigger says the same thing with its
|
|
111
|
+
// two halves, but the trigger is behind the popup while the popup is up, so
|
|
112
|
+
// the footer is the only place that can say it where it will be read.
|
|
113
|
+
const hint = anchor !== null ? labels.end : start === null ? labels.start : null;
|
|
114
|
+
const calendarProps = {
|
|
115
|
+
size,
|
|
116
|
+
color,
|
|
117
|
+
locale,
|
|
118
|
+
weekStartsOn: firstDay,
|
|
119
|
+
selected: [start, end, anchor],
|
|
120
|
+
rangeStart: bandStart,
|
|
121
|
+
rangeEnd: bandEnd,
|
|
122
|
+
onSelect: select,
|
|
123
|
+
onPreviewChange: (date) => {
|
|
124
|
+
if (anchor !== null) {
|
|
125
|
+
setPreview(date ?? anchor);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
minDate,
|
|
129
|
+
maxDate,
|
|
130
|
+
shouldDisableDate,
|
|
131
|
+
// With both panels showing six full weeks, the 1st of August is a trailing
|
|
132
|
+
// day of the July panel *and* the first day of the August one. Two cells
|
|
133
|
+
// with the same name in one popup is ambiguous to a pointer and outright
|
|
134
|
+
// broken to a screen reader.
|
|
135
|
+
showOutsideDays: false,
|
|
136
|
+
labels
|
|
137
|
+
};
|
|
138
|
+
return (_jsx(PickerShell, { ...shell, size: size, color: color, readOnly: readOnly, disabled: disabled, triggerRef: ref, startIcon: startIcon ?? _jsx(CalendarIcon, {}), display: _jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [_jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "truncate", children: write(start, startPlaceholder) }), _jsx(WidthSizer, { samples: withPlaceholder(dateSamples, startPlaceholder) })] }), _jsx("span", { "aria-hidden": "true", className: "flex shrink-0 items-center text-(--plass-muted-fg) rtl:rotate-180", children: _jsx(ArrowRightIcon, {}) }), _jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "truncate", children: write(end, endPlaceholder) }), _jsx(WidthSizer, { samples: withPlaceholder(dateSamples, endPlaceholder) })] })] }), empty: start === null && end === null, clearable: clearable, onClear: () => commit(EMPTY), open: open, onOpenChange: setOpen, labels: labels, hiddenValues: name
|
|
139
|
+
? [
|
|
140
|
+
{ name, value: start ? toISODate(start) : '' },
|
|
141
|
+
{ name, value: end ? toISODate(end) : '' }
|
|
142
|
+
]
|
|
143
|
+
: undefined, children: _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsxs("div", { className: cx('flex items-stretch', gapClasses[size]), children: [presets && presets.length > 0 ? (_jsx("div", { className: cx('flex max-h-[calc(var(--p-cell,2.5rem)*8)] flex-col overflow-y-auto border-e pe-1.5', '[border-color:var(--plass-divider)]'), children: presets.map((preset, index) => (_jsx(PlButton, { variant: "ghost", size: size, color: color, density: "compact", className: "justify-start whitespace-nowrap", onClick: () => applyPreset(preset), children: preset.label }, index))) })) : null, _jsx(Calendar, { ...calendarProps, month: month, onMonthChange: setMonth, showNextButton: !twoUp, autoFocus: true }), twoUp ? (_jsx(Calendar, { ...calendarProps, month: secondMonth,
|
|
144
|
+
// The right panel is a month ahead, so moving it means moving the
|
|
145
|
+
// pair. Both headers drive one number.
|
|
146
|
+
onMonthChange: (next) => setMonth(addMonths(next, -1)), showPreviousButton: false })) : null] }), clearable || hint !== null ? (_jsxs(PickerFooter, { size: size, children: [hint !== null ? (_jsx("span", { className: cx('me-auto text-(--plass-muted-fg)', metaTextClasses[size]), children: hint })) : null, clearable ? (_jsx(PlButton, { variant: "ghost", size: size, color: color, density: "compact", onClick: () => {
|
|
147
|
+
setAnchor(null);
|
|
148
|
+
setPreview(null);
|
|
149
|
+
commit(EMPTY);
|
|
150
|
+
setOpen(false);
|
|
151
|
+
}, children: labels.clear })) : null] })) : null] }) }));
|
|
152
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PlDateRangePicker } from './PlDateRangePicker.js';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type PlassPickerLabels } from '../../internal/calendar.js';
|
|
3
|
+
import { type PlassPickerShellProps } from '../../internal/picker.js';
|
|
4
|
+
import { type TimeUnit } from '../../internal/date.js';
|
|
5
|
+
import type { PlassWeekday } from '../../types.js';
|
|
6
|
+
export interface PlDateTimePickerProps extends PlassPickerShellProps {
|
|
7
|
+
/** The chosen moment. Use with `onValueChange` for a controlled picker. */
|
|
8
|
+
value?: Date | null;
|
|
9
|
+
defaultValue?: Date | null;
|
|
10
|
+
onValueChange?: (value: Date | null) => void;
|
|
11
|
+
open?: boolean;
|
|
12
|
+
defaultOpen?: boolean;
|
|
13
|
+
onOpenChange?: (open: boolean) => void;
|
|
14
|
+
/** Which month the calendar opens on when there is no value. */
|
|
15
|
+
defaultMonth?: Date;
|
|
16
|
+
/**
|
|
17
|
+
* The earliest moment that may be chosen. Unlike a `PlDatePicker`'s, this one
|
|
18
|
+
* is read at full precision: the day it falls on stays available and the clock
|
|
19
|
+
* columns block the hours before it.
|
|
20
|
+
*/
|
|
21
|
+
minDate?: Date | null;
|
|
22
|
+
/** The latest moment that may be chosen, likewise at full precision. */
|
|
23
|
+
maxDate?: Date | null;
|
|
24
|
+
shouldDisableDate?: (date: Date) => boolean;
|
|
25
|
+
shouldDisableTime?: (value: Date, unit: TimeUnit) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* BCP 47 tag deciding the month and weekday names, whether the clock is on a
|
|
28
|
+
* 12-hour dial, and how the trigger writes the moment.
|
|
29
|
+
*/
|
|
30
|
+
locale?: string;
|
|
31
|
+
weekStartsOn?: PlassWeekday;
|
|
32
|
+
/**
|
|
33
|
+
* How the trigger writes the chosen moment. Passed straight to `Intl`.
|
|
34
|
+
* @default { dateStyle: 'medium', timeStyle: 'short' }
|
|
35
|
+
*/
|
|
36
|
+
format?: Intl.DateTimeFormatOptions;
|
|
37
|
+
/** A 12-hour dial with an AM/PM column. Defaults to whatever the locale does. */
|
|
38
|
+
hour12?: boolean;
|
|
39
|
+
showSeconds?: boolean;
|
|
40
|
+
hourStep?: number;
|
|
41
|
+
minuteStep?: number;
|
|
42
|
+
secondStep?: number;
|
|
43
|
+
placeholder?: React.ReactNode;
|
|
44
|
+
clearable?: boolean;
|
|
45
|
+
/** Offers the shortcut to this moment in the footer. @default true */
|
|
46
|
+
showNowButton?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Closes the popup as soon as a day is chosen. `false` here and `true` on a
|
|
49
|
+
* `PlDatePicker`, because a moment is a day *and* a time and closing on the
|
|
50
|
+
* first of the two would leave the second unanswered.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
closeOnSelect?: boolean;
|
|
54
|
+
/** The strings the picker says. Every one has an English default. */
|
|
55
|
+
labels?: Partial<PlassPickerLabels>;
|
|
56
|
+
/** Identifies the field when a form is submitted, as `YYYY-MM-DDTHH:MM`. */
|
|
57
|
+
name?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A day and a time, in one popup.
|
|
61
|
+
*
|
|
62
|
+
* Not a date picker that grew a clock and not a time picker that grew a
|
|
63
|
+
* calendar: the two panels sit side by side at exactly the same height — seven
|
|
64
|
+
* rows of cells each, which is why the calendar's grid and the clock's columns
|
|
65
|
+
* share the `--p-cell` ladder — so the popup is one rectangle rather than two of
|
|
66
|
+
* different sizes pushed together.
|
|
67
|
+
*
|
|
68
|
+
* The bounds do more work here than anywhere else. `minDate` is read at **full
|
|
69
|
+
* precision**, so a minimum of 09:30 on the 27th leaves the 27th selectable in
|
|
70
|
+
* the calendar and greys out the morning in the clock. That is the behaviour a
|
|
71
|
+
* "not before now" rule needs, and it is the one a day-granular check cannot
|
|
72
|
+
* give.
|
|
73
|
+
*/
|
|
74
|
+
export declare const PlDateTimePicker: React.ForwardRefExoticComponent<PlDateTimePickerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { PlButton } from '../button/PlButton.js';
|
|
4
|
+
import { Calendar, TimeGrid, usePickerLabels } from '../../internal/calendar.js';
|
|
5
|
+
import { CalendarIcon } from '../../internal/icons.js';
|
|
6
|
+
import { PickerDivider, PickerFooter, PickerShell } from '../../internal/picker.js';
|
|
7
|
+
import { displaySamples, formatDate, isDayOutside, isHour12, isValidDate, localeWeekStart, mergeDateAndTime, startOfDay, startOfMonth, timeUnitSpan, toISODateTime, today, withPlaceholder, withTime } from '../../internal/date.js';
|
|
8
|
+
import { cx, gapClasses } from '../../internal/styles.js';
|
|
9
|
+
/**
|
|
10
|
+
* A day and a time, in one popup.
|
|
11
|
+
*
|
|
12
|
+
* Not a date picker that grew a clock and not a time picker that grew a
|
|
13
|
+
* calendar: the two panels sit side by side at exactly the same height — seven
|
|
14
|
+
* rows of cells each, which is why the calendar's grid and the clock's columns
|
|
15
|
+
* share the `--p-cell` ladder — so the popup is one rectangle rather than two of
|
|
16
|
+
* different sizes pushed together.
|
|
17
|
+
*
|
|
18
|
+
* The bounds do more work here than anywhere else. `minDate` is read at **full
|
|
19
|
+
* precision**, so a minimum of 09:30 on the 27th leaves the 27th selectable in
|
|
20
|
+
* the calendar and greys out the morning in the clock. That is the behaviour a
|
|
21
|
+
* "not before now" rule needs, and it is the one a day-granular check cannot
|
|
22
|
+
* give.
|
|
23
|
+
*/
|
|
24
|
+
export const PlDateTimePicker = /* @__PURE__ */ React.forwardRef(function PlDateTimePicker({ value: valueProp, defaultValue, onValueChange, open: openProp, defaultOpen, onOpenChange, defaultMonth, minDate, maxDate, shouldDisableDate, shouldDisableTime, locale, weekStartsOn, format = { dateStyle: 'medium', timeStyle: 'short' }, hour12: hour12Prop, showSeconds = false, hourStep = 1, minuteStep = 1, secondStep = 1, placeholder, clearable = false, showNowButton = true, closeOnSelect = false, labels: labelOverrides, name, size = 'md', color = 'primary', density = 'default', readOnly = false, disabled = false, startIcon, ...shell }, ref) {
|
|
25
|
+
const labels = usePickerLabels(labelOverrides);
|
|
26
|
+
const firstDay = weekStartsOn ?? localeWeekStart(locale);
|
|
27
|
+
const hour12 = hour12Prop ?? isHour12(locale);
|
|
28
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue ?? null);
|
|
29
|
+
const value = valueProp !== undefined ? valueProp : uncontrolledValue;
|
|
30
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
|
|
31
|
+
const open = openProp ?? uncontrolledOpen;
|
|
32
|
+
const [month, setMonth] = React.useState(() => startOfMonth(isValidDate(value) ? value : (defaultMonth ?? today())));
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (open) {
|
|
35
|
+
setMonth(startOfMonth(isValidDate(value) ? value : (defaultMonth ?? today())));
|
|
36
|
+
}
|
|
37
|
+
// Only when the popup opens — following `value` here would drag the calendar
|
|
38
|
+
// out from under someone typing into a form elsewhere.
|
|
39
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
+
}, [open]);
|
|
41
|
+
const setOpen = (next) => {
|
|
42
|
+
if (next && (readOnly || disabled)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (openProp === undefined) {
|
|
46
|
+
setUncontrolledOpen(next);
|
|
47
|
+
}
|
|
48
|
+
onOpenChange?.(next);
|
|
49
|
+
};
|
|
50
|
+
const commit = (next) => {
|
|
51
|
+
if (valueProp === undefined) {
|
|
52
|
+
setUncontrolledValue(next);
|
|
53
|
+
}
|
|
54
|
+
onValueChange?.(next);
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Blocks a clock row whose whole span falls outside the bounds — the same span
|
|
58
|
+
* test a `PlTimePicker` makes, moved onto the absolute timeline so the check
|
|
59
|
+
* knows which day the columns are writing into.
|
|
60
|
+
*/
|
|
61
|
+
const isTimeBlocked = React.useCallback((candidate, unit) => {
|
|
62
|
+
const [from, to] = timeUnitSpan(unit, candidate);
|
|
63
|
+
const midnight = startOfDay(candidate).getTime();
|
|
64
|
+
if (isValidDate(minDate) && midnight + to * 1000 < minDate.getTime()) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (isValidDate(maxDate) && midnight + from * 1000 > maxDate.getTime()) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return shouldDisableTime?.(candidate, unit) ?? false;
|
|
71
|
+
}, [minDate, maxDate, shouldDisableTime]);
|
|
72
|
+
const selectDay = (date) => {
|
|
73
|
+
// The day changes, the clock does not. A picker that reset the time to
|
|
74
|
+
// midnight every time the date was corrected would make choosing a moment an
|
|
75
|
+
// ordered task, and nobody reads a popup in the order it was written.
|
|
76
|
+
const next = isValidDate(value) ? mergeDateAndTime(date, value) : startOfDay(date);
|
|
77
|
+
commit(next);
|
|
78
|
+
setMonth(startOfMonth(next));
|
|
79
|
+
if (closeOnSelect) {
|
|
80
|
+
setOpen(false);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const nowMoment = new Date();
|
|
84
|
+
const nowValue = withTime(nowMoment, { seconds: showSeconds ? nowMoment.getSeconds() : 0 });
|
|
85
|
+
const nowBlocked = isDayOutside(nowValue, minDate, maxDate) ||
|
|
86
|
+
(shouldDisableDate?.(nowValue) ?? false) ||
|
|
87
|
+
isTimeBlocked(nowValue, 'second');
|
|
88
|
+
// Holds the trigger open at the width of the longest moment it could show, so
|
|
89
|
+
// choosing an earlier one does not shrink the field.
|
|
90
|
+
const samples = React.useMemo(() => withPlaceholder(displaySamples(locale, format), placeholder), [locale, format, placeholder]);
|
|
91
|
+
return (_jsx(PickerShell, { ...shell, size: size, color: color, density: density, readOnly: readOnly, disabled: disabled, triggerRef: ref,
|
|
92
|
+
// The calendar glyph alone, not both: a control cannot say two things at
|
|
93
|
+
// once, and the date is the part a reader scans for.
|
|
94
|
+
startIcon: startIcon ?? _jsx(CalendarIcon, {}), display: isValidDate(value) ? formatDate(value, locale, format) : (placeholder ?? ''), samples: samples, empty: !isValidDate(value), clearable: clearable, onClear: () => commit(null), open: open, onOpenChange: setOpen, labels: labels, hiddenValues: name
|
|
95
|
+
? [{ name, value: isValidDate(value) ? toISODateTime(value, showSeconds) : '' }]
|
|
96
|
+
: undefined, children: _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsxs("div", { className: cx('flex items-stretch', gapClasses[size]), children: [_jsx(Calendar, { size: size, color: color, locale: locale, weekStartsOn: firstDay, month: month, onMonthChange: setMonth, selected: [value], onSelect: selectDay, minDate: minDate, maxDate: maxDate, shouldDisableDate: shouldDisableDate, labels: labels, autoFocus: true }), _jsx(PickerDivider, {}), _jsx(TimeGrid, { size: size, density: density, locale: locale, value: isValidDate(value) ? value : null,
|
|
97
|
+
// With no day chosen yet the clock writes onto today, and picking a
|
|
98
|
+
// day afterwards keeps whatever time was set.
|
|
99
|
+
referenceDate: isValidDate(value) ? value : today(), onChange: commit, hour12: hour12, showSeconds: showSeconds, hourStep: hourStep, minuteStep: minuteStep, secondStep: secondStep, shouldDisableTime: isTimeBlocked, labels: labels })] }), _jsxs(PickerFooter, { size: size, children: [clearable ? (_jsx(PlButton, { variant: "ghost", size: size, color: color, density: "compact", onClick: () => {
|
|
100
|
+
commit(null);
|
|
101
|
+
setOpen(false);
|
|
102
|
+
}, children: labels.clear })) : null, showNowButton ? (_jsx(PlButton, { variant: "ghost", size: size, color: color, density: "compact", disabled: nowBlocked, onClick: () => {
|
|
103
|
+
commit(nowValue);
|
|
104
|
+
setMonth(startOfMonth(nowValue));
|
|
105
|
+
}, children: labels.now })) : null, _jsx(PlButton, { variant: "solid", size: size, color: color, density: "compact", onClick: () => setOpen(false), children: labels.done })] })] }) }));
|
|
106
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PlDateTimePicker } from './PlDateTimePicker.js';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PlassAlign, PlassColor, PlassOrientation, PlassSize } from '../../types.js';
|
|
3
|
+
/** Where the label sits along a labelled divider. Ignored without a label. */
|
|
4
|
+
export type PlDividerTextAlign = PlassAlign;
|
|
5
|
+
export interface PlDividerProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'children'> {
|
|
6
|
+
/**
|
|
7
|
+
* Which way the line runs. A vertical divider has no height of its own — it
|
|
8
|
+
* stretches to its flex parent, which is what a rule between two toolbar
|
|
9
|
+
* groups should do.
|
|
10
|
+
* @default 'horizontal'
|
|
11
|
+
*/
|
|
12
|
+
orientation?: PlassOrientation;
|
|
13
|
+
/**
|
|
14
|
+
* Semantic colour role, and — like `PlTextLink`'s — it has **no default**.
|
|
15
|
+
*
|
|
16
|
+
* Left out, the rule is the neutral hairline, which is the one that is
|
|
17
|
+
* visible on every ground the library has: a page wash, a glass sheet, a
|
|
18
|
+
* card. The sheet's own white hairline is white light on a translucent pane
|
|
19
|
+
* and disappears the moment a divider is set on something opaque, which is
|
|
20
|
+
* the same reason a checkbox's edge is drawn in the neutral one.
|
|
21
|
+
*
|
|
22
|
+
* Passing a family tints the rule instead, at the strength a hairline takes
|
|
23
|
+
* everywhere else in the library.
|
|
24
|
+
*/
|
|
25
|
+
color?: PlassColor;
|
|
26
|
+
/** Type scale of the label. Nothing else on a divider has a size. */
|
|
27
|
+
size?: PlassSize;
|
|
28
|
+
/**
|
|
29
|
+
* How far the rule runs — the width of a horizontal divider, the height of a
|
|
30
|
+
* vertical one. A number is pixels; a string is any CSS length, so `'50%'`
|
|
31
|
+
* and `'12rem'` both work.
|
|
32
|
+
*
|
|
33
|
+
* `length` rather than `width`, because a divider is the one component whose
|
|
34
|
+
* long axis turns with `orientation`: a `width` that meant height half the
|
|
35
|
+
* time would be a worse name than a longer one.
|
|
36
|
+
*
|
|
37
|
+
* Left out, a horizontal divider is the full width of its container and a
|
|
38
|
+
* vertical one stretches to the height of the flex row it is in.
|
|
39
|
+
*/
|
|
40
|
+
length?: number | string;
|
|
41
|
+
/**
|
|
42
|
+
* How thick the rule is. A number is pixels; a string is any CSS length.
|
|
43
|
+
* @default 1
|
|
44
|
+
*/
|
|
45
|
+
thickness?: number | string;
|
|
46
|
+
/** A label set into the line — "OR" between two sign-in options. */
|
|
47
|
+
children?: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Where the label sits. `center` splits the line in half; `start` and `end`
|
|
50
|
+
* leave a short stub on the near side, so the label still reads as set *into*
|
|
51
|
+
* the rule rather than floating above it.
|
|
52
|
+
* @default 'center'
|
|
53
|
+
*/
|
|
54
|
+
textAlign?: PlDividerTextAlign;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A rule between two things.
|
|
58
|
+
*
|
|
59
|
+
* With no children it is Base UI's `Separator` and nothing else — a real
|
|
60
|
+
* `role="separator"` with the right `aria-orientation`. With children the line
|
|
61
|
+
* breaks around the label.
|
|
62
|
+
*
|
|
63
|
+
* `separator` is not a name-from-content role, so a visible label does *not*
|
|
64
|
+
* become the accessible name on its own: a screen reader would announce a bare
|
|
65
|
+
* "separator" and read the word "OR" as loose text somewhere nearby. A string
|
|
66
|
+
* label is therefore copied into `aria-label`. Anything richer is left alone —
|
|
67
|
+
* only the caller knows which part of it is the name.
|
|
68
|
+
*
|
|
69
|
+
* There is no `variant` and no `elevation`, because a divider is not a surface.
|
|
70
|
+
* It is not made of glass, catches no light and casts no shadow — it is the
|
|
71
|
+
* absence of a surface, drawn.
|
|
72
|
+
*/
|
|
73
|
+
export declare const PlDivider: React.ForwardRefExoticComponent<PlDividerProps & React.RefAttributes<HTMLDivElement>>;
|