tempest-react-sdk 0.53.0 → 0.55.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/README.md +27 -6
- package/dist/access/Can.cjs +1 -1
- package/dist/access/Can.cjs.map +1 -1
- package/dist/access/Can.js +3 -3
- package/dist/access/Can.js.map +1 -1
- package/dist/audio/level-meter.cjs +1 -1
- package/dist/audio/level-meter.cjs.map +1 -1
- package/dist/audio/level-meter.js +15 -15
- package/dist/audio/level-meter.js.map +1 -1
- package/dist/audio/noise-floor.cjs +2 -0
- package/dist/audio/noise-floor.cjs.map +1 -0
- package/dist/audio/noise-floor.js +27 -0
- package/dist/audio/noise-floor.js.map +1 -0
- package/dist/audio/voice-activity.cjs +2 -0
- package/dist/audio/voice-activity.cjs.map +1 -0
- package/dist/audio/voice-activity.js +26 -0
- package/dist/audio/voice-activity.js.map +1 -0
- package/dist/audio/voice-chain-stages.cjs +2 -0
- package/dist/audio/voice-chain-stages.cjs.map +1 -0
- package/dist/audio/voice-chain-stages.js +82 -0
- package/dist/audio/voice-chain-stages.js.map +1 -0
- package/dist/audio/voice-chain.cjs +2 -0
- package/dist/audio/voice-chain.cjs.map +1 -0
- package/dist/audio/voice-chain.js +74 -0
- package/dist/audio/voice-chain.js.map +1 -0
- package/dist/auth/lazy-with-retry.cjs.map +1 -1
- package/dist/auth/lazy-with-retry.js.map +1 -1
- package/dist/auth/passkey.cjs.map +1 -1
- package/dist/auth/passkey.js.map +1 -1
- package/dist/br/BrazilStateCitySelect.cjs +1 -1
- package/dist/br/BrazilStateCitySelect.cjs.map +1 -1
- package/dist/br/BrazilStateCitySelect.js +36 -28
- package/dist/br/BrazilStateCitySelect.js.map +1 -1
- package/dist/br/data/br-centroids.cjs +1 -1
- package/dist/br/data/br-centroids.cjs.map +1 -1
- package/dist/br/data/br-centroids.js +11105 -11045
- package/dist/br/data/br-centroids.js.map +1 -1
- package/dist/br/data/br-locations.cjs +1 -1
- package/dist/br/data/br-locations.cjs.map +1 -1
- package/dist/br/data/br-locations.js +5803 -137
- package/dist/br/data/br-locations.js.map +1 -1
- package/dist/br/data/br-uf-geo.cjs +1 -1
- package/dist/br/data/br-uf-geo.cjs.map +1 -1
- package/dist/br/data/br-uf-geo.js +5721 -6777
- package/dist/br/data/br-uf-geo.js.map +1 -1
- package/dist/br/data/mun/AC.cjs +1 -1
- package/dist/br/data/mun/AC.cjs.map +1 -1
- package/dist/br/data/mun/AC.js +681 -689
- package/dist/br/data/mun/AC.js.map +1 -1
- package/dist/br/data/mun/AL.cjs +1 -1
- package/dist/br/data/mun/AL.cjs.map +1 -1
- package/dist/br/data/mun/AL.js +949 -844
- package/dist/br/data/mun/AL.js.map +1 -1
- package/dist/br/data/mun/AM.cjs +1 -1
- package/dist/br/data/mun/AM.cjs.map +1 -1
- package/dist/br/data/mun/AM.js +4337 -4218
- package/dist/br/data/mun/AM.js.map +1 -1
- package/dist/br/data/mun/AP.cjs +1 -1
- package/dist/br/data/mun/AP.cjs.map +1 -1
- package/dist/br/data/mun/AP.js +786 -780
- package/dist/br/data/mun/AP.js.map +1 -1
- package/dist/br/data/mun/BA.cjs +1 -1
- package/dist/br/data/mun/BA.cjs.map +1 -1
- package/dist/br/data/mun/BA.js +6329 -5633
- package/dist/br/data/mun/BA.js.map +1 -1
- package/dist/br/data/mun/CE.cjs +1 -1
- package/dist/br/data/mun/CE.cjs.map +1 -1
- package/dist/br/data/mun/CE.js +2544 -2487
- package/dist/br/data/mun/CE.js.map +1 -1
- package/dist/br/data/mun/DF.cjs +1 -1
- package/dist/br/data/mun/DF.cjs.map +1 -1
- package/dist/br/data/mun/DF.js +17 -16
- package/dist/br/data/mun/DF.js.map +1 -1
- package/dist/br/data/mun/ES.cjs +1 -1
- package/dist/br/data/mun/ES.cjs.map +1 -1
- package/dist/br/data/mun/ES.js +1101 -1070
- package/dist/br/data/mun/ES.js.map +1 -1
- package/dist/br/data/mun/GO.cjs +1 -1
- package/dist/br/data/mun/GO.cjs.map +1 -1
- package/dist/br/data/mun/GO.js +4632 -4636
- package/dist/br/data/mun/GO.js.map +1 -1
- package/dist/br/data/mun/MA.cjs +1 -1
- package/dist/br/data/mun/MA.cjs.map +1 -1
- package/dist/br/data/mun/MA.js +3603 -3457
- package/dist/br/data/mun/MA.js.map +1 -1
- package/dist/br/data/mun/MG.cjs +1 -1
- package/dist/br/data/mun/MG.cjs.map +1 -1
- package/dist/br/data/mun/MG.js +12716 -11739
- package/dist/br/data/mun/MG.js.map +1 -1
- package/dist/br/data/mun/MS.cjs +1 -1
- package/dist/br/data/mun/MS.cjs.map +1 -1
- package/dist/br/data/mun/MS.js +2182 -2335
- package/dist/br/data/mun/MS.js.map +1 -1
- package/dist/br/data/mun/MT.cjs +1 -1
- package/dist/br/data/mun/MT.cjs.map +1 -1
- package/dist/br/data/mun/MT.js +4808 -4896
- package/dist/br/data/mun/MT.js.map +1 -1
- package/dist/br/data/mun/PA.cjs +1 -1
- package/dist/br/data/mun/PA.cjs.map +1 -1
- package/dist/br/data/mun/PA.js +4981 -4901
- package/dist/br/data/mun/PA.js.map +1 -1
- package/dist/br/data/mun/PB.cjs +1 -1
- package/dist/br/data/mun/PB.cjs.map +1 -1
- package/dist/br/data/mun/PB.js +2418 -1956
- package/dist/br/data/mun/PB.js.map +1 -1
- package/dist/br/data/mun/PE.cjs +1 -1
- package/dist/br/data/mun/PE.cjs.map +1 -1
- package/dist/br/data/mun/PE.js +2164 -1987
- package/dist/br/data/mun/PE.js.map +1 -1
- package/dist/br/data/mun/PI.cjs +1 -1
- package/dist/br/data/mun/PI.cjs.map +1 -1
- package/dist/br/data/mun/PI.js +2982 -2844
- package/dist/br/data/mun/PI.js.map +1 -1
- package/dist/br/data/mun/PR.cjs +1 -1
- package/dist/br/data/mun/PR.cjs.map +1 -1
- package/dist/br/data/mun/PR.js +5425 -5240
- package/dist/br/data/mun/PR.js.map +1 -1
- package/dist/br/data/mun/RJ.cjs +1 -1
- package/dist/br/data/mun/RJ.cjs.map +1 -1
- package/dist/br/data/mun/RJ.js +1395 -1178
- package/dist/br/data/mun/RJ.js.map +1 -1
- package/dist/br/data/mun/RN.cjs +1 -1
- package/dist/br/data/mun/RN.cjs.map +1 -1
- package/dist/br/data/mun/RN.js +1608 -1382
- package/dist/br/data/mun/RN.js.map +1 -1
- package/dist/br/data/mun/RO.cjs +1 -1
- package/dist/br/data/mun/RO.cjs.map +1 -1
- package/dist/br/data/mun/RO.js +1392 -1470
- package/dist/br/data/mun/RO.js.map +1 -1
- package/dist/br/data/mun/RR.cjs +1 -1
- package/dist/br/data/mun/RR.cjs.map +1 -1
- package/dist/br/data/mun/RR.js +795 -778
- package/dist/br/data/mun/RR.js.map +1 -1
- package/dist/br/data/mun/RS.cjs +1 -1
- package/dist/br/data/mun/RS.cjs.map +1 -1
- package/dist/br/data/mun/RS.js +7579 -6424
- package/dist/br/data/mun/RS.js.map +1 -1
- package/dist/br/data/mun/SC.cjs +1 -1
- package/dist/br/data/mun/SC.cjs.map +1 -1
- package/dist/br/data/mun/SC.js +3979 -3357
- package/dist/br/data/mun/SC.js.map +1 -1
- package/dist/br/data/mun/SE.cjs +1 -1
- package/dist/br/data/mun/SE.cjs.map +1 -1
- package/dist/br/data/mun/SE.js +812 -625
- package/dist/br/data/mun/SE.js.map +1 -1
- package/dist/br/data/mun/SP.cjs +1 -1
- package/dist/br/data/mun/SP.cjs.map +1 -1
- package/dist/br/data/mun/SP.js +7866 -6803
- package/dist/br/data/mun/SP.js.map +1 -1
- package/dist/br/data/mun/TO.cjs +1 -1
- package/dist/br/data/mun/TO.cjs.map +1 -1
- package/dist/br/data/mun/TO.js +2763 -2817
- package/dist/br/data/mun/TO.js.map +1 -1
- package/dist/br/locations.cjs +1 -1
- package/dist/br/locations.cjs.map +1 -1
- package/dist/br/locations.js +97 -24
- package/dist/br/locations.js.map +1 -1
- package/dist/br/scales.cjs +1 -1
- package/dist/br/scales.cjs.map +1 -1
- package/dist/br/scales.js +8 -4
- package/dist/br/scales.js.map +1 -1
- package/dist/br/whatsapp.cjs +2 -0
- package/dist/br/whatsapp.cjs.map +1 -0
- package/dist/br/whatsapp.js +21 -0
- package/dist/br/whatsapp.js.map +1 -0
- package/dist/br.cjs +1 -1
- package/dist/br.cjs.map +1 -1
- package/dist/br.d.ts +188 -10
- package/dist/br.js +18 -17
- package/dist/br.js.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.cjs +1 -1
- package/dist/components/BottomSheet/BottomSheet.cjs.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.js +30 -27
- package/dist/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/components/Command/Command.cjs +1 -1
- package/dist/components/Command/Command.cjs.map +1 -1
- package/dist/components/Command/Command.js +78 -75
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/Drawer/Drawer.cjs +1 -1
- package/dist/components/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.js +42 -39
- package/dist/components/Drawer/Drawer.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.cjs +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +111 -67
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/Modal/Modal.cjs +1 -1
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.js +45 -42
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Money/Money.cjs +1 -1
- package/dist/components/Money/Money.cjs.map +1 -1
- package/dist/components/Money/Money.js +10 -9
- package/dist/components/Money/Money.js.map +1 -1
- package/dist/components/Pagination/Pagination.cjs +1 -1
- package/dist/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/components/Pagination/Pagination.js +38 -31
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Pagination/Pagination.module.cjs +1 -1
- package/dist/components/Pagination/Pagination.module.cjs.map +1 -1
- package/dist/components/Pagination/Pagination.module.js +4 -4
- package/dist/components/Pagination/Pagination.module.js.map +1 -1
- package/dist/components/Portal/Portal.cjs +1 -1
- package/dist/components/Portal/Portal.cjs.map +1 -1
- package/dist/components/Portal/Portal.js +9 -6
- package/dist/components/Portal/Portal.js.map +1 -1
- package/dist/components/Portal/portal-host.cjs +2 -0
- package/dist/components/Portal/portal-host.cjs.map +1 -0
- package/dist/components/Portal/portal-host.js +11 -0
- package/dist/components/Portal/portal-host.js.map +1 -0
- package/dist/components/Scheduler/Scheduler.cjs +1 -1
- package/dist/components/Scheduler/Scheduler.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.js +83 -82
- package/dist/components/Scheduler/Scheduler.js.map +1 -1
- package/dist/components/Toast/ToastProvider.cjs +1 -1
- package/dist/components/Toast/ToastProvider.cjs.map +1 -1
- package/dist/components/Toast/ToastProvider.js +55 -53
- package/dist/components/Toast/ToastProvider.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.cjs +1 -1
- package/dist/components/VirtualList/VirtualList.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.js +41 -31
- package/dist/components/VirtualList/VirtualList.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.js +78 -68
- package/dist/components/VirtualTable/VirtualTable.js.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 +20 -19
- package/dist/forms/masked-inputs.js.map +1 -1
- package/dist/hooks/use-fullscreen-element.cjs +2 -0
- package/dist/hooks/use-fullscreen-element.cjs.map +1 -0
- package/dist/hooks/use-fullscreen-element.js +20 -0
- package/dist/hooks/use-fullscreen-element.js.map +1 -0
- package/dist/hooks/use-fullscreen.cjs +2 -0
- package/dist/hooks/use-fullscreen.cjs.map +1 -0
- package/dist/hooks/use-fullscreen.js +66 -0
- package/dist/hooks/use-fullscreen.js.map +1 -0
- package/dist/hooks/use-push-to-talk.cjs +2 -0
- package/dist/hooks/use-push-to-talk.cjs.map +1 -0
- package/dist/hooks/use-push-to-talk.js +61 -0
- package/dist/hooks/use-push-to-talk.js.map +1 -0
- package/dist/http/describe-api-error.cjs.map +1 -1
- package/dist/http/describe-api-error.js.map +1 -1
- package/dist/http/errors.cjs +1 -1
- package/dist/http/errors.cjs.map +1 -1
- package/dist/http/errors.js +34 -16
- package/dist/http/errors.js.map +1 -1
- package/dist/http/parse-response.cjs +2 -2
- package/dist/http/parse-response.cjs.map +1 -1
- package/dist/http/parse-response.js +9 -8
- package/dist/http/parse-response.js.map +1 -1
- package/dist/i18n/create-i18n.cjs +1 -1
- package/dist/i18n/create-i18n.cjs.map +1 -1
- package/dist/i18n/create-i18n.js +28 -27
- package/dist/i18n/create-i18n.js.map +1 -1
- package/dist/router/AppRouter.cjs +1 -1
- package/dist/router/AppRouter.cjs.map +1 -1
- package/dist/router/AppRouter.js +28 -21
- package/dist/router/AppRouter.js.map +1 -1
- package/dist/router/RouteGuard.cjs +1 -1
- package/dist/router/RouteGuard.cjs.map +1 -1
- package/dist/router/RouteGuard.js +4 -4
- package/dist/router/RouteGuard.js.map +1 -1
- package/dist/sse/create-event-stream.cjs +1 -1
- package/dist/sse/create-event-stream.cjs.map +1 -1
- package/dist/sse/create-event-stream.js +34 -38
- package/dist/sse/create-event-stream.js.map +1 -1
- package/dist/styles/AIChat.css +79 -0
- package/dist/styles/Accordion.css +12 -0
- package/dist/styles/Alert.css +32 -0
- package/dist/styles/AppBar.css +17 -0
- package/dist/styles/AppShell.css +8 -0
- package/dist/styles/AspectRatio.css +3 -0
- package/dist/styles/AudioPlayer.css +13 -0
- package/dist/styles/AudioRecorder.css +20 -0
- package/dist/styles/Avatar.css +13 -0
- package/dist/styles/AvatarGroup.css +18 -0
- package/dist/styles/Badge.css +25 -0
- package/dist/styles/Banner.css +13 -0
- package/dist/styles/BarList.css +10 -0
- package/dist/styles/BarcodeScanner.css +21 -0
- package/dist/styles/BottomNavigation.css +10 -0
- package/dist/styles/BottomSheet.css +11 -0
- package/dist/styles/BrazilMap.css +20 -0
- package/dist/styles/Breadcrumbs.css +8 -0
- package/dist/styles/Button.css +42 -0
- package/dist/styles/Calendar.css +16 -0
- package/dist/styles/Card.css +15 -0
- package/dist/styles/Carousel.css +17 -0
- package/dist/styles/Center.css +5 -0
- package/dist/styles/Chat.css +35 -0
- package/dist/styles/Checkbox.css +11 -0
- package/dist/styles/ChipInput.css +13 -0
- package/dist/styles/CodeBlock.css +25 -0
- package/dist/styles/Collapsible.css +6 -0
- package/dist/styles/Combobox.css +18 -0
- package/dist/styles/Command.css +20 -0
- package/dist/styles/ContextMenu.css +11 -0
- package/dist/styles/CopyButton.css +4 -0
- package/dist/styles/DataList.css +3 -0
- package/dist/styles/DataTable.css +19 -0
- package/dist/styles/DateRangePicker.css +22 -0
- package/dist/styles/DescriptionList.css +4 -0
- package/dist/styles/Divider.css +11 -0
- package/dist/styles/Drawer.css +22 -0
- package/dist/styles/DropdownMenu.css +16 -0
- package/dist/styles/Dropzone.css +7 -0
- package/dist/styles/EmptyState.css +6 -0
- package/dist/styles/ErrorState.css +6 -0
- package/dist/styles/ErrorText.css +2 -0
- package/dist/styles/FileUpload.css +17 -0
- package/dist/styles/FilterBar.css +19 -0
- package/dist/styles/FloatingActionButton.css +23 -0
- package/dist/styles/Form.css +21 -0
- package/dist/styles/HoverCard.css +11 -0
- package/dist/styles/IconPicker.css +6 -0
- package/dist/styles/Image.css +2 -0
- package/dist/styles/ImageCropper.css +16 -0
- package/dist/styles/Input.css +24 -0
- package/dist/styles/InstallBanner.css +8 -0
- package/dist/styles/Kanban.css +15 -0
- package/dist/styles/Kbd.css +5 -0
- package/dist/styles/Label.css +3 -0
- package/dist/styles/Layout.css +22 -0
- package/dist/styles/Lightbox.css +21 -0
- package/dist/styles/ListTile.css +14 -0
- package/dist/styles/MapLegend.css +9 -0
- package/dist/styles/Markdown.css +24 -0
- package/dist/styles/Masonry.css +4 -0
- package/dist/styles/Menubar.css +17 -0
- package/dist/styles/Modal.css +21 -0
- package/dist/styles/ModalsManager.css +2 -0
- package/dist/styles/MultiSelect.css +21 -0
- package/dist/styles/MunicipalitySearch.css +6 -0
- package/dist/styles/NProgress.css +2 -0
- package/dist/styles/Navbar.css +10 -0
- package/dist/styles/NavigationMenu.css +12 -0
- package/dist/styles/NavigationRail.css +14 -0
- package/dist/styles/NotificationCenter.css +21 -0
- package/dist/styles/OfflineIndicator.css +7 -0
- package/dist/styles/Page.css +13 -0
- package/dist/styles/Pagination.css +12 -0
- package/dist/styles/PasswordInput.css +21 -0
- package/dist/styles/PinInput.css +13 -0
- package/dist/styles/PixQRCode.css +9 -0
- package/dist/styles/Popover.css +10 -0
- package/dist/styles/Progress.css +11 -0
- package/dist/styles/QRCode.css +3 -0
- package/dist/styles/Radio.css +14 -0
- package/dist/styles/RangeSlider.css +15 -0
- package/dist/styles/RatingStars.css +11 -0
- package/dist/styles/RefreshIndicator.css +5 -0
- package/dist/styles/Resizable.css +13 -0
- package/dist/styles/RichTextEditor.css +19 -0
- package/dist/styles/SafeArea.css +7 -0
- package/dist/styles/Scheduler.css +24 -0
- package/dist/styles/ScrollArea.css +7 -0
- package/dist/styles/SearchBar.css +11 -0
- package/dist/styles/SegmentedControl.css +12 -0
- package/dist/styles/Select.css +14 -0
- package/dist/styles/Sidebar.css +19 -0
- package/dist/styles/SignaturePad.css +6 -0
- package/dist/styles/Skeleton.css +7 -0
- package/dist/styles/Slider.css +15 -0
- package/dist/styles/Spacer.css +4 -0
- package/dist/styles/Sparkline.css +4 -0
- package/dist/styles/Spinner.css +12 -0
- package/dist/styles/Stat.css +12 -0
- package/dist/styles/Stepper.css +17 -0
- package/dist/styles/StepperInput.css +15 -0
- package/dist/styles/Switch.css +11 -0
- package/dist/styles/SyncStatusBadge.css +13 -0
- package/dist/styles/Table.css +16 -0
- package/dist/styles/Tabs.css +14 -0
- package/dist/styles/Tag.css +14 -0
- package/dist/styles/Textarea.css +13 -0
- package/dist/styles/TimePicker.css +14 -0
- package/dist/styles/Timeline.css +17 -0
- package/dist/styles/Toast.css +21 -0
- package/dist/styles/Toggle.css +12 -0
- package/dist/styles/ToggleGroup.css +9 -0
- package/dist/styles/Tooltip.css +10 -0
- package/dist/styles/Tour.css +20 -0
- package/dist/styles/TrajectoryMap.css +16 -0
- package/dist/styles/Transfer.css +21 -0
- package/dist/styles/TreeView.css +17 -0
- package/dist/styles/TruncateText.css +2 -0
- package/dist/styles/UpdatePrompt.css +10 -0
- package/dist/styles/VirtualList.css +5 -0
- package/dist/styles/VirtualTable.css +17 -0
- package/dist/styles/VisuallyHidden.css +2 -0
- package/dist/styles/Wizard.css +4 -0
- package/dist/styles/actions.css +104 -0
- package/dist/styles/advanced.css +66 -0
- package/dist/styles/br.css +41 -0
- package/dist/styles/chat.css +113 -0
- package/dist/styles/core.css +40 -0
- package/dist/styles/data.css +222 -0
- package/dist/styles/editor.css +19 -0
- package/dist/styles/feedback.css +201 -0
- package/dist/styles/forms.css +321 -0
- package/dist/styles/geo.css +16 -0
- package/dist/styles/icons.css +6 -0
- package/dist/styles/identity.css +48 -0
- package/dist/styles/layout.css +122 -0
- package/dist/styles/media.css +52 -0
- package/dist/styles/navigation.css +167 -0
- package/dist/styles/overlay.css +73 -0
- package/dist/styles/utility.css +39 -0
- package/dist/styles.css +1 -1
- package/dist/sw/register-service-worker.cjs +1 -1
- package/dist/sw/register-service-worker.cjs.map +1 -1
- package/dist/sw/register-service-worker.js +21 -17
- package/dist/sw/register-service-worker.js.map +1 -1
- package/dist/sw.d.ts +17 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +1151 -41
- package/dist/tempest-react-sdk.js +295 -286
- package/dist/utils/dev-mode.cjs.map +1 -1
- package/dist/utils/dev-mode.js.map +1 -1
- package/dist/utils/format.cjs +1 -1
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.js +22 -14
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/intl-cache.cjs +2 -0
- package/dist/utils/intl-cache.cjs.map +1 -0
- package/dist/utils/intl-cache.js +23 -0
- package/dist/utils/intl-cache.js.map +1 -0
- package/dist/utils/json-frame.cjs +2 -0
- package/dist/utils/json-frame.cjs.map +1 -0
- package/dist/utils/json-frame.js +30 -0
- package/dist/utils/json-frame.js.map +1 -0
- package/dist/utils/numbers.cjs +1 -1
- package/dist/utils/numbers.cjs.map +1 -1
- package/dist/utils/numbers.js +8 -7
- package/dist/utils/numbers.js.map +1 -1
- package/dist/vision/results.cjs +1 -1
- package/dist/vision/results.cjs.map +1 -1
- package/dist/vision/results.js +26 -17
- package/dist/vision/results.js.map +1 -1
- package/dist/vision.d.ts +29 -0
- package/dist/vite/tempest-icons.cjs +1 -1
- package/dist/vite/tempest-icons.cjs.map +1 -1
- package/dist/vite/tempest-icons.js +1 -1
- package/dist/vite/tempest-icons.js.map +1 -1
- package/dist/webrtc/link-stats.cjs +2 -0
- package/dist/webrtc/link-stats.cjs.map +1 -0
- package/dist/webrtc/link-stats.js +74 -0
- package/dist/webrtc/link-stats.js.map +1 -0
- package/dist/webrtc/mesh-quality.cjs +2 -0
- package/dist/webrtc/mesh-quality.cjs.map +1 -0
- package/dist/webrtc/mesh-quality.js +51 -0
- package/dist/webrtc/mesh-quality.js.map +1 -0
- package/dist/webrtc/peer-link.cjs +2 -0
- package/dist/webrtc/peer-link.cjs.map +1 -0
- package/dist/webrtc/peer-link.js +45 -0
- package/dist/webrtc/peer-link.js.map +1 -0
- package/dist/webrtc/peer-mesh.cjs +2 -0
- package/dist/webrtc/peer-mesh.cjs.map +1 -0
- package/dist/webrtc/peer-mesh.js +155 -0
- package/dist/webrtc/peer-mesh.js.map +1 -0
- package/dist/webrtc/use-link-stats.cjs +2 -0
- package/dist/webrtc/use-link-stats.cjs.map +1 -0
- package/dist/webrtc/use-link-stats.js +22 -0
- package/dist/webrtc/use-link-stats.js.map +1 -0
- package/dist/ws/create-web-socket.cjs +1 -1
- package/dist/ws/create-web-socket.cjs.map +1 -1
- package/dist/ws/create-web-socket.js +81 -85
- package/dist/ws/create-web-socket.js.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 +42 -48
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +5 -2
package/dist/br.d.ts
CHANGED
|
@@ -22,6 +22,18 @@ import { ReactNode } from 'react';
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function addBusinessDays(date: DateInput, days: number, options?: BusinessDayOptions): Date;
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Administrative regions of a federative unit.
|
|
27
|
+
*
|
|
28
|
+
* Only the Federal District has any — 35 of them, inside its single
|
|
29
|
+
* municipality. Every other UF answers `[]`, which is a valid result and not an
|
|
30
|
+
* error.
|
|
31
|
+
*
|
|
32
|
+
* @param uf - Federative unit acronym, case-insensitive.
|
|
33
|
+
* @returns The regions, alphabetically. Empty outside the DF.
|
|
34
|
+
*/
|
|
35
|
+
export declare function administrativeRegionsByUf(uf: string): readonly BrazilAdministrativeRegion[];
|
|
36
|
+
|
|
25
37
|
/** What the two parsers return. Narrow on `kind`. */
|
|
26
38
|
export declare type Boleto = BoletoBanco | BoletoArrecadacao;
|
|
27
39
|
|
|
@@ -167,6 +179,23 @@ export declare interface BoletoOptions {
|
|
|
167
179
|
reference?: Date;
|
|
168
180
|
}
|
|
169
181
|
|
|
182
|
+
/**
|
|
183
|
+
* An administrative region of the Federal District.
|
|
184
|
+
*
|
|
185
|
+
* The DF has exactly one municipality — Brasília — and 35 administrative
|
|
186
|
+
* regions inside it. Nobody in the DF writes "Brasília" in an address field,
|
|
187
|
+
* so the regions are listed and resolvable; they are not municipalities, and
|
|
188
|
+
* `municipalityId` is what they geocode through.
|
|
189
|
+
*/
|
|
190
|
+
export declare interface BrazilAdministrativeRegion {
|
|
191
|
+
/** IBGE subdistrict code, e.g. `"53001080515"` for Ceilândia. */
|
|
192
|
+
id: string;
|
|
193
|
+
/** IBGE name, e.g. `"Sudoeste/Octogonal"`. */
|
|
194
|
+
name: string;
|
|
195
|
+
/** The municipality it belongs to — Brasília (`"5300108"`) for all 35. */
|
|
196
|
+
municipalityId: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
170
199
|
/**
|
|
171
200
|
* Clickable choropleth map of Brazil's 27 federative units. Renders the bundled
|
|
172
201
|
* simplified UF GeoJSON as SVG paths — **no external tiles or paid API**. Click
|
|
@@ -241,6 +270,14 @@ export declare interface BrazilMapTooltipData {
|
|
|
241
270
|
value?: number;
|
|
242
271
|
}
|
|
243
272
|
|
|
273
|
+
/** A municipality, identified by the code that survives its renames. */
|
|
274
|
+
export declare interface BrazilMunicipality {
|
|
275
|
+
/** 7-digit IBGE code, e.g. `"3550308"`. Stable across a rename. */
|
|
276
|
+
id: string;
|
|
277
|
+
/** Current IBGE name, e.g. `"São Paulo"`. */
|
|
278
|
+
name: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
244
281
|
/** A federative unit with its display name and city list. */
|
|
245
282
|
export declare interface BrazilState {
|
|
246
283
|
/** Two-letter acronym, e.g. `"SP"`. */
|
|
@@ -249,19 +286,14 @@ export declare interface BrazilState {
|
|
|
249
286
|
name: string;
|
|
250
287
|
/** Macro-region the state belongs to. */
|
|
251
288
|
region: BrRegion;
|
|
252
|
-
/**
|
|
289
|
+
/** Municipality names within the state, alphabetically. */
|
|
253
290
|
cities: string[];
|
|
291
|
+
/** The same municipalities carrying their IBGE codes, same order. */
|
|
292
|
+
municipalities: readonly BrazilMunicipality[];
|
|
293
|
+
/** Administrative regions — 35 for `"DF"`, empty everywhere else. */
|
|
294
|
+
administrativeRegions: readonly BrazilAdministrativeRegion[];
|
|
254
295
|
}
|
|
255
296
|
|
|
256
|
-
/**
|
|
257
|
-
* Cascading Estado → Cidade selector backed by the bundled BR locations data —
|
|
258
|
-
* pick a state and the city list narrows to that UF's municipalities. No
|
|
259
|
-
* network, no external API. Complements {@link BrazilMap} (wire the map's
|
|
260
|
-
* `onSelect` to drive the same UF).
|
|
261
|
-
*
|
|
262
|
-
* @example
|
|
263
|
-
* <BrazilStateCitySelect onChange={({ uf, city }) => console.log(uf, city)} />
|
|
264
|
-
*/
|
|
265
297
|
export declare function BrazilStateCitySelect({ defaultUf, defaultCity, onChange, stateLabel, cityLabel, statePlaceholder, cityPlaceholder, disabled, layout, }: BrazilStateCitySelectProps): ReactElement;
|
|
266
298
|
|
|
267
299
|
/** Current selection emitted by {@link BrazilStateCitySelect}. */
|
|
@@ -270,6 +302,15 @@ export declare interface BrazilStateCitySelection {
|
|
|
270
302
|
uf: UF | null;
|
|
271
303
|
/** Selected city, or `null` when none. */
|
|
272
304
|
city: string | null;
|
|
305
|
+
/**
|
|
306
|
+
* IBGE code of the selected municipality, or `null` when none is selected.
|
|
307
|
+
*
|
|
308
|
+
* This is the value to store. It survives the renames `city` does not, and
|
|
309
|
+
* it is what `geocodeMunicipality` and every other dataset here join on. A
|
|
310
|
+
* DF administrative region carries Brasília's code, because that is the
|
|
311
|
+
* municipality it is part of.
|
|
312
|
+
*/
|
|
313
|
+
municipalityId: string | null;
|
|
273
314
|
}
|
|
274
315
|
|
|
275
316
|
export declare interface BrazilStateCitySelectProps {
|
|
@@ -509,6 +550,21 @@ declare interface Coordinate {
|
|
|
509
550
|
longitude: number;
|
|
510
551
|
}
|
|
511
552
|
|
|
553
|
+
/**
|
|
554
|
+
* The IBGE vintages the bundled datasets were built from.
|
|
555
|
+
*
|
|
556
|
+
* `roster` is the day the municipality list was read and `mesh` the boundary
|
|
557
|
+
* release it was joined to. They differ on purpose: IBGE publishes new
|
|
558
|
+
* municipalities before it publishes their boundaries, and the gap is what
|
|
559
|
+
* {@link pendingGeometryIds} enumerates.
|
|
560
|
+
*
|
|
561
|
+
* @returns The two vintages, as they were written into the data file.
|
|
562
|
+
*/
|
|
563
|
+
export declare function datasetVintage(): {
|
|
564
|
+
roster: string;
|
|
565
|
+
mesh: string;
|
|
566
|
+
};
|
|
567
|
+
|
|
512
568
|
/** Anything these helpers accept as a day. */
|
|
513
569
|
export declare type DateInput = Date | string;
|
|
514
570
|
|
|
@@ -848,6 +904,18 @@ export declare function mod11DacArrecadacao(value: string): number;
|
|
|
848
904
|
*/
|
|
849
905
|
export declare function mod11DacCobranca(value: string): number;
|
|
850
906
|
|
|
907
|
+
/**
|
|
908
|
+
* Municipalities of a federative unit, each carrying its IBGE code.
|
|
909
|
+
*
|
|
910
|
+
* The code is what a backend wants stored: it survives the renames that keep
|
|
911
|
+
* happening (`Presidente Juscelino` became `Serra Caiada` in 2013) and it is the
|
|
912
|
+
* key every other dataset in this module joins on.
|
|
913
|
+
*
|
|
914
|
+
* @param uf - Federative unit acronym, case-insensitive.
|
|
915
|
+
* @returns The municipalities, alphabetically. Empty for an unknown UF.
|
|
916
|
+
*/
|
|
917
|
+
export declare function municipalitiesByUf(uf: string): readonly BrazilMunicipality[];
|
|
918
|
+
|
|
851
919
|
/** A municipality identified for selection callbacks. */
|
|
852
920
|
export declare interface Municipality {
|
|
853
921
|
/** 7-digit IBGE code. */
|
|
@@ -997,6 +1065,24 @@ export declare function normalizePixKey(key: string): NormalizedPixKey;
|
|
|
997
1065
|
*/
|
|
998
1066
|
export declare function normalizeUf(value: string): UF | null;
|
|
999
1067
|
|
|
1068
|
+
/**
|
|
1069
|
+
* Open the WhatsApp chat in a new tab.
|
|
1070
|
+
*
|
|
1071
|
+
* @example
|
|
1072
|
+
* <Button onClick={() => openWhatsApp(client.phone, greeting)}>
|
|
1073
|
+
* Falar no WhatsApp
|
|
1074
|
+
* </Button>
|
|
1075
|
+
*
|
|
1076
|
+
* @param phone - Phone number in any shape; normalised by {@link toWhatsAppNumber}.
|
|
1077
|
+
* @param text - Message to pre-fill. Omitted or empty leaves the composer blank.
|
|
1078
|
+
* @returns `true` when a URL was built and the open was requested, `false` when
|
|
1079
|
+
* the number is unusable or there is no `window` (test runner, service worker,
|
|
1080
|
+
* build plugin). It reports the **request**, not the tab: opening with
|
|
1081
|
+
* `noopener` makes `window.open` return `null` even on success, so its result
|
|
1082
|
+
* cannot distinguish a blocked popup from an opened one.
|
|
1083
|
+
*/
|
|
1084
|
+
export declare function openWhatsApp(phone: string, text?: string): boolean;
|
|
1085
|
+
|
|
1000
1086
|
/**
|
|
1001
1087
|
* Read a 44-digit fiscal access key into its fields.
|
|
1002
1088
|
*
|
|
@@ -1090,6 +1176,19 @@ export declare interface ParsePixOptions {
|
|
|
1090
1176
|
*/
|
|
1091
1177
|
export declare function parsePixPayload(payload: string, options?: ParsePixOptions): PixData;
|
|
1092
1178
|
|
|
1179
|
+
/**
|
|
1180
|
+
* Municipalities that exist in the roster and have no boundary yet.
|
|
1181
|
+
*
|
|
1182
|
+
* One today: Boa Esperança do Norte (MT), installed in 2023, for which IBGE
|
|
1183
|
+
* serves no mesh at any endpoint. It is listed and selectable, and it is the one
|
|
1184
|
+
* municipality `geocodeMunicipality` cannot place — so a caller that must plot
|
|
1185
|
+
* every selection can check this list up front instead of discovering it as an
|
|
1186
|
+
* empty result.
|
|
1187
|
+
*
|
|
1188
|
+
* @returns The IBGE codes, in the order the data file declares them.
|
|
1189
|
+
*/
|
|
1190
|
+
export declare function pendingGeometryIds(): readonly string[];
|
|
1191
|
+
|
|
1093
1192
|
/**
|
|
1094
1193
|
* CRC-16/CCITT-FALSE of a string, as four upper-case hex characters.
|
|
1095
1194
|
*
|
|
@@ -1360,6 +1459,29 @@ export declare const REGION_COLORS: Record<BrRegion, string>;
|
|
|
1360
1459
|
/** Legend entries (swatch + region name) for a region-colored map. */
|
|
1361
1460
|
export declare function regionLegendItems(): LegendItem[];
|
|
1362
1461
|
|
|
1462
|
+
/**
|
|
1463
|
+
* Find the municipality a name refers to, however it was written down.
|
|
1464
|
+
*
|
|
1465
|
+
* Four kinds of name resolve, which is the point — an address saved years ago
|
|
1466
|
+
* has to keep pointing at the same place:
|
|
1467
|
+
*
|
|
1468
|
+
* 1. The current IBGE name (`"Serra Caiada"`).
|
|
1469
|
+
* 2. A former name (`"Presidente Juscelino"`), from the alias table the
|
|
1470
|
+
* generator builds by diffing vintages.
|
|
1471
|
+
* 3. A different spelling — accents, case and apostrophes are folded, so
|
|
1472
|
+
* `"sant'ana do livramento"` finds `"Sant'Ana do Livramento"`.
|
|
1473
|
+
* 4. An administrative region of the DF (`"Ceilândia"`), which resolves to
|
|
1474
|
+
* Brasília — the municipality it is part of.
|
|
1475
|
+
*
|
|
1476
|
+
* A live municipality always wins over a former name, so a name that is current
|
|
1477
|
+
* in one UF and historical in another resolves to the live one in each.
|
|
1478
|
+
*
|
|
1479
|
+
* @param uf - Federative unit acronym, case-insensitive.
|
|
1480
|
+
* @param name - The municipality, region or former name.
|
|
1481
|
+
* @returns The municipality, or `null` when nothing in that UF answers to it.
|
|
1482
|
+
*/
|
|
1483
|
+
export declare function resolveMunicipality(uf: string, name: string): BrazilMunicipality | null;
|
|
1484
|
+
|
|
1363
1485
|
/**
|
|
1364
1486
|
* Exact reverse-geocode: the municipality whose (simplified) boundary
|
|
1365
1487
|
* **contains** the coordinate, via point-in-polygon. Loads one state's geometry
|
|
@@ -1452,6 +1574,39 @@ export declare function statesByRegion(region: BrRegion): readonly BrazilState[]
|
|
|
1452
1574
|
*/
|
|
1453
1575
|
export declare function thresholdScale(thresholds: readonly number[], palette: readonly string[]): ColorScale;
|
|
1454
1576
|
|
|
1577
|
+
/**
|
|
1578
|
+
* Normalise a phone number to the digits-only form `wa.me` accepts.
|
|
1579
|
+
*
|
|
1580
|
+
* A Brazilian number is stored almost everywhere **without** the country code —
|
|
1581
|
+
* ten digits for a landline, eleven for a mobile — and `wa.me` refuses anything
|
|
1582
|
+
* that is not fully qualified. Those two shapes get `55` in front; a number that
|
|
1583
|
+
* already carries a country code (12 to 15 digits, the E.164 range that no
|
|
1584
|
+
* Brazilian national number can reach) is returned untouched, so a foreign
|
|
1585
|
+
* client's number still works.
|
|
1586
|
+
*
|
|
1587
|
+
* Everything else returns an empty string rather than a best guess. Handing back
|
|
1588
|
+
* the digits as typed is what the naive version does, and it builds a `wa.me`
|
|
1589
|
+
* URL that opens WhatsApp on a number nobody owns — a typo becomes a dead chat
|
|
1590
|
+
* window instead of a disabled button.
|
|
1591
|
+
*
|
|
1592
|
+
* Trunk and carrier-selection prefixes (`0`, `021`, …) are **not** stripped: a
|
|
1593
|
+
* leading zero is ambiguous between the two, so a number carrying one reads as
|
|
1594
|
+
* invalid instead of being silently reinterpreted. Pass the plain number. The
|
|
1595
|
+
* leading zero is what rules it out even at a plausible length — no E.164
|
|
1596
|
+
* country code starts with `0`, so `011999998888` is a national number wearing a
|
|
1597
|
+
* trunk prefix, never an international one.
|
|
1598
|
+
*
|
|
1599
|
+
* @example
|
|
1600
|
+
* toWhatsAppNumber("(11) 99999-8888"); // "5511999998888"
|
|
1601
|
+
* toWhatsAppNumber("+55 11 99999-8888"); // "5511999998888"
|
|
1602
|
+
* toWhatsAppNumber("99999-8888"); // "" — no area code, nothing to dial
|
|
1603
|
+
*
|
|
1604
|
+
* @param phone - Phone number in any shape: masked, spaced, `+`-prefixed.
|
|
1605
|
+
* @returns Digits ready for a `wa.me` link, or an empty string when the input
|
|
1606
|
+
* cannot be resolved to a dialable number.
|
|
1607
|
+
*/
|
|
1608
|
+
export declare function toWhatsAppNumber(phone: string): string;
|
|
1609
|
+
|
|
1455
1610
|
/** The 27 Brazilian federative units (26 states + Federal District). */
|
|
1456
1611
|
export declare type UF = "AC" | "AL" | "AP" | "AM" | "BA" | "CE" | "DF" | "ES" | "GO" | "MA" | "MT" | "MS" | "MG" | "PA" | "PB" | "PR" | "PE" | "PI" | "RJ" | "RN" | "RS" | "RO" | "RR" | "SC" | "SP" | "SE" | "TO";
|
|
1457
1612
|
|
|
@@ -1491,4 +1646,27 @@ export declare function validateBoleto(value: string): boolean;
|
|
|
1491
1646
|
*/
|
|
1492
1647
|
export declare function validateChaveNFe(chave: string): boolean;
|
|
1493
1648
|
|
|
1649
|
+
/**
|
|
1650
|
+
* Build the `wa.me` deep link that opens a chat with an optional message
|
|
1651
|
+
* already typed.
|
|
1652
|
+
*
|
|
1653
|
+
* This is a **deep link, never a send**: the chat opens with the text ready and
|
|
1654
|
+
* the person presses send. That is the feature, not a limitation — it needs no
|
|
1655
|
+
* official Cloud API, no approved template and no business verification, and it
|
|
1656
|
+
* cannot let the UI claim a message was delivered when it was not.
|
|
1657
|
+
*
|
|
1658
|
+
* `api.whatsapp.com/send?phone=…` is deliberately not offered as an alternative
|
|
1659
|
+
* host: both resolve to the same chooser, and `wa.me` is the short form of it.
|
|
1660
|
+
*
|
|
1661
|
+
* @example
|
|
1662
|
+
* whatsAppUrl("(11) 99999-8888", "Seu horário é amanhã às 14h.");
|
|
1663
|
+
* // "https://wa.me/5511999998888?text=Seu%20hor%C3%A1rio%20%C3%A9%20amanh%C3%A3%20%C3%A0s%2014h."
|
|
1664
|
+
*
|
|
1665
|
+
* @param phone - Phone number in any shape; normalised by {@link toWhatsAppNumber}.
|
|
1666
|
+
* @param text - Message to pre-fill. Omitted or empty leaves the composer blank.
|
|
1667
|
+
* @returns The `https://wa.me/…` URL, or an empty string when the number cannot
|
|
1668
|
+
* be normalised.
|
|
1669
|
+
*/
|
|
1670
|
+
export declare function whatsAppUrl(phone: string, text?: string): string;
|
|
1671
|
+
|
|
1494
1672
|
export { }
|
package/dist/br.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { loadStateMunicipalities as
|
|
3
|
-
import { geocodeMunicipality as
|
|
4
|
-
import { REGION_COLORS as
|
|
5
|
-
import { BrazilMap as
|
|
6
|
-
import { BrazilStateMap as
|
|
7
|
-
import { BrazilStateCitySelect as
|
|
8
|
-
import { MunicipalitySearch as
|
|
9
|
-
import { DIVERGING_RDBU as
|
|
10
|
-
import { MapLegend as
|
|
11
|
-
import { PixError as
|
|
12
|
-
import { PixQRCode as
|
|
13
|
-
import { BoletoError as
|
|
14
|
-
import { ChaveNFeError as
|
|
15
|
-
import {
|
|
1
|
+
import { administrativeRegionsByUf as e, citiesByUf as t, cityChoices as n, datasetVintage as r, getState as i, isValidCity as a, isValidUf as o, listStates as s, municipalitiesByUf as c, normalizeUf as l, pendingGeometryIds as u, resolveMunicipality as d, statesByRegion as f, ufChoices as p } from "./br/locations.js";
|
|
2
|
+
import { loadStateMunicipalities as m } from "./br/state-geo.js";
|
|
3
|
+
import { geocodeMunicipality as h, municipalityCentroid as g, nearestMunicipality as _, reverseGeocode as v, searchMunicipalities as y, stateCentroid as b } from "./br/geocode.js";
|
|
4
|
+
import { REGION_COLORS as x, regionLegendItems as S } from "./br/regions.js";
|
|
5
|
+
import { BrazilMap as C } from "./br/BrazilMap.js";
|
|
6
|
+
import { BrazilStateMap as w } from "./br/BrazilStateMap.js";
|
|
7
|
+
import { BrazilStateCitySelect as T } from "./br/BrazilStateCitySelect.js";
|
|
8
|
+
import { MunicipalitySearch as E } from "./br/MunicipalitySearch.js";
|
|
9
|
+
import { DIVERGING_RDBU as D, SEQUENTIAL_BLUES as O, SEQUENTIAL_GREENS as k, SEQUENTIAL_VIRIDIS as A, quantizeScale as j, sequentialScale as M, thresholdScale as N } from "./br/scales.js";
|
|
10
|
+
import { MapLegend as P } from "./br/MapLegend.js";
|
|
11
|
+
import { PixError as F, normalizePixKey as I, parsePixPayload as L, pixCrc16 as R, pixKeyType as z, pixPayload as B } from "./br/pix.js";
|
|
12
|
+
import { PixQRCode as V } from "./br/PixQRCode.js";
|
|
13
|
+
import { BoletoError as H, boletoDueDate as U, boletoKind as W, codigoBarrasToLinhaDigitavel as G, fatorVencimento as K, formatLinhaDigitavel as q, linhaDigitavelToCodigoBarras as J, mod10Dac as Y, mod11DacArrecadacao as X, mod11DacCobranca as Z, parseCodigoBarras as Q, parseLinhaDigitavel as $, validateBoleto as ee } from "./br/boleto.js";
|
|
14
|
+
import { ChaveNFeError as te, chaveNFeCheckDigit as ne, formatChaveNFe as re, parseChaveNFe as ie, validateChaveNFe as ae } from "./br/nfe.js";
|
|
15
|
+
import { openWhatsApp as oe, toWhatsAppNumber as se, whatsAppUrl as ce } from "./br/whatsapp.js";
|
|
16
|
+
import { addBusinessDays as le, easterSunday as ue, holidaysFor as de, isBusinessDay as fe, isHoliday as pe, nextBusinessDay as me } from "./br/holidays.js";
|
|
16
17
|
//#region src/br/index.ts
|
|
17
|
-
async function
|
|
18
|
+
async function he() {
|
|
18
19
|
return (await import("./br/br-geo.js")).BR_UF_GEOJSON;
|
|
19
20
|
}
|
|
20
21
|
//#endregion
|
|
21
|
-
export {
|
|
22
|
+
export { H as BoletoError, C as BrazilMap, T as BrazilStateCitySelect, w as BrazilStateMap, te as ChaveNFeError, D as DIVERGING_RDBU, P as MapLegend, E as MunicipalitySearch, F as PixError, V as PixQRCode, x as REGION_COLORS, O as SEQUENTIAL_BLUES, k as SEQUENTIAL_GREENS, A as SEQUENTIAL_VIRIDIS, le as addBusinessDays, e as administrativeRegionsByUf, U as boletoDueDate, W as boletoKind, ne as chaveNFeCheckDigit, t as citiesByUf, n as cityChoices, G as codigoBarrasToLinhaDigitavel, r as datasetVintage, ue as easterSunday, K as fatorVencimento, re as formatChaveNFe, q as formatLinhaDigitavel, h as geocodeMunicipality, i as getState, de as holidaysFor, fe as isBusinessDay, pe as isHoliday, a as isValidCity, o as isValidUf, J as linhaDigitavelToCodigoBarras, s as listStates, he as loadBrUfGeoJson, m as loadStateMunicipalities, Y as mod10Dac, X as mod11DacArrecadacao, Z as mod11DacCobranca, c as municipalitiesByUf, g as municipalityCentroid, _ as nearestMunicipality, me as nextBusinessDay, I as normalizePixKey, l as normalizeUf, oe as openWhatsApp, ie as parseChaveNFe, Q as parseCodigoBarras, $ as parseLinhaDigitavel, L as parsePixPayload, u as pendingGeometryIds, R as pixCrc16, z as pixKeyType, B as pixPayload, j as quantizeScale, S as regionLegendItems, d as resolveMunicipality, v as reverseGeocode, y as searchMunicipalities, M as sequentialScale, b as stateCentroid, f as statesByRegion, N as thresholdScale, se as toWhatsAppNumber, p as ufChoices, ee as validateBoleto, ae as validateChaveNFe, ce as whatsAppUrl };
|
|
22
23
|
|
|
23
24
|
//# sourceMappingURL=br.js.map
|
package/dist/br.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"br.js","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type {
|
|
1
|
+
{"version":3,"file":"br.js","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n municipalitiesByUf,\n administrativeRegionsByUf,\n resolveMunicipality,\n datasetVintage,\n pendingGeometryIds,\n} from \"./locations\";\nexport type {\n UF,\n BrRegion,\n BrazilState,\n BrazilMunicipality,\n BrazilAdministrativeRegion,\n Choice,\n} from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// WhatsApp deep link (chat opened with the message ready, never an API send).\nexport { openWhatsApp, toWhatsAppNumber, whatsAppUrl } from \"./whatsapp\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":";;;;;;;;;;;;;;;;;AAmCA,eAAsB,KAAkD;CAEpE,QAAO,MADW,OAAO,kBAAA,CACd;AACf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../utils/cn.cjs"),t=require("./BottomSheet.module.cjs");let
|
|
1
|
+
const e=require("../../utils/cn.cjs"),t=require("./BottomSheet.module.cjs"),n=require("../Portal/portal-host.cjs");let r=require("react"),i=require("react/jsx-runtime"),a=require("react-dom");function o({open:o,onClose:s,title:c,showHandle:l=!0,dismissOnBackdrop:u=!0,dismissOnEsc:d=!0,className:f,children:p,...m}){(0,r.useEffect)(()=>{if(!o||!d)return;let e=e=>{e.key===`Escape`&&s()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[o,d,s]),(0,r.useEffect)(()=>{if(!o)return;let e=document.body.style.overflow;return document.body.style.overflow=`hidden`,()=>{document.body.style.overflow=e}},[o]);let h=n.usePortalHost();return!o||!h?null:(0,a.createPortal)((0,i.jsxs)(`div`,{className:t.default.root,role:`dialog`,"aria-modal":`true`,children:[(0,i.jsx)(`div`,{className:t.default.backdrop,onClick:()=>u&&s(),"aria-hidden":`true`}),(0,i.jsxs)(`div`,{className:e.cn(t.default.sheet,f),...m,children:[l&&(0,i.jsx)(`button`,{type:`button`,className:t.default.handle,"aria-label":`Arrastar para fechar`,onClick:s,children:(0,i.jsx)(`span`,{className:t.default.handleBar})}),c&&(0,i.jsx)(`div`,{className:t.default.title,children:c}),(0,i.jsx)(`div`,{className:t.default.body,children:p})]})]}),h)}exports.BottomSheet=o;
|
|
2
2
|
//# sourceMappingURL=BottomSheet.cjs.map
|
|
@@ -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 ||
|
|
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\";\nimport { usePortalHost } from \"../Portal/portal-host\";\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 const portalHost = usePortalHost();\n\n if (!open || !portalHost) 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 portalHost,\n );\n}\n"],"mappings":"gMAgCA,SAAgB,EAAY,CACxB,OACA,UACA,QACA,aAAa,GACb,oBAAoB,GACpB,eAAe,GACf,YACA,WACA,GAAG,GACc,EACjB,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,EAET,IAAM,EAAa,EAAA,cAAc,EAIjC,MAFI,CAAC,GAAQ,CAAC,EAAmB,MAEjC,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,CACJ,CACJ"}
|
|
@@ -1,58 +1,61 @@
|
|
|
1
1
|
import { cn as e } from "../../utils/cn.js";
|
|
2
2
|
import t from "./BottomSheet.module.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { usePortalHost as n } from "../Portal/portal-host.js";
|
|
4
|
+
import { useEffect as r } from "react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
import { createPortal as o } from "react-dom";
|
|
6
7
|
//#region src/components/BottomSheet/BottomSheet.tsx
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
if (!
|
|
8
|
+
function s({ open: s, onClose: c, title: l, showHandle: u = !0, dismissOnBackdrop: d = !0, dismissOnEsc: f = !0, className: p, children: m, ...h }) {
|
|
9
|
+
r(() => {
|
|
10
|
+
if (!s || !f) return;
|
|
10
11
|
let e = (e) => {
|
|
11
|
-
e.key === "Escape" &&
|
|
12
|
+
e.key === "Escape" && c();
|
|
12
13
|
};
|
|
13
14
|
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
14
15
|
}, [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
]),
|
|
19
|
-
if (!
|
|
16
|
+
s,
|
|
17
|
+
f,
|
|
18
|
+
c
|
|
19
|
+
]), r(() => {
|
|
20
|
+
if (!s) return;
|
|
20
21
|
let e = document.body.style.overflow;
|
|
21
22
|
return document.body.style.overflow = "hidden", () => {
|
|
22
23
|
document.body.style.overflow = e;
|
|
23
24
|
};
|
|
24
|
-
}, [
|
|
25
|
+
}, [s]);
|
|
26
|
+
let g = n();
|
|
27
|
+
return !s || !g ? null : o(/* @__PURE__ */ a("div", {
|
|
25
28
|
className: t.root,
|
|
26
29
|
role: "dialog",
|
|
27
30
|
"aria-modal": "true",
|
|
28
|
-
children: [/* @__PURE__ */
|
|
31
|
+
children: [/* @__PURE__ */ i("div", {
|
|
29
32
|
className: t.backdrop,
|
|
30
|
-
onClick: () =>
|
|
33
|
+
onClick: () => d && c(),
|
|
31
34
|
"aria-hidden": "true"
|
|
32
|
-
}), /* @__PURE__ */
|
|
33
|
-
className: e(t.sheet,
|
|
34
|
-
...
|
|
35
|
+
}), /* @__PURE__ */ a("div", {
|
|
36
|
+
className: e(t.sheet, p),
|
|
37
|
+
...h,
|
|
35
38
|
children: [
|
|
36
|
-
|
|
39
|
+
u && /* @__PURE__ */ i("button", {
|
|
37
40
|
type: "button",
|
|
38
41
|
className: t.handle,
|
|
39
42
|
"aria-label": "Arrastar para fechar",
|
|
40
|
-
onClick:
|
|
41
|
-
children: /* @__PURE__ */
|
|
43
|
+
onClick: c,
|
|
44
|
+
children: /* @__PURE__ */ i("span", { className: t.handleBar })
|
|
42
45
|
}),
|
|
43
|
-
|
|
46
|
+
l && /* @__PURE__ */ i("div", {
|
|
44
47
|
className: t.title,
|
|
45
|
-
children:
|
|
48
|
+
children: l
|
|
46
49
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
50
|
+
/* @__PURE__ */ i("div", {
|
|
48
51
|
className: t.body,
|
|
49
|
-
children:
|
|
52
|
+
children: m
|
|
50
53
|
})
|
|
51
54
|
]
|
|
52
55
|
})]
|
|
53
|
-
}),
|
|
56
|
+
}), g);
|
|
54
57
|
}
|
|
55
58
|
//#endregion
|
|
56
|
-
export {
|
|
59
|
+
export { s as BottomSheet };
|
|
57
60
|
|
|
58
61
|
//# sourceMappingURL=BottomSheet.js.map
|
|
@@ -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 ||
|
|
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\";\nimport { usePortalHost } from \"../Portal/portal-host\";\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 const portalHost = usePortalHost();\n\n if (!open || !portalHost) 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 portalHost,\n );\n}\n"],"mappings":";;;;;;;AAgCA,SAAgB,EAAY,EACxB,SACA,YACA,UACA,gBAAa,IACb,uBAAoB,IACpB,kBAAe,IACf,cACA,aACA,GAAG,KACc;CAUjB,AATA,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;CAET,IAAM,IAAa,EAAc;CAIjC,OAFI,CAAC,KAAQ,CAAC,IAAmB,OAE1B,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,CACJ;AACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../utils/cn.cjs"),t=require("../../hooks/use-focus-trap.cjs"),
|
|
1
|
+
const e=require("../../utils/cn.cjs"),t=require("../Portal/portal-host.cjs"),n=require("../../hooks/use-focus-trap.cjs"),r=require("./Command.module.cjs");let i=require("react"),a=require("react/jsx-runtime"),o=require("react-dom");function s(e,t){return t===``||e.label.toLowerCase().includes(t)?!0:(e.keywords??[]).some(e=>e.toLowerCase().includes(t))}function c(e){let t=[],n=new Map;for(let r of e){let e=n.get(r.group);e===void 0?(n.set(r.group,t.length),t.push({name:r.group,items:[r]})):t[e].items.push(r)}return t}function l({open:l,onOpenChange:d,items:f,placeholder:p=`Type a command…`,emptyMessage:m=`No results`,className:h}){let g=(0,i.useRef)(null),[_,v]=(0,i.useState)(``),[y,b]=(0,i.useState)(0),x=`tempest-command-list`;n.useFocusTrap(g,l);let S=(0,i.useMemo)(()=>{let e=_.trim().toLowerCase();return c(f.filter(t=>s(t,e))).flatMap(e=>e.items)},[f,_]),C=(0,i.useMemo)(()=>c(S),[S]);(0,i.useEffect)(()=>{l&&(v(``),b(0))},[l]),(0,i.useEffect)(()=>{b(e=>S.length===0?0:Math.min(e,S.length-1))},[S.length]);let w=t.usePortalHost();if(!l||!w)return null;function T(e){e.onSelect(),d(!1)}function E(e){if(e.key===`Escape`){e.preventDefault(),d(!1);return}if(e.key===`ArrowDown`){if(e.preventDefault(),S.length===0)return;b(e=>(e+1)%S.length);return}if(e.key===`ArrowUp`){if(e.preventDefault(),S.length===0)return;b(e=>(e-1+S.length)%S.length);return}if(e.key===`Enter`){e.preventDefault();let t=S[y];t&&T(t)}}let D=-1;return(0,o.createPortal)((0,a.jsx)(`div`,{className:r.default.overlay,role:`presentation`,onClick:()=>d(!1),children:(0,a.jsxs)(`div`,{ref:g,role:`dialog`,"aria-modal":`true`,"aria-label":`Command palette`,className:e.cn(r.default.dialog,h),onClick:e=>e.stopPropagation(),children:[(0,a.jsxs)(`div`,{className:r.default.inputRow,children:[(0,a.jsx)(u,{}),(0,a.jsx)(`input`,{type:`text`,role:`combobox`,"aria-expanded":`true`,"aria-controls":x,"aria-autocomplete":`list`,autoFocus:!0,className:r.default.input,placeholder:p,value:_,onChange:e=>v(e.target.value),onKeyDown:E})]}),(0,a.jsx)(`ul`,{id:x,role:`listbox`,className:r.default.list,children:S.length===0?(0,a.jsx)(`li`,{className:r.default.empty,children:m}):C.map(t=>(0,a.jsxs)(`li`,{className:r.default.group,children:[t.name&&(0,a.jsx)(`div`,{className:r.default.groupHeading,children:t.name}),(0,a.jsx)(`ul`,{role:`presentation`,className:r.default.groupList,children:t.items.map(t=>{D+=1;let n=D===y,i=D;return(0,a.jsxs)(`li`,{role:`option`,"aria-selected":n,className:e.cn(r.default.option,n&&r.default.active),onMouseMove:()=>b(i),onClick:()=>T(t),children:[t.icon&&(0,a.jsx)(`span`,{className:r.default.icon,children:t.icon}),(0,a.jsx)(`span`,{className:r.default.label,children:t.label})]},t.id)})})]},t.name??`__ungrouped__`))})]})}),w)}function u(){return(0,a.jsxs)(`svg`,{className:r.default.searchIcon,width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,"aria-hidden":`true`,children:[(0,a.jsx)(`circle`,{cx:`11`,cy:`11`,r:`7`,stroke:`currentColor`,strokeWidth:`2`}),(0,a.jsx)(`path`,{d:`M20 20l-3.5-3.5`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`})]})}exports.Command=l;
|
|
2
2
|
//# sourceMappingURL=Command.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.cjs","names":[],"sources":["../../../src/components/Command/Command.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, function-lines — a command palette is a filtered\n * listbox with its own keyboard contract: the body holds the query, the flattened\n * result list, the active index and the Escape/Enter handling, all of which read\n * each other on every keystroke.\n */\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/utils/cn\";\nimport { useFocusTrap } from \"@/hooks/use-focus-trap\";\nimport styles from \"./Command.module.css\";\n\nexport interface CommandItem {\n /** Stable unique identifier for the item. */\n id: string;\n /** Human-readable label shown in the list and matched against the query. */\n label: string;\n /** Optional group heading; items sharing a group are rendered together. */\n group?: string;\n /** Extra terms matched against the query in addition to `label`. */\n keywords?: string[];\n /** Invoked when the item is chosen (click or Enter on the active row). */\n onSelect: () => void;\n /** Optional leading icon. */\n icon?: ReactNode;\n}\n\nexport interface CommandProps {\n /** Whether the palette is visible. */\n open: boolean;\n /** Called with the next open state (Escape, selection, backdrop click). */\n onOpenChange: (open: boolean) => void;\n /** Candidate items to filter and display. */\n items: CommandItem[];\n /** Placeholder for the search input. */\n placeholder?: string;\n /** Rendered when no item matches the current query. */\n emptyMessage?: ReactNode;\n /** Forwarded to the dialog element. */\n className?: string;\n}\n\ninterface CommandGroup {\n name: string | undefined;\n items: CommandItem[];\n}\n\n/**\n * Case-insensitively test whether `item` matches `query` by substring against\n * its label and any keywords. An empty query matches everything.\n *\n * @param item - The candidate command item.\n * @param query - The lowercased search query.\n * @returns `true` when the item should be shown.\n */\nfunction matchesQuery(item: CommandItem, query: string): boolean {\n if (query === \"\") return true;\n if (item.label.toLowerCase().includes(query)) return true;\n return (item.keywords ?? []).some((keyword) => keyword.toLowerCase().includes(query));\n}\n\n/**\n * Partition a flat item list into ordered groups, preserving first-seen order\n * for both groups and the items within them.\n *\n * @param items - The (already filtered) items to group.\n * @returns An ordered list of groups.\n */\nfunction groupItems(items: CommandItem[]): CommandGroup[] {\n const groups: CommandGroup[] = [];\n const indexByName = new Map<string | undefined, number>();\n for (const item of items) {\n const existing = indexByName.get(item.group);\n if (existing === undefined) {\n indexByName.set(item.group, groups.length);\n groups.push({ name: item.group, items: [item] });\n } else {\n groups[existing]!.items.push(item);\n }\n }\n return groups;\n}\n\n/**\n * A ⌘K-style command palette: an overlay dialog with a search input that\n * substring-filters items by label and keywords, groups results, and supports\n * full keyboard navigation (Arrow up/down, Enter, Escape). Traps focus while\n * open.\n */\nexport function Command({\n open,\n onOpenChange,\n items,\n placeholder = \"Type a command…\",\n emptyMessage = \"No results\",\n className,\n}: CommandProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const [query, setQuery] = useState<string>(\"\");\n const [activeIndex, setActiveIndex] = useState<number>(0);\n const listId = \"tempest-command-list\";\n\n useFocusTrap(dialogRef, open);\n\n const filtered = useMemo<CommandItem[]>(() => {\n const normalized = query.trim().toLowerCase();\n const visible = items.filter((item) => matchesQuery(item, normalized));\n return groupItems(visible).flatMap((group) => group.items);\n }, [items, query]);\n\n const groups = useMemo<CommandGroup[]>(() => groupItems(filtered), [filtered]);\n\n // Reset transient state whenever the palette opens.\n useEffect(() => {\n if (open) {\n setQuery(\"\");\n setActiveIndex(0);\n }\n }, [open]);\n\n // Keep the active index within bounds as the filtered list shrinks/grows.\n useEffect(() => {\n setActiveIndex((index) => {\n if (filtered.length === 0) return 0;\n return Math.min(index, filtered.length - 1);\n });\n }, [filtered.length]);\n\n if (!open || typeof document === \"undefined\") return null;\n\n function selectItem(item: CommandItem): void {\n item.onSelect();\n onOpenChange(false);\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\n if (event.key === \"Escape\") {\n event.preventDefault();\n onOpenChange(false);\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n if (filtered.length === 0) return;\n setActiveIndex((index) => (index + 1) % filtered.length);\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n if (filtered.length === 0) return;\n setActiveIndex((index) => (index - 1 + filtered.length) % filtered.length);\n return;\n }\n if (event.key === \"Enter\") {\n event.preventDefault();\n const item = filtered[activeIndex];\n if (item) selectItem(item);\n }\n }\n\n let renderIndex = -1;\n\n return createPortal(\n <div className={styles.overlay} role=\"presentation\" onClick={() => onOpenChange(false)}>\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n className={cn(styles.dialog, className)}\n onClick={(event) => event.stopPropagation()}\n >\n <div className={styles.inputRow}>\n <SearchIcon />\n <input\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n autoFocus\n className={styles.input}\n placeholder={placeholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={handleKeyDown}\n />\n </div>\n <ul id={listId} role=\"listbox\" className={styles.list}>\n {filtered.length === 0 ? (\n <li className={styles.empty}>{emptyMessage}</li>\n ) : (\n groups.map((group) => (\n <li key={group.name ?? \"__ungrouped__\"} className={styles.group}>\n {group.name && (\n <div className={styles.groupHeading}>{group.name}</div>\n )}\n <ul role=\"presentation\" className={styles.groupList}>\n {group.items.map((item) => {\n renderIndex += 1;\n const isActive = renderIndex === activeIndex;\n const index = renderIndex;\n return (\n <li\n key={item.id}\n role=\"option\"\n aria-selected={isActive}\n className={cn(\n styles.option,\n isActive && styles.active,\n )}\n onMouseMove={() => setActiveIndex(index)}\n onClick={() => selectItem(item)}\n >\n {item.icon && (\n <span className={styles.icon}>{item.icon}</span>\n )}\n <span className={styles.label}>{item.label}</span>\n </li>\n );\n })}\n </ul>\n </li>\n ))\n )}\n </ul>\n </div>\n </div>,\n document.body,\n );\n}\n\nfunction SearchIcon() {\n return (\n <svg\n className={styles.searchIcon}\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path d=\"M20 20l-3.5-3.5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Command.cjs","names":[],"sources":["../../../src/components/Command/Command.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, function-lines — a command palette is a filtered\n * listbox with its own keyboard contract: the body holds the query, the flattened\n * result list, the active index and the Escape/Enter handling, all of which read\n * each other on every keystroke.\n */\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/utils/cn\";\nimport { useFocusTrap } from \"@/hooks/use-focus-trap\";\nimport styles from \"./Command.module.css\";\nimport { usePortalHost } from \"../Portal/portal-host\";\n\nexport interface CommandItem {\n /** Stable unique identifier for the item. */\n id: string;\n /** Human-readable label shown in the list and matched against the query. */\n label: string;\n /** Optional group heading; items sharing a group are rendered together. */\n group?: string;\n /** Extra terms matched against the query in addition to `label`. */\n keywords?: string[];\n /** Invoked when the item is chosen (click or Enter on the active row). */\n onSelect: () => void;\n /** Optional leading icon. */\n icon?: ReactNode;\n}\n\nexport interface CommandProps {\n /** Whether the palette is visible. */\n open: boolean;\n /** Called with the next open state (Escape, selection, backdrop click). */\n onOpenChange: (open: boolean) => void;\n /** Candidate items to filter and display. */\n items: CommandItem[];\n /** Placeholder for the search input. */\n placeholder?: string;\n /** Rendered when no item matches the current query. */\n emptyMessage?: ReactNode;\n /** Forwarded to the dialog element. */\n className?: string;\n}\n\ninterface CommandGroup {\n name: string | undefined;\n items: CommandItem[];\n}\n\n/**\n * Case-insensitively test whether `item` matches `query` by substring against\n * its label and any keywords. An empty query matches everything.\n *\n * @param item - The candidate command item.\n * @param query - The lowercased search query.\n * @returns `true` when the item should be shown.\n */\nfunction matchesQuery(item: CommandItem, query: string): boolean {\n if (query === \"\") return true;\n if (item.label.toLowerCase().includes(query)) return true;\n return (item.keywords ?? []).some((keyword) => keyword.toLowerCase().includes(query));\n}\n\n/**\n * Partition a flat item list into ordered groups, preserving first-seen order\n * for both groups and the items within them.\n *\n * @param items - The (already filtered) items to group.\n * @returns An ordered list of groups.\n */\nfunction groupItems(items: CommandItem[]): CommandGroup[] {\n const groups: CommandGroup[] = [];\n const indexByName = new Map<string | undefined, number>();\n for (const item of items) {\n const existing = indexByName.get(item.group);\n if (existing === undefined) {\n indexByName.set(item.group, groups.length);\n groups.push({ name: item.group, items: [item] });\n } else {\n groups[existing]!.items.push(item);\n }\n }\n return groups;\n}\n\n/**\n * A ⌘K-style command palette: an overlay dialog with a search input that\n * substring-filters items by label and keywords, groups results, and supports\n * full keyboard navigation (Arrow up/down, Enter, Escape). Traps focus while\n * open.\n */\nexport function Command({\n open,\n onOpenChange,\n items,\n placeholder = \"Type a command…\",\n emptyMessage = \"No results\",\n className,\n}: CommandProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const [query, setQuery] = useState<string>(\"\");\n const [activeIndex, setActiveIndex] = useState<number>(0);\n const listId = \"tempest-command-list\";\n\n useFocusTrap(dialogRef, open);\n\n const filtered = useMemo<CommandItem[]>(() => {\n const normalized = query.trim().toLowerCase();\n const visible = items.filter((item) => matchesQuery(item, normalized));\n return groupItems(visible).flatMap((group) => group.items);\n }, [items, query]);\n\n const groups = useMemo<CommandGroup[]>(() => groupItems(filtered), [filtered]);\n\n // Reset transient state whenever the palette opens.\n useEffect(() => {\n if (open) {\n setQuery(\"\");\n setActiveIndex(0);\n }\n }, [open]);\n\n // Keep the active index within bounds as the filtered list shrinks/grows.\n useEffect(() => {\n setActiveIndex((index) => {\n if (filtered.length === 0) return 0;\n return Math.min(index, filtered.length - 1);\n });\n }, [filtered.length]);\n\n const portalHost = usePortalHost();\n\n if (!open || !portalHost) return null;\n\n function selectItem(item: CommandItem): void {\n item.onSelect();\n onOpenChange(false);\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\n if (event.key === \"Escape\") {\n event.preventDefault();\n onOpenChange(false);\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n if (filtered.length === 0) return;\n setActiveIndex((index) => (index + 1) % filtered.length);\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n if (filtered.length === 0) return;\n setActiveIndex((index) => (index - 1 + filtered.length) % filtered.length);\n return;\n }\n if (event.key === \"Enter\") {\n event.preventDefault();\n const item = filtered[activeIndex];\n if (item) selectItem(item);\n }\n }\n\n let renderIndex = -1;\n\n return createPortal(\n <div className={styles.overlay} role=\"presentation\" onClick={() => onOpenChange(false)}>\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n className={cn(styles.dialog, className)}\n onClick={(event) => event.stopPropagation()}\n >\n <div className={styles.inputRow}>\n <SearchIcon />\n <input\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n autoFocus\n className={styles.input}\n placeholder={placeholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={handleKeyDown}\n />\n </div>\n <ul id={listId} role=\"listbox\" className={styles.list}>\n {filtered.length === 0 ? (\n <li className={styles.empty}>{emptyMessage}</li>\n ) : (\n groups.map((group) => (\n <li key={group.name ?? \"__ungrouped__\"} className={styles.group}>\n {group.name && (\n <div className={styles.groupHeading}>{group.name}</div>\n )}\n <ul role=\"presentation\" className={styles.groupList}>\n {group.items.map((item) => {\n renderIndex += 1;\n const isActive = renderIndex === activeIndex;\n const index = renderIndex;\n return (\n <li\n key={item.id}\n role=\"option\"\n aria-selected={isActive}\n className={cn(\n styles.option,\n isActive && styles.active,\n )}\n onMouseMove={() => setActiveIndex(index)}\n onClick={() => selectItem(item)}\n >\n {item.icon && (\n <span className={styles.icon}>{item.icon}</span>\n )}\n <span className={styles.label}>{item.label}</span>\n </li>\n );\n })}\n </ul>\n </li>\n ))\n )}\n </ul>\n </div>\n </div>,\n portalHost,\n );\n}\n\nfunction SearchIcon() {\n return (\n <svg\n className={styles.searchIcon}\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path d=\"M20 20l-3.5-3.5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n"],"mappings":"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"}
|