@allxsmith/bestax-bulma 5.56.0 → 5.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/esm/columns/Column.js +1 -0
- package/dist/esm/columns/Column.js.map +1 -1
- package/dist/esm/columns/Columns.js +1 -0
- package/dist/esm/columns/Columns.js.map +1 -1
- package/dist/esm/components/Avatar.js +1 -0
- package/dist/esm/components/Avatar.js.map +1 -1
- package/dist/esm/components/Avatars.js +1 -0
- package/dist/esm/components/Avatars.js.map +1 -1
- package/dist/esm/components/Badge.js +1 -0
- package/dist/esm/components/Badge.js.map +1 -1
- package/dist/esm/components/Breadcrumb.js +1 -0
- package/dist/esm/components/Breadcrumb.js.map +1 -1
- package/dist/esm/components/Card.js +1 -0
- package/dist/esm/components/Card.js.map +1 -1
- package/dist/esm/components/Carousel.js +1 -0
- package/dist/esm/components/Carousel.js.map +1 -1
- package/dist/esm/components/Collapse.js +1 -0
- package/dist/esm/components/Collapse.js.map +1 -1
- package/dist/esm/components/Collapses.js +1 -0
- package/dist/esm/components/Collapses.js.map +1 -1
- package/dist/esm/components/Command.js +1 -0
- package/dist/esm/components/Command.js.map +1 -1
- package/dist/esm/components/ContextMenu.js +1 -0
- package/dist/esm/components/ContextMenu.js.map +1 -1
- package/dist/esm/components/DataTable.js +1 -0
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/Dialog.js +1 -0
- package/dist/esm/components/Dialog.js.map +1 -1
- package/dist/esm/components/Dropdown.js +5 -1
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/EmptyState.js +1 -0
- package/dist/esm/components/EmptyState.js.map +1 -1
- package/dist/esm/components/HoverCard.js +1 -0
- package/dist/esm/components/HoverCard.js.map +1 -1
- package/dist/esm/components/Loading.js +1 -0
- package/dist/esm/components/Loading.js.map +1 -1
- package/dist/esm/components/Menu.js +1 -0
- package/dist/esm/components/Menu.js.map +1 -1
- package/dist/esm/components/Message.js +1 -0
- package/dist/esm/components/Message.js.map +1 -1
- package/dist/esm/components/Modal.js +1 -0
- package/dist/esm/components/Modal.js.map +1 -1
- package/dist/esm/components/Navbar.js +1 -0
- package/dist/esm/components/Navbar.js.map +1 -1
- package/dist/esm/components/Pagination.js +1 -0
- package/dist/esm/components/Pagination.js.map +1 -1
- package/dist/esm/components/Panel.js +1 -0
- package/dist/esm/components/Panel.js.map +1 -1
- package/dist/esm/components/Popover.js +1 -0
- package/dist/esm/components/Popover.js.map +1 -1
- package/dist/esm/components/Reveal.js +1 -0
- package/dist/esm/components/Reveal.js.map +1 -1
- package/dist/esm/components/ScrollArea.js +1 -0
- package/dist/esm/components/ScrollArea.js.map +1 -1
- package/dist/esm/components/SegmentedControl.js +1 -0
- package/dist/esm/components/SegmentedControl.js.map +1 -1
- package/dist/esm/components/Sidebar.js +1 -0
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/components/Steps.js +1 -0
- package/dist/esm/components/Steps.js.map +1 -1
- package/dist/esm/components/Tabs.js +1 -0
- package/dist/esm/components/Tabs.js.map +1 -1
- package/dist/esm/components/Timeline.js +1 -0
- package/dist/esm/components/Timeline.js.map +1 -1
- package/dist/esm/components/Toast.js +1 -0
- package/dist/esm/components/Toast.js.map +1 -1
- package/dist/esm/components/Tooltip.js +1 -0
- package/dist/esm/components/Tooltip.js.map +1 -1
- package/dist/esm/components/TreeView.js +1 -0
- package/dist/esm/components/TreeView.js.map +1 -1
- package/dist/esm/components/collapsesContext.js +1 -0
- package/dist/esm/components/collapsesContext.js.map +1 -1
- package/dist/esm/components/useDataTable.js +1 -0
- package/dist/esm/components/useDataTable.js.map +1 -1
- package/dist/esm/elements/Block.js +1 -0
- package/dist/esm/elements/Block.js.map +1 -1
- package/dist/esm/elements/Box.js +1 -0
- package/dist/esm/elements/Box.js.map +1 -1
- package/dist/esm/elements/Button.js +1 -0
- package/dist/esm/elements/Button.js.map +1 -1
- package/dist/esm/elements/Buttons.js +1 -0
- package/dist/esm/elements/Buttons.js.map +1 -1
- package/dist/esm/elements/Code.js +1 -0
- package/dist/esm/elements/Code.js.map +1 -1
- package/dist/esm/elements/ColorSwatch.js +1 -0
- package/dist/esm/elements/ColorSwatch.js.map +1 -1
- package/dist/esm/elements/Content.js +1 -0
- package/dist/esm/elements/Content.js.map +1 -1
- package/dist/esm/elements/Delete.js +1 -0
- package/dist/esm/elements/Delete.js.map +1 -1
- package/dist/esm/elements/DescriptionList.js +1 -0
- package/dist/esm/elements/DescriptionList.js.map +1 -1
- package/dist/esm/elements/Divider.js +1 -0
- package/dist/esm/elements/Divider.js.map +1 -1
- package/dist/esm/elements/Emphasis.js +1 -0
- package/dist/esm/elements/Emphasis.js.map +1 -1
- package/dist/esm/elements/Figure.js +1 -0
- package/dist/esm/elements/Figure.js.map +1 -1
- package/dist/esm/elements/Icon.js +1 -0
- package/dist/esm/elements/Icon.js.map +1 -1
- package/dist/esm/elements/IconText.js +1 -0
- package/dist/esm/elements/IconText.js.map +1 -1
- package/dist/esm/elements/Image.js +1 -0
- package/dist/esm/elements/Image.js.map +1 -1
- package/dist/esm/elements/Kbd.js +1 -0
- package/dist/esm/elements/Kbd.js.map +1 -1
- package/dist/esm/elements/Link.js +1 -0
- package/dist/esm/elements/Link.js.map +1 -1
- package/dist/esm/elements/LinkButton.js +1 -0
- package/dist/esm/elements/LinkButton.js.map +1 -1
- package/dist/esm/elements/ListItem.js +1 -0
- package/dist/esm/elements/ListItem.js.map +1 -1
- package/dist/esm/elements/Loader.js +1 -0
- package/dist/esm/elements/Loader.js.map +1 -1
- package/dist/esm/elements/Notification.js +1 -0
- package/dist/esm/elements/Notification.js.map +1 -1
- package/dist/esm/elements/OrderedList.js +1 -0
- package/dist/esm/elements/OrderedList.js.map +1 -1
- package/dist/esm/elements/Paragraph.js +1 -0
- package/dist/esm/elements/Paragraph.js.map +1 -1
- package/dist/esm/elements/Pre.js +1 -0
- package/dist/esm/elements/Pre.js.map +1 -1
- package/dist/esm/elements/Progress.js +1 -0
- package/dist/esm/elements/Progress.js.map +1 -1
- package/dist/esm/elements/RingProgress.js +1 -0
- package/dist/esm/elements/RingProgress.js.map +1 -1
- package/dist/esm/elements/Skeleton.js +1 -0
- package/dist/esm/elements/Skeleton.js.map +1 -1
- package/dist/esm/elements/Span.js +1 -0
- package/dist/esm/elements/Span.js.map +1 -1
- package/dist/esm/elements/Strong.js +1 -0
- package/dist/esm/elements/Strong.js.map +1 -1
- package/dist/esm/elements/SubTitle.js +1 -0
- package/dist/esm/elements/SubTitle.js.map +1 -1
- package/dist/esm/elements/Table.js +1 -0
- package/dist/esm/elements/Table.js.map +1 -1
- package/dist/esm/elements/Tag.js +1 -0
- package/dist/esm/elements/Tag.js.map +1 -1
- package/dist/esm/elements/Tags.js +1 -0
- package/dist/esm/elements/Tags.js.map +1 -1
- package/dist/esm/elements/Tbody.js +1 -0
- package/dist/esm/elements/Tbody.js.map +1 -1
- package/dist/esm/elements/Td.js +1 -0
- package/dist/esm/elements/Td.js.map +1 -1
- package/dist/esm/elements/Tfoot.js +1 -0
- package/dist/esm/elements/Tfoot.js.map +1 -1
- package/dist/esm/elements/Th.js +1 -0
- package/dist/esm/elements/Th.js.map +1 -1
- package/dist/esm/elements/Thead.js +1 -0
- package/dist/esm/elements/Thead.js.map +1 -1
- package/dist/esm/elements/Title.js +1 -0
- package/dist/esm/elements/Title.js.map +1 -1
- package/dist/esm/elements/ToggleButton.js +1 -0
- package/dist/esm/elements/ToggleButton.js.map +1 -1
- package/dist/esm/elements/Tr.js +1 -0
- package/dist/esm/elements/Tr.js.map +1 -1
- package/dist/esm/elements/UnorderedList.js +1 -0
- package/dist/esm/elements/UnorderedList.js.map +1 -1
- package/dist/esm/elements/iconProps.js +1 -0
- package/dist/esm/elements/iconProps.js.map +1 -1
- package/dist/esm/form/Autocomplete.js +1 -0
- package/dist/esm/form/Autocomplete.js.map +1 -1
- package/dist/esm/form/Checkbox.js +1 -0
- package/dist/esm/form/Checkbox.js.map +1 -1
- package/dist/esm/form/CheckboxCard.js +1 -0
- package/dist/esm/form/CheckboxCard.js.map +1 -1
- package/dist/esm/form/Checkboxes.js +1 -0
- package/dist/esm/form/Checkboxes.js.map +1 -1
- package/dist/esm/form/ColorInput.js +1 -0
- package/dist/esm/form/ColorInput.js.map +1 -1
- package/dist/esm/form/ColorInputBase.js +1 -0
- package/dist/esm/form/ColorInputBase.js.map +1 -1
- package/dist/esm/form/ColorPicker.js +1 -0
- package/dist/esm/form/ColorPicker.js.map +1 -1
- package/dist/esm/form/Combobox.js +1 -0
- package/dist/esm/form/Combobox.js.map +1 -1
- package/dist/esm/form/Control.js +1 -0
- package/dist/esm/form/Control.js.map +1 -1
- package/dist/esm/form/DateInput.js +1 -0
- package/dist/esm/form/DateInput.js.map +1 -1
- package/dist/esm/form/DateInputBase.js +1 -0
- package/dist/esm/form/DateInputBase.js.map +1 -1
- package/dist/esm/form/DateRangeInput.js +1 -0
- package/dist/esm/form/DateRangeInput.js.map +1 -1
- package/dist/esm/form/DateRangeInputBase.js +1 -0
- package/dist/esm/form/DateRangeInputBase.js.map +1 -1
- package/dist/esm/form/DateTimeInput.js +1 -0
- package/dist/esm/form/DateTimeInput.js.map +1 -1
- package/dist/esm/form/DateTimeInputBase.js +1 -0
- package/dist/esm/form/DateTimeInputBase.js.map +1 -1
- package/dist/esm/form/Dropzone.js +1 -0
- package/dist/esm/form/Dropzone.js.map +1 -1
- package/dist/esm/form/Field.js +1 -0
- package/dist/esm/form/Field.js.map +1 -1
- package/dist/esm/form/Fieldset.js +1 -0
- package/dist/esm/form/Fieldset.js.map +1 -1
- package/dist/esm/form/File.js +1 -0
- package/dist/esm/form/File.js.map +1 -1
- package/dist/esm/form/FormContext.js +1 -0
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/Input.js +1 -0
- package/dist/esm/form/Input.js.map +1 -1
- package/dist/esm/form/InputBase.js +1 -0
- package/dist/esm/form/InputBase.js.map +1 -1
- package/dist/esm/form/Numberinput.js +1 -0
- package/dist/esm/form/Numberinput.js.map +1 -1
- package/dist/esm/form/PinInput.js +1 -0
- package/dist/esm/form/PinInput.js.map +1 -1
- package/dist/esm/form/Radio.js +1 -0
- package/dist/esm/form/Radio.js.map +1 -1
- package/dist/esm/form/RadioCard.js +1 -0
- package/dist/esm/form/RadioCard.js.map +1 -1
- package/dist/esm/form/Radios.js +1 -0
- package/dist/esm/form/Radios.js.map +1 -1
- package/dist/esm/form/Rate.js +1 -0
- package/dist/esm/form/Rate.js.map +1 -1
- package/dist/esm/form/Select.js +1 -0
- package/dist/esm/form/Select.js.map +1 -1
- package/dist/esm/form/SelectBase.js +1 -0
- package/dist/esm/form/SelectBase.js.map +1 -1
- package/dist/esm/form/Slider.js +1 -0
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/Switch.js +1 -0
- package/dist/esm/form/Switch.js.map +1 -1
- package/dist/esm/form/Taginput.js +1 -0
- package/dist/esm/form/Taginput.js.map +1 -1
- package/dist/esm/form/TextArea.js +1 -0
- package/dist/esm/form/TextArea.js.map +1 -1
- package/dist/esm/form/TextAreaBase.js +1 -0
- package/dist/esm/form/TextAreaBase.js.map +1 -1
- package/dist/esm/form/TimeInput.js +1 -0
- package/dist/esm/form/TimeInput.js.map +1 -1
- package/dist/esm/form/TimeInputBase.js +1 -0
- package/dist/esm/form/TimeInputBase.js.map +1 -1
- package/dist/esm/form/_colorInternals/EyeDropperButton.js +1 -0
- package/dist/esm/form/_colorInternals/EyeDropperButton.js.map +1 -1
- package/dist/esm/form/_colorInternals/pickerState.js +1 -0
- package/dist/esm/form/_colorInternals/pickerState.js.map +1 -1
- package/dist/esm/form/_pickerInternals/Calendar.js +1 -0
- package/dist/esm/form/_pickerInternals/Calendar.js.map +1 -1
- package/dist/esm/form/_pickerInternals/PickerPopover.js +1 -0
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
- package/dist/esm/form/_pickerInternals/TimeWheels.js +1 -0
- package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useLocaleDefaults.js +1 -0
- package/dist/esm/form/_pickerInternals/useLocaleDefaults.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js +1 -0
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js +1 -0
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js.map +1 -1
- package/dist/esm/form/controlLoading.js +1 -0
- package/dist/esm/form/controlLoading.js.map +1 -1
- package/dist/esm/form/groupFieldset.js +1 -0
- package/dist/esm/form/groupFieldset.js.map +1 -1
- package/dist/esm/form/useAutoLabelId.js +1 -0
- package/dist/esm/form/useAutoLabelId.js.map +1 -1
- package/dist/esm/grid/Cell.js +1 -0
- package/dist/esm/grid/Cell.js.map +1 -1
- package/dist/esm/grid/Grid.js +1 -0
- package/dist/esm/grid/Grid.js.map +1 -1
- package/dist/esm/helpers/ClientOnly.js +1 -0
- package/dist/esm/helpers/ClientOnly.js.map +1 -1
- package/dist/esm/helpers/Config.js +1 -0
- package/dist/esm/helpers/Config.js.map +1 -1
- package/dist/esm/helpers/LocaleProvider.js +1 -0
- package/dist/esm/helpers/LocaleProvider.js.map +1 -1
- package/dist/esm/helpers/Theme.js +1 -0
- package/dist/esm/helpers/Theme.js.map +1 -1
- package/dist/esm/helpers/flattenChildren.js +1 -0
- package/dist/esm/helpers/flattenChildren.js.map +1 -1
- package/dist/esm/helpers/inertProps.js +1 -0
- package/dist/esm/helpers/inertProps.js.map +1 -1
- package/dist/esm/helpers/localeFormat.js +1 -0
- package/dist/esm/helpers/localeFormat.js.map +1 -1
- package/dist/esm/helpers/overlayStack.js +1 -0
- package/dist/esm/helpers/overlayStack.js.map +1 -1
- package/dist/esm/helpers/portal.js +1 -0
- package/dist/esm/helpers/portal.js.map +1 -1
- package/dist/esm/helpers/scrollLock.js +1 -0
- package/dist/esm/helpers/scrollLock.js.map +1 -1
- package/dist/esm/helpers/statusRegion.js +1 -0
- package/dist/esm/helpers/statusRegion.js.map +1 -1
- package/dist/esm/helpers/typeahead.js +1 -0
- package/dist/esm/helpers/typeahead.js.map +1 -1
- package/dist/esm/helpers/useAnchoredPosition.js +1 -0
- package/dist/esm/helpers/useAnchoredPosition.js.map +1 -1
- package/dist/esm/helpers/useBulmaClasses.js +1 -0
- package/dist/esm/helpers/useBulmaClasses.js.map +1 -1
- package/dist/esm/helpers/useClientLayoutEffect.js +1 -0
- package/dist/esm/helpers/useClientLayoutEffect.js.map +1 -1
- package/dist/esm/helpers/useColorClasses.js +1 -0
- package/dist/esm/helpers/useColorClasses.js.map +1 -1
- package/dist/esm/helpers/useComboboxEngine.js +1 -0
- package/dist/esm/helpers/useComboboxEngine.js.map +1 -1
- package/dist/esm/helpers/useContextMenuTrigger.js +1 -0
- package/dist/esm/helpers/useContextMenuTrigger.js.map +1 -1
- package/dist/esm/helpers/useFlexboxClasses.js +1 -0
- package/dist/esm/helpers/useFlexboxClasses.js.map +1 -1
- package/dist/esm/helpers/useFocusTrap.js +1 -0
- package/dist/esm/helpers/useFocusTrap.js.map +1 -1
- package/dist/esm/helpers/useHoverOpen.js +1 -0
- package/dist/esm/helpers/useHoverOpen.js.map +1 -1
- package/dist/esm/helpers/useInertSiblings.js +1 -0
- package/dist/esm/helpers/useInertSiblings.js.map +1 -1
- package/dist/esm/helpers/useIsHydrated.js +1 -0
- package/dist/esm/helpers/useIsHydrated.js.map +1 -1
- package/dist/esm/helpers/useLatestRef.js +1 -0
- package/dist/esm/helpers/useLatestRef.js.map +1 -1
- package/dist/esm/helpers/useMenuKeys.js +1 -0
- package/dist/esm/helpers/useMenuKeys.js.map +1 -1
- package/dist/esm/helpers/useOtherClasses.js +1 -0
- package/dist/esm/helpers/useOtherClasses.js.map +1 -1
- package/dist/esm/helpers/useSpacingClasses.js +1 -0
- package/dist/esm/helpers/useSpacingClasses.js.map +1 -1
- package/dist/esm/helpers/useTreeView.js +1 -0
- package/dist/esm/helpers/useTreeView.js.map +1 -1
- package/dist/esm/helpers/useTypographyClasses.js +1 -0
- package/dist/esm/helpers/useTypographyClasses.js.map +1 -1
- package/dist/esm/helpers/useVisibilityClasses.js +1 -0
- package/dist/esm/helpers/useVisibilityClasses.js.map +1 -1
- package/dist/esm/layout/Container.js +1 -0
- package/dist/esm/layout/Container.js.map +1 -1
- package/dist/esm/layout/Footer.js +1 -0
- package/dist/esm/layout/Footer.js.map +1 -1
- package/dist/esm/layout/Hero.js +1 -0
- package/dist/esm/layout/Hero.js.map +1 -1
- package/dist/esm/layout/Level.js +1 -0
- package/dist/esm/layout/Level.js.map +1 -1
- package/dist/esm/layout/Media.js +1 -0
- package/dist/esm/layout/Media.js.map +1 -1
- package/dist/esm/layout/Section.js +1 -0
- package/dist/esm/layout/Section.js.map +1 -1
- package/dist/esm/layout/Splitter.js +1 -0
- package/dist/esm/layout/Splitter.js.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/package.json +28 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useId, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { visuallyHidden } from '../helpers/statusRegion';\nimport { Table } from '../elements/Table';\nimport { Thead } from '../elements/Thead';\nimport { Tbody } from '../elements/Tbody';\nimport { Tr, TrProps } from '../elements/Tr';\nimport { Th } from '../elements/Th';\nimport { Td } from '../elements/Td';\nimport { Skeleton } from '../elements/Skeleton';\nimport { Checkbox } from '../form/Checkbox';\nimport { Input } from '../form/Input';\nimport { EmptyState } from './EmptyState';\nimport { Pagination } from './Pagination';\nimport { ScrollArea } from './ScrollArea';\nimport {\n isFiltering,\n useDataTable,\n type DataTableColumn,\n type DataTableFilters,\n type DataTableModel,\n type DataTableStateOptions,\n} from './useDataTable';\n\nexport { useDataTable } from './useDataTable';\nexport type {\n DataTableCSVOptions,\n DataTableCellContext,\n DataTableCellProps,\n DataTableCheckboxProps,\n DataTableColumn,\n DataTableColumnMeta,\n DataTableFilters,\n DataTableHeaderCellProps,\n DataTableLabels,\n DataTableModel,\n DataTablePaginationProps,\n DataTableResolvedLabels,\n DataTableRowScope,\n DataTableSearchProps,\n DataTableSelectionMode,\n DataTableSort,\n DataTableSortButtonProps,\n DataTableSortDirection,\n DataTableState,\n DataTableStateOptions,\n UseDataTableOptions,\n} from './useDataTable';\n\n/**\n * Props for the DataTable component. The helper props, `className`, the\n * `ref` and the other attributes go on the wrapper `<div>`, which holds the\n * toolbar, the table and the pager. `aria-label` and `aria-labelledby` name\n * the `<table>` itself.\n *\n * @extraProp {string} [aria-label] - Names the table, in place of a `caption`. A table needs a name, so pass a `caption`, this or `aria-labelledby`, and a development build warns when it has none.\n * @extraProp {string} [aria-labelledby] - The id of a visible heading that names the table, in place of a `caption`.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the wrapper `<div>`.\n */\nexport interface DataTableProps<TRow>\n extends\n DataTableStateOptions<TRow>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The columns, in the order they're shown. Required unless `table` is\n * given. Keep the array the same from one render to the next, defined\n * outside the component or in `useMemo`: a new one has every cell's text\n * worked out again.\n */\n columns?: DataTableColumn<TRow>[];\n /** The rows, as records of your own. Required unless `table` is given. */\n data?: TRow[];\n /**\n * A table made by `useDataTable`, rendered in place of one made from\n * `columns`, `data` and the state props, which are then left unread. Use\n * it to put a toolbar, a count or an export button elsewhere on the page.\n */\n table?: DataTableModel<TRow>;\n /**\n * Names the table, as a visible `<caption>`. A table needs a name: this,\n * `aria-label` or `aria-labelledby`.\n */\n caption?: React.ReactNode;\n /** Adds borders to all cells. */\n isBordered?: boolean;\n /** Adds zebra-striping to rows. */\n isStriped?: boolean;\n /** Makes the table more compact by cutting cell padding in half. */\n isNarrow?: boolean;\n /** Adds a hover effect on rows. */\n isHoverable?: boolean;\n /** Makes the table span the full width of its wrapper. */\n isFullwidth?: boolean;\n /**\n * Scrolls a table wider than its wrapper sideways, in a `ScrollArea`\n * named after the table, which can be scrolled from the keyboard while it\n * overflows.\n */\n isResponsive?: boolean;\n /** Shows a search field in the toolbar, labelled by `labels.search`. */\n hasSearch?: boolean;\n /**\n * More of the toolbar, after the search field: buttons for the selected\n * rows, a filter, a download. Given the table.\n */\n toolbar?: (table: DataTableModel<TRow>) => React.ReactNode;\n /**\n * Shows a page of skeleton rows under the header in place of the rows,\n * and marks the table busy. For data on its way, as from a server with\n * `manual`.\n */\n loading?: boolean;\n /**\n * What the table shows when it has no rows at all, in one cell across\n * every column. A small `EmptyState` saying `labels.empty` by default. A\n * title of your own sits under the heading the table does, so give it the\n * next level down with `titleAs`.\n */\n empty?: React.ReactNode;\n /**\n * What the table shows when the search and filters let no row through, in\n * one cell across every column. A small `EmptyState` saying\n * `labels.noResults` by default. A button that clears the search goes\n * away with it, so send focus back to the search field when it's pressed.\n */\n noResults?: React.ReactNode;\n /**\n * Props of your own for a row's `Tr`, such as a handler or a class. The\n * table's own (`isSelected`) win. To wrap a row in a `ContextMenu`, build\n * the table from `useDataTable`'s props instead.\n */\n rowProps?: (row: TRow) => DataTableRowProps;\n /** Additional CSS classes, on the wrapper `<div>`. */\n className?: string;\n}\n\n/** What `rowProps` gives a row's `Tr`: any of its props but the ones the table sets. */\nexport type DataTableRowProps = Omit<TrProps, 'isSelected' | 'children'>;\n\n/** The type of `DataTable`, generic in the row. */\nexport type DataTableComponent = (<TRow>(\n props: DataTableProps<TRow> & React.RefAttributes<HTMLDivElement>\n) => React.ReactElement | null) & { displayName?: string };\n\n/** How long the status region waits after a change before it speaks, in ms. */\nconst statusDelay = 500;\n\nconst noColumns: never[] = [];\nconst noRows: never[] = [];\n\n/** A text signature of the search and the filters, to tell when they change. */\nfunction filterSignature(search: string, filters: DataTableFilters): string {\n try {\n return JSON.stringify([search, Object.entries(filters).sort()]);\n } catch {\n return search;\n }\n}\n\n/** Whether a node renders something. */\nconst isShown = (node: React.ReactNode) =>\n node !== undefined && node !== null && node !== false && node !== '';\n\n/**\n * The `DataTable` component is a table of records that people can sort,\n * search, page through and select rows from, rendered with bestax's own\n * `Table` parts, `Checkbox` and `Pagination`.\n *\n * It's a native table, as in the WAI-ARIA Authoring Practices' sortable\n * table: a sortable header holds a button, the sorted one carries\n * `aria-sort`, and each row's checkbox is named for the row. It runs on\n * `useDataTable`, which custom markup can use too.\n *\n * @example\n * <DataTable\n * caption=\"Users\"\n * columns={[\n * { id: 'name', header: 'Name', sortable: true, isRowHeader: true },\n * { id: 'role', header: 'Role', sortable: true },\n * ]}\n * data={users}\n * selectionMode=\"multiple\"\n * pageSize={10}\n * hasSearch\n * />\n */\nexport const DataTable = forwardRef(function DataTableRender<TRow>(\n {\n columns,\n data,\n table: given,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n caption,\n isBordered,\n isStriped,\n isNarrow,\n isHoverable,\n isFullwidth,\n isResponsive,\n hasSearch,\n toolbar,\n loading,\n empty,\n noResults,\n rowProps,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n }: DataTableProps<TRow>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const own = useDataTable<TRow>({\n columns: columns ?? noColumns,\n data: data ?? noRows,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n });\n const table = given ?? own;\n const { state } = table;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootClass = classNames(\n usePrefixedClassNames('data-table'),\n bulmaHelperClasses,\n className\n );\n const toolbarClass = usePrefixedClassNames('data-table-toolbar');\n const actionsClass = usePrefixedClassNames('data-table-actions');\n const emptyClass = usePrefixedClassNames('data-table-empty');\n\n const nameId = useId();\n const hasCaption = isShown(caption);\n const named = hasCaption || Boolean(ariaLabel || ariaLabelledby);\n useEffect(() => {\n if (!named) {\n warnOnce(\n 'DataTable:unnamed',\n '[bestax-bulma] <DataTable> has no accessible name. Pass a caption, ' +\n 'aria-label or aria-labelledby, so a screen reader can say which ' +\n 'table it is in.'\n );\n }\n }, [named]);\n const mixed = Boolean(given) && Boolean(columns || data);\n const bare = !given && (!columns || !data);\n useEffect(() => {\n if (mixed) {\n warnOnce(\n 'DataTable:table-and-columns',\n '[bestax-bulma] <DataTable> was given a `table` and `columns` or ' +\n '`data` too. It renders the `table` and leaves the rest unread, so ' +\n 'pass those to useDataTable instead.'\n );\n }\n if (bare) {\n warnOnce(\n 'DataTable:no-data',\n '[bestax-bulma] <DataTable> needs `columns` and `data`, or a `table` ' +\n 'from useDataTable.'\n );\n }\n }, [mixed, bare]);\n\n // The status region speaks only after the search, a filter or the page\n // changes, so nothing is read out as the page loads. `kind` is what last\n // changed, kept beside the values it changed from.\n const signature = filterSignature(state.search, state.filters);\n const [last, setLast] = useState({\n signature,\n page: state.page,\n kind: null as 'results' | 'page' | null,\n });\n if (last.signature !== signature) {\n setLast({ signature, page: state.page, kind: 'results' });\n } else if (last.page !== state.page) {\n setLast({ signature, page: state.page, kind: 'page' });\n }\n const { labels: words, rowCount: total, pageCount } = table;\n const size = state.pageSize;\n let message = '';\n if (last.kind && loading) {\n message = words.loading;\n } else if (last.kind === 'results' || (last.kind === 'page' && !total)) {\n message = words.results(total);\n } else if (last.kind === 'page') {\n // Without a page size, as when it's just been taken away, there's one\n // page, holding every row.\n const per = size ?? total;\n message = words.pageRange(\n (state.page - 1) * per + 1,\n Math.min(state.page * per, total),\n total\n );\n }\n // Written a moment after it changes, so typing in the search is read out\n // once it pauses rather than at every keystroke.\n const [said, setSaid] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setSaid(message), statusDelay);\n return () => clearTimeout(timer);\n }, [message]);\n\n const selectable = table.selectionMode === 'multiple';\n const sortable = table.columns.some(column => column.sortable);\n const columnCount = table.columns.length + (selectable ? 1 : 0);\n const pageRows = table.getRows('page');\n const selectAll = table.getSelectAllProps();\n\n const captionNode = hasCaption ? (\n <caption>\n <span id={nameId}>{caption}</span>\n {sortable && <span style={visuallyHidden}>{`, ${words.sortHint}.`}</span>}\n </caption>\n ) : sortable ? (\n <caption>\n <span style={visuallyHidden}>{words.sortHint}</span>\n </caption>\n ) : null;\n\n const header = (\n <Thead>\n <Tr>\n {selectable && (\n <Th scope=\"col\" isNarrow>\n <Checkbox\n {...selectAll}\n // While loading, the rows it would select aren't on screen.\n disabled={selectAll.disabled || Boolean(loading)}\n />\n </Th>\n )}\n {table.columns.map(column => (\n <Th key={column.id} {...table.getHeaderCellProps(column)}>\n {column.sortable ? (\n <button {...table.getSortButtonProps(column)}>\n {column.header}\n </button>\n ) : (\n column.header\n )}\n </Th>\n ))}\n </Tr>\n </Thead>\n );\n\n let body: React.ReactNode;\n if (loading) {\n body = Array.from({ length: size ?? 5 }, (_, index) => (\n <Tr key={index} aria-hidden=\"true\">\n {Array.from({ length: columnCount }, (__, cell) => (\n <Td key={cell}>\n <Skeleton variant=\"lines\" lines={1} />\n </Td>\n ))}\n </Tr>\n ));\n } else if (pageRows.length === 0) {\n // With `manual`, no rows under a search or a filter is no match: only\n // the server knows whether there's anything else.\n const nothing =\n table.getRows('all').length === 0 &&\n !(table.manual && isFiltering(state.search, state.filters));\n const content = nothing\n ? isShown(empty)\n ? empty\n : empty === undefined && (\n <EmptyState size=\"small\" description={words.empty} />\n )\n : isShown(noResults)\n ? noResults\n : noResults === undefined && (\n <EmptyState size=\"small\" description={words.noResults} />\n );\n body = (\n <Tr>\n <Td colSpan={columnCount} className={emptyClass}>\n {content}\n </Td>\n </Tr>\n );\n } else {\n body = pageRows.map(row => {\n const rowId = table.getRowId(row);\n return (\n <Tr key={rowId} {...rowProps?.(row)} {...table.getRowProps(row)}>\n {selectable && (\n <Td isNarrow>\n <Checkbox {...table.getSelectRowProps(row)} />\n </Td>\n )}\n {table.columns.map(column => {\n const text = table.getText(row, column.id);\n const content = column.cell\n ? column.cell(row, {\n value: table.getValue(row, column.id),\n text,\n rowId,\n })\n : text;\n const cellProps = table.getCellProps(row, column);\n return column.isRowHeader ? (\n <Th key={column.id} {...cellProps}>\n {content}\n </Th>\n ) : (\n <Td key={column.id} {...cellProps}>\n {content}\n </Td>\n );\n })}\n </Tr>\n );\n });\n }\n\n const tableElement = (\n <Table\n isBordered={isBordered}\n isStriped={isStriped}\n isNarrow={isNarrow}\n isHoverable={isHoverable}\n isFullwidth={isFullwidth}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-busy={loading || undefined}\n >\n {captionNode}\n {header}\n <Tbody>{body}</Tbody>\n </Table>\n );\n\n // The name the scroll area and the pager take from the table.\n const textName =\n ariaLabel || (typeof caption === 'string' ? caption : undefined);\n const scrollName = ariaLabel\n ? { 'aria-label': ariaLabel }\n : {\n 'aria-labelledby': ariaLabelledby || (hasCaption ? nameId : undefined),\n };\n\n // Pagination names itself \"pagination\" unless given another name.\n const pagerLabel =\n words.pagination || (textName ? `${textName} pages` : undefined);\n const pagerName = pagerLabel ? { 'aria-label': pagerLabel } : {};\n\n const toolbarContent = toolbar?.(table);\n const hasToolbar = hasSearch || isShown(toolbarContent);\n\n return (\n <div ref={ref} className={rootClass} {...rest}>\n {hasToolbar && (\n <div className={toolbarClass}>\n {hasSearch && (\n <Input label={words.search} {...table.getSearchProps()} />\n )}\n {isShown(toolbarContent) && (\n <div className={actionsClass}>{toolbarContent}</div>\n )}\n </div>\n )}\n {isResponsive ? (\n <ScrollArea orientation=\"horizontal\" {...scrollName}>\n {tableElement}\n </ScrollArea>\n ) : (\n tableElement\n )}\n {/* In the page from the start, so a change to it is announced. */}\n <div role=\"status\" aria-live=\"polite\" style={visuallyHidden}>\n {said}\n </div>\n {pageCount > 1 && (\n <Pagination {...table.getPaginationProps()} {...pagerName} />\n )}\n </div>\n );\n}) as DataTableComponent;\n\nDataTable.displayName = 'DataTable';\n\nexport default DataTable;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useId, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { visuallyHidden } from '../helpers/statusRegion';\nimport { Table } from '../elements/Table';\nimport { Thead } from '../elements/Thead';\nimport { Tbody } from '../elements/Tbody';\nimport { Tr, TrProps } from '../elements/Tr';\nimport { Th } from '../elements/Th';\nimport { Td } from '../elements/Td';\nimport { Skeleton } from '../elements/Skeleton';\nimport { Checkbox } from '../form/Checkbox';\nimport { Input } from '../form/Input';\nimport { EmptyState } from './EmptyState';\nimport { Pagination } from './Pagination';\nimport { ScrollArea } from './ScrollArea';\nimport {\n isFiltering,\n useDataTable,\n type DataTableColumn,\n type DataTableFilters,\n type DataTableModel,\n type DataTableStateOptions,\n} from './useDataTable';\n\nexport { useDataTable } from './useDataTable';\nexport type {\n DataTableCSVOptions,\n DataTableCellContext,\n DataTableCellProps,\n DataTableCheckboxProps,\n DataTableColumn,\n DataTableColumnMeta,\n DataTableFilters,\n DataTableHeaderCellProps,\n DataTableLabels,\n DataTableModel,\n DataTablePaginationProps,\n DataTableResolvedLabels,\n DataTableRowScope,\n DataTableSearchProps,\n DataTableSelectionMode,\n DataTableSort,\n DataTableSortButtonProps,\n DataTableSortDirection,\n DataTableState,\n DataTableStateOptions,\n UseDataTableOptions,\n} from './useDataTable';\n\n/**\n * Props for the DataTable component. The helper props, `className`, the\n * `ref` and the other attributes go on the wrapper `<div>`, which holds the\n * toolbar, the table and the pager. `aria-label` and `aria-labelledby` name\n * the `<table>` itself.\n *\n * @extraProp {string} [aria-label] - Names the table, in place of a `caption`. A table needs a name, so pass a `caption`, this or `aria-labelledby`, and a development build warns when it has none.\n * @extraProp {string} [aria-labelledby] - The id of a visible heading that names the table, in place of a `caption`.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the wrapper `<div>`.\n */\nexport interface DataTableProps<TRow>\n extends\n DataTableStateOptions<TRow>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The columns, in the order they're shown. Required unless `table` is\n * given. Keep the array the same from one render to the next, defined\n * outside the component or in `useMemo`: a new one has every cell's text\n * worked out again.\n */\n columns?: DataTableColumn<TRow>[];\n /** The rows, as records of your own. Required unless `table` is given. */\n data?: TRow[];\n /**\n * A table made by `useDataTable`, rendered in place of one made from\n * `columns`, `data` and the state props, which are then left unread. Use\n * it to put a toolbar, a count or an export button elsewhere on the page.\n */\n table?: DataTableModel<TRow>;\n /**\n * Names the table, as a visible `<caption>`. A table needs a name: this,\n * `aria-label` or `aria-labelledby`.\n */\n caption?: React.ReactNode;\n /** Adds borders to all cells. */\n isBordered?: boolean;\n /** Adds zebra-striping to rows. */\n isStriped?: boolean;\n /** Makes the table more compact by cutting cell padding in half. */\n isNarrow?: boolean;\n /** Adds a hover effect on rows. */\n isHoverable?: boolean;\n /** Makes the table span the full width of its wrapper. */\n isFullwidth?: boolean;\n /**\n * Scrolls a table wider than its wrapper sideways, in a `ScrollArea`\n * named after the table, which can be scrolled from the keyboard while it\n * overflows.\n */\n isResponsive?: boolean;\n /** Shows a search field in the toolbar, labelled by `labels.search`. */\n hasSearch?: boolean;\n /**\n * More of the toolbar, after the search field: buttons for the selected\n * rows, a filter, a download. Given the table.\n */\n toolbar?: (table: DataTableModel<TRow>) => React.ReactNode;\n /**\n * Shows a page of skeleton rows under the header in place of the rows,\n * and marks the table busy. For data on its way, as from a server with\n * `manual`.\n */\n loading?: boolean;\n /**\n * What the table shows when it has no rows at all, in one cell across\n * every column. A small `EmptyState` saying `labels.empty` by default. A\n * title of your own sits under the heading the table does, so give it the\n * next level down with `titleAs`.\n */\n empty?: React.ReactNode;\n /**\n * What the table shows when the search and filters let no row through, in\n * one cell across every column. A small `EmptyState` saying\n * `labels.noResults` by default. A button that clears the search goes\n * away with it, so send focus back to the search field when it's pressed.\n */\n noResults?: React.ReactNode;\n /**\n * Props of your own for a row's `Tr`, such as a handler or a class. The\n * table's own (`isSelected`) win. To wrap a row in a `ContextMenu`, build\n * the table from `useDataTable`'s props instead.\n */\n rowProps?: (row: TRow) => DataTableRowProps;\n /** Additional CSS classes, on the wrapper `<div>`. */\n className?: string;\n}\n\n/** What `rowProps` gives a row's `Tr`: any of its props but the ones the table sets. */\nexport type DataTableRowProps = Omit<TrProps, 'isSelected' | 'children'>;\n\n/** The type of `DataTable`, generic in the row. */\nexport type DataTableComponent = (<TRow>(\n props: DataTableProps<TRow> & React.RefAttributes<HTMLDivElement>\n) => React.ReactElement | null) & { displayName?: string };\n\n/** How long the status region waits after a change before it speaks, in ms. */\nconst statusDelay = 500;\n\nconst noColumns: never[] = [];\nconst noRows: never[] = [];\n\n/** A text signature of the search and the filters, to tell when they change. */\nfunction filterSignature(search: string, filters: DataTableFilters): string {\n try {\n return JSON.stringify([search, Object.entries(filters).sort()]);\n } catch {\n return search;\n }\n}\n\n/** Whether a node renders something. */\nconst isShown = (node: React.ReactNode) =>\n node !== undefined && node !== null && node !== false && node !== '';\n\n/**\n * The `DataTable` component is a table of records that people can sort,\n * search, page through and select rows from, rendered with bestax's own\n * `Table` parts, `Checkbox` and `Pagination`.\n *\n * It's a native table, as in the WAI-ARIA Authoring Practices' sortable\n * table: a sortable header holds a button, the sorted one carries\n * `aria-sort`, and each row's checkbox is named for the row. It runs on\n * `useDataTable`, which custom markup can use too.\n *\n * @example\n * <DataTable\n * caption=\"Users\"\n * columns={[\n * { id: 'name', header: 'Name', sortable: true, isRowHeader: true },\n * { id: 'role', header: 'Role', sortable: true },\n * ]}\n * data={users}\n * selectionMode=\"multiple\"\n * pageSize={10}\n * hasSearch\n * />\n */\nexport const DataTable = forwardRef(function DataTableRender<TRow>(\n {\n columns,\n data,\n table: given,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n caption,\n isBordered,\n isStriped,\n isNarrow,\n isHoverable,\n isFullwidth,\n isResponsive,\n hasSearch,\n toolbar,\n loading,\n empty,\n noResults,\n rowProps,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n }: DataTableProps<TRow>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const own = useDataTable<TRow>({\n columns: columns ?? noColumns,\n data: data ?? noRows,\n getRowId,\n sort,\n defaultSort,\n onSortChange,\n selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n pageSize,\n page,\n defaultPage,\n onPageChange,\n search,\n defaultSearch,\n onSearchChange,\n filters,\n defaultFilters,\n onFiltersChange,\n manual,\n rowCount,\n labels,\n });\n const table = given ?? own;\n const { state } = table;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootClass = classNames(\n usePrefixedClassNames('data-table'),\n bulmaHelperClasses,\n className\n );\n const toolbarClass = usePrefixedClassNames('data-table-toolbar');\n const actionsClass = usePrefixedClassNames('data-table-actions');\n const emptyClass = usePrefixedClassNames('data-table-empty');\n\n const nameId = useId();\n const hasCaption = isShown(caption);\n const named = hasCaption || Boolean(ariaLabel || ariaLabelledby);\n useEffect(() => {\n if (!named) {\n warnOnce(\n 'DataTable:unnamed',\n '[bestax-bulma] <DataTable> has no accessible name. Pass a caption, ' +\n 'aria-label or aria-labelledby, so a screen reader can say which ' +\n 'table it is in.'\n );\n }\n }, [named]);\n const mixed = Boolean(given) && Boolean(columns || data);\n const bare = !given && (!columns || !data);\n useEffect(() => {\n if (mixed) {\n warnOnce(\n 'DataTable:table-and-columns',\n '[bestax-bulma] <DataTable> was given a `table` and `columns` or ' +\n '`data` too. It renders the `table` and leaves the rest unread, so ' +\n 'pass those to useDataTable instead.'\n );\n }\n if (bare) {\n warnOnce(\n 'DataTable:no-data',\n '[bestax-bulma] <DataTable> needs `columns` and `data`, or a `table` ' +\n 'from useDataTable.'\n );\n }\n }, [mixed, bare]);\n\n // The status region speaks only after the search, a filter or the page\n // changes, so nothing is read out as the page loads. `kind` is what last\n // changed, kept beside the values it changed from.\n const signature = filterSignature(state.search, state.filters);\n const [last, setLast] = useState({\n signature,\n page: state.page,\n kind: null as 'results' | 'page' | null,\n });\n if (last.signature !== signature) {\n setLast({ signature, page: state.page, kind: 'results' });\n } else if (last.page !== state.page) {\n setLast({ signature, page: state.page, kind: 'page' });\n }\n const { labels: words, rowCount: total, pageCount } = table;\n const size = state.pageSize;\n let message = '';\n if (last.kind && loading) {\n message = words.loading;\n } else if (last.kind === 'results' || (last.kind === 'page' && !total)) {\n message = words.results(total);\n } else if (last.kind === 'page') {\n // Without a page size, as when it's just been taken away, there's one\n // page, holding every row.\n const per = size ?? total;\n message = words.pageRange(\n (state.page - 1) * per + 1,\n Math.min(state.page * per, total),\n total\n );\n }\n // Written a moment after it changes, so typing in the search is read out\n // once it pauses rather than at every keystroke.\n const [said, setSaid] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setSaid(message), statusDelay);\n return () => clearTimeout(timer);\n }, [message]);\n\n const selectable = table.selectionMode === 'multiple';\n const sortable = table.columns.some(column => column.sortable);\n const columnCount = table.columns.length + (selectable ? 1 : 0);\n const pageRows = table.getRows('page');\n const selectAll = table.getSelectAllProps();\n\n const captionNode = hasCaption ? (\n <caption>\n <span id={nameId}>{caption}</span>\n {sortable && <span style={visuallyHidden}>{`, ${words.sortHint}.`}</span>}\n </caption>\n ) : sortable ? (\n <caption>\n <span style={visuallyHidden}>{words.sortHint}</span>\n </caption>\n ) : null;\n\n const header = (\n <Thead>\n <Tr>\n {selectable && (\n <Th scope=\"col\" isNarrow>\n <Checkbox\n {...selectAll}\n // While loading, the rows it would select aren't on screen.\n disabled={selectAll.disabled || Boolean(loading)}\n />\n </Th>\n )}\n {table.columns.map(column => (\n <Th key={column.id} {...table.getHeaderCellProps(column)}>\n {column.sortable ? (\n <button {...table.getSortButtonProps(column)}>\n {column.header}\n </button>\n ) : (\n column.header\n )}\n </Th>\n ))}\n </Tr>\n </Thead>\n );\n\n let body: React.ReactNode;\n if (loading) {\n body = Array.from({ length: size ?? 5 }, (_, index) => (\n <Tr key={index} aria-hidden=\"true\">\n {Array.from({ length: columnCount }, (__, cell) => (\n <Td key={cell}>\n <Skeleton variant=\"lines\" lines={1} />\n </Td>\n ))}\n </Tr>\n ));\n } else if (pageRows.length === 0) {\n // With `manual`, no rows under a search or a filter is no match: only\n // the server knows whether there's anything else.\n const nothing =\n table.getRows('all').length === 0 &&\n !(table.manual && isFiltering(state.search, state.filters));\n const content = nothing\n ? isShown(empty)\n ? empty\n : empty === undefined && (\n <EmptyState size=\"small\" description={words.empty} />\n )\n : isShown(noResults)\n ? noResults\n : noResults === undefined && (\n <EmptyState size=\"small\" description={words.noResults} />\n );\n body = (\n <Tr>\n <Td colSpan={columnCount} className={emptyClass}>\n {content}\n </Td>\n </Tr>\n );\n } else {\n body = pageRows.map(row => {\n const rowId = table.getRowId(row);\n return (\n <Tr key={rowId} {...rowProps?.(row)} {...table.getRowProps(row)}>\n {selectable && (\n <Td isNarrow>\n <Checkbox {...table.getSelectRowProps(row)} />\n </Td>\n )}\n {table.columns.map(column => {\n const text = table.getText(row, column.id);\n const content = column.cell\n ? column.cell(row, {\n value: table.getValue(row, column.id),\n text,\n rowId,\n })\n : text;\n const cellProps = table.getCellProps(row, column);\n return column.isRowHeader ? (\n <Th key={column.id} {...cellProps}>\n {content}\n </Th>\n ) : (\n <Td key={column.id} {...cellProps}>\n {content}\n </Td>\n );\n })}\n </Tr>\n );\n });\n }\n\n const tableElement = (\n <Table\n isBordered={isBordered}\n isStriped={isStriped}\n isNarrow={isNarrow}\n isHoverable={isHoverable}\n isFullwidth={isFullwidth}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-busy={loading || undefined}\n >\n {captionNode}\n {header}\n <Tbody>{body}</Tbody>\n </Table>\n );\n\n // The name the scroll area and the pager take from the table.\n const textName =\n ariaLabel || (typeof caption === 'string' ? caption : undefined);\n const scrollName = ariaLabel\n ? { 'aria-label': ariaLabel }\n : {\n 'aria-labelledby': ariaLabelledby || (hasCaption ? nameId : undefined),\n };\n\n // Pagination names itself \"pagination\" unless given another name.\n const pagerLabel =\n words.pagination || (textName ? `${textName} pages` : undefined);\n const pagerName = pagerLabel ? { 'aria-label': pagerLabel } : {};\n\n const toolbarContent = toolbar?.(table);\n const hasToolbar = hasSearch || isShown(toolbarContent);\n\n return (\n <div ref={ref} className={rootClass} {...rest}>\n {hasToolbar && (\n <div className={toolbarClass}>\n {hasSearch && (\n <Input label={words.search} {...table.getSearchProps()} />\n )}\n {isShown(toolbarContent) && (\n <div className={actionsClass}>{toolbarContent}</div>\n )}\n </div>\n )}\n {isResponsive ? (\n <ScrollArea orientation=\"horizontal\" {...scrollName}>\n {tableElement}\n </ScrollArea>\n ) : (\n tableElement\n )}\n {/* In the page from the start, so a change to it is announced. */}\n <div role=\"status\" aria-live=\"polite\" style={visuallyHidden}>\n {said}\n </div>\n {pageCount > 1 && (\n <Pagination {...table.getPaginationProps()} {...pagerName} />\n )}\n </div>\n );\n}) as DataTableComponent;\n\nDataTable.displayName = 'DataTable';\n\nexport default DataTable;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmJA;AACA,MAAM,WAAW,GAAG,GAAG;AAEvB,MAAM,SAAS,GAAY,EAAE;AAC7B,MAAM,MAAM,GAAY,EAAE;AAE1B;AACA,SAAS,eAAe,CAAC,MAAc,EAAE,OAAyB,EAAA;AAChE,IAAA,IAAI;AACF,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,MAAM;IACf;AACF;AAEA;AACA,MAAM,OAAO,GAAG,CAAC,IAAqB,KACpC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,EAAE;AAEtE;;;;;;;;;;;;;;;;;;;;;;AAsBG;MACU,SAAS,GAAG,UAAU,CAAC,SAAS,eAAe,CAC1D,EACE,OAAO,EACP,IAAI,EACJ,KAAK,EAAE,KAAK,EACZ,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,MAAM,EACN,aAAa,EACb,cAAc,EACd,OAAO,EACP,cAAc,EACd,eAAe,EACf,MAAM,EACN,QAAQ,EACR,MAAM,EACN,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,EACR,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,OAAO,EACP,OAAO,EACP,KAAK,EACL,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,KAAK,EACa,EACvB,GAAuC,EAAA;IAEvC,MAAM,GAAG,GAAG,YAAY,CAAO;QAC7B,OAAO,EAAE,OAAO,IAAI,SAAS;QAC7B,IAAI,EAAE,IAAI,IAAI,MAAM;QACpB,QAAQ;QACR,IAAI;QACJ,WAAW;QACX,YAAY;QACZ,aAAa;QACb,QAAQ;QACR,eAAe;QACf,gBAAgB;QAChB,QAAQ;QACR,IAAI;QACJ,WAAW;QACX,YAAY;QACZ,MAAM;QACN,aAAa;QACb,cAAc;QACd,OAAO;QACP,cAAc;QACd,eAAe;QACf,MAAM;QACN,QAAQ;QACR,MAAM;AACP,KAAA,CAAC;AACF,IAAA,MAAM,KAAK,GAAG,KAAK,IAAI,GAAG;AAC1B,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK;IAEvB,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC;AAC3D,IAAA,MAAM,SAAS,GAAG,UAAU,CAC1B,qBAAqB,CAAC,YAAY,CAAC,EACnC,kBAAkB,EAClB,SAAS,CACV;AACD,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,oBAAoB,CAAC;AAChE,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,oBAAoB,CAAC;AAChE,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,kBAAkB,CAAC;AAE5D,IAAA,MAAM,MAAM,GAAG,KAAK,EAAE;AACtB,IAAA,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,IAAI,OAAO,CAAC,SAAS,IAAI,cAAc,CAAC;IAChE,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,KAAK,EAAE;YACV,QAAQ,CACN,mBAAmB,EACnB,qEAAqE;gBACnE,kEAAkE;AAClE,gBAAA,iBAAiB,CACpB;QACH;AACF,IAAA,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACX,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;AACxD,IAAA,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC;IAC1C,SAAS,CAAC,MAAK;QACb,IAAI,KAAK,EAAE;YACT,QAAQ,CACN,6BAA6B,EAC7B,kEAAkE;gBAChE,oEAAoE;AACpE,gBAAA,qCAAqC,CACxC;QACH;QACA,IAAI,IAAI,EAAE;YACR,QAAQ,CACN,mBAAmB,EACnB,sEAAsE;AACpE,gBAAA,oBAAoB,CACvB;QACH;AACF,IAAA,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;;;;AAKjB,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;AAC9D,IAAA,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;QAC/B,SAAS;QACT,IAAI,EAAE,KAAK,CAAC,IAAI;AAChB,QAAA,IAAI,EAAE,IAAiC;AACxC,KAAA,CAAC;AACF,IAAA,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE;AAChC,QAAA,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC3D;SAAO,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE;AACnC,QAAA,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACxD;AACA,IAAA,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK;AAC3D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ;IAC3B,IAAI,OAAO,GAAG,EAAE;AAChB,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,EAAE;AACxB,QAAA,OAAO,GAAG,KAAK,CAAC,OAAO;IACzB;AAAO,SAAA,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE;AACtE,QAAA,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IAChC;AAAO,SAAA,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE;;;AAG/B,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,KAAK;AACzB,QAAA,OAAO,GAAG,KAAK,CAAC,SAAS,CACvB,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,EAAE,KAAK,CAAC,EACjC,KAAK,CACN;IACH;;;IAGA,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;IACpC,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;AAC7D,QAAA,OAAO,MAAM,YAAY,CAAC,KAAK,CAAC;AAClC,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAEb,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,KAAK,UAAU;AACrD,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC;AAC9D,IAAA,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AACtC,IAAA,MAAM,SAAS,GAAG,KAAK,CAAC,iBAAiB,EAAE;IAE3C,MAAM,WAAW,GAAG,UAAU,IAC5BA,IAAA,CAAA,SAAA,EAAA,EAAA,QAAA,EAAA,CACEC,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAE,MAAM,YAAG,OAAO,EAAA,CAAQ,EACjC,QAAQ,IAAIA,GAAA,CAAA,MAAA,EAAA,EAAM,KAAK,EAAE,cAAc,EAAA,QAAA,EAAG,CAAA,EAAA,EAAK,KAAK,CAAC,QAAQ,GAAG,EAAA,CAAQ,CAAA,EAAA,CACjE,IACR,QAAQ,IACVA,GAAA,CAAA,SAAA,EAAA,EAAA,QAAA,EACEA,GAAA,CAAA,MAAA,EAAA,EAAM,KAAK,EAAE,cAAc,EAAA,QAAA,EAAG,KAAK,CAAC,QAAQ,EAAA,CAAQ,EAAA,CAC5C,IACR,IAAI;IAER,MAAM,MAAM,IACVA,GAAA,CAAC,KAAK,cACJD,IAAA,CAAC,EAAE,EAAA,EAAA,QAAA,EAAA,CACA,UAAU,KACTC,IAAC,EAAE,EAAA,EAAC,KAAK,EAAC,KAAK,EAAC,QAAQ,EAAA,IAAA,EAAA,QAAA,EACtBA,GAAA,CAAC,QAAQ,EAAA,EAAA,GACH,SAAS;;AAEb,wBAAA,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,GAChD,EAAA,CACC,CACN,EACA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,KACvBA,GAAA,CAAC,EAAE,EAAA,EAAA,GAAqB,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,YACrD,MAAM,CAAC,QAAQ,IACdA,GAAA,CAAA,QAAA,EAAA,EAAA,GAAY,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAA,QAAA,EACzC,MAAM,CAAC,MAAM,GACP,KAET,MAAM,CAAC,MAAM,CACd,EAAA,EAPM,MAAM,CAAC,EAAE,CAQb,CACN,CAAC,CAAA,EAAA,CACC,EAAA,CACC,CACT;AAED,IAAA,IAAI,IAAqB;IACzB,IAAI,OAAO,EAAE;AACX,QAAA,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,MAChDA,GAAA,CAAC,EAAE,EAAA,EAAA,aAAA,EAAyB,MAAM,EAAA,QAAA,EAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,MAC5CA,GAAA,CAAC,EAAE,EAAA,EAAA,QAAA,EACDA,GAAA,CAAC,QAAQ,IAAC,OAAO,EAAC,OAAO,EAAC,KAAK,EAAE,CAAC,EAAA,CAAI,IAD/B,IAAI,CAER,CACN,CAAC,EAAA,EALK,KAAK,CAMT,CACN,CAAC;IACJ;AAAO,SAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;;;QAGhC,MAAM,OAAO,GACX,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;AACjC,YAAA,EAAE,KAAK,CAAC,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG;AACd,cAAE,OAAO,CAAC,KAAK;AACb,kBAAE;AACF,kBAAE,KAAK,KAAK,SAAS,KACjBA,IAAC,UAAU,EAAA,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAE,KAAK,CAAC,KAAK,GAAI;AAE3D,cAAE,OAAO,CAAC,SAAS;AACjB,kBAAE;kBACA,SAAS,KAAK,SAAS,KACrBA,GAAA,CAAC,UAAU,EAAA,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAA,CAAI,CAC1D;QACP,IAAI,IACFA,GAAA,CAAC,EAAE,cACDA,GAAA,CAAC,EAAE,IAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAA,QAAA,EAC5C,OAAO,EAAA,CACL,EAAA,CACF,CACN;IACH;SAAO;AACL,QAAA,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAG;YACxB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;YACjC,QACED,KAAC,EAAE,EAAA,EAAA,GAAiB,QAAQ,GAAG,GAAG,CAAC,EAAA,GAAM,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,aAC5D,UAAU,KACTC,GAAA,CAAC,EAAE,EAAA,EAAC,QAAQ,EAAA,IAAA,EAAA,QAAA,EACVA,GAAA,CAAC,QAAQ,EAAA,EAAA,GAAK,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAA,CAAI,GAC3C,CACN,EACA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAG;AAC1B,wBAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;AAC1C,wBAAA,MAAM,OAAO,GAAG,MAAM,CAAC;AACrB,8BAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;gCACf,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;gCACrC,IAAI;gCACJ,KAAK;6BACN;8BACD,IAAI;wBACR,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC;AACjD,wBAAA,OAAO,MAAM,CAAC,WAAW,IACvBA,GAAA,CAAC,EAAE,OAAqB,SAAS,EAAA,QAAA,EAC9B,OAAO,EAAA,EADD,MAAM,CAAC,EAAE,CAEb,KAELA,GAAA,CAAC,EAAE,EAAA,EAAA,GAAqB,SAAS,EAAA,QAAA,EAC9B,OAAO,IADD,MAAM,CAAC,EAAE,CAEb,CACN;AACH,oBAAA,CAAC,CAAC,CAAA,EAAA,EAzBK,KAAK,CA0BT;AAET,QAAA,CAAC,CAAC;IACJ;IAEA,MAAM,YAAY,IAChBD,IAAA,CAAC,KAAK,EAAA,EACJ,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,WAAW,gBACZ,SAAS,EAAA,iBAAA,EACJ,cAAc,EAAA,WAAA,EACpB,OAAO,IAAI,SAAS,EAAA,QAAA,EAAA,CAE9B,WAAW,EACX,MAAM,EACPC,GAAA,CAAC,KAAK,cAAE,IAAI,EAAA,CAAS,CAAA,EAAA,CACf,CACT;;AAGD,IAAA,MAAM,QAAQ,GACZ,SAAS,KAAK,OAAO,OAAO,KAAK,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAClE,MAAM,UAAU,GAAG;AACjB,UAAE,EAAE,YAAY,EAAE,SAAS;AAC3B,UAAE;AACE,YAAA,iBAAiB,EAAE,cAAc,KAAK,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;SACvE;;AAGL,IAAA,MAAM,UAAU,GACd,KAAK,CAAC,UAAU,KAAK,QAAQ,GAAG,CAAA,EAAG,QAAQ,CAAA,MAAA,CAAQ,GAAG,SAAS,CAAC;AAClE,IAAA,MAAM,SAAS,GAAG,UAAU,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE;AAEhE,IAAA,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,CAAC;IACvC,MAAM,UAAU,GAAG,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAEvD,QACED,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAAA,CAC1C,UAAU,KACTA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,YAAY,EAAA,QAAA,EAAA,CACzB,SAAS,KACRC,GAAA,CAAC,KAAK,EAAA,EAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAA,GAAM,KAAK,CAAC,cAAc,EAAE,EAAA,CAAI,CAC3D,EACA,OAAO,CAAC,cAAc,CAAC,KACtBA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,YAAY,EAAA,QAAA,EAAG,cAAc,EAAA,CAAO,CACrD,CAAA,EAAA,CACG,CACP,EACA,YAAY,IACXA,GAAA,CAAC,UAAU,IAAC,WAAW,EAAC,YAAY,EAAA,GAAK,UAAU,EAAA,QAAA,EAChD,YAAY,EAAA,CACF,KAEb,YAAY,CACb,EAEDA,GAAA,CAAA,KAAA,EAAA,EAAK,IAAI,EAAC,QAAQ,EAAA,WAAA,EAAW,QAAQ,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EACxD,IAAI,GACD,EACL,SAAS,GAAG,CAAC,KACZA,IAAC,UAAU,EAAA,EAAA,GAAK,KAAK,CAAC,kBAAkB,EAAE,EAAA,GAAM,SAAS,EAAA,CAAI,CAC9D,CAAA,EAAA,CACG;AAEV,CAAC;AAED,SAAS,CAAC,WAAW,GAAG,WAAW;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
4
|
import { forwardRef, useRef, useCallback, useEffect, useSyncExternalStore } from 'react';
|
|
4
5
|
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","sources":["../../../src/components/Dialog.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useConfig } from '../helpers/Config';\nimport { Modal } from './Modal';\n\n/** Valid dialog type/color values. */\nexport type DialogType = 'default' | 'success' | 'danger' | 'warning' | 'info';\n\n/**\n * Props for the Dialog component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the dialog element.\n */\nexport interface DialogProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color'> {\n /** Whether the dialog is open (required). */\n isOpen: boolean;\n /** Dialog title. */\n title?: string;\n /** Dialog message/content (required). */\n message: string | React.ReactNode;\n /** The type/color of the dialog. Default: 'default'. */\n type?: DialogType;\n /** Text for confirm button. Default: 'OK'. */\n confirmText?: string;\n /** Text for cancel button. Default: 'Cancel'. */\n cancelText?: string;\n /** Callback when confirm button is clicked. */\n onConfirm?: () => void;\n /** Callback when cancel button is clicked or dismissed. */\n onCancel?: () => void;\n /** Whether to show cancel button. Default: true for confirm dialogs. */\n showCancel?: boolean;\n /** Whether the dialog can be dismissed. Default: true. */\n canCancel?: boolean;\n /** Focus cancel button instead of confirm. Default: false. */\n focusCancel?: boolean;\n /** Custom icon to display. */\n icon?: React.ReactNode;\n /**\n * Renders the dialog into a portal target instead of inline. Forwarded to\n * the underlying `Modal`; see its `portal` prop for the accepted values.\n * @defaultValue false\n */\n portal?: boolean | string | HTMLElement;\n}\n\n/**\n * The `Dialog` component provides ready-made confirm and alert dialogs, so a destructive action stays one `await dialog.confirm()` call away.\n *\n * @function\n * @param {DialogProps} props - Props for the Dialog component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the dialog element.\n * @returns {JSX.Element | null} The rendered dialog component.\n *\n * @example\n * // Alert dialog\n * <Dialog\n * isOpen={showAlert}\n * title=\"Success\"\n * message=\"Operation completed successfully!\"\n * type=\"success\"\n * onConfirm={() => setShowAlert(false)}\n * showCancel={false}\n * />\n *\n * @example\n * // Confirm dialog\n * <Dialog\n * isOpen={showConfirm}\n * title=\"Delete Item?\"\n * message=\"This action cannot be undone.\"\n * type=\"danger\"\n * confirmText=\"Delete\"\n * onConfirm={handleDelete}\n * onCancel={() => setShowConfirm(false)}\n * />\n */\nexport const Dialog = forwardRef<HTMLDivElement, DialogProps>(\n (\n {\n isOpen,\n title,\n message,\n type = 'default',\n confirmText = 'OK',\n cancelText = 'Cancel',\n onConfirm,\n onCancel,\n showCancel = true,\n canCancel = true,\n focusCancel = false,\n icon,\n portal,\n className,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const dialogRef = useRef<HTMLDivElement>(null);\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n const cancelRef = useRef<HTMLButtonElement>(null);\n\n // Handle cancel\n const handleCancel = useCallback(() => {\n if (canCancel) {\n onCancel?.();\n }\n }, [canCancel, onCancel]);\n\n // Handle confirm\n const handleConfirm = useCallback(() => {\n onConfirm?.();\n }, [onConfirm]);\n\n // Handle background click\n const handleBackgroundClick = useCallback(() => {\n if (canCancel) {\n handleCancel();\n }\n }, [canCancel, handleCancel]);\n\n // Moving into the portal, or from one portal target to another, remounts\n // the Modal's subtree, these buttons included, so the focus effect below\n // has to re-run against the new nodes, exactly as the Modal's own focus\n // effect does, on the same inputs.\n const isHydrated = useIsHydrated();\n const isPortaled = Boolean(portal) && isHydrated;\n const { portalContainer } = useConfig();\n const defaultTarget =\n isPortaled && portal === true ? portalContainer : undefined;\n\n // Focus management — Dialog picks a specific button rather than the\n // Modal's default (first focusable/root); this effect runs after the\n // inner Modal's own focus-on-open effect, so it wins.\n useEffect(() => {\n if (isOpen) {\n const buttonToFocus =\n focusCancel && showCancel ? cancelRef.current : confirmRef.current;\n buttonToFocus?.focus();\n }\n }, [isOpen, focusCancel, showCancel, isPortaled, portal, defaultTarget]);\n\n // Use combined ref\n const combinedRef = useCallback(\n (node: HTMLDivElement | null) => {\n (dialogRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches by\n // running it instead of calling the ref with `null`; React 18 discards the\n // return value entirely. Returning it from here would be a React-19-only\n // contract, so we hold the cleanup and run it ourselves on detach — the\n // same shape as `Dropdown`, `Modal`, `Sidebar`, `Toast` and `Carousel`.\n // The form controls that merge a forwarded ref still discard the cleanup\n // and detach with `ref(null)`, so this is not yet library-wide — grep\n // `typeof ref === 'function'` for the current split.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const dialogClasses = usePrefixedClassNames('dialog', {\n [`is-${type}`]: type !== 'default',\n });\n const headerClass = usePrefixedClassNames('dialog-header');\n const iconClass = usePrefixedClassNames('dialog-icon');\n const titleClass = usePrefixedClassNames('dialog-title');\n const bodyClass = usePrefixedClassNames('dialog-body');\n const footerClass = usePrefixedClassNames('dialog-footer');\n const cancelButtonClass = usePrefixedClassNames('button');\n const confirmButtonClass = usePrefixedClassNames('button', {\n 'is-success': type === 'success',\n 'is-danger': type === 'danger',\n 'is-warning': type === 'warning',\n 'is-info': type === 'info',\n 'is-primary': type === 'default',\n });\n\n const combinedClasses = classNames(\n dialogClasses,\n bulmaHelperClasses,\n className\n );\n\n // Get default icon based on type\n const getDefaultIcon = () => {\n switch (type) {\n case 'success':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n );\n case 'danger':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n );\n case 'warning':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n >\n <path d=\"M12 2L1 21h22L12 2zm0 3.99L19.53 19H4.47L12 5.99zM11 16h2v2h-2zm0-6h2v4h-2z\" />\n </svg>\n );\n case 'info':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n >\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-9h2v6h-2zm0-4h2v2h-2z\" />\n </svg>\n );\n default:\n return null;\n }\n };\n\n const displayIcon = icon !== undefined ? icon : getDefaultIcon();\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <Modal\n isActive={isOpen}\n onClose={handleCancel}\n role=\"presentation\"\n portal={portal}\n >\n <Modal.Background onClick={handleBackgroundClick} />\n <div\n ref={combinedRef}\n className={combinedClasses}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'dialog-title' : undefined}\n aria-describedby=\"dialog-message\"\n {...rest}\n >\n {title && (\n <div className={headerClass}>\n {displayIcon && <span className={iconClass}>{displayIcon}</span>}\n <h3 id=\"dialog-title\" className={titleClass}>\n {title}\n </h3>\n </div>\n )}\n <div id=\"dialog-message\" className={bodyClass}>\n {message}\n </div>\n <div className={footerClass}>\n {showCancel && (\n <button\n ref={cancelRef}\n type=\"button\"\n className={cancelButtonClass}\n onClick={handleCancel}\n >\n {cancelText}\n </button>\n )}\n <button\n ref={confirmRef}\n type=\"button\"\n className={confirmButtonClass}\n onClick={handleConfirm}\n >\n {confirmText}\n </button>\n </div>\n </div>\n </Modal>\n );\n }\n);\n\nDialog.displayName = 'Dialog';\n\n// Dialog Manager for programmatic dialogs\n\n/**\n * Options for showing a programmatic alert dialog.\n */\nexport interface AlertOptions {\n /** Dialog title. */\n title?: string;\n /** Dialog message/content. */\n message: string | React.ReactNode;\n /** Dialog type/color. */\n type?: DialogType;\n /** Text for the confirm button. */\n confirmText?: string;\n /** Custom icon to display. */\n icon?: React.ReactNode;\n}\n\n/**\n * Options for showing a programmatic confirm dialog.\n */\nexport interface ConfirmOptions extends AlertOptions {\n /** Text for the cancel button. */\n cancelText?: string;\n /** Focus cancel button instead of confirm. */\n focusCancel?: boolean;\n}\n\n/**\n * Options for showing a programmatic prompt dialog.\n */\nexport interface PromptOptions extends ConfirmOptions {\n /** Input placeholder text. */\n placeholder?: string;\n /** Default input value. */\n defaultValue?: string;\n}\n\ntype DialogResolve = (value?: void | boolean | string) => void;\n\ntype DialogState = {\n type: 'alert' | 'confirm' | 'prompt';\n options: PromptOptions;\n resolve: DialogResolve;\n};\n\nlet dialogListeners: Set<(dialog: DialogState | null) => void> = new Set();\nlet currentDialog: DialogState | null = null;\n\n// DialogContainer renders from the open dialog rather than from updates alone,\n// so a dialog raised before it mounted still opens once it does.\nconst getCurrentDialog = () => currentDialog;\n\n// The server renders no dialog: its copy of this module is shared by every\n// request, so the dialog it holds may belong to another page. Hydration reads\n// the same empty value, which keeps the first client render matching the\n// server's, and the dialog opens right after.\nconst getServerDialog = (): DialogState | null => null;\n\nconst notifyDialogListeners = () => {\n dialogListeners.forEach(listener => listener(currentDialog));\n};\n\n/**\n * Programmatic dialog API for showing dialogs from anywhere.\n */\nexport const dialog = {\n /**\n * Show an alert dialog. Returns a promise that resolves when closed.\n */\n alert: (options: AlertOptions | string): Promise<void> => {\n return new Promise<void>(resolve => {\n const opts = typeof options === 'string' ? { message: options } : options;\n currentDialog = {\n type: 'alert',\n options: opts,\n resolve: () => resolve(),\n };\n notifyDialogListeners();\n });\n },\n\n /**\n * Show a confirm dialog. Returns a promise that resolves to true/false.\n */\n confirm: (options: ConfirmOptions | string): Promise<boolean> => {\n return new Promise<boolean>(resolve => {\n const opts = typeof options === 'string' ? { message: options } : options;\n currentDialog = {\n type: 'confirm',\n options: opts,\n resolve: value => resolve(Boolean(value)),\n };\n notifyDialogListeners();\n });\n },\n\n /**\n * Close the current dialog.\n */\n close: (value?: void | boolean | string): void => {\n if (currentDialog) {\n currentDialog.resolve(value);\n currentDialog = null;\n notifyDialogListeners();\n }\n },\n\n /**\n * Subscribe to dialog changes.\n */\n subscribe: (listener: (dialog: DialogState | null) => void): (() => void) => {\n dialogListeners.add(listener);\n return () => dialogListeners.delete(listener);\n },\n};\n\n/**\n * DialogContainer component to render programmatic dialogs.\n * Place this once at the root of your app.\n *\n * @function\n * @returns {JSX.Element | null} The rendered dialog, or null if none is active.\n */\nexport const DialogContainer: React.FC = () => {\n // Starts from the dialog already open instead of none, then follows changes.\n const current = useSyncExternalStore(\n dialog.subscribe,\n getCurrentDialog,\n getServerDialog\n );\n\n if (!current) {\n return null;\n }\n\n const { type, options } = current;\n\n return (\n <Dialog\n isOpen\n title={options.title}\n message={options.message}\n type={options.type}\n confirmText={options.confirmText}\n cancelText={options.cancelText}\n icon={options.icon}\n showCancel={type === 'confirm'}\n focusCancel={options.focusCancel}\n onConfirm={() => dialog.close(type === 'confirm' ? true : undefined)}\n onCancel={() => dialog.close(type === 'confirm' ? false : undefined)}\n />\n );\n};\n\nexport default Dialog;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Dialog.js","sources":["../../../src/components/Dialog.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useConfig } from '../helpers/Config';\nimport { Modal } from './Modal';\n\n/** Valid dialog type/color values. */\nexport type DialogType = 'default' | 'success' | 'danger' | 'warning' | 'info';\n\n/**\n * Props for the Dialog component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the dialog element.\n */\nexport interface DialogProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color'> {\n /** Whether the dialog is open (required). */\n isOpen: boolean;\n /** Dialog title. */\n title?: string;\n /** Dialog message/content (required). */\n message: string | React.ReactNode;\n /** The type/color of the dialog. Default: 'default'. */\n type?: DialogType;\n /** Text for confirm button. Default: 'OK'. */\n confirmText?: string;\n /** Text for cancel button. Default: 'Cancel'. */\n cancelText?: string;\n /** Callback when confirm button is clicked. */\n onConfirm?: () => void;\n /** Callback when cancel button is clicked or dismissed. */\n onCancel?: () => void;\n /** Whether to show cancel button. Default: true for confirm dialogs. */\n showCancel?: boolean;\n /** Whether the dialog can be dismissed. Default: true. */\n canCancel?: boolean;\n /** Focus cancel button instead of confirm. Default: false. */\n focusCancel?: boolean;\n /** Custom icon to display. */\n icon?: React.ReactNode;\n /**\n * Renders the dialog into a portal target instead of inline. Forwarded to\n * the underlying `Modal`; see its `portal` prop for the accepted values.\n * @defaultValue false\n */\n portal?: boolean | string | HTMLElement;\n}\n\n/**\n * The `Dialog` component provides ready-made confirm and alert dialogs, so a destructive action stays one `await dialog.confirm()` call away.\n *\n * @function\n * @param {DialogProps} props - Props for the Dialog component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the dialog element.\n * @returns {JSX.Element | null} The rendered dialog component.\n *\n * @example\n * // Alert dialog\n * <Dialog\n * isOpen={showAlert}\n * title=\"Success\"\n * message=\"Operation completed successfully!\"\n * type=\"success\"\n * onConfirm={() => setShowAlert(false)}\n * showCancel={false}\n * />\n *\n * @example\n * // Confirm dialog\n * <Dialog\n * isOpen={showConfirm}\n * title=\"Delete Item?\"\n * message=\"This action cannot be undone.\"\n * type=\"danger\"\n * confirmText=\"Delete\"\n * onConfirm={handleDelete}\n * onCancel={() => setShowConfirm(false)}\n * />\n */\nexport const Dialog = forwardRef<HTMLDivElement, DialogProps>(\n (\n {\n isOpen,\n title,\n message,\n type = 'default',\n confirmText = 'OK',\n cancelText = 'Cancel',\n onConfirm,\n onCancel,\n showCancel = true,\n canCancel = true,\n focusCancel = false,\n icon,\n portal,\n className,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const dialogRef = useRef<HTMLDivElement>(null);\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n const cancelRef = useRef<HTMLButtonElement>(null);\n\n // Handle cancel\n const handleCancel = useCallback(() => {\n if (canCancel) {\n onCancel?.();\n }\n }, [canCancel, onCancel]);\n\n // Handle confirm\n const handleConfirm = useCallback(() => {\n onConfirm?.();\n }, [onConfirm]);\n\n // Handle background click\n const handleBackgroundClick = useCallback(() => {\n if (canCancel) {\n handleCancel();\n }\n }, [canCancel, handleCancel]);\n\n // Moving into the portal, or from one portal target to another, remounts\n // the Modal's subtree, these buttons included, so the focus effect below\n // has to re-run against the new nodes, exactly as the Modal's own focus\n // effect does, on the same inputs.\n const isHydrated = useIsHydrated();\n const isPortaled = Boolean(portal) && isHydrated;\n const { portalContainer } = useConfig();\n const defaultTarget =\n isPortaled && portal === true ? portalContainer : undefined;\n\n // Focus management — Dialog picks a specific button rather than the\n // Modal's default (first focusable/root); this effect runs after the\n // inner Modal's own focus-on-open effect, so it wins.\n useEffect(() => {\n if (isOpen) {\n const buttonToFocus =\n focusCancel && showCancel ? cancelRef.current : confirmRef.current;\n buttonToFocus?.focus();\n }\n }, [isOpen, focusCancel, showCancel, isPortaled, portal, defaultTarget]);\n\n // Use combined ref\n const combinedRef = useCallback(\n (node: HTMLDivElement | null) => {\n (dialogRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches by\n // running it instead of calling the ref with `null`; React 18 discards the\n // return value entirely. Returning it from here would be a React-19-only\n // contract, so we hold the cleanup and run it ourselves on detach — the\n // same shape as `Dropdown`, `Modal`, `Sidebar`, `Toast` and `Carousel`.\n // The form controls that merge a forwarded ref still discard the cleanup\n // and detach with `ref(null)`, so this is not yet library-wide — grep\n // `typeof ref === 'function'` for the current split.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const dialogClasses = usePrefixedClassNames('dialog', {\n [`is-${type}`]: type !== 'default',\n });\n const headerClass = usePrefixedClassNames('dialog-header');\n const iconClass = usePrefixedClassNames('dialog-icon');\n const titleClass = usePrefixedClassNames('dialog-title');\n const bodyClass = usePrefixedClassNames('dialog-body');\n const footerClass = usePrefixedClassNames('dialog-footer');\n const cancelButtonClass = usePrefixedClassNames('button');\n const confirmButtonClass = usePrefixedClassNames('button', {\n 'is-success': type === 'success',\n 'is-danger': type === 'danger',\n 'is-warning': type === 'warning',\n 'is-info': type === 'info',\n 'is-primary': type === 'default',\n });\n\n const combinedClasses = classNames(\n dialogClasses,\n bulmaHelperClasses,\n className\n );\n\n // Get default icon based on type\n const getDefaultIcon = () => {\n switch (type) {\n case 'success':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n );\n case 'danger':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n );\n case 'warning':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n >\n <path d=\"M12 2L1 21h22L12 2zm0 3.99L19.53 19H4.47L12 5.99zM11 16h2v2h-2zm0-6h2v4h-2z\" />\n </svg>\n );\n case 'info':\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n >\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-9h2v6h-2zm0-4h2v2h-2z\" />\n </svg>\n );\n default:\n return null;\n }\n };\n\n const displayIcon = icon !== undefined ? icon : getDefaultIcon();\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <Modal\n isActive={isOpen}\n onClose={handleCancel}\n role=\"presentation\"\n portal={portal}\n >\n <Modal.Background onClick={handleBackgroundClick} />\n <div\n ref={combinedRef}\n className={combinedClasses}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'dialog-title' : undefined}\n aria-describedby=\"dialog-message\"\n {...rest}\n >\n {title && (\n <div className={headerClass}>\n {displayIcon && <span className={iconClass}>{displayIcon}</span>}\n <h3 id=\"dialog-title\" className={titleClass}>\n {title}\n </h3>\n </div>\n )}\n <div id=\"dialog-message\" className={bodyClass}>\n {message}\n </div>\n <div className={footerClass}>\n {showCancel && (\n <button\n ref={cancelRef}\n type=\"button\"\n className={cancelButtonClass}\n onClick={handleCancel}\n >\n {cancelText}\n </button>\n )}\n <button\n ref={confirmRef}\n type=\"button\"\n className={confirmButtonClass}\n onClick={handleConfirm}\n >\n {confirmText}\n </button>\n </div>\n </div>\n </Modal>\n );\n }\n);\n\nDialog.displayName = 'Dialog';\n\n// Dialog Manager for programmatic dialogs\n\n/**\n * Options for showing a programmatic alert dialog.\n */\nexport interface AlertOptions {\n /** Dialog title. */\n title?: string;\n /** Dialog message/content. */\n message: string | React.ReactNode;\n /** Dialog type/color. */\n type?: DialogType;\n /** Text for the confirm button. */\n confirmText?: string;\n /** Custom icon to display. */\n icon?: React.ReactNode;\n}\n\n/**\n * Options for showing a programmatic confirm dialog.\n */\nexport interface ConfirmOptions extends AlertOptions {\n /** Text for the cancel button. */\n cancelText?: string;\n /** Focus cancel button instead of confirm. */\n focusCancel?: boolean;\n}\n\n/**\n * Options for showing a programmatic prompt dialog.\n */\nexport interface PromptOptions extends ConfirmOptions {\n /** Input placeholder text. */\n placeholder?: string;\n /** Default input value. */\n defaultValue?: string;\n}\n\ntype DialogResolve = (value?: void | boolean | string) => void;\n\ntype DialogState = {\n type: 'alert' | 'confirm' | 'prompt';\n options: PromptOptions;\n resolve: DialogResolve;\n};\n\nlet dialogListeners: Set<(dialog: DialogState | null) => void> = new Set();\nlet currentDialog: DialogState | null = null;\n\n// DialogContainer renders from the open dialog rather than from updates alone,\n// so a dialog raised before it mounted still opens once it does.\nconst getCurrentDialog = () => currentDialog;\n\n// The server renders no dialog: its copy of this module is shared by every\n// request, so the dialog it holds may belong to another page. Hydration reads\n// the same empty value, which keeps the first client render matching the\n// server's, and the dialog opens right after.\nconst getServerDialog = (): DialogState | null => null;\n\nconst notifyDialogListeners = () => {\n dialogListeners.forEach(listener => listener(currentDialog));\n};\n\n/**\n * Programmatic dialog API for showing dialogs from anywhere.\n */\nexport const dialog = {\n /**\n * Show an alert dialog. Returns a promise that resolves when closed.\n */\n alert: (options: AlertOptions | string): Promise<void> => {\n return new Promise<void>(resolve => {\n const opts = typeof options === 'string' ? { message: options } : options;\n currentDialog = {\n type: 'alert',\n options: opts,\n resolve: () => resolve(),\n };\n notifyDialogListeners();\n });\n },\n\n /**\n * Show a confirm dialog. Returns a promise that resolves to true/false.\n */\n confirm: (options: ConfirmOptions | string): Promise<boolean> => {\n return new Promise<boolean>(resolve => {\n const opts = typeof options === 'string' ? { message: options } : options;\n currentDialog = {\n type: 'confirm',\n options: opts,\n resolve: value => resolve(Boolean(value)),\n };\n notifyDialogListeners();\n });\n },\n\n /**\n * Close the current dialog.\n */\n close: (value?: void | boolean | string): void => {\n if (currentDialog) {\n currentDialog.resolve(value);\n currentDialog = null;\n notifyDialogListeners();\n }\n },\n\n /**\n * Subscribe to dialog changes.\n */\n subscribe: (listener: (dialog: DialogState | null) => void): (() => void) => {\n dialogListeners.add(listener);\n return () => dialogListeners.delete(listener);\n },\n};\n\n/**\n * DialogContainer component to render programmatic dialogs.\n * Place this once at the root of your app.\n *\n * @function\n * @returns {JSX.Element | null} The rendered dialog, or null if none is active.\n */\nexport const DialogContainer: React.FC = () => {\n // Starts from the dialog already open instead of none, then follows changes.\n const current = useSyncExternalStore(\n dialog.subscribe,\n getCurrentDialog,\n getServerDialog\n );\n\n if (!current) {\n return null;\n }\n\n const { type, options } = current;\n\n return (\n <Dialog\n isOpen\n title={options.title}\n message={options.message}\n type={options.type}\n confirmText={options.confirmText}\n cancelText={options.cancelText}\n icon={options.icon}\n showCancel={type === 'confirm'}\n focusCancel={options.focusCancel}\n onConfirm={() => dialog.close(type === 'confirm' ? true : undefined)}\n onCancel={() => dialog.close(type === 'confirm' ? false : undefined)}\n />\n );\n};\n\nexport default Dialog;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
4
|
import { forwardRef, useState, useRef, useCallback, useEffect } from 'react';
|
|
4
5
|
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
@@ -107,7 +108,10 @@ const DropdownComponent = forwardRef(function DropdownComponent({ label, childre
|
|
|
107
108
|
useEffect(() => {
|
|
108
109
|
if (!active)
|
|
109
110
|
return;
|
|
110
|
-
|
|
111
|
+
// Reading `window` or `document` bare throws where neither exists, so
|
|
112
|
+
// the check is `typeof`, as `isBrowser`'s own note recommends.
|
|
113
|
+
/* istanbul ignore next: React DOM runs effects only in a browser */
|
|
114
|
+
if (typeof document === 'undefined')
|
|
111
115
|
return;
|
|
112
116
|
const handleClick = (e) => {
|
|
113
117
|
if (!isEventInside(e, dropdownRef.current)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.js","sources":["../../../src/components/Dropdown.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useState,\n useRef,\n useEffect,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { getActiveElementInTree, isEventInside } from '../helpers/shadowDom';\nimport type { ConstrainedPolymorphicComponentWithoutRef } from '../helpers/polymorphic';\nimport {\n type AnchorOnlyAttributes,\n ANCHOR_ONLY_ATTRS,\n omitAttrs,\n} from '../helpers/anchorAttrs';\nimport { buttonType } from '../helpers/buttonType';\nimport { enabledMenuItems, useMenuKeys } from '../helpers/useMenuKeys';\nimport { useLatestRef } from '../helpers/useLatestRef';\n\n/**\n * Checks if code is running in a browser environment.\n * @deprecated Dropdown's internal SSR guard, exported by accident; it will\n * be removed in the next major. Check `typeof window !== 'undefined' &&\n * typeof document !== 'undefined'` instead.\n * @param win - Window object.\n * @param doc - Document object.\n * @returns {boolean} True if in browser, false otherwise.\n */\nexport const isBrowser = (win?: typeof window, doc?: typeof document) =>\n typeof win !== 'undefined' && typeof doc !== 'undefined';\n\n/**\n * Props for the Dropdown component.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root dropdown element.\n */\nexport interface DropdownProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, keyof BulmaClassesProps>,\n BulmaClassesProps {\n /** The dropdown button/trigger content. */\n label: React.ReactNode;\n /** Dropdown menu items and dividers. */\n children: React.ReactNode;\n /** Additional CSS classes for root. */\n className?: string;\n /** Additional CSS classes for the dropdown menu. */\n menuClassName?: string;\n /** Whether the dropdown is open (controlled). */\n active?: boolean;\n /** Dropdown menu opens upward. */\n up?: boolean;\n /** Menu is right-aligned. */\n right?: boolean;\n /** Open on hover instead of click. */\n hoverable?: boolean;\n /** Disables the dropdown trigger. */\n disabled?: boolean;\n /** Callback when dropdown active state changes. */\n onActiveChange?: (active: boolean) => void;\n /** Close dropdown when a menu item is clicked, or activated with Enter or Space. */\n closeOnClick?: boolean;\n /** Root element ID (for aria-controls, etc). */\n id?: string;\n}\n\n/**\n * The `Dropdown` component provides Bulma's versatile dropdown menu for your Bulma React UI.\n *\n * Down, Enter and Space on the trigger open the menu on its first enabled\n * item, and Up opens it on its last. On the trigger of a menu that's already\n * open, Down and Up move focus to its first and last item. In the menu, the\n * arrow keys, Home and End move between the items, and Enter and Space run\n * the focused one the way a click does. Typing a letter moves to the next\n * item whose text starts with it, skipping disabled ones, and letters typed\n * in quick succession add up to one search. Typing searches once focus is in\n * the menu, so a letter typed on the trigger does nothing. Escape closes the\n * menu and focuses the trigger, and Tab closes it and lets focus move on.\n * Anything focusable in the menu that isn't an item, such as a field, keeps\n * its own keys apart from Escape and Tab, though an Escape it calls\n * `preventDefault()` on in its own `onKeyDown` stays its own and leaves the\n * menu open. For a panel built around fields, use `Popover`.\n *\n * @function\n * @param {DropdownProps} props - Props for the Dropdown component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the root dropdown element.\n * @returns {JSX.Element} The rendered dropdown.\n * @see {@link https://bulma.io/documentation/components/dropdown/ | Bulma Dropdown documentation}\n */\nconst DropdownComponent = forwardRef<HTMLDivElement, DropdownProps>(\n function DropdownComponent(\n {\n label,\n children,\n className,\n menuClassName,\n active: activeProp,\n up,\n right,\n hoverable,\n disabled,\n onActiveChange,\n closeOnClick = true,\n id,\n ...props\n },\n ref\n ) {\n const [active, setActive] = useState<boolean>(!!activeProp);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const menuKeys = useMenuKeys();\n const pendingFocusRef = useRef<'first' | 'last' | null>(null);\n\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n\n const setRefs = useCallback(\n (node: HTMLDivElement | null) => {\n (dropdownRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches\n // by running it instead of calling the ref with `null`; React 18\n // discards the return value entirely. Returning it from here would be\n // a React-19-only contract, so instead we hold the cleanup and run it\n // ourselves on detach — a consumer's cleanup ref then behaves the same\n // on both majors of the CI matrix.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [ref]\n );\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('dropdown', {\n 'is-active': active,\n 'is-up': up,\n 'is-right': right,\n 'is-hoverable': hoverable,\n 'is-disabled': disabled,\n });\n\n const buttonClass = usePrefixedClassNames('button');\n\n // Controlled mode support: mirror the controlled `active` prop into local\n // state. This is an intentional external-prop sync (controlled/uncontrolled\n // hybrid); behavior is covered by tests and certified in-browser.\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- syncing to controlled prop\n if (typeof activeProp === 'boolean') setActive(activeProp);\n }, [activeProp]);\n\n // Read when a click lands outside, so the listener stays put while\n // `onActiveChange` changes identity, as an inline one does on every\n // render of the parent.\n const onActiveChangeRef = useLatestRef(onActiveChange);\n\n // SSR-safe outside click\n useEffect(() => {\n if (!active) return;\n\n if (!isBrowser(window, document)) return;\n\n const handleClick = (e: MouseEvent) => {\n if (!isEventInside(e, dropdownRef.current)) {\n setActive(false);\n onActiveChangeRef.current?.(false);\n }\n };\n document.addEventListener('mousedown', handleClick);\n return () => document.removeEventListener('mousedown', handleClick);\n }, [active, onActiveChangeRef]);\n\n const handleToggle = () => {\n /* istanbul ignore next: guard is enforced by button[disabled] at the DOM level */\n if (disabled) return;\n\n const newActive = !active;\n setActive(newActive);\n onActiveChange?.(newActive);\n };\n\n const handleMenuClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (closeOnClick) {\n setActive(false);\n onActiveChange?.(false);\n // Closing hides the item that has focus, and the browser drops focus\n // to the page when that happens. Hand it back to the trigger, as\n // Escape does. An item that moved focus somewhere else keeps it there.\n // The menu around this content is what a click between items focuses.\n const menu = e.currentTarget.parentElement as HTMLElement;\n if (menu.contains(getActiveElementInTree(e.currentTarget))) {\n triggerRef.current?.focus();\n }\n }\n };\n\n const focusEdgeItem = (edge: 'first' | 'last') => {\n const items = enabledMenuItems(menuRef.current as HTMLElement);\n items[edge === 'first' ? 0 : items.length - 1]?.focus();\n };\n\n // Once the menu shows, forget a search typed just before it last closed,\n // and focus the pending item. The item is unfocusable while\n // `display: none` applies, so this must wait for the `is-active` class to\n // actually land in the DOM.\n useEffect(() => {\n if (!active) return;\n menuKeys.reset();\n if (!pendingFocusRef.current) return;\n focusEdgeItem(pendingFocusRef.current);\n pendingFocusRef.current = null;\n }, [active, menuKeys]);\n\n const handleTriggerKeyDown = (\n e: React.KeyboardEvent<HTMLButtonElement>\n ) => {\n if (disabled) return;\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n pendingFocusRef.current = 'first';\n if (!active) {\n setActive(true);\n onActiveChange?.(true);\n } else {\n focusEdgeItem('first');\n pendingFocusRef.current = null;\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n pendingFocusRef.current = 'last';\n if (!active) {\n setActive(true);\n onActiveChange?.(true);\n } else {\n focusEdgeItem('last');\n pendingFocusRef.current = null;\n }\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n // A held key sends a keydown per auto-repeat. Running an item hands\n // focus back here, so without this a held Enter would reopen the\n // menu and run whichever item it focused next.\n if (e.repeat) break;\n if (!active) {\n pendingFocusRef.current = 'first';\n setActive(true);\n onActiveChange?.(true);\n } else {\n setActive(false);\n onActiveChange?.(false);\n }\n break;\n case 'Escape':\n if (active) {\n e.preventDefault();\n setActive(false);\n onActiveChange?.(false);\n }\n break;\n default:\n break;\n }\n };\n\n const handleMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n // Closing is Dropdown's: Escape and Tab close the menu from anywhere in\n // it, a field included, and an empty or all-disabled menu too. Moving\n // between the items, running them and typeahead are the hook's, which\n // acts only while focus is on the menu or one of its items. An Escape\n // something in the menu already used, such as a field's own list\n // closing on it, leaves the menu open for the next one.\n if (e.key === 'Escape') {\n if (e.defaultPrevented) return;\n e.preventDefault();\n setActive(false);\n onActiveChange?.(false);\n triggerRef.current?.focus();\n return;\n }\n if (e.key === 'Tab') {\n setActive(false);\n onActiveChange?.(false);\n return;\n }\n\n menuKeys.onKeyDown(e);\n };\n\n const dropdownClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <div\n className={dropdownClasses}\n ref={setRefs}\n id={id}\n data-testid=\"dropdown-root\"\n {...rest}\n >\n <div className={usePrefixedClassNames('dropdown-trigger')}>\n <button\n ref={triggerRef}\n className={buttonClass}\n aria-haspopup=\"true\"\n aria-controls={id ? `${id}-menu` : undefined}\n aria-expanded={active}\n onClick={handleToggle}\n onKeyDown={handleTriggerKeyDown}\n disabled={disabled}\n type=\"button\"\n >\n <span>{label}</span>\n <span\n className={usePrefixedClassNames('icon', 'is-small')}\n aria-hidden=\"true\"\n >\n <i className=\"fas fa-angle-down\" />\n </span>\n </button>\n </div>\n <div\n className={classNames(\n usePrefixedClassNames('dropdown-menu'),\n menuClassName\n )}\n id={id ? `${id}-menu` : undefined}\n ref={menuRef}\n role=\"menu\"\n data-testid=\"dropdown-menu\"\n onKeyDown={handleMenuKeyDown}\n // The menu, not its content, takes focus from a click between items,\n // so the menu owns nothing focusable but its items.\n tabIndex={-1}\n >\n <div\n className={usePrefixedClassNames('dropdown-content')}\n onClick={handleMenuClick}\n >\n {children}\n </div>\n </div>\n </div>\n );\n }\n);\n\n/**\n * The elements a dropdown item may render as. Bulma's dropdown markup names\n * these three and no others, so `as` is a closed set rather than an open\n * `React.ElementType`.\n */\nexport type DropdownItemElement = 'a' | 'div' | 'button';\n\n/**\n * The DropdownItem component's own props.\n */\nexport interface DropdownItemOwnProps extends BulmaClassesProps {\n /** Whether the item is active. */\n active?: boolean;\n /** Additional CSS classes. */\n className?: string;\n /** Marks the item as disabled; disabled items are skipped during keyboard navigation. Use with `as=\"button\"` for a native disabled control, or pair with `aria-disabled` on a link. */\n disabled?: boolean;\n /** Item content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the DropdownItem component. Everything the item does not own\n * follows `as`: `href`, `target` and `rel` under the default `'a'`, `type` and\n * `form` under `'button'`, and the shared HTML attributes under any of them.\n *\n * Pinning these to `React.HTMLAttributes<HTMLElement>` instead — which is what\n * this type did before — rejected `href` on an anchor and `type` on a button,\n * both of which have always worked at runtime. Same defect as #641, in the\n * narrower shape a constrained `as` takes.\n *\n * **Name the tag you mean.** The type parameter defaults to the whole union, not\n * to the rendered element, so bare `DropdownItemProps` keeps accepting\n * `{ as: 'div' }` the way it always has. The cost is that it is not\n * distributive: `Omit` over a union keeps only the shared keys, so the bare\n * alias carries no `href` even though the component takes one under `as=\"a\"`.\n * Write `DropdownItemProps<'a'>` for the anchor's props. That is the #667 alias\n * limitation Button carries, labelled next-major because closing it is\n * source-breaking, and pinned for this component in\n * `__typetests__/polymorphic.tsx`; the component itself is unaffected.\n */\nexport type DropdownItemProps<\n T extends DropdownItemElement = DropdownItemElement,\n> = DropdownItemOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof DropdownItemOwnProps | 'as'> & {\n /**\n * The element type to render.\n *\n * `'button'` renders `type=\"button\"` unless you pass `type=\"submit\"` or `type=\"reset\"`, so\n * an item inside a form does not submit it.\n */\n as?: T;\n };\n\n/**\n * The anchor's attributes, minus the one a `<button>` legitimately takes.\n *\n * `type` stays: `as=\"button\"` is a supported form and `type=\"submit\"` is valid\n * there, so stripping it would remove a working attribute. A `<div>` takes no\n * `type`, so it gets the whole `ANCHOR_ONLY_ATTRS` set instead. The set is\n * chosen by the rendered tag because that is where the reason lives (#692).\n *\n * Neither set withholds `rel`, which `Level.Item` does: React declares `rel` on\n * `HTMLAttributes` for every element, so withholding it would diverge from\n * React's own typing, the call #641 recorded for `Navbar.Link`. Level\n * withholds it anyway, because it always has.\n */\nconst STRIP_FROM_BUTTON: Readonly<\n Record<Exclude<keyof AnchorOnlyAttributes, 'type'>, true>\n> = (() => {\n const { type: _type, ...rest } = ANCHOR_ONLY_ATTRS;\n return rest;\n})();\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `DropdownItemProps<T>` above — the body cannot see through `T`.\n */\ntype DropdownItemImplProps = DropdownItemOwnProps & {\n as?: DropdownItemElement;\n};\n\n/**\n * Bulma Dropdown item.\n *\n * @function\n * @param {DropdownItemProps} props - Props for the DropdownItem component.\n * @returns {JSX.Element} The rendered dropdown item.\n */\nexport const DropdownItem = ((itemProps: DropdownItemProps) => {\n const {\n children,\n active,\n className,\n as: Component = 'a',\n ...props\n } = itemProps as DropdownItemImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n // The anchor's attributes reach an anchor and nothing else — `<div href>` and\n // `<button target>` are invalid HTML. The same rule Menu applies, for the same\n // reason: the type now derives these from `as`, and deriving them must not\n // quietly widen where they land. The type stops a direct caller; this stops a\n // plain-JS one, a loose `{...props}` spread, and the genericity a wrapping HOC\n // erases.\n //\n // The whole link set, not `href` alone: they all arrive together under\n // `as=\"a\"`. Menu strips `href` only, because its `as` is open and a flat set\n // would delete attributes legal on the element a caller named.\n //\n // `bestax-migrate` tracks the same question from the other side, per attribute\n // per element (`LINK_ATTR_ELEMENTS`) rather than as one set — so the two lists\n // are not interchangeable and neither derives from the other.\n //\n // Menu's condition also admits a custom component and a custom element, which\n // own their prop contracts. Here the set follows the tag: an `<a>` keeps all\n // of them, a `<button>` keeps `type`, and any other `as` keeps none of them.\n const forwarded =\n Component === 'a'\n ? rest\n : Component === 'button'\n ? omitAttrs(rest, STRIP_FROM_BUTTON)\n : omitAttrs(rest, ANCHOR_ONLY_ATTRS);\n return (\n <Component\n className={classNames(\n usePrefixedClassNames('dropdown-item', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n data-testid=\"dropdown-item\"\n {...forwarded}\n // After `forwarded` for the same reason as `role` and `type` below: a\n // spread carrying `tabIndex: undefined` would otherwise erase the\n // default. The item keeps its menu role and its place in the arrow-key\n // order, but a `<div>` or an anchor without an `href` cannot take focus\n // without a tabindex, so the arrow keys stall on it.\n tabIndex={(forwarded as { tabIndex?: number }).tabIndex ?? 0}\n // After `forwarded` for the same reason as `type` below: a spread\n // carrying `role: undefined` would otherwise erase the default, and an\n // item with no role drops out of the menu and its arrow-key order.\n role={(forwarded as { role?: React.AriaRole }).role ?? 'menuitem'}\n // A menu item inside a form must not submit it. `<button>` defaults to\n // type=\"submit\", and a filter or sort menu sitting in a form is ordinary.\n // Dropdown's own trigger sets it, and `Avatar` and `Menu.Item` default it\n // the same way. A caller's `submit` or `reset` still wins, and anything\n // else becomes `button`, since HTML reads a value it does not define for\n // a button as submit too; `buttonType` says more.\n //\n // After `forwarded`, reading through it rather than before it: React\n // treats `type={undefined}` as \"remove the attribute\", and a spread\n // carrying an absent key is how that arrives. Spreading the default first\n // let such a spread erase it and restore the submit behaviour, so the\n // guard only held for callers who passed nothing.\n {...(Component === 'button'\n ? { type: buttonType((forwarded as { type?: unknown }).type) }\n : {})}\n >\n {children}\n </Component>\n );\n}) as ConstrainedPolymorphicComponentWithoutRef<\n DropdownItemOwnProps,\n DropdownItemElement,\n 'a'\n>;\n\n/**\n * Bulma Dropdown divider.\n *\n * @function\n * @returns {JSX.Element} The rendered divider element.\n */\nexport const DropdownDivider: React.FC = () => (\n <hr className={usePrefixedClassNames('dropdown-divider')} />\n);\n\n/** Bulma Dropdown component with Item and Divider sub-components. */\nexport const Dropdown = withSubComponents(\n DropdownComponent,\n {\n Item: DropdownItem,\n Divider: DropdownDivider,\n },\n 'Dropdown'\n);\n\nexport default Dropdown;\n"],"names":["isBrowser","_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Dropdown.js","sources":["../../../src/components/Dropdown.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useState,\n useRef,\n useEffect,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { getActiveElementInTree, isEventInside } from '../helpers/shadowDom';\nimport type { ConstrainedPolymorphicComponentWithoutRef } from '../helpers/polymorphic';\nimport {\n type AnchorOnlyAttributes,\n ANCHOR_ONLY_ATTRS,\n omitAttrs,\n} from '../helpers/anchorAttrs';\nimport { buttonType } from '../helpers/buttonType';\nimport { enabledMenuItems, useMenuKeys } from '../helpers/useMenuKeys';\nimport { useLatestRef } from '../helpers/useLatestRef';\n\n/**\n * Checks if code is running in a browser environment.\n * @deprecated Dropdown's internal SSR guard, exported by accident; it will\n * be removed in the next major. Check `typeof window !== 'undefined' &&\n * typeof document !== 'undefined'` instead.\n * @param win - Window object.\n * @param doc - Document object.\n * @returns {boolean} True if in browser, false otherwise.\n */\nexport const isBrowser = (win?: typeof window, doc?: typeof document) =>\n typeof win !== 'undefined' && typeof doc !== 'undefined';\n\n/**\n * Props for the Dropdown component.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root dropdown element.\n */\nexport interface DropdownProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, keyof BulmaClassesProps>,\n BulmaClassesProps {\n /** The dropdown button/trigger content. */\n label: React.ReactNode;\n /** Dropdown menu items and dividers. */\n children: React.ReactNode;\n /** Additional CSS classes for root. */\n className?: string;\n /** Additional CSS classes for the dropdown menu. */\n menuClassName?: string;\n /** Whether the dropdown is open (controlled). */\n active?: boolean;\n /** Dropdown menu opens upward. */\n up?: boolean;\n /** Menu is right-aligned. */\n right?: boolean;\n /** Open on hover instead of click. */\n hoverable?: boolean;\n /** Disables the dropdown trigger. */\n disabled?: boolean;\n /** Callback when dropdown active state changes. */\n onActiveChange?: (active: boolean) => void;\n /** Close dropdown when a menu item is clicked, or activated with Enter or Space. */\n closeOnClick?: boolean;\n /** Root element ID (for aria-controls, etc). */\n id?: string;\n}\n\n/**\n * The `Dropdown` component provides Bulma's versatile dropdown menu for your Bulma React UI.\n *\n * Down, Enter and Space on the trigger open the menu on its first enabled\n * item, and Up opens it on its last. On the trigger of a menu that's already\n * open, Down and Up move focus to its first and last item. In the menu, the\n * arrow keys, Home and End move between the items, and Enter and Space run\n * the focused one the way a click does. Typing a letter moves to the next\n * item whose text starts with it, skipping disabled ones, and letters typed\n * in quick succession add up to one search. Typing searches once focus is in\n * the menu, so a letter typed on the trigger does nothing. Escape closes the\n * menu and focuses the trigger, and Tab closes it and lets focus move on.\n * Anything focusable in the menu that isn't an item, such as a field, keeps\n * its own keys apart from Escape and Tab, though an Escape it calls\n * `preventDefault()` on in its own `onKeyDown` stays its own and leaves the\n * menu open. For a panel built around fields, use `Popover`.\n *\n * @function\n * @param {DropdownProps} props - Props for the Dropdown component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the root dropdown element.\n * @returns {JSX.Element} The rendered dropdown.\n * @see {@link https://bulma.io/documentation/components/dropdown/ | Bulma Dropdown documentation}\n */\nconst DropdownComponent = forwardRef<HTMLDivElement, DropdownProps>(\n function DropdownComponent(\n {\n label,\n children,\n className,\n menuClassName,\n active: activeProp,\n up,\n right,\n hoverable,\n disabled,\n onActiveChange,\n closeOnClick = true,\n id,\n ...props\n },\n ref\n ) {\n const [active, setActive] = useState<boolean>(!!activeProp);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const menuKeys = useMenuKeys();\n const pendingFocusRef = useRef<'first' | 'last' | null>(null);\n\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n\n const setRefs = useCallback(\n (node: HTMLDivElement | null) => {\n (dropdownRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches\n // by running it instead of calling the ref with `null`; React 18\n // discards the return value entirely. Returning it from here would be\n // a React-19-only contract, so instead we hold the cleanup and run it\n // ourselves on detach — a consumer's cleanup ref then behaves the same\n // on both majors of the CI matrix.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n },\n [ref]\n );\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('dropdown', {\n 'is-active': active,\n 'is-up': up,\n 'is-right': right,\n 'is-hoverable': hoverable,\n 'is-disabled': disabled,\n });\n\n const buttonClass = usePrefixedClassNames('button');\n\n // Controlled mode support: mirror the controlled `active` prop into local\n // state. This is an intentional external-prop sync (controlled/uncontrolled\n // hybrid); behavior is covered by tests and certified in-browser.\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- syncing to controlled prop\n if (typeof activeProp === 'boolean') setActive(activeProp);\n }, [activeProp]);\n\n // Read when a click lands outside, so the listener stays put while\n // `onActiveChange` changes identity, as an inline one does on every\n // render of the parent.\n const onActiveChangeRef = useLatestRef(onActiveChange);\n\n // SSR-safe outside click\n useEffect(() => {\n if (!active) return;\n\n // Reading `window` or `document` bare throws where neither exists, so\n // the check is `typeof`, as `isBrowser`'s own note recommends.\n /* istanbul ignore next: React DOM runs effects only in a browser */\n if (typeof document === 'undefined') return;\n\n const handleClick = (e: MouseEvent) => {\n if (!isEventInside(e, dropdownRef.current)) {\n setActive(false);\n onActiveChangeRef.current?.(false);\n }\n };\n document.addEventListener('mousedown', handleClick);\n return () => document.removeEventListener('mousedown', handleClick);\n }, [active, onActiveChangeRef]);\n\n const handleToggle = () => {\n /* istanbul ignore next: guard is enforced by button[disabled] at the DOM level */\n if (disabled) return;\n\n const newActive = !active;\n setActive(newActive);\n onActiveChange?.(newActive);\n };\n\n const handleMenuClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (closeOnClick) {\n setActive(false);\n onActiveChange?.(false);\n // Closing hides the item that has focus, and the browser drops focus\n // to the page when that happens. Hand it back to the trigger, as\n // Escape does. An item that moved focus somewhere else keeps it there.\n // The menu around this content is what a click between items focuses.\n const menu = e.currentTarget.parentElement as HTMLElement;\n if (menu.contains(getActiveElementInTree(e.currentTarget))) {\n triggerRef.current?.focus();\n }\n }\n };\n\n const focusEdgeItem = (edge: 'first' | 'last') => {\n const items = enabledMenuItems(menuRef.current as HTMLElement);\n items[edge === 'first' ? 0 : items.length - 1]?.focus();\n };\n\n // Once the menu shows, forget a search typed just before it last closed,\n // and focus the pending item. The item is unfocusable while\n // `display: none` applies, so this must wait for the `is-active` class to\n // actually land in the DOM.\n useEffect(() => {\n if (!active) return;\n menuKeys.reset();\n if (!pendingFocusRef.current) return;\n focusEdgeItem(pendingFocusRef.current);\n pendingFocusRef.current = null;\n }, [active, menuKeys]);\n\n const handleTriggerKeyDown = (\n e: React.KeyboardEvent<HTMLButtonElement>\n ) => {\n if (disabled) return;\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n pendingFocusRef.current = 'first';\n if (!active) {\n setActive(true);\n onActiveChange?.(true);\n } else {\n focusEdgeItem('first');\n pendingFocusRef.current = null;\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n pendingFocusRef.current = 'last';\n if (!active) {\n setActive(true);\n onActiveChange?.(true);\n } else {\n focusEdgeItem('last');\n pendingFocusRef.current = null;\n }\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n // A held key sends a keydown per auto-repeat. Running an item hands\n // focus back here, so without this a held Enter would reopen the\n // menu and run whichever item it focused next.\n if (e.repeat) break;\n if (!active) {\n pendingFocusRef.current = 'first';\n setActive(true);\n onActiveChange?.(true);\n } else {\n setActive(false);\n onActiveChange?.(false);\n }\n break;\n case 'Escape':\n if (active) {\n e.preventDefault();\n setActive(false);\n onActiveChange?.(false);\n }\n break;\n default:\n break;\n }\n };\n\n const handleMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n // Closing is Dropdown's: Escape and Tab close the menu from anywhere in\n // it, a field included, and an empty or all-disabled menu too. Moving\n // between the items, running them and typeahead are the hook's, which\n // acts only while focus is on the menu or one of its items. An Escape\n // something in the menu already used, such as a field's own list\n // closing on it, leaves the menu open for the next one.\n if (e.key === 'Escape') {\n if (e.defaultPrevented) return;\n e.preventDefault();\n setActive(false);\n onActiveChange?.(false);\n triggerRef.current?.focus();\n return;\n }\n if (e.key === 'Tab') {\n setActive(false);\n onActiveChange?.(false);\n return;\n }\n\n menuKeys.onKeyDown(e);\n };\n\n const dropdownClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <div\n className={dropdownClasses}\n ref={setRefs}\n id={id}\n data-testid=\"dropdown-root\"\n {...rest}\n >\n <div className={usePrefixedClassNames('dropdown-trigger')}>\n <button\n ref={triggerRef}\n className={buttonClass}\n aria-haspopup=\"true\"\n aria-controls={id ? `${id}-menu` : undefined}\n aria-expanded={active}\n onClick={handleToggle}\n onKeyDown={handleTriggerKeyDown}\n disabled={disabled}\n type=\"button\"\n >\n <span>{label}</span>\n <span\n className={usePrefixedClassNames('icon', 'is-small')}\n aria-hidden=\"true\"\n >\n <i className=\"fas fa-angle-down\" />\n </span>\n </button>\n </div>\n <div\n className={classNames(\n usePrefixedClassNames('dropdown-menu'),\n menuClassName\n )}\n id={id ? `${id}-menu` : undefined}\n ref={menuRef}\n role=\"menu\"\n data-testid=\"dropdown-menu\"\n onKeyDown={handleMenuKeyDown}\n // The menu, not its content, takes focus from a click between items,\n // so the menu owns nothing focusable but its items.\n tabIndex={-1}\n >\n <div\n className={usePrefixedClassNames('dropdown-content')}\n onClick={handleMenuClick}\n >\n {children}\n </div>\n </div>\n </div>\n );\n }\n);\n\n/**\n * The elements a dropdown item may render as. Bulma's dropdown markup names\n * these three and no others, so `as` is a closed set rather than an open\n * `React.ElementType`.\n */\nexport type DropdownItemElement = 'a' | 'div' | 'button';\n\n/**\n * The DropdownItem component's own props.\n */\nexport interface DropdownItemOwnProps extends BulmaClassesProps {\n /** Whether the item is active. */\n active?: boolean;\n /** Additional CSS classes. */\n className?: string;\n /** Marks the item as disabled; disabled items are skipped during keyboard navigation. Use with `as=\"button\"` for a native disabled control, or pair with `aria-disabled` on a link. */\n disabled?: boolean;\n /** Item content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the DropdownItem component. Everything the item does not own\n * follows `as`: `href`, `target` and `rel` under the default `'a'`, `type` and\n * `form` under `'button'`, and the shared HTML attributes under any of them.\n *\n * Pinning these to `React.HTMLAttributes<HTMLElement>` instead — which is what\n * this type did before — rejected `href` on an anchor and `type` on a button,\n * both of which have always worked at runtime. Same defect as #641, in the\n * narrower shape a constrained `as` takes.\n *\n * **Name the tag you mean.** The type parameter defaults to the whole union, not\n * to the rendered element, so bare `DropdownItemProps` keeps accepting\n * `{ as: 'div' }` the way it always has. The cost is that it is not\n * distributive: `Omit` over a union keeps only the shared keys, so the bare\n * alias carries no `href` even though the component takes one under `as=\"a\"`.\n * Write `DropdownItemProps<'a'>` for the anchor's props. That is the #667 alias\n * limitation Button carries, labelled next-major because closing it is\n * source-breaking, and pinned for this component in\n * `__typetests__/polymorphic.tsx`; the component itself is unaffected.\n */\nexport type DropdownItemProps<\n T extends DropdownItemElement = DropdownItemElement,\n> = DropdownItemOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof DropdownItemOwnProps | 'as'> & {\n /**\n * The element type to render.\n *\n * `'button'` renders `type=\"button\"` unless you pass `type=\"submit\"` or `type=\"reset\"`, so\n * an item inside a form does not submit it.\n */\n as?: T;\n };\n\n/**\n * The anchor's attributes, minus the one a `<button>` legitimately takes.\n *\n * `type` stays: `as=\"button\"` is a supported form and `type=\"submit\"` is valid\n * there, so stripping it would remove a working attribute. A `<div>` takes no\n * `type`, so it gets the whole `ANCHOR_ONLY_ATTRS` set instead. The set is\n * chosen by the rendered tag because that is where the reason lives (#692).\n *\n * Neither set withholds `rel`, which `Level.Item` does: React declares `rel` on\n * `HTMLAttributes` for every element, so withholding it would diverge from\n * React's own typing, the call #641 recorded for `Navbar.Link`. Level\n * withholds it anyway, because it always has.\n */\nconst STRIP_FROM_BUTTON: Readonly<\n Record<Exclude<keyof AnchorOnlyAttributes, 'type'>, true>\n> = (() => {\n const { type: _type, ...rest } = ANCHOR_ONLY_ATTRS;\n return rest;\n})();\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `DropdownItemProps<T>` above — the body cannot see through `T`.\n */\ntype DropdownItemImplProps = DropdownItemOwnProps & {\n as?: DropdownItemElement;\n};\n\n/**\n * Bulma Dropdown item.\n *\n * @function\n * @param {DropdownItemProps} props - Props for the DropdownItem component.\n * @returns {JSX.Element} The rendered dropdown item.\n */\nexport const DropdownItem = ((itemProps: DropdownItemProps) => {\n const {\n children,\n active,\n className,\n as: Component = 'a',\n ...props\n } = itemProps as DropdownItemImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n // The anchor's attributes reach an anchor and nothing else — `<div href>` and\n // `<button target>` are invalid HTML. The same rule Menu applies, for the same\n // reason: the type now derives these from `as`, and deriving them must not\n // quietly widen where they land. The type stops a direct caller; this stops a\n // plain-JS one, a loose `{...props}` spread, and the genericity a wrapping HOC\n // erases.\n //\n // The whole link set, not `href` alone: they all arrive together under\n // `as=\"a\"`. Menu strips `href` only, because its `as` is open and a flat set\n // would delete attributes legal on the element a caller named.\n //\n // `bestax-migrate` tracks the same question from the other side, per attribute\n // per element (`LINK_ATTR_ELEMENTS`) rather than as one set — so the two lists\n // are not interchangeable and neither derives from the other.\n //\n // Menu's condition also admits a custom component and a custom element, which\n // own their prop contracts. Here the set follows the tag: an `<a>` keeps all\n // of them, a `<button>` keeps `type`, and any other `as` keeps none of them.\n const forwarded =\n Component === 'a'\n ? rest\n : Component === 'button'\n ? omitAttrs(rest, STRIP_FROM_BUTTON)\n : omitAttrs(rest, ANCHOR_ONLY_ATTRS);\n return (\n <Component\n className={classNames(\n usePrefixedClassNames('dropdown-item', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n data-testid=\"dropdown-item\"\n {...forwarded}\n // After `forwarded` for the same reason as `role` and `type` below: a\n // spread carrying `tabIndex: undefined` would otherwise erase the\n // default. The item keeps its menu role and its place in the arrow-key\n // order, but a `<div>` or an anchor without an `href` cannot take focus\n // without a tabindex, so the arrow keys stall on it.\n tabIndex={(forwarded as { tabIndex?: number }).tabIndex ?? 0}\n // After `forwarded` for the same reason as `type` below: a spread\n // carrying `role: undefined` would otherwise erase the default, and an\n // item with no role drops out of the menu and its arrow-key order.\n role={(forwarded as { role?: React.AriaRole }).role ?? 'menuitem'}\n // A menu item inside a form must not submit it. `<button>` defaults to\n // type=\"submit\", and a filter or sort menu sitting in a form is ordinary.\n // Dropdown's own trigger sets it, and `Avatar` and `Menu.Item` default it\n // the same way. A caller's `submit` or `reset` still wins, and anything\n // else becomes `button`, since HTML reads a value it does not define for\n // a button as submit too; `buttonType` says more.\n //\n // After `forwarded`, reading through it rather than before it: React\n // treats `type={undefined}` as \"remove the attribute\", and a spread\n // carrying an absent key is how that arrives. Spreading the default first\n // let such a spread erase it and restore the submit behaviour, so the\n // guard only held for callers who passed nothing.\n {...(Component === 'button'\n ? { type: buttonType((forwarded as { type?: unknown }).type) }\n : {})}\n >\n {children}\n </Component>\n );\n}) as ConstrainedPolymorphicComponentWithoutRef<\n DropdownItemOwnProps,\n DropdownItemElement,\n 'a'\n>;\n\n/**\n * Bulma Dropdown divider.\n *\n * @function\n * @returns {JSX.Element} The rendered divider element.\n */\nexport const DropdownDivider: React.FC = () => (\n <hr className={usePrefixedClassNames('dropdown-divider')} />\n);\n\n/** Bulma Dropdown component with Item and Divider sub-components. */\nexport const Dropdown = withSubComponents(\n DropdownComponent,\n {\n Item: DropdownItem,\n Divider: DropdownDivider,\n },\n 'Dropdown'\n);\n\nexport default Dropdown;\n"],"names":["isBrowser","_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
4
|
import { forwardRef } from 'react';
|
|
4
5
|
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.js","sources":["../../../src/components/EmptyState.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { Buttons, ButtonsProps } from '../elements/Buttons';\nimport { Icon } from '../elements/Icon';\nimport { Paragraph, ParagraphProps } from '../elements/Paragraph';\nimport { Title, TitleProps } from '../elements/Title';\n\nconst validEmptyStateColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n/** The Bulma colors the indicator takes. */\nexport type EmptyStateColor = (typeof validEmptyStateColors)[number];\n\nconst validEmptyStateHeadings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\n/** A title's heading level. It's always a heading, so there's no `p`. */\nexport type EmptyStateHeading = (typeof validEmptyStateHeadings)[number];\n\nconst validEmptyStateSizes = ['small', 'medium', 'large'] as const;\n\n/**\n * Props for the EmptyState component. The helper props, the other attributes\n * and the `ref` land on the root `<div>`. The native `title` attribute isn't\n * one of them, since `title` here is the heading.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root `<div>`.\n */\nexport interface EmptyStateProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'title'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The picture in the indicator's circle. A string is an `Icon` name, drawn\n * from the icon library `ConfigProvider` sets. Anything else (an `<Icon>`\n * with its own `variant` or `library`, an SVG, an `<img>`) renders as it is.\n * It's decorative and hidden from assistive tech, so the title says what\n * it means.\n */\n icon?: React.ReactNode;\n /**\n * The heading, rendered as `EmptyState.Title`. It's always a real heading,\n * at the level `titleAs` sets.\n */\n title?: React.ReactNode;\n /**\n * The heading level for `title`: the level under the heading of the list\n * it stands in for, such as `h3` for a list under an `h2`. Only this sets\n * the level, and the size comes from `size`.\n */\n titleAs?: EmptyStateHeading;\n /** A sentence or two under the title, rendered as `EmptyState.Description`. */\n description?: React.ReactNode;\n /**\n * Rendered as written, after whatever `icon`, `title` and `description`\n * render. One button can go straight in, and it sits centered under the\n * text. Group two or more in `EmptyState.Actions`, or they stack. Without\n * the props, write the parts here in the order they're shown:\n * `EmptyState.Indicator`, `.Title`, `.Description`, then the actions.\n */\n children?: React.ReactNode;\n /**\n * The indicator's color. It colors the circle and its icon, not the text.\n * Without it the circle is neutral, since an empty list isn't a status.\n */\n color?: EmptyStateColor;\n /**\n * `light` is a soft tint of `color` behind the icon in the color. `filled`\n * is the color itself, with the icon in its invert.\n */\n variant?: 'light' | 'filled';\n /** Sizes the indicator, the title, the description and the spacing together. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /**\n * `center` stacks everything in a centered column. `left` puts the\n * indicator beside the text, at the start of the line, so on the right in\n * a right-to-left page, and keeps the block at least as tall as the circle\n * whatever block padding is in effect. Without an indicator, it only puts\n * the text at the start of the line. In `left`, the padding at the start\n * of the line is what makes room for the indicator, so pad it with `py`\n * rather than `p` or `px`.\n */\n align?: 'center' | 'left';\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/** Props for EmptyState.Indicator, the circle the picture sits in. */\nexport interface EmptyStateIndicatorProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The picture: an `Icon`, an SVG or an `<img>`. The indicator is hidden\n * from assistive tech, an `Icon` with an `ariaLabel` included, so anything\n * it means goes in the title or the description.\n */\n children?: React.ReactNode;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/**\n * Props for EmptyState.Title. It renders `Title` with `as` and never `size`,\n * so the level is `as` alone and the size comes from the EmptyState.\n */\nexport interface EmptyStateTitleProps extends Omit<\n TitleProps,\n 'as' | 'size' | 'isSpaced'\n> {\n /**\n * The heading level: the level under the heading of the list the empty\n * state stands in for.\n */\n as?: EmptyStateHeading;\n}\n\n/** Props for EmptyState.Description, a `<p>` under the title. */\nexport type EmptyStateDescriptionProps = ParagraphProps;\n\n/**\n * Props for EmptyState.Actions, the row of buttons. It renders `Buttons`,\n * and the EmptyState aligns it, so `isCentered` and `isRight` are left out.\n */\nexport type EmptyStateActionsProps = Omit<\n ButtonsProps,\n 'isCentered' | 'isRight'\n>;\n\n/**\n * The circle the picture sits in, hidden from assistive tech whatever is in it.\n *\n * @function\n * @param {EmptyStateIndicatorProps} props - Props for EmptyState.Indicator.\n * @returns {JSX.Element} The rendered indicator.\n */\nexport const EmptyStateIndicator: React.FC<EmptyStateIndicatorProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const indicatorClass = usePrefixedClassNames('empty-state-indicator');\n\n // Hidden after the rest of the props, so nothing passed in can expose the\n // picture: the title says what it means.\n return (\n <div\n className={classNames(indicatorClass, bulmaHelperClasses, className)}\n {...rest}\n aria-hidden=\"true\"\n >\n {children}\n </div>\n );\n};\n\nEmptyStateIndicator.displayName = 'EmptyState.Indicator';\n\n/**\n * The heading, a Bulma `Title` at the level `as` sets, `h2` by default, and at the EmptyState's size.\n *\n * @function\n * @param {EmptyStateTitleProps} props - Props for EmptyState.Title.\n * @returns {JSX.Element} The rendered heading.\n */\nexport const EmptyStateTitle: React.FC<EmptyStateTitleProps> = ({\n as = 'h2',\n className,\n ...props\n}) => {\n // `size` isn't in the type, but on `Title` it picks the tag, so it's kept\n // off even when it's passed anyway. The level is `as` alone.\n const { size: _size, ...rest } = props as typeof props & { size?: unknown };\n const titleClass = usePrefixedClassNames('empty-state-title');\n const level = validEmptyStateHeadings.includes(as) ? as : 'h2';\n\n return (\n <Title as={level} className={classNames(titleClass, className)} {...rest} />\n );\n};\n\nEmptyStateTitle.displayName = 'EmptyState.Title';\n\n/**\n * A sentence or two under the title, in the color of the text around it.\n *\n * @function\n * @param {EmptyStateDescriptionProps} props - Props for EmptyState.Description.\n * @returns {JSX.Element} The rendered description.\n */\nexport const EmptyStateDescription: React.FC<EmptyStateDescriptionProps> = ({\n className,\n ...props\n}) => {\n const descriptionClass = usePrefixedClassNames('empty-state-description');\n return (\n <Paragraph className={classNames(descriptionClass, className)} {...props} />\n );\n};\n\nEmptyStateDescription.displayName = 'EmptyState.Description';\n\n/**\n * A row of buttons, centered under the text or at the start of the line beside the indicator.\n *\n * @function\n * @param {EmptyStateActionsProps} props - Props for EmptyState.Actions.\n * @returns {JSX.Element} The rendered row of buttons.\n */\nexport const EmptyStateActions: React.FC<EmptyStateActionsProps> = ({\n className,\n ...props\n}) => {\n const actionsClass = usePrefixedClassNames('empty-state-actions');\n return <Buttons className={classNames(actionsClass, className)} {...props} />;\n};\n\nEmptyStateActions.displayName = 'EmptyState.Actions';\n\n/** Whether a shorthand prop was given something to render. */\nconst isGiven = (node: React.ReactNode) =>\n node !== undefined &&\n node !== null &&\n typeof node !== 'boolean' &&\n node !== '';\n\n/**\n * The `EmptyState` component renders the block an app shows where content would be: an empty list, a search with no results, or a first-run screen.\n *\n * It's a column of a picture in a circle, a heading, a line of text and the\n * actions, with one layout whether it's written with the `icon`, `title` and\n * `description` props or with the parts. The children always render as\n * written, after the parts the props render.\n *\n * It has no role and no live region. It arrives already filled and goes away\n * when results come back, so it can't announce a search that matched\n * nothing: keep a `role=\"status\"` region beside the search field for that,\n * in the page the whole time. While the data loads, show a `Skeleton` or a\n * `Loader` instead, so \"No projects yet\" doesn't flash first, and show a\n * load that failed in a `Message` or a `Notification`.\n *\n * @function\n * @param {EmptyStateProps} props - Props for the EmptyState component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the root `<div>`.\n * @returns {JSX.Element} The rendered empty state.\n *\n * @example\n * <EmptyState\n * icon=\"folder-open\"\n * title=\"No projects yet\"\n * description=\"Projects you create or join show up here.\"\n * >\n * <Button color=\"primary\">New project</Button>\n * </EmptyState>\n */\nconst EmptyStateRoot = forwardRef<HTMLDivElement, EmptyStateProps>(\n (\n {\n className,\n icon,\n title,\n titleAs = 'h2',\n description,\n children,\n color,\n variant = 'light',\n size = 'normal',\n align = 'center',\n textColor,\n bgColor,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const rootClass = usePrefixedClassNames('empty-state', {\n [`is-${size}`]: (validEmptyStateSizes as readonly string[]).includes(\n size\n ),\n 'is-left': align === 'left',\n [`is-${color}`]:\n !!color && (validEmptyStateColors as readonly string[]).includes(color),\n 'is-filled': variant === 'filled',\n });\n\n // The props' parts first, each only when it's given, then the children\n // exactly as they were written: nothing here looks at them.\n return (\n <div\n ref={ref}\n className={classNames(rootClass, bulmaHelperClasses, className)}\n {...rest}\n >\n {isGiven(icon) && (\n <EmptyStateIndicator>\n {typeof icon === 'string' ? <Icon name={icon} /> : icon}\n </EmptyStateIndicator>\n )}\n {isGiven(title) && (\n <EmptyStateTitle as={titleAs}>{title}</EmptyStateTitle>\n )}\n {isGiven(description) && (\n <EmptyStateDescription>{description}</EmptyStateDescription>\n )}\n {children}\n </div>\n );\n }\n);\n\nexport const EmptyState = withSubComponents(\n EmptyStateRoot,\n {\n Indicator: EmptyStateIndicator,\n Title: EmptyStateTitle,\n Description: EmptyStateDescription,\n Actions: EmptyStateActions,\n },\n 'EmptyState'\n);\n\nexport default EmptyState;\n"],"names":["_jsx","isGiven","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EmptyState.js","sources":["../../../src/components/EmptyState.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { Buttons, ButtonsProps } from '../elements/Buttons';\nimport { Icon } from '../elements/Icon';\nimport { Paragraph, ParagraphProps } from '../elements/Paragraph';\nimport { Title, TitleProps } from '../elements/Title';\n\nconst validEmptyStateColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n/** The Bulma colors the indicator takes. */\nexport type EmptyStateColor = (typeof validEmptyStateColors)[number];\n\nconst validEmptyStateHeadings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\n/** A title's heading level. It's always a heading, so there's no `p`. */\nexport type EmptyStateHeading = (typeof validEmptyStateHeadings)[number];\n\nconst validEmptyStateSizes = ['small', 'medium', 'large'] as const;\n\n/**\n * Props for the EmptyState component. The helper props, the other attributes\n * and the `ref` land on the root `<div>`. The native `title` attribute isn't\n * one of them, since `title` here is the heading.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root `<div>`.\n */\nexport interface EmptyStateProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'title'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The picture in the indicator's circle. A string is an `Icon` name, drawn\n * from the icon library `ConfigProvider` sets. Anything else (an `<Icon>`\n * with its own `variant` or `library`, an SVG, an `<img>`) renders as it is.\n * It's decorative and hidden from assistive tech, so the title says what\n * it means.\n */\n icon?: React.ReactNode;\n /**\n * The heading, rendered as `EmptyState.Title`. It's always a real heading,\n * at the level `titleAs` sets.\n */\n title?: React.ReactNode;\n /**\n * The heading level for `title`: the level under the heading of the list\n * it stands in for, such as `h3` for a list under an `h2`. Only this sets\n * the level, and the size comes from `size`.\n */\n titleAs?: EmptyStateHeading;\n /** A sentence or two under the title, rendered as `EmptyState.Description`. */\n description?: React.ReactNode;\n /**\n * Rendered as written, after whatever `icon`, `title` and `description`\n * render. One button can go straight in, and it sits centered under the\n * text. Group two or more in `EmptyState.Actions`, or they stack. Without\n * the props, write the parts here in the order they're shown:\n * `EmptyState.Indicator`, `.Title`, `.Description`, then the actions.\n */\n children?: React.ReactNode;\n /**\n * The indicator's color. It colors the circle and its icon, not the text.\n * Without it the circle is neutral, since an empty list isn't a status.\n */\n color?: EmptyStateColor;\n /**\n * `light` is a soft tint of `color` behind the icon in the color. `filled`\n * is the color itself, with the icon in its invert.\n */\n variant?: 'light' | 'filled';\n /** Sizes the indicator, the title, the description and the spacing together. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /**\n * `center` stacks everything in a centered column. `left` puts the\n * indicator beside the text, at the start of the line, so on the right in\n * a right-to-left page, and keeps the block at least as tall as the circle\n * whatever block padding is in effect. Without an indicator, it only puts\n * the text at the start of the line. In `left`, the padding at the start\n * of the line is what makes room for the indicator, so pad it with `py`\n * rather than `p` or `px`.\n */\n align?: 'center' | 'left';\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/** Props for EmptyState.Indicator, the circle the picture sits in. */\nexport interface EmptyStateIndicatorProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The picture: an `Icon`, an SVG or an `<img>`. The indicator is hidden\n * from assistive tech, an `Icon` with an `ariaLabel` included, so anything\n * it means goes in the title or the description.\n */\n children?: React.ReactNode;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/**\n * Props for EmptyState.Title. It renders `Title` with `as` and never `size`,\n * so the level is `as` alone and the size comes from the EmptyState.\n */\nexport interface EmptyStateTitleProps extends Omit<\n TitleProps,\n 'as' | 'size' | 'isSpaced'\n> {\n /**\n * The heading level: the level under the heading of the list the empty\n * state stands in for.\n */\n as?: EmptyStateHeading;\n}\n\n/** Props for EmptyState.Description, a `<p>` under the title. */\nexport type EmptyStateDescriptionProps = ParagraphProps;\n\n/**\n * Props for EmptyState.Actions, the row of buttons. It renders `Buttons`,\n * and the EmptyState aligns it, so `isCentered` and `isRight` are left out.\n */\nexport type EmptyStateActionsProps = Omit<\n ButtonsProps,\n 'isCentered' | 'isRight'\n>;\n\n/**\n * The circle the picture sits in, hidden from assistive tech whatever is in it.\n *\n * @function\n * @param {EmptyStateIndicatorProps} props - Props for EmptyState.Indicator.\n * @returns {JSX.Element} The rendered indicator.\n */\nexport const EmptyStateIndicator: React.FC<EmptyStateIndicatorProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const indicatorClass = usePrefixedClassNames('empty-state-indicator');\n\n // Hidden after the rest of the props, so nothing passed in can expose the\n // picture: the title says what it means.\n return (\n <div\n className={classNames(indicatorClass, bulmaHelperClasses, className)}\n {...rest}\n aria-hidden=\"true\"\n >\n {children}\n </div>\n );\n};\n\nEmptyStateIndicator.displayName = 'EmptyState.Indicator';\n\n/**\n * The heading, a Bulma `Title` at the level `as` sets, `h2` by default, and at the EmptyState's size.\n *\n * @function\n * @param {EmptyStateTitleProps} props - Props for EmptyState.Title.\n * @returns {JSX.Element} The rendered heading.\n */\nexport const EmptyStateTitle: React.FC<EmptyStateTitleProps> = ({\n as = 'h2',\n className,\n ...props\n}) => {\n // `size` isn't in the type, but on `Title` it picks the tag, so it's kept\n // off even when it's passed anyway. The level is `as` alone.\n const { size: _size, ...rest } = props as typeof props & { size?: unknown };\n const titleClass = usePrefixedClassNames('empty-state-title');\n const level = validEmptyStateHeadings.includes(as) ? as : 'h2';\n\n return (\n <Title as={level} className={classNames(titleClass, className)} {...rest} />\n );\n};\n\nEmptyStateTitle.displayName = 'EmptyState.Title';\n\n/**\n * A sentence or two under the title, in the color of the text around it.\n *\n * @function\n * @param {EmptyStateDescriptionProps} props - Props for EmptyState.Description.\n * @returns {JSX.Element} The rendered description.\n */\nexport const EmptyStateDescription: React.FC<EmptyStateDescriptionProps> = ({\n className,\n ...props\n}) => {\n const descriptionClass = usePrefixedClassNames('empty-state-description');\n return (\n <Paragraph className={classNames(descriptionClass, className)} {...props} />\n );\n};\n\nEmptyStateDescription.displayName = 'EmptyState.Description';\n\n/**\n * A row of buttons, centered under the text or at the start of the line beside the indicator.\n *\n * @function\n * @param {EmptyStateActionsProps} props - Props for EmptyState.Actions.\n * @returns {JSX.Element} The rendered row of buttons.\n */\nexport const EmptyStateActions: React.FC<EmptyStateActionsProps> = ({\n className,\n ...props\n}) => {\n const actionsClass = usePrefixedClassNames('empty-state-actions');\n return <Buttons className={classNames(actionsClass, className)} {...props} />;\n};\n\nEmptyStateActions.displayName = 'EmptyState.Actions';\n\n/** Whether a shorthand prop was given something to render. */\nconst isGiven = (node: React.ReactNode) =>\n node !== undefined &&\n node !== null &&\n typeof node !== 'boolean' &&\n node !== '';\n\n/**\n * The `EmptyState` component renders the block an app shows where content would be: an empty list, a search with no results, or a first-run screen.\n *\n * It's a column of a picture in a circle, a heading, a line of text and the\n * actions, with one layout whether it's written with the `icon`, `title` and\n * `description` props or with the parts. The children always render as\n * written, after the parts the props render.\n *\n * It has no role and no live region. It arrives already filled and goes away\n * when results come back, so it can't announce a search that matched\n * nothing: keep a `role=\"status\"` region beside the search field for that,\n * in the page the whole time. While the data loads, show a `Skeleton` or a\n * `Loader` instead, so \"No projects yet\" doesn't flash first, and show a\n * load that failed in a `Message` or a `Notification`.\n *\n * @function\n * @param {EmptyStateProps} props - Props for the EmptyState component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the root `<div>`.\n * @returns {JSX.Element} The rendered empty state.\n *\n * @example\n * <EmptyState\n * icon=\"folder-open\"\n * title=\"No projects yet\"\n * description=\"Projects you create or join show up here.\"\n * >\n * <Button color=\"primary\">New project</Button>\n * </EmptyState>\n */\nconst EmptyStateRoot = forwardRef<HTMLDivElement, EmptyStateProps>(\n (\n {\n className,\n icon,\n title,\n titleAs = 'h2',\n description,\n children,\n color,\n variant = 'light',\n size = 'normal',\n align = 'center',\n textColor,\n bgColor,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const rootClass = usePrefixedClassNames('empty-state', {\n [`is-${size}`]: (validEmptyStateSizes as readonly string[]).includes(\n size\n ),\n 'is-left': align === 'left',\n [`is-${color}`]:\n !!color && (validEmptyStateColors as readonly string[]).includes(color),\n 'is-filled': variant === 'filled',\n });\n\n // The props' parts first, each only when it's given, then the children\n // exactly as they were written: nothing here looks at them.\n return (\n <div\n ref={ref}\n className={classNames(rootClass, bulmaHelperClasses, className)}\n {...rest}\n >\n {isGiven(icon) && (\n <EmptyStateIndicator>\n {typeof icon === 'string' ? <Icon name={icon} /> : icon}\n </EmptyStateIndicator>\n )}\n {isGiven(title) && (\n <EmptyStateTitle as={titleAs}>{title}</EmptyStateTitle>\n )}\n {isGiven(description) && (\n <EmptyStateDescription>{description}</EmptyStateDescription>\n )}\n {children}\n </div>\n );\n }\n);\n\nexport const EmptyState = withSubComponents(\n EmptyStateRoot,\n {\n Indicator: EmptyStateIndicator,\n Title: EmptyStateTitle,\n Description: EmptyStateDescription,\n Actions: EmptyStateActions,\n },\n 'EmptyState'\n);\n\nexport default EmptyState;\n"],"names":["_jsx","isGiven","_jsxs"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
4
|
import { useRef, useId, useState, useCallback, useMemo, useEffect, cloneElement } from 'react';
|
|
4
5
|
import { classNames, usePrefixedClassNames } from '../helpers/classNames.js';
|