@react-md/core 1.0.0-next.19 → 1.0.0-next.20
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/CoreProviders.js.map +1 -1
- package/dist/NoSsr.js.map +1 -1
- package/dist/RootHtml.js.map +1 -1
- package/dist/SsrProvider.js.map +1 -1
- package/dist/_core.scss +10 -9
- package/dist/app-bar/AppBar.js.map +1 -1
- package/dist/app-bar/AppBarTitle.js.map +1 -1
- package/dist/app-bar/_app-bar.scss +0 -4
- package/dist/app-bar/styles.js.map +1 -1
- package/dist/autocomplete/Autocomplete.js.map +1 -1
- package/dist/autocomplete/AutocompleteChip.js +1 -1
- package/dist/autocomplete/AutocompleteChip.js.map +1 -1
- package/dist/autocomplete/AutocompleteCircularProgress.js.map +1 -1
- package/dist/autocomplete/AutocompleteClearButton.js +1 -1
- package/dist/autocomplete/AutocompleteClearButton.js.map +1 -1
- package/dist/autocomplete/AutocompleteDropdownButton.js +1 -1
- package/dist/autocomplete/AutocompleteDropdownButton.js.map +1 -1
- package/dist/autocomplete/AutocompleteListboxChildren.js.map +1 -1
- package/dist/autocomplete/_autocomplete.scss +15 -13
- package/dist/autocomplete/autocompleteStyles.js.map +1 -1
- package/dist/autocomplete/types.js.map +1 -1
- package/dist/autocomplete/useAutocomplete.js +1 -1
- package/dist/autocomplete/useAutocomplete.js.map +1 -1
- package/dist/autocomplete/utils.js.map +1 -1
- package/dist/avatar/Avatar.js.map +1 -1
- package/dist/avatar/styles.js.map +1 -1
- package/dist/badge/Badge.js.map +1 -1
- package/dist/badge/styles.js.map +1 -1
- package/dist/box/Box.js +2 -1
- package/dist/box/Box.js.map +1 -1
- package/dist/box/_box.scss +24 -1
- package/dist/box/styles.d.ts +11 -0
- package/dist/box/styles.js +4 -3
- package/dist/box/styles.js.map +1 -1
- package/dist/button/AsyncButton.js.map +1 -1
- package/dist/button/Button.js.map +1 -1
- package/dist/button/ButtonUnstyled.js.map +1 -1
- package/dist/button/FloatingActionButton.js.map +1 -1
- package/dist/button/TooltippedButton.js.map +1 -1
- package/dist/button/buttonStyles.js.map +1 -1
- package/dist/card/Card.d.ts +4 -13
- package/dist/card/Card.js +3 -3
- package/dist/card/Card.js.map +1 -1
- package/dist/card/CardContent.js.map +1 -1
- package/dist/card/CardFooter.js.map +1 -1
- package/dist/card/CardHeader.js.map +1 -1
- package/dist/card/CardSubtitle.js.map +1 -1
- package/dist/card/CardTitle.js.map +1 -1
- package/dist/card/ClickableCard.js.map +1 -1
- package/dist/card/_card.scss +5 -0
- package/dist/card/styles.js.map +1 -1
- package/dist/chip/Chip.js +1 -1
- package/dist/chip/Chip.js.map +1 -1
- package/dist/chip/styles.js.map +1 -1
- package/dist/dialog/Dialog.d.ts +4 -4
- package/dist/dialog/Dialog.js.map +1 -1
- package/dist/dialog/DialogContent.js.map +1 -1
- package/dist/dialog/DialogFooter.js.map +1 -1
- package/dist/dialog/DialogHeader.js.map +1 -1
- package/dist/dialog/DialogTitle.js.map +1 -1
- package/dist/dialog/FixedDialog.js +8 -5
- package/dist/dialog/FixedDialog.js.map +1 -1
- package/dist/dialog/NestedDialogProvider.js.map +1 -1
- package/dist/dialog/styles.d.ts +12 -3
- package/dist/dialog/styles.js.map +1 -1
- package/dist/divider/Divider.js.map +1 -1
- package/dist/divider/styles.js.map +1 -1
- package/dist/draggable/useDraggable.d.ts +3 -0
- package/dist/draggable/useDraggable.js +20 -5
- package/dist/draggable/useDraggable.js.map +1 -1
- package/dist/draggable/utils.js.map +1 -1
- package/dist/expansion-panel/ExpansionList.js.map +1 -1
- package/dist/expansion-panel/ExpansionPanel.js.map +1 -1
- package/dist/expansion-panel/ExpansionPanelHeader.js +1 -1
- package/dist/expansion-panel/ExpansionPanelHeader.js.map +1 -1
- package/dist/expansion-panel/expansionPanelStyles.js.map +1 -1
- package/dist/expansion-panel/useExpansionList.js.map +1 -1
- package/dist/expansion-panel/useExpansionPanels.js.map +1 -1
- package/dist/files/FileInput.js +1 -1
- package/dist/files/FileInput.js.map +1 -1
- package/dist/files/styles.js.map +1 -1
- package/dist/files/useFileUpload.js.map +1 -1
- package/dist/files/utils.d.ts +31 -1
- package/dist/files/utils.js +30 -0
- package/dist/files/utils.js.map +1 -1
- package/dist/focus/useFocusContainer.d.ts +5 -7
- package/dist/focus/useFocusContainer.js +5 -7
- package/dist/focus/useFocusContainer.js.map +1 -1
- package/dist/form/Checkbox.js.map +1 -1
- package/dist/form/Fieldset.js.map +1 -1
- package/dist/form/Form.js.map +1 -1
- package/dist/form/FormMessage.js.map +1 -1
- package/dist/form/FormMessageContainer.js.map +1 -1
- package/dist/form/FormMessageCounter.js.map +1 -1
- package/dist/form/InputToggle.js.map +1 -1
- package/dist/form/InputToggleIcon.js +1 -1
- package/dist/form/InputToggleIcon.js.map +1 -1
- package/dist/form/Label.js.map +1 -1
- package/dist/form/Legend.js.map +1 -1
- package/dist/form/Listbox.js.map +1 -1
- package/dist/form/ListboxProvider.js.map +1 -1
- package/dist/form/MenuItemCheckbox.js.map +1 -1
- package/dist/form/MenuItemFileInput.d.ts +1 -4
- package/dist/form/MenuItemFileInput.js +15 -6
- package/dist/form/MenuItemFileInput.js.map +1 -1
- package/dist/form/MenuItemInputToggle.js.map +1 -1
- package/dist/form/MenuItemRadio.js.map +1 -1
- package/dist/form/MenuItemSwitch.js.map +1 -1
- package/dist/form/MenuItemTextField.js.map +1 -1
- package/dist/form/NativeSelect.js +1 -1
- package/dist/form/NativeSelect.js.map +1 -1
- package/dist/form/OptGroup.js.map +1 -1
- package/dist/form/Option.js +4 -4
- package/dist/form/Option.js.map +1 -1
- package/dist/form/Password.js +2 -2
- package/dist/form/Password.js.map +1 -1
- package/dist/form/Radio.js.map +1 -1
- package/dist/form/ResizingTextAreaWrapper.js.map +1 -1
- package/dist/form/Select.js +1 -1
- package/dist/form/Select.js.map +1 -1
- package/dist/form/SelectedOption.js.map +1 -1
- package/dist/form/Slider.js +9 -62
- package/dist/form/Slider.js.map +1 -1
- package/dist/form/SliderContainer.js.map +1 -1
- package/dist/form/SliderMark.js.map +1 -1
- package/dist/form/SliderMarkLabel.js.map +1 -1
- package/dist/form/SliderThumb.js +1 -0
- package/dist/form/SliderThumb.js.map +1 -1
- package/dist/form/SliderTrack.js.map +1 -1
- package/dist/form/SliderValueMarks.js.map +1 -1
- package/dist/form/SliderValueTooltip.js.map +1 -1
- package/dist/form/Switch.js.map +1 -1
- package/dist/form/SwitchTrack.js.map +1 -1
- package/dist/form/TextArea.js.map +1 -1
- package/dist/form/TextField.js.map +1 -1
- package/dist/form/TextFieldAddon.js.map +1 -1
- package/dist/form/TextFieldContainer.js.map +1 -1
- package/dist/form/_form.scss +313 -269
- package/dist/form/formMessageContainerStyles.js.map +1 -1
- package/dist/form/formMessageStyles.js.map +1 -1
- package/dist/form/inputToggleStyles.js.map +1 -1
- package/dist/form/menuItemInputToggleStyles.js.map +1 -1
- package/dist/form/nativeSelectStyles.js.map +1 -1
- package/dist/form/optionStyles.js.map +1 -1
- package/dist/form/passwordStyles.js.map +1 -1
- package/dist/form/selectStyles.js.map +1 -1
- package/dist/form/selectUtils.js.map +1 -1
- package/dist/form/sliderUtils.d.ts +2 -7
- package/dist/form/sliderUtils.js +5 -5
- package/dist/form/sliderUtils.js.map +1 -1
- package/dist/form/switchStyles.js.map +1 -1
- package/dist/form/textAreaStyles.js.map +1 -1
- package/dist/form/textFieldContainerStyles.js.map +1 -1
- package/dist/form/textFieldStyles.js.map +1 -1
- package/dist/form/types.js.map +1 -1
- package/dist/form/useCheckboxGroup.d.ts +2 -2
- package/dist/form/useCheckboxGroup.js.map +1 -1
- package/dist/form/useCombobox.js.map +1 -1
- package/dist/form/useEditableCombobox.js.map +1 -1
- package/dist/form/useFormReset.js.map +1 -1
- package/dist/form/useNumberField.js.map +1 -1
- package/dist/form/useRadioGroup.d.ts +1 -1
- package/dist/form/useRadioGroup.js.map +1 -1
- package/dist/form/useRangeSlider.d.ts +1 -0
- package/dist/form/useRangeSlider.js.map +1 -1
- package/dist/form/useResizingTextArea.js.map +1 -1
- package/dist/form/useSelectCombobox.js.map +1 -1
- package/dist/form/useSlider.d.ts +1 -3
- package/dist/form/useSlider.js.map +1 -1
- package/dist/form/useSliderDraggable.d.ts +9 -0
- package/dist/form/useSliderDraggable.js +44 -0
- package/dist/form/useSliderDraggable.js.map +1 -0
- package/dist/form/useTextField.d.ts +24 -14
- package/dist/form/useTextField.js +7 -5
- package/dist/form/useTextField.js.map +1 -1
- package/dist/form/useTextFieldContainerAddons.js.map +1 -1
- package/dist/form/validation.js +2 -0
- package/dist/form/validation.js.map +1 -1
- package/dist/hoverMode/useHoverMode.d.ts +64 -3
- package/dist/hoverMode/useHoverMode.js.map +1 -1
- package/dist/hoverMode/useHoverModeProvider.d.ts +22 -12
- package/dist/hoverMode/useHoverModeProvider.js +21 -11
- package/dist/hoverMode/useHoverModeProvider.js.map +1 -1
- package/dist/icon/FontIcon.js.map +1 -1
- package/dist/icon/IconRotator.js.map +1 -1
- package/dist/icon/MaterialIcon.js.map +1 -1
- package/dist/icon/MaterialSymbol.js.map +1 -1
- package/dist/icon/SVGIcon.js.map +1 -1
- package/dist/icon/TextIconSpacing.js.map +1 -1
- package/dist/icon/{iconConfig.js → config.js} +1 -1
- package/dist/icon/config.js.map +1 -0
- package/dist/icon/materialConfig.js.map +1 -1
- package/dist/icon/styles.js.map +1 -1
- package/dist/interaction/Ripple.js.map +1 -1
- package/dist/interaction/RippleContainer.js.map +1 -1
- package/dist/interaction/UserInteractionModeProvider.js.map +1 -1
- package/dist/interaction/_interaction.scss +2 -2
- package/dist/interaction/useElementInteraction.d.ts +24 -25
- package/dist/interaction/useElementInteraction.js +20 -21
- package/dist/interaction/useElementInteraction.js.map +1 -1
- package/dist/interaction/useHigherContrastChildren.d.ts +8 -6
- package/dist/interaction/useHigherContrastChildren.js +10 -8
- package/dist/interaction/useHigherContrastChildren.js.map +1 -1
- package/dist/interaction/utils.js.map +1 -1
- package/dist/layout/LayoutAppBar.js.map +1 -1
- package/dist/layout/LayoutNav.js.map +1 -1
- package/dist/layout/LayoutWindowSplitter.js.map +1 -1
- package/dist/layout/Main.js.map +1 -1
- package/dist/layout/_layout.scss +4 -0
- package/dist/layout/layoutNavStyles.js.map +1 -1
- package/dist/layout/layoutWindowSplitterStyles.js.map +1 -1
- package/dist/layout/mainStyles.js.map +1 -1
- package/dist/layout/useExpandableLayout.d.ts +12 -14
- package/dist/layout/useExpandableLayout.js +13 -15
- package/dist/layout/useExpandableLayout.js.map +1 -1
- package/dist/layout/useHorizontalLayoutTransition.js.map +1 -1
- package/dist/layout/useLayoutAppBarHeight.js.map +1 -1
- package/dist/layout/useLayoutTree.d.ts +4 -3
- package/dist/layout/useLayoutTree.js +4 -3
- package/dist/layout/useLayoutTree.js.map +1 -1
- package/dist/layout/useLayoutWindowSplitter.js.map +1 -1
- package/dist/layout/useMainTabIndex.js.map +1 -1
- package/dist/layout/useResizableLayout.d.ts +13 -16
- package/dist/layout/useResizableLayout.js +13 -16
- package/dist/layout/useResizableLayout.js.map +1 -1
- package/dist/layout/useTemporaryLayout.d.ts +14 -9
- package/dist/layout/useTemporaryLayout.js +12 -10
- package/dist/layout/useTemporaryLayout.js.map +1 -1
- package/dist/link/Link.js.map +1 -1
- package/dist/link/SkipToMainContent.js.map +1 -1
- package/dist/link/styles.js.map +1 -1
- package/dist/list/List.js.map +1 -1
- package/dist/list/ListItem.js +1 -1
- package/dist/list/ListItem.js.map +1 -1
- package/dist/list/ListItemAddon.js.map +1 -1
- package/dist/list/ListItemChildren.js.map +1 -1
- package/dist/list/ListItemLink.js.map +1 -1
- package/dist/list/ListItemText.js.map +1 -1
- package/dist/list/ListSubheader.js.map +1 -1
- package/dist/list/listItemStyles.js.map +1 -1
- package/dist/list/listStyles.js.map +1 -1
- package/dist/list/types.js.map +1 -1
- package/dist/media-queries/AppSizeProvider.d.ts +1 -1
- package/dist/media-queries/AppSizeProvider.js +1 -1
- package/dist/media-queries/AppSizeProvider.js.map +1 -1
- package/dist/media-queries/useMediaQuery.d.ts +3 -3
- package/dist/media-queries/useMediaQuery.js +3 -3
- package/dist/media-queries/useMediaQuery.js.map +1 -1
- package/dist/menu/DropdownMenu.js.map +1 -1
- package/dist/menu/Menu.js.map +1 -1
- package/dist/menu/MenuBar.js.map +1 -1
- package/dist/menu/MenuButton.js +1 -1
- package/dist/menu/MenuButton.js.map +1 -1
- package/dist/menu/MenuConfigurationProvider.js.map +1 -1
- package/dist/menu/MenuItem.js.map +1 -1
- package/dist/menu/MenuItemButton.js +1 -1
- package/dist/menu/MenuItemButton.js.map +1 -1
- package/dist/menu/MenuItemCircularProgress.js.map +1 -1
- package/dist/menu/MenuItemGroup.js.map +1 -1
- package/dist/menu/MenuItemSeparator.js.map +1 -1
- package/dist/menu/MenuSheet.js.map +1 -1
- package/dist/menu/MenuVisibilityProvider.js.map +1 -1
- package/dist/menu/MenuWidget.js.map +1 -1
- package/dist/menu/MenuWidgetKeyboardProvider.js.map +1 -1
- package/dist/menu/useContextMenu.js.map +1 -1
- package/dist/menu/useMenuBarProvider.js.map +1 -1
- package/dist/movement/types.js.map +1 -1
- package/dist/movement/useKeyboardMovementProvider.js.map +1 -1
- package/dist/movement/utils.js.map +1 -1
- package/dist/navigation/CollapsibleNavGroup.js.map +1 -1
- package/dist/navigation/DefaultNavigationRenderer.js.map +1 -1
- package/dist/navigation/NavGroup.js.map +1 -1
- package/dist/navigation/NavItem.js.map +1 -1
- package/dist/navigation/NavItemButton.js +1 -1
- package/dist/navigation/NavItemButton.js.map +1 -1
- package/dist/navigation/NavItemLink.js.map +1 -1
- package/dist/navigation/NavSubheader.d.ts +1 -1
- package/dist/navigation/NavSubheader.js +1 -1
- package/dist/navigation/NavSubheader.js.map +1 -1
- package/dist/navigation/Navigation.js.map +1 -1
- package/dist/navigation/navGroupStyles.js.map +1 -1
- package/dist/navigation/navItemStyles.js.map +1 -1
- package/dist/navigation/types.js.map +1 -1
- package/dist/navigation/useActiveHeadingId.d.ts +1 -1
- package/dist/navigation/useActiveHeadingId.js +4 -4
- package/dist/navigation/useActiveHeadingId.js.map +1 -1
- package/dist/navigation/useNavigationExpansion.js.map +1 -1
- package/dist/navigation/useTableOfContentsHeadings.d.ts +75 -0
- package/dist/navigation/useTableOfContentsHeadings.js +91 -0
- package/dist/navigation/useTableOfContentsHeadings.js.map +1 -0
- package/dist/objectFit.js.map +1 -1
- package/dist/overlay/Overlay.js +1 -1
- package/dist/overlay/Overlay.js.map +1 -1
- package/dist/overlay/overlayStyles.d.ts +7 -3
- package/dist/overlay/overlayStyles.js.map +1 -1
- package/dist/portal/Portal.js.map +1 -1
- package/dist/portal/PortalContainerProvider.js.map +1 -1
- package/dist/positioning/createHorizontalPosition.js.map +1 -1
- package/dist/positioning/createVerticalPosition.js.map +1 -1
- package/dist/positioning/useFixedPositioning.d.ts +11 -8
- package/dist/positioning/useFixedPositioning.js +7 -6
- package/dist/positioning/useFixedPositioning.js.map +1 -1
- package/dist/progress/CircularProgress.js.map +1 -1
- package/dist/progress/LinearProgress.js.map +1 -1
- package/dist/progress/_progress.scss +2 -1
- package/dist/responsive-item/ResponsiveItem.js.map +1 -1
- package/dist/responsive-item/ResponsiveItemOverlay.js.map +1 -1
- package/dist/responsive-item/responsiveItemOverlayStyles.js.map +1 -1
- package/dist/responsive-item/responsiveItemStyles.js.map +1 -1
- package/dist/scroll/ScrollLock.js.map +1 -1
- package/dist/scroll/useScrollLock.d.ts +1 -1
- package/dist/scroll/useScrollLock.js +1 -1
- package/dist/scroll/useScrollLock.js.map +1 -1
- package/dist/searching/fuzzy.d.ts +1 -1
- package/dist/searching/fuzzy.js.map +1 -1
- package/dist/searching/useFuzzyMatch.js.map +1 -1
- package/dist/segmented-button/SegmentedButton.js +1 -1
- package/dist/segmented-button/SegmentedButton.js.map +1 -1
- package/dist/segmented-button/SegmentedButtonContainer.js.map +1 -1
- package/dist/segmented-button/_segmented-button.scss +40 -0
- package/dist/segmented-button/segmentedButtonContainerStyles.js.map +1 -1
- package/dist/segmented-button/segmentedButtonStyles.js.map +1 -1
- package/dist/sheet/Sheet.js.map +1 -1
- package/dist/sheet/styles.js.map +1 -1
- package/dist/snackbar/DefaultToastRenderer.js.map +1 -1
- package/dist/snackbar/Snackbar.js.map +1 -1
- package/dist/snackbar/Toast.js.map +1 -1
- package/dist/snackbar/ToastActionButton.js.map +1 -1
- package/dist/snackbar/ToastCloseButton.js +1 -1
- package/dist/snackbar/ToastCloseButton.js.map +1 -1
- package/dist/snackbar/ToastContent.js.map +1 -1
- package/dist/snackbar/ToastManager.js.map +1 -1
- package/dist/snackbar/ToastManagerProvider.js.map +1 -1
- package/dist/snackbar/snackbarStyles.js.map +1 -1
- package/dist/snackbar/toastContentStyles.js.map +1 -1
- package/dist/snackbar/toastStyles.js.map +1 -1
- package/dist/snackbar/useCurrentToastActions.js.map +1 -1
- package/dist/storage/internalUtils.d.ts +19 -0
- package/dist/storage/internalUtils.js +22 -0
- package/dist/storage/internalUtils.js.map +1 -0
- package/dist/storage/types.d.ts +75 -0
- package/dist/storage/types.js +3 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/useStorage.d.ts +113 -0
- package/dist/storage/useStorage.js +247 -0
- package/dist/storage/useStorage.js.map +1 -0
- package/dist/storage/utils.d.ts +94 -0
- package/dist/storage/utils.js +106 -0
- package/dist/storage/utils.js.map +1 -0
- package/dist/suspense/CircularProgressSuspense.js.map +1 -1
- package/dist/suspense/NullSuspense.js.map +1 -1
- package/dist/table/StickyTableSection.js.map +1 -1
- package/dist/table/Table.js.map +1 -1
- package/dist/table/TableBody.js.map +1 -1
- package/dist/table/TableCell.js +1 -1
- package/dist/table/TableCell.js.map +1 -1
- package/dist/table/TableCellContent.js.map +1 -1
- package/dist/table/TableCheckbox.js.map +1 -1
- package/dist/table/TableConfigurationProvider.js.map +1 -1
- package/dist/table/TableContainer.js.map +1 -1
- package/dist/table/TableContainerProvider.js.map +1 -1
- package/dist/table/TableFooter.js.map +1 -1
- package/dist/table/TableHeader.js.map +1 -1
- package/dist/table/TableRadio.js.map +1 -1
- package/dist/table/TableRow.js.map +1 -1
- package/dist/table/_table.scss +0 -1
- package/dist/table/tableCellStyles.js.map +1 -1
- package/dist/table/tableFooterStyles.js.map +1 -1
- package/dist/table/tableHeaderStyles.js.map +1 -1
- package/dist/table/tableRowStyles.js.map +1 -1
- package/dist/table/tableStyles.js.map +1 -1
- package/dist/table/useStickyTableSection.js.map +1 -1
- package/dist/table/useTableSectionConfig.js.map +1 -1
- package/dist/tabs/SimpleTabPanel.d.ts +17 -0
- package/dist/tabs/SimpleTabPanel.js +21 -0
- package/dist/tabs/SimpleTabPanel.js.map +1 -0
- package/dist/tabs/SimpleTabPanels.d.ts +17 -0
- package/dist/tabs/SimpleTabPanels.js +18 -0
- package/dist/tabs/SimpleTabPanels.js.map +1 -0
- package/dist/tabs/Tab.js.map +1 -1
- package/dist/tabs/TabList.d.ts +8 -25
- package/dist/tabs/TabList.js +4 -6
- package/dist/tabs/TabList.js.map +1 -1
- package/dist/tabs/TabListScrollButton.js +2 -1
- package/dist/tabs/TabListScrollButton.js.map +1 -1
- package/dist/tabs/_tabs.scss +50 -14
- package/dist/tabs/tabIndicatorStyles.js.map +1 -1
- package/dist/tabs/tabListScrollButtonStyles.js.map +1 -1
- package/dist/tabs/tabListStyles.d.ts +9 -0
- package/dist/tabs/tabListStyles.js +2 -1
- package/dist/tabs/tabListStyles.js.map +1 -1
- package/dist/tabs/tabStyles.d.ts +7 -0
- package/dist/tabs/tabStyles.js.map +1 -1
- package/dist/tabs/types.d.ts +25 -0
- package/dist/tabs/types.js +24 -0
- package/dist/tabs/types.js.map +1 -0
- package/dist/tabs/useMaxTabPanelHeight.d.ts +82 -0
- package/dist/tabs/useMaxTabPanelHeight.js +95 -0
- package/dist/tabs/useMaxTabPanelHeight.js.map +1 -0
- package/dist/tabs/useTabList.d.ts +4 -2
- package/dist/tabs/useTabList.js +24 -6
- package/dist/tabs/useTabList.js.map +1 -1
- package/dist/tabs/useTabs.d.ts +53 -68
- package/dist/tabs/useTabs.js +6 -2
- package/dist/tabs/useTabs.js.map +1 -1
- package/dist/tabs/utils.d.ts +4 -0
- package/dist/tabs/utils.js +5 -0
- package/dist/tabs/utils.js.map +1 -1
- package/dist/test-utils/drag.d.ts +1 -0
- package/dist/test-utils/index.d.ts +6 -4
- package/dist/test-utils/index.js +6 -4
- package/dist/test-utils/index.js.map +1 -1
- package/dist/test-utils/jest-globals/index.d.ts +4 -0
- package/dist/test-utils/jest-globals/index.js +6 -0
- package/dist/test-utils/jest-globals/index.js.map +1 -0
- package/dist/test-utils/jest-globals/match-media.d.ts +32 -0
- package/dist/test-utils/jest-globals/match-media.js +35 -0
- package/dist/test-utils/jest-globals/match-media.js.map +1 -0
- package/dist/test-utils/jest-globals/resize-observer.d.ts +5 -0
- package/dist/test-utils/jest-globals/resize-observer.js +10 -0
- package/dist/test-utils/jest-globals/resize-observer.js.map +1 -0
- package/dist/test-utils/jest-globals/setup.d.ts +1 -0
- package/dist/test-utils/{jest-setup.js → jest-globals/setup.js} +4 -3
- package/dist/test-utils/jest-globals/setup.js.map +1 -0
- package/dist/test-utils/{timers.d.ts → jest-globals/timers.d.ts} +2 -2
- package/dist/test-utils/{timers.js → jest-globals/timers.js} +2 -2
- package/dist/test-utils/jest-globals/timers.js.map +1 -0
- package/dist/test-utils/jest-globals/uploadMenuItemFileInput.d.ts +32 -0
- package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js +39 -0
- package/dist/test-utils/jest-globals/uploadMenuItemFileInput.js.map +1 -0
- package/dist/test-utils/mocks/IntersectionObserver.js.map +1 -0
- package/dist/test-utils/{ResizeObserver.d.ts → mocks/ResizeObserver.d.ts} +16 -23
- package/dist/test-utils/{ResizeObserver.js → mocks/ResizeObserver.js} +17 -38
- package/dist/test-utils/mocks/ResizeObserver.js.map +1 -0
- package/dist/test-utils/mocks/match-media-implementation.d.ts +42 -0
- package/dist/test-utils/mocks/match-media-implementation.js +46 -0
- package/dist/test-utils/mocks/match-media-implementation.js.map +1 -0
- package/dist/test-utils/mocks/match-media.d.ts +32 -0
- package/dist/test-utils/mocks/match-media.js +39 -0
- package/dist/test-utils/mocks/match-media.js.map +1 -0
- package/dist/test-utils/polyfills/IntersectionObserver.js +1 -1
- package/dist/test-utils/polyfills/IntersectionObserver.js.map +1 -1
- package/dist/test-utils/polyfills/ResizeObserver.js +1 -1
- package/dist/test-utils/polyfills/ResizeObserver.js.map +1 -1
- package/dist/test-utils/polyfills/matchMedia.js +1 -1
- package/dist/test-utils/polyfills/matchMedia.js.map +1 -1
- package/dist/test-utils/queries/index.d.ts +2 -0
- package/dist/test-utils/queries/index.js +4 -0
- package/dist/test-utils/queries/index.js.map +1 -0
- package/dist/test-utils/queries/select.d.ts +67 -0
- package/dist/test-utils/queries/select.js +69 -0
- package/dist/test-utils/queries/select.js.map +1 -0
- package/dist/test-utils/queries/slider.d.ts +126 -0
- package/dist/test-utils/queries/slider.js +136 -0
- package/dist/test-utils/queries/slider.js.map +1 -0
- package/dist/test-utils/queries/types.d.ts +8 -0
- package/dist/test-utils/queries/types.js +5 -0
- package/dist/test-utils/queries/types.js.map +1 -0
- package/dist/test-utils/render.js.map +1 -1
- package/dist/test-utils/utils/createFileList.d.ts +4 -0
- package/dist/test-utils/utils/createFileList.js +27 -0
- package/dist/test-utils/utils/createFileList.js.map +1 -0
- package/dist/test-utils/utils/createResizeObserverEntry.d.ts +18 -0
- package/dist/test-utils/utils/createResizeObserverEntry.js +33 -0
- package/dist/test-utils/utils/createResizeObserverEntry.js.map +1 -0
- package/dist/test-utils/vitest/index.d.ts +4 -0
- package/dist/test-utils/vitest/index.js +6 -0
- package/dist/test-utils/vitest/index.js.map +1 -0
- package/dist/test-utils/vitest/match-media.d.ts +32 -0
- package/dist/test-utils/vitest/match-media.js +35 -0
- package/dist/test-utils/vitest/match-media.js.map +1 -0
- package/dist/test-utils/vitest/resize-observer.d.ts +5 -0
- package/dist/test-utils/vitest/resize-observer.js +10 -0
- package/dist/test-utils/vitest/resize-observer.js.map +1 -0
- package/dist/test-utils/vitest/setup.d.ts +1 -0
- package/dist/test-utils/vitest/setup.js +14 -0
- package/dist/test-utils/vitest/setup.js.map +1 -0
- package/dist/test-utils/vitest/timers.d.ts +42 -0
- package/dist/test-utils/vitest/timers.js +42 -0
- package/dist/test-utils/vitest/timers.js.map +1 -0
- package/dist/test-utils/vitest/uploadMenuItemFileInput.d.ts +32 -0
- package/dist/test-utils/vitest/uploadMenuItemFileInput.js +39 -0
- package/dist/test-utils/vitest/uploadMenuItemFileInput.js.map +1 -0
- package/dist/theme/LocalStorageColorSchemeProvider.d.ts +17 -17
- package/dist/theme/LocalStorageColorSchemeProvider.js +19 -19
- package/dist/theme/LocalStorageColorSchemeProvider.js.map +1 -1
- package/dist/theme/ThemeProvider.d.ts +2 -2
- package/dist/theme/ThemeProvider.js +4 -4
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/_theme.scss +0 -4
- package/dist/theme/isColorScheme.d.ts +5 -5
- package/dist/theme/isColorScheme.js +5 -5
- package/dist/theme/isColorScheme.js.map +1 -1
- package/dist/theme/types.d.ts +10 -22
- package/dist/theme/types.js.map +1 -1
- package/dist/theme/useCSSVariables.d.ts +8 -15
- package/dist/theme/useCSSVariables.js.map +1 -1
- package/dist/theme/useColorScheme.d.ts +15 -13
- package/dist/theme/useColorScheme.js +17 -15
- package/dist/theme/useColorScheme.js.map +1 -1
- package/dist/theme/useColorSchemeMetaTag.d.ts +15 -2
- package/dist/theme/useColorSchemeMetaTag.js +13 -0
- package/dist/theme/useColorSchemeMetaTag.js.map +1 -1
- package/dist/theme/useColorSchemeProvider.d.ts +18 -20
- package/dist/theme/useColorSchemeProvider.js +13 -13
- package/dist/theme/useColorSchemeProvider.js.map +1 -1
- package/dist/theme/{usePrefersDarkScheme.js → usePrefersDarkTheme.js} +1 -1
- package/dist/theme/usePrefersDarkTheme.js.map +1 -0
- package/dist/tooltip/Tooltip.js.map +1 -1
- package/dist/tooltip/TooltipHoverModeProvider.js.map +1 -1
- package/dist/tooltip/tooltipStyles.js.map +1 -1
- package/dist/tooltip/useTooltip.d.ts +5 -2
- package/dist/tooltip/useTooltip.js.map +1 -1
- package/dist/tooltip/useTooltipPosition.js.map +1 -1
- package/dist/transition/CSSTransition.js.map +1 -1
- package/dist/transition/Collapse.js.map +1 -1
- package/dist/transition/CrossFade.d.ts +1 -1
- package/dist/transition/CrossFade.js +1 -1
- package/dist/transition/CrossFade.js.map +1 -1
- package/dist/transition/ScaleTransition.js.map +1 -1
- package/dist/transition/SkeletonPlaceholder.js.map +1 -1
- package/dist/transition/Slide.js.map +1 -1
- package/dist/transition/SlideContainer.js.map +1 -1
- package/dist/transition/collapseStyles.js.map +1 -1
- package/dist/transition/config.d.ts +4 -1
- package/dist/transition/config.js.map +1 -1
- package/dist/transition/maxWidthTransition.d.ts +6 -0
- package/dist/transition/maxWidthTransition.js +3 -1
- package/dist/transition/maxWidthTransition.js.map +1 -1
- package/dist/transition/skeletonPlaceholderUtils.js.map +1 -1
- package/dist/transition/types.d.ts +0 -1
- package/dist/transition/types.js.map +1 -1
- package/dist/transition/useCSSTransition.d.ts +8 -4
- package/dist/transition/useCSSTransition.js +8 -4
- package/dist/transition/useCSSTransition.js.map +1 -1
- package/dist/transition/useCarousel.js.map +1 -1
- package/dist/transition/useCollapseTransition.d.ts +13 -8
- package/dist/transition/useCollapseTransition.js +11 -6
- package/dist/transition/useCollapseTransition.js.map +1 -1
- package/dist/transition/useCrossFadeTransition.js.map +1 -1
- package/dist/transition/useMaxWidthTransition.d.ts +9 -0
- package/dist/transition/useMaxWidthTransition.js +9 -0
- package/dist/transition/useMaxWidthTransition.js.map +1 -1
- package/dist/transition/useScaleTransition.d.ts +27 -6
- package/dist/transition/useScaleTransition.js +4 -2
- package/dist/transition/useScaleTransition.js.map +1 -1
- package/dist/transition/useSkeletonPlaceholder.d.ts +16 -0
- package/dist/transition/useSkeletonPlaceholder.js +13 -1
- package/dist/transition/useSkeletonPlaceholder.js.map +1 -1
- package/dist/transition/useSlideTransition.d.ts +12 -16
- package/dist/transition/useSlideTransition.js +12 -16
- package/dist/transition/useSlideTransition.js.map +1 -1
- package/dist/transition/useTransition.js +1 -1
- package/dist/transition/useTransition.js.map +1 -1
- package/dist/tree/DefaultTreeItemRenderer.js.map +1 -1
- package/dist/tree/Tree.js.map +1 -1
- package/dist/tree/TreeGroup.js.map +1 -1
- package/dist/tree/TreeItem.js.map +1 -1
- package/dist/tree/TreeItemExpander.js +1 -1
- package/dist/tree/TreeItemExpander.js.map +1 -1
- package/dist/tree/TreeProvider.js.map +1 -1
- package/dist/tree/_tree.scss +0 -1
- package/dist/tree/styles.js.map +1 -1
- package/dist/tree/types.js.map +1 -1
- package/dist/tree/useTree.js.map +1 -1
- package/dist/tree/useTreeExpansion.js.map +1 -1
- package/dist/tree/useTreeItems.d.ts +1 -1
- package/dist/tree/useTreeItems.js.map +1 -1
- package/dist/tree/useTreeMovement.js.map +1 -1
- package/dist/tree/useTreeSelection.js.map +1 -1
- package/dist/typography/SrOnly.js.map +1 -1
- package/dist/typography/TextContainer.js.map +1 -1
- package/dist/typography/Typography.js.map +1 -1
- package/dist/typography/WritingDirectionProvider.js.map +1 -1
- package/dist/typography/textContainerStyles.js.map +1 -1
- package/dist/typography/typographyStyles.js.map +1 -1
- package/dist/useAsyncFunction.d.ts +20 -0
- package/dist/useAsyncFunction.js.map +1 -1
- package/dist/useDebouncedFunction.js.map +1 -1
- package/dist/useDropzone.d.ts +18 -11
- package/dist/useDropzone.js +27 -23
- package/dist/useDropzone.js.map +1 -1
- package/dist/useElementSize.d.ts +3 -3
- package/dist/useElementSize.js +1 -1
- package/dist/useElementSize.js.map +1 -1
- package/dist/useEnsuredId.d.ts +1 -1
- package/dist/useEnsuredId.js +1 -1
- package/dist/useEnsuredId.js.map +1 -1
- package/dist/useEnsuredRef.d.ts +1 -1
- package/dist/useEnsuredRef.js +1 -1
- package/dist/useEnsuredRef.js.map +1 -1
- package/dist/useEnsuredState.js.map +1 -1
- package/dist/useHtmlClassName.d.ts +11 -0
- package/dist/useHtmlClassName.js +11 -0
- package/dist/useHtmlClassName.js.map +1 -1
- package/dist/useIntersectionObserver.d.ts +3 -3
- package/dist/useIntersectionObserver.js +2 -2
- package/dist/useIntersectionObserver.js.map +1 -1
- package/dist/useIsomorphicLayoutEffect.js.map +1 -1
- package/dist/useMutationObserver.d.ts +3 -3
- package/dist/useMutationObserver.js +4 -4
- package/dist/useMutationObserver.js.map +1 -1
- package/dist/useOrientation.d.ts +0 -1
- package/dist/useOrientation.js +0 -1
- package/dist/useOrientation.js.map +1 -1
- package/dist/usePageInactive.d.ts +7 -2
- package/dist/usePageInactive.js +7 -2
- package/dist/usePageInactive.js.map +1 -1
- package/dist/useReadonlySet.d.ts +5 -4
- package/dist/useReadonlySet.js +4 -3
- package/dist/useReadonlySet.js.map +1 -1
- package/dist/useResizeListener.d.ts +6 -4
- package/dist/useResizeListener.js +6 -4
- package/dist/useResizeListener.js.map +1 -1
- package/dist/useResizeObserver.d.ts +1 -1
- package/dist/useResizeObserver.js +1 -1
- package/dist/useResizeObserver.js.map +1 -1
- package/dist/useThrottledFunction.js.map +1 -1
- package/dist/useToggle.d.ts +3 -3
- package/dist/useToggle.js +3 -3
- package/dist/useToggle.js.map +1 -1
- package/dist/useUnmounted.js.map +1 -1
- package/dist/useWindowSize.d.ts +1 -1
- package/dist/useWindowSize.js +1 -1
- package/dist/useWindowSize.js.map +1 -1
- package/dist/utils/RenderRecursively.d.ts +88 -32
- package/dist/utils/RenderRecursively.js +88 -32
- package/dist/utils/RenderRecursively.js.map +1 -1
- package/dist/utils/alphaNumericSort.d.ts +5 -0
- package/dist/utils/alphaNumericSort.js +5 -4
- package/dist/utils/alphaNumericSort.js.map +1 -1
- package/dist/utils/bem.d.ts +49 -6
- package/dist/utils/bem.js +5 -14
- package/dist/utils/bem.js.map +1 -1
- package/dist/utils/getRangeDefaultValue.js.map +1 -1
- package/dist/utils/isElementVisible.d.ts +1 -1
- package/dist/utils/isElementVisible.js +1 -1
- package/dist/utils/isElementVisible.js.map +1 -1
- package/dist/utils/loop.d.ts +2 -0
- package/dist/utils/loop.js.map +1 -1
- package/dist/utils/parseCssLengthUnit.d.ts +1 -1
- package/dist/utils/parseCssLengthUnit.js.map +1 -1
- package/dist/utils/wait.d.ts +4 -4
- package/dist/utils/wait.js +6 -4
- package/dist/utils/wait.js.map +1 -1
- package/dist/window-splitter/WindowSplitter.js.map +1 -1
- package/dist/window-splitter/styles.js.map +1 -1
- package/dist/window-splitter/useWindowSplitter.d.ts +4 -1
- package/dist/window-splitter/useWindowSplitter.js +4 -1
- package/dist/window-splitter/useWindowSplitter.js.map +1 -1
- package/package.json +26 -22
- package/src/CoreProviders.tsx +8 -6
- package/src/NoSsr.tsx +3 -1
- package/src/RootHtml.tsx +1 -0
- package/src/SsrProvider.tsx +3 -2
- package/src/app-bar/AppBar.tsx +3 -2
- package/src/app-bar/AppBarTitle.tsx +1 -0
- package/src/app-bar/styles.ts +1 -0
- package/src/autocomplete/Autocomplete.tsx +2 -0
- package/src/autocomplete/AutocompleteChip.tsx +2 -1
- package/src/autocomplete/AutocompleteCircularProgress.tsx +1 -0
- package/src/autocomplete/AutocompleteClearButton.tsx +3 -1
- package/src/autocomplete/AutocompleteDropdownButton.tsx +3 -1
- package/src/autocomplete/AutocompleteListboxChildren.tsx +2 -0
- package/src/autocomplete/autocompleteStyles.ts +1 -0
- package/src/autocomplete/types.ts +1 -0
- package/src/autocomplete/useAutocomplete.ts +4 -2
- package/src/autocomplete/utils.ts +1 -0
- package/src/avatar/Avatar.tsx +3 -2
- package/src/avatar/styles.ts +2 -1
- package/src/badge/Badge.tsx +3 -2
- package/src/badge/styles.ts +1 -0
- package/src/box/Box.tsx +5 -2
- package/src/box/styles.ts +17 -2
- package/src/button/AsyncButton.tsx +3 -1
- package/src/button/Button.tsx +4 -2
- package/src/button/ButtonUnstyled.tsx +2 -1
- package/src/button/FloatingActionButton.tsx +2 -1
- package/src/button/TooltippedButton.tsx +4 -2
- package/src/button/buttonStyles.ts +2 -1
- package/src/card/Card.tsx +10 -23
- package/src/card/CardContent.tsx +3 -2
- package/src/card/CardFooter.tsx +1 -0
- package/src/card/CardHeader.tsx +2 -1
- package/src/card/CardSubtitle.tsx +1 -0
- package/src/card/CardTitle.tsx +1 -0
- package/src/card/ClickableCard.tsx +3 -1
- package/src/card/styles.ts +1 -0
- package/src/chip/Chip.tsx +4 -2
- package/src/chip/styles.ts +1 -0
- package/src/dialog/Dialog.tsx +10 -6
- package/src/dialog/DialogContent.tsx +3 -2
- package/src/dialog/DialogFooter.tsx +3 -2
- package/src/dialog/DialogHeader.tsx +2 -1
- package/src/dialog/DialogTitle.tsx +2 -1
- package/src/dialog/FixedDialog.tsx +14 -9
- package/src/dialog/NestedDialogProvider.ts +1 -0
- package/src/dialog/styles.ts +5 -4
- package/src/divider/Divider.tsx +3 -2
- package/src/divider/styles.ts +1 -0
- package/src/draggable/useDraggable.ts +25 -12
- package/src/draggable/utils.ts +2 -1
- package/src/expansion-panel/ExpansionList.tsx +3 -1
- package/src/expansion-panel/ExpansionPanel.tsx +3 -1
- package/src/expansion-panel/ExpansionPanelHeader.tsx +3 -2
- package/src/expansion-panel/expansionPanelStyles.ts +1 -0
- package/src/expansion-panel/useExpansionList.ts +2 -0
- package/src/expansion-panel/useExpansionPanels.ts +1 -0
- package/src/files/FileInput.tsx +4 -2
- package/src/files/styles.ts +1 -0
- package/src/files/useFileUpload.ts +7 -5
- package/src/files/utils.ts +31 -1
- package/src/focus/useFocusContainer.ts +10 -10
- package/src/form/Checkbox.tsx +2 -1
- package/src/form/Fieldset.tsx +2 -1
- package/src/form/Form.tsx +2 -1
- package/src/form/FormMessage.tsx +1 -0
- package/src/form/FormMessageContainer.tsx +2 -1
- package/src/form/FormMessageCounter.tsx +1 -0
- package/src/form/InputToggle.tsx +3 -1
- package/src/form/InputToggleIcon.tsx +4 -3
- package/src/form/Label.tsx +1 -0
- package/src/form/Legend.tsx +1 -0
- package/src/form/Listbox.tsx +1 -0
- package/src/form/ListboxProvider.ts +2 -0
- package/src/form/MenuItemCheckbox.tsx +5 -3
- package/src/form/MenuItemFileInput.tsx +25 -13
- package/src/form/MenuItemInputToggle.tsx +3 -1
- package/src/form/MenuItemRadio.tsx +4 -2
- package/src/form/MenuItemSwitch.tsx +2 -0
- package/src/form/MenuItemTextField.tsx +3 -1
- package/src/form/NativeSelect.tsx +3 -2
- package/src/form/OptGroup.tsx +3 -1
- package/src/form/Option.tsx +6 -4
- package/src/form/Password.tsx +5 -3
- package/src/form/Radio.tsx +2 -0
- package/src/form/ResizingTextAreaWrapper.tsx +2 -1
- package/src/form/Select.tsx +6 -4
- package/src/form/SelectedOption.tsx +1 -0
- package/src/form/Slider.tsx +13 -71
- package/src/form/SliderContainer.tsx +2 -1
- package/src/form/SliderMark.tsx +1 -0
- package/src/form/SliderMarkLabel.tsx +2 -1
- package/src/form/SliderThumb.tsx +6 -3
- package/src/form/SliderTrack.tsx +4 -3
- package/src/form/SliderValueMarks.tsx +3 -2
- package/src/form/SliderValueTooltip.tsx +2 -0
- package/src/form/Switch.tsx +2 -1
- package/src/form/SwitchTrack.tsx +2 -1
- package/src/form/TextArea.tsx +4 -2
- package/src/form/TextField.tsx +2 -1
- package/src/form/TextFieldAddon.tsx +1 -0
- package/src/form/TextFieldContainer.tsx +3 -1
- package/src/form/formMessageContainerStyles.ts +1 -0
- package/src/form/formMessageStyles.ts +1 -0
- package/src/form/inputToggleStyles.ts +1 -0
- package/src/form/menuItemInputToggleStyles.ts +1 -0
- package/src/form/nativeSelectStyles.ts +1 -0
- package/src/form/optionStyles.ts +1 -0
- package/src/form/passwordStyles.ts +1 -0
- package/src/form/selectStyles.ts +1 -0
- package/src/form/selectUtils.ts +2 -1
- package/src/form/sliderUtils.ts +8 -7
- package/src/form/switchStyles.ts +1 -0
- package/src/form/textAreaStyles.ts +2 -1
- package/src/form/textFieldContainerStyles.ts +2 -1
- package/src/form/textFieldStyles.ts +1 -0
- package/src/form/types.ts +1 -0
- package/src/form/useCheckboxGroup.ts +4 -2
- package/src/form/useCombobox.ts +4 -2
- package/src/form/useEditableCombobox.ts +2 -0
- package/src/form/useFormReset.ts +4 -2
- package/src/form/useNumberField.ts +3 -1
- package/src/form/useRadioGroup.ts +5 -3
- package/src/form/useRangeSlider.ts +3 -0
- package/src/form/useResizingTextArea.ts +5 -3
- package/src/form/useSelectCombobox.ts +2 -1
- package/src/form/useSlider.ts +3 -3
- package/src/form/useSliderDraggable.ts +71 -0
- package/src/form/useTextField.ts +40 -26
- package/src/form/useTextFieldContainerAddons.ts +4 -2
- package/src/form/validation.ts +2 -0
- package/src/hoverMode/useHoverMode.ts +76 -4
- package/src/hoverMode/useHoverModeProvider.ts +24 -12
- package/src/icon/FontIcon.tsx +3 -2
- package/src/icon/IconRotator.tsx +5 -4
- package/src/icon/MaterialIcon.tsx +3 -2
- package/src/icon/MaterialSymbol.tsx +4 -3
- package/src/icon/SVGIcon.tsx +3 -2
- package/src/icon/TextIconSpacing.tsx +2 -2
- package/src/icon/{iconConfig.tsx → config.tsx} +1 -0
- package/src/icon/materialConfig.ts +1 -0
- package/src/icon/styles.ts +2 -1
- package/src/interaction/Ripple.tsx +2 -0
- package/src/interaction/RippleContainer.tsx +1 -0
- package/src/interaction/UserInteractionModeProvider.tsx +3 -2
- package/src/interaction/useElementInteraction.tsx +39 -36
- package/src/interaction/useHigherContrastChildren.tsx +11 -8
- package/src/interaction/utils.ts +1 -0
- package/src/layout/LayoutAppBar.tsx +2 -0
- package/src/layout/LayoutNav.tsx +4 -2
- package/src/layout/LayoutWindowSplitter.tsx +4 -2
- package/src/layout/Main.tsx +4 -2
- package/src/layout/layoutNavStyles.ts +1 -0
- package/src/layout/layoutWindowSplitterStyles.ts +1 -0
- package/src/layout/mainStyles.ts +1 -0
- package/src/layout/useExpandableLayout.ts +17 -17
- package/src/layout/useHorizontalLayoutTransition.ts +2 -0
- package/src/layout/useLayoutAppBarHeight.ts +3 -1
- package/src/layout/useLayoutTree.ts +6 -3
- package/src/layout/useLayoutWindowSplitter.ts +2 -1
- package/src/layout/useMainTabIndex.ts +1 -0
- package/src/layout/useResizableLayout.ts +14 -17
- package/src/layout/useTemporaryLayout.ts +18 -11
- package/src/link/Link.tsx +3 -2
- package/src/link/SkipToMainContent.tsx +4 -2
- package/src/link/styles.ts +1 -0
- package/src/list/List.tsx +2 -1
- package/src/list/ListItem.tsx +4 -2
- package/src/list/ListItemAddon.tsx +2 -1
- package/src/list/ListItemChildren.tsx +1 -0
- package/src/list/ListItemLink.tsx +4 -2
- package/src/list/ListItemText.tsx +2 -1
- package/src/list/ListSubheader.tsx +2 -1
- package/src/list/listItemStyles.ts +1 -0
- package/src/list/listStyles.ts +1 -0
- package/src/list/types.ts +1 -0
- package/src/media-queries/AppSizeProvider.tsx +7 -5
- package/src/media-queries/useMediaQuery.ts +5 -3
- package/src/menu/DropdownMenu.tsx +5 -3
- package/src/menu/Menu.tsx +8 -6
- package/src/menu/MenuBar.tsx +2 -0
- package/src/menu/MenuButton.tsx +3 -1
- package/src/menu/MenuConfigurationProvider.tsx +4 -2
- package/src/menu/MenuItem.tsx +2 -0
- package/src/menu/MenuItemButton.tsx +3 -1
- package/src/menu/MenuItemCircularProgress.tsx +2 -1
- package/src/menu/MenuItemGroup.tsx +3 -1
- package/src/menu/MenuItemSeparator.tsx +3 -1
- package/src/menu/MenuSheet.tsx +3 -1
- package/src/menu/MenuVisibilityProvider.tsx +4 -2
- package/src/menu/MenuWidget.tsx +3 -1
- package/src/menu/MenuWidgetKeyboardProvider.tsx +2 -0
- package/src/menu/useContextMenu.ts +2 -0
- package/src/menu/useMenuBarProvider.ts +2 -0
- package/src/movement/types.ts +1 -0
- package/src/movement/useKeyboardMovementProvider.ts +2 -0
- package/src/movement/utils.ts +1 -0
- package/src/navigation/CollapsibleNavGroup.tsx +3 -1
- package/src/navigation/DefaultNavigationRenderer.tsx +1 -0
- package/src/navigation/NavGroup.tsx +2 -1
- package/src/navigation/NavItem.tsx +2 -1
- package/src/navigation/NavItemButton.tsx +4 -2
- package/src/navigation/NavItemLink.tsx +4 -2
- package/src/navigation/NavSubheader.tsx +2 -1
- package/src/navigation/Navigation.tsx +3 -2
- package/src/navigation/navGroupStyles.ts +1 -0
- package/src/navigation/navItemStyles.ts +1 -0
- package/src/navigation/types.ts +1 -0
- package/src/navigation/useActiveHeadingId.ts +8 -6
- package/src/navigation/useNavigationExpansion.ts +2 -0
- package/src/navigation/useTableOfContentsHeadings.ts +150 -0
- package/src/objectFit.ts +1 -0
- package/src/overlay/Overlay.tsx +4 -2
- package/src/overlay/overlayStyles.ts +10 -10
- package/src/portal/Portal.tsx +1 -0
- package/src/portal/PortalContainerProvider.tsx +4 -3
- package/src/positioning/createHorizontalPosition.ts +1 -1
- package/src/positioning/createVerticalPosition.ts +1 -1
- package/src/positioning/useFixedPositioning.ts +17 -12
- package/src/progress/CircularProgress.tsx +3 -2
- package/src/progress/LinearProgress.tsx +3 -2
- package/src/responsive-item/ResponsiveItem.tsx +3 -2
- package/src/responsive-item/ResponsiveItemOverlay.tsx +3 -2
- package/src/responsive-item/responsiveItemOverlayStyles.ts +1 -0
- package/src/responsive-item/responsiveItemStyles.ts +1 -0
- package/src/scroll/ScrollLock.tsx +1 -0
- package/src/scroll/useScrollLock.ts +3 -1
- package/src/searching/fuzzy.ts +1 -1
- package/src/searching/useFuzzyMatch.ts +2 -0
- package/src/segmented-button/SegmentedButton.tsx +4 -2
- package/src/segmented-button/SegmentedButtonContainer.tsx +3 -2
- package/src/segmented-button/segmentedButtonContainerStyles.ts +1 -0
- package/src/segmented-button/segmentedButtonStyles.ts +1 -0
- package/src/sheet/Sheet.tsx +4 -2
- package/src/sheet/styles.ts +3 -3
- package/src/snackbar/DefaultToastRenderer.tsx +5 -3
- package/src/snackbar/Snackbar.tsx +4 -2
- package/src/snackbar/Toast.tsx +4 -2
- package/src/snackbar/ToastActionButton.tsx +2 -0
- package/src/snackbar/ToastCloseButton.tsx +3 -1
- package/src/snackbar/ToastContent.tsx +3 -1
- package/src/snackbar/ToastManager.tsx +1 -0
- package/src/snackbar/ToastManagerProvider.tsx +4 -3
- package/src/snackbar/snackbarStyles.ts +1 -0
- package/src/snackbar/toastContentStyles.ts +1 -0
- package/src/snackbar/toastStyles.ts +2 -1
- package/src/snackbar/useCurrentToastActions.ts +1 -0
- package/src/storage/internalUtils.ts +43 -0
- package/src/storage/types.ts +88 -0
- package/src/storage/useStorage.ts +277 -0
- package/src/storage/utils.ts +156 -0
- package/src/suspense/CircularProgressSuspense.tsx +2 -1
- package/src/suspense/NullSuspense.tsx +1 -1
- package/src/table/StickyTableSection.tsx +3 -1
- package/src/table/Table.tsx +3 -1
- package/src/table/TableBody.tsx +3 -1
- package/src/table/TableCell.tsx +4 -2
- package/src/table/TableCellContent.tsx +2 -1
- package/src/table/TableCheckbox.tsx +3 -1
- package/src/table/TableConfigurationProvider.tsx +2 -0
- package/src/table/TableContainer.tsx +4 -2
- package/src/table/TableContainerProvider.tsx +2 -1
- package/src/table/TableFooter.tsx +3 -1
- package/src/table/TableHeader.tsx +3 -1
- package/src/table/TableRadio.tsx +3 -1
- package/src/table/TableRow.tsx +3 -1
- package/src/table/tableCellStyles.ts +1 -0
- package/src/table/tableFooterStyles.ts +1 -0
- package/src/table/tableHeaderStyles.ts +1 -0
- package/src/table/tableRowStyles.ts +1 -0
- package/src/table/tableStyles.ts +1 -0
- package/src/table/useStickyTableSection.tsx +4 -2
- package/src/table/useTableSectionConfig.ts +2 -0
- package/src/tabs/SimpleTabPanel.tsx +35 -0
- package/src/tabs/SimpleTabPanels.tsx +28 -0
- package/src/tabs/Tab.tsx +4 -3
- package/src/tabs/TabList.tsx +38 -51
- package/src/tabs/TabListScrollButton.tsx +6 -3
- package/src/tabs/tabIndicatorStyles.ts +1 -0
- package/src/tabs/tabListScrollButtonStyles.ts +1 -0
- package/src/tabs/tabListStyles.ts +22 -2
- package/src/tabs/tabStyles.ts +8 -0
- package/src/tabs/types.ts +30 -0
- package/src/tabs/useMaxTabPanelHeight.ts +138 -0
- package/src/tabs/useTabList.ts +45 -8
- package/src/tabs/useTabs.ts +64 -79
- package/src/tabs/utils.ts +9 -0
- package/src/test-utils/drag.ts +10 -2
- package/src/test-utils/index.ts +6 -5
- package/src/test-utils/jest-globals/index.ts +4 -0
- package/src/test-utils/jest-globals/match-media.ts +41 -0
- package/src/test-utils/jest-globals/resize-observer.ts +11 -0
- package/src/test-utils/{jest-setup.ts → jest-globals/setup.ts} +4 -2
- package/src/test-utils/{timers.ts → jest-globals/timers.ts} +2 -2
- package/src/test-utils/jest-globals/uploadMenuItemFileInput.ts +52 -0
- package/src/test-utils/{ResizeObserver.ts → mocks/ResizeObserver.ts} +25 -59
- package/src/test-utils/mocks/match-media-implementation.ts +111 -0
- package/src/test-utils/mocks/match-media.ts +63 -0
- package/src/test-utils/polyfills/IntersectionObserver.ts +1 -1
- package/src/test-utils/polyfills/ResizeObserver.ts +1 -1
- package/src/test-utils/polyfills/matchMedia.ts +1 -1
- package/src/test-utils/queries/index.ts +2 -0
- package/src/test-utils/queries/select.ts +116 -0
- package/src/test-utils/queries/slider.ts +247 -0
- package/src/test-utils/queries/types.ts +13 -0
- package/src/test-utils/render.tsx +2 -1
- package/src/test-utils/utils/createFileList.ts +27 -0
- package/src/test-utils/utils/createResizeObserverEntry.ts +47 -0
- package/src/test-utils/vitest/index.ts +4 -0
- package/src/test-utils/vitest/match-media.ts +41 -0
- package/src/test-utils/vitest/resize-observer.ts +11 -0
- package/src/test-utils/vitest/setup.ts +15 -0
- package/src/test-utils/vitest/timers.ts +48 -0
- package/src/test-utils/vitest/uploadMenuItemFileInput.ts +52 -0
- package/src/theme/LocalStorageColorSchemeProvider.tsx +30 -30
- package/src/theme/ThemeProvider.tsx +9 -7
- package/src/theme/isColorScheme.ts +8 -6
- package/src/theme/types.ts +11 -23
- package/src/theme/useCSSVariables.ts +10 -15
- package/src/theme/useColorScheme.ts +19 -15
- package/src/theme/useColorSchemeMetaTag.ts +17 -2
- package/src/theme/useColorSchemeProvider.ts +36 -37
- package/src/theme/{usePrefersDarkScheme.ts → usePrefersDarkTheme.ts} +1 -0
- package/src/tooltip/Tooltip.tsx +3 -1
- package/src/tooltip/TooltipHoverModeProvider.tsx +6 -4
- package/src/tooltip/tooltipStyles.ts +2 -1
- package/src/tooltip/useTooltip.ts +15 -10
- package/src/tooltip/useTooltipPosition.ts +2 -0
- package/src/transition/CSSTransition.tsx +3 -1
- package/src/transition/Collapse.tsx +4 -2
- package/src/transition/CrossFade.tsx +5 -3
- package/src/transition/ScaleTransition.tsx +4 -2
- package/src/transition/SkeletonPlaceholder.tsx +4 -2
- package/src/transition/Slide.tsx +3 -1
- package/src/transition/SlideContainer.tsx +2 -1
- package/src/transition/collapseStyles.ts +1 -0
- package/src/transition/config.ts +4 -1
- package/src/transition/maxWidthTransition.ts +7 -0
- package/src/transition/skeletonPlaceholderUtils.ts +1 -0
- package/src/transition/types.ts +0 -2
- package/src/transition/useCSSTransition.ts +10 -4
- package/src/transition/useCarousel.ts +2 -0
- package/src/transition/useCollapseTransition.ts +20 -14
- package/src/transition/useCrossFadeTransition.ts +1 -0
- package/src/transition/useMaxWidthTransition.ts +11 -0
- package/src/transition/useScaleTransition.ts +12 -10
- package/src/transition/useSkeletonPlaceholder.ts +20 -2
- package/src/transition/useSlideTransition.ts +14 -16
- package/src/transition/useTransition.ts +3 -1
- package/src/tree/DefaultTreeItemRenderer.tsx +1 -0
- package/src/tree/Tree.tsx +3 -1
- package/src/tree/TreeGroup.tsx +3 -1
- package/src/tree/TreeItem.tsx +4 -2
- package/src/tree/TreeItemExpander.tsx +5 -3
- package/src/tree/TreeProvider.tsx +4 -2
- package/src/tree/styles.ts +1 -0
- package/src/tree/types.ts +1 -0
- package/src/tree/useTree.ts +3 -2
- package/src/tree/useTreeExpansion.ts +1 -0
- package/src/tree/useTreeItems.ts +4 -3
- package/src/tree/useTreeMovement.ts +2 -0
- package/src/tree/useTreeSelection.ts +1 -0
- package/src/typography/SrOnly.tsx +2 -1
- package/src/typography/TextContainer.tsx +3 -2
- package/src/typography/Typography.tsx +3 -2
- package/src/typography/WritingDirectionProvider.tsx +4 -2
- package/src/typography/textContainerStyles.ts +1 -0
- package/src/typography/typographyStyles.ts +2 -1
- package/src/useAsyncFunction.ts +23 -0
- package/src/useDebouncedFunction.ts +2 -0
- package/src/useDropzone.ts +50 -34
- package/src/useElementSize.ts +7 -5
- package/src/useEnsuredId.ts +1 -1
- package/src/useEnsuredRef.ts +3 -1
- package/src/useEnsuredState.ts +1 -0
- package/src/useHtmlClassName.ts +12 -0
- package/src/useIntersectionObserver.ts +5 -3
- package/src/useIsomorphicLayoutEffect.ts +1 -0
- package/src/useMutationObserver.ts +7 -6
- package/src/useOrientation.ts +1 -1
- package/src/usePageInactive.ts +8 -2
- package/src/useReadonlySet.ts +7 -4
- package/src/useResizeListener.ts +8 -4
- package/src/useResizeObserver.ts +4 -3
- package/src/useThrottledFunction.ts +2 -0
- package/src/useToggle.ts +5 -3
- package/src/useUnmounted.ts +2 -0
- package/src/useWindowSize.ts +4 -2
- package/src/utils/RenderRecursively.tsx +88 -32
- package/src/utils/alphaNumericSort.ts +10 -4
- package/src/utils/bem.ts +58 -26
- package/src/utils/getRangeDefaultValue.ts +1 -1
- package/src/utils/isElementVisible.ts +1 -1
- package/src/utils/loop.ts +2 -0
- package/src/utils/parseCssLengthUnit.ts +1 -1
- package/src/utils/wait.ts +6 -5
- package/src/window-splitter/WindowSplitter.tsx +2 -2
- package/src/window-splitter/styles.ts +1 -0
- package/src/window-splitter/useWindowSplitter.ts +7 -2
- package/dist/icon/iconConfig.js.map +0 -1
- package/dist/test-utils/IntersectionObserver.js.map +0 -1
- package/dist/test-utils/ResizeObserver.js.map +0 -1
- package/dist/test-utils/jest-setup.d.ts +0 -1
- package/dist/test-utils/jest-setup.js.map +0 -1
- package/dist/test-utils/matchMedia.d.ts +0 -97
- package/dist/test-utils/matchMedia.js +0 -112
- package/dist/test-utils/matchMedia.js.map +0 -1
- package/dist/test-utils/timers.js.map +0 -1
- package/dist/theme/usePrefersDarkScheme.js.map +0 -1
- package/dist/useLocalStorage.d.ts +0 -368
- package/dist/useLocalStorage.js +0 -377
- package/dist/useLocalStorage.js.map +0 -1
- package/src/test-utils/README.md +0 -150
- package/src/test-utils/matchMedia.ts +0 -194
- package/src/useLocalStorage.ts +0 -584
- /package/dist/icon/{iconConfig.d.ts → config.d.ts} +0 -0
- /package/dist/test-utils/{IntersectionObserver.d.ts → mocks/IntersectionObserver.d.ts} +0 -0
- /package/dist/test-utils/{IntersectionObserver.js → mocks/IntersectionObserver.js} +0 -0
- /package/dist/theme/{usePrefersDarkScheme.d.ts → usePrefersDarkTheme.d.ts} +0 -0
- /package/src/test-utils/{IntersectionObserver.ts → mocks/IntersectionObserver.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/expansion-panel/useExpansionList.ts"],"sourcesContent":["\"use client\";\nimport type {\n FocusEventHandler,\n KeyboardEventHandler,\n MouseEventHandler,\n} from \"react\";\nimport type { KeyboardMovementProviderImplementation } from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nconst getPanelsOnly = (container: HTMLElement): readonly HTMLElement[] => [\n ...container.querySelectorAll<HTMLElement>(\".rmd-expansion-panel__button\"),\n];\n\n/** @since 6.0.0 */\nexport interface ExpansionListHookOptions<E extends HTMLElement> {\n onClick?: MouseEventHandler<E>;\n onFocus?: FocusEventHandler<E>;\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/** @since 6.0.0 */\nexport type ExpansionListImplementation<E extends HTMLElement> =\n KeyboardMovementProviderImplementation<E>;\n\n/**\n * @example Custom Implementation\n * ```tsx\n * import {\n * ExpansionPanel,\n * Form,\n * KeyboardMovementProvider,\n * useExpansionList,\n * useExpansionPanels,\n * } from \"@react-md/core\";\n * import type { ReactElement } from \"react\";\n *\n * import { BillingAddress } from \"./BillingAddress\";\n * import { BillingInformation } from \"./BillingInformation\";\n * import { PersonalInformation } from \"./PersonalInformation\";\n *\n * function Example(): ReactElement {\n * const { movementContext, movementProps } = useExpansionList();\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <Form {...movementProps}>\n * <ExpansionPanel {...getPanelProps(\"personal-information-panel\")}>\n * <PersonalInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(\"billing-information-panel\")}>\n * <BillingInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(\"billing-address-panel\")}>\n * <BillingAddress />\n * </ExpansionPanel>\n * </Form>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useExpansionList<E extends HTMLElement>(\n options: ExpansionListHookOptions<E> = {}\n): ExpansionListImplementation<E> {\n return useKeyboardMovementProvider({\n ...options,\n loopable: true,\n includeDisabled: true,\n getFocusableElements: getPanelsOnly,\n });\n}\n"],"names":["useKeyboardMovementProvider","getPanelsOnly","container","querySelectorAll","useExpansionList","options","loopable","includeDisabled","getFocusableElements"],"mappings":"AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/expansion-panel/useExpansionList.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n FocusEventHandler,\n KeyboardEventHandler,\n MouseEventHandler,\n} from \"react\";\n\nimport type { KeyboardMovementProviderImplementation } from \"../movement/types.js\";\nimport { useKeyboardMovementProvider } from \"../movement/useKeyboardMovementProvider.js\";\n\n/**\n * @internal\n * @since 6.0.0\n */\nconst getPanelsOnly = (container: HTMLElement): readonly HTMLElement[] => [\n ...container.querySelectorAll<HTMLElement>(\".rmd-expansion-panel__button\"),\n];\n\n/** @since 6.0.0 */\nexport interface ExpansionListHookOptions<E extends HTMLElement> {\n onClick?: MouseEventHandler<E>;\n onFocus?: FocusEventHandler<E>;\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/** @since 6.0.0 */\nexport type ExpansionListImplementation<E extends HTMLElement> =\n KeyboardMovementProviderImplementation<E>;\n\n/**\n * @example Custom Implementation\n * ```tsx\n * import {\n * ExpansionPanel,\n * Form,\n * KeyboardMovementProvider,\n * useExpansionList,\n * useExpansionPanels,\n * } from \"@react-md/core\";\n * import type { ReactElement } from \"react\";\n *\n * import { BillingAddress } from \"./BillingAddress\";\n * import { BillingInformation } from \"./BillingInformation\";\n * import { PersonalInformation } from \"./PersonalInformation\";\n *\n * function Example(): ReactElement {\n * const { movementContext, movementProps } = useExpansionList();\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <KeyboardMovementProvider value={movementContext}>\n * <Form {...movementProps}>\n * <ExpansionPanel {...getPanelProps(\"personal-information-panel\")}>\n * <PersonalInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(\"billing-information-panel\")}>\n * <BillingInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(\"billing-address-panel\")}>\n * <BillingAddress />\n * </ExpansionPanel>\n * </Form>\n * </KeyboardMovementProvider>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useExpansionList<E extends HTMLElement>(\n options: ExpansionListHookOptions<E> = {}\n): ExpansionListImplementation<E> {\n return useKeyboardMovementProvider({\n ...options,\n loopable: true,\n includeDisabled: true,\n getFocusableElements: getPanelsOnly,\n });\n}\n"],"names":["useKeyboardMovementProvider","getPanelsOnly","container","querySelectorAll","useExpansionList","options","loopable","includeDisabled","getFocusableElements"],"mappings":"AAAA;AASA,SAASA,2BAA2B,QAAQ,6CAA6C;AAEzF;;;CAGC,GACD,MAAMC,gBAAgB,CAACC,YAAmD;WACrEA,UAAUC,gBAAgB,CAAc;KAC5C;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCC,GACD,OAAO,SAASC,iBACdC,UAAuC,CAAC,CAAC;IAEzC,OAAOL,4BAA4B;QACjC,GAAGK,OAAO;QACVC,UAAU;QACVC,iBAAiB;QACjBC,sBAAsBP;IACxB;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/expansion-panel/useExpansionPanels.ts"],"sourcesContent":["\"use client\";\nimport type { UseStateInitializer, UseStateSetter } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useReadonlySet } from \"../useReadonlySet.js\";\nimport type { ExpansionPanelProps } from \"./ExpansionPanel.js\";\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelHookOptions {\n /**\n * An optional id to prefix each panel with.\n *\n * @defaultValue `\"expansion-panel-\" + useId()`\n */\n baseId?: string;\n\n /**\n * Set this to `true` if multiple panels can be open at the same time.\n *\n * @defaultValue `false`\n */\n multiple?: boolean;\n\n /**\n * Set this to `true` to enforce that at least one panel must always be\n * expanded.\n *\n * @defaultValue `false`\n */\n preventAllCollapsed?: boolean;\n\n /**\n * This is a convenience option to disable the expansion transition for all\n * panels.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @defaultValue `preventAllCollapsed ? [\"expansion-panel-\" + useId() + \"-1\"] : []`\n */\n defaultExpandedIds?: UseStateInitializer<string[]>;\n\n /**\n * This can only be used if the {@link defaultExpandedIds} was not provided\n * and using index based panels.\n *\n * @example\n * ```tsx\n * const { getPanelProps } = useExpansionPanels({\n * defaultExpandedIndex: 2,\n * });\n *\n * return (\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * // expanded on first render\n * <ExpansionPanel {...getPanelProps(2)} />\n * <ExpansionPanel {...getPanelProps(3)} />\n * );\n * ```\n */\n defaultExpandedIndex?: number;\n\n /**\n * @defaultValue `false`\n */\n disableContentPadding?: boolean;\n}\n\n/** @since 6.0.0 */\nexport type ProvidedExpansionPanelProps = Pick<\n Required<ExpansionPanelProps>,\n | \"disabled\"\n | \"expanded\"\n | \"onExpandClick\"\n | \"disableTransition\"\n | \"disableContentPadding\"\n> & { id?: string };\n\n/**\n * @param indexOrPanelId - This should either be a DOM id to use for the panel\n * or the panel's index.\n * @returns Props to pass to an `ExpansionPanel` for it to work correctly.\n * @since 6.0.0\n */\nexport type GetExpansionPanelProps = (\n indexOrPanelId: string | number\n) => ProvidedExpansionPanelProps;\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelImplementation {\n /**\n * The current set of expanded panel ids if you need this for some reason.\n */\n expandedIds: ReadonlySet<string>;\n\n /**\n * This can be used to manually control which panels are expanded if the\n * default behavior does not work for your use case.\n */\n setExpandedIds: UseStateSetter<ReadonlySet<string>>;\n\n /**\n * @example Index Based Panels\n * ```tsx\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * <ExpansionPanel {...getPanelProps(2)} />\n * ```\n *\n * @example Custom Panel Ids\n * ```tsx\n * <ExpansionPanel {...getPanelProps(\"address-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"billing-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"confirmation-panel\")} />\n * ```\n */\n getPanelProps: GetExpansionPanelProps;\n}\n\n/**\n * Use this hook to control the expanded state for a group of `ExpansionPanel`.\n *\n * @example Index Based Panels\n * ```tsx\n * import {\n * ExpansionList,\n * ExpansionPanel,\n * useExpansionPanels,\n * } from \"@react-md/core\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(0)} headerChildren=\"Panel 1\">\n * Panel 1 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(1)} headerChildren=\"Panel 2\">\n * Panel 2 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(2)} headerChildren=\"Panel 3\">\n * Panel 3 Contents\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n * @example Custom Panel Ids and Expand All Panels by Default\n * ```tsx\n * import {\n * ExpansionList,\n * ExpansionPanel,\n * useExpansionPanels,\n * } from \"@react-md/core\";\n * import { type ReactElement } from \"react\";\n *\n * import { BillingAddress } from \"./BillingAddress\";\n * import { BillingInformation } from \"./BillingInformation\";\n * import { PersonalInformation } from \"./PersonalInformation\";\n *\n * const panel1Id = \"personal-information-panel\";\n * const panel2Id = \"billing-information-panel\";\n * const panel3Id = \"billing-address-panel\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels({\n * multiple: true,\n * defaultExpandedIds: () => [panel1Id, panel2Id, panel3Id],\n * });\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(panel1Id)} headerChildren=\"Personal Information\">\n * <PersonalInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel2Id)} headerChildren=\"Billing Information\">\n * <BillingInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel3Id)} headerChildren=\"Billing Address\">\n * <BillingAddress />\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n *\n * @since 6.0.0 The hook was renamed from `usePanels` to `useExpansionPanels`,\n * the API changed to return `getPanelProps` instead of a generated list of\n * panel props based on the provided `count`, and the hook no longer supports\n * having all panels expanded by default.\n */\nexport function useExpansionPanels(\n options: ExpansionPanelHookOptions = {}\n): ExpansionPanelImplementation {\n const {\n baseId: propBaseId,\n multiple = false,\n preventAllCollapsed = false,\n disableTransition = false,\n defaultExpandedIds,\n defaultExpandedIndex,\n disableContentPadding = false,\n } = options;\n\n const baseId = useEnsuredId(propBaseId, \"expansion-panel\");\n const createId = (index: number): string => `${baseId}-${index + 1}`;\n const {\n value: expandedIds,\n setValue: setExpandedIds,\n toggleValue,\n } = useReadonlySet({\n toggleType: multiple ? \"multiple\" : \"single\",\n defaultValue: () => {\n if (typeof defaultExpandedIds === \"undefined\") {\n const initialList: string[] = [];\n if (typeof defaultExpandedIndex === \"number\" || preventAllCollapsed) {\n initialList.push(createId(defaultExpandedIndex ?? 0));\n }\n\n return new Set(initialList);\n }\n\n return typeof defaultExpandedIds === \"function\"\n ? defaultExpandedIds()\n : defaultExpandedIds;\n },\n });\n\n return {\n expandedIds,\n setExpandedIds,\n getPanelProps(indexOrPanelId) {\n let id: string | undefined;\n let panelId: string;\n if (typeof indexOrPanelId === \"number\") {\n id = createId(indexOrPanelId);\n panelId = id;\n } else {\n panelId = indexOrPanelId;\n }\n\n const expanded = expandedIds.has(panelId);\n const disabled =\n expanded && preventAllCollapsed && expandedIds.size === 1;\n return {\n id,\n disabled,\n expanded,\n onExpandClick() {\n if (disabled) {\n return;\n }\n\n toggleValue(panelId);\n },\n disableTransition,\n disableContentPadding,\n };\n },\n };\n}\n"],"names":["useEnsuredId","useReadonlySet","useExpansionPanels","options","baseId","propBaseId","multiple","preventAllCollapsed","disableTransition","defaultExpandedIds","defaultExpandedIndex","disableContentPadding","createId","index","value","expandedIds","setValue","setExpandedIds","toggleValue","toggleType","defaultValue","initialList","push","Set","getPanelProps","indexOrPanelId","id","panelId","expanded","has","disabled","size","onExpandClick"],"mappings":"AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/expansion-panel/useExpansionPanels.ts"],"sourcesContent":["\"use client\";\n\nimport type { UseStateInitializer, UseStateSetter } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useReadonlySet } from \"../useReadonlySet.js\";\nimport type { ExpansionPanelProps } from \"./ExpansionPanel.js\";\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelHookOptions {\n /**\n * An optional id to prefix each panel with.\n *\n * @defaultValue `\"expansion-panel-\" + useId()`\n */\n baseId?: string;\n\n /**\n * Set this to `true` if multiple panels can be open at the same time.\n *\n * @defaultValue `false`\n */\n multiple?: boolean;\n\n /**\n * Set this to `true` to enforce that at least one panel must always be\n * expanded.\n *\n * @defaultValue `false`\n */\n preventAllCollapsed?: boolean;\n\n /**\n * This is a convenience option to disable the expansion transition for all\n * panels.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * @defaultValue `preventAllCollapsed ? [\"expansion-panel-\" + useId() + \"-1\"] : []`\n */\n defaultExpandedIds?: UseStateInitializer<string[]>;\n\n /**\n * This can only be used if the {@link defaultExpandedIds} was not provided\n * and using index based panels.\n *\n * @example\n * ```tsx\n * const { getPanelProps } = useExpansionPanels({\n * defaultExpandedIndex: 2,\n * });\n *\n * return (\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * // expanded on first render\n * <ExpansionPanel {...getPanelProps(2)} />\n * <ExpansionPanel {...getPanelProps(3)} />\n * );\n * ```\n */\n defaultExpandedIndex?: number;\n\n /**\n * @defaultValue `false`\n */\n disableContentPadding?: boolean;\n}\n\n/** @since 6.0.0 */\nexport type ProvidedExpansionPanelProps = Pick<\n Required<ExpansionPanelProps>,\n | \"disabled\"\n | \"expanded\"\n | \"onExpandClick\"\n | \"disableTransition\"\n | \"disableContentPadding\"\n> & { id?: string };\n\n/**\n * @param indexOrPanelId - This should either be a DOM id to use for the panel\n * or the panel's index.\n * @returns Props to pass to an `ExpansionPanel` for it to work correctly.\n * @since 6.0.0\n */\nexport type GetExpansionPanelProps = (\n indexOrPanelId: string | number\n) => ProvidedExpansionPanelProps;\n\n/** @since 6.0.0 */\nexport interface ExpansionPanelImplementation {\n /**\n * The current set of expanded panel ids if you need this for some reason.\n */\n expandedIds: ReadonlySet<string>;\n\n /**\n * This can be used to manually control which panels are expanded if the\n * default behavior does not work for your use case.\n */\n setExpandedIds: UseStateSetter<ReadonlySet<string>>;\n\n /**\n * @example Index Based Panels\n * ```tsx\n * <ExpansionPanel {...getPanelProps(0)} />\n * <ExpansionPanel {...getPanelProps(1)} />\n * <ExpansionPanel {...getPanelProps(2)} />\n * ```\n *\n * @example Custom Panel Ids\n * ```tsx\n * <ExpansionPanel {...getPanelProps(\"address-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"billing-panel\")} />\n * <ExpansionPanel {...getPanelProps(\"confirmation-panel\")} />\n * ```\n */\n getPanelProps: GetExpansionPanelProps;\n}\n\n/**\n * Use this hook to control the expanded state for a group of `ExpansionPanel`.\n *\n * @example Index Based Panels\n * ```tsx\n * import {\n * ExpansionList,\n * ExpansionPanel,\n * useExpansionPanels,\n * } from \"@react-md/core\";\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels();\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(0)} headerChildren=\"Panel 1\">\n * Panel 1 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(1)} headerChildren=\"Panel 2\">\n * Panel 2 Contents\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(2)} headerChildren=\"Panel 3\">\n * Panel 3 Contents\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n * @example Custom Panel Ids and Expand All Panels by Default\n * ```tsx\n * import {\n * ExpansionList,\n * ExpansionPanel,\n * useExpansionPanels,\n * } from \"@react-md/core\";\n * import { type ReactElement } from \"react\";\n *\n * import { BillingAddress } from \"./BillingAddress\";\n * import { BillingInformation } from \"./BillingInformation\";\n * import { PersonalInformation } from \"./PersonalInformation\";\n *\n * const panel1Id = \"personal-information-panel\";\n * const panel2Id = \"billing-information-panel\";\n * const panel3Id = \"billing-address-panel\";\n *\n * function Example(): ReactElement {\n * const { getPanelProps } = useExpansionPanels({\n * multiple: true,\n * defaultExpandedIds: () => [panel1Id, panel2Id, panel3Id],\n * });\n *\n * return (\n * <ExpansionList>\n * <ExpansionPanel {...getPanelProps(panel1Id)} headerChildren=\"Personal Information\">\n * <PersonalInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel2Id)} headerChildren=\"Billing Information\">\n * <BillingInformation />\n * </ExpansionPanel>\n * <ExpansionPanel {...getPanelProps(panel3Id)} headerChildren=\"Billing Address\">\n * <BillingAddress />\n * </ExpansionPanel>\n * </ExpansionList>\n * );\n * }\n * ```\n *\n *\n * @since 6.0.0 The hook was renamed from `usePanels` to `useExpansionPanels`,\n * the API changed to return `getPanelProps` instead of a generated list of\n * panel props based on the provided `count`, and the hook no longer supports\n * having all panels expanded by default.\n */\nexport function useExpansionPanels(\n options: ExpansionPanelHookOptions = {}\n): ExpansionPanelImplementation {\n const {\n baseId: propBaseId,\n multiple = false,\n preventAllCollapsed = false,\n disableTransition = false,\n defaultExpandedIds,\n defaultExpandedIndex,\n disableContentPadding = false,\n } = options;\n\n const baseId = useEnsuredId(propBaseId, \"expansion-panel\");\n const createId = (index: number): string => `${baseId}-${index + 1}`;\n const {\n value: expandedIds,\n setValue: setExpandedIds,\n toggleValue,\n } = useReadonlySet({\n toggleType: multiple ? \"multiple\" : \"single\",\n defaultValue: () => {\n if (typeof defaultExpandedIds === \"undefined\") {\n const initialList: string[] = [];\n if (typeof defaultExpandedIndex === \"number\" || preventAllCollapsed) {\n initialList.push(createId(defaultExpandedIndex ?? 0));\n }\n\n return new Set(initialList);\n }\n\n return typeof defaultExpandedIds === \"function\"\n ? defaultExpandedIds()\n : defaultExpandedIds;\n },\n });\n\n return {\n expandedIds,\n setExpandedIds,\n getPanelProps(indexOrPanelId) {\n let id: string | undefined;\n let panelId: string;\n if (typeof indexOrPanelId === \"number\") {\n id = createId(indexOrPanelId);\n panelId = id;\n } else {\n panelId = indexOrPanelId;\n }\n\n const expanded = expandedIds.has(panelId);\n const disabled =\n expanded && preventAllCollapsed && expandedIds.size === 1;\n return {\n id,\n disabled,\n expanded,\n onExpandClick() {\n if (disabled) {\n return;\n }\n\n toggleValue(panelId);\n },\n disableTransition,\n disableContentPadding,\n };\n },\n };\n}\n"],"names":["useEnsuredId","useReadonlySet","useExpansionPanels","options","baseId","propBaseId","multiple","preventAllCollapsed","disableTransition","defaultExpandedIds","defaultExpandedIndex","disableContentPadding","createId","index","value","expandedIds","setValue","setExpandedIds","toggleValue","toggleType","defaultValue","initialList","push","Set","getPanelProps","indexOrPanelId","id","panelId","expanded","has","disabled","size","onExpandClick"],"mappings":"AAAA;AAGA,SAASA,YAAY,QAAQ,qBAAqB;AAClD,SAASC,cAAc,QAAQ,uBAAuB;AAsHtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EC,GACD,OAAO,SAASC,mBACdC,UAAqC,CAAC,CAAC;IAEvC,MAAM,EACJC,QAAQC,UAAU,EAClBC,WAAW,KAAK,EAChBC,sBAAsB,KAAK,EAC3BC,oBAAoB,KAAK,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,wBAAwB,KAAK,EAC9B,GAAGR;IAEJ,MAAMC,SAASJ,aAAaK,YAAY;IACxC,MAAMO,WAAW,CAACC,QAA0B,GAAGT,OAAO,CAAC,EAAES,QAAQ,GAAG;IACpE,MAAM,EACJC,OAAOC,WAAW,EAClBC,UAAUC,cAAc,EACxBC,WAAW,EACZ,GAAGjB,eAAe;QACjBkB,YAAYb,WAAW,aAAa;QACpCc,cAAc;YACZ,IAAI,OAAOX,uBAAuB,aAAa;gBAC7C,MAAMY,cAAwB,EAAE;gBAChC,IAAI,OAAOX,yBAAyB,YAAYH,qBAAqB;oBACnEc,YAAYC,IAAI,CAACV,SAASF,wBAAwB;gBACpD;gBAEA,OAAO,IAAIa,IAAIF;YACjB;YAEA,OAAO,OAAOZ,uBAAuB,aACjCA,uBACAA;QACN;IACF;IAEA,OAAO;QACLM;QACAE;QACAO,eAAcC,cAAc;YAC1B,IAAIC;YACJ,IAAIC;YACJ,IAAI,OAAOF,mBAAmB,UAAU;gBACtCC,KAAKd,SAASa;gBACdE,UAAUD;YACZ,OAAO;gBACLC,UAAUF;YACZ;YAEA,MAAMG,WAAWb,YAAYc,GAAG,CAACF;YACjC,MAAMG,WACJF,YAAYrB,uBAAuBQ,YAAYgB,IAAI,KAAK;YAC1D,OAAO;gBACLL;gBACAI;gBACAF;gBACAI;oBACE,IAAIF,UAAU;wBACZ;oBACF;oBAEAZ,YAAYS;gBACd;gBACAnB;gBACAG;YACF;QACF;IACF;AACF"}
|
package/dist/files/FileInput.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
|
-
import { getIcon } from "../icon/
|
|
4
|
+
import { getIcon } from "../icon/config.js";
|
|
5
5
|
import { useElementInteraction } from "../interaction/useElementInteraction.js";
|
|
6
6
|
import { SrOnly } from "../typography/SrOnly.js";
|
|
7
7
|
import { useEnsuredId } from "../useEnsuredId.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/files/FileInput.tsx"],"sourcesContent":["\"use client\";\nimport {\n
|
|
1
|
+
{"version":3,"sources":["../../src/files/FileInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type InputHTMLAttributes,\n type LabelHTMLAttributes,\n type ReactNode,\n forwardRef,\n} from \"react\";\n\nimport { type ButtonClassNameThemeOptions } from \"../button/buttonStyles.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { type ComponentWithRippleProps } from \"../interaction/types.js\";\nimport { useElementInteraction } from \"../interaction/useElementInteraction.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { SrOnly } from \"../typography/SrOnly.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { fileInput } from \"./styles.js\";\n\n/** @since 6.0.0 */\nexport type FileInputHTMLAttributes = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"type\"\n>;\n\n/**\n * @since 6.0.0 Removed the `disableIconSpacing` prop since it is no\n * longer required.\n */\nexport interface FileInputProps\n extends ButtonClassNameThemeOptions,\n FileInputHTMLAttributes,\n ComponentWithRippleProps {\n /**\n * This is the label text for icon-only file inputs.\n *\n * @defaultValue `\"Upload\"`\n */\n srOnlyLabel?: ReactNode;\n\n /**\n * Any additional props to provide to the container `<label>` element since\n * most props get passed to the `<input type=\"file\">`. So this would be useful\n * for inline style or click handlers.\n */\n labelProps?: PropsWithRef<\n LabelHTMLAttributes<HTMLLabelElement>,\n HTMLLabelElement\n >;\n\n /**\n * An optional icon to display for the file input.\n *\n * @defaultValue `getIcon(\"upload\")`\n */\n icon?: ReactNode;\n\n /**\n * Boolean if the icon should appear after the children in the label.\n *\n * @defaultValue `false`\n */\n iconAfter?: boolean;\n\n /**\n * Boolean if the file input should no longer allow the same file to be\n * selected multiple times and trigger the `onChange` each time it is\n * selected.\n *\n * @defaultValue `false`\n */\n disableRepeatableFiles?: boolean;\n\n /**\n * Children should generally be provided when the {@link buttonType} is\n * set to `\"text\"`. This defaults to a screen-reader only accessible text.\n *\n * @defaultValue `<SrOnly phoneOnly={responsive}>Upload</SrOnly>`\n */\n children?: ReactNode;\n}\n\n/**\n * **Client Component**\n * This might be able to become a server component if I remove the getIcon hook\n *\n * @example Simple Example\n * ```tsx\n * import { FileInput, Form } from \"@react-md/core\";\n * import type { ReactElement } from \"react\";\n *\n * const extensions = [\n * \"svg\",\n * \"jpeg\",\n * \"jpg\",\n * \"png\",\n * \"apng\",\n * \"mkv\",\n * \"mp4\",\n * \"mpeg\",\n * \"mpg\",\n * \"webm\",\n * \"mov\",\n * ] as const;\n *\n * const FOUR_HUNDRED_MB = 400 * 1024 * 1024;\n * const maxFiles = 10;\n *\n * function Example(): ReactElement {\n * const { stats, errors, onChange, clearErrors, reset, remove, accept } =\n * useFileUpload({\n * maxFiles,\n * maxFileSize: FOUR_HUNDRED_MB,\n * extensions,\n * });\n *\n * return (\n * <Form>\n * <FileInput accept={accept} multiple={maxFiles > 1} onChange={onChange} />\n * <Button onClick={reset} disabled={!stats.length}>\n * Remove all files\n * </Button>\n * </Form>\n * );\n * }\n * ```\n *\n * @since 6.0.0 Added additional support for `iconSize` and\n * `responsive`. Also removed the `disableIconSpacing` prop since it is no\n * longer required.\n */\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(\n function FileInput(props, ref) {\n const {\n id: propId,\n className,\n children: propChildren,\n icon: propIcon,\n iconAfter = false,\n srOnlyLabel = \"Upload\",\n disableRepeatableFiles = false,\n labelProps,\n theme = \"primary\",\n themeType = \"contained\",\n buttonType = propChildren ? \"text\" : \"icon\",\n disabled = false,\n iconSize,\n responsive,\n multiple = false,\n disableRipple,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"file-input\");\n const { pressed, pressedClassName, ripples, handlers } =\n useElementInteraction({\n ...labelProps,\n mode: disableRipple ? \"none\" : undefined,\n onClick(event) {\n labelProps?.onClick?.(event);\n\n // stop propagation so 2 ripples are not created\n event.stopPropagation();\n },\n disabled,\n });\n\n const icon = getIcon(\"upload\", propIcon);\n let children = propChildren;\n if (\n typeof propChildren === \"undefined\" &&\n !props[\"aria-label\"] &&\n !props[\"aria-labelledby\"]\n ) {\n children = <SrOnly phoneOnly={responsive}>{srOnlyLabel}</SrOnly>;\n }\n\n return (\n <label\n {...labelProps}\n {...handlers}\n className={fileInput({\n theme,\n themeType,\n buttonType,\n disabled,\n iconSize,\n pressed,\n responsive,\n pressedClassName,\n className: className || labelProps?.className,\n })}\n >\n {!iconAfter && icon}\n {children}\n {iconAfter && icon}\n <input\n {...remaining}\n id={id}\n ref={ref}\n value={\n disableRepeatableFiles || !props.onChange ? remaining.value : \"\"\n }\n type=\"file\"\n className=\"rmd-hidden-input\"\n disabled={disabled}\n multiple={multiple}\n />\n {ripples}\n </label>\n );\n }\n);\n"],"names":["forwardRef","getIcon","useElementInteraction","SrOnly","useEnsuredId","fileInput","FileInput","props","ref","id","propId","className","children","propChildren","icon","propIcon","iconAfter","srOnlyLabel","disableRepeatableFiles","labelProps","theme","themeType","buttonType","disabled","iconSize","responsive","multiple","disableRipple","remaining","pressed","pressedClassName","ripples","handlers","mode","undefined","onClick","event","stopPropagation","phoneOnly","label","input","value","onChange","type"],"mappings":"AAAA;;AAEA,SAIEA,UAAU,QACL,QAAQ;AAGf,SAASC,OAAO,QAAQ,oBAAoB;AAE5C,SAASC,qBAAqB,QAAQ,0CAA0C;AAEhF,SAASC,MAAM,QAAQ,0BAA0B;AACjD,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,SAAS,QAAQ,cAAc;AAiExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDC,GACD,OAAO,MAAMC,0BAAYN,WACvB,SAASM,UAAUC,KAAK,EAAEC,GAAG;IAC3B,MAAM,EACJC,IAAIC,MAAM,EACVC,SAAS,EACTC,UAAUC,YAAY,EACtBC,MAAMC,QAAQ,EACdC,YAAY,KAAK,EACjBC,cAAc,QAAQ,EACtBC,yBAAyB,KAAK,EAC9BC,UAAU,EACVC,QAAQ,SAAS,EACjBC,YAAY,WAAW,EACvBC,aAAaT,eAAe,SAAS,MAAM,EAC3CU,WAAW,KAAK,EAChBC,QAAQ,EACRC,UAAU,EACVC,WAAW,KAAK,EAChBC,aAAa,EACb,GAAGC,WACJ,GAAGrB;IACJ,MAAME,KAAKL,aAAaM,QAAQ;IAChC,MAAM,EAAEmB,OAAO,EAAEC,gBAAgB,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GACpD9B,sBAAsB;QACpB,GAAGiB,UAAU;QACbc,MAAMN,gBAAgB,SAASO;QAC/BC,SAAQC,KAAK;YACXjB,YAAYgB,UAAUC;YAEtB,gDAAgD;YAChDA,MAAMC,eAAe;QACvB;QACAd;IACF;IAEF,MAAMT,OAAOb,QAAQ,UAAUc;IAC/B,IAAIH,WAAWC;IACf,IACE,OAAOA,iBAAiB,eACxB,CAACN,KAAK,CAAC,aAAa,IACpB,CAACA,KAAK,CAAC,kBAAkB,EACzB;QACAK,yBAAW,KAACT;YAAOmC,WAAWb;sBAAaR;;IAC7C;IAEA,qBACE,MAACsB;QACE,GAAGpB,UAAU;QACb,GAAGa,QAAQ;QACZrB,WAAWN,UAAU;YACnBe;YACAC;YACAC;YACAC;YACAC;YACAK;YACAJ;YACAK;YACAnB,WAAWA,aAAaQ,YAAYR;QACtC;;YAEC,CAACK,aAAaF;YACdF;YACAI,aAAaF;0BACd,KAAC0B;gBACE,GAAGZ,SAAS;gBACbnB,IAAIA;gBACJD,KAAKA;gBACLiC,OACEvB,0BAA0B,CAACX,MAAMmC,QAAQ,GAAGd,UAAUa,KAAK,GAAG;gBAEhEE,MAAK;gBACLhC,WAAU;gBACVY,UAAUA;gBACVG,UAAUA;;YAEXK;;;AAGP,GACA"}
|
package/dist/files/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/files/styles.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport { type ButtonClassNameOptions, button } from \"../button/buttonStyles.js\";\n\n/** @since 6.0.0 */\nexport type FileInputClassNameOptions = ButtonClassNameOptions;\n\n/** @since 6.0.0 */\nexport function fileInput(options: FileInputClassNameOptions = {}): string {\n return cnb(\"rmd-file-input\", button(options));\n}\n"],"names":["cnb","button","fileInput","options"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;
|
|
1
|
+
{"version":3,"sources":["../../src/files/styles.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\nimport { type ButtonClassNameOptions, button } from \"../button/buttonStyles.js\";\n\n/** @since 6.0.0 */\nexport type FileInputClassNameOptions = ButtonClassNameOptions;\n\n/** @since 6.0.0 */\nexport function fileInput(options: FileInputClassNameOptions = {}): string {\n return cnb(\"rmd-file-input\", button(options));\n}\n"],"names":["cnb","button","fileInput","options"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AAEhC,SAAsCC,MAAM,QAAQ,4BAA4B;AAKhF,iBAAiB,GACjB,OAAO,SAASC,UAAUC,UAAqC,CAAC,CAAC;IAC/D,OAAOH,IAAI,kBAAkBC,OAAOE;AACtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/files/useFileUpload.ts"],"sourcesContent":["\"use client\";\nimport { nanoid } from \"nanoid\";\nimport {\n useCallback,\n useEffect,\n useReducer,\n type ChangeEvent,\n type DragEvent,\n} from \"react\";\nimport {\n getFileParser as defaultGetFileParser,\n type CompletedFileUploadStats,\n type FileReaderResult,\n type FileUploadHandlers,\n type FileUploadStats,\n type GetFileParser,\n type ProcessingFileUploadStats,\n} from \"./utils.js\";\nimport {\n FileAccessError,\n isValidFileName as defaultIsValidFileName,\n validateFiles as defaultValidateFiles,\n type FileValidationError,\n type FileValidationOptions,\n type FilesValidator,\n} from \"./validation.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n *\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n */\nexport interface FileUploadState<CustomError = never> {\n /**\n * All the files that have been validated and are either:\n * - pending upload\n * - uploading\n * - complete\n *\n * Each key in this object is the {@link BaseFileUploadStats.key} generated\n * once the upload starts pending.\n */\n stats: Readonly<Record<string, Readonly<FileUploadStats>>>;\n\n /**\n * A list of validation errors that have occurred before starting the upload\n * process.\n *\n * @see {@link FileAccessError}\n * @see {@link TooManyFilesError}\n * @see {@link FileValidationError}\n */\n errors: readonly FileValidationError<CustomError>[];\n}\n\n/**\n *\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n * @internal\n */\nexport interface FileUploadHookState<CustomError = never>\n extends FileUploadState<CustomError> {\n /**\n * All the current readers used for uploading files to the browser.\n *\n * Note: Once an upload has completed, the reader will be removed.\n */\n readers: Readonly<Record<string, FileReader>>;\n}\n\n/**\n *\n * @typeParam E - An optional HTMLElement type that is used for the\n * {@link FileUploadHandlers}.\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n */\nexport interface FileUploadOptions<E extends HTMLElement, CustomError = never>\n extends FileUploadHandlers<E>,\n FileValidationOptions {\n /**\n * Setting this value to a number greater than `0` will update the browser\n * upload process to queue the uploads in chunks instead of all at once. This\n * can help prevent the browser from freezing if dealing with large files that\n * are being converted to data urls.\n *\n * @defaultValue `-1`\n */\n concurrency?: number;\n\n /** {@inheritDoc FilesValidator} */\n validateFiles?: FilesValidator<CustomError>;\n /** {@inheritDoc GetFileParser} */\n getFileParser?: GetFileParser;\n}\n\n/** @internal */\ntype Action<E = never> =\n | {\n type: \"queue\";\n errors: readonly FileValidationError<E>[];\n files: readonly File[];\n }\n | { type: \"reset\" }\n | { type: \"remove\"; files: readonly string[] }\n | { type: \"start\"; key: string; reader: FileReader }\n | { type: \"progress\"; key: string; progress: number }\n | { type: \"complete\"; key: string; result: FileReaderResult }\n | { type: \"clearErrors\" };\n\n/** @since 2.9.0 */\nexport interface FileUploadActions {\n /**\n * Reset everything related to uploads ensuring that all file readers have\n * been aborted.\n */\n reset: () => void;\n\n /**\n * Removes all the errors that exist in state without canceling any of the\n * uploads already in progress.\n */\n clearErrors: () => void;\n\n /**\n * This function is used to cancel pending and uploading files or removing\n * completed files.\n *\n * @param keyOrKeys - A single or list of {@link BaseFileUploadStats.key} to\n * remove from state.\n */\n remove: (keyOrKeys: string | readonly string[]) => void;\n}\n\n/**\n *\n * @typeParam E - An optional HTMLElement type that is used for the\n * {@link FileUploadHandlers}.\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n */\nexport interface FileUploadHookReturnValue<\n E extends HTMLElement = HTMLElement,\n CustomError = never,\n> extends FileUploadActions,\n Required<FileUploadHandlers<E>> {\n /** {@inheritDoc FileUploadState.errors} */\n errors: readonly FileValidationError<CustomError>[];\n\n /**\n * A list of all the {@link FileUploadStats}.\n *\n * @see {@link getSplitFileUploads} for separating by status\n */\n stats: readonly Readonly<FileUploadStats>[];\n\n /**\n * The total number of bytes for all the files that exist in the\n * {@link stats} list.\n */\n totalBytes: number;\n\n /**\n * The total number of files in the {@link stats} list.\n */\n totalFiles: number;\n\n /**\n * An `accept` string that can be passed to the {@link FileInput} component\n * when the {@link FileValidationOptions.extensions} list has been provided to\n * limit which files the OS will _attempt_ to allow access to.\n *\n * @example Simple example\n * ```ts\n * const extensions = ['pdf', 'docx', 'ppt'];\n * const { accept } = useFileUpload({ extensions, ...others });\n *\n * expect(accept).toBe(\"*.pdf,*.docx,*.ppt\")\n * ```\n *\n * @defaultValue `\"*\"`\n */\n accept: string;\n}\n\n/** @internal */\nconst EMPTY_LIST = [] as const;\n/** @internal */\nconst EMPTY_OBJECT = {} as const;\n\n/**\n * This hook is generally used to upload files **to the browser** in different\n * formats to be previewed `<img>`, `<video>`, `<embed>`, etc tags. However, it\n * can also be used to upload the files as an `ArrayBuffer` and then uploaded to\n * a server.\n *\n * @typeParam E - An optional HTMLElement type that is used for the\n * {@link FileUploadHandlers}.\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @param options - All the {@link FileUploadOptions}\n * @returns the {@link FileUploadHookReturnValue}\n * @since 2.9.0\n */\nexport function useFileUpload<E extends HTMLElement, CustomError = never>(\n options: FileUploadOptions<E, CustomError> = {}\n): Readonly<FileUploadHookReturnValue<E, CustomError>> {\n const {\n maxFiles = -1,\n extensions = EMPTY_LIST,\n minFileSize = -1,\n maxFileSize = -1,\n totalFileSize = -1,\n concurrency = -1,\n onDrop: propOnDrop = noop,\n onChange: propOnChange = noop,\n validateFiles = defaultValidateFiles,\n getFileParser = defaultGetFileParser,\n isValidFileName = defaultIsValidFileName,\n } = options;\n\n const [state, dispatch] = useReducer(\n function reducer(\n state: FileUploadHookState<CustomError>,\n action: Action<CustomError>\n ): FileUploadHookState<CustomError> {\n switch (action.type) {\n case \"reset\":\n // need to reuse constants so that calling reset doesn't cause an\n // infinite loop in an effect\n return {\n stats: EMPTY_OBJECT,\n errors: EMPTY_LIST,\n readers: EMPTY_OBJECT,\n };\n case \"remove\": {\n const stats: Record<string, FileUploadStats> = {};\n for (const key in state.stats) {\n if (!action.files.includes(key)) {\n stats[key] = state.stats[key];\n }\n }\n\n return {\n ...state,\n stats,\n };\n }\n case \"queue\":\n return {\n ...state,\n stats: {\n ...state.stats,\n ...action.files.reduce<Record<string, ProcessingFileUploadStats>>(\n (files, file) => {\n const key = nanoid();\n files[key] = {\n key,\n file,\n progress: 0,\n status: \"pending\",\n };\n\n return files;\n },\n {}\n ),\n },\n errors: [...state.errors, ...action.errors],\n };\n case \"start\": {\n const { key, reader } = action;\n const fileStats: ProcessingFileUploadStats = {\n key,\n file: state.stats[key].file,\n progress: 0,\n status: \"uploading\",\n };\n\n return {\n ...state,\n readers: {\n ...state.readers,\n [key]: reader,\n },\n stats: {\n ...state.stats,\n [key]: fileStats,\n },\n };\n }\n case \"progress\": {\n const { key, progress } = action;\n return {\n ...state,\n stats: {\n ...state.stats,\n [key]: {\n ...state.stats[key],\n progress,\n },\n },\n };\n }\n case \"complete\": {\n const { key, result } = action;\n const file: CompletedFileUploadStats = {\n key,\n file: state.stats[key].file,\n status: \"complete\",\n result,\n progress: 100,\n };\n const { [key]: _reader, ...readers } = state.readers;\n\n return {\n ...state,\n readers,\n stats: {\n ...state.stats,\n [key]: file,\n },\n };\n }\n case \"clearErrors\":\n return { ...state, errors: [] };\n }\n },\n {\n stats: EMPTY_OBJECT,\n errors: EMPTY_LIST,\n readers: EMPTY_OBJECT,\n }\n );\n const { stats, errors, readers } = state;\n\n const statsList = Object.values(stats);\n const totalFiles = statsList.length;\n const totalBytes = statsList.reduce(\n (result, { file: { size } }) => result + size,\n 0\n );\n const queueFiles = useCallback(\n (files: readonly File[]) => {\n const { pending, errors } = validateFiles(files, {\n maxFiles,\n extensions,\n minFileSize,\n maxFileSize,\n totalBytes,\n totalFiles,\n totalFileSize,\n isValidFileName,\n });\n\n dispatch({ type: \"queue\", errors, files: pending });\n },\n [\n validateFiles,\n maxFiles,\n extensions,\n minFileSize,\n maxFileSize,\n totalBytes,\n totalFiles,\n totalFileSize,\n isValidFileName,\n ]\n );\n const onDrop = useCallback(\n (event: DragEvent<E>) => {\n propOnDrop(event);\n event.preventDefault();\n event.stopPropagation();\n\n try {\n const files = event.dataTransfer.files;\n if (files) {\n queueFiles(Array.from(files));\n }\n } catch (e) {\n dispatch({\n type: \"queue\",\n files: [],\n errors: [\n new FileAccessError(e instanceof Error ? e.message : undefined),\n ],\n });\n }\n },\n [queueFiles, propOnDrop]\n );\n const onChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n propOnChange(event);\n try {\n const files = event.currentTarget.files;\n if (files) {\n queueFiles(Array.from(files));\n } else {\n throw new Error();\n }\n } catch (e) {\n dispatch({\n type: \"queue\",\n files: [],\n errors: [\n new FileAccessError(e instanceof Error ? e.message : undefined),\n ],\n });\n }\n },\n [queueFiles, propOnChange]\n );\n\n const remove = useCallback(\n (keyOrKeys: string | readonly string[]) => {\n const files = typeof keyOrKeys === \"string\" ? [keyOrKeys] : keyOrKeys;\n files.forEach((fileKey) => {\n readers[fileKey]?.abort();\n });\n\n dispatch({ type: \"remove\", files });\n },\n [readers]\n );\n const reset = useCallback(() => {\n Object.values(readers).forEach((reader) => {\n reader.abort();\n });\n\n dispatch({ type: \"reset\" });\n }, [readers]);\n const clearErrors = useCallback(() => {\n dispatch({ type: \"clearErrors\" });\n }, []);\n const start = useCallback((key: string, reader: FileReader) => {\n dispatch({ type: \"start\", key, reader });\n }, []);\n const complete = useCallback(\n (key: string, result: FileReaderResult = null) => {\n dispatch({ type: \"complete\", key, result });\n },\n []\n );\n const createProgressEventHandler = useCallback(\n (key: string) => (event: ProgressEvent) => {\n if (event.lengthComputable) {\n const percentage = Math.round((event.loaded * 100) / event.total);\n dispatch({ type: \"progress\", key, progress: percentage });\n }\n },\n []\n );\n\n useEffect(() => {\n const pending: ProcessingFileUploadStats[] = [];\n const uploading: ProcessingFileUploadStats[] = [];\n Object.values(stats).forEach((file) => {\n if (file.status === \"pending\") {\n pending.push(file);\n } else if (file.status === \"uploading\") {\n uploading.push(file);\n }\n });\n\n const lastIndex =\n concurrency === -1\n ? pending.length\n : Math.max(0, concurrency - uploading.length);\n const queue = pending.slice(0, lastIndex);\n if (!queue.length) {\n return;\n }\n\n queue.forEach((stats) => {\n const { key, file } = stats;\n const reader = new FileReader();\n\n // using `addEventListener` instead of directly setting to\n // `reader.progress`/`reader.load` so it's easier to test\n reader.addEventListener(\"progress\", createProgressEventHandler(key));\n reader.addEventListener(\"load\", () => {\n complete(key, reader.result);\n });\n\n start(key, reader);\n const parser = getFileParser(file);\n /* istanbul ignore next */\n if (\n process.env.NODE_ENV !== \"production\" &&\n ![\"readAsText\", \"readAsDataURL\", \"readAsArrayBuffer\"].includes(parser)\n ) {\n throw new Error(\"Invalid file reader parser\");\n }\n\n reader[parser](file);\n });\n }, [\n concurrency,\n stats,\n getFileParser,\n createProgressEventHandler,\n start,\n complete,\n ]);\n\n let accept = \"\";\n if (extensions.length) {\n accept = extensions.reduce((s, ext) => `${s ? `${s},` : \"\"}.${ext}`, \"\");\n }\n\n return {\n stats: statsList,\n errors,\n accept,\n totalBytes,\n totalFiles,\n onDrop,\n onChange,\n reset,\n remove,\n clearErrors,\n };\n}\n"],"names":["nanoid","useCallback","useEffect","useReducer","getFileParser","defaultGetFileParser","FileAccessError","isValidFileName","defaultIsValidFileName","validateFiles","defaultValidateFiles","noop","EMPTY_LIST","EMPTY_OBJECT","useFileUpload","options","maxFiles","extensions","minFileSize","maxFileSize","totalFileSize","concurrency","onDrop","propOnDrop","onChange","propOnChange","state","dispatch","reducer","action","type","stats","errors","readers","key","files","includes","reduce","file","progress","status","reader","fileStats","result","_reader","statsList","Object","values","totalFiles","length","totalBytes","size","queueFiles","pending","event","preventDefault","stopPropagation","dataTransfer","Array","from","e","Error","message","undefined","currentTarget","remove","keyOrKeys","forEach","fileKey","abort","reset","clearErrors","start","complete","createProgressEventHandler","lengthComputable","percentage","Math","round","loaded","total","uploading","push","lastIndex","max","queue","slice","FileReader","addEventListener","parser","process","env","NODE_ENV","accept","s","ext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/files/useFileUpload.ts"],"sourcesContent":["\"use client\";\n\nimport { nanoid } from \"nanoid\";\nimport {\n type ChangeEvent,\n type DragEvent,\n useCallback,\n useEffect,\n useReducer,\n} from \"react\";\n\nimport {\n type CompletedFileUploadStats,\n type FileReaderResult,\n type FileUploadHandlers,\n type FileUploadStats,\n type GetFileParser,\n type ProcessingFileUploadStats,\n getFileParser as defaultGetFileParser,\n} from \"./utils.js\";\nimport {\n FileAccessError,\n type FileValidationError,\n type FileValidationOptions,\n type FilesValidator,\n isValidFileName as defaultIsValidFileName,\n validateFiles as defaultValidateFiles,\n} from \"./validation.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n *\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n */\nexport interface FileUploadState<CustomError = never> {\n /**\n * All the files that have been validated and are either:\n * - pending upload\n * - uploading\n * - complete\n *\n * Each key in this object is the {@link BaseFileUploadStats.key} generated\n * once the upload starts pending.\n */\n stats: Readonly<Record<string, Readonly<FileUploadStats>>>;\n\n /**\n * A list of validation errors that have occurred before starting the upload\n * process.\n *\n * @see {@link FileAccessError}\n * @see {@link TooManyFilesError}\n * @see {@link FileValidationError}\n */\n errors: readonly FileValidationError<CustomError>[];\n}\n\n/**\n *\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n * @internal\n */\nexport interface FileUploadHookState<CustomError = never>\n extends FileUploadState<CustomError> {\n /**\n * All the current readers used for uploading files to the browser.\n *\n * Note: Once an upload has completed, the reader will be removed.\n */\n readers: Readonly<Record<string, FileReader>>;\n}\n\n/**\n *\n * @typeParam E - An optional HTMLElement type that is used for the\n * {@link FileUploadHandlers}.\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n */\nexport interface FileUploadOptions<E extends HTMLElement, CustomError = never>\n extends FileUploadHandlers<E>,\n FileValidationOptions {\n /**\n * Setting this value to a number greater than `0` will update the browser\n * upload process to queue the uploads in chunks instead of all at once. This\n * can help prevent the browser from freezing if dealing with large files that\n * are being converted to data urls.\n *\n * @defaultValue `-1`\n */\n concurrency?: number;\n\n /** {@inheritDoc FilesValidator} */\n validateFiles?: FilesValidator<CustomError>;\n /** {@inheritDoc GetFileParser} */\n getFileParser?: GetFileParser;\n}\n\n/** @internal */\ntype Action<E = never> =\n | {\n type: \"queue\";\n errors: readonly FileValidationError<E>[];\n files: readonly File[];\n }\n | { type: \"reset\" }\n | { type: \"remove\"; files: readonly string[] }\n | { type: \"start\"; key: string; reader: FileReader }\n | { type: \"progress\"; key: string; progress: number }\n | { type: \"complete\"; key: string; result: FileReaderResult }\n | { type: \"clearErrors\" };\n\n/** @since 2.9.0 */\nexport interface FileUploadActions {\n /**\n * Reset everything related to uploads ensuring that all file readers have\n * been aborted.\n */\n reset: () => void;\n\n /**\n * Removes all the errors that exist in state without canceling any of the\n * uploads already in progress.\n */\n clearErrors: () => void;\n\n /**\n * This function is used to cancel pending and uploading files or removing\n * completed files.\n *\n * @param keyOrKeys - A single or list of {@link BaseFileUploadStats.key} to\n * remove from state.\n */\n remove: (keyOrKeys: string | readonly string[]) => void;\n}\n\n/**\n *\n * @typeParam E - An optional HTMLElement type that is used for the\n * {@link FileUploadHandlers}.\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @since 2.9.0\n */\nexport interface FileUploadHookReturnValue<\n E extends HTMLElement = HTMLElement,\n CustomError = never,\n> extends FileUploadActions,\n Required<FileUploadHandlers<E>> {\n /** {@inheritDoc FileUploadState.errors} */\n errors: readonly FileValidationError<CustomError>[];\n\n /**\n * A list of all the {@link FileUploadStats}.\n *\n * @see {@link getSplitFileUploads} for separating by status\n */\n stats: readonly Readonly<FileUploadStats>[];\n\n /**\n * The total number of bytes for all the files that exist in the\n * {@link stats} list.\n */\n totalBytes: number;\n\n /**\n * The total number of files in the {@link stats} list.\n */\n totalFiles: number;\n\n /**\n * An `accept` string that can be passed to the {@link FileInput} component\n * when the {@link FileValidationOptions.extensions} list has been provided to\n * limit which files the OS will _attempt_ to allow access to.\n *\n * @example Simple example\n * ```ts\n * const extensions = ['pdf', 'docx', 'ppt'];\n * const { accept } = useFileUpload({ extensions, ...others });\n *\n * expect(accept).toBe(\"*.pdf,*.docx,*.ppt\")\n * ```\n *\n * @defaultValue `\"*\"`\n */\n accept: string;\n}\n\n/** @internal */\nconst EMPTY_LIST = [] as const;\n/** @internal */\nconst EMPTY_OBJECT = {} as const;\n\n/**\n * This hook is generally used to upload files **to the browser** in different\n * formats to be previewed `<img>`, `<video>`, `<embed>`, etc tags. However, it\n * can also be used to upload the files as an `ArrayBuffer` and then uploaded to\n * a server.\n *\n * @typeParam E - An optional HTMLElement type that is used for the\n * {@link FileUploadHandlers}.\n * @typeParam CustomError - An optional error type that gets returned from the\n * {@link FilesValidator}.\n * @param options - All the {@link FileUploadOptions}\n * @returns the {@link FileUploadHookReturnValue}\n * @since 2.9.0\n */\nexport function useFileUpload<E extends HTMLElement, CustomError = never>(\n options: FileUploadOptions<E, CustomError> = {}\n): Readonly<FileUploadHookReturnValue<E, CustomError>> {\n const {\n maxFiles = -1,\n extensions = EMPTY_LIST,\n minFileSize = -1,\n maxFileSize = -1,\n totalFileSize = -1,\n concurrency = -1,\n onDrop: propOnDrop = noop,\n onChange: propOnChange = noop,\n validateFiles = defaultValidateFiles,\n getFileParser = defaultGetFileParser,\n isValidFileName = defaultIsValidFileName,\n } = options;\n\n const [state, dispatch] = useReducer(\n function reducer(\n state: FileUploadHookState<CustomError>,\n action: Action<CustomError>\n ): FileUploadHookState<CustomError> {\n switch (action.type) {\n case \"reset\":\n // need to reuse constants so that calling reset doesn't cause an\n // infinite loop in an effect\n return {\n stats: EMPTY_OBJECT,\n errors: EMPTY_LIST,\n readers: EMPTY_OBJECT,\n };\n case \"remove\": {\n const stats: Record<string, FileUploadStats> = {};\n for (const key in state.stats) {\n if (!action.files.includes(key)) {\n stats[key] = state.stats[key];\n }\n }\n\n return {\n ...state,\n stats,\n };\n }\n case \"queue\":\n return {\n ...state,\n stats: {\n ...state.stats,\n ...action.files.reduce<Record<string, ProcessingFileUploadStats>>(\n (files, file) => {\n const key = nanoid();\n files[key] = {\n key,\n file,\n progress: 0,\n status: \"pending\",\n };\n\n return files;\n },\n {}\n ),\n },\n errors: [...state.errors, ...action.errors],\n };\n case \"start\": {\n const { key, reader } = action;\n const fileStats: ProcessingFileUploadStats = {\n key,\n file: state.stats[key].file,\n progress: 0,\n status: \"uploading\",\n };\n\n return {\n ...state,\n readers: {\n ...state.readers,\n [key]: reader,\n },\n stats: {\n ...state.stats,\n [key]: fileStats,\n },\n };\n }\n case \"progress\": {\n const { key, progress } = action;\n return {\n ...state,\n stats: {\n ...state.stats,\n [key]: {\n ...state.stats[key],\n progress,\n },\n },\n };\n }\n case \"complete\": {\n const { key, result } = action;\n const file: CompletedFileUploadStats = {\n key,\n file: state.stats[key].file,\n status: \"complete\",\n result,\n progress: 100,\n };\n const { [key]: _reader, ...readers } = state.readers;\n\n return {\n ...state,\n readers,\n stats: {\n ...state.stats,\n [key]: file,\n },\n };\n }\n case \"clearErrors\":\n return { ...state, errors: [] };\n }\n },\n {\n stats: EMPTY_OBJECT,\n errors: EMPTY_LIST,\n readers: EMPTY_OBJECT,\n }\n );\n const { stats, errors, readers } = state;\n\n const statsList = Object.values(stats);\n const totalFiles = statsList.length;\n const totalBytes = statsList.reduce(\n (result, { file: { size } }) => result + size,\n 0\n );\n const queueFiles = useCallback(\n (files: readonly File[]) => {\n const { pending, errors } = validateFiles(files, {\n maxFiles,\n extensions,\n minFileSize,\n maxFileSize,\n totalBytes,\n totalFiles,\n totalFileSize,\n isValidFileName,\n });\n\n dispatch({ type: \"queue\", errors, files: pending });\n },\n [\n validateFiles,\n maxFiles,\n extensions,\n minFileSize,\n maxFileSize,\n totalBytes,\n totalFiles,\n totalFileSize,\n isValidFileName,\n ]\n );\n const onDrop = useCallback(\n (event: DragEvent<E>) => {\n propOnDrop(event);\n event.preventDefault();\n event.stopPropagation();\n\n try {\n const files = event.dataTransfer.files;\n if (files) {\n queueFiles(Array.from(files));\n }\n } catch (e) {\n dispatch({\n type: \"queue\",\n files: [],\n errors: [\n new FileAccessError(e instanceof Error ? e.message : undefined),\n ],\n });\n }\n },\n [queueFiles, propOnDrop]\n );\n const onChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n propOnChange(event);\n try {\n const files = event.currentTarget.files;\n if (files) {\n queueFiles(Array.from(files));\n } else {\n throw new Error();\n }\n } catch (e) {\n dispatch({\n type: \"queue\",\n files: [],\n errors: [\n new FileAccessError(e instanceof Error ? e.message : undefined),\n ],\n });\n }\n },\n [queueFiles, propOnChange]\n );\n\n const remove = useCallback(\n (keyOrKeys: string | readonly string[]) => {\n const files = typeof keyOrKeys === \"string\" ? [keyOrKeys] : keyOrKeys;\n files.forEach((fileKey) => {\n readers[fileKey]?.abort();\n });\n\n dispatch({ type: \"remove\", files });\n },\n [readers]\n );\n const reset = useCallback(() => {\n Object.values(readers).forEach((reader) => {\n reader.abort();\n });\n\n dispatch({ type: \"reset\" });\n }, [readers]);\n const clearErrors = useCallback(() => {\n dispatch({ type: \"clearErrors\" });\n }, []);\n const start = useCallback((key: string, reader: FileReader) => {\n dispatch({ type: \"start\", key, reader });\n }, []);\n const complete = useCallback(\n (key: string, result: FileReaderResult = null) => {\n dispatch({ type: \"complete\", key, result });\n },\n []\n );\n const createProgressEventHandler = useCallback(\n (key: string) => (event: ProgressEvent) => {\n if (event.lengthComputable) {\n const percentage = Math.round((event.loaded * 100) / event.total);\n dispatch({ type: \"progress\", key, progress: percentage });\n }\n },\n []\n );\n\n useEffect(() => {\n const pending: ProcessingFileUploadStats[] = [];\n const uploading: ProcessingFileUploadStats[] = [];\n Object.values(stats).forEach((file) => {\n if (file.status === \"pending\") {\n pending.push(file);\n } else if (file.status === \"uploading\") {\n uploading.push(file);\n }\n });\n\n const lastIndex =\n concurrency === -1\n ? pending.length\n : Math.max(0, concurrency - uploading.length);\n const queue = pending.slice(0, lastIndex);\n if (!queue.length) {\n return;\n }\n\n queue.forEach((stats) => {\n const { key, file } = stats;\n const reader = new FileReader();\n\n // using `addEventListener` instead of directly setting to\n // `reader.progress`/`reader.load` so it's easier to test\n reader.addEventListener(\"progress\", createProgressEventHandler(key));\n reader.addEventListener(\"load\", () => {\n complete(key, reader.result);\n });\n\n start(key, reader);\n const parser = getFileParser(file);\n /* istanbul ignore next */\n if (\n process.env.NODE_ENV !== \"production\" &&\n ![\"readAsText\", \"readAsDataURL\", \"readAsArrayBuffer\"].includes(parser)\n ) {\n throw new Error(\"Invalid file reader parser\");\n }\n\n reader[parser](file);\n });\n }, [\n concurrency,\n stats,\n getFileParser,\n createProgressEventHandler,\n start,\n complete,\n ]);\n\n let accept = \"\";\n if (extensions.length) {\n accept = extensions.reduce((s, ext) => `${s ? `${s},` : \"\"}.${ext}`, \"\");\n }\n\n return {\n stats: statsList,\n errors,\n accept,\n totalBytes,\n totalFiles,\n onDrop,\n onChange,\n reset,\n remove,\n clearErrors,\n };\n}\n"],"names":["nanoid","useCallback","useEffect","useReducer","getFileParser","defaultGetFileParser","FileAccessError","isValidFileName","defaultIsValidFileName","validateFiles","defaultValidateFiles","noop","EMPTY_LIST","EMPTY_OBJECT","useFileUpload","options","maxFiles","extensions","minFileSize","maxFileSize","totalFileSize","concurrency","onDrop","propOnDrop","onChange","propOnChange","state","dispatch","reducer","action","type","stats","errors","readers","key","files","includes","reduce","file","progress","status","reader","fileStats","result","_reader","statsList","Object","values","totalFiles","length","totalBytes","size","queueFiles","pending","event","preventDefault","stopPropagation","dataTransfer","Array","from","e","Error","message","undefined","currentTarget","remove","keyOrKeys","forEach","fileKey","abort","reset","clearErrors","start","complete","createProgressEventHandler","lengthComputable","percentage","Math","round","loaded","total","uploading","push","lastIndex","max","queue","slice","FileReader","addEventListener","parser","process","env","NODE_ENV","accept","s","ext"],"mappings":"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"}
|
package/dist/files/utils.d.ts
CHANGED
|
@@ -114,7 +114,7 @@ export declare function isMediaFile(file: File): boolean;
|
|
|
114
114
|
*
|
|
115
115
|
* @since 2.9.0
|
|
116
116
|
* @since 6.0.0 Removed `"readAsBinaryString` since it is deprecated
|
|
117
|
-
*
|
|
117
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString}
|
|
118
118
|
*/
|
|
119
119
|
export type FileReaderParser = "readAsText" | "readAsDataURL" | "readAsArrayBuffer";
|
|
120
120
|
/**
|
|
@@ -161,6 +161,36 @@ export interface SplitFileUploads {
|
|
|
161
161
|
/**
|
|
162
162
|
* This util will split all the current upload stats by status.
|
|
163
163
|
*
|
|
164
|
+
* @example Main Usage
|
|
165
|
+
* ```tsx
|
|
166
|
+
* import { FileUpload } from "@react-md/core/files/FileUpload";
|
|
167
|
+
* import { useFileUpload } from "@react-md/core/files/useFileUpload";
|
|
168
|
+
* import { getSplitFileUploads } from "@react-md/core/files/utils";
|
|
169
|
+
*
|
|
170
|
+
* function Example() {
|
|
171
|
+
* const { stats, errors, accept, onChange } = useFileUpload();
|
|
172
|
+
* const { pending, uploading, completed } = getSplitFileUploads(stats);
|
|
173
|
+
*
|
|
174
|
+
* return (
|
|
175
|
+
* <>
|
|
176
|
+
* <FileUpload accept={accept} onChange={onChange} />
|
|
177
|
+
* {pending.map(({ key, file, progress, status }) => {
|
|
178
|
+
* // pretend some UI for each pending item with the provided data
|
|
179
|
+
* return null;
|
|
180
|
+
* })}
|
|
181
|
+
* {uploading.map(({ file, key, progress, status }) => {
|
|
182
|
+
* // pretend some UI for each uploading item with the provided data
|
|
183
|
+
* return null;
|
|
184
|
+
* })}
|
|
185
|
+
* {complete.map(({ file, key, progress, result, status }) => {
|
|
186
|
+
* // pretend some UI for each complete item with the provided data
|
|
187
|
+
* return null;
|
|
188
|
+
* })}
|
|
189
|
+
* </>
|
|
190
|
+
* );
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*
|
|
164
194
|
* @param stats - The {@link FileUploadStats} list generally returned by the
|
|
165
195
|
* {@link useFileUpload} hook.
|
|
166
196
|
* @returns the {@link SplitFileUploads}.
|
package/dist/files/utils.js
CHANGED
|
@@ -85,6 +85,36 @@
|
|
|
85
85
|
/**
|
|
86
86
|
* This util will split all the current upload stats by status.
|
|
87
87
|
*
|
|
88
|
+
* @example Main Usage
|
|
89
|
+
* ```tsx
|
|
90
|
+
* import { FileUpload } from "@react-md/core/files/FileUpload";
|
|
91
|
+
* import { useFileUpload } from "@react-md/core/files/useFileUpload";
|
|
92
|
+
* import { getSplitFileUploads } from "@react-md/core/files/utils";
|
|
93
|
+
*
|
|
94
|
+
* function Example() {
|
|
95
|
+
* const { stats, errors, accept, onChange } = useFileUpload();
|
|
96
|
+
* const { pending, uploading, completed } = getSplitFileUploads(stats);
|
|
97
|
+
*
|
|
98
|
+
* return (
|
|
99
|
+
* <>
|
|
100
|
+
* <FileUpload accept={accept} onChange={onChange} />
|
|
101
|
+
* {pending.map(({ key, file, progress, status }) => {
|
|
102
|
+
* // pretend some UI for each pending item with the provided data
|
|
103
|
+
* return null;
|
|
104
|
+
* })}
|
|
105
|
+
* {uploading.map(({ file, key, progress, status }) => {
|
|
106
|
+
* // pretend some UI for each uploading item with the provided data
|
|
107
|
+
* return null;
|
|
108
|
+
* })}
|
|
109
|
+
* {complete.map(({ file, key, progress, result, status }) => {
|
|
110
|
+
* // pretend some UI for each complete item with the provided data
|
|
111
|
+
* return null;
|
|
112
|
+
* })}
|
|
113
|
+
* </>
|
|
114
|
+
* );
|
|
115
|
+
* }
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
88
118
|
* @param stats - The {@link FileUploadStats} list generally returned by the
|
|
89
119
|
* {@link useFileUpload} hook.
|
|
90
120
|
* @returns the {@link SplitFileUploads}.
|
package/dist/files/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/files/utils.ts"],"sourcesContent":["import { type ChangeEventHandler, type DragEventHandler } from \"react\";\n\n/** @since 2.9.0 */\nexport interface BaseFileUploadStats {\n /**\n * A unique key associated with each upload generated by `nanoid`.\n */\n key: string;\n\n /**\n * The file instance that is being uploaded.\n */\n file: File;\n\n /**\n * The current upload progress as a percentage from 0 - 100 percent.\n */\n progress: number;\n}\n\n/** @since 2.9.0 */\nexport interface ProcessingFileUploadStats extends BaseFileUploadStats {\n status: \"pending\" | \"uploading\";\n}\n\n/** @since 2.9.0 */\nexport type FileReaderResult = FileReader[\"result\"];\n\n/** @since 2.9.0 */\nexport interface CompletedFileUploadStats extends BaseFileUploadStats {\n status: \"complete\";\n\n /**\n * The result after a `FileReader` has read a file completely.\n *\n * Note: This _should_ be an `ArrayBuffer` if the next step is to upload to a\n * server.\n *\n * @see {@link FileReaderParser}\n * @see {@link getFileParser}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader | FileReader}\n */\n result: FileReaderResult;\n}\n\n/** @since 2.9.0 */\nexport type FileUploadStats =\n | ProcessingFileUploadStats\n | CompletedFileUploadStats;\n\n/** @since 2.9.0 */\nexport type FileUploadStatus = FileUploadStats[\"status\"];\n\n/** @since 2.9.0 */\nexport interface FileUploadHandlers<E extends HTMLElement> {\n onDrop?: DragEventHandler<E>;\n onChange?: ChangeEventHandler<HTMLInputElement>;\n}\n\n/**\n * This will first check if the mime-type of the file starts with `text/` and\n * fallback to checking a few file names or extensions that should be considered\n * text.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a text-content file.\n * @since 2.9.0\n */\nexport function isTextFile(file: File): boolean {\n return /\\.((j|t)sx?|json|lock|hbs|ya?ml|log|txt|md)$/i.test(file.name);\n}\n\n/**\n * This will first check if the mime-type of the file starts with `text\\/` and\n * fallback to checking a few file names or extensions that should be considered\n * text.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a text content file.\n * @since 2.9.0\n */\nexport function isImageFile(file: File): boolean {\n return /\\.(a?png|avif|svg|tiff|gifv?|jpe?g)/i.test(file.name);\n}\n\n/**\n * This will first check if the mime-type of the file starts with `audio/` and\n * fallback to checking a few file names or extensions that should be considered\n * audio.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a audio content file.\n * @since 2.9.0\n */\nexport function isAudioFile(file: File): boolean {\n return /\\.(mp3|wav|ogg|m4p|flac)$/i.test(file.name);\n}\n\n/**\n * This will first check if the mime-type of the file starts with `video/` and\n * fallback to checking a few file names or extensions that should be considered\n * video.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a video content file.\n * @since 2.9.0\n */\nexport function isVideoFile(file: File): boolean {\n return /\\.(mkv|mpe?g|mov|avi|flv|webm|mp4)$/i.test(file.name);\n}\n\n/**\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file matches an image, audio, or video file.\n * @since 2.9.0\n */\nexport function isMediaFile(file: File): boolean {\n return isImageFile(file) || isAudioFile(file) || isVideoFile(file);\n}\n\n/**\n * One of the function names from a `FileReader` to upload a file to the\n * client.\n *\n * Note: If this file does not need to be previewed in the browser and will\n * immediately be uploaded to a server, use `readAsArrayBuffer`.\n *\n * @since 2.9.0\n * @since 6.0.0 Removed `\"readAsBinaryString` since it is deprecated\n *
|
|
1
|
+
{"version":3,"sources":["../../src/files/utils.ts"],"sourcesContent":["import { type ChangeEventHandler, type DragEventHandler } from \"react\";\n\n/** @since 2.9.0 */\nexport interface BaseFileUploadStats {\n /**\n * A unique key associated with each upload generated by `nanoid`.\n */\n key: string;\n\n /**\n * The file instance that is being uploaded.\n */\n file: File;\n\n /**\n * The current upload progress as a percentage from 0 - 100 percent.\n */\n progress: number;\n}\n\n/** @since 2.9.0 */\nexport interface ProcessingFileUploadStats extends BaseFileUploadStats {\n status: \"pending\" | \"uploading\";\n}\n\n/** @since 2.9.0 */\nexport type FileReaderResult = FileReader[\"result\"];\n\n/** @since 2.9.0 */\nexport interface CompletedFileUploadStats extends BaseFileUploadStats {\n status: \"complete\";\n\n /**\n * The result after a `FileReader` has read a file completely.\n *\n * Note: This _should_ be an `ArrayBuffer` if the next step is to upload to a\n * server.\n *\n * @see {@link FileReaderParser}\n * @see {@link getFileParser}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader | FileReader}\n */\n result: FileReaderResult;\n}\n\n/** @since 2.9.0 */\nexport type FileUploadStats =\n | ProcessingFileUploadStats\n | CompletedFileUploadStats;\n\n/** @since 2.9.0 */\nexport type FileUploadStatus = FileUploadStats[\"status\"];\n\n/** @since 2.9.0 */\nexport interface FileUploadHandlers<E extends HTMLElement> {\n onDrop?: DragEventHandler<E>;\n onChange?: ChangeEventHandler<HTMLInputElement>;\n}\n\n/**\n * This will first check if the mime-type of the file starts with `text/` and\n * fallback to checking a few file names or extensions that should be considered\n * text.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a text-content file.\n * @since 2.9.0\n */\nexport function isTextFile(file: File): boolean {\n return /\\.((j|t)sx?|json|lock|hbs|ya?ml|log|txt|md)$/i.test(file.name);\n}\n\n/**\n * This will first check if the mime-type of the file starts with `text\\/` and\n * fallback to checking a few file names or extensions that should be considered\n * text.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a text content file.\n * @since 2.9.0\n */\nexport function isImageFile(file: File): boolean {\n return /\\.(a?png|avif|svg|tiff|gifv?|jpe?g)/i.test(file.name);\n}\n\n/**\n * This will first check if the mime-type of the file starts with `audio/` and\n * fallback to checking a few file names or extensions that should be considered\n * audio.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a audio content file.\n * @since 2.9.0\n */\nexport function isAudioFile(file: File): boolean {\n return /\\.(mp3|wav|ogg|m4p|flac)$/i.test(file.name);\n}\n\n/**\n * This will first check if the mime-type of the file starts with `video/` and\n * fallback to checking a few file names or extensions that should be considered\n * video.\n *\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file should be considered as a video content file.\n * @since 2.9.0\n */\nexport function isVideoFile(file: File): boolean {\n return /\\.(mkv|mpe?g|mov|avi|flv|webm|mp4)$/i.test(file.name);\n}\n\n/**\n * This function is not guaranteed to be 100% correct and is only useful if\n * trying to generate a preview of files uploaded to the browser.\n *\n * @param file - The file to check\n * @returns `true` if the file matches an image, audio, or video file.\n * @since 2.9.0\n */\nexport function isMediaFile(file: File): boolean {\n return isImageFile(file) || isAudioFile(file) || isVideoFile(file);\n}\n\n/**\n * One of the function names from a `FileReader` to upload a file to the\n * client.\n *\n * Note: If this file does not need to be previewed in the browser and will\n * immediately be uploaded to a server, use `readAsArrayBuffer`.\n *\n * @since 2.9.0\n * @since 6.0.0 Removed `\"readAsBinaryString` since it is deprecated\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString}\n */\nexport type FileReaderParser =\n | \"readAsText\"\n | \"readAsDataURL\"\n | \"readAsArrayBuffer\";\n\n/**\n * A function that should return one of the {@link FileReaderParser} functions\n * to start uploading a file to the browser.\n *\n * @example The Default File Upload Parser\n * ```ts\n * export const getFileParser: GetFileParser = (file) => {\n * if (isMediaFile(file)) {\n * return \"readAsDataURL\";\n * }\n *\n * if (isTextFile(file)) {\n * return \"readAsText\";\n * }\n *\n * return \"readAsArrayBuffer\";\n * };\n * ```\n *\n * @param file - The file to get a parser for\n * @returns the {@link FileReaderParser} string.\n * @since 2.9.0\n */\nexport type GetFileParser = (file: File) => FileReaderParser;\n\n/**\n * This function will attempt to read:\n * - media (image, audio, and video) files as a data url so they can be\n * previewed in `<img>`, `<audio>`, and `<video>` tags\n * - text files as plain text\n * - everything else as an `ArrayBuffer` which can be manually converted into a\n * data url if needed with `URL.createObjectURL`\n *\n * @since 2.9.0\n */\nexport const getFileParser: GetFileParser = (file) => {\n if (isMediaFile(file)) {\n return \"readAsDataURL\";\n }\n\n if (isTextFile(file)) {\n return \"readAsText\";\n }\n\n return \"readAsArrayBuffer\";\n};\n\n/** @since 2.9.0 */\nexport interface SplitFileUploads {\n readonly pending: readonly ProcessingFileUploadStats[];\n readonly uploading: readonly ProcessingFileUploadStats[];\n readonly complete: readonly CompletedFileUploadStats[];\n}\n\n/**\n * This util will split all the current upload stats by status.\n *\n * @example Main Usage\n * ```tsx\n * import { FileUpload } from \"@react-md/core/files/FileUpload\";\n * import { useFileUpload } from \"@react-md/core/files/useFileUpload\";\n * import { getSplitFileUploads } from \"@react-md/core/files/utils\";\n *\n * function Example() {\n * const { stats, errors, accept, onChange } = useFileUpload();\n * const { pending, uploading, completed } = getSplitFileUploads(stats);\n *\n * return (\n * <>\n * <FileUpload accept={accept} onChange={onChange} />\n * {pending.map(({ key, file, progress, status }) => {\n * // pretend some UI for each pending item with the provided data\n * return null;\n * })}\n * {uploading.map(({ file, key, progress, status }) => {\n * // pretend some UI for each uploading item with the provided data\n * return null;\n * })}\n * {complete.map(({ file, key, progress, result, status }) => {\n * // pretend some UI for each complete item with the provided data\n * return null;\n * })}\n * </>\n * );\n * }\n * ```\n *\n * @param stats - The {@link FileUploadStats} list generally returned by the\n * {@link useFileUpload} hook.\n * @returns the {@link SplitFileUploads}.\n * @since 2.9.0\n */\nexport function getSplitFileUploads(\n stats: readonly FileUploadStats[]\n): SplitFileUploads {\n const pending: ProcessingFileUploadStats[] = [];\n const uploading: ProcessingFileUploadStats[] = [];\n const complete: CompletedFileUploadStats[] = [];\n stats.forEach((stat) => {\n if (stat.status === \"pending\") {\n pending.push(stat);\n } else if (stat.status === \"uploading\") {\n uploading.push(stat);\n } else if (stat.status === \"complete\") {\n complete.push(stat);\n } else {\n /* istanbul ignore next */\n throw new Error(\"Invalid upload stat\");\n }\n });\n\n return { pending, uploading, complete };\n}\n"],"names":["isTextFile","file","test","name","isImageFile","isAudioFile","isVideoFile","isMediaFile","getFileParser","getSplitFileUploads","stats","pending","uploading","complete","forEach","stat","status","push","Error"],"mappings":"AA2DA;;;;;;;;;;;CAWC,GACD,OAAO,SAASA,WAAWC,IAAU;IACnC,OAAO,gDAAgDC,IAAI,CAACD,KAAKE,IAAI;AACvE;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,YAAYH,IAAU;IACpC,OAAO,uCAAuCC,IAAI,CAACD,KAAKE,IAAI;AAC9D;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASE,YAAYJ,IAAU;IACpC,OAAO,6BAA6BC,IAAI,CAACD,KAAKE,IAAI;AACpD;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASG,YAAYL,IAAU;IACpC,OAAO,uCAAuCC,IAAI,CAACD,KAAKE,IAAI;AAC9D;AAEA;;;;;;;CAOC,GACD,OAAO,SAASI,YAAYN,IAAU;IACpC,OAAOG,YAAYH,SAASI,YAAYJ,SAASK,YAAYL;AAC/D;AA2CA;;;;;;;;;CASC,GACD,OAAO,MAAMO,gBAA+B,CAACP;IAC3C,IAAIM,YAAYN,OAAO;QACrB,OAAO;IACT;IAEA,IAAID,WAAWC,OAAO;QACpB,OAAO;IACT;IAEA,OAAO;AACT,EAAE;AASF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCC,GACD,OAAO,SAASQ,oBACdC,KAAiC;IAEjC,MAAMC,UAAuC,EAAE;IAC/C,MAAMC,YAAyC,EAAE;IACjD,MAAMC,WAAuC,EAAE;IAC/CH,MAAMI,OAAO,CAAC,CAACC;QACb,IAAIA,KAAKC,MAAM,KAAK,WAAW;YAC7BL,QAAQM,IAAI,CAACF;QACf,OAAO,IAAIA,KAAKC,MAAM,KAAK,aAAa;YACtCJ,UAAUK,IAAI,CAACF;QACjB,OAAO,IAAIA,KAAKC,MAAM,KAAK,YAAY;YACrCH,SAASI,IAAI,CAACF;QAChB,OAAO;YACL,wBAAwB,GACxB,MAAM,IAAIG,MAAM;QAClB;IACF;IAEA,OAAO;QAAEP;QAASC;QAAWC;IAAS;AACxC"}
|
|
@@ -76,13 +76,11 @@ export interface FocusContainerImplementation<E extends HTMLElement> {
|
|
|
76
76
|
*
|
|
77
77
|
* @example Main Usage
|
|
78
78
|
* ```tsx
|
|
79
|
-
* import {
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* } from "@react-md/core";
|
|
85
|
-
* import type { ReactElement } from "react";
|
|
79
|
+
* import { Button } from "@react-md/core/button/Button"
|
|
80
|
+
* import { useFocusContainer } from "@react-md/core/focus/useFocusContainer"
|
|
81
|
+
* import { useScaleTransition } from "@react-md/core/transition/useScaleTransition"
|
|
82
|
+
* import { useToggle } from "@react-md/core/useToggle"
|
|
83
|
+
* import { type ReactElement } from "react";
|
|
86
84
|
*
|
|
87
85
|
* function Example(): ReactElement {
|
|
88
86
|
* const { toggled, enable, disable } = useToggle(false);
|
|
@@ -14,13 +14,11 @@ const noop = ()=>{
|
|
|
14
14
|
*
|
|
15
15
|
* @example Main Usage
|
|
16
16
|
* ```tsx
|
|
17
|
-
* import {
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* } from "@react-md/core";
|
|
23
|
-
* import type { ReactElement } from "react";
|
|
17
|
+
* import { Button } from "@react-md/core/button/Button"
|
|
18
|
+
* import { useFocusContainer } from "@react-md/core/focus/useFocusContainer"
|
|
19
|
+
* import { useScaleTransition } from "@react-md/core/transition/useScaleTransition"
|
|
20
|
+
* import { useToggle } from "@react-md/core/useToggle"
|
|
21
|
+
* import { type ReactElement } from "react";
|
|
24
22
|
*
|
|
25
23
|
* function Example(): ReactElement {
|
|
26
24
|
* const { toggled, enable, disable } = useToggle(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/focus/useFocusContainer.ts"],"sourcesContent":["\"use client\";\nimport {\n useEffect,\n useRef,\n type KeyboardEventHandler,\n type Ref,\n type RefObject,\n} from \"react\";\nimport { TRANSITION_CONFIG } from \"../transition/config.js\";\nimport {\n type TransitionCallbacks,\n type TransitionEnterHandler,\n type TransitionExitHandler,\n} from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport {\n focusElementWithin,\n getFocusableElements,\n type FocusElementWithinType,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * `\"mount\"` - this will attempt to focus the container element if:\n * - there is no `document.activeElement`\n * - the container element does not contain the `document.activeElement`\n *\n * `\"unmount\"` - attempts to re-focus the element that was focused before the\n * focus container became active. The previous focus element is captured\n * whenever the `activate` option on the `useFocusContainer` hook is set to\n * `true`. This is normally when an element becomes `visible`.\n *\n * `\"keyboard\"` - refocuses the first focusable element if pressing `Tab` would\n * move the focus outside of the container element. If `Shift + Tab` was used,\n * the last focusable element will be used instead.\n *\n * @since 6.0.0\n */\nexport type FocusType = \"mount\" | \"unmount\" | \"keyboard\";\n\n/** @since 6.0.0 */\nexport type FocusContainerTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEntering\" | \"onEntered\" | \"onExiting\" | \"onExited\"\n>;\n\n/** @since 6.0.0 */\nexport interface FocusContainerTransitionOptions<E extends HTMLElement>\n extends FocusContainerTransitionCallbacks {\n /**\n * An optional ref that will be merged with the\n * {@link FocusContainerImplementation.nodeRef}\n */\n nodeRef?: Ref<E>;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerEventHandlers<E extends HTMLElement> {\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type IsFocusTypeDisabled = (type: FocusType) => boolean;\n\nexport interface FocusContainerComponentProps {\n /**\n * @defaultValue `() => false`\n */\n isFocusTypeDisabled?: IsFocusTypeDisabled;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerOptions<E extends HTMLElement>\n extends FocusContainerTransitionOptions<E>,\n FocusContainerComponentProps {\n onKeyDown?: KeyboardEventHandler<E>;\n /**\n * This to `true` will capture the current focused element as a focus target\n * once the `onExited` hook is fired. This should usually be set to the\n * `transitionIn` prop for `useTransition`.\n */\n activate: boolean;\n\n /**\n * Set this to true if elements that can be programmatically focused should be\n * included. These would be elements with a `tabIndex={-1}`.\n *\n * @defaultValue `false`\n */\n programmatic?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerImplementation<E extends HTMLElement> {\n nodeRef: RefObject<E>;\n eventHandlers: Required<FocusContainerEventHandlers<E>>;\n transitionOptions: Required<FocusContainerTransitionOptions<E>>;\n}\n\n/**\n * This hook is mostly for internal use only for dialog accessibility behavior\n * to prevent the focus from moving outside of the dialog while it is visible.\n * This API was developed to be used with the `useCSSTransition`/`useTransition`\n * hooks as well.\n *\n * @example Main Usage\n * ```tsx\n * import {\n * Button,\n * useFocusContainer,\n * useScaleTransition,\n * useToggle,\n * } from \"@react-md/core\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { toggled, enable, disable } = useToggle(false);\n *\n * const { eventHandlers, transitionOptions } = useFocusContainer({\n * activate: toggled,\n * });\n * const { elementProps, rendered } = useScaleTransition({\n * transitionIn: toggled,\n * temporary: true,\n * ...transitionOptions,\n * });\n *\n * return (\n * <>\n * <Button onClick={enable}>Toggle</Button>\n * {rendered && (\n * <div {...eventHandlers} {...elementProps}>\n * <Button onClick={disable}>Button 1</Button>\n * <Button onClick={disable}>Button 2</Button>\n * <Button onClick={disable}>Button 3</Button>\n * <Button onClick={disable}>Button 4</Button>\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useFocusContainer<E extends HTMLElement>(\n options: FocusContainerOptions<E>\n): FocusContainerImplementation<E> {\n const {\n nodeRef,\n activate,\n onEntering = noop,\n onEntered = noop,\n onExiting = noop,\n onExited = noop,\n onKeyDown = noop,\n programmatic = false,\n disableTransition = false,\n isFocusTypeDisabled = noop,\n } = options;\n\n const [ref, refCallback] = useEnsuredRef(nodeRef);\n const prevFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!activate || !(document.activeElement instanceof HTMLElement)) {\n return;\n }\n\n prevFocus.current = document.activeElement;\n }, [activate]);\n\n const handleMountFocus =\n (callback: TransitionEnterHandler, skipped: boolean) =>\n (appearing: boolean) => {\n callback(appearing);\n const instance = ref.current;\n if (\n instance &&\n !skipped &&\n !isFocusTypeDisabled(\"mount\") &&\n (!document.activeElement || !instance.contains(document.activeElement))\n ) {\n instance.focus();\n }\n };\n\n const handleUnmountFocus =\n (callback: TransitionExitHandler, skipped: boolean) => (): void => {\n callback();\n if (skipped || isFocusTypeDisabled(\"unmount\")) {\n return;\n }\n\n // For some reason, the `\"Enter\"` keydown event fires at a different timing\n // than the Space keydown event.\n window.requestAnimationFrame(() => {\n prevFocus.current?.focus();\n });\n };\n\n return {\n nodeRef: ref,\n transitionOptions: {\n nodeRef: refCallback,\n onEntering: handleMountFocus(onEntering, false),\n onEntered: handleMountFocus(\n onEntered,\n !disableTransition && !TRANSITION_CONFIG.disabled\n ),\n onExiting: handleUnmountFocus(onExiting, false),\n onExited: handleUnmountFocus(\n onExited,\n !disableTransition && !TRANSITION_CONFIG.disabled\n ),\n },\n eventHandlers: {\n onKeyDown(event) {\n onKeyDown(event);\n if (\n event.isPropagationStopped() ||\n event.key !== \"Tab\" ||\n isFocusTypeDisabled(\"keyboard\")\n ) {\n return;\n }\n\n const { target, shiftKey, currentTarget } = event;\n const elements = getFocusableElements(currentTarget, programmatic);\n const count = elements.length;\n if (count === 0) {\n event.preventDefault();\n return;\n }\n\n // if the container element is the current focus, need to either focus\n // the first or last element so focus doesn't escape\n let type: FocusElementWithinType | undefined;\n if (\n count === 1 ||\n (!shiftKey &&\n (target === currentTarget || target === elements[count - 1]))\n ) {\n type = \"first\";\n } else if (\n shiftKey &&\n (target === currentTarget || target === elements[0])\n ) {\n type = \"last\";\n }\n\n if (type) {\n event.preventDefault();\n focusElementWithin({\n type,\n elements,\n container: currentTarget,\n });\n }\n },\n },\n };\n}\n"],"names":["useEffect","useRef","TRANSITION_CONFIG","useEnsuredRef","focusElementWithin","getFocusableElements","noop","useFocusContainer","options","nodeRef","activate","onEntering","onEntered","onExiting","onExited","onKeyDown","programmatic","disableTransition","isFocusTypeDisabled","ref","refCallback","prevFocus","document","activeElement","HTMLElement","current","handleMountFocus","callback","skipped","appearing","instance","contains","focus","handleUnmountFocus","window","requestAnimationFrame","transitionOptions","disabled","eventHandlers","event","isPropagationStopped","key","target","shiftKey","currentTarget","elements","count","length","preventDefault","type","container"],"mappings":"AAAA;AACA,SACEA,SAAS,EACTC,MAAM,QAID,QAAQ;AACf,SAASC,iBAAiB,QAAQ,0BAA0B;AAM5D,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SACEC,kBAAkB,EAClBC,oBAAoB,QAEf,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AAsFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CC,GACD,OAAO,SAASC,kBACdC,OAAiC;IAEjC,MAAM,EACJC,OAAO,EACPC,QAAQ,EACRC,aAAaL,IAAI,EACjBM,YAAYN,IAAI,EAChBO,YAAYP,IAAI,EAChBQ,WAAWR,IAAI,EACfS,YAAYT,IAAI,EAChBU,eAAe,KAAK,EACpBC,oBAAoB,KAAK,EACzBC,sBAAsBZ,IAAI,EAC3B,GAAGE;IAEJ,MAAM,CAACW,KAAKC,YAAY,GAAGjB,cAAcM;IACzC,MAAMY,YAAYpB,OAA2B;IAE7CD,UAAU;QACR,IAAI,CAACU,YAAY,CAAEY,CAAAA,SAASC,aAAa,YAAYC,WAAU,GAAI;YACjE;QACF;QAEAH,UAAUI,OAAO,GAAGH,SAASC,aAAa;IAC5C,GAAG;QAACb;KAAS;IAEb,MAAMgB,mBACJ,CAACC,UAAkCC,UACnC,CAACC;YACCF,SAASE;YACT,MAAMC,WAAWX,IAAIM,OAAO;YAC5B,IACEK,YACA,CAACF,WACD,CAACV,oBAAoB,YACpB,CAAA,CAACI,SAASC,aAAa,IAAI,CAACO,SAASC,QAAQ,CAACT,SAASC,aAAa,CAAA,GACrE;gBACAO,SAASE,KAAK;YAChB;QACF;IAEF,MAAMC,qBACJ,CAACN,UAAiCC,UAAqB;YACrDD;YACA,IAAIC,WAAWV,oBAAoB,YAAY;gBAC7C;YACF;YAEA,2EAA2E;YAC3E,iCAAiC;YACjCgB,OAAOC,qBAAqB,CAAC;gBAC3Bd,UAAUI,OAAO,EAAEO;YACrB;QACF;IAEF,OAAO;QACLvB,SAASU;QACTiB,mBAAmB;YACjB3B,SAASW;YACTT,YAAYe,iBAAiBf,YAAY;YACzCC,WAAWc,iBACTd,WACA,CAACK,qBAAqB,CAACf,kBAAkBmC,QAAQ;YAEnDxB,WAAWoB,mBAAmBpB,WAAW;YACzCC,UAAUmB,mBACRnB,UACA,CAACG,qBAAqB,CAACf,kBAAkBmC,QAAQ;QAErD;QACAC,eAAe;YACbvB,WAAUwB,KAAK;gBACbxB,UAAUwB;gBACV,IACEA,MAAMC,oBAAoB,MAC1BD,MAAME,GAAG,KAAK,SACdvB,oBAAoB,aACpB;oBACA;gBACF;gBAEA,MAAM,EAAEwB,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAGL;gBAC5C,MAAMM,WAAWxC,qBAAqBuC,eAAe5B;gBACrD,MAAM8B,QAAQD,SAASE,MAAM;gBAC7B,IAAID,UAAU,GAAG;oBACfP,MAAMS,cAAc;oBACpB;gBACF;gBAEA,sEAAsE;gBACtE,oDAAoD;gBACpD,IAAIC;gBACJ,IACEH,UAAU,KACT,CAACH,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAACC,QAAQ,EAAE,AAAD,GAC5D;oBACAG,OAAO;gBACT,OAAO,IACLN,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAAC,EAAE,AAAD,GAClD;oBACAI,OAAO;gBACT;gBAEA,IAAIA,MAAM;oBACRV,MAAMS,cAAc;oBACpB5C,mBAAmB;wBACjB6C;wBACAJ;wBACAK,WAAWN;oBACb;gBACF;YACF;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/focus/useFocusContainer.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type KeyboardEventHandler,\n type Ref,\n type RefObject,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { TRANSITION_CONFIG } from \"../transition/config.js\";\nimport {\n type TransitionCallbacks,\n type TransitionEnterHandler,\n type TransitionExitHandler,\n} from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport {\n type FocusElementWithinType,\n focusElementWithin,\n getFocusableElements,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * `\"mount\"` - this will attempt to focus the container element if:\n * - there is no `document.activeElement`\n * - the container element does not contain the `document.activeElement`\n *\n * `\"unmount\"` - attempts to re-focus the element that was focused before the\n * focus container became active. The previous focus element is captured\n * whenever the `activate` option on the `useFocusContainer` hook is set to\n * `true`. This is normally when an element becomes `visible`.\n *\n * `\"keyboard\"` - refocuses the first focusable element if pressing `Tab` would\n * move the focus outside of the container element. If `Shift + Tab` was used,\n * the last focusable element will be used instead.\n *\n * @since 6.0.0\n */\nexport type FocusType = \"mount\" | \"unmount\" | \"keyboard\";\n\n/** @since 6.0.0 */\nexport type FocusContainerTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEntering\" | \"onEntered\" | \"onExiting\" | \"onExited\"\n>;\n\n/** @since 6.0.0 */\nexport interface FocusContainerTransitionOptions<E extends HTMLElement>\n extends FocusContainerTransitionCallbacks {\n /**\n * An optional ref that will be merged with the\n * {@link FocusContainerImplementation.nodeRef}\n */\n nodeRef?: Ref<E>;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerEventHandlers<E extends HTMLElement> {\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type IsFocusTypeDisabled = (type: FocusType) => boolean;\n\nexport interface FocusContainerComponentProps {\n /**\n * @defaultValue `() => false`\n */\n isFocusTypeDisabled?: IsFocusTypeDisabled;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerOptions<E extends HTMLElement>\n extends FocusContainerTransitionOptions<E>,\n FocusContainerComponentProps {\n onKeyDown?: KeyboardEventHandler<E>;\n /**\n * This to `true` will capture the current focused element as a focus target\n * once the `onExited` hook is fired. This should usually be set to the\n * `transitionIn` prop for `useTransition`.\n */\n activate: boolean;\n\n /**\n * Set this to true if elements that can be programmatically focused should be\n * included. These would be elements with a `tabIndex={-1}`.\n *\n * @defaultValue `false`\n */\n programmatic?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerImplementation<E extends HTMLElement> {\n nodeRef: RefObject<E>;\n eventHandlers: Required<FocusContainerEventHandlers<E>>;\n transitionOptions: Required<FocusContainerTransitionOptions<E>>;\n}\n\n/**\n * This hook is mostly for internal use only for dialog accessibility behavior\n * to prevent the focus from moving outside of the dialog while it is visible.\n * This API was developed to be used with the `useCSSTransition`/`useTransition`\n * hooks as well.\n *\n * @example Main Usage\n * ```tsx\n * import { Button } from \"@react-md/core/button/Button\"\n * import { useFocusContainer } from \"@react-md/core/focus/useFocusContainer\"\n * import { useScaleTransition } from \"@react-md/core/transition/useScaleTransition\"\n * import { useToggle } from \"@react-md/core/useToggle\"\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { toggled, enable, disable } = useToggle(false);\n *\n * const { eventHandlers, transitionOptions } = useFocusContainer({\n * activate: toggled,\n * });\n * const { elementProps, rendered } = useScaleTransition({\n * transitionIn: toggled,\n * temporary: true,\n * ...transitionOptions,\n * });\n *\n * return (\n * <>\n * <Button onClick={enable}>Toggle</Button>\n * {rendered && (\n * <div {...eventHandlers} {...elementProps}>\n * <Button onClick={disable}>Button 1</Button>\n * <Button onClick={disable}>Button 2</Button>\n * <Button onClick={disable}>Button 3</Button>\n * <Button onClick={disable}>Button 4</Button>\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useFocusContainer<E extends HTMLElement>(\n options: FocusContainerOptions<E>\n): FocusContainerImplementation<E> {\n const {\n nodeRef,\n activate,\n onEntering = noop,\n onEntered = noop,\n onExiting = noop,\n onExited = noop,\n onKeyDown = noop,\n programmatic = false,\n disableTransition = false,\n isFocusTypeDisabled = noop,\n } = options;\n\n const [ref, refCallback] = useEnsuredRef(nodeRef);\n const prevFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!activate || !(document.activeElement instanceof HTMLElement)) {\n return;\n }\n\n prevFocus.current = document.activeElement;\n }, [activate]);\n\n const handleMountFocus =\n (callback: TransitionEnterHandler, skipped: boolean) =>\n (appearing: boolean) => {\n callback(appearing);\n const instance = ref.current;\n if (\n instance &&\n !skipped &&\n !isFocusTypeDisabled(\"mount\") &&\n (!document.activeElement || !instance.contains(document.activeElement))\n ) {\n instance.focus();\n }\n };\n\n const handleUnmountFocus =\n (callback: TransitionExitHandler, skipped: boolean) => (): void => {\n callback();\n if (skipped || isFocusTypeDisabled(\"unmount\")) {\n return;\n }\n\n // For some reason, the `\"Enter\"` keydown event fires at a different timing\n // than the Space keydown event.\n window.requestAnimationFrame(() => {\n prevFocus.current?.focus();\n });\n };\n\n return {\n nodeRef: ref,\n transitionOptions: {\n nodeRef: refCallback,\n onEntering: handleMountFocus(onEntering, false),\n onEntered: handleMountFocus(\n onEntered,\n !disableTransition && !TRANSITION_CONFIG.disabled\n ),\n onExiting: handleUnmountFocus(onExiting, false),\n onExited: handleUnmountFocus(\n onExited,\n !disableTransition && !TRANSITION_CONFIG.disabled\n ),\n },\n eventHandlers: {\n onKeyDown(event) {\n onKeyDown(event);\n if (\n event.isPropagationStopped() ||\n event.key !== \"Tab\" ||\n isFocusTypeDisabled(\"keyboard\")\n ) {\n return;\n }\n\n const { target, shiftKey, currentTarget } = event;\n const elements = getFocusableElements(currentTarget, programmatic);\n const count = elements.length;\n if (count === 0) {\n event.preventDefault();\n return;\n }\n\n // if the container element is the current focus, need to either focus\n // the first or last element so focus doesn't escape\n let type: FocusElementWithinType | undefined;\n if (\n count === 1 ||\n (!shiftKey &&\n (target === currentTarget || target === elements[count - 1]))\n ) {\n type = \"first\";\n } else if (\n shiftKey &&\n (target === currentTarget || target === elements[0])\n ) {\n type = \"last\";\n }\n\n if (type) {\n event.preventDefault();\n focusElementWithin({\n type,\n elements,\n container: currentTarget,\n });\n }\n },\n },\n };\n}\n"],"names":["useEffect","useRef","TRANSITION_CONFIG","useEnsuredRef","focusElementWithin","getFocusableElements","noop","useFocusContainer","options","nodeRef","activate","onEntering","onEntered","onExiting","onExited","onKeyDown","programmatic","disableTransition","isFocusTypeDisabled","ref","refCallback","prevFocus","document","activeElement","HTMLElement","current","handleMountFocus","callback","skipped","appearing","instance","contains","focus","handleUnmountFocus","window","requestAnimationFrame","transitionOptions","disabled","eventHandlers","event","isPropagationStopped","key","target","shiftKey","currentTarget","elements","count","length","preventDefault","type","container"],"mappings":"AAAA;AAEA,SAIEA,SAAS,EACTC,MAAM,QACD,QAAQ;AAEf,SAASC,iBAAiB,QAAQ,0BAA0B;AAM5D,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAEEC,kBAAkB,EAClBC,oBAAoB,QACf,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AAsFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CC,GACD,OAAO,SAASC,kBACdC,OAAiC;IAEjC,MAAM,EACJC,OAAO,EACPC,QAAQ,EACRC,aAAaL,IAAI,EACjBM,YAAYN,IAAI,EAChBO,YAAYP,IAAI,EAChBQ,WAAWR,IAAI,EACfS,YAAYT,IAAI,EAChBU,eAAe,KAAK,EACpBC,oBAAoB,KAAK,EACzBC,sBAAsBZ,IAAI,EAC3B,GAAGE;IAEJ,MAAM,CAACW,KAAKC,YAAY,GAAGjB,cAAcM;IACzC,MAAMY,YAAYpB,OAA2B;IAE7CD,UAAU;QACR,IAAI,CAACU,YAAY,CAAEY,CAAAA,SAASC,aAAa,YAAYC,WAAU,GAAI;YACjE;QACF;QAEAH,UAAUI,OAAO,GAAGH,SAASC,aAAa;IAC5C,GAAG;QAACb;KAAS;IAEb,MAAMgB,mBACJ,CAACC,UAAkCC,UACnC,CAACC;YACCF,SAASE;YACT,MAAMC,WAAWX,IAAIM,OAAO;YAC5B,IACEK,YACA,CAACF,WACD,CAACV,oBAAoB,YACpB,CAAA,CAACI,SAASC,aAAa,IAAI,CAACO,SAASC,QAAQ,CAACT,SAASC,aAAa,CAAA,GACrE;gBACAO,SAASE,KAAK;YAChB;QACF;IAEF,MAAMC,qBACJ,CAACN,UAAiCC,UAAqB;YACrDD;YACA,IAAIC,WAAWV,oBAAoB,YAAY;gBAC7C;YACF;YAEA,2EAA2E;YAC3E,iCAAiC;YACjCgB,OAAOC,qBAAqB,CAAC;gBAC3Bd,UAAUI,OAAO,EAAEO;YACrB;QACF;IAEF,OAAO;QACLvB,SAASU;QACTiB,mBAAmB;YACjB3B,SAASW;YACTT,YAAYe,iBAAiBf,YAAY;YACzCC,WAAWc,iBACTd,WACA,CAACK,qBAAqB,CAACf,kBAAkBmC,QAAQ;YAEnDxB,WAAWoB,mBAAmBpB,WAAW;YACzCC,UAAUmB,mBACRnB,UACA,CAACG,qBAAqB,CAACf,kBAAkBmC,QAAQ;QAErD;QACAC,eAAe;YACbvB,WAAUwB,KAAK;gBACbxB,UAAUwB;gBACV,IACEA,MAAMC,oBAAoB,MAC1BD,MAAME,GAAG,KAAK,SACdvB,oBAAoB,aACpB;oBACA;gBACF;gBAEA,MAAM,EAAEwB,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAGL;gBAC5C,MAAMM,WAAWxC,qBAAqBuC,eAAe5B;gBACrD,MAAM8B,QAAQD,SAASE,MAAM;gBAC7B,IAAID,UAAU,GAAG;oBACfP,MAAMS,cAAc;oBACpB;gBACF;gBAEA,sEAAsE;gBACtE,oDAAoD;gBACpD,IAAIC;gBACJ,IACEH,UAAU,KACT,CAACH,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAACC,QAAQ,EAAE,AAAD,GAC5D;oBACAG,OAAO;gBACT,OAAO,IACLN,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAAC,EAAE,AAAD,GAClD;oBACAI,OAAO;gBACT;gBAEA,IAAIA,MAAM;oBACRV,MAAMS,cAAc;oBACpB5C,mBAAmB;wBACjB6C;wBACAJ;wBACAK,WAAWN;oBACb;gBACF;YACF;QACF;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/Checkbox.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/form/Checkbox.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { type CheckboxProps, InputToggle } from \"./InputToggle.js\";\n\n/**\n * **Client Component**\n *\n * You'll generally want to use the `useCheckboxGroup` hook for managing the\n * checked state for groups of checkboxes and indeterminate checkbox behavior.\n *\n * @example Simple Example\n * ```tsx\n * import type { ReactElement } from \"react\";\n * import { Checkbox } from \"@react-md/core\";\n *\n * function Example(): ReactElement {\n * return <Checkbox label=\"Checkbox\" value=\"a\" />;\n * }\n * ```\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n function Checkbox(props, ref) {\n return <InputToggle {...props} ref={ref} type=\"checkbox\" />;\n }\n);\n"],"names":["forwardRef","InputToggle","Checkbox","props","ref","type"],"mappings":";AAAA,SAASA,UAAU,QAAQ,QAAQ;AAEnC,SAA6BC,WAAW,QAAQ,mBAAmB;AAEnE;;;;;;;;;;;;;;;CAeC,GACD,OAAO,MAAMC,yBAAWF,WACtB,SAASE,SAASC,KAAK,EAAEC,GAAG;IAC1B,qBAAO,KAACH;QAAa,GAAGE,KAAK;QAAEC,KAAKA;QAAKC,MAAK;;AAChD,GACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/Fieldset.tsx"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/form/Fieldset.tsx"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport { type FieldsetHTMLAttributes, forwardRef } from \"react\";\n\nimport { bem } from \"../utils/bem.js\";\n\nconst styles = bem(\"rmd-fieldset\");\n\n/** @since 6.0.0 */\nexport interface FieldsetClassNameOptions {\n className?: string;\n\n /**\n * Set this to `true` to enable the default browser styles for a fieldset.\n *\n * @since 6.0.0 This was renamed from `unstyled`.\n * @defaultValue `false`\n */\n browserStyles?: boolean;\n\n /**\n * @defaultValue `false`\n */\n fullWidth?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport function fieldset(options: FieldsetClassNameOptions = {}): string {\n const { className, fullWidth, browserStyles = false } = options;\n\n return cnb(\n styles({ unstyled: !browserStyles, \"full-width\": fullWidth }),\n className\n );\n}\n\n/**\n * @since 6.0.0 Removed the `legend`, `legendStyle`,\n * `legendClassName`, and `legendSROnly` props. You must provide a `Legend`\n * yourself manually instead of using a prop.\n */\nexport interface FieldsetProps\n extends FieldsetHTMLAttributes<HTMLFieldSetElement>,\n FieldsetClassNameOptions {}\n\n/**\n * @example Simple Example\n * ```tsx\n * import { Form, Fieldset, Legend } from \"@react-md/core\";\n *\n * function Example(): ReactElement {\n * return (\n * <Form>\n * <Fieldset>\n * <Legend>Some Title</Legend>\n * // form components\n * </Fieldset>\n * </Form>\n * );\n * }\n * ```\n */\nexport const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(\n function Fieldset(props, ref) {\n const {\n className,\n fullWidth = false,\n browserStyles = false,\n children,\n ...remaining\n } = props;\n\n return (\n <fieldset\n {...remaining}\n ref={ref}\n className={fieldset({\n className,\n fullWidth,\n browserStyles,\n })}\n >\n {children}\n </fieldset>\n );\n }\n);\n"],"names":["cnb","forwardRef","bem","styles","fieldset","options","className","fullWidth","browserStyles","unstyled","Fieldset","props","ref","children","remaining"],"mappings":";AAAA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAAsCC,UAAU,QAAQ,QAAQ;AAEhE,SAASC,GAAG,QAAQ,kBAAkB;AAEtC,MAAMC,SAASD,IAAI;AAoBnB;;CAEC,GACD,OAAO,SAASE,SAASC,UAAoC,CAAC,CAAC;IAC7D,MAAM,EAAEC,SAAS,EAAEC,SAAS,EAAEC,gBAAgB,KAAK,EAAE,GAAGH;IAExD,OAAOL,IACLG,OAAO;QAAEM,UAAU,CAACD;QAAe,cAAcD;IAAU,IAC3DD;AAEJ;AAWA;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,MAAMI,yBAAWT,WACtB,SAASS,SAASC,KAAK,EAAEC,GAAG;IAC1B,MAAM,EACJN,SAAS,EACTC,YAAY,KAAK,EACjBC,gBAAgB,KAAK,EACrBK,QAAQ,EACR,GAAGC,WACJ,GAAGH;IAEJ,qBACE,KAACP;QACE,GAAGU,SAAS;QACbF,KAAKA;QACLN,WAAWF,SAAS;YAClBE;YACAC;YACAC;QACF;kBAECK;;AAGP,GACA"}
|
package/dist/form/Form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/Form.tsx"],"sourcesContent":["\"use client\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/form/Form.tsx"],"sourcesContent":["\"use client\";\n\nimport { type FormHTMLAttributes, forwardRef } from \"react\";\n\nconst noop = (): void => {\n // do nothing\n};\n\nexport interface FormProps extends FormHTMLAttributes<HTMLFormElement> {\n /**\n * Boolean if the form should no longer prevent default submit behavior. If\n * you enable this prop you should honestly just use a `<form>` element\n * instead\n *\n * @defaultValue `false`\n */\n disablePreventDefault?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * This is probably one of the least useful components available as it doesn't\n * do much styling or logic. All this form component will do is add basic flex\n * behavior and prevent the default form submit behavior.\n */\nexport const Form = forwardRef<HTMLFormElement, FormProps>(\n function Form(props, ref) {\n const {\n children,\n onSubmit = noop,\n disablePreventDefault = false,\n ...remaining\n } = props;\n\n return (\n <form\n {...remaining}\n onSubmit={(event) => {\n if (!disablePreventDefault) {\n event.preventDefault();\n }\n\n onSubmit(event);\n }}\n ref={ref}\n >\n {children}\n </form>\n );\n }\n);\n"],"names":["forwardRef","noop","Form","props","ref","children","onSubmit","disablePreventDefault","remaining","form","event","preventDefault"],"mappings":"AAAA;;AAEA,SAAkCA,UAAU,QAAQ,QAAQ;AAE5D,MAAMC,OAAO;AACX,aAAa;AACf;AAaA;;;;;;CAMC,GACD,OAAO,MAAMC,qBAAOF,WAClB,SAASE,KAAKC,KAAK,EAAEC,GAAG;IACtB,MAAM,EACJC,QAAQ,EACRC,WAAWL,IAAI,EACfM,wBAAwB,KAAK,EAC7B,GAAGC,WACJ,GAAGL;IAEJ,qBACE,KAACM;QACE,GAAGD,SAAS;QACbF,UAAU,CAACI;YACT,IAAI,CAACH,uBAAuB;gBAC1BG,MAAMC,cAAc;YACtB;YAEAL,SAASI;QACX;QACAN,KAAKA;kBAEJC;;AAGP,GACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/FormMessage.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageCounter } from \"./FormMessageCounter.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { formMessage, formMessageText } from \"./formMessageStyles.js\";\nimport {\n type FormMessageInputLengthCounterProps,\n type FormMessageProps,\n} from \"./types.js\";\n\n/**\n * The `FormMessage` component is used to create additional helper messages or\n * error messages and generally placed below the related `TextField`. If a\n * `length` (of the `value`) and `maxLength` are provided, a counter will also\n * be displayed to the right of the `children`.\n *\n * This component can also be used to create form-level validation messages by\n * setting the `role` prop to `\"alert\"`.\n */\nexport const FormMessage = forwardRef<\n HTMLDivElement,\n FormMessageProps & Partial<FormMessageInputLengthCounterProps>\n>(function FormMessage(props, ref) {\n const {\n id: propId,\n role,\n className,\n counterStyle,\n counterClassName,\n messageStyle,\n messageClassName,\n error = false,\n disableWrap = false,\n theme: propTheme,\n children,\n length,\n maxLength,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"form-message\");\n const theme = getFormConfig(\"theme\", propTheme);\n\n let message = children;\n if (!disableWrap && children) {\n message = (\n <p\n id={`${id}-message`}\n style={messageStyle}\n className={formMessageText({ className: messageClassName })}\n >\n {children}\n </p>\n );\n }\n\n return (\n <div\n {...remaining}\n id={id}\n ref={ref}\n aria-live={role !== \"alert\" ? \"polite\" : undefined}\n role={role}\n className={formMessage({ error, theme, className })}\n >\n {message}\n {typeof length === \"number\" && typeof maxLength === \"number\" && (\n <FormMessageCounter\n id={`${id}-counter`}\n style={counterStyle}\n className={counterClassName}\n >\n {`${length} / ${maxLength}`}\n </FormMessageCounter>\n )}\n </div>\n );\n});\n"],"names":["forwardRef","useEnsuredId","FormMessageCounter","getFormConfig","formMessage","formMessageText","FormMessage","props","ref","id","propId","role","className","counterStyle","counterClassName","messageStyle","messageClassName","error","disableWrap","theme","propTheme","children","length","maxLength","remaining","message","p","style","div","aria-live","undefined"],"mappings":";AAAA,SAASA,UAAU,QAAQ,QAAQ;
|
|
1
|
+
{"version":3,"sources":["../../src/form/FormMessage.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageCounter } from \"./FormMessageCounter.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { formMessage, formMessageText } from \"./formMessageStyles.js\";\nimport {\n type FormMessageInputLengthCounterProps,\n type FormMessageProps,\n} from \"./types.js\";\n\n/**\n * The `FormMessage` component is used to create additional helper messages or\n * error messages and generally placed below the related `TextField`. If a\n * `length` (of the `value`) and `maxLength` are provided, a counter will also\n * be displayed to the right of the `children`.\n *\n * This component can also be used to create form-level validation messages by\n * setting the `role` prop to `\"alert\"`.\n */\nexport const FormMessage = forwardRef<\n HTMLDivElement,\n FormMessageProps & Partial<FormMessageInputLengthCounterProps>\n>(function FormMessage(props, ref) {\n const {\n id: propId,\n role,\n className,\n counterStyle,\n counterClassName,\n messageStyle,\n messageClassName,\n error = false,\n disableWrap = false,\n theme: propTheme,\n children,\n length,\n maxLength,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"form-message\");\n const theme = getFormConfig(\"theme\", propTheme);\n\n let message = children;\n if (!disableWrap && children) {\n message = (\n <p\n id={`${id}-message`}\n style={messageStyle}\n className={formMessageText({ className: messageClassName })}\n >\n {children}\n </p>\n );\n }\n\n return (\n <div\n {...remaining}\n id={id}\n ref={ref}\n aria-live={role !== \"alert\" ? \"polite\" : undefined}\n role={role}\n className={formMessage({ error, theme, className })}\n >\n {message}\n {typeof length === \"number\" && typeof maxLength === \"number\" && (\n <FormMessageCounter\n id={`${id}-counter`}\n style={counterStyle}\n className={counterClassName}\n >\n {`${length} / ${maxLength}`}\n </FormMessageCounter>\n )}\n </div>\n );\n});\n"],"names":["forwardRef","useEnsuredId","FormMessageCounter","getFormConfig","formMessage","formMessageText","FormMessage","props","ref","id","propId","role","className","counterStyle","counterClassName","messageStyle","messageClassName","error","disableWrap","theme","propTheme","children","length","maxLength","remaining","message","p","style","div","aria-live","undefined"],"mappings":";AAAA,SAASA,UAAU,QAAQ,QAAQ;AAEnC,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,WAAW,EAAEC,eAAe,QAAQ,yBAAyB;AAMtE;;;;;;;;CAQC,GACD,OAAO,MAAMC,4BAAcN,WAGzB,SAASM,YAAYC,KAAK,EAAEC,GAAG;IAC/B,MAAM,EACJC,IAAIC,MAAM,EACVC,IAAI,EACJC,SAAS,EACTC,YAAY,EACZC,gBAAgB,EAChBC,YAAY,EACZC,gBAAgB,EAChBC,QAAQ,KAAK,EACbC,cAAc,KAAK,EACnBC,OAAOC,SAAS,EAChBC,QAAQ,EACRC,MAAM,EACNC,SAAS,EACT,GAAGC,WACJ,GAAGjB;IACJ,MAAME,KAAKR,aAAaS,QAAQ;IAChC,MAAMS,QAAQhB,cAAc,SAASiB;IAErC,IAAIK,UAAUJ;IACd,IAAI,CAACH,eAAeG,UAAU;QAC5BI,wBACE,KAACC;YACCjB,IAAI,GAAGA,GAAG,QAAQ,CAAC;YACnBkB,OAAOZ;YACPH,WAAWP,gBAAgB;gBAAEO,WAAWI;YAAiB;sBAExDK;;IAGP;IAEA,qBACE,MAACO;QACE,GAAGJ,SAAS;QACbf,IAAIA;QACJD,KAAKA;QACLqB,aAAWlB,SAAS,UAAU,WAAWmB;QACzCnB,MAAMA;QACNC,WAAWR,YAAY;YAAEa;YAAOE;YAAOP;QAAU;;YAEhDa;YACA,OAAOH,WAAW,YAAY,OAAOC,cAAc,0BAClD,KAACrB;gBACCO,IAAI,GAAGA,GAAG,QAAQ,CAAC;gBACnBkB,OAAOd;gBACPD,WAAWE;0BAEV,GAAGQ,OAAO,GAAG,EAAEC,WAAW;;;;AAKrC,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/FormMessageContainer.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/form/FormMessageContainer.tsx"],"sourcesContent":["import { type HTMLAttributes, forwardRef } from \"react\";\n\nimport { type PropsWithRef } from \"../types.js\";\nimport { FormMessage } from \"./FormMessage.js\";\nimport { formMessageContainer } from \"./formMessageContainerStyles.js\";\nimport { type FormMessageProps } from \"./types.js\";\n\n/**\n * @since 2.5.0\n */\nexport interface FormMessageContainerProps\n extends HTMLAttributes<HTMLDivElement> {\n /**\n * If the extension doesn't actually want to render the `FormMessage`\n * component, these props are optional. It kind of eliminates the whole\n * purpose of this component though.\n */\n messageProps?: PropsWithRef<FormMessageProps, HTMLDivElement>;\n}\n\n/**\n * Conditionally wraps the `children` in a `.rmd-form-message-container` wrapper\n * and renders the {@link FormMessage} component.\n *\n * @since 2.5.0\n */\nexport const FormMessageContainer = forwardRef<\n HTMLDivElement,\n FormMessageContainerProps\n>(function FormMessageContainer(props, ref) {\n const { className, children, messageProps, ...remaining } = props;\n if (!messageProps) {\n return <>{children}</>;\n }\n\n return (\n <div\n {...remaining}\n ref={ref}\n className={formMessageContainer({ className })}\n >\n {children}\n <FormMessage {...messageProps} />\n </div>\n );\n});\n"],"names":["forwardRef","FormMessage","formMessageContainer","FormMessageContainer","props","ref","className","children","messageProps","remaining","div"],"mappings":";AAAA,SAA8BA,UAAU,QAAQ,QAAQ;AAGxD,SAASC,WAAW,QAAQ,mBAAmB;AAC/C,SAASC,oBAAoB,QAAQ,kCAAkC;AAgBvE;;;;;CAKC,GACD,OAAO,MAAMC,qCAAuBH,WAGlC,SAASG,qBAAqBC,KAAK,EAAEC,GAAG;IACxC,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,YAAY,EAAE,GAAGC,WAAW,GAAGL;IAC5D,IAAI,CAACI,cAAc;QACjB,qBAAO;sBAAGD;;IACZ;IAEA,qBACE,MAACG;QACE,GAAGD,SAAS;QACbJ,KAAKA;QACLC,WAAWJ,qBAAqB;YAAEI;QAAU;;YAE3CC;0BACD,KAACN;gBAAa,GAAGO,YAAY;;;;AAGnC,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/FormMessageCounter.tsx"],"sourcesContent":["import { type HTMLAttributes, type ReactElement, type ReactNode } from \"react\";\nimport { formMessageCounter } from \"./formMessageStyles.js\";\n\n/** @since 2.9.0 */\nexport interface FormMessageCounterProps\n extends HTMLAttributes<HTMLSpanElement> {\n /**\n * The children to display in the counter. This is normally a string like:\n *\n * @example String Example\n * ```ts\n * `${min} / ${max}`\n * ```\n */\n children: ReactNode;\n}\n\n/**\n * This component can be used to create a \"counter\" within the\n * {@link FormMessage} component.\n *\n * Note: This is really only useful when using the {@link FormMessage} component\n * without a {@link TextField}.\n *\n * @example Example Usage\n * ```ts\n * interface ExampleProps {\n * min: number;\n * max: number;\n * }\n *\n * function Example({ min, max }: ExampleProps) {\n * return (\n * <FormMessage disableWrap>\n * <FormMessageCounter>\n * {`${min} / ${max}`}\n * </FormMessageCounter>\n * </FormMessage>\n * );\n * }\n * ```\n *\n * @since 2.9.0\n */\nexport function FormMessageCounter(\n props: FormMessageCounterProps\n): ReactElement {\n const { children, className, ...remaining } = props;\n\n return (\n <span {...remaining} className={formMessageCounter({ className })}>\n {children}\n </span>\n );\n}\n"],"names":["formMessageCounter","FormMessageCounter","props","children","className","remaining","span"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/form/FormMessageCounter.tsx"],"sourcesContent":["import { type HTMLAttributes, type ReactElement, type ReactNode } from \"react\";\n\nimport { formMessageCounter } from \"./formMessageStyles.js\";\n\n/** @since 2.9.0 */\nexport interface FormMessageCounterProps\n extends HTMLAttributes<HTMLSpanElement> {\n /**\n * The children to display in the counter. This is normally a string like:\n *\n * @example String Example\n * ```ts\n * `${min} / ${max}`\n * ```\n */\n children: ReactNode;\n}\n\n/**\n * This component can be used to create a \"counter\" within the\n * {@link FormMessage} component.\n *\n * Note: This is really only useful when using the {@link FormMessage} component\n * without a {@link TextField}.\n *\n * @example Example Usage\n * ```ts\n * interface ExampleProps {\n * min: number;\n * max: number;\n * }\n *\n * function Example({ min, max }: ExampleProps) {\n * return (\n * <FormMessage disableWrap>\n * <FormMessageCounter>\n * {`${min} / ${max}`}\n * </FormMessageCounter>\n * </FormMessage>\n * );\n * }\n * ```\n *\n * @since 2.9.0\n */\nexport function FormMessageCounter(\n props: FormMessageCounterProps\n): ReactElement {\n const { children, className, ...remaining } = props;\n\n return (\n <span {...remaining} className={formMessageCounter({ className })}>\n {children}\n </span>\n );\n}\n"],"names":["formMessageCounter","FormMessageCounter","props","children","className","remaining","span"],"mappings":";AAEA,SAASA,kBAAkB,QAAQ,yBAAyB;AAgB5D;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GACD,OAAO,SAASC,mBACdC,KAA8B;IAE9B,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAE,GAAGC,WAAW,GAAGH;IAE9C,qBACE,KAACI;QAAM,GAAGD,SAAS;QAAED,WAAWJ,mBAAmB;YAAEI;QAAU;kBAC5DD;;AAGP"}
|