tempest-react-sdk 0.39.0 → 0.40.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/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/access/access-control-context.cjs.map +1 -1
- package/dist/access/use-can.cjs.map +1 -1
- package/dist/app/AppProviders.cjs.map +1 -1
- package/dist/app/AppProviders.js.map +1 -1
- package/dist/audio/use-audio-recorder.cjs.map +1 -1
- package/dist/audio/use-audio.cjs.map +1 -1
- package/dist/audio/use-microphone.cjs.map +1 -1
- package/dist/auth/create-auth-store.cjs.map +1 -1
- package/dist/auth/lazy-with-retry.cjs.map +1 -1
- package/dist/auth/passkey.cjs.map +1 -1
- package/dist/auth/passkey.js.map +1 -1
- package/dist/auth/use-passkey.cjs.map +1 -1
- package/dist/br/BrazilMap.cjs +1 -1
- package/dist/br/BrazilMap.cjs.map +1 -1
- package/dist/br/BrazilMap.js +2 -2
- package/dist/br/BrazilMap.js.map +1 -1
- package/dist/br/BrazilStateCitySelect.cjs.map +1 -1
- package/dist/br/BrazilStateCitySelect.js.map +1 -1
- package/dist/br/BrazilStateMap.cjs +1 -1
- package/dist/br/BrazilStateMap.cjs.map +1 -1
- package/dist/br/BrazilStateMap.js +2 -2
- package/dist/br/BrazilStateMap.js.map +1 -1
- package/dist/br/MapLegend.cjs.map +1 -1
- package/dist/br/MapLegend.js.map +1 -1
- package/dist/br/MapMarkers.cjs.map +1 -1
- package/dist/br/MapMarkers.js.map +1 -1
- package/dist/br/MunicipalitySearch.cjs.map +1 -1
- package/dist/br/MunicipalitySearch.js.map +1 -1
- package/dist/br/PixQRCode.cjs.map +1 -1
- package/dist/br/PixQRCode.js.map +1 -1
- package/dist/br/use-map-hover.cjs.map +1 -1
- package/dist/br/use-map-zoom.cjs.map +1 -1
- package/dist/capture/media-recorder.cjs +1 -1
- package/dist/capture/media-recorder.js +2 -2
- package/dist/capture/use-barcode-scanner.cjs +1 -1
- package/dist/capture/use-barcode-scanner.cjs.map +1 -1
- package/dist/capture/use-barcode-scanner.js +2 -2
- package/dist/capture/use-barcode-scanner.js.map +1 -1
- package/dist/capture/use-screen-capture.cjs.map +1 -1
- package/dist/capture/use-speech-recognition.cjs.map +1 -1
- package/dist/capture/use-torch.cjs.map +1 -1
- package/dist/capture/use-video-recorder.cjs.map +1 -1
- package/dist/charts/AreaChart.cjs.map +1 -1
- package/dist/charts/AreaChart.js.map +1 -1
- package/dist/charts/BarChart.cjs.map +1 -1
- package/dist/charts/BarChart.js.map +1 -1
- package/dist/charts/LineChart.cjs.map +1 -1
- package/dist/charts/LineChart.js.map +1 -1
- package/dist/charts/PieChart.cjs.map +1 -1
- package/dist/charts/PieChart.js.map +1 -1
- package/dist/charts/RadarChart.cjs.map +1 -1
- package/dist/charts/RadarChart.js.map +1 -1
- package/dist/charts/use-chart-colors.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.js.map +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
- package/dist/components/AIChat/AIChatComposer.js.map +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs.map +1 -1
- package/dist/components/AIChat/AIChatTurn.js.map +1 -1
- package/dist/components/Accordion/Accordion.cjs.map +1 -1
- package/dist/components/Accordion/Accordion.js.map +1 -1
- package/dist/components/Alert/Alert.cjs.map +1 -1
- package/dist/components/Alert/Alert.js.map +1 -1
- package/dist/components/AppBar/AppBar.cjs.map +1 -1
- package/dist/components/AppBar/AppBar.js.map +1 -1
- package/dist/components/AppShell/AppShell.cjs.map +1 -1
- package/dist/components/AppShell/AppShell.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -1
- package/dist/components/Avatar/Avatar.cjs.map +1 -1
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/AvatarGroup/AvatarGroup.cjs.map +1 -1
- package/dist/components/AvatarGroup/AvatarGroup.js.map +1 -1
- package/dist/components/Badge/Badge.cjs.map +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Banner/Banner.cjs.map +1 -1
- package/dist/components/Banner/Banner.js.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.cjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.js.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.cjs.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.cjs.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/components/Button/Button.cjs.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.cjs +1 -1
- package/dist/components/Calendar/Calendar.cjs.map +1 -1
- package/dist/components/Calendar/Calendar.js +38 -41
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Card/Card.cjs.map +1 -1
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Carousel/Carousel.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.js.map +1 -1
- package/dist/components/Chat/Chat.cjs.map +1 -1
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/Chat/ChatComposer.cjs.map +1 -1
- package/dist/components/Chat/ChatComposer.js.map +1 -1
- package/dist/components/Chat/chat-groups.cjs +1 -1
- package/dist/components/Chat/chat-groups.cjs.map +1 -1
- package/dist/components/Chat/chat-groups.js +2 -2
- package/dist/components/Chat/chat-groups.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/ChipInput/ChipInput.cjs.map +1 -1
- package/dist/components/ChipInput/ChipInput.js.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/Collapsible/Collapsible.cjs.map +1 -1
- package/dist/components/Collapsible/Collapsible.js.map +1 -1
- package/dist/components/Combobox/Combobox.cjs.map +1 -1
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Command/Command.cjs.map +1 -1
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.cjs.map +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.cjs.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/CopyButton/CopyButton.cjs.map +1 -1
- package/dist/components/CopyButton/CopyButton.js.map +1 -1
- package/dist/components/DataList/DataList.cjs.map +1 -1
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +2 -2
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/EditableCell.cjs.map +1 -1
- package/dist/components/DataTable/EditableCell.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.cjs.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.js.map +1 -1
- package/dist/components/Divider/Divider.cjs.map +1 -1
- package/dist/components/Divider/Divider.js.map +1 -1
- package/dist/components/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/Dropzone/Dropzone.cjs.map +1 -1
- package/dist/components/Dropzone/Dropzone.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.cjs.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/ErrorState/ErrorState.cjs.map +1 -1
- package/dist/components/ErrorState/ErrorState.js.map +1 -1
- package/dist/components/FileUpload/FileUpload.cjs +1 -1
- package/dist/components/FileUpload/FileUpload.cjs.map +1 -1
- package/dist/components/FileUpload/FileUpload.js +1 -1
- package/dist/components/FileUpload/FileUpload.js.map +1 -1
- package/dist/components/FilterBar/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar/FilterBar.js.map +1 -1
- package/dist/components/FloatingActionButton/FloatingActionButton.cjs.map +1 -1
- package/dist/components/FloatingActionButton/FloatingActionButton.js.map +1 -1
- package/dist/components/Form/Form.cjs.map +1 -1
- package/dist/components/Form/Form.js.map +1 -1
- package/dist/components/HoverCard/HoverCard.cjs.map +1 -1
- package/dist/components/HoverCard/HoverCard.js.map +1 -1
- package/dist/components/Image/Image.cjs.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.js +1 -1
- package/dist/components/ImageCropper/ImageCropper.js.map +1 -1
- package/dist/components/Input/Input.cjs.map +1 -1
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.cjs.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.js.map +1 -1
- package/dist/components/InstallButton/InstallButton.cjs.map +1 -1
- package/dist/components/InstallButton/InstallButton.js.map +1 -1
- package/dist/components/Kanban/Kanban.cjs.map +1 -1
- package/dist/components/Kanban/Kanban.js.map +1 -1
- package/dist/components/Label/Label.cjs.map +1 -1
- package/dist/components/Label/Label.js.map +1 -1
- package/dist/components/Lightbox/Lightbox.cjs.map +1 -1
- package/dist/components/Lightbox/Lightbox.js.map +1 -1
- package/dist/components/ListTile/ListTile.cjs.map +1 -1
- package/dist/components/ListTile/ListTile.js.map +1 -1
- package/dist/components/Markdown/Markdown.cjs +1 -1
- package/dist/components/Markdown/Markdown.cjs.map +1 -1
- package/dist/components/Markdown/Markdown.js +2 -2
- package/dist/components/Markdown/Markdown.js.map +1 -1
- package/dist/components/Masonry/Masonry.cjs.map +1 -1
- package/dist/components/Masonry/Masonry.js.map +1 -1
- package/dist/components/Menubar/Menubar.cjs.map +1 -1
- package/dist/components/Menubar/Menubar.js.map +1 -1
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.cjs.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.js.map +1 -1
- package/dist/components/Money/Money.cjs.map +1 -1
- package/dist/components/Money/Money.js.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.cjs.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/components/NProgress/NProgress.cjs.map +1 -1
- package/dist/components/Navbar/Navbar.cjs.map +1 -1
- package/dist/components/Navbar/Navbar.js.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.cjs.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.js.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.cjs.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.js.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.cjs.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.js.map +1 -1
- package/dist/components/NotificationCenter/use-notification-inbox.cjs.map +1 -1
- package/dist/components/OfflineIndicator/OfflineIndicator.cjs.map +1 -1
- package/dist/components/OfflineIndicator/OfflineIndicator.js.map +1 -1
- package/dist/components/Page/Page.cjs.map +1 -1
- package/dist/components/Page/Page.js.map +1 -1
- package/dist/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.cjs.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.js.map +1 -1
- package/dist/components/PinInput/PinInput.cjs.map +1 -1
- package/dist/components/PinInput/PinInput.js.map +1 -1
- package/dist/components/Popover/Popover.cjs.map +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Portal/Portal.cjs.map +1 -1
- package/dist/components/Progress/Progress.cjs.map +1 -1
- package/dist/components/Progress/Progress.js.map +1 -1
- package/dist/components/QRCode/QRCode.cjs.map +1 -1
- package/dist/components/QRCode/QRCode.js.map +1 -1
- package/dist/components/Radio/Radio.cjs.map +1 -1
- package/dist/components/Radio/Radio.js.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.cjs.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.js.map +1 -1
- package/dist/components/RatingStars/RatingStars.cjs.map +1 -1
- package/dist/components/RatingStars/RatingStars.js.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.cjs.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.js.map +1 -1
- package/dist/components/RelativeTime/RelativeTime.cjs.map +1 -1
- package/dist/components/RelativeTime/RelativeTime.js.map +1 -1
- package/dist/components/Resizable/Resizable.cjs.map +1 -1
- package/dist/components/Resizable/Resizable.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.js.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.cjs.map +1 -1
- package/dist/components/SearchBar/SearchBar.cjs.map +1 -1
- package/dist/components/SearchBar/SearchBar.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/Select/Select.cjs.map +1 -1
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.js.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.cjs.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.js.map +1 -1
- package/dist/components/Slider/Slider.cjs.map +1 -1
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.cjs.map +1 -1
- package/dist/components/Sparkline/Sparkline.js.map +1 -1
- package/dist/components/Spinner/Spinner.cjs.map +1 -1
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/Stat/Stat.cjs.map +1 -1
- package/dist/components/Stat/Stat.js.map +1 -1
- package/dist/components/Stepper/Stepper.cjs.map +1 -1
- package/dist/components/Stepper/Stepper.js.map +1 -1
- package/dist/components/StepperInput/StepperInput.cjs.map +1 -1
- package/dist/components/StepperInput/StepperInput.js.map +1 -1
- package/dist/components/Switch/Switch.cjs.map +1 -1
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.js.map +1 -1
- package/dist/components/Table/Table.cjs.map +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Tabs/Tabs.cjs.map +1 -1
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tag/Tag.cjs.map +1 -1
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Textarea/Textarea.cjs.map +1 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.cjs.map +1 -1
- package/dist/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/Timeline/Timeline.cjs.map +1 -1
- package/dist/components/Timeline/Timeline.js.map +1 -1
- package/dist/components/Toast/ToastProvider.cjs.map +1 -1
- package/dist/components/Toast/ToastProvider.js.map +1 -1
- package/dist/components/Toggle/Toggle.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/Tour/Tour.cjs.map +1 -1
- package/dist/components/Tour/Tour.js.map +1 -1
- package/dist/components/Transfer/Transfer.cjs.map +1 -1
- package/dist/components/Transfer/Transfer.js.map +1 -1
- package/dist/components/TreeView/TreeView.cjs +1 -1
- package/dist/components/TreeView/TreeView.cjs.map +1 -1
- package/dist/components/TreeView/TreeView.js +1 -4
- package/dist/components/TreeView/TreeView.js.map +1 -1
- package/dist/components/UpdatePrompt/UpdatePrompt.cjs.map +1 -1
- package/dist/components/UpdatePrompt/UpdatePrompt.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.js.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.cjs.map +1 -1
- package/dist/components/Wizard/Wizard.cjs.map +1 -1
- package/dist/components/Wizard/Wizard.js.map +1 -1
- package/dist/data/data-provider-context.cjs.map +1 -1
- package/dist/data/use-resource.cjs.map +1 -1
- package/dist/editor/RichTextEditor.cjs.map +1 -1
- package/dist/editor/RichTextEditor.js.map +1 -1
- package/dist/error-boundary/use-error-handler.cjs.map +1 -1
- package/dist/feature-flags/FeatureFlagsProvider.cjs.map +1 -1
- package/dist/forms/FormField.cjs.map +1 -1
- package/dist/forms/masked-inputs.cjs +1 -1
- package/dist/forms/masked-inputs.cjs.map +1 -1
- package/dist/forms/masked-inputs.js +1 -1
- package/dist/forms/masked-inputs.js.map +1 -1
- package/dist/forms/use-viacep.cjs.map +1 -1
- package/dist/forms/use-zod-form.cjs.map +1 -1
- package/dist/forms/zod-resolver.cjs.map +1 -1
- package/dist/forms/zod-resolver.js.map +1 -1
- package/dist/geo/TrajectoryMap.cjs.map +1 -1
- package/dist/geo/TrajectoryMap.js.map +1 -1
- package/dist/geo/leaflet-map.cjs.map +1 -1
- package/dist/geo/leaflet-map.js.map +1 -1
- package/dist/geo/use-position-tracker.cjs.map +1 -1
- package/dist/hooks/use-announce.cjs.map +1 -1
- package/dist/hooks/use-async.cjs.map +1 -1
- package/dist/hooks/use-before-install-prompt.cjs.map +1 -1
- package/dist/hooks/use-breakpoint.cjs.map +1 -1
- package/dist/hooks/use-click-outside.cjs.map +1 -1
- package/dist/hooks/use-client-filter.cjs.map +1 -1
- package/dist/hooks/use-clipboard.cjs.map +1 -1
- package/dist/hooks/use-counter.cjs.map +1 -1
- package/dist/hooks/use-debounce.cjs.map +1 -1
- package/dist/hooks/use-deep-memo.cjs.map +1 -1
- package/dist/hooks/use-disclosure.cjs.map +1 -1
- package/dist/hooks/use-document-visibility.cjs.map +1 -1
- package/dist/hooks/use-event-listener.cjs.map +1 -1
- package/dist/hooks/use-geolocation.cjs.map +1 -1
- package/dist/hooks/use-hover.cjs.map +1 -1
- package/dist/hooks/use-idle.cjs.map +1 -1
- package/dist/hooks/use-install-prompt.cjs +1 -1
- package/dist/hooks/use-install-prompt.cjs.map +1 -1
- package/dist/hooks/use-install-prompt.js +1 -1
- package/dist/hooks/use-install-prompt.js.map +1 -1
- package/dist/hooks/use-intersection-observer.cjs.map +1 -1
- package/dist/hooks/use-interval.cjs.map +1 -1
- package/dist/hooks/use-is-first-render.cjs.map +1 -1
- package/dist/hooks/use-keyboard-shortcut.cjs +1 -1
- package/dist/hooks/use-keyboard-shortcut.cjs.map +1 -1
- package/dist/hooks/use-keyboard-shortcut.js +1 -1
- package/dist/hooks/use-keyboard-shortcut.js.map +1 -1
- package/dist/hooks/use-list-state.cjs.map +1 -1
- package/dist/hooks/use-local-storage.cjs.map +1 -1
- package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
- package/dist/hooks/use-long-press.cjs.map +1 -1
- package/dist/hooks/use-map.cjs.map +1 -1
- package/dist/hooks/use-media-devices.cjs.map +1 -1
- package/dist/hooks/use-media-permission.cjs.map +1 -1
- package/dist/hooks/use-media-query.cjs.map +1 -1
- package/dist/hooks/use-object-url.cjs.map +1 -1
- package/dist/hooks/use-online.cjs.map +1 -1
- package/dist/hooks/use-pagination.cjs.map +1 -1
- package/dist/hooks/use-previous.cjs.map +1 -1
- package/dist/hooks/use-queue.cjs.map +1 -1
- package/dist/hooks/use-resize-observer.cjs.map +1 -1
- package/dist/hooks/use-scroll-overflow.cjs.map +1 -1
- package/dist/hooks/use-service-worker-update.cjs.map +1 -1
- package/dist/hooks/use-set.cjs.map +1 -1
- package/dist/hooks/use-sortable.cjs +1 -1
- package/dist/hooks/use-sortable.cjs.map +1 -1
- package/dist/hooks/use-sortable.js +0 -2
- package/dist/hooks/use-sortable.js.map +1 -1
- package/dist/hooks/use-stable-callback.cjs.map +1 -1
- package/dist/hooks/use-storage-estimate.cjs.map +1 -1
- package/dist/hooks/use-throttle.cjs.map +1 -1
- package/dist/hooks/use-timeout.cjs.map +1 -1
- package/dist/hooks/use-toggle.cjs.map +1 -1
- package/dist/hooks/use-window-size.cjs.map +1 -1
- package/dist/http/api-client.cjs +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js +7 -5
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +1 -1
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/http/use-poll.cjs.map +1 -1
- package/dist/i18n/I18nProvider.cjs.map +1 -1
- package/dist/icons/Icon.cjs.map +1 -1
- package/dist/icons/IconProvider.cjs.map +1 -1
- package/dist/icons/icon-context.cjs.map +1 -1
- package/dist/icons/use-icon.cjs.map +1 -1
- package/dist/imaging/use-image-processing.cjs.map +1 -1
- package/dist/oauth/GoogleSignIn.cjs.map +1 -1
- package/dist/oauth/GoogleSignIn.js.map +1 -1
- package/dist/oauth/use-oauth-callback.cjs.map +1 -1
- package/dist/offline/use-offline-sync.cjs.map +1 -1
- package/dist/push/use-push-subscription.cjs.map +1 -1
- package/dist/query/QueryProvider.cjs.map +1 -1
- package/dist/query/constants.cjs +1 -1
- package/dist/query/constants.cjs.map +1 -1
- package/dist/query/constants.js +10 -10
- package/dist/query/constants.js.map +1 -1
- package/dist/query/create-query-keys.cjs +1 -1
- package/dist/query/create-query-keys.cjs.map +1 -1
- package/dist/query/create-query-keys.js +1 -1
- package/dist/query/create-query-keys.js.map +1 -1
- package/dist/query/offline-persistence.cjs.map +1 -1
- package/dist/query/use-cursor-query.cjs.map +1 -1
- package/dist/query/use-offline-mutation.cjs.map +1 -1
- package/dist/query/use-paginated-query.cjs.map +1 -1
- package/dist/router/AppRouter.cjs +1 -1
- package/dist/router/AppRouter.cjs.map +1 -1
- package/dist/router/AppRouter.js +7 -2
- package/dist/router/AppRouter.js.map +1 -1
- package/dist/sse/use-event-stream.cjs.map +1 -1
- package/dist/store/create-store.cjs.map +1 -1
- package/dist/tabular/use-tabular-predictor.cjs.map +1 -1
- package/dist/telemetry/TelemetryProvider.cjs.map +1 -1
- package/dist/tempest-react-sdk.d.ts +25 -26
- package/dist/theme/ThemeProvider.cjs.map +1 -1
- package/dist/theme/color.cjs +1 -1
- package/dist/theme/color.cjs.map +1 -1
- package/dist/theme/color.js +1 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/utils/cn.cjs +1 -1
- package/dist/utils/cn.cjs.map +1 -1
- package/dist/utils/cn.js +1 -1
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/objects.cjs +1 -1
- package/dist/utils/objects.cjs.map +1 -1
- package/dist/utils/objects.js +1 -1
- package/dist/utils/objects.js.map +1 -1
- package/dist/utils/xlsx.cjs +1 -1
- package/dist/utils/xlsx.cjs.map +1 -1
- package/dist/utils/xlsx.js +3 -3
- package/dist/utils/xlsx.js.map +1 -1
- package/dist/vision/core/exceptions.cjs.map +1 -1
- package/dist/vision/core/exceptions.js.map +1 -1
- package/dist/vision/core/metadata.cjs +1 -1
- package/dist/vision/core/metadata.cjs.map +1 -1
- package/dist/vision/core/metadata.js +1 -1
- package/dist/vision/core/metadata.js.map +1 -1
- package/dist/vision/io/image.cjs +1 -1
- package/dist/vision/io/image.cjs.map +1 -1
- package/dist/vision/io/image.js +4 -2
- package/dist/vision/io/image.js.map +1 -1
- package/dist/vision/preprocess/image.cjs +1 -1
- package/dist/vision/preprocess/image.cjs.map +1 -1
- package/dist/vision/preprocess/image.js +4 -2
- package/dist/vision/preprocess/image.js.map +1 -1
- package/dist/vision/tasks/base.cjs +1 -1
- package/dist/vision/tasks/base.cjs.map +1 -1
- package/dist/vision/tasks/base.js +3 -1
- package/dist/vision/tasks/base.js.map +1 -1
- package/dist/vision/tasks/classifier.cjs +1 -1
- package/dist/vision/tasks/classifier.cjs.map +1 -1
- package/dist/vision/tasks/classifier.js +2 -2
- package/dist/vision/tasks/classifier.js.map +1 -1
- package/dist/vision/tasks/detectClassify.cjs +1 -1
- package/dist/vision/tasks/detectClassify.cjs.map +1 -1
- package/dist/vision/tasks/detectClassify.js +16 -15
- package/dist/vision/tasks/detectClassify.js.map +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-live-luminance.cjs.map +1 -1
- package/dist/vite/create-vite-config.cjs +1 -1
- package/dist/vite/create-vite-config.cjs.map +1 -1
- package/dist/vite/create-vite-config.js +3 -3
- package/dist/vite/create-vite-config.js.map +1 -1
- package/dist/vite/tempest-icons.cjs.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
- package/dist/vite/tempest-pwa-icons.cjs.map +1 -1
- package/dist/ws/use-web-socket.cjs +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js +5 -3
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +2 -2
- package/template/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomNavigation.cjs","names":[],"sources":["../../../src/components/BottomNavigation/BottomNavigation.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomNavigation.module.css\";\n\nexport interface BottomNavigationItem {\n /** Unique identifier — used as React key and for value matching. */\n key: string;\n /** Visible label. */\n label: ReactNode;\n /** Icon rendered above the label. */\n icon?: ReactNode;\n /** Optional badge content rendered above the icon. */\n badge?: ReactNode;\n /** When true, the item is not selectable. */\n disabled?: boolean;\n}\n\nexport interface BottomNavigationProps extends Omit<HTMLAttributes<HTMLElement>, \"onChange\"> {\n items: BottomNavigationItem[];\n /** Selected key. */\n value: string;\n /** Called with the new selected key on click. */\n onChange: (key: string) => void;\n /** Show label below each icon. Default `true`. */\n showLabels?: boolean;\n}\n\n/**\n * Fixed-bottom mobile tab bar. 3–5 items recommended. Pair with\n * `<Show below=\"md\">` to render only on mobile.\n *\n * @example\n * <Show below=\"md\">\n * <BottomNavigation\n * items={[\n * { key: \"home\", label: \"Início\", icon: <Home /> },\n * { key: \"search\", label: \"Buscar\", icon: <Search /> },\n * { key: \"profile\", label: \"Perfil\", icon: <User /> },\n * ]}\n * value={tab}\n * onChange={setTab}\n * />\n * </Show>\n */\nexport function BottomNavigation({\n items,\n value,\n onChange,\n showLabels = true,\n className,\n ...props\n}: BottomNavigationProps) {\n return (\n <nav className={cn(styles.bar, className)} aria-label=\"Navegação principal\" {...props}>\n {items.map((item) => {\n const active = item.key === value;\n return (\n <button\n key={item.key}\n type=\"button\"\n className={cn(styles.item, active && styles.active)}\n aria-current={active ? \"page\" : undefined}\n disabled={item.disabled}\n onClick={() => onChange(item.key)}\n >\n <span className={styles.iconWrap}>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {item.badge !== undefined && (\n <span className={styles.badge}>{item.badge}</span>\n )}\n </span>\n {showLabels && <span className={styles.label}>{item.label}</span>}\n </button>\n );\n })}\n </nav>\n );\n}\n"],"mappings":"oHA4CA,SAAgB,EAAiB,CAC7B,QACA,QACA,WACA,aAAa,GACb,YACA,GAAG,GACmB,CACtB,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,GAAG,EAAA,QAAO,IAAK,CAAS,EAAG,aAAW,sBAAsB,GAAI,
|
|
1
|
+
{"version":3,"file":"BottomNavigation.cjs","names":[],"sources":["../../../src/components/BottomNavigation/BottomNavigation.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomNavigation.module.css\";\n\nexport interface BottomNavigationItem {\n /** Unique identifier — used as React key and for value matching. */\n key: string;\n /** Visible label. */\n label: ReactNode;\n /** Icon rendered above the label. */\n icon?: ReactNode;\n /** Optional badge content rendered above the icon. */\n badge?: ReactNode;\n /** When true, the item is not selectable. */\n disabled?: boolean;\n}\n\nexport interface BottomNavigationProps extends Omit<HTMLAttributes<HTMLElement>, \"onChange\"> {\n items: BottomNavigationItem[];\n /** Selected key. */\n value: string;\n /** Called with the new selected key on click. */\n onChange: (key: string) => void;\n /** Show label below each icon. Default `true`. */\n showLabels?: boolean;\n}\n\n/**\n * Fixed-bottom mobile tab bar. 3–5 items recommended. Pair with\n * `<Show below=\"md\">` to render only on mobile.\n *\n * @example\n * <Show below=\"md\">\n * <BottomNavigation\n * items={[\n * { key: \"home\", label: \"Início\", icon: <Home /> },\n * { key: \"search\", label: \"Buscar\", icon: <Search /> },\n * { key: \"profile\", label: \"Perfil\", icon: <User /> },\n * ]}\n * value={tab}\n * onChange={setTab}\n * />\n * </Show>\n */\nexport function BottomNavigation({\n items,\n value,\n onChange,\n showLabels = true,\n className,\n ...props\n}: BottomNavigationProps) {\n return (\n <nav className={cn(styles.bar, className)} aria-label=\"Navegação principal\" {...props}>\n {items.map((item) => {\n const active = item.key === value;\n return (\n <button\n key={item.key}\n type=\"button\"\n className={cn(styles.item, active && styles.active)}\n aria-current={active ? \"page\" : undefined}\n disabled={item.disabled}\n onClick={() => onChange(item.key)}\n >\n <span className={styles.iconWrap}>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {item.badge !== undefined && (\n <span className={styles.badge}>{item.badge}</span>\n )}\n </span>\n {showLabels && <span className={styles.label}>{item.label}</span>}\n </button>\n );\n })}\n </nav>\n );\n}\n"],"mappings":"oHA4CA,SAAgB,EAAiB,CAC7B,QACA,QACA,WACA,aAAa,GACb,YACA,GAAG,GACmB,CACtB,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,GAAG,EAAA,QAAO,IAAK,CAAS,EAAG,aAAW,sBAAsB,GAAI,EAC3E,SAAA,EAAM,IAAK,GAAS,CACjB,IAAM,EAAS,EAAK,MAAQ,EAC5B,OACI,EAAA,EAAA,KAAA,CAAC,SAAD,CAEI,KAAK,SACL,UAAW,EAAA,GAAG,EAAA,QAAO,KAAM,GAAU,EAAA,QAAO,MAAM,EAClD,eAAc,EAAS,OAAS,IAAA,GAChC,SAAU,EAAK,SACf,YAAe,EAAS,EAAK,GAAG,EANpC,SAAA,EAQI,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,SAAxB,SAAA,CACK,EAAK,OAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,KAAO,SAAA,EAAK,IAAW,CAAA,EAC5D,EAAK,QAAU,IAAA,KACZ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,MAAQ,SAAA,EAAK,KAAY,CAAA,CAEnD,CACL,CAAA,EAAA,IAAc,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,MAAQ,SAAA,EAAK,KAAY,CAAA,CAC5D,CAdC,EAAA,EAAK,GAcN,CAEhB,CAAC,CACA,CAAA,CAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomNavigation.js","names":[],"sources":["../../../src/components/BottomNavigation/BottomNavigation.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomNavigation.module.css\";\n\nexport interface BottomNavigationItem {\n /** Unique identifier — used as React key and for value matching. */\n key: string;\n /** Visible label. */\n label: ReactNode;\n /** Icon rendered above the label. */\n icon?: ReactNode;\n /** Optional badge content rendered above the icon. */\n badge?: ReactNode;\n /** When true, the item is not selectable. */\n disabled?: boolean;\n}\n\nexport interface BottomNavigationProps extends Omit<HTMLAttributes<HTMLElement>, \"onChange\"> {\n items: BottomNavigationItem[];\n /** Selected key. */\n value: string;\n /** Called with the new selected key on click. */\n onChange: (key: string) => void;\n /** Show label below each icon. Default `true`. */\n showLabels?: boolean;\n}\n\n/**\n * Fixed-bottom mobile tab bar. 3–5 items recommended. Pair with\n * `<Show below=\"md\">` to render only on mobile.\n *\n * @example\n * <Show below=\"md\">\n * <BottomNavigation\n * items={[\n * { key: \"home\", label: \"Início\", icon: <Home /> },\n * { key: \"search\", label: \"Buscar\", icon: <Search /> },\n * { key: \"profile\", label: \"Perfil\", icon: <User /> },\n * ]}\n * value={tab}\n * onChange={setTab}\n * />\n * </Show>\n */\nexport function BottomNavigation({\n items,\n value,\n onChange,\n showLabels = true,\n className,\n ...props\n}: BottomNavigationProps) {\n return (\n <nav className={cn(styles.bar, className)} aria-label=\"Navegação principal\" {...props}>\n {items.map((item) => {\n const active = item.key === value;\n return (\n <button\n key={item.key}\n type=\"button\"\n className={cn(styles.item, active && styles.active)}\n aria-current={active ? \"page\" : undefined}\n disabled={item.disabled}\n onClick={() => onChange(item.key)}\n >\n <span className={styles.iconWrap}>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {item.badge !== undefined && (\n <span className={styles.badge}>{item.badge}</span>\n )}\n </span>\n {showLabels && <span className={styles.label}>{item.label}</span>}\n </button>\n );\n })}\n </nav>\n );\n}\n"],"mappings":";;;;AA4CA,SAAgB,EAAiB,EAC7B,UACA,UACA,aACA,gBAAa,IACb,cACA,GAAG,KACmB;CACtB,OACI,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAO,KAAK,CAAS;EAAG,cAAW;EAAsB,GAAI;
|
|
1
|
+
{"version":3,"file":"BottomNavigation.js","names":[],"sources":["../../../src/components/BottomNavigation/BottomNavigation.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomNavigation.module.css\";\n\nexport interface BottomNavigationItem {\n /** Unique identifier — used as React key and for value matching. */\n key: string;\n /** Visible label. */\n label: ReactNode;\n /** Icon rendered above the label. */\n icon?: ReactNode;\n /** Optional badge content rendered above the icon. */\n badge?: ReactNode;\n /** When true, the item is not selectable. */\n disabled?: boolean;\n}\n\nexport interface BottomNavigationProps extends Omit<HTMLAttributes<HTMLElement>, \"onChange\"> {\n items: BottomNavigationItem[];\n /** Selected key. */\n value: string;\n /** Called with the new selected key on click. */\n onChange: (key: string) => void;\n /** Show label below each icon. Default `true`. */\n showLabels?: boolean;\n}\n\n/**\n * Fixed-bottom mobile tab bar. 3–5 items recommended. Pair with\n * `<Show below=\"md\">` to render only on mobile.\n *\n * @example\n * <Show below=\"md\">\n * <BottomNavigation\n * items={[\n * { key: \"home\", label: \"Início\", icon: <Home /> },\n * { key: \"search\", label: \"Buscar\", icon: <Search /> },\n * { key: \"profile\", label: \"Perfil\", icon: <User /> },\n * ]}\n * value={tab}\n * onChange={setTab}\n * />\n * </Show>\n */\nexport function BottomNavigation({\n items,\n value,\n onChange,\n showLabels = true,\n className,\n ...props\n}: BottomNavigationProps) {\n return (\n <nav className={cn(styles.bar, className)} aria-label=\"Navegação principal\" {...props}>\n {items.map((item) => {\n const active = item.key === value;\n return (\n <button\n key={item.key}\n type=\"button\"\n className={cn(styles.item, active && styles.active)}\n aria-current={active ? \"page\" : undefined}\n disabled={item.disabled}\n onClick={() => onChange(item.key)}\n >\n <span className={styles.iconWrap}>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {item.badge !== undefined && (\n <span className={styles.badge}>{item.badge}</span>\n )}\n </span>\n {showLabels && <span className={styles.label}>{item.label}</span>}\n </button>\n );\n })}\n </nav>\n );\n}\n"],"mappings":";;;;AA4CA,SAAgB,EAAiB,EAC7B,UACA,UACA,aACA,gBAAa,IACb,cACA,GAAG,KACmB;CACtB,OACI,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAO,KAAK,CAAS;EAAG,cAAW;EAAsB,GAAI;EAC3E,UAAA,EAAM,KAAK,MAAS;GACjB,IAAM,IAAS,EAAK,QAAQ;GAC5B,OACI,kBAAC,UAAD;IAEI,MAAK;IACL,WAAW,EAAG,EAAO,MAAM,KAAU,EAAO,MAAM;IAClD,gBAAc,IAAS,SAAS,KAAA;IAChC,UAAU,EAAK;IACf,eAAe,EAAS,EAAK,GAAG;IANpC,UAAA,CAQI,kBAAC,QAAD;KAAM,WAAW,EAAO;KAAxB,UAAA,CACK,EAAK,QAAQ,kBAAC,QAAD;MAAM,WAAW,EAAO;MAAO,UAAA,EAAK;KAAW,CAAA,GAC5D,EAAK,UAAU,KAAA,KACZ,kBAAC,QAAD;MAAM,WAAW,EAAO;MAAQ,UAAA,EAAK;KAAY,CAAA,CAEnD;IACL,CAAA,GAAA,KAAc,kBAAC,QAAD;KAAM,WAAW,EAAO;KAAQ,UAAA,EAAK;IAAY,CAAA,CAC5D;GAdC,GAAA,EAAK,GAcN;EAEhB,CAAC;CACA,CAAA;AAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheet.cjs","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomSheet.module.css\";\n\nexport interface BottomSheetProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Controlled open state. */\n open: boolean;\n /** Fires when user dismisses (backdrop click, Esc, swipe). */\n onClose: () => void;\n /** Optional title rendered at the top of the sheet. */\n title?: ReactNode;\n /** Show a drag handle indicator at the top. Default `true`. */\n showHandle?: boolean;\n /** When `true`, clicking the backdrop closes the sheet. Default `true`. */\n dismissOnBackdrop?: boolean;\n /** When `true`, pressing Esc closes the sheet. Default `true`. */\n dismissOnEsc?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Slide-up modal panel — mobile-style sheet anchored to the bottom edge.\n * Uses portal + safe-area padding + scroll lock.\n *\n * @example\n * <BottomSheet open={open} onClose={() => setOpen(false)} title=\"Filters\">\n * <FilterForm />\n * </BottomSheet>\n */\nexport function BottomSheet({\n open,\n onClose,\n title,\n showHandle = true,\n dismissOnBackdrop = true,\n dismissOnEsc = true,\n className,\n children,\n ...props\n}: BottomSheetProps) {\n useEffect(() => {\n if (!open || !dismissOnEsc) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, dismissOnEsc, onClose]);\n\n useEffect(() => {\n if (!open) return;\n const previous = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = previous;\n };\n }, [open]);\n\n if (!open || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div className={styles.root} role=\"dialog\" aria-modal=\"true\">\n <div\n className={styles.backdrop}\n onClick={() => dismissOnBackdrop && onClose()}\n aria-hidden=\"true\"\n />\n <div className={cn(styles.sheet, className)} {...props}>\n {showHandle && (\n <button\n type=\"button\"\n className={styles.handle}\n aria-label=\"Arrastar para fechar\"\n onClick={onClose}\n >\n <span className={styles.handleBar} />\n </button>\n )}\n {title && <div className={styles.title}>{title}</div>}\n <div className={styles.body}>{children}</div>\n </div>\n </div>,\n document.body,\n );\n}\n"],"mappings":"yJA+BA,SAAgB,EAAY,CACxB,OACA,UACA,QACA,aAAa,GACb,oBAAoB,GACpB,eAAe,GACf,YACA,WACA,GAAG,GACc,CAqBjB,OApBA,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,GAAQ,CAAC,EAAc,OAC5B,IAAM,EAAW,GAAqB,CAC9B,EAAE,MAAQ,UAAU,EAAQ,CACpC,EAEA,OADA,OAAO,iBAAiB,UAAW,CAAO,MAC7B,OAAO,oBAAoB,UAAW,CAAO,CAC9D,EAAG,CAAC,EAAM,EAAc,CAAO,CAAC,GAEhC,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,EAAM,OACX,IAAM,EAAW,SAAS,KAAK,MAAM,SAErC,MADA,UAAS,KAAK,MAAM,SAAW,aAClB,CACT,SAAS,KAAK,MAAM,SAAW,CACnC,CACJ,EAAG,CAAC,CAAI,CAAC,EAEL,CAAC,GAAQ,OAAO,SAAa,IAAoB,MAErD,
|
|
1
|
+
{"version":3,"file":"BottomSheet.cjs","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomSheet.module.css\";\n\nexport interface BottomSheetProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Controlled open state. */\n open: boolean;\n /** Fires when user dismisses (backdrop click, Esc, swipe). */\n onClose: () => void;\n /** Optional title rendered at the top of the sheet. */\n title?: ReactNode;\n /** Show a drag handle indicator at the top. Default `true`. */\n showHandle?: boolean;\n /** When `true`, clicking the backdrop closes the sheet. Default `true`. */\n dismissOnBackdrop?: boolean;\n /** When `true`, pressing Esc closes the sheet. Default `true`. */\n dismissOnEsc?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Slide-up modal panel — mobile-style sheet anchored to the bottom edge.\n * Uses portal + safe-area padding + scroll lock.\n *\n * @example\n * <BottomSheet open={open} onClose={() => setOpen(false)} title=\"Filters\">\n * <FilterForm />\n * </BottomSheet>\n */\nexport function BottomSheet({\n open,\n onClose,\n title,\n showHandle = true,\n dismissOnBackdrop = true,\n dismissOnEsc = true,\n className,\n children,\n ...props\n}: BottomSheetProps) {\n useEffect(() => {\n if (!open || !dismissOnEsc) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, dismissOnEsc, onClose]);\n\n useEffect(() => {\n if (!open) return;\n const previous = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = previous;\n };\n }, [open]);\n\n if (!open || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div className={styles.root} role=\"dialog\" aria-modal=\"true\">\n <div\n className={styles.backdrop}\n onClick={() => dismissOnBackdrop && onClose()}\n aria-hidden=\"true\"\n />\n <div className={cn(styles.sheet, className)} {...props}>\n {showHandle && (\n <button\n type=\"button\"\n className={styles.handle}\n aria-label=\"Arrastar para fechar\"\n onClick={onClose}\n >\n <span className={styles.handleBar} />\n </button>\n )}\n {title && <div className={styles.title}>{title}</div>}\n <div className={styles.body}>{children}</div>\n </div>\n </div>,\n document.body,\n );\n}\n"],"mappings":"yJA+BA,SAAgB,EAAY,CACxB,OACA,UACA,QACA,aAAa,GACb,oBAAoB,GACpB,eAAe,GACf,YACA,WACA,GAAG,GACc,CAqBjB,OApBA,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,GAAQ,CAAC,EAAc,OAC5B,IAAM,EAAW,GAAqB,CAC9B,EAAE,MAAQ,UAAU,EAAQ,CACpC,EAEA,OADA,OAAO,iBAAiB,UAAW,CAAO,MAC7B,OAAO,oBAAoB,UAAW,CAAO,CAC9D,EAAG,CAAC,EAAM,EAAc,CAAO,CAAC,GAEhC,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,EAAM,OACX,IAAM,EAAW,SAAS,KAAK,MAAM,SAErC,MADA,UAAS,KAAK,MAAM,SAAW,aAClB,CACT,SAAS,KAAK,MAAM,SAAW,CACnC,CACJ,EAAG,CAAC,CAAI,CAAC,EAEL,CAAC,GAAQ,OAAO,SAAa,IAAoB,MAErD,EAAO,EAAA,aAAA,EACH,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,KAAM,KAAK,SAAS,aAAW,OAAtD,SAAA,EACI,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,UAAW,EAAA,QAAO,SAClB,YAAe,GAAqB,EAAQ,EAC5C,cAAY,MACf,CAAA,GACD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAA,GAAG,EAAA,QAAO,MAAO,CAAS,EAAG,GAAI,EAAjD,SAAA,CACK,IACG,EAAA,EAAA,IAAA,CAAC,SAAD,CACI,KAAK,SACL,UAAW,EAAA,QAAO,OAClB,aAAW,uBACX,QAAS,EAET,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,SAAY,CAAA,CAChC,CAAA,EAEX,IAAS,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,MAAQ,SAAA,CAAW,CAAA,GACpD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,KAAO,UAAc,CAAA,CAC3C,CACJ,CAAA,CAAA,CACL,CAAA,EAAA,SAAS,IACb,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheet.js","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomSheet.module.css\";\n\nexport interface BottomSheetProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Controlled open state. */\n open: boolean;\n /** Fires when user dismisses (backdrop click, Esc, swipe). */\n onClose: () => void;\n /** Optional title rendered at the top of the sheet. */\n title?: ReactNode;\n /** Show a drag handle indicator at the top. Default `true`. */\n showHandle?: boolean;\n /** When `true`, clicking the backdrop closes the sheet. Default `true`. */\n dismissOnBackdrop?: boolean;\n /** When `true`, pressing Esc closes the sheet. Default `true`. */\n dismissOnEsc?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Slide-up modal panel — mobile-style sheet anchored to the bottom edge.\n * Uses portal + safe-area padding + scroll lock.\n *\n * @example\n * <BottomSheet open={open} onClose={() => setOpen(false)} title=\"Filters\">\n * <FilterForm />\n * </BottomSheet>\n */\nexport function BottomSheet({\n open,\n onClose,\n title,\n showHandle = true,\n dismissOnBackdrop = true,\n dismissOnEsc = true,\n className,\n children,\n ...props\n}: BottomSheetProps) {\n useEffect(() => {\n if (!open || !dismissOnEsc) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, dismissOnEsc, onClose]);\n\n useEffect(() => {\n if (!open) return;\n const previous = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = previous;\n };\n }, [open]);\n\n if (!open || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div className={styles.root} role=\"dialog\" aria-modal=\"true\">\n <div\n className={styles.backdrop}\n onClick={() => dismissOnBackdrop && onClose()}\n aria-hidden=\"true\"\n />\n <div className={cn(styles.sheet, className)} {...props}>\n {showHandle && (\n <button\n type=\"button\"\n className={styles.handle}\n aria-label=\"Arrastar para fechar\"\n onClick={onClose}\n >\n <span className={styles.handleBar} />\n </button>\n )}\n {title && <div className={styles.title}>{title}</div>}\n <div className={styles.body}>{children}</div>\n </div>\n </div>,\n document.body,\n );\n}\n"],"mappings":";;;;;;AA+BA,SAAgB,EAAY,EACxB,SACA,YACA,UACA,gBAAa,IACb,uBAAoB,IACpB,kBAAe,IACf,cACA,aACA,GAAG,KACc;CAqBjB,OApBA,QAAgB;EACZ,IAAI,CAAC,KAAQ,CAAC,GAAc;EAC5B,IAAM,KAAW,MAAqB;GAClC,AAAI,EAAE,QAAQ,YAAU,EAAQ;EACpC;EAEA,OADA,OAAO,iBAAiB,WAAW,CAAO,SAC7B,OAAO,oBAAoB,WAAW,CAAO;CAC9D,GAAG;EAAC;EAAM;EAAc;CAAO,CAAC,GAEhC,QAAgB;EACZ,IAAI,CAAC,GAAM;EACX,IAAM,IAAW,SAAS,KAAK,MAAM;EAErC,OADA,SAAS,KAAK,MAAM,WAAW,gBAClB;GACT,SAAS,KAAK,MAAM,WAAW;EACnC;CACJ,GAAG,CAAC,CAAI,CAAC,GAEL,CAAC,KAAQ,OAAO,WAAa,MAAoB,OAE9C,EACH,kBAAC,OAAD;EAAK,WAAW,EAAO;EAAM,MAAK;EAAS,cAAW;
|
|
1
|
+
{"version":3,"file":"BottomSheet.js","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BottomSheet.module.css\";\n\nexport interface BottomSheetProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Controlled open state. */\n open: boolean;\n /** Fires when user dismisses (backdrop click, Esc, swipe). */\n onClose: () => void;\n /** Optional title rendered at the top of the sheet. */\n title?: ReactNode;\n /** Show a drag handle indicator at the top. Default `true`. */\n showHandle?: boolean;\n /** When `true`, clicking the backdrop closes the sheet. Default `true`. */\n dismissOnBackdrop?: boolean;\n /** When `true`, pressing Esc closes the sheet. Default `true`. */\n dismissOnEsc?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Slide-up modal panel — mobile-style sheet anchored to the bottom edge.\n * Uses portal + safe-area padding + scroll lock.\n *\n * @example\n * <BottomSheet open={open} onClose={() => setOpen(false)} title=\"Filters\">\n * <FilterForm />\n * </BottomSheet>\n */\nexport function BottomSheet({\n open,\n onClose,\n title,\n showHandle = true,\n dismissOnBackdrop = true,\n dismissOnEsc = true,\n className,\n children,\n ...props\n}: BottomSheetProps) {\n useEffect(() => {\n if (!open || !dismissOnEsc) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, dismissOnEsc, onClose]);\n\n useEffect(() => {\n if (!open) return;\n const previous = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = previous;\n };\n }, [open]);\n\n if (!open || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div className={styles.root} role=\"dialog\" aria-modal=\"true\">\n <div\n className={styles.backdrop}\n onClick={() => dismissOnBackdrop && onClose()}\n aria-hidden=\"true\"\n />\n <div className={cn(styles.sheet, className)} {...props}>\n {showHandle && (\n <button\n type=\"button\"\n className={styles.handle}\n aria-label=\"Arrastar para fechar\"\n onClick={onClose}\n >\n <span className={styles.handleBar} />\n </button>\n )}\n {title && <div className={styles.title}>{title}</div>}\n <div className={styles.body}>{children}</div>\n </div>\n </div>,\n document.body,\n );\n}\n"],"mappings":";;;;;;AA+BA,SAAgB,EAAY,EACxB,SACA,YACA,UACA,gBAAa,IACb,uBAAoB,IACpB,kBAAe,IACf,cACA,aACA,GAAG,KACc;CAqBjB,OApBA,QAAgB;EACZ,IAAI,CAAC,KAAQ,CAAC,GAAc;EAC5B,IAAM,KAAW,MAAqB;GAClC,AAAI,EAAE,QAAQ,YAAU,EAAQ;EACpC;EAEA,OADA,OAAO,iBAAiB,WAAW,CAAO,SAC7B,OAAO,oBAAoB,WAAW,CAAO;CAC9D,GAAG;EAAC;EAAM;EAAc;CAAO,CAAC,GAEhC,QAAgB;EACZ,IAAI,CAAC,GAAM;EACX,IAAM,IAAW,SAAS,KAAK,MAAM;EAErC,OADA,SAAS,KAAK,MAAM,WAAW,gBAClB;GACT,SAAS,KAAK,MAAM,WAAW;EACnC;CACJ,GAAG,CAAC,CAAI,CAAC,GAEL,CAAC,KAAQ,OAAO,WAAa,MAAoB,OAE9C,EACH,kBAAC,OAAD;EAAK,WAAW,EAAO;EAAM,MAAK;EAAS,cAAW;EAAtD,UAAA,CACI,kBAAC,OAAD;GACI,WAAW,EAAO;GAClB,eAAe,KAAqB,EAAQ;GAC5C,eAAY;EACf,CAAA,GACD,kBAAC,OAAD;GAAK,WAAW,EAAG,EAAO,OAAO,CAAS;GAAG,GAAI;GAAjD,UAAA;IACK,KACG,kBAAC,UAAD;KACI,MAAK;KACL,WAAW,EAAO;KAClB,cAAW;KACX,SAAS;KAET,UAAA,kBAAC,QAAD,EAAM,WAAW,EAAO,UAAY,CAAA;IAChC,CAAA;IAEX,KAAS,kBAAC,OAAD;KAAK,WAAW,EAAO;KAAQ,UAAA;IAAW,CAAA;IACpD,kBAAC,OAAD;KAAK,WAAW,EAAO;KAAO;IAAc,CAAA;GAC3C;EACJ,CAAA,CAAA;CACL,CAAA,GAAA,SAAS,IACb;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumbs.cjs","names":[],"sources":["../../../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import { Fragment } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Breadcrumbs.module.css\";\n\nexport interface BreadcrumbItem {\n label: ReactNode;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface BreadcrumbsProps {\n items: BreadcrumbItem[];\n separator?: ReactNode;\n className?: string;\n}\n\n/**\n * Hierarchical navigation breadcrumbs. The last item is rendered as plain\n * text with `aria-current=\"page\"`. Items with neither `href` nor `onClick`\n * also render as text (intermediate but non-clickable).\n */\nexport function Breadcrumbs({ items, separator = \"/\", className }: BreadcrumbsProps) {\n return (\n <nav aria-label=\"breadcrumb\" className={cn(styles.nav, className)}>\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const interactive = !isLast && (item.href || item.onClick);\n return (\n <Fragment key={index}>\n <span className={styles.item}>\n {interactive ? (\n <a\n href={item.href}\n onClick={(event) => {\n if (item.onClick) {\n event.preventDefault();\n item.onClick();\n }\n }}\n className={styles.link}\n >\n {item.label}\n </a>\n ) : (\n <span\n aria-current={isLast ? \"page\" : undefined}\n className={isLast ? styles.current : undefined}\n >\n {item.label}\n </span>\n )}\n </span>\n {!isLast && (\n <span className={styles.separator} aria-hidden>\n {separator}\n </span>\n )}\n </Fragment>\n );\n })}\n </nav>\n );\n}\n"],"mappings":"kIAsBA,SAAgB,EAAY,CAAE,QAAO,YAAY,IAAK,aAA+B,CACjF,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,aAAW,aAAa,UAAW,EAAA,GAAG,EAAA,QAAO,IAAK,CAAS,
|
|
1
|
+
{"version":3,"file":"Breadcrumbs.cjs","names":[],"sources":["../../../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import { Fragment } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Breadcrumbs.module.css\";\n\nexport interface BreadcrumbItem {\n label: ReactNode;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface BreadcrumbsProps {\n items: BreadcrumbItem[];\n separator?: ReactNode;\n className?: string;\n}\n\n/**\n * Hierarchical navigation breadcrumbs. The last item is rendered as plain\n * text with `aria-current=\"page\"`. Items with neither `href` nor `onClick`\n * also render as text (intermediate but non-clickable).\n */\nexport function Breadcrumbs({ items, separator = \"/\", className }: BreadcrumbsProps) {\n return (\n <nav aria-label=\"breadcrumb\" className={cn(styles.nav, className)}>\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const interactive = !isLast && (item.href || item.onClick);\n return (\n <Fragment key={index}>\n <span className={styles.item}>\n {interactive ? (\n <a\n href={item.href}\n onClick={(event) => {\n if (item.onClick) {\n event.preventDefault();\n item.onClick();\n }\n }}\n className={styles.link}\n >\n {item.label}\n </a>\n ) : (\n <span\n aria-current={isLast ? \"page\" : undefined}\n className={isLast ? styles.current : undefined}\n >\n {item.label}\n </span>\n )}\n </span>\n {!isLast && (\n <span className={styles.separator} aria-hidden>\n {separator}\n </span>\n )}\n </Fragment>\n );\n })}\n </nav>\n );\n}\n"],"mappings":"kIAsBA,SAAgB,EAAY,CAAE,QAAO,YAAY,IAAK,aAA+B,CACjF,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,aAAW,aAAa,UAAW,EAAA,GAAG,EAAA,QAAO,IAAK,CAAS,EAC3D,SAAA,EAAM,KAAK,EAAM,IAAU,CACxB,IAAM,EAAS,IAAU,EAAM,OAAS,EAClC,EAAc,CAAC,IAAW,EAAK,MAAQ,EAAK,SAClD,OACI,EAAA,EAAA,KAAA,CAAC,EAAA,SAAD,CAAA,SAAA,EACI,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,KACnB,SAAA,GACG,EAAA,EAAA,IAAA,CAAC,IAAD,CACI,KAAM,EAAK,KACX,QAAU,GAAU,CACZ,EAAK,UACL,EAAM,eAAe,EACrB,EAAK,QAAQ,EAErB,EACA,UAAW,EAAA,QAAO,KAEjB,SAAA,EAAK,KACP,CAAA,GAEH,EAAA,EAAA,IAAA,CAAC,OAAD,CACI,eAAc,EAAS,OAAS,IAAA,GAChC,UAAW,EAAS,EAAA,QAAO,QAAU,IAAA,GAEpC,SAAA,EAAK,KACJ,CAAA,CAER,CAAA,EACL,CAAC,IACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,UAAW,cAAA,GAC9B,SAAA,CACC,CAAA,CAEJ,CAAA,EA7BK,CA6BL,CAElB,CAAC,CACA,CAAA,CAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumbs.js","names":[],"sources":["../../../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import { Fragment } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Breadcrumbs.module.css\";\n\nexport interface BreadcrumbItem {\n label: ReactNode;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface BreadcrumbsProps {\n items: BreadcrumbItem[];\n separator?: ReactNode;\n className?: string;\n}\n\n/**\n * Hierarchical navigation breadcrumbs. The last item is rendered as plain\n * text with `aria-current=\"page\"`. Items with neither `href` nor `onClick`\n * also render as text (intermediate but non-clickable).\n */\nexport function Breadcrumbs({ items, separator = \"/\", className }: BreadcrumbsProps) {\n return (\n <nav aria-label=\"breadcrumb\" className={cn(styles.nav, className)}>\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const interactive = !isLast && (item.href || item.onClick);\n return (\n <Fragment key={index}>\n <span className={styles.item}>\n {interactive ? (\n <a\n href={item.href}\n onClick={(event) => {\n if (item.onClick) {\n event.preventDefault();\n item.onClick();\n }\n }}\n className={styles.link}\n >\n {item.label}\n </a>\n ) : (\n <span\n aria-current={isLast ? \"page\" : undefined}\n className={isLast ? styles.current : undefined}\n >\n {item.label}\n </span>\n )}\n </span>\n {!isLast && (\n <span className={styles.separator} aria-hidden>\n {separator}\n </span>\n )}\n </Fragment>\n );\n })}\n </nav>\n );\n}\n"],"mappings":";;;;;AAsBA,SAAgB,EAAY,EAAE,UAAO,eAAY,KAAK,gBAA+B;CACjF,OACI,kBAAC,OAAD;EAAK,cAAW;EAAa,WAAW,EAAG,EAAO,KAAK,CAAS;
|
|
1
|
+
{"version":3,"file":"Breadcrumbs.js","names":[],"sources":["../../../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import { Fragment } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Breadcrumbs.module.css\";\n\nexport interface BreadcrumbItem {\n label: ReactNode;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface BreadcrumbsProps {\n items: BreadcrumbItem[];\n separator?: ReactNode;\n className?: string;\n}\n\n/**\n * Hierarchical navigation breadcrumbs. The last item is rendered as plain\n * text with `aria-current=\"page\"`. Items with neither `href` nor `onClick`\n * also render as text (intermediate but non-clickable).\n */\nexport function Breadcrumbs({ items, separator = \"/\", className }: BreadcrumbsProps) {\n return (\n <nav aria-label=\"breadcrumb\" className={cn(styles.nav, className)}>\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const interactive = !isLast && (item.href || item.onClick);\n return (\n <Fragment key={index}>\n <span className={styles.item}>\n {interactive ? (\n <a\n href={item.href}\n onClick={(event) => {\n if (item.onClick) {\n event.preventDefault();\n item.onClick();\n }\n }}\n className={styles.link}\n >\n {item.label}\n </a>\n ) : (\n <span\n aria-current={isLast ? \"page\" : undefined}\n className={isLast ? styles.current : undefined}\n >\n {item.label}\n </span>\n )}\n </span>\n {!isLast && (\n <span className={styles.separator} aria-hidden>\n {separator}\n </span>\n )}\n </Fragment>\n );\n })}\n </nav>\n );\n}\n"],"mappings":";;;;;AAsBA,SAAgB,EAAY,EAAE,UAAO,eAAY,KAAK,gBAA+B;CACjF,OACI,kBAAC,OAAD;EAAK,cAAW;EAAa,WAAW,EAAG,EAAO,KAAK,CAAS;EAC3D,UAAA,EAAM,KAAK,GAAM,MAAU;GACxB,IAAM,IAAS,MAAU,EAAM,SAAS,GAClC,IAAc,CAAC,MAAW,EAAK,QAAQ,EAAK;GAClD,OACI,kBAAC,GAAD,EAAA,UAAA,CACI,kBAAC,QAAD;IAAM,WAAW,EAAO;IACnB,UAAA,IACG,kBAAC,KAAD;KACI,MAAM,EAAK;KACX,UAAU,MAAU;MAChB,AAAI,EAAK,YACL,EAAM,eAAe,GACrB,EAAK,QAAQ;KAErB;KACA,WAAW,EAAO;KAEjB,UAAA,EAAK;IACP,CAAA,IAEH,kBAAC,QAAD;KACI,gBAAc,IAAS,SAAS,KAAA;KAChC,WAAW,IAAS,EAAO,UAAU,KAAA;KAEpC,UAAA,EAAK;IACJ,CAAA;GAER,CAAA,GACL,CAAC,KACE,kBAAC,QAAD;IAAM,WAAW,EAAO;IAAW,eAAA;IAC9B,UAAA;GACC,CAAA,CAEJ,EAAA,GA7BK,CA6BL;EAElB,CAAC;CACA,CAAA;AAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.cjs","names":[],"sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — this is the design system's button: variant, size,\n * loading, fullWidth, iconOnly, pill, leftIcon and rightIcon are the whole\n * vocabulary every screen composes from. Eight orthogonal knobs on the most-used\n * component is the API working — the count rule is looking for two components fused\n * together, and there is only one here.\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Button.module.css\";\n\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"ghost\" | \"soft\" | \"outline\" | \"link\";\nexport type ButtonSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n loading?: boolean;\n fullWidth?: boolean;\n /** Removes horizontal padding and forces a square footprint (use with `aria-label`). */\n iconOnly?: boolean;\n /** Pill-shaped border radius. */\n pill?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n}\n\n/**\n * Primary action button with variants, sizes and a loading state that\n * preserves layout via an absolutely-positioned spinner.\n *\n * Variants: `primary` (solid), `secondary` (neutral), `danger`, `success`,\n * `ghost` (transparent), `soft` (tinted), `outline` (bordered), `link`.\n *\n * Sizes are density-aware — they read from `--tempest-control-height-*`\n * tokens which respond to the `data-tempest-density` attribute.\n */\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n loading = false,\n fullWidth = false,\n iconOnly = false,\n pill = false,\n leftIcon,\n rightIcon,\n disabled,\n className,\n children,\n ...props\n}: ButtonProps) {\n return (\n <button\n className={cn(\n styles.button,\n styles[variant],\n styles[size],\n iconOnly && styles.iconOnly,\n pill && styles.pill,\n loading && styles.loading,\n fullWidth && styles.fullWidth,\n className,\n )}\n disabled={disabled || loading}\n {...props}\n >\n {loading && (\n <span className={styles.spinner} aria-hidden>\n <SpinnerIcon />\n </span>\n )}\n <span className={cn(styles.content, loading && styles.hiddenText)}>\n {leftIcon}\n {children}\n {rightIcon}\n </span>\n </button>\n );\n}\n\nfunction SpinnerIcon() {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M21 12a9 9 0 1 1-6.219-8.56\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n"],"mappings":"0GAsCA,SAAgB,EAAO,CACnB,UAAU,UACV,OAAO,KACP,UAAU,GACV,YAAY,GACZ,WAAW,GACX,OAAO,GACP,WACA,YACA,WACA,YACA,WACA,GAAG,GACS,CACZ,OACI,EAAA,EAAA,KAAA,CAAC,SAAD,CACI,UAAW,EAAA,GACP,EAAA,QAAO,OACP,EAAA,QAAO,GACP,EAAA,QAAO,GACP,GAAY,EAAA,QAAO,SACnB,GAAQ,EAAA,QAAO,KACf,GAAW,EAAA,QAAO,QAClB,GAAa,EAAA,QAAO,UACpB,CACJ,EACA,SAAU,GAAY,EACtB,GAAI,
|
|
1
|
+
{"version":3,"file":"Button.cjs","names":[],"sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — this is the design system's button: variant, size,\n * loading, fullWidth, iconOnly, pill, leftIcon and rightIcon are the whole\n * vocabulary every screen composes from. Eight orthogonal knobs on the most-used\n * component is the API working — the count rule is looking for two components fused\n * together, and there is only one here.\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Button.module.css\";\n\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"ghost\" | \"soft\" | \"outline\" | \"link\";\nexport type ButtonSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n loading?: boolean;\n fullWidth?: boolean;\n /** Removes horizontal padding and forces a square footprint (use with `aria-label`). */\n iconOnly?: boolean;\n /** Pill-shaped border radius. */\n pill?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n}\n\n/**\n * Primary action button with variants, sizes and a loading state that\n * preserves layout via an absolutely-positioned spinner.\n *\n * Variants: `primary` (solid), `secondary` (neutral), `danger`, `success`,\n * `ghost` (transparent), `soft` (tinted), `outline` (bordered), `link`.\n *\n * Sizes are density-aware — they read from `--tempest-control-height-*`\n * tokens which respond to the `data-tempest-density` attribute.\n */\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n loading = false,\n fullWidth = false,\n iconOnly = false,\n pill = false,\n leftIcon,\n rightIcon,\n disabled,\n className,\n children,\n ...props\n}: ButtonProps) {\n return (\n <button\n className={cn(\n styles.button,\n styles[variant],\n styles[size],\n iconOnly && styles.iconOnly,\n pill && styles.pill,\n loading && styles.loading,\n fullWidth && styles.fullWidth,\n className,\n )}\n disabled={disabled || loading}\n {...props}\n >\n {loading && (\n <span className={styles.spinner} aria-hidden>\n <SpinnerIcon />\n </span>\n )}\n <span className={cn(styles.content, loading && styles.hiddenText)}>\n {leftIcon}\n {children}\n {rightIcon}\n </span>\n </button>\n );\n}\n\nfunction SpinnerIcon() {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M21 12a9 9 0 1 1-6.219-8.56\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n"],"mappings":"0GAsCA,SAAgB,EAAO,CACnB,UAAU,UACV,OAAO,KACP,UAAU,GACV,YAAY,GACZ,WAAW,GACX,OAAO,GACP,WACA,YACA,WACA,YACA,WACA,GAAG,GACS,CACZ,OACI,EAAA,EAAA,KAAA,CAAC,SAAD,CACI,UAAW,EAAA,GACP,EAAA,QAAO,OACP,EAAA,QAAO,GACP,EAAA,QAAO,GACP,GAAY,EAAA,QAAO,SACnB,GAAQ,EAAA,QAAO,KACf,GAAW,EAAA,QAAO,QAClB,GAAa,EAAA,QAAO,UACpB,CACJ,EACA,SAAU,GAAY,EACtB,GAAI,EAZR,SAAA,CAcK,IACG,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,QAAS,cAAA,GAC7B,UAAA,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,CAAA,CACZ,CAAA,GAEV,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAA,GAAG,EAAA,QAAO,QAAS,GAAW,EAAA,QAAO,UAAU,EAAhE,SAAA,CACK,EACA,EACA,CACC,CACF,CAAA,CAAA,GAEhB,CAEA,SAAS,GAAc,CACnB,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,MAAM,6BAEN,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACI,EAAE,8BACF,OAAO,eACP,YAAY,IACZ,cAAc,OACjB,CAAA,CACA,CAAA,CAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","names":[],"sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — this is the design system's button: variant, size,\n * loading, fullWidth, iconOnly, pill, leftIcon and rightIcon are the whole\n * vocabulary every screen composes from. Eight orthogonal knobs on the most-used\n * component is the API working — the count rule is looking for two components fused\n * together, and there is only one here.\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Button.module.css\";\n\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"ghost\" | \"soft\" | \"outline\" | \"link\";\nexport type ButtonSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n loading?: boolean;\n fullWidth?: boolean;\n /** Removes horizontal padding and forces a square footprint (use with `aria-label`). */\n iconOnly?: boolean;\n /** Pill-shaped border radius. */\n pill?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n}\n\n/**\n * Primary action button with variants, sizes and a loading state that\n * preserves layout via an absolutely-positioned spinner.\n *\n * Variants: `primary` (solid), `secondary` (neutral), `danger`, `success`,\n * `ghost` (transparent), `soft` (tinted), `outline` (bordered), `link`.\n *\n * Sizes are density-aware — they read from `--tempest-control-height-*`\n * tokens which respond to the `data-tempest-density` attribute.\n */\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n loading = false,\n fullWidth = false,\n iconOnly = false,\n pill = false,\n leftIcon,\n rightIcon,\n disabled,\n className,\n children,\n ...props\n}: ButtonProps) {\n return (\n <button\n className={cn(\n styles.button,\n styles[variant],\n styles[size],\n iconOnly && styles.iconOnly,\n pill && styles.pill,\n loading && styles.loading,\n fullWidth && styles.fullWidth,\n className,\n )}\n disabled={disabled || loading}\n {...props}\n >\n {loading && (\n <span className={styles.spinner} aria-hidden>\n <SpinnerIcon />\n </span>\n )}\n <span className={cn(styles.content, loading && styles.hiddenText)}>\n {leftIcon}\n {children}\n {rightIcon}\n </span>\n </button>\n );\n}\n\nfunction SpinnerIcon() {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M21 12a9 9 0 1 1-6.219-8.56\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n"],"mappings":";;;;AAsCA,SAAgB,EAAO,EACnB,aAAU,WACV,UAAO,MACP,aAAU,IACV,eAAY,IACZ,cAAW,IACX,UAAO,IACP,aACA,cACA,aACA,cACA,aACA,GAAG,KACS;CACZ,OACI,kBAAC,UAAD;EACI,WAAW,EACP,EAAO,QACP,EAAO,IACP,EAAO,IACP,KAAY,EAAO,UACnB,KAAQ,EAAO,MACf,KAAW,EAAO,SAClB,KAAa,EAAO,WACpB,CACJ;EACA,UAAU,KAAY;EACtB,GAAI;
|
|
1
|
+
{"version":3,"file":"Button.js","names":[],"sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — this is the design system's button: variant, size,\n * loading, fullWidth, iconOnly, pill, leftIcon and rightIcon are the whole\n * vocabulary every screen composes from. Eight orthogonal knobs on the most-used\n * component is the API working — the count rule is looking for two components fused\n * together, and there is only one here.\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Button.module.css\";\n\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"ghost\" | \"soft\" | \"outline\" | \"link\";\nexport type ButtonSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n loading?: boolean;\n fullWidth?: boolean;\n /** Removes horizontal padding and forces a square footprint (use with `aria-label`). */\n iconOnly?: boolean;\n /** Pill-shaped border radius. */\n pill?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n}\n\n/**\n * Primary action button with variants, sizes and a loading state that\n * preserves layout via an absolutely-positioned spinner.\n *\n * Variants: `primary` (solid), `secondary` (neutral), `danger`, `success`,\n * `ghost` (transparent), `soft` (tinted), `outline` (bordered), `link`.\n *\n * Sizes are density-aware — they read from `--tempest-control-height-*`\n * tokens which respond to the `data-tempest-density` attribute.\n */\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n loading = false,\n fullWidth = false,\n iconOnly = false,\n pill = false,\n leftIcon,\n rightIcon,\n disabled,\n className,\n children,\n ...props\n}: ButtonProps) {\n return (\n <button\n className={cn(\n styles.button,\n styles[variant],\n styles[size],\n iconOnly && styles.iconOnly,\n pill && styles.pill,\n loading && styles.loading,\n fullWidth && styles.fullWidth,\n className,\n )}\n disabled={disabled || loading}\n {...props}\n >\n {loading && (\n <span className={styles.spinner} aria-hidden>\n <SpinnerIcon />\n </span>\n )}\n <span className={cn(styles.content, loading && styles.hiddenText)}>\n {leftIcon}\n {children}\n {rightIcon}\n </span>\n </button>\n );\n}\n\nfunction SpinnerIcon() {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M21 12a9 9 0 1 1-6.219-8.56\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n"],"mappings":";;;;AAsCA,SAAgB,EAAO,EACnB,aAAU,WACV,UAAO,MACP,aAAU,IACV,eAAY,IACZ,cAAW,IACX,UAAO,IACP,aACA,cACA,aACA,cACA,aACA,GAAG,KACS;CACZ,OACI,kBAAC,UAAD;EACI,WAAW,EACP,EAAO,QACP,EAAO,IACP,EAAO,IACP,KAAY,EAAO,UACnB,KAAQ,EAAO,MACf,KAAW,EAAO,SAClB,KAAa,EAAO,WACpB,CACJ;EACA,UAAU,KAAY;EACtB,GAAI;EAZR,UAAA,CAcK,KACG,kBAAC,QAAD;GAAM,WAAW,EAAO;GAAS,eAAA;GAC7B,UAAA,kBAAC,GAAD,CAAc,CAAA;EACZ,CAAA,GAEV,kBAAC,QAAD;GAAM,WAAW,EAAG,EAAO,SAAS,KAAW,EAAO,UAAU;GAAhE,UAAA;IACK;IACA;IACA;GACC;EACF,CAAA,CAAA;;AAEhB;AAEA,SAAS,IAAc;CACnB,OACI,kBAAC,OAAD;EACI,OAAM;EACN,QAAO;EACP,SAAQ;EACR,MAAK;EACL,OAAM;EAEN,UAAA,kBAAC,QAAD;GACI,GAAE;GACF,QAAO;GACP,aAAY;GACZ,eAAc;EACjB,CAAA;CACA,CAAA;AAEb"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../utils/cn.cjs"),t=require("./Calendar.module.cjs");let n=require("react"),r=require("react/jsx-runtime");var i=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],a=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],o=42;function s(e,t,n){return new Date(e,t,n)}function c(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())}function l(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function u(e,t,n){let r=c(e).getTime();return!!(t&&r<c(t).getTime()||n&&r>c(n).getTime())}function d(e,t){let n=e.getFullYear(),r=e.getMonth(),i=s(n,r,1-(s(n,r,1).getDay()-t+7)%7),a=[];for(let e=0;e<o;e+=1)a.push(s(i.getFullYear(),i.getMonth(),i.getDate()+e));return a}function f({value:
|
|
1
|
+
const e=require("../../utils/cn.cjs"),t=require("./Calendar.module.cjs");let n=require("react"),r=require("react/jsx-runtime");var i=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],a=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],o=42;function s(e,t,n){return new Date(e,t,n)}function c(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())}function l(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function u(e,t,n){let r=c(e).getTime();return!!(t&&r<c(t).getTime()||n&&r>c(n).getTime())}function d(e,t){let n=e.getFullYear(),r=e.getMonth(),i=s(n,r,1-(s(n,r,1).getDay()-t+7)%7),a=[];for(let e=0;e<o;e+=1)a.push(s(i.getFullYear(),i.getMonth(),i.getDate()+e));return a}function f({value:o,defaultValue:f,onChange:p,month:m,onMonthChange:h,minDate:g,maxDate:_,weekStartsOn:v=0,className:y,...b}){let x=o!==void 0,[S,C]=(0,n.useState)(f),w=x?o:S,T=m!==void 0,[E,D]=(0,n.useState)(()=>{let e=m??o??f??new Date;return s(e.getFullYear(),e.getMonth(),1)}),O=T?s(m.getFullYear(),m.getMonth(),1):E,[k,A]=(0,n.useState)(null),j=(0,n.useRef)(null),M=(0,n.useMemo)(()=>c(new Date),[]),N=(0,n.useMemo)(()=>d(O,v),[O,v]),P=(0,n.useMemo)(()=>Array.from({length:7},(e,t)=>i[(t+v)%7]),[v]),F=(0,n.useCallback)(e=>{let t=s(O.getFullYear(),O.getMonth()+e,1);h&&h(t),T||D(t)},[O,h,T]),I=(0,n.useCallback)(e=>{u(e,g,_)||(p&&p(e),x||C(e))},[g,_,p,x]),L=(0,n.useCallback)(e=>{let t=Math.max(0,Math.min(41,e));A(t);let n=j.current;n&&n.querySelectorAll(`button[data-day]`)[t]?.focus()},[]),R=(0,n.useCallback)((e,t)=>{switch(e.key){case`ArrowLeft`:e.preventDefault(),L(t-1);break;case`ArrowRight`:e.preventDefault(),L(t+1);break;case`ArrowUp`:e.preventDefault(),L(t-7);break;case`ArrowDown`:e.preventDefault(),L(t+7);break;case`Enter`:case` `:e.preventDefault(),I(N[t])}},[L,I,N]);return(0,r.jsxs)(`div`,{className:e.cn(t.default.root,y),...b,children:[(0,r.jsxs)(`div`,{className:t.default.header,children:[(0,r.jsx)(`button`,{type:`button`,className:t.default.nav,"aria-label":`Previous month`,onClick:()=>F(-1),children:`‹`}),(0,r.jsxs)(`span`,{className:t.default.title,"aria-live":`polite`,children:[a[O.getMonth()],` `,O.getFullYear()]}),(0,r.jsx)(`button`,{type:`button`,className:t.default.nav,"aria-label":`Next month`,onClick:()=>F(1),children:`›`})]}),(0,r.jsx)(`div`,{className:t.default.weekdays,role:`row`,children:P.map(e=>(0,r.jsx)(`span`,{className:t.default.weekday,role:`columnheader`,children:e},e))}),(0,r.jsx)(`div`,{className:t.default.grid,role:`grid`,ref:j,children:N.map((n,i)=>{let a=n.getMonth()===O.getMonth(),o=w?l(n,w):!1,s=l(n,M),c=u(n,g,_),d=k===null?a&&n.getDate()===1:k===i;return(0,r.jsx)(`button`,{type:`button`,"data-day":!0,role:`gridcell`,className:e.cn(t.default.day,!a&&t.default.outside,o&&t.default.selected,s&&t.default.today),"aria-pressed":o,"aria-selected":o,"aria-current":s?`date`:void 0,disabled:c,tabIndex:d?0:-1,onClick:()=>I(n),onKeyDown:e=>R(e,i),children:n.getDate()},i)})})]})}exports.Calendar=f;
|
|
2
2
|
//# sourceMappingURL=Calendar.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.cjs","names":[],"sources":["../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — a date grid is\n * controlled two ways at once — the selected day (value, defaultValue, onChange) and\n * the visible month (month, onMonthChange) — inside the bounds (minDate, maxDate,\n * weekStartsOn). The body builds the grid and owns roving focus and keyboard\n * navigation, which read the same cursor date.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Calendar.module.css\";\n\nexport type WeekStart = 0 | 1;\n\nexport interface CalendarProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n /** Controlled selected date. */\n value?: Date;\n /** Initial selected date for the uncontrolled case. */\n defaultValue?: Date;\n /** Called with the newly selected date. */\n onChange?: (date: Date) => void;\n /** Controlled visible month (any day within it). */\n month?: Date;\n /** Called when the visible month changes (prev/next). */\n onMonthChange?: (month: Date) => void;\n /** Earliest selectable date (inclusive). */\n minDate?: Date;\n /** Latest selectable date (inclusive). */\n maxDate?: Date;\n /** First column of the week — `0` Sunday (default) or `1` Monday. */\n weekStartsOn?: WeekStart;\n}\n\nconst WEEKDAY_LABELS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst MONTH_LABELS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n];\n\nconst DAYS_IN_GRID = 42;\n\n/**\n * Build a `Date` at midnight local time for the given year/month/day.\n *\n * @param year - Full year.\n * @param month - Zero-based month index.\n * @param day - Day of the month.\n * @returns A normalized `Date`.\n */\nfunction makeDate(year: number, month: number, day: number): Date {\n return new Date(year, month, day);\n}\n\n/**\n * Strip the time portion so two dates can be compared by calendar day.\n *\n * @param date - The date to normalize.\n * @returns A new `Date` at local midnight.\n */\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/**\n * Whether two dates fall on the same calendar day.\n *\n * @param a - First date.\n * @param b - Second date.\n * @returns `true` when year, month and day match.\n */\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/**\n * Whether a date is outside the inclusive `[minDate, maxDate]` window.\n *\n * @param date - The candidate day.\n * @param minDate - Optional lower bound.\n * @param maxDate - Optional upper bound.\n * @returns `true` when the date is disabled.\n */\nfunction isOutOfRange(date: Date, minDate?: Date, maxDate?: Date): boolean {\n const day = startOfDay(date).getTime();\n if (minDate && day < startOfDay(minDate).getTime()) return true;\n if (maxDate && day > startOfDay(maxDate).getTime()) return true;\n return false;\n}\n\n/**\n * Compute the 42-cell (6x7) grid of dates covering the given month, padded with\n * leading/trailing days from the adjacent months.\n *\n * @param month - Any date within the target month.\n * @param weekStartsOn - First column of the week.\n * @returns An array of 42 `Date` objects.\n */\nfunction buildGrid(month: Date, weekStartsOn: WeekStart): Date[] {\n const year = month.getFullYear();\n const monthIndex = month.getMonth();\n const firstOfMonth = makeDate(year, monthIndex, 1);\n const firstWeekday = firstOfMonth.getDay();\n const leading = (firstWeekday - weekStartsOn + 7) % 7;\n const start = makeDate(year, monthIndex, 1 - leading);\n\n const cells: Date[] = [];\n for (let i = 0; i < DAYS_IN_GRID; i += 1) {\n cells.push(makeDate(start.getFullYear(), start.getMonth(), start.getDate() + i));\n }\n return cells;\n}\n\n/**\n * Standalone month-grid date picker. Renders a header with the month/year and\n * prev/next buttons, a weekday row, and a 6x7 grid of day buttons. Selection and\n * the visible month can each be controlled or uncontrolled. Grid arithmetic uses\n * plain `Date` math — no external date libraries.\n *\n * Keyboard: arrow keys move focus by day (left/right) or week (up/down), and\n * Enter/Space selects the focused day.\n */\nexport function Calendar({\n value,\n defaultValue,\n onChange,\n month,\n onMonthChange,\n minDate,\n maxDate,\n weekStartsOn = 0,\n className,\n ...props\n}: CalendarProps) {\n const isSelectionControlled = value !== undefined;\n const [internalSelected, setInternalSelected] = useState<Date | undefined>(defaultValue);\n const selected = isSelectionControlled ? value : internalSelected;\n\n const isMonthControlled = month !== undefined;\n const [internalMonth, setInternalMonth] = useState<Date>(() => {\n const base = month ?? value ?? defaultValue ?? new Date();\n return makeDate(base.getFullYear(), base.getMonth(), 1);\n });\n const visibleMonth = isMonthControlled\n ? makeDate(month.getFullYear(), month.getMonth(), 1)\n : internalMonth;\n\n const [focusedDay, setFocusedDay] = useState<number | null>(null);\n const gridRef = useRef<HTMLDivElement | null>(null);\n\n const today = useMemo(() => startOfDay(new Date()), []);\n const cells = useMemo(\n () => buildGrid(visibleMonth, weekStartsOn),\n [visibleMonth, weekStartsOn],\n );\n\n const weekdayLabels = useMemo(() => {\n return Array.from({ length: 7 }, (_, i) => WEEKDAY_LABELS[(i + weekStartsOn) % 7]);\n }, [weekStartsOn]);\n\n const changeMonth = useCallback(\n (offset: number): void => {\n const next = makeDate(visibleMonth.getFullYear(), visibleMonth.getMonth() + offset, 1);\n if (onMonthChange) onMonthChange(next);\n if (!isMonthControlled) setInternalMonth(next);\n },\n [visibleMonth, onMonthChange, isMonthControlled],\n );\n\n const selectDate = useCallback(\n (date: Date): void => {\n if (isOutOfRange(date, minDate, maxDate)) return;\n if (onChange) onChange(date);\n if (!isSelectionControlled) setInternalSelected(date);\n },\n [minDate, maxDate, onChange, isSelectionControlled],\n );\n\n const focusCell = useCallback((index: number): void => {\n const clamped = Math.max(0, Math.min(DAYS_IN_GRID - 1, index));\n setFocusedDay(clamped);\n const grid = gridRef.current;\n if (!grid) return;\n const buttons = grid.querySelectorAll<HTMLButtonElement>(\"button[data-day]\");\n buttons[clamped]?.focus();\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number): void => {\n switch (event.key) {\n case \"ArrowLeft\":\n event.preventDefault();\n focusCell(index - 1);\n break;\n case \"ArrowRight\":\n event.preventDefault();\n focusCell(index + 1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n focusCell(index - 7);\n break;\n case \"ArrowDown\":\n event.preventDefault();\n focusCell(index + 7);\n break;\n case \"Enter\":\n case \" \":\n event.preventDefault();\n selectDate(cells[index]);\n break;\n default:\n break;\n }\n },\n [focusCell, selectDate, cells],\n );\n\n return (\n <div className={cn(styles.root, className)} {...props}>\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Previous month\"\n onClick={() => changeMonth(-1)}\n >\n {\"‹\"}\n </button>\n <span className={styles.title} aria-live=\"polite\">\n {MONTH_LABELS[visibleMonth.getMonth()]} {visibleMonth.getFullYear()}\n </span>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Next month\"\n onClick={() => changeMonth(1)}\n >\n {\"›\"}\n </button>\n </div>\n\n <div className={styles.weekdays} role=\"row\">\n {weekdayLabels.map((label) => (\n <span key={label} className={styles.weekday} role=\"columnheader\">\n {label}\n </span>\n ))}\n </div>\n\n <div className={styles.grid} role=\"grid\" ref={gridRef}>\n {cells.map((date, index) => {\n const inMonth = date.getMonth() === visibleMonth.getMonth();\n const isSelected = selected ? isSameDay(date, selected) : false;\n const isToday = isSameDay(date, today);\n const disabled = isOutOfRange(date, minDate, maxDate);\n const isFocusTarget =\n focusedDay === null\n ? inMonth && date.getDate() === 1\n : focusedDay === index;\n return (\n <button\n key={index}\n type=\"button\"\n data-day\n role=\"gridcell\"\n className={cn(\n styles.day,\n !inMonth && styles.outside,\n isSelected && styles.selected,\n isToday && styles.today,\n )}\n aria-pressed={isSelected}\n aria-selected={isSelected}\n aria-current={isToday ? \"date\" : undefined}\n disabled={disabled}\n tabIndex={isFocusTarget ? 0 : -1}\n onClick={() => selectDate(date)}\n onKeyDown={(event) => handleKeyDown(event, index)}\n >\n {date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Calendar.cjs","names":[],"sources":["../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — a date grid is\n * controlled two ways at once — the selected day (value, defaultValue, onChange) and\n * the visible month (month, onMonthChange) — inside the bounds (minDate, maxDate,\n * weekStartsOn). The body builds the grid and owns roving focus and keyboard\n * navigation, which read the same cursor date.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Calendar.module.css\";\n\nexport type WeekStart = 0 | 1;\n\nexport interface CalendarProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n /** Controlled selected date. */\n value?: Date;\n /** Initial selected date for the uncontrolled case. */\n defaultValue?: Date;\n /** Called with the newly selected date. */\n onChange?: (date: Date) => void;\n /** Controlled visible month (any day within it). */\n month?: Date;\n /** Called when the visible month changes (prev/next). */\n onMonthChange?: (month: Date) => void;\n /** Earliest selectable date (inclusive). */\n minDate?: Date;\n /** Latest selectable date (inclusive). */\n maxDate?: Date;\n /** First column of the week — `0` Sunday (default) or `1` Monday. */\n weekStartsOn?: WeekStart;\n}\n\nconst WEEKDAY_LABELS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst MONTH_LABELS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n];\n\nconst DAYS_IN_GRID = 42;\n\n/**\n * Build a `Date` at midnight local time for the given year/month/day.\n *\n * @param year - Full year.\n * @param month - Zero-based month index.\n * @param day - Day of the month.\n * @returns A normalized `Date`.\n */\nfunction makeDate(year: number, month: number, day: number): Date {\n return new Date(year, month, day);\n}\n\n/**\n * Strip the time portion so two dates can be compared by calendar day.\n *\n * @param date - The date to normalize.\n * @returns A new `Date` at local midnight.\n */\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/**\n * Whether two dates fall on the same calendar day.\n *\n * @param a - First date.\n * @param b - Second date.\n * @returns `true` when year, month and day match.\n */\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/**\n * Whether a date is outside the inclusive `[minDate, maxDate]` window.\n *\n * @param date - The candidate day.\n * @param minDate - Optional lower bound.\n * @param maxDate - Optional upper bound.\n * @returns `true` when the date is disabled.\n */\nfunction isOutOfRange(date: Date, minDate?: Date, maxDate?: Date): boolean {\n const day = startOfDay(date).getTime();\n if (minDate && day < startOfDay(minDate).getTime()) return true;\n if (maxDate && day > startOfDay(maxDate).getTime()) return true;\n return false;\n}\n\n/**\n * Compute the 42-cell (6x7) grid of dates covering the given month, padded with\n * leading/trailing days from the adjacent months.\n *\n * @param month - Any date within the target month.\n * @param weekStartsOn - First column of the week.\n * @returns An array of 42 `Date` objects.\n */\nfunction buildGrid(month: Date, weekStartsOn: WeekStart): Date[] {\n const year = month.getFullYear();\n const monthIndex = month.getMonth();\n const firstOfMonth = makeDate(year, monthIndex, 1);\n const firstWeekday = firstOfMonth.getDay();\n const leading = (firstWeekday - weekStartsOn + 7) % 7;\n const start = makeDate(year, monthIndex, 1 - leading);\n\n const cells: Date[] = [];\n for (let i = 0; i < DAYS_IN_GRID; i += 1) {\n cells.push(makeDate(start.getFullYear(), start.getMonth(), start.getDate() + i));\n }\n return cells;\n}\n\n/**\n * Standalone month-grid date picker. Renders a header with the month/year and\n * prev/next buttons, a weekday row, and a 6x7 grid of day buttons. Selection and\n * the visible month can each be controlled or uncontrolled. Grid arithmetic uses\n * plain `Date` math — no external date libraries.\n *\n * Keyboard: arrow keys move focus by day (left/right) or week (up/down), and\n * Enter/Space selects the focused day.\n */\nexport function Calendar({\n value,\n defaultValue,\n onChange,\n month,\n onMonthChange,\n minDate,\n maxDate,\n weekStartsOn = 0,\n className,\n ...props\n}: CalendarProps) {\n const isSelectionControlled = value !== undefined;\n const [internalSelected, setInternalSelected] = useState<Date | undefined>(defaultValue);\n const selected = isSelectionControlled ? value : internalSelected;\n\n const isMonthControlled = month !== undefined;\n const [internalMonth, setInternalMonth] = useState<Date>(() => {\n const base = month ?? value ?? defaultValue ?? new Date();\n return makeDate(base.getFullYear(), base.getMonth(), 1);\n });\n const visibleMonth = isMonthControlled\n ? makeDate(month.getFullYear(), month.getMonth(), 1)\n : internalMonth;\n\n const [focusedDay, setFocusedDay] = useState<number | null>(null);\n const gridRef = useRef<HTMLDivElement | null>(null);\n\n const today = useMemo(() => startOfDay(new Date()), []);\n const cells = useMemo(\n () => buildGrid(visibleMonth, weekStartsOn),\n [visibleMonth, weekStartsOn],\n );\n\n const weekdayLabels = useMemo(() => {\n return Array.from({ length: 7 }, (_, i) => WEEKDAY_LABELS[(i + weekStartsOn) % 7]);\n }, [weekStartsOn]);\n\n const changeMonth = useCallback(\n (offset: number): void => {\n const next = makeDate(visibleMonth.getFullYear(), visibleMonth.getMonth() + offset, 1);\n if (onMonthChange) onMonthChange(next);\n if (!isMonthControlled) setInternalMonth(next);\n },\n [visibleMonth, onMonthChange, isMonthControlled],\n );\n\n const selectDate = useCallback(\n (date: Date): void => {\n if (isOutOfRange(date, minDate, maxDate)) return;\n if (onChange) onChange(date);\n if (!isSelectionControlled) setInternalSelected(date);\n },\n [minDate, maxDate, onChange, isSelectionControlled],\n );\n\n const focusCell = useCallback((index: number): void => {\n const clamped = Math.max(0, Math.min(DAYS_IN_GRID - 1, index));\n setFocusedDay(clamped);\n const grid = gridRef.current;\n if (!grid) return;\n const buttons = grid.querySelectorAll<HTMLButtonElement>(\"button[data-day]\");\n buttons[clamped]?.focus();\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number): void => {\n switch (event.key) {\n case \"ArrowLeft\":\n event.preventDefault();\n focusCell(index - 1);\n break;\n case \"ArrowRight\":\n event.preventDefault();\n focusCell(index + 1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n focusCell(index - 7);\n break;\n case \"ArrowDown\":\n event.preventDefault();\n focusCell(index + 7);\n break;\n case \"Enter\":\n case \" \":\n event.preventDefault();\n selectDate(cells[index]);\n break;\n default:\n break;\n }\n },\n [focusCell, selectDate, cells],\n );\n\n return (\n <div className={cn(styles.root, className)} {...props}>\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Previous month\"\n onClick={() => changeMonth(-1)}\n >\n {\"‹\"}\n </button>\n <span className={styles.title} aria-live=\"polite\">\n {MONTH_LABELS[visibleMonth.getMonth()]} {visibleMonth.getFullYear()}\n </span>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Next month\"\n onClick={() => changeMonth(1)}\n >\n {\"›\"}\n </button>\n </div>\n\n <div className={styles.weekdays} role=\"row\">\n {weekdayLabels.map((label) => (\n <span key={label} className={styles.weekday} role=\"columnheader\">\n {label}\n </span>\n ))}\n </div>\n\n <div className={styles.grid} role=\"grid\" ref={gridRef}>\n {cells.map((date, index) => {\n const inMonth = date.getMonth() === visibleMonth.getMonth();\n const isSelected = selected ? isSameDay(date, selected) : false;\n const isToday = isSameDay(date, today);\n const disabled = isOutOfRange(date, minDate, maxDate);\n const isFocusTarget =\n focusedDay === null\n ? inMonth && date.getDate() === 1\n : focusedDay === index;\n return (\n <button\n key={index}\n type=\"button\"\n data-day\n role=\"gridcell\"\n className={cn(\n styles.day,\n !inMonth && styles.outside,\n isSelected && styles.selected,\n isToday && styles.today,\n )}\n aria-pressed={isSelected}\n aria-selected={isSelected}\n aria-current={isToday ? \"date\" : undefined}\n disabled={disabled}\n tabIndex={isFocusTarget ? 0 : -1}\n onClick={() => selectDate(date)}\n onKeyDown={(event) => handleKeyDown(event, index)}\n >\n {date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -43,57 +43,54 @@ function h(e, t) {
|
|
|
43
43
|
for (let e = 0; e < u; e += 1) a.push(d(i.getFullYear(), i.getMonth(), i.getDate() + e));
|
|
44
44
|
return a;
|
|
45
45
|
}
|
|
46
|
-
function g({ value:
|
|
47
|
-
let
|
|
48
|
-
let e =
|
|
46
|
+
function g({ value: u, defaultValue: g, onChange: _, month: v, onMonthChange: y, minDate: b, maxDate: x, weekStartsOn: S = 0, className: C, ...w }) {
|
|
47
|
+
let T = u !== void 0, [E, D] = a(g), O = T ? u : E, k = v !== void 0, [A, j] = a(() => {
|
|
48
|
+
let e = v ?? u ?? g ?? /* @__PURE__ */ new Date();
|
|
49
49
|
return d(e.getFullYear(), e.getMonth(), 1);
|
|
50
|
-
}),
|
|
51
|
-
let t = d(
|
|
52
|
-
|
|
50
|
+
}), M = k ? d(v.getFullYear(), v.getMonth(), 1) : A, [N, P] = a(null), F = i(null), I = r(() => f(/* @__PURE__ */ new Date()), []), L = r(() => h(M, S), [M, S]), R = r(() => Array.from({ length: 7 }, (e, t) => c[(t + S) % 7]), [S]), z = n((e) => {
|
|
51
|
+
let t = d(M.getFullYear(), M.getMonth() + e, 1);
|
|
52
|
+
y && y(t), k || j(t);
|
|
53
53
|
}, [
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
]),
|
|
58
|
-
m(e,
|
|
54
|
+
M,
|
|
55
|
+
y,
|
|
56
|
+
k
|
|
57
|
+
]), B = n((e) => {
|
|
58
|
+
m(e, b, x) || (_ && _(e), T || D(e));
|
|
59
59
|
}, [
|
|
60
|
+
b,
|
|
60
61
|
x,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
F
|
|
67
|
-
let n = I.current;
|
|
62
|
+
_,
|
|
63
|
+
T
|
|
64
|
+
]), V = n((e) => {
|
|
65
|
+
let t = Math.max(0, Math.min(41, e));
|
|
66
|
+
P(t);
|
|
67
|
+
let n = F.current;
|
|
68
68
|
n && n.querySelectorAll("button[data-day]")[t]?.focus();
|
|
69
|
-
}, []),
|
|
69
|
+
}, []), H = n((e, t) => {
|
|
70
70
|
switch (e.key) {
|
|
71
71
|
case "ArrowLeft":
|
|
72
|
-
e.preventDefault(),
|
|
72
|
+
e.preventDefault(), V(t - 1);
|
|
73
73
|
break;
|
|
74
74
|
case "ArrowRight":
|
|
75
|
-
e.preventDefault(),
|
|
75
|
+
e.preventDefault(), V(t + 1);
|
|
76
76
|
break;
|
|
77
77
|
case "ArrowUp":
|
|
78
|
-
e.preventDefault(),
|
|
78
|
+
e.preventDefault(), V(t - 7);
|
|
79
79
|
break;
|
|
80
80
|
case "ArrowDown":
|
|
81
|
-
e.preventDefault(),
|
|
81
|
+
e.preventDefault(), V(t + 7);
|
|
82
82
|
break;
|
|
83
83
|
case "Enter":
|
|
84
|
-
case " ":
|
|
85
|
-
e.preventDefault(), V(R[t]);
|
|
86
|
-
break;
|
|
87
|
-
default: break;
|
|
84
|
+
case " ": e.preventDefault(), B(L[t]);
|
|
88
85
|
}
|
|
89
86
|
}, [
|
|
90
|
-
H,
|
|
91
87
|
V,
|
|
92
|
-
|
|
88
|
+
B,
|
|
89
|
+
L
|
|
93
90
|
]);
|
|
94
91
|
return /* @__PURE__ */ s("div", {
|
|
95
|
-
className: e(t.root,
|
|
96
|
-
...
|
|
92
|
+
className: e(t.root, C),
|
|
93
|
+
...w,
|
|
97
94
|
children: [
|
|
98
95
|
/* @__PURE__ */ s("div", {
|
|
99
96
|
className: t.header,
|
|
@@ -102,23 +99,23 @@ function g({ value: g, defaultValue: _, onChange: v, month: y, onMonthChange: b,
|
|
|
102
99
|
type: "button",
|
|
103
100
|
className: t.nav,
|
|
104
101
|
"aria-label": "Previous month",
|
|
105
|
-
onClick: () =>
|
|
102
|
+
onClick: () => z(-1),
|
|
106
103
|
children: "‹"
|
|
107
104
|
}),
|
|
108
105
|
/* @__PURE__ */ s("span", {
|
|
109
106
|
className: t.title,
|
|
110
107
|
"aria-live": "polite",
|
|
111
108
|
children: [
|
|
112
|
-
l[
|
|
109
|
+
l[M.getMonth()],
|
|
113
110
|
" ",
|
|
114
|
-
|
|
111
|
+
M.getFullYear()
|
|
115
112
|
]
|
|
116
113
|
}),
|
|
117
114
|
/* @__PURE__ */ o("button", {
|
|
118
115
|
type: "button",
|
|
119
116
|
className: t.nav,
|
|
120
117
|
"aria-label": "Next month",
|
|
121
|
-
onClick: () =>
|
|
118
|
+
onClick: () => z(1),
|
|
122
119
|
children: "›"
|
|
123
120
|
})
|
|
124
121
|
]
|
|
@@ -126,7 +123,7 @@ function g({ value: g, defaultValue: _, onChange: v, month: y, onMonthChange: b,
|
|
|
126
123
|
/* @__PURE__ */ o("div", {
|
|
127
124
|
className: t.weekdays,
|
|
128
125
|
role: "row",
|
|
129
|
-
children:
|
|
126
|
+
children: R.map((e) => /* @__PURE__ */ o("span", {
|
|
130
127
|
className: t.weekday,
|
|
131
128
|
role: "columnheader",
|
|
132
129
|
children: e
|
|
@@ -135,9 +132,9 @@ function g({ value: g, defaultValue: _, onChange: v, month: y, onMonthChange: b,
|
|
|
135
132
|
/* @__PURE__ */ o("div", {
|
|
136
133
|
className: t.grid,
|
|
137
134
|
role: "grid",
|
|
138
|
-
ref:
|
|
139
|
-
children:
|
|
140
|
-
let i = n.getMonth() ===
|
|
135
|
+
ref: F,
|
|
136
|
+
children: L.map((n, r) => {
|
|
137
|
+
let i = n.getMonth() === M.getMonth(), a = O ? p(n, O) : !1, s = p(n, I), c = m(n, b, x), l = N === null ? i && n.getDate() === 1 : N === r;
|
|
141
138
|
return /* @__PURE__ */ o("button", {
|
|
142
139
|
type: "button",
|
|
143
140
|
"data-day": !0,
|
|
@@ -148,8 +145,8 @@ function g({ value: g, defaultValue: _, onChange: v, month: y, onMonthChange: b,
|
|
|
148
145
|
"aria-current": s ? "date" : void 0,
|
|
149
146
|
disabled: c,
|
|
150
147
|
tabIndex: l ? 0 : -1,
|
|
151
|
-
onClick: () =>
|
|
152
|
-
onKeyDown: (e) =>
|
|
148
|
+
onClick: () => B(n),
|
|
149
|
+
onKeyDown: (e) => H(e, r),
|
|
153
150
|
children: n.getDate()
|
|
154
151
|
}, r);
|
|
155
152
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.js","names":[],"sources":["../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — a date grid is\n * controlled two ways at once — the selected day (value, defaultValue, onChange) and\n * the visible month (month, onMonthChange) — inside the bounds (minDate, maxDate,\n * weekStartsOn). The body builds the grid and owns roving focus and keyboard\n * navigation, which read the same cursor date.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Calendar.module.css\";\n\nexport type WeekStart = 0 | 1;\n\nexport interface CalendarProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n /** Controlled selected date. */\n value?: Date;\n /** Initial selected date for the uncontrolled case. */\n defaultValue?: Date;\n /** Called with the newly selected date. */\n onChange?: (date: Date) => void;\n /** Controlled visible month (any day within it). */\n month?: Date;\n /** Called when the visible month changes (prev/next). */\n onMonthChange?: (month: Date) => void;\n /** Earliest selectable date (inclusive). */\n minDate?: Date;\n /** Latest selectable date (inclusive). */\n maxDate?: Date;\n /** First column of the week — `0` Sunday (default) or `1` Monday. */\n weekStartsOn?: WeekStart;\n}\n\nconst WEEKDAY_LABELS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst MONTH_LABELS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n];\n\nconst DAYS_IN_GRID = 42;\n\n/**\n * Build a `Date` at midnight local time for the given year/month/day.\n *\n * @param year - Full year.\n * @param month - Zero-based month index.\n * @param day - Day of the month.\n * @returns A normalized `Date`.\n */\nfunction makeDate(year: number, month: number, day: number): Date {\n return new Date(year, month, day);\n}\n\n/**\n * Strip the time portion so two dates can be compared by calendar day.\n *\n * @param date - The date to normalize.\n * @returns A new `Date` at local midnight.\n */\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/**\n * Whether two dates fall on the same calendar day.\n *\n * @param a - First date.\n * @param b - Second date.\n * @returns `true` when year, month and day match.\n */\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/**\n * Whether a date is outside the inclusive `[minDate, maxDate]` window.\n *\n * @param date - The candidate day.\n * @param minDate - Optional lower bound.\n * @param maxDate - Optional upper bound.\n * @returns `true` when the date is disabled.\n */\nfunction isOutOfRange(date: Date, minDate?: Date, maxDate?: Date): boolean {\n const day = startOfDay(date).getTime();\n if (minDate && day < startOfDay(minDate).getTime()) return true;\n if (maxDate && day > startOfDay(maxDate).getTime()) return true;\n return false;\n}\n\n/**\n * Compute the 42-cell (6x7) grid of dates covering the given month, padded with\n * leading/trailing days from the adjacent months.\n *\n * @param month - Any date within the target month.\n * @param weekStartsOn - First column of the week.\n * @returns An array of 42 `Date` objects.\n */\nfunction buildGrid(month: Date, weekStartsOn: WeekStart): Date[] {\n const year = month.getFullYear();\n const monthIndex = month.getMonth();\n const firstOfMonth = makeDate(year, monthIndex, 1);\n const firstWeekday = firstOfMonth.getDay();\n const leading = (firstWeekday - weekStartsOn + 7) % 7;\n const start = makeDate(year, monthIndex, 1 - leading);\n\n const cells: Date[] = [];\n for (let i = 0; i < DAYS_IN_GRID; i += 1) {\n cells.push(makeDate(start.getFullYear(), start.getMonth(), start.getDate() + i));\n }\n return cells;\n}\n\n/**\n * Standalone month-grid date picker. Renders a header with the month/year and\n * prev/next buttons, a weekday row, and a 6x7 grid of day buttons. Selection and\n * the visible month can each be controlled or uncontrolled. Grid arithmetic uses\n * plain `Date` math — no external date libraries.\n *\n * Keyboard: arrow keys move focus by day (left/right) or week (up/down), and\n * Enter/Space selects the focused day.\n */\nexport function Calendar({\n value,\n defaultValue,\n onChange,\n month,\n onMonthChange,\n minDate,\n maxDate,\n weekStartsOn = 0,\n className,\n ...props\n}: CalendarProps) {\n const isSelectionControlled = value !== undefined;\n const [internalSelected, setInternalSelected] = useState<Date | undefined>(defaultValue);\n const selected = isSelectionControlled ? value : internalSelected;\n\n const isMonthControlled = month !== undefined;\n const [internalMonth, setInternalMonth] = useState<Date>(() => {\n const base = month ?? value ?? defaultValue ?? new Date();\n return makeDate(base.getFullYear(), base.getMonth(), 1);\n });\n const visibleMonth = isMonthControlled\n ? makeDate(month.getFullYear(), month.getMonth(), 1)\n : internalMonth;\n\n const [focusedDay, setFocusedDay] = useState<number | null>(null);\n const gridRef = useRef<HTMLDivElement | null>(null);\n\n const today = useMemo(() => startOfDay(new Date()), []);\n const cells = useMemo(\n () => buildGrid(visibleMonth, weekStartsOn),\n [visibleMonth, weekStartsOn],\n );\n\n const weekdayLabels = useMemo(() => {\n return Array.from({ length: 7 }, (_, i) => WEEKDAY_LABELS[(i + weekStartsOn) % 7]);\n }, [weekStartsOn]);\n\n const changeMonth = useCallback(\n (offset: number): void => {\n const next = makeDate(visibleMonth.getFullYear(), visibleMonth.getMonth() + offset, 1);\n if (onMonthChange) onMonthChange(next);\n if (!isMonthControlled) setInternalMonth(next);\n },\n [visibleMonth, onMonthChange, isMonthControlled],\n );\n\n const selectDate = useCallback(\n (date: Date): void => {\n if (isOutOfRange(date, minDate, maxDate)) return;\n if (onChange) onChange(date);\n if (!isSelectionControlled) setInternalSelected(date);\n },\n [minDate, maxDate, onChange, isSelectionControlled],\n );\n\n const focusCell = useCallback((index: number): void => {\n const clamped = Math.max(0, Math.min(DAYS_IN_GRID - 1, index));\n setFocusedDay(clamped);\n const grid = gridRef.current;\n if (!grid) return;\n const buttons = grid.querySelectorAll<HTMLButtonElement>(\"button[data-day]\");\n buttons[clamped]?.focus();\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number): void => {\n switch (event.key) {\n case \"ArrowLeft\":\n event.preventDefault();\n focusCell(index - 1);\n break;\n case \"ArrowRight\":\n event.preventDefault();\n focusCell(index + 1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n focusCell(index - 7);\n break;\n case \"ArrowDown\":\n event.preventDefault();\n focusCell(index + 7);\n break;\n case \"Enter\":\n case \" \":\n event.preventDefault();\n selectDate(cells[index]);\n break;\n default:\n break;\n }\n },\n [focusCell, selectDate, cells],\n );\n\n return (\n <div className={cn(styles.root, className)} {...props}>\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Previous month\"\n onClick={() => changeMonth(-1)}\n >\n {\"‹\"}\n </button>\n <span className={styles.title} aria-live=\"polite\">\n {MONTH_LABELS[visibleMonth.getMonth()]} {visibleMonth.getFullYear()}\n </span>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Next month\"\n onClick={() => changeMonth(1)}\n >\n {\"›\"}\n </button>\n </div>\n\n <div className={styles.weekdays} role=\"row\">\n {weekdayLabels.map((label) => (\n <span key={label} className={styles.weekday} role=\"columnheader\">\n {label}\n </span>\n ))}\n </div>\n\n <div className={styles.grid} role=\"grid\" ref={gridRef}>\n {cells.map((date, index) => {\n const inMonth = date.getMonth() === visibleMonth.getMonth();\n const isSelected = selected ? isSameDay(date, selected) : false;\n const isToday = isSameDay(date, today);\n const disabled = isOutOfRange(date, minDate, maxDate);\n const isFocusTarget =\n focusedDay === null\n ? inMonth && date.getDate() === 1\n : focusedDay === index;\n return (\n <button\n key={index}\n type=\"button\"\n data-day\n role=\"gridcell\"\n className={cn(\n styles.day,\n !inMonth && styles.outside,\n isSelected && styles.selected,\n isToday && styles.today,\n )}\n aria-pressed={isSelected}\n aria-selected={isSelected}\n aria-current={isToday ? \"date\" : undefined}\n disabled={disabled}\n tabIndex={isFocusTarget ? 0 : -1}\n onClick={() => selectDate(date)}\n onKeyDown={(event) => handleKeyDown(event, index)}\n >\n {date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Calendar.js","names":[],"sources":["../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — a date grid is\n * controlled two ways at once — the selected day (value, defaultValue, onChange) and\n * the visible month (month, onMonthChange) — inside the bounds (minDate, maxDate,\n * weekStartsOn). The body builds the grid and owns roving focus and keyboard\n * navigation, which read the same cursor date.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Calendar.module.css\";\n\nexport type WeekStart = 0 | 1;\n\nexport interface CalendarProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n /** Controlled selected date. */\n value?: Date;\n /** Initial selected date for the uncontrolled case. */\n defaultValue?: Date;\n /** Called with the newly selected date. */\n onChange?: (date: Date) => void;\n /** Controlled visible month (any day within it). */\n month?: Date;\n /** Called when the visible month changes (prev/next). */\n onMonthChange?: (month: Date) => void;\n /** Earliest selectable date (inclusive). */\n minDate?: Date;\n /** Latest selectable date (inclusive). */\n maxDate?: Date;\n /** First column of the week — `0` Sunday (default) or `1` Monday. */\n weekStartsOn?: WeekStart;\n}\n\nconst WEEKDAY_LABELS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst MONTH_LABELS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n];\n\nconst DAYS_IN_GRID = 42;\n\n/**\n * Build a `Date` at midnight local time for the given year/month/day.\n *\n * @param year - Full year.\n * @param month - Zero-based month index.\n * @param day - Day of the month.\n * @returns A normalized `Date`.\n */\nfunction makeDate(year: number, month: number, day: number): Date {\n return new Date(year, month, day);\n}\n\n/**\n * Strip the time portion so two dates can be compared by calendar day.\n *\n * @param date - The date to normalize.\n * @returns A new `Date` at local midnight.\n */\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/**\n * Whether two dates fall on the same calendar day.\n *\n * @param a - First date.\n * @param b - Second date.\n * @returns `true` when year, month and day match.\n */\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/**\n * Whether a date is outside the inclusive `[minDate, maxDate]` window.\n *\n * @param date - The candidate day.\n * @param minDate - Optional lower bound.\n * @param maxDate - Optional upper bound.\n * @returns `true` when the date is disabled.\n */\nfunction isOutOfRange(date: Date, minDate?: Date, maxDate?: Date): boolean {\n const day = startOfDay(date).getTime();\n if (minDate && day < startOfDay(minDate).getTime()) return true;\n if (maxDate && day > startOfDay(maxDate).getTime()) return true;\n return false;\n}\n\n/**\n * Compute the 42-cell (6x7) grid of dates covering the given month, padded with\n * leading/trailing days from the adjacent months.\n *\n * @param month - Any date within the target month.\n * @param weekStartsOn - First column of the week.\n * @returns An array of 42 `Date` objects.\n */\nfunction buildGrid(month: Date, weekStartsOn: WeekStart): Date[] {\n const year = month.getFullYear();\n const monthIndex = month.getMonth();\n const firstOfMonth = makeDate(year, monthIndex, 1);\n const firstWeekday = firstOfMonth.getDay();\n const leading = (firstWeekday - weekStartsOn + 7) % 7;\n const start = makeDate(year, monthIndex, 1 - leading);\n\n const cells: Date[] = [];\n for (let i = 0; i < DAYS_IN_GRID; i += 1) {\n cells.push(makeDate(start.getFullYear(), start.getMonth(), start.getDate() + i));\n }\n return cells;\n}\n\n/**\n * Standalone month-grid date picker. Renders a header with the month/year and\n * prev/next buttons, a weekday row, and a 6x7 grid of day buttons. Selection and\n * the visible month can each be controlled or uncontrolled. Grid arithmetic uses\n * plain `Date` math — no external date libraries.\n *\n * Keyboard: arrow keys move focus by day (left/right) or week (up/down), and\n * Enter/Space selects the focused day.\n */\nexport function Calendar({\n value,\n defaultValue,\n onChange,\n month,\n onMonthChange,\n minDate,\n maxDate,\n weekStartsOn = 0,\n className,\n ...props\n}: CalendarProps) {\n const isSelectionControlled = value !== undefined;\n const [internalSelected, setInternalSelected] = useState<Date | undefined>(defaultValue);\n const selected = isSelectionControlled ? value : internalSelected;\n\n const isMonthControlled = month !== undefined;\n const [internalMonth, setInternalMonth] = useState<Date>(() => {\n const base = month ?? value ?? defaultValue ?? new Date();\n return makeDate(base.getFullYear(), base.getMonth(), 1);\n });\n const visibleMonth = isMonthControlled\n ? makeDate(month.getFullYear(), month.getMonth(), 1)\n : internalMonth;\n\n const [focusedDay, setFocusedDay] = useState<number | null>(null);\n const gridRef = useRef<HTMLDivElement | null>(null);\n\n const today = useMemo(() => startOfDay(new Date()), []);\n const cells = useMemo(\n () => buildGrid(visibleMonth, weekStartsOn),\n [visibleMonth, weekStartsOn],\n );\n\n const weekdayLabels = useMemo(() => {\n return Array.from({ length: 7 }, (_, i) => WEEKDAY_LABELS[(i + weekStartsOn) % 7]);\n }, [weekStartsOn]);\n\n const changeMonth = useCallback(\n (offset: number): void => {\n const next = makeDate(visibleMonth.getFullYear(), visibleMonth.getMonth() + offset, 1);\n if (onMonthChange) onMonthChange(next);\n if (!isMonthControlled) setInternalMonth(next);\n },\n [visibleMonth, onMonthChange, isMonthControlled],\n );\n\n const selectDate = useCallback(\n (date: Date): void => {\n if (isOutOfRange(date, minDate, maxDate)) return;\n if (onChange) onChange(date);\n if (!isSelectionControlled) setInternalSelected(date);\n },\n [minDate, maxDate, onChange, isSelectionControlled],\n );\n\n const focusCell = useCallback((index: number): void => {\n const clamped = Math.max(0, Math.min(DAYS_IN_GRID - 1, index));\n setFocusedDay(clamped);\n const grid = gridRef.current;\n if (!grid) return;\n const buttons = grid.querySelectorAll<HTMLButtonElement>(\"button[data-day]\");\n buttons[clamped]?.focus();\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number): void => {\n switch (event.key) {\n case \"ArrowLeft\":\n event.preventDefault();\n focusCell(index - 1);\n break;\n case \"ArrowRight\":\n event.preventDefault();\n focusCell(index + 1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n focusCell(index - 7);\n break;\n case \"ArrowDown\":\n event.preventDefault();\n focusCell(index + 7);\n break;\n case \"Enter\":\n case \" \":\n event.preventDefault();\n selectDate(cells[index]);\n break;\n default:\n break;\n }\n },\n [focusCell, selectDate, cells],\n );\n\n return (\n <div className={cn(styles.root, className)} {...props}>\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Previous month\"\n onClick={() => changeMonth(-1)}\n >\n {\"‹\"}\n </button>\n <span className={styles.title} aria-live=\"polite\">\n {MONTH_LABELS[visibleMonth.getMonth()]} {visibleMonth.getFullYear()}\n </span>\n <button\n type=\"button\"\n className={styles.nav}\n aria-label=\"Next month\"\n onClick={() => changeMonth(1)}\n >\n {\"›\"}\n </button>\n </div>\n\n <div className={styles.weekdays} role=\"row\">\n {weekdayLabels.map((label) => (\n <span key={label} className={styles.weekday} role=\"columnheader\">\n {label}\n </span>\n ))}\n </div>\n\n <div className={styles.grid} role=\"grid\" ref={gridRef}>\n {cells.map((date, index) => {\n const inMonth = date.getMonth() === visibleMonth.getMonth();\n const isSelected = selected ? isSameDay(date, selected) : false;\n const isToday = isSameDay(date, today);\n const disabled = isOutOfRange(date, minDate, maxDate);\n const isFocusTarget =\n focusedDay === null\n ? inMonth && date.getDate() === 1\n : focusedDay === index;\n return (\n <button\n key={index}\n type=\"button\"\n data-day\n role=\"gridcell\"\n className={cn(\n styles.day,\n !inMonth && styles.outside,\n isSelected && styles.selected,\n isToday && styles.today,\n )}\n aria-pressed={isSelected}\n aria-selected={isSelected}\n aria-current={isToday ? \"date\" : undefined}\n disabled={disabled}\n tabIndex={isFocusTarget ? 0 : -1}\n onClick={() => selectDate(date)}\n onKeyDown={(event) => handleKeyDown(event, index)}\n >\n {date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.cjs","names":[],"sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Card.module.css\";\n\nexport type CardElevation = \"flat\" | \"default\" | \"raised\" | \"elevated\";\n\nexport interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: ReactNode;\n actions?: ReactNode;\n footer?: ReactNode;\n flush?: boolean;\n /** Hoverable card — adds elevation lift, cursor pointer and focus ring. */\n interactive?: boolean;\n /** Visual elevation level. Defaults to `default` (subtle shadow + border). */\n elevation?: CardElevation;\n}\n\n/**\n * Card container with optional header (title + actions) and footer slot.\n * Use `flush` when you need to host content (tables, lists) without inner padding.\n * Use `interactive` for clickable cards — adds hover lift and focus ring.\n */\nexport function Card({\n title,\n actions,\n footer,\n flush = false,\n interactive = false,\n elevation = \"default\",\n className,\n children,\n ...props\n}: CardProps) {\n const hasHeader = !!(title || actions);\n return (\n <div\n className={cn(\n styles.card,\n elevation === \"flat\" && styles.flat,\n elevation === \"raised\" && styles.raised,\n elevation === \"elevated\" && styles.elevated,\n interactive && styles.interactive,\n !hasHeader && !flush && styles.padded,\n flush && styles.flush,\n className,\n )}\n tabIndex={interactive ? (props.tabIndex ?? 0) : props.tabIndex}\n {...props}\n >\n {hasHeader && (\n <header className={styles.header}>\n {typeof title === \"string\" ? <h3 className={styles.title}>{title}</h3> : title}\n {actions}\n </header>\n )}\n {hasHeader ? <div className={styles.body}>{children}</div> : children}\n {footer && <footer className={styles.footer}>{footer}</footer>}\n </div>\n );\n}\n"],"mappings":"wGAsBA,SAAgB,EAAK,CACjB,QACA,UACA,SACA,QAAQ,GACR,cAAc,GACd,YAAY,UACZ,YACA,WACA,GAAG,GACO,CACV,IAAM,EAAY,CAAC,EAAE,GAAS,GAC9B,OACI,EAAA,EAAA,KAAA,CAAC,MAAD,CACI,UAAW,EAAA,GACP,EAAA,QAAO,KACP,IAAc,QAAU,EAAA,QAAO,KAC/B,IAAc,UAAY,EAAA,QAAO,OACjC,IAAc,YAAc,EAAA,QAAO,SACnC,GAAe,EAAA,QAAO,YACtB,CAAC,GAAa,CAAC,GAAS,EAAA,QAAO,OAC/B,GAAS,EAAA,QAAO,MAChB,CACJ,EACA,SAAU,EAAe,EAAM,UAAY,EAAK,EAAM,SACtD,GAAI,
|
|
1
|
+
{"version":3,"file":"Card.cjs","names":[],"sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Card.module.css\";\n\nexport type CardElevation = \"flat\" | \"default\" | \"raised\" | \"elevated\";\n\nexport interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: ReactNode;\n actions?: ReactNode;\n footer?: ReactNode;\n flush?: boolean;\n /** Hoverable card — adds elevation lift, cursor pointer and focus ring. */\n interactive?: boolean;\n /** Visual elevation level. Defaults to `default` (subtle shadow + border). */\n elevation?: CardElevation;\n}\n\n/**\n * Card container with optional header (title + actions) and footer slot.\n * Use `flush` when you need to host content (tables, lists) without inner padding.\n * Use `interactive` for clickable cards — adds hover lift and focus ring.\n */\nexport function Card({\n title,\n actions,\n footer,\n flush = false,\n interactive = false,\n elevation = \"default\",\n className,\n children,\n ...props\n}: CardProps) {\n const hasHeader = !!(title || actions);\n return (\n <div\n className={cn(\n styles.card,\n elevation === \"flat\" && styles.flat,\n elevation === \"raised\" && styles.raised,\n elevation === \"elevated\" && styles.elevated,\n interactive && styles.interactive,\n !hasHeader && !flush && styles.padded,\n flush && styles.flush,\n className,\n )}\n tabIndex={interactive ? (props.tabIndex ?? 0) : props.tabIndex}\n {...props}\n >\n {hasHeader && (\n <header className={styles.header}>\n {typeof title === \"string\" ? <h3 className={styles.title}>{title}</h3> : title}\n {actions}\n </header>\n )}\n {hasHeader ? <div className={styles.body}>{children}</div> : children}\n {footer && <footer className={styles.footer}>{footer}</footer>}\n </div>\n );\n}\n"],"mappings":"wGAsBA,SAAgB,EAAK,CACjB,QACA,UACA,SACA,QAAQ,GACR,cAAc,GACd,YAAY,UACZ,YACA,WACA,GAAG,GACO,CACV,IAAM,EAAY,CAAC,EAAE,GAAS,GAC9B,OACI,EAAA,EAAA,KAAA,CAAC,MAAD,CACI,UAAW,EAAA,GACP,EAAA,QAAO,KACP,IAAc,QAAU,EAAA,QAAO,KAC/B,IAAc,UAAY,EAAA,QAAO,OACjC,IAAc,YAAc,EAAA,QAAO,SACnC,GAAe,EAAA,QAAO,YACtB,CAAC,GAAa,CAAC,GAAS,EAAA,QAAO,OAC/B,GAAS,EAAA,QAAO,MAChB,CACJ,EACA,SAAU,EAAe,EAAM,UAAY,EAAK,EAAM,SACtD,GAAI,EAZR,SAAA,CAcK,IACG,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,UAAW,EAAA,QAAO,OAA1B,SAAA,CACK,OAAO,GAAU,UAAW,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAA,QAAO,MAAQ,SAAA,CAAU,CAAA,EAAI,EACxE,CACG,IAEX,GAAY,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,KAAO,UAAc,CAAA,EAAI,EAC5D,IAAU,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAW,EAAA,QAAO,OAAS,SAAA,CAAe,CAAA,CAC5D,GAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.js","names":[],"sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Card.module.css\";\n\nexport type CardElevation = \"flat\" | \"default\" | \"raised\" | \"elevated\";\n\nexport interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: ReactNode;\n actions?: ReactNode;\n footer?: ReactNode;\n flush?: boolean;\n /** Hoverable card — adds elevation lift, cursor pointer and focus ring. */\n interactive?: boolean;\n /** Visual elevation level. Defaults to `default` (subtle shadow + border). */\n elevation?: CardElevation;\n}\n\n/**\n * Card container with optional header (title + actions) and footer slot.\n * Use `flush` when you need to host content (tables, lists) without inner padding.\n * Use `interactive` for clickable cards — adds hover lift and focus ring.\n */\nexport function Card({\n title,\n actions,\n footer,\n flush = false,\n interactive = false,\n elevation = \"default\",\n className,\n children,\n ...props\n}: CardProps) {\n const hasHeader = !!(title || actions);\n return (\n <div\n className={cn(\n styles.card,\n elevation === \"flat\" && styles.flat,\n elevation === \"raised\" && styles.raised,\n elevation === \"elevated\" && styles.elevated,\n interactive && styles.interactive,\n !hasHeader && !flush && styles.padded,\n flush && styles.flush,\n className,\n )}\n tabIndex={interactive ? (props.tabIndex ?? 0) : props.tabIndex}\n {...props}\n >\n {hasHeader && (\n <header className={styles.header}>\n {typeof title === \"string\" ? <h3 className={styles.title}>{title}</h3> : title}\n {actions}\n </header>\n )}\n {hasHeader ? <div className={styles.body}>{children}</div> : children}\n {footer && <footer className={styles.footer}>{footer}</footer>}\n </div>\n );\n}\n"],"mappings":";;;;AAsBA,SAAgB,EAAK,EACjB,UACA,YACA,WACA,WAAQ,IACR,iBAAc,IACd,eAAY,WACZ,cACA,aACA,GAAG,KACO;CACV,IAAM,IAAY,CAAC,EAAE,KAAS;CAC9B,OACI,kBAAC,OAAD;EACI,WAAW,EACP,EAAO,MACP,MAAc,UAAU,EAAO,MAC/B,MAAc,YAAY,EAAO,QACjC,MAAc,cAAc,EAAO,UACnC,KAAe,EAAO,aACtB,CAAC,KAAa,CAAC,KAAS,EAAO,QAC/B,KAAS,EAAO,OAChB,CACJ;EACA,UAAU,IAAe,EAAM,YAAY,IAAK,EAAM;EACtD,GAAI;
|
|
1
|
+
{"version":3,"file":"Card.js","names":[],"sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Card.module.css\";\n\nexport type CardElevation = \"flat\" | \"default\" | \"raised\" | \"elevated\";\n\nexport interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: ReactNode;\n actions?: ReactNode;\n footer?: ReactNode;\n flush?: boolean;\n /** Hoverable card — adds elevation lift, cursor pointer and focus ring. */\n interactive?: boolean;\n /** Visual elevation level. Defaults to `default` (subtle shadow + border). */\n elevation?: CardElevation;\n}\n\n/**\n * Card container with optional header (title + actions) and footer slot.\n * Use `flush` when you need to host content (tables, lists) without inner padding.\n * Use `interactive` for clickable cards — adds hover lift and focus ring.\n */\nexport function Card({\n title,\n actions,\n footer,\n flush = false,\n interactive = false,\n elevation = \"default\",\n className,\n children,\n ...props\n}: CardProps) {\n const hasHeader = !!(title || actions);\n return (\n <div\n className={cn(\n styles.card,\n elevation === \"flat\" && styles.flat,\n elevation === \"raised\" && styles.raised,\n elevation === \"elevated\" && styles.elevated,\n interactive && styles.interactive,\n !hasHeader && !flush && styles.padded,\n flush && styles.flush,\n className,\n )}\n tabIndex={interactive ? (props.tabIndex ?? 0) : props.tabIndex}\n {...props}\n >\n {hasHeader && (\n <header className={styles.header}>\n {typeof title === \"string\" ? <h3 className={styles.title}>{title}</h3> : title}\n {actions}\n </header>\n )}\n {hasHeader ? <div className={styles.body}>{children}</div> : children}\n {footer && <footer className={styles.footer}>{footer}</footer>}\n </div>\n );\n}\n"],"mappings":";;;;AAsBA,SAAgB,EAAK,EACjB,UACA,YACA,WACA,WAAQ,IACR,iBAAc,IACd,eAAY,WACZ,cACA,aACA,GAAG,KACO;CACV,IAAM,IAAY,CAAC,EAAE,KAAS;CAC9B,OACI,kBAAC,OAAD;EACI,WAAW,EACP,EAAO,MACP,MAAc,UAAU,EAAO,MAC/B,MAAc,YAAY,EAAO,QACjC,MAAc,cAAc,EAAO,UACnC,KAAe,EAAO,aACtB,CAAC,KAAa,CAAC,KAAS,EAAO,QAC/B,KAAS,EAAO,OAChB,CACJ;EACA,UAAU,IAAe,EAAM,YAAY,IAAK,EAAM;EACtD,GAAI;EAZR,UAAA;GAcK,KACG,kBAAC,UAAD;IAAQ,WAAW,EAAO;IAA1B,UAAA,CACK,OAAO,KAAU,WAAW,kBAAC,MAAD;KAAI,WAAW,EAAO;KAAQ,UAAA;IAAU,CAAA,IAAI,GACxE,CACG;;GAEX,IAAY,kBAAC,OAAD;IAAK,WAAW,EAAO;IAAO;GAAc,CAAA,IAAI;GAC5D,KAAU,kBAAC,UAAD;IAAQ,WAAW,EAAO;IAAS,UAAA;GAAe,CAAA;EAC5D;;AAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Carousel.cjs","names":[],"sources":["../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["/**\n * @tempest-limits function-lines — the body owns the scroll snap position, the\n * swipe, the autoplay timer that must pause on interaction and the dot indicators\n * that read the same index.\n */\nimport { useCallback, useState } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Carousel.module.css\";\n\nexport interface CarouselProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** Slides — one rendered at a time. */\n children: ReactNode[];\n /** Wrap around at the ends instead of stopping. Default `false`. */\n loop?: boolean;\n /** Show prev/next arrow buttons. Default `true`. */\n showArrows?: boolean;\n /** Show dot indicators. Default `true`. */\n showDots?: boolean;\n /** Controlled active index. */\n index?: number;\n /** Initial index for uncontrolled use. Default `0`. */\n defaultIndex?: number;\n /** Called whenever the active index changes. */\n onIndexChange?: (index: number) => void;\n}\n\n/**\n * Horizontal content slider showing one slide at a time.\n *\n * - Track translates by the active index (`translateX(-index * 100%)`).\n * - Prev/next arrows (disabled at the ends unless `loop`); dot indicators jump.\n * - Controlled (`index`) or uncontrolled (`defaultIndex`).\n * - Arrow Left/Right on the focused region navigates.\n *\n * @example\n * <Carousel loop>\n * <img src=\"/1.jpg\" alt=\"\" />\n * <img src=\"/2.jpg\" alt=\"\" />\n * <img src=\"/3.jpg\" alt=\"\" />\n * </Carousel>\n */\nexport function Carousel({\n children,\n loop = false,\n showArrows = true,\n showDots = true,\n index,\n defaultIndex = 0,\n onIndexChange,\n className,\n ...props\n}: CarouselProps) {\n const count = children.length;\n const isControlled = index !== undefined;\n const [internalIndex, setInternalIndex] = useState<number>(defaultIndex);\n const current = isControlled ? index : internalIndex;\n\n const goTo = useCallback(\n (next: number): void => {\n let target = next;\n if (target < 0) target = loop ? count - 1 : 0;\n else if (target >= count) target = loop ? 0 : count - 1;\n if (target === current) return;\n if (!isControlled) setInternalIndex(target);\n onIndexChange?.(target);\n },\n [count, loop, current, isControlled, onIndexChange],\n );\n\n const atStart = current <= 0;\n const atEnd = current >= count - 1;\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n goTo(current + 1);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n goTo(current - 1);\n }\n };\n\n return (\n <div\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabIndex={0}\n className={cn(styles.root, className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n <div className={styles.viewport}>\n <div\n className={styles.track}\n style={{ transform: `translateX(-${current * 100}%)` }}\n >\n {children.map((slide, slideIndex) => (\n <div\n key={slideIndex}\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${slideIndex + 1} of ${count}`}\n aria-hidden={slideIndex !== current}\n className={styles.slide}\n >\n {slide}\n </div>\n ))}\n </div>\n </div>\n\n {showArrows && count > 1 && (\n <>\n <button\n type=\"button\"\n className={cn(styles.arrow, styles.prev)}\n aria-label=\"Previous slide\"\n disabled={!loop && atStart}\n onClick={() => goTo(current - 1)}\n >\n ‹\n </button>\n <button\n type=\"button\"\n className={cn(styles.arrow, styles.next)}\n aria-label=\"Next slide\"\n disabled={!loop && atEnd}\n onClick={() => goTo(current + 1)}\n >\n ›\n </button>\n </>\n )}\n\n {showDots && count > 1 && (\n <div className={styles.dots} role=\"tablist\" aria-label=\"Slides\">\n {children.map((_, dotIndex) => (\n <button\n key={dotIndex}\n type=\"button\"\n role=\"tab\"\n aria-label={`Go to slide ${dotIndex + 1}`}\n aria-selected={dotIndex === current}\n className={cn(styles.dot, dotIndex === current && styles.dotActive)}\n onClick={() => goTo(dotIndex)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"+HA0CA,SAAgB,EAAS,CACrB,WACA,OAAO,GACP,aAAa,GACb,WAAW,GACX,QACA,eAAe,EACf,gBACA,YACA,GAAG,GACW,CACd,IAAM,EAAQ,EAAS,OACjB,EAAe,IAAU,IAAA,GACzB,CAAC,EAAe,IAAA,
|
|
1
|
+
{"version":3,"file":"Carousel.cjs","names":[],"sources":["../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["/**\n * @tempest-limits function-lines — the body owns the scroll snap position, the\n * swipe, the autoplay timer that must pause on interaction and the dot indicators\n * that read the same index.\n */\nimport { useCallback, useState } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Carousel.module.css\";\n\nexport interface CarouselProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** Slides — one rendered at a time. */\n children: ReactNode[];\n /** Wrap around at the ends instead of stopping. Default `false`. */\n loop?: boolean;\n /** Show prev/next arrow buttons. Default `true`. */\n showArrows?: boolean;\n /** Show dot indicators. Default `true`. */\n showDots?: boolean;\n /** Controlled active index. */\n index?: number;\n /** Initial index for uncontrolled use. Default `0`. */\n defaultIndex?: number;\n /** Called whenever the active index changes. */\n onIndexChange?: (index: number) => void;\n}\n\n/**\n * Horizontal content slider showing one slide at a time.\n *\n * - Track translates by the active index (`translateX(-index * 100%)`).\n * - Prev/next arrows (disabled at the ends unless `loop`); dot indicators jump.\n * - Controlled (`index`) or uncontrolled (`defaultIndex`).\n * - Arrow Left/Right on the focused region navigates.\n *\n * @example\n * <Carousel loop>\n * <img src=\"/1.jpg\" alt=\"\" />\n * <img src=\"/2.jpg\" alt=\"\" />\n * <img src=\"/3.jpg\" alt=\"\" />\n * </Carousel>\n */\nexport function Carousel({\n children,\n loop = false,\n showArrows = true,\n showDots = true,\n index,\n defaultIndex = 0,\n onIndexChange,\n className,\n ...props\n}: CarouselProps) {\n const count = children.length;\n const isControlled = index !== undefined;\n const [internalIndex, setInternalIndex] = useState<number>(defaultIndex);\n const current = isControlled ? index : internalIndex;\n\n const goTo = useCallback(\n (next: number): void => {\n let target = next;\n if (target < 0) target = loop ? count - 1 : 0;\n else if (target >= count) target = loop ? 0 : count - 1;\n if (target === current) return;\n if (!isControlled) setInternalIndex(target);\n onIndexChange?.(target);\n },\n [count, loop, current, isControlled, onIndexChange],\n );\n\n const atStart = current <= 0;\n const atEnd = current >= count - 1;\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n goTo(current + 1);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n goTo(current - 1);\n }\n };\n\n return (\n <div\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabIndex={0}\n className={cn(styles.root, className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n <div className={styles.viewport}>\n <div\n className={styles.track}\n style={{ transform: `translateX(-${current * 100}%)` }}\n >\n {children.map((slide, slideIndex) => (\n <div\n key={slideIndex}\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${slideIndex + 1} of ${count}`}\n aria-hidden={slideIndex !== current}\n className={styles.slide}\n >\n {slide}\n </div>\n ))}\n </div>\n </div>\n\n {showArrows && count > 1 && (\n <>\n <button\n type=\"button\"\n className={cn(styles.arrow, styles.prev)}\n aria-label=\"Previous slide\"\n disabled={!loop && atStart}\n onClick={() => goTo(current - 1)}\n >\n ‹\n </button>\n <button\n type=\"button\"\n className={cn(styles.arrow, styles.next)}\n aria-label=\"Next slide\"\n disabled={!loop && atEnd}\n onClick={() => goTo(current + 1)}\n >\n ›\n </button>\n </>\n )}\n\n {showDots && count > 1 && (\n <div className={styles.dots} role=\"tablist\" aria-label=\"Slides\">\n {children.map((_, dotIndex) => (\n <button\n key={dotIndex}\n type=\"button\"\n role=\"tab\"\n aria-label={`Go to slide ${dotIndex + 1}`}\n aria-selected={dotIndex === current}\n className={cn(styles.dot, dotIndex === current && styles.dotActive)}\n onClick={() => goTo(dotIndex)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"+HA0CA,SAAgB,EAAS,CACrB,WACA,OAAO,GACP,aAAa,GACb,WAAW,GACX,QACA,eAAe,EACf,gBACA,YACA,GAAG,GACW,CACd,IAAM,EAAQ,EAAS,OACjB,EAAe,IAAU,IAAA,GACzB,CAAC,EAAe,IAAA,EAAoB,EAAA,SAAA,CAAiB,CAAY,EACjE,EAAU,EAAe,EAAQ,EAEjC,GAAA,EAAO,EAAA,YAAA,CACR,GAAuB,CACpB,IAAI,EAAS,EACT,EAAS,EAAG,EAAS,EAAO,EAAQ,EAAI,EACnC,GAAU,IAAO,EAAS,EAAO,EAAI,EAAQ,GAClD,IAAW,IACV,GAAc,EAAiB,CAAM,EAC1C,IAAgB,CAAM,EAC1B,EACA,CAAC,EAAO,EAAM,EAAS,EAAc,CAAa,CACtD,EAEM,EAAU,GAAW,EACrB,EAAQ,GAAW,EAAQ,EAYjC,OACI,EAAA,EAAA,KAAA,CAAC,MAAD,CACI,KAAK,SACL,uBAAqB,WACrB,SAAU,EACV,UAAW,EAAA,GAAG,EAAA,QAAO,KAAM,CAAS,EACpC,UAhBe,GAAqD,CACpE,EAAM,MAAQ,cACd,EAAM,eAAe,EACrB,EAAK,EAAU,CAAC,GACT,EAAM,MAAQ,cACrB,EAAM,eAAe,EACrB,EAAK,EAAU,CAAC,EAExB,EASQ,GAAI,EANR,SAAA,EAQI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,SACnB,UAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,UAAW,EAAA,QAAO,MAClB,MAAO,CAAE,UAAW,eAAe,EAAU,IAAI,GAAI,EAEpD,SAAA,EAAS,KAAK,EAAO,KAClB,EAAA,EAAA,IAAA,CAAC,MAAD,CAEI,KAAK,QACL,uBAAqB,QACrB,aAAY,GAAG,EAAa,EAAE,MAAM,IACpC,cAAa,IAAe,EAC5B,UAAW,EAAA,QAAO,MAEjB,SAAA,CACA,EARI,CAQJ,CACR,CACA,CAAA,CACJ,CAAA,EAEJ,GAAc,EAAQ,IACnB,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACI,EAAA,EAAA,IAAA,CAAC,SAAD,CACI,KAAK,SACL,UAAW,EAAA,GAAG,EAAA,QAAO,MAAO,EAAA,QAAO,IAAI,EACvC,aAAW,iBACX,SAAU,CAAC,GAAQ,EACnB,YAAe,EAAK,EAAU,CAAC,EAClC,SAAA,GAEO,CAAA,GACR,EAAA,EAAA,IAAA,CAAC,SAAD,CACI,KAAK,SACL,UAAW,EAAA,GAAG,EAAA,QAAO,MAAO,EAAA,QAAO,IAAI,EACvC,aAAW,aACX,SAAU,CAAC,GAAQ,EACnB,YAAe,EAAK,EAAU,CAAC,EAClC,SAAA,GAEO,CAAA,CACV,CAAA,CAAA,EAGL,GAAY,EAAQ,IACjB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,KAAM,KAAK,UAAU,aAAW,SAClD,SAAA,EAAS,KAAK,EAAG,KACd,EAAA,EAAA,IAAA,CAAC,SAAD,CAEI,KAAK,SACL,KAAK,MACL,aAAY,eAAe,EAAW,IACtC,gBAAe,IAAa,EAC5B,UAAW,EAAA,GAAG,EAAA,QAAO,IAAK,IAAa,GAAW,EAAA,QAAO,SAAS,EAClE,YAAe,EAAK,CAAQ,CAC/B,EAPQ,CAOR,CACJ,CACA,CAAA,CAER,GAEb"}
|