@allxsmith/bestax-bulma 5.26.6 → 5.27.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/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/columns/Column.js +48 -0
- package/dist/esm/columns/Column.js.map +1 -0
- package/dist/esm/columns/Columns.js +53 -0
- package/dist/esm/columns/Columns.js.map +1 -0
- package/dist/esm/components/Avatar.js +299 -0
- package/dist/esm/components/Avatar.js.map +1 -0
- package/dist/esm/components/Avatars.js +81 -0
- package/dist/esm/components/Avatars.js.map +1 -0
- package/dist/esm/components/Badge.js +105 -0
- package/dist/esm/components/Badge.js.map +1 -0
- package/dist/esm/components/Breadcrumb.js +36 -0
- package/dist/esm/components/Breadcrumb.js.map +1 -0
- package/dist/esm/components/Card.js +252 -0
- package/dist/esm/components/Card.js.map +1 -0
- package/dist/esm/components/Carousel.js +351 -0
- package/dist/esm/components/Carousel.js.map +1 -0
- package/dist/esm/components/Collapse.js +193 -0
- package/dist/esm/components/Collapse.js.map +1 -0
- package/dist/esm/components/Collapses.js +99 -0
- package/dist/esm/components/Collapses.js.map +1 -0
- package/dist/esm/components/Dialog.js +230 -0
- package/dist/esm/components/Dialog.js.map +1 -0
- package/dist/esm/components/Dropdown.js +362 -0
- package/dist/esm/components/Dropdown.js.map +1 -0
- package/dist/esm/components/Loading.js +87 -0
- package/dist/esm/components/Loading.js.map +1 -0
- package/dist/esm/components/Menu.js +117 -0
- package/dist/esm/components/Menu.js.map +1 -0
- package/dist/esm/components/Message.js +56 -0
- package/dist/esm/components/Message.js.map +1 -0
- package/dist/esm/components/Modal.js +354 -0
- package/dist/esm/components/Modal.js.map +1 -0
- package/dist/esm/components/Navbar.js +287 -0
- package/dist/esm/components/Navbar.js.map +1 -0
- package/dist/esm/components/Pagination.js +191 -0
- package/dist/esm/components/Pagination.js.map +1 -0
- package/dist/esm/components/Panel.js +100 -0
- package/dist/esm/components/Panel.js.map +1 -0
- package/dist/esm/components/Popover.js +298 -0
- package/dist/esm/components/Popover.js.map +1 -0
- package/dist/esm/components/Reveal.js +157 -0
- package/dist/esm/components/Reveal.js.map +1 -0
- package/dist/esm/components/Sidebar.js +209 -0
- package/dist/esm/components/Sidebar.js.map +1 -0
- package/dist/esm/components/Steps.js +128 -0
- package/dist/esm/components/Steps.js.map +1 -0
- package/dist/esm/components/Tabs.js +335 -0
- package/dist/esm/components/Tabs.js.map +1 -0
- package/dist/esm/components/Toast.js +322 -0
- package/dist/esm/components/Toast.js.map +1 -0
- package/dist/esm/components/Tooltip.js +202 -0
- package/dist/esm/components/Tooltip.js.map +1 -0
- package/dist/esm/components/collapsesContext.js +12 -0
- package/dist/esm/components/collapsesContext.js.map +1 -0
- package/dist/esm/elements/Block.js +29 -0
- package/dist/esm/elements/Block.js.map +1 -0
- package/dist/esm/elements/Box.js +32 -0
- package/dist/esm/elements/Box.js.map +1 -0
- package/dist/esm/elements/Button.js +139 -0
- package/dist/esm/elements/Button.js.map +1 -0
- package/dist/esm/elements/Buttons.js +42 -0
- package/dist/esm/elements/Buttons.js.map +1 -0
- package/dist/esm/elements/Code.js +25 -0
- package/dist/esm/elements/Code.js.map +1 -0
- package/dist/esm/elements/Content.js +33 -0
- package/dist/esm/elements/Content.js.map +1 -0
- package/dist/esm/elements/Delete.js +35 -0
- package/dist/esm/elements/Delete.js.map +1 -0
- package/dist/esm/elements/Divider.js +27 -0
- package/dist/esm/elements/Divider.js.map +1 -0
- package/dist/esm/elements/Emphasis.js +25 -0
- package/dist/esm/elements/Emphasis.js.map +1 -0
- package/dist/esm/elements/Figure.js +58 -0
- package/dist/esm/elements/Figure.js.map +1 -0
- package/dist/esm/elements/Icon.js +256 -0
- package/dist/esm/elements/Icon.js.map +1 -0
- package/dist/esm/elements/IconText.js +36 -0
- package/dist/esm/elements/IconText.js.map +1 -0
- package/dist/esm/elements/Image.js +46 -0
- package/dist/esm/elements/Image.js.map +1 -0
- package/dist/esm/elements/Link.js +36 -0
- package/dist/esm/elements/Link.js.map +1 -0
- package/dist/esm/elements/LinkButton.js +37 -0
- package/dist/esm/elements/LinkButton.js.map +1 -0
- package/dist/esm/elements/ListItem.js +28 -0
- package/dist/esm/elements/ListItem.js.map +1 -0
- package/dist/esm/elements/Loader.js +37 -0
- package/dist/esm/elements/Loader.js.map +1 -0
- package/dist/esm/elements/Notification.js +316 -0
- package/dist/esm/elements/Notification.js.map +1 -0
- package/dist/esm/elements/OrderedList.js +31 -0
- package/dist/esm/elements/OrderedList.js.map +1 -0
- package/dist/esm/elements/Paragraph.js +28 -0
- package/dist/esm/elements/Paragraph.js.map +1 -0
- package/dist/esm/elements/Pre.js +25 -0
- package/dist/esm/elements/Pre.js.map +1 -0
- package/dist/esm/elements/Progress.js +33 -0
- package/dist/esm/elements/Progress.js.map +1 -0
- package/dist/esm/elements/Skeleton.js +30 -0
- package/dist/esm/elements/Skeleton.js.map +1 -0
- package/dist/esm/elements/Span.js +28 -0
- package/dist/esm/elements/Span.js.map +1 -0
- package/dist/esm/elements/Strong.js +25 -0
- package/dist/esm/elements/Strong.js.map +1 -0
- package/dist/esm/elements/SubTitle.js +51 -0
- package/dist/esm/elements/SubTitle.js.map +1 -0
- package/dist/esm/elements/Table.js +51 -0
- package/dist/esm/elements/Table.js.map +1 -0
- package/dist/esm/elements/Tag.js +49 -0
- package/dist/esm/elements/Tag.js.map +1 -0
- package/dist/esm/elements/Tags.js +34 -0
- package/dist/esm/elements/Tags.js.map +1 -0
- package/dist/esm/elements/Tbody.js +26 -0
- package/dist/esm/elements/Tbody.js.map +1 -0
- package/dist/esm/elements/Td.js +61 -0
- package/dist/esm/elements/Td.js.map +1 -0
- package/dist/esm/elements/Tfoot.js +26 -0
- package/dist/esm/elements/Tfoot.js.map +1 -0
- package/dist/esm/elements/Th.js +34 -0
- package/dist/esm/elements/Th.js.map +1 -0
- package/dist/esm/elements/Thead.js +26 -0
- package/dist/esm/elements/Thead.js.map +1 -0
- package/dist/esm/elements/Title.js +44 -0
- package/dist/esm/elements/Title.js.map +1 -0
- package/dist/esm/elements/Tr.js +31 -0
- package/dist/esm/elements/Tr.js.map +1 -0
- package/dist/esm/elements/UnorderedList.js +31 -0
- package/dist/esm/elements/UnorderedList.js.map +1 -0
- package/dist/esm/elements/iconProps.js +49 -0
- package/dist/esm/elements/iconProps.js.map +1 -0
- package/dist/esm/form/Autocomplete.js +279 -0
- package/dist/esm/form/Autocomplete.js.map +1 -0
- package/dist/esm/form/Checkbox.js +111 -0
- package/dist/esm/form/Checkbox.js.map +1 -0
- package/dist/esm/form/Checkboxes.js +89 -0
- package/dist/esm/form/Checkboxes.js.map +1 -0
- package/dist/esm/form/Control.js +79 -0
- package/dist/esm/form/Control.js.map +1 -0
- package/dist/esm/form/DateInput.js +87 -0
- package/dist/esm/form/DateInput.js.map +1 -0
- package/dist/esm/form/DateInputBase.js +263 -0
- package/dist/esm/form/DateInputBase.js.map +1 -0
- package/dist/esm/form/DateRangeInput.js +76 -0
- package/dist/esm/form/DateRangeInput.js.map +1 -0
- package/dist/esm/form/DateRangeInputBase.js +301 -0
- package/dist/esm/form/DateRangeInputBase.js.map +1 -0
- package/dist/esm/form/DateTimeInput.js +87 -0
- package/dist/esm/form/DateTimeInput.js.map +1 -0
- package/dist/esm/form/DateTimeInputBase.js +333 -0
- package/dist/esm/form/DateTimeInputBase.js.map +1 -0
- package/dist/esm/form/Field.js +153 -0
- package/dist/esm/form/Field.js.map +1 -0
- package/dist/esm/form/File.js +109 -0
- package/dist/esm/form/File.js.map +1 -0
- package/dist/esm/form/FormContext.js +170 -0
- package/dist/esm/form/FormContext.js.map +1 -0
- package/dist/esm/form/Input.js +88 -0
- package/dist/esm/form/Input.js.map +1 -0
- package/dist/esm/form/InputBase.js +40 -0
- package/dist/esm/form/InputBase.js.map +1 -0
- package/dist/esm/form/Numberinput.js +199 -0
- package/dist/esm/form/Numberinput.js.map +1 -0
- package/dist/esm/form/Radio.js +108 -0
- package/dist/esm/form/Radio.js.map +1 -0
- package/dist/esm/form/Radios.js +91 -0
- package/dist/esm/form/Radios.js.map +1 -0
- package/dist/esm/form/Rate.js +279 -0
- package/dist/esm/form/Rate.js.map +1 -0
- package/dist/esm/form/Select.js +81 -0
- package/dist/esm/form/Select.js.map +1 -0
- package/dist/esm/form/SelectBase.js +54 -0
- package/dist/esm/form/SelectBase.js.map +1 -0
- package/dist/esm/form/Slider.js +459 -0
- package/dist/esm/form/Slider.js.map +1 -0
- package/dist/esm/form/Switch.js +96 -0
- package/dist/esm/form/Switch.js.map +1 -0
- package/dist/esm/form/Taginput.js +352 -0
- package/dist/esm/form/Taginput.js.map +1 -0
- package/dist/esm/form/TextArea.js +77 -0
- package/dist/esm/form/TextArea.js.map +1 -0
- package/dist/esm/form/TextAreaBase.js +45 -0
- package/dist/esm/form/TextAreaBase.js.map +1 -0
- package/dist/esm/form/TimeInput.js +83 -0
- package/dist/esm/form/TimeInput.js.map +1 -0
- package/dist/esm/form/TimeInputBase.js +246 -0
- package/dist/esm/form/TimeInputBase.js.map +1 -0
- package/dist/esm/form/_pickerInternals/Calendar.js +760 -0
- package/dist/esm/form/_pickerInternals/Calendar.js.map +1 -0
- package/dist/esm/form/_pickerInternals/PickerPopover.js +95 -0
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -0
- package/dist/esm/form/_pickerInternals/TimeWheels.js +721 -0
- package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -0
- package/dist/esm/form/_pickerInternals/audioTick.js +109 -0
- package/dist/esm/form/_pickerInternals/audioTick.js.map +1 -0
- package/dist/esm/form/_pickerInternals/dateUtils.js +267 -0
- package/dist/esm/form/_pickerInternals/dateUtils.js.map +1 -0
- package/dist/esm/form/_pickerInternals/formatters.js +322 -0
- package/dist/esm/form/_pickerInternals/formatters.js.map +1 -0
- package/dist/esm/form/_pickerInternals/haptics.js +38 -0
- package/dist/esm/form/_pickerInternals/haptics.js.map +1 -0
- package/dist/esm/form/_pickerInternals/nativeInputSupport.js +25 -0
- package/dist/esm/form/_pickerInternals/nativeInputSupport.js.map +1 -0
- package/dist/esm/form/_pickerInternals/pickerTypes.js +50 -0
- package/dist/esm/form/_pickerInternals/pickerTypes.js.map +1 -0
- package/dist/esm/form/_pickerInternals/segmentMap.js +315 -0
- package/dist/esm/form/_pickerInternals/segmentMap.js.map +1 -0
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js +49 -0
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js.map +1 -0
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js +427 -0
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js.map +1 -0
- package/dist/esm/form/controlLoading.js +18 -0
- package/dist/esm/form/controlLoading.js.map +1 -0
- package/dist/esm/form/useAutoLabelId.js +54 -0
- package/dist/esm/form/useAutoLabelId.js.map +1 -0
- package/dist/esm/grid/Cell.js +35 -0
- package/dist/esm/grid/Cell.js.map +1 -0
- package/dist/esm/grid/Grid.js +51 -0
- package/dist/esm/grid/Grid.js.map +1 -0
- package/dist/esm/helpers/ClientOnly.js +33 -0
- package/dist/esm/helpers/ClientOnly.js.map +1 -0
- package/dist/esm/helpers/Config.js +60 -0
- package/dist/esm/helpers/Config.js.map +1 -0
- package/dist/esm/helpers/Theme.js +947 -0
- package/dist/esm/helpers/Theme.js.map +1 -0
- package/dist/esm/helpers/anchorAttrs.js +72 -0
- package/dist/esm/helpers/anchorAttrs.js.map +1 -0
- package/dist/esm/helpers/bulmaClassHelpers.js +415 -0
- package/dist/esm/helpers/bulmaClassHelpers.js.map +1 -0
- package/dist/esm/helpers/buttonType.js +24 -0
- package/dist/esm/helpers/buttonType.js.map +1 -0
- package/dist/esm/helpers/classNames.js +137 -0
- package/dist/esm/helpers/classNames.js.map +1 -0
- package/dist/esm/helpers/colorDeprecations.js +50 -0
- package/dist/esm/helpers/colorDeprecations.js.map +1 -0
- package/dist/esm/helpers/devWarnings.js +27 -0
- package/dist/esm/helpers/devWarnings.js.map +1 -0
- package/dist/esm/helpers/inertProps.js +27 -0
- package/dist/esm/helpers/inertProps.js.map +1 -0
- package/dist/esm/helpers/mergeBulmaStyles.js +20 -0
- package/dist/esm/helpers/mergeBulmaStyles.js.map +1 -0
- package/dist/esm/helpers/polymorphic.js +18 -0
- package/dist/esm/helpers/polymorphic.js.map +1 -0
- package/dist/esm/helpers/portal.js +76 -0
- package/dist/esm/helpers/portal.js.map +1 -0
- package/dist/esm/helpers/positionStacks.js +45 -0
- package/dist/esm/helpers/positionStacks.js.map +1 -0
- package/dist/esm/helpers/scrollLock.js +38 -0
- package/dist/esm/helpers/scrollLock.js.map +1 -0
- package/dist/esm/helpers/shadowDom.js +71 -0
- package/dist/esm/helpers/shadowDom.js.map +1 -0
- package/dist/esm/helpers/statusRegion.js +282 -0
- package/dist/esm/helpers/statusRegion.js.map +1 -0
- package/dist/esm/helpers/useAnchoredPosition.js +86 -0
- package/dist/esm/helpers/useAnchoredPosition.js.map +1 -0
- package/dist/esm/helpers/useBulmaClasses.js +158 -0
- package/dist/esm/helpers/useBulmaClasses.js.map +1 -0
- package/dist/esm/helpers/useClientLayoutEffect.js +13 -0
- package/dist/esm/helpers/useClientLayoutEffect.js.map +1 -0
- package/dist/esm/helpers/useColorClasses.js +84 -0
- package/dist/esm/helpers/useColorClasses.js.map +1 -0
- package/dist/esm/helpers/useFlexboxClasses.js +92 -0
- package/dist/esm/helpers/useFlexboxClasses.js.map +1 -0
- package/dist/esm/helpers/useFocusTrap.js +470 -0
- package/dist/esm/helpers/useFocusTrap.js.map +1 -0
- package/dist/esm/helpers/useIsHydrated.js +31 -0
- package/dist/esm/helpers/useIsHydrated.js.map +1 -0
- package/dist/esm/helpers/useOtherClasses.js +115 -0
- package/dist/esm/helpers/useOtherClasses.js.map +1 -0
- package/dist/esm/helpers/useSpacingClasses.js +82 -0
- package/dist/esm/helpers/useSpacingClasses.js.map +1 -0
- package/dist/esm/helpers/useTypographyClasses.js +93 -0
- package/dist/esm/helpers/useTypographyClasses.js.map +1 -0
- package/dist/esm/helpers/useVisibilityClasses.js +134 -0
- package/dist/esm/helpers/useVisibilityClasses.js.map +1 -0
- package/dist/esm/helpers/withSubComponents.js +24 -0
- package/dist/esm/helpers/withSubComponents.js.map +1 -0
- package/dist/esm/layout/Container.js +48 -0
- package/dist/esm/layout/Container.js.map +1 -0
- package/dist/esm/layout/Footer.js +33 -0
- package/dist/esm/layout/Footer.js.map +1 -0
- package/dist/esm/layout/Hero.js +90 -0
- package/dist/esm/layout/Hero.js.map +1 -0
- package/dist/esm/layout/Level.js +110 -0
- package/dist/esm/layout/Level.js.map +1 -0
- package/dist/esm/layout/Media.js +86 -0
- package/dist/esm/layout/Media.js.map +1 -0
- package/dist/esm/layout/Section.js +30 -0
- package/dist/esm/layout/Section.js.map +1 -0
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +821 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +115 -16845
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Tabs.d.ts +25 -3
- package/dist/types/elements/Icon.d.ts +10 -7
- package/dist/types/form/DateInputBase.d.ts +8 -6
- package/dist/types/form/DateRangeInput.d.ts +91 -0
- package/dist/types/form/DateRangeInputBase.d.ts +172 -0
- package/dist/types/form/DateTimeInputBase.d.ts +10 -6
- package/dist/types/form/File.d.ts +18 -5
- package/dist/types/form/FormContext.d.ts +11 -0
- package/dist/types/form/TimeInputBase.d.ts +1 -1
- package/dist/types/form/_pickerInternals/PickerPopover.d.ts +1 -0
- package/dist/types/form/_pickerInternals/dateUtils.d.ts +7 -0
- package/dist/types/form/_pickerInternals/formatters.d.ts +14 -0
- package/dist/types/form/_pickerInternals/pickerTypes.d.ts +13 -0
- package/dist/types/form/_pickerInternals/useSegmentedEntry.d.ts +12 -3
- package/dist/types/index.d.ts +4 -0
- package/dist/types-cjs/components/Tabs.d.ts +25 -3
- package/dist/types-cjs/elements/Icon.d.ts +10 -7
- package/dist/types-cjs/form/DateInputBase.d.ts +8 -6
- package/dist/types-cjs/form/DateRangeInput.d.ts +91 -0
- package/dist/types-cjs/form/DateRangeInputBase.d.ts +172 -0
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +10 -6
- package/dist/types-cjs/form/File.d.ts +18 -5
- package/dist/types-cjs/form/FormContext.d.ts +11 -0
- package/dist/types-cjs/form/TimeInputBase.d.ts +1 -1
- package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +1 -0
- package/dist/types-cjs/form/_pickerInternals/dateUtils.d.ts +7 -0
- package/dist/types-cjs/form/_pickerInternals/formatters.d.ts +14 -0
- package/dist/types-cjs/form/_pickerInternals/pickerTypes.d.ts +13 -0
- package/dist/types-cjs/form/_pickerInternals/useSegmentedEntry.d.ts +12 -3
- package/dist/types-cjs/index.d.ts +4 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/components/_tabs.scss +44 -0
- package/src/scss/form/_dateinput.scss +87 -8
- package/src/scss/form/_daterangeinput.scss +63 -0
- package/src/scss/form/_datetimeinput.scss +7 -2
- package/src/scss/form/_file.scss +37 -0
- package/src/scss/form/_index.scss +2 -0
- package/src/scss/form/_picker-popover.scss +1 -4
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { useSyncExternalStore, useMemo, useRef, useCallback, useState, useEffect } from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
6
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
7
|
+
import { warnUnstyledColor } from '../helpers/colorDeprecations.js';
|
|
8
|
+
import { groupIntoPositionStacks } from '../helpers/positionStacks.js';
|
|
9
|
+
import { useIsHydrated } from '../helpers/useIsHydrated.js';
|
|
10
|
+
import { spokenText, StatusRegion } from '../helpers/statusRegion.js';
|
|
11
|
+
import { validColors } from '../helpers/bulmaClassHelpers.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The `Notification` component is a Bulma-styled alert/message area for providing feedback, warnings, or information to users.
|
|
15
|
+
*
|
|
16
|
+
* @function
|
|
17
|
+
* @param {NotificationProps} props - Props for the Notification component.
|
|
18
|
+
* @returns {JSX.Element} The rendered notification element.
|
|
19
|
+
* @see {@link https://bulma.io/documentation/elements/notification/ | Bulma Notification documentation}
|
|
20
|
+
*/
|
|
21
|
+
const Notification = ({ className, color, textColor, isLight, hasDelete, onDelete, children, ...props }) => {
|
|
22
|
+
warnUnstyledColor('Notification', color);
|
|
23
|
+
/**
|
|
24
|
+
* Generates Bulma helper classes and separates out remaining props.
|
|
25
|
+
*/
|
|
26
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
27
|
+
color: textColor,
|
|
28
|
+
...props,
|
|
29
|
+
});
|
|
30
|
+
const bulmaClasses = usePrefixedClassNames('notification', {
|
|
31
|
+
[`is-${color}`]: color && validColors.includes(color),
|
|
32
|
+
'is-light': isLight,
|
|
33
|
+
});
|
|
34
|
+
const deleteClasses = usePrefixedClassNames('delete');
|
|
35
|
+
const notificationClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
36
|
+
return (jsxs("div", { className: notificationClasses, ...rest, children: [hasDelete && (jsx("button", { type: "button", className: deleteClasses, onClick: onDelete, "aria-label": "Close notification" })), children] }));
|
|
37
|
+
};
|
|
38
|
+
let notificationId = 0;
|
|
39
|
+
const notificationListeners = new Set();
|
|
40
|
+
let notifications = [];
|
|
41
|
+
// Queue support
|
|
42
|
+
let queuedNotifications = [];
|
|
43
|
+
let currentQueuedNotification = null;
|
|
44
|
+
// The server has nowhere to portal a notification to, and its copy of this
|
|
45
|
+
// module is shared by every request, so server rendering reads an empty list.
|
|
46
|
+
// Hydration reads it too, which keeps the first client render matching the
|
|
47
|
+
// server's.
|
|
48
|
+
const noNotifications = [];
|
|
49
|
+
const getServerNotifications = () => noNotifications;
|
|
50
|
+
// What a container shows right now: the stacked notifications, then the queued
|
|
51
|
+
// one on screen. NotificationContainer renders from this rather than from
|
|
52
|
+
// updates alone, so notifications raised before it mounted still appear. It is
|
|
53
|
+
// replaced rather than mutated, and only when listeners are notified, because
|
|
54
|
+
// useSyncExternalStore needs the same array back between changes. An empty
|
|
55
|
+
// list is `noNotifications` itself, so an empty store reads the same snapshot
|
|
56
|
+
// on the client as on the server, and a notify that leaves nothing showing
|
|
57
|
+
// when nothing was showing doesn't render the container again.
|
|
58
|
+
let visibleNotifications = noNotifications;
|
|
59
|
+
const getVisibleNotifications = () => visibleNotifications;
|
|
60
|
+
const notifyNotificationListeners = () => {
|
|
61
|
+
const allVisible = [...notifications];
|
|
62
|
+
if (currentQueuedNotification) {
|
|
63
|
+
allVisible.push(currentQueuedNotification);
|
|
64
|
+
}
|
|
65
|
+
visibleNotifications = allVisible.length > 0 ? allVisible : noNotifications;
|
|
66
|
+
notificationListeners.forEach(listener => listener([...allVisible]));
|
|
67
|
+
};
|
|
68
|
+
const processQueuedNotification = () => {
|
|
69
|
+
if (currentQueuedNotification || queuedNotifications.length === 0)
|
|
70
|
+
return;
|
|
71
|
+
currentQueuedNotification = queuedNotifications.shift();
|
|
72
|
+
notifyNotificationListeners();
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Programmatic notification API for showing, closing, and managing notifications.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* notification.success('File saved successfully');
|
|
79
|
+
* notification.danger('Something went wrong', { duration: 5000 });
|
|
80
|
+
*/
|
|
81
|
+
const notification = {
|
|
82
|
+
/**
|
|
83
|
+
* Show a notification with the given options.
|
|
84
|
+
* @param {NotificationOptions} options - Notification configuration.
|
|
85
|
+
* @returns {string} The unique ID of the created notification.
|
|
86
|
+
*/
|
|
87
|
+
show: (options) => {
|
|
88
|
+
const id = `notification-${++notificationId}`;
|
|
89
|
+
const instance = { id, options };
|
|
90
|
+
if (options.queue) {
|
|
91
|
+
queuedNotifications.push(instance);
|
|
92
|
+
processQueuedNotification();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
notifications.push(instance);
|
|
96
|
+
notifyNotificationListeners();
|
|
97
|
+
}
|
|
98
|
+
return id;
|
|
99
|
+
},
|
|
100
|
+
/**
|
|
101
|
+
* Show a success notification.
|
|
102
|
+
* @param {string|React.ReactNode} message - The message to display.
|
|
103
|
+
* @param {Partial<NotificationOptions>} [options] - Additional options.
|
|
104
|
+
* @returns {string} The notification ID.
|
|
105
|
+
*/
|
|
106
|
+
success: (message, options) => {
|
|
107
|
+
return notification.show({ message, color: 'success', ...options });
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Show a danger notification.
|
|
111
|
+
* @param {string|React.ReactNode} message - The message to display.
|
|
112
|
+
* @param {Partial<NotificationOptions>} [options] - Additional options.
|
|
113
|
+
* @returns {string} The notification ID.
|
|
114
|
+
*/
|
|
115
|
+
danger: (message, options) => {
|
|
116
|
+
return notification.show({ message, color: 'danger', ...options });
|
|
117
|
+
},
|
|
118
|
+
/**
|
|
119
|
+
* Show a warning notification.
|
|
120
|
+
* @param {string|React.ReactNode} message - The message to display.
|
|
121
|
+
* @param {Partial<NotificationOptions>} [options] - Additional options.
|
|
122
|
+
* @returns {string} The notification ID.
|
|
123
|
+
*/
|
|
124
|
+
warning: (message, options) => {
|
|
125
|
+
return notification.show({ message, color: 'warning', ...options });
|
|
126
|
+
},
|
|
127
|
+
/**
|
|
128
|
+
* Show an info notification.
|
|
129
|
+
* @param {string|React.ReactNode} message - The message to display.
|
|
130
|
+
* @param {Partial<NotificationOptions>} [options] - Additional options.
|
|
131
|
+
* @returns {string} The notification ID.
|
|
132
|
+
*/
|
|
133
|
+
info: (message, options) => {
|
|
134
|
+
return notification.show({ message, color: 'info', ...options });
|
|
135
|
+
},
|
|
136
|
+
/**
|
|
137
|
+
* Close a specific notification by ID.
|
|
138
|
+
* @param {string} id - The notification ID to close.
|
|
139
|
+
*/
|
|
140
|
+
close: (id) => {
|
|
141
|
+
if (currentQueuedNotification && currentQueuedNotification.id === id) {
|
|
142
|
+
currentQueuedNotification = null;
|
|
143
|
+
processQueuedNotification();
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
queuedNotifications = queuedNotifications.filter(n => n.id !== id);
|
|
147
|
+
notifications = notifications.filter(n => n.id !== id);
|
|
148
|
+
}
|
|
149
|
+
notifyNotificationListeners();
|
|
150
|
+
},
|
|
151
|
+
/** Close all notifications and clear the queue. */
|
|
152
|
+
closeAll: () => {
|
|
153
|
+
notifications = [];
|
|
154
|
+
queuedNotifications = [];
|
|
155
|
+
currentQueuedNotification = null;
|
|
156
|
+
notifyNotificationListeners();
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* Subscribe to notification state changes.
|
|
160
|
+
* @param {(items: NotificationInstance[]) => void} listener - Callback invoked on changes.
|
|
161
|
+
* @returns {() => void} Unsubscribe function.
|
|
162
|
+
*/
|
|
163
|
+
subscribe: (listener) => {
|
|
164
|
+
notificationListeners.add(listener);
|
|
165
|
+
return () => notificationListeners.delete(listener);
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Whether a notification of this color announces itself as an alert, rather
|
|
170
|
+
* than politely through NotificationContainer's status region.
|
|
171
|
+
*
|
|
172
|
+
* @function isUrgentColor
|
|
173
|
+
* @param {NotificationOptions['color']} color - The notification's color.
|
|
174
|
+
* @returns {boolean} True for `danger` and `warning`.
|
|
175
|
+
*/
|
|
176
|
+
const isUrgentColor = (color) => color === 'danger' || color === 'warning';
|
|
177
|
+
/**
|
|
178
|
+
* Single auto-dismissing notification item used by NotificationContainer.
|
|
179
|
+
*
|
|
180
|
+
* @function
|
|
181
|
+
* @param {{ instance: NotificationInstance; onClose: (id: string) => void; registerMessage: (id: string, node: HTMLElement | null) => void }} props - Component props.
|
|
182
|
+
* @returns {JSX.Element} The rendered notification item.
|
|
183
|
+
*/
|
|
184
|
+
const NotificationItem = ({ instance, onClose, registerMessage }) => {
|
|
185
|
+
const { message, color, isLight, duration = 3000, hasDelete = true, indefinite = false, pauseOnHover = true, } = instance.options;
|
|
186
|
+
const [isPaused, setIsPaused] = useState(false);
|
|
187
|
+
const urgent = isUrgentColor(color);
|
|
188
|
+
const handleClose = useCallback(() => {
|
|
189
|
+
onClose(instance.id);
|
|
190
|
+
}, [onClose, instance.id]);
|
|
191
|
+
const messageRef = useCallback((node) => {
|
|
192
|
+
registerMessage(instance.id, node);
|
|
193
|
+
}, [registerMessage, instance.id]);
|
|
194
|
+
// Auto-close timer
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
if (indefinite || duration === 0 || isPaused)
|
|
197
|
+
return undefined;
|
|
198
|
+
const timer = setTimeout(handleClose, duration);
|
|
199
|
+
return () => clearTimeout(timer);
|
|
200
|
+
}, [duration, indefinite, isPaused, handleClose]);
|
|
201
|
+
const handleMouseEnter = useCallback(() => {
|
|
202
|
+
if (pauseOnHover)
|
|
203
|
+
setIsPaused(true);
|
|
204
|
+
}, [pauseOnHover]);
|
|
205
|
+
const handleMouseLeave = useCallback(() => {
|
|
206
|
+
if (pauseOnHover)
|
|
207
|
+
setIsPaused(false);
|
|
208
|
+
}, [pauseOnHover]);
|
|
209
|
+
return (jsx(Notification, { color: color, isLight: isLight, hasDelete: hasDelete, onDelete: handleClose, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: { pointerEvents: 'auto' }, children: urgent ? (jsx("span", { role: "alert", "aria-live": "assertive", children: message })) : (jsx("span", { ref: messageRef, children: message })) }));
|
|
210
|
+
};
|
|
211
|
+
// The order NotificationContainer renders its stacks in: across the top of the
|
|
212
|
+
// screen, then across the bottom.
|
|
213
|
+
const notificationStackOrder = [
|
|
214
|
+
'top-left',
|
|
215
|
+
'top',
|
|
216
|
+
'top-right',
|
|
217
|
+
'bottom-left',
|
|
218
|
+
'bottom',
|
|
219
|
+
'bottom-right',
|
|
220
|
+
];
|
|
221
|
+
/**
|
|
222
|
+
* Inline style that fixes a stack of notifications to its place on the screen.
|
|
223
|
+
*
|
|
224
|
+
* @function
|
|
225
|
+
* @param {NotificationPosition} position - Where the stack sits.
|
|
226
|
+
* @returns {React.CSSProperties} The stack's style.
|
|
227
|
+
*/
|
|
228
|
+
const notificationStackStyle = (position) => {
|
|
229
|
+
const isBottom = position.startsWith('bottom');
|
|
230
|
+
const isCenter = position === 'top' || position === 'bottom';
|
|
231
|
+
const isRight = position.endsWith('right');
|
|
232
|
+
return {
|
|
233
|
+
position: 'fixed',
|
|
234
|
+
zIndex: 100,
|
|
235
|
+
display: 'flex',
|
|
236
|
+
flexDirection: isBottom ? 'column-reverse' : 'column',
|
|
237
|
+
gap: '0.75rem',
|
|
238
|
+
padding: '1rem',
|
|
239
|
+
pointerEvents: 'none',
|
|
240
|
+
maxWidth: '100%',
|
|
241
|
+
...(isBottom ? { bottom: 0 } : { top: 0 }),
|
|
242
|
+
...(isCenter
|
|
243
|
+
? { left: '50%', transform: 'translateX(-50%)', alignItems: 'center' }
|
|
244
|
+
: isRight
|
|
245
|
+
? { right: 0, alignItems: 'flex-end' }
|
|
246
|
+
: { left: 0, alignItems: 'flex-start' }),
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Container component for rendering programmatic notifications.
|
|
251
|
+
* Place once at your app root to enable the notification API. A notification
|
|
252
|
+
* shown with a `position` appears there, and one shown without goes to the
|
|
253
|
+
* container's `position`, so the container renders a stack for each position
|
|
254
|
+
* in use.
|
|
255
|
+
*
|
|
256
|
+
* It keeps a visually hidden `role="status"` live region in the page from the
|
|
257
|
+
* moment it mounts, even while nothing is showing, and announces every
|
|
258
|
+
* notification other than `danger` and `warning` through it, a moment after
|
|
259
|
+
* the notification appears. Those notifications carry no `role="status"` of
|
|
260
|
+
* their own, so `getByRole('status')` finds the region, not the notification.
|
|
261
|
+
* The text stays in the region briefly, even if the notification closes in
|
|
262
|
+
* the meantime, and while both are up the page holds two copies of it. A
|
|
263
|
+
* polite notification that closes before its announcement is written, a
|
|
264
|
+
* moment after it appears, isn't announced at all. `danger` and `warning`
|
|
265
|
+
* notifications announce themselves as assertive alerts. The region is hidden
|
|
266
|
+
* with inline styles, so it needs no stylesheet.
|
|
267
|
+
*
|
|
268
|
+
* @function
|
|
269
|
+
* @param {{ position?: NotificationPosition }} props - Container props.
|
|
270
|
+
* @returns {JSX.Element | null} The rendered notification container, or null on the server and while hydrating.
|
|
271
|
+
*/
|
|
272
|
+
const NotificationContainer = ({ position = 'top-right' }) => {
|
|
273
|
+
// Starts from the notifications already showing instead of an empty list,
|
|
274
|
+
// then follows changes.
|
|
275
|
+
const items = useSyncExternalStore(notification.subscribe, getVisibleNotifications, getServerNotifications);
|
|
276
|
+
// A portal needs a document, and it has no server-rendered counterpart, so
|
|
277
|
+
// the server render and the hydrating one render nothing, and the container
|
|
278
|
+
// portals in from the render after hydration.
|
|
279
|
+
const isHydrated = useIsHydrated();
|
|
280
|
+
// The notifications the status region announces. Danger and warning
|
|
281
|
+
// announce themselves.
|
|
282
|
+
const politeItems = useMemo(() => items.filter(item => !isUrgentColor(item.options.color)), [items]);
|
|
283
|
+
// Each polite notification's message element, so the text the region
|
|
284
|
+
// announces is the text on screen, whatever the message renders.
|
|
285
|
+
const messageNodesRef = useRef(new Map());
|
|
286
|
+
const registerMessage = useCallback((id, node) => {
|
|
287
|
+
if (node) {
|
|
288
|
+
messageNodesRef.current.set(id, node);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
messageNodesRef.current.delete(id);
|
|
292
|
+
}
|
|
293
|
+
}, []);
|
|
294
|
+
// StatusRegion only describes polite notifications that are on screen, and
|
|
295
|
+
// each of those registered its message element when it mounted. The
|
|
296
|
+
// fallback is for a notification announced without being rendered, should
|
|
297
|
+
// the container ever render fewer than it announces: a plain-text message
|
|
298
|
+
// still says itself, and anything else is skipped.
|
|
299
|
+
const describe = useCallback((item) => {
|
|
300
|
+
const node = messageNodesRef.current.get(item.id);
|
|
301
|
+
/* istanbul ignore if: every polite notification on screen registers its message element when it mounts */
|
|
302
|
+
if (!node) {
|
|
303
|
+
const { message } = item.options;
|
|
304
|
+
return typeof message === 'string' ? message : null;
|
|
305
|
+
}
|
|
306
|
+
return spokenText(node);
|
|
307
|
+
}, []);
|
|
308
|
+
if (typeof document === 'undefined' || !isHydrated) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
const stacks = groupIntoPositionStacks(items, item => item.options.position, position, notificationStackOrder);
|
|
312
|
+
return createPortal(jsxs(Fragment, { children: [stacks.map(stack => (jsx("div", { style: notificationStackStyle(stack.position), children: stack.items.map(item => (jsx(NotificationItem, { instance: item, onClose: notification.close, registerMessage: registerMessage }, item.id))) }, stack.key))), jsx(StatusRegion, { items: politeItems, describe: describe })] }), document.body);
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
export { Notification, NotificationContainer, notification };
|
|
316
|
+
//# sourceMappingURL=Notification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Notification.js","sources":["../../../src/elements/Notification.tsx"],"sourcesContent":["import React, {\n useEffect,\n useMemo,\n useRef,\n useState,\n useCallback,\n useSyncExternalStore,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnUnstyledColor } from '../helpers/colorDeprecations';\nimport { groupIntoPositionStacks } from '../helpers/positionStacks';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\n\n/**\n * Props for the Notification component.\n */\nexport interface NotificationProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * Bulma color modifier for the notification (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.notification`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * notification renders unstyled; those log a console warning in development\n * and will be removed from this union in the next major version.\n */\n color?: (typeof validColors)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Use the light color variant. */\n isLight?: boolean;\n /**\n * Shows a close (delete) button in the notification. It renders\n * `type=\"button\"`, so it does not submit a form around it.\n */\n hasDelete?: boolean;\n /** Callback fired when the delete button is clicked. */\n onDelete?: () => void;\n /** Content inside the notification. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Notification` component is a Bulma-styled alert/message area for providing feedback, warnings, or information to users.\n *\n * @function\n * @param {NotificationProps} props - Props for the Notification component.\n * @returns {JSX.Element} The rendered notification element.\n * @see {@link https://bulma.io/documentation/elements/notification/ | Bulma Notification documentation}\n */\nexport const Notification: React.FC<NotificationProps> = ({\n className,\n color,\n textColor,\n isLight,\n hasDelete,\n onDelete,\n children,\n ...props\n}) => {\n warnUnstyledColor('Notification', color);\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n const bulmaClasses = usePrefixedClassNames('notification', {\n [`is-${color}`]: color && validColors.includes(color),\n 'is-light': isLight,\n });\n\n const deleteClasses = usePrefixedClassNames('delete');\n\n const notificationClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <div className={notificationClasses} {...rest}>\n {hasDelete && (\n <button\n type=\"button\"\n className={deleteClasses}\n onClick={onDelete}\n aria-label=\"Close notification\"\n />\n )}\n {children}\n </div>\n );\n};\n\n// Programmatic Notification API\n\n/** Screen positions where programmatic notifications can be displayed. */\nexport type NotificationPosition =\n 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right';\n\n/**\n * Options for showing a programmatic notification.\n */\nexport interface NotificationOptions {\n /**\n * The message to display.\n *\n * For a notification other than `danger` and `warning`, NotificationContainer\n * announces the text the message renders, with an element's `aria-label`,\n * or an image's `alt`, standing in for what's inside it, a break between\n * block-level elements, and parts that are `aria-hidden`, `hidden` or\n * inline-styled `display: none` left out. Other ways of naming or hiding\n * content, such as `aria-labelledby`, CSS-generated content or a\n * stylesheet's `display: none`, aren't followed, so a message that relies on\n * them can be announced differently from what a screen reader would read.\n */\n message: string | React.ReactNode;\n /**\n * Bulma color modifier for the notification (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.notification`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * notification renders unstyled; those log a console warning in development\n * and will be removed from this union in the next major version.\n */\n color?: (typeof validColors)[number];\n /** Use the light color variant. */\n isLight?: boolean;\n /** Duration in ms before auto-close. Default 3000. */\n duration?: number;\n /**\n * Position on the screen. A notification shown without one goes to\n * `NotificationContainer`'s `position`.\n */\n position?: NotificationPosition;\n /**\n * When true, notifications enter a FIFO queue and display one at a time,\n * one queue across every `position`. Default false.\n */\n queue?: boolean;\n /** Show a delete (close) button. Default true. */\n hasDelete?: boolean;\n /** Stay open until dismissed. */\n indefinite?: boolean;\n /** Pause auto-close timer on hover. Default true. */\n pauseOnHover?: boolean;\n}\n\n/**\n * Internal representation of a notification instance.\n */\ninterface NotificationInstance {\n /** Unique identifier for this notification. */\n id: string;\n /** Configuration options for the notification. */\n options: NotificationOptions;\n}\n\nlet notificationId = 0;\nconst notificationListeners: Set<(items: NotificationInstance[]) => void> =\n new Set();\nlet notifications: NotificationInstance[] = [];\n\n// Queue support\nlet queuedNotifications: NotificationInstance[] = [];\nlet currentQueuedNotification: NotificationInstance | null = null;\n\n// The server has nowhere to portal a notification to, and its copy of this\n// module is shared by every request, so server rendering reads an empty list.\n// Hydration reads it too, which keeps the first client render matching the\n// server's.\nconst noNotifications: NotificationInstance[] = [];\nconst getServerNotifications = () => noNotifications;\n\n// What a container shows right now: the stacked notifications, then the queued\n// one on screen. NotificationContainer renders from this rather than from\n// updates alone, so notifications raised before it mounted still appear. It is\n// replaced rather than mutated, and only when listeners are notified, because\n// useSyncExternalStore needs the same array back between changes. An empty\n// list is `noNotifications` itself, so an empty store reads the same snapshot\n// on the client as on the server, and a notify that leaves nothing showing\n// when nothing was showing doesn't render the container again.\nlet visibleNotifications: NotificationInstance[] = noNotifications;\nconst getVisibleNotifications = () => visibleNotifications;\n\nconst notifyNotificationListeners = () => {\n const allVisible = [...notifications];\n if (currentQueuedNotification) {\n allVisible.push(currentQueuedNotification);\n }\n visibleNotifications = allVisible.length > 0 ? allVisible : noNotifications;\n notificationListeners.forEach(listener => listener([...allVisible]));\n};\n\nconst processQueuedNotification = () => {\n if (currentQueuedNotification || queuedNotifications.length === 0) return;\n currentQueuedNotification = queuedNotifications.shift()!;\n notifyNotificationListeners();\n};\n\n/**\n * Programmatic notification API for showing, closing, and managing notifications.\n *\n * @example\n * notification.success('File saved successfully');\n * notification.danger('Something went wrong', { duration: 5000 });\n */\nexport const notification = {\n /**\n * Show a notification with the given options.\n * @param {NotificationOptions} options - Notification configuration.\n * @returns {string} The unique ID of the created notification.\n */\n show: (options: NotificationOptions): string => {\n const id = `notification-${++notificationId}`;\n const instance = { id, options };\n\n if (options.queue) {\n queuedNotifications.push(instance);\n processQueuedNotification();\n } else {\n notifications.push(instance);\n notifyNotificationListeners();\n }\n\n return id;\n },\n\n /**\n * Show a success notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n success: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'success', ...options });\n },\n\n /**\n * Show a danger notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n danger: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'danger', ...options });\n },\n\n /**\n * Show a warning notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n warning: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'warning', ...options });\n },\n\n /**\n * Show an info notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n info: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'info', ...options });\n },\n\n /**\n * Close a specific notification by ID.\n * @param {string} id - The notification ID to close.\n */\n close: (id: string): void => {\n if (currentQueuedNotification && currentQueuedNotification.id === id) {\n currentQueuedNotification = null;\n processQueuedNotification();\n } else {\n queuedNotifications = queuedNotifications.filter(n => n.id !== id);\n notifications = notifications.filter(n => n.id !== id);\n }\n notifyNotificationListeners();\n },\n\n /** Close all notifications and clear the queue. */\n closeAll: (): void => {\n notifications = [];\n queuedNotifications = [];\n currentQueuedNotification = null;\n notifyNotificationListeners();\n },\n\n /**\n * Subscribe to notification state changes.\n * @param {(items: NotificationInstance[]) => void} listener - Callback invoked on changes.\n * @returns {() => void} Unsubscribe function.\n */\n subscribe: (\n listener: (items: NotificationInstance[]) => void\n ): (() => void) => {\n notificationListeners.add(listener);\n return () => notificationListeners.delete(listener);\n },\n};\n\n/**\n * Whether a notification of this color announces itself as an alert, rather\n * than politely through NotificationContainer's status region.\n *\n * @function isUrgentColor\n * @param {NotificationOptions['color']} color - The notification's color.\n * @returns {boolean} True for `danger` and `warning`.\n */\nconst isUrgentColor = (color: NotificationOptions['color']): boolean =>\n color === 'danger' || color === 'warning';\n\n/**\n * Single auto-dismissing notification item used by NotificationContainer.\n *\n * @function\n * @param {{ instance: NotificationInstance; onClose: (id: string) => void; registerMessage: (id: string, node: HTMLElement | null) => void }} props - Component props.\n * @returns {JSX.Element} The rendered notification item.\n */\nconst NotificationItem: React.FC<{\n instance: NotificationInstance;\n onClose: (id: string) => void;\n registerMessage: (id: string, node: HTMLElement | null) => void;\n}> = ({ instance, onClose, registerMessage }) => {\n const {\n message,\n color,\n isLight,\n duration = 3000,\n hasDelete = true,\n indefinite = false,\n pauseOnHover = true,\n } = instance.options;\n\n const [isPaused, setIsPaused] = useState(false);\n const urgent = isUrgentColor(color);\n\n const handleClose = useCallback(() => {\n onClose(instance.id);\n }, [onClose, instance.id]);\n\n const messageRef = useCallback(\n (node: HTMLElement | null) => {\n registerMessage(instance.id, node);\n },\n [registerMessage, instance.id]\n );\n\n // Auto-close timer\n useEffect(() => {\n if (indefinite || duration === 0 || isPaused) return undefined;\n\n const timer = setTimeout(handleClose, duration);\n return () => clearTimeout(timer);\n }, [duration, indefinite, isPaused, handleClose]);\n\n const handleMouseEnter = useCallback(() => {\n if (pauseOnHover) setIsPaused(true);\n }, [pauseOnHover]);\n\n const handleMouseLeave = useCallback(() => {\n if (pauseOnHover) setIsPaused(false);\n }, [pauseOnHover]);\n\n return (\n <Notification\n color={color}\n isLight={isLight}\n hasDelete={hasDelete}\n onDelete={handleClose}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n style={{ pointerEvents: 'auto' }}\n >\n {/* Only the message is announced, not the close button Notification\n renders ahead of its children. Danger and warning announce\n themselves as an assertive alert, which a screen reader reliably\n reads out even when it arrives with its text. The rest are announced\n through the container's status region, which reads their text from\n this span, so it carries no role of its own that would announce them\n a second time. */}\n {urgent ? (\n <span role=\"alert\" aria-live=\"assertive\">\n {message}\n </span>\n ) : (\n <span ref={messageRef}>{message}</span>\n )}\n </Notification>\n );\n};\n\n// The order NotificationContainer renders its stacks in: across the top of the\n// screen, then across the bottom.\nconst notificationStackOrder: readonly NotificationPosition[] = [\n 'top-left',\n 'top',\n 'top-right',\n 'bottom-left',\n 'bottom',\n 'bottom-right',\n];\n\n/**\n * Inline style that fixes a stack of notifications to its place on the screen.\n *\n * @function\n * @param {NotificationPosition} position - Where the stack sits.\n * @returns {React.CSSProperties} The stack's style.\n */\nconst notificationStackStyle = (\n position: NotificationPosition\n): React.CSSProperties => {\n const isBottom = position.startsWith('bottom');\n const isCenter = position === 'top' || position === 'bottom';\n const isRight = position.endsWith('right');\n\n return {\n position: 'fixed',\n zIndex: 100,\n display: 'flex',\n flexDirection: isBottom ? 'column-reverse' : 'column',\n gap: '0.75rem',\n padding: '1rem',\n pointerEvents: 'none',\n maxWidth: '100%',\n ...(isBottom ? { bottom: 0 } : { top: 0 }),\n ...(isCenter\n ? { left: '50%', transform: 'translateX(-50%)', alignItems: 'center' }\n : isRight\n ? { right: 0, alignItems: 'flex-end' }\n : { left: 0, alignItems: 'flex-start' }),\n };\n};\n\n/**\n * Container component for rendering programmatic notifications.\n * Place once at your app root to enable the notification API. A notification\n * shown with a `position` appears there, and one shown without goes to the\n * container's `position`, so the container renders a stack for each position\n * in use.\n *\n * It keeps a visually hidden `role=\"status\"` live region in the page from the\n * moment it mounts, even while nothing is showing, and announces every\n * notification other than `danger` and `warning` through it, a moment after\n * the notification appears. Those notifications carry no `role=\"status\"` of\n * their own, so `getByRole('status')` finds the region, not the notification.\n * The text stays in the region briefly, even if the notification closes in\n * the meantime, and while both are up the page holds two copies of it. A\n * polite notification that closes before its announcement is written, a\n * moment after it appears, isn't announced at all. `danger` and `warning`\n * notifications announce themselves as assertive alerts. The region is hidden\n * with inline styles, so it needs no stylesheet.\n *\n * @function\n * @param {{ position?: NotificationPosition }} props - Container props.\n * @returns {JSX.Element | null} The rendered notification container, or null on the server and while hydrating.\n */\nexport const NotificationContainer: React.FC<{\n /**\n * Where a notification shown without a `position` of its own appears.\n * Default: 'top-right'. When it changes, those notifications move without\n * remounting, but one shown with its own `position` equal to the old or new\n * value remounts and starts over as if it had just been shown.\n */\n position?: NotificationPosition;\n}> = ({ position = 'top-right' }) => {\n // Starts from the notifications already showing instead of an empty list,\n // then follows changes.\n const items = useSyncExternalStore(\n notification.subscribe,\n getVisibleNotifications,\n getServerNotifications\n );\n // A portal needs a document, and it has no server-rendered counterpart, so\n // the server render and the hydrating one render nothing, and the container\n // portals in from the render after hydration.\n const isHydrated = useIsHydrated();\n\n // The notifications the status region announces. Danger and warning\n // announce themselves.\n const politeItems = useMemo(\n () => items.filter(item => !isUrgentColor(item.options.color)),\n [items]\n );\n\n // Each polite notification's message element, so the text the region\n // announces is the text on screen, whatever the message renders.\n const messageNodesRef = useRef(new Map<string, HTMLElement>());\n const registerMessage = useCallback(\n (id: string, node: HTMLElement | null) => {\n if (node) {\n messageNodesRef.current.set(id, node);\n } else {\n messageNodesRef.current.delete(id);\n }\n },\n []\n );\n // StatusRegion only describes polite notifications that are on screen, and\n // each of those registered its message element when it mounted. The\n // fallback is for a notification announced without being rendered, should\n // the container ever render fewer than it announces: a plain-text message\n // still says itself, and anything else is skipped.\n const describe = useCallback((item: NotificationInstance) => {\n const node = messageNodesRef.current.get(item.id);\n /* istanbul ignore if: every polite notification on screen registers its message element when it mounts */\n if (!node) {\n const { message } = item.options;\n return typeof message === 'string' ? message : null;\n }\n return spokenText(node);\n }, []);\n\n if (typeof document === 'undefined' || !isHydrated) {\n return null;\n }\n\n const stacks = groupIntoPositionStacks(\n items,\n item => item.options.position,\n position,\n notificationStackOrder\n );\n\n return createPortal(\n <>\n {stacks.map(stack => (\n <div key={stack.key} style={notificationStackStyle(stack.position)}>\n {stack.items.map(item => (\n <NotificationItem\n key={item.id}\n instance={item}\n onClose={notification.close}\n registerMessage={registerMessage}\n />\n ))}\n </div>\n ))}\n <StatusRegion items={politeItems} describe={describe} />\n </>,\n document.body\n );\n};\n"],"names":["_jsxs","_jsx","_Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
import { withSubComponents } from '../helpers/withSubComponents.js';
|
|
5
|
+
import { ListItem } from './ListItem.js';
|
|
6
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The `OrderedList` component renders a styled ordered list (`<ol>`) element with Bulma helper class integration.
|
|
10
|
+
*
|
|
11
|
+
* @function
|
|
12
|
+
* @param {OrderedListProps} props - Props for the OrderedList component.
|
|
13
|
+
* @returns {JSX.Element} The rendered ol element.
|
|
14
|
+
*/
|
|
15
|
+
const OrderedListComponent = ({ className, textColor, bgColor, children, ...props }) => {
|
|
16
|
+
/**
|
|
17
|
+
* Generates Bulma helper classes and separates out remaining props.
|
|
18
|
+
*/
|
|
19
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
20
|
+
color: textColor,
|
|
21
|
+
backgroundColor: bgColor,
|
|
22
|
+
...props,
|
|
23
|
+
});
|
|
24
|
+
const bulmaClasses = usePrefixedClassNames();
|
|
25
|
+
const listClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
26
|
+
return (jsx("ol", { className: listClasses || undefined, ...rest, children: children }));
|
|
27
|
+
};
|
|
28
|
+
const OrderedList = withSubComponents(OrderedListComponent, { Item: ListItem }, 'OrderedList');
|
|
29
|
+
|
|
30
|
+
export { OrderedList };
|
|
31
|
+
//# sourceMappingURL=OrderedList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderedList.js","sources":["../../../src/elements/OrderedList.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { ListItem } from './ListItem';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * Props for the OrderedList component.\n * @extraProp {'1' | 'a' | 'A' | 'i' | 'I'} [type='1'] - The numbering type for the list.\n * @extraProp {number} [start] - The starting number for the list.\n * @extraProp {boolean} [reversed] - Whether to reverse the list numbering.\n */\nexport interface OrderedListProps\n extends\n React.OlHTMLAttributes<HTMLOListElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** List items to render inside the list. */\n children?: React.ReactNode;\n}\n\n/**\n * The `OrderedList` component renders a styled ordered list (`<ol>`) element with Bulma helper class integration.\n *\n * @function\n * @param {OrderedListProps} props - Props for the OrderedList component.\n * @returns {JSX.Element} The rendered ol element.\n */\nconst OrderedListComponent: React.FC<OrderedListProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n } as BulmaClassesProps & typeof props);\n\n const bulmaClasses = usePrefixedClassNames();\n const listClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n return (\n <ol className={listClasses || undefined} {...rest}>\n {children}\n </ol>\n );\n};\n\nexport const OrderedList = withSubComponents(\n OrderedListComponent,\n { Item: ListItem },\n 'OrderedList'\n);\n"],"names":["_jsx"],"mappings":";;;;;;;AA8BA;;;;;;AAMG;AACH,MAAM,oBAAoB,GAA+B,CAAC,EACxD,SAAS,EACT,SAAS,EACT,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AAC2B,KAAA,CAAC;AAEtC,IAAA,MAAM,YAAY,GAAG,qBAAqB,EAAE;IAC5C,MAAM,WAAW,GAAG,UAAU,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC;AAE3E,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,WAAW,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAC9C,QAAQ,EAAA,CACN;AAET,CAAC;AAEM,MAAM,WAAW,GAAG,iBAAiB,CAC1C,oBAAoB,EACpB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAClB,aAAa;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The `Paragraph` component renders a styled `<p>` element with Bulma helper class integration.
|
|
8
|
+
*
|
|
9
|
+
* @function
|
|
10
|
+
* @param {ParagraphProps} props - Props for the Paragraph component.
|
|
11
|
+
* @returns {JSX.Element} The rendered paragraph element.
|
|
12
|
+
*/
|
|
13
|
+
const Paragraph = ({ className, textColor, bgColor, children, ...props }) => {
|
|
14
|
+
/**
|
|
15
|
+
* Generates Bulma helper classes and separates out remaining props.
|
|
16
|
+
*/
|
|
17
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
18
|
+
color: textColor,
|
|
19
|
+
backgroundColor: bgColor,
|
|
20
|
+
...props,
|
|
21
|
+
});
|
|
22
|
+
const bulmaClasses = usePrefixedClassNames();
|
|
23
|
+
const paragraphClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
24
|
+
return (jsx("p", { className: paragraphClasses || undefined, ...rest, children: children }));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { Paragraph };
|
|
28
|
+
//# sourceMappingURL=Paragraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Paragraph.js","sources":["../../../src/elements/Paragraph.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * Props for the Paragraph component.\n */\nexport interface ParagraphProps\n extends\n React.HTMLAttributes<HTMLParagraphElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Content to render inside the paragraph. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Paragraph` component renders a styled `<p>` element with Bulma helper class integration.\n *\n * @function\n * @param {ParagraphProps} props - Props for the Paragraph component.\n * @returns {JSX.Element} The rendered paragraph element.\n */\nexport const Paragraph: React.FC<ParagraphProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n } as BulmaClassesProps & typeof props);\n\n const bulmaClasses = usePrefixedClassNames();\n const paragraphClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <p className={paragraphClasses || undefined} {...rest}>\n {children}\n </p>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;AAyBA;;;;;;AAMG;AACI,MAAM,SAAS,GAA6B,CAAC,EAClD,SAAS,EACT,SAAS,EACT,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AAC2B,KAAA,CAAC;AAEtC,IAAA,MAAM,YAAY,GAAG,qBAAqB,EAAE;IAC5C,MAAM,gBAAgB,GAAG,UAAU,CACjC,YAAY,EACZ,kBAAkB,EAClB,SAAS,CACV;AAED,IAAA,QACEA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,gBAAgB,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAClD,QAAQ,EAAA,CACP;AAER;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The `Pre` component renders a styled `<pre>` element with Bulma helper class integration.
|
|
8
|
+
*
|
|
9
|
+
* @function
|
|
10
|
+
* @param {PreProps} props - Props for the Pre component.
|
|
11
|
+
* @returns {JSX.Element} The rendered pre element.
|
|
12
|
+
*/
|
|
13
|
+
const Pre = ({ className, textColor, bgColor, children, ...props }) => {
|
|
14
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
15
|
+
color: textColor,
|
|
16
|
+
backgroundColor: bgColor,
|
|
17
|
+
...props,
|
|
18
|
+
});
|
|
19
|
+
const bulmaClasses = usePrefixedClassNames();
|
|
20
|
+
const preClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
21
|
+
return (jsx("pre", { className: preClasses || undefined, ...rest, children: children }));
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { Pre };
|
|
25
|
+
//# sourceMappingURL=Pre.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pre.js","sources":["../../../src/elements/Pre.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * Props for the Pre component.\n */\nexport interface PreProps\n extends\n React.HTMLAttributes<HTMLPreElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Preformatted content to render. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Pre` component renders a styled `<pre>` element with Bulma helper class integration.\n *\n * @function\n * @param {PreProps} props - Props for the Pre component.\n * @returns {JSX.Element} The rendered pre element.\n */\nexport const Pre: React.FC<PreProps> = ({\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 } as BulmaClassesProps & typeof props);\n\n const bulmaClasses = usePrefixedClassNames();\n const preClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n return (\n <pre className={preClasses || undefined} {...rest}>\n {children}\n </pre>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;AAyBA;;;;;;AAMG;AACI,MAAM,GAAG,GAAuB,CAAC,EACtC,SAAS,EACT,SAAS,EACT,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AAC2B,KAAA,CAAC;AAEtC,IAAA,MAAM,YAAY,GAAG,qBAAqB,EAAE;IAC5C,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC;AAE1E,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAC9C,QAAQ,EAAA,CACL;AAEV;;"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
5
|
+
import { warnUnstyledColor } from '../helpers/colorDeprecations.js';
|
|
6
|
+
import { validColors } from '../helpers/bulmaClassHelpers.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The `Progress` component displays a Bulma-styled progress bar.
|
|
10
|
+
*
|
|
11
|
+
* @function
|
|
12
|
+
* @param {ProgressProps} props - Props for the Progress component.
|
|
13
|
+
* @returns {JSX.Element} The rendered progress bar element.
|
|
14
|
+
* @see {@link https://bulma.io/documentation/elements/progress/ | Bulma Progress documentation}
|
|
15
|
+
*/
|
|
16
|
+
const Progress = ({ className, color, size, value, max, children, ...props }) => {
|
|
17
|
+
warnUnstyledColor('Progress', color);
|
|
18
|
+
/**
|
|
19
|
+
* Generates Bulma helper classes and separates out remaining props.
|
|
20
|
+
*/
|
|
21
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
22
|
+
...props,
|
|
23
|
+
});
|
|
24
|
+
const bulmaClasses = usePrefixedClassNames('progress', {
|
|
25
|
+
[`is-${color}`]: color && validColors.includes(color),
|
|
26
|
+
[`is-${size}`]: size,
|
|
27
|
+
});
|
|
28
|
+
const progressClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
29
|
+
return (jsx("progress", { className: progressClasses, value: value, max: max, ...rest, children: children }));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { Progress };
|
|
33
|
+
//# sourceMappingURL=Progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.js","sources":["../../../src/elements/Progress.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnUnstyledColor } from '../helpers/colorDeprecations';\n\n/**\n * Props for the Progress component.\n */\nexport interface ProgressProps\n extends\n React.ProgressHTMLAttributes<HTMLProgressElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * Bulma color modifier for the progress bar (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.progress`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * bar renders unstyled; those log a console warning in development and will\n * be removed from this union in the next major version.\n */\n color?: (typeof validColors)[number];\n /** Size modifier for the progress bar. */\n size?: 'small' | 'medium' | 'large';\n /**\n * Current value of the progress bar. Leave it unset for an indeterminate\n * bar, which sweeps across the track. Under `prefers-reduced-motion: reduce`\n * that bar holds still (with bestax's CSS loaded), so it can read as\n * partly filled.\n */\n value?: number;\n /** Maximum value of the progress bar. */\n max?: number;\n /** Optional custom content inside the progress bar. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Progress` component displays a Bulma-styled progress bar.\n *\n * @function\n * @param {ProgressProps} props - Props for the Progress component.\n * @returns {JSX.Element} The rendered progress bar element.\n * @see {@link https://bulma.io/documentation/elements/progress/ | Bulma Progress documentation}\n */\nexport const Progress: React.FC<ProgressProps> = ({\n className,\n color,\n size,\n value,\n max,\n children,\n ...props\n}) => {\n warnUnstyledColor('Progress', color);\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n ...props,\n });\n\n const bulmaClasses = usePrefixedClassNames('progress', {\n [`is-${color}`]: color && validColors.includes(color),\n [`is-${size}`]: size,\n });\n\n const progressClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <progress className={progressClasses} value={value} max={max} {...rest}>\n {children}\n </progress>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;AA2CA;;;;;;;AAOG;MACU,QAAQ,GAA4B,CAAC,EAChD,SAAS,EACT,KAAK,EACL,IAAI,EACJ,KAAK,EACL,GAAG,EACH,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,iBAAiB,CAAC,UAAU,EAAE,KAAK,CAAC;AAEpC;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;AAEF,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,UAAU,EAAE;AACrD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;AACrD,QAAA,CAAC,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,GAAG,IAAI;AACrB,KAAA,CAAC;IAEF,MAAM,eAAe,GAAG,UAAU,CAChC,YAAY,EACZ,kBAAkB,EAClB,SAAS,CACV;AAED,IAAA,QACEA,GAAA,CAAA,UAAA,EAAA,EAAU,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAA,GAAM,IAAI,YACnE,QAAQ,EAAA,CACA;AAEf;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `Skeleton` component provides a Bulma-styled skeleton loader for React applications, useful for indicating that content is loading.
|
|
7
|
+
*
|
|
8
|
+
* @function
|
|
9
|
+
* @param {SkeletonProps} props - Props for the Skeleton component.
|
|
10
|
+
* @returns {JSX.Element} The rendered skeleton element.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Block skeleton
|
|
14
|
+
* <Skeleton />
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Multi-line skeleton
|
|
18
|
+
* <Skeleton variant="lines" lines={5} />
|
|
19
|
+
*/
|
|
20
|
+
const Skeleton = ({ className, variant = 'block', lines = 3, children, ...props }) => {
|
|
21
|
+
const linesClass = usePrefixedClassNames('skeleton-lines');
|
|
22
|
+
const blockClass = usePrefixedClassNames('skeleton-block');
|
|
23
|
+
if (variant === 'lines') {
|
|
24
|
+
return (jsx("div", { className: classNames(linesClass, className), ...props, children: Array.from({ length: lines }).map((_, i) => (jsx("div", {}, i))) }));
|
|
25
|
+
}
|
|
26
|
+
return (jsx("div", { className: classNames(blockClass, className), ...props, children: children }));
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { Skeleton };
|
|
30
|
+
//# sourceMappingURL=Skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.js","sources":["../../../src/elements/Skeleton.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\n\n/**\n * Props for the Skeleton component.\n */\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes to apply */\n className?: string;\n /** Skeleton variant: block (single block) or lines. */\n variant?: 'block' | 'lines';\n /** Number of lines (only for `lines` variant). */\n lines?: number;\n /** Content inside the block (only for block variant). */\n children?: React.ReactNode;\n}\n\n/**\n * The `Skeleton` component provides a Bulma-styled skeleton loader for React applications, useful for indicating that content is loading.\n *\n * @function\n * @param {SkeletonProps} props - Props for the Skeleton component.\n * @returns {JSX.Element} The rendered skeleton element.\n *\n * @example\n * // Block skeleton\n * <Skeleton />\n *\n * @example\n * // Multi-line skeleton\n * <Skeleton variant=\"lines\" lines={5} />\n */\nexport const Skeleton: React.FC<SkeletonProps> = ({\n className,\n variant = 'block',\n lines = 3,\n children,\n ...props\n}) => {\n const linesClass = usePrefixedClassNames('skeleton-lines');\n const blockClass = usePrefixedClassNames('skeleton-block');\n\n if (variant === 'lines') {\n return (\n <div className={classNames(linesClass, className)} {...props}>\n {Array.from({ length: lines }).map((_, i) => (\n <div key={i} />\n ))}\n </div>\n );\n }\n\n return (\n <div className={classNames(blockClass, className)} {...props}>\n {children}\n </div>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;AAiBA;;;;;;;;;;;;;;AAcG;MACU,QAAQ,GAA4B,CAAC,EAChD,SAAS,EACT,OAAO,GAAG,OAAO,EACjB,KAAK,GAAG,CAAC,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,gBAAgB,CAAC;AAC1D,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,gBAAgB,CAAC;AAE1D,IAAA,IAAI,OAAO,KAAK,OAAO,EAAE;AACvB,QAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,EAAA,GAAM,KAAK,EAAA,QAAA,EACzD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MACtCA,eAAU,CAAC,CAAI,CAChB,CAAC,EAAA,CACE;IAEV;AAEA,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,KAAM,KAAK,EAAA,QAAA,EACzD,QAAQ,EAAA,CACL;AAEV;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The `Span` component renders a styled inline `<span>` element with Bulma helper class integration.
|
|
8
|
+
*
|
|
9
|
+
* @function
|
|
10
|
+
* @param {SpanProps} props - Props for the Span component.
|
|
11
|
+
* @returns {JSX.Element} The rendered span element.
|
|
12
|
+
*/
|
|
13
|
+
const Span = ({ className, textColor, bgColor, children, ...props }) => {
|
|
14
|
+
/**
|
|
15
|
+
* Generates Bulma helper classes and separates out remaining props.
|
|
16
|
+
*/
|
|
17
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
18
|
+
color: textColor,
|
|
19
|
+
backgroundColor: bgColor,
|
|
20
|
+
...props,
|
|
21
|
+
});
|
|
22
|
+
const bulmaClasses = usePrefixedClassNames();
|
|
23
|
+
const spanClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
24
|
+
return (jsx("span", { className: spanClasses || undefined, ...rest, children: children }));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { Span };
|
|
28
|
+
//# sourceMappingURL=Span.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Span.js","sources":["../../../src/elements/Span.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * Props for the Span component.\n */\nexport interface SpanProps\n extends\n React.HTMLAttributes<HTMLSpanElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Content to render inside the span. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Span` component renders a styled inline `<span>` element with Bulma helper class integration.\n *\n * @function\n * @param {SpanProps} props - Props for the Span component.\n * @returns {JSX.Element} The rendered span element.\n */\nexport const Span: React.FC<SpanProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n } as BulmaClassesProps & typeof props);\n\n const bulmaClasses = usePrefixedClassNames();\n const spanClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n return (\n <span className={spanClasses || undefined} {...rest}>\n {children}\n </span>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;AAyBA;;;;;;AAMG;AACI,MAAM,IAAI,GAAwB,CAAC,EACxC,SAAS,EACT,SAAS,EACT,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AAC2B,KAAA,CAAC;AAEtC,IAAA,MAAM,YAAY,GAAG,qBAAqB,EAAE;IAC5C,MAAM,WAAW,GAAG,UAAU,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC;AAE3E,IAAA,QACEA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,WAAW,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAChD,QAAQ,EAAA,CACJ;AAEX;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The `Strong` component renders a styled `<strong>` element with Bulma helper class integration.
|
|
8
|
+
*
|
|
9
|
+
* @function
|
|
10
|
+
* @param {StrongProps} props - Props for the Strong component.
|
|
11
|
+
* @returns {JSX.Element} The rendered strong element.
|
|
12
|
+
*/
|
|
13
|
+
const Strong = ({ className, textColor, bgColor, children, ...props }) => {
|
|
14
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
15
|
+
color: textColor,
|
|
16
|
+
backgroundColor: bgColor,
|
|
17
|
+
...props,
|
|
18
|
+
});
|
|
19
|
+
const bulmaClasses = usePrefixedClassNames();
|
|
20
|
+
const strongClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
|
|
21
|
+
return (jsx("strong", { className: strongClasses || undefined, ...rest, children: children }));
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { Strong };
|
|
25
|
+
//# sourceMappingURL=Strong.js.map
|