@allxsmith/bestax-bulma 5.19.0 → 5.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/extras.css +1 -1
  4. package/dist/extras.css.map +1 -1
  5. package/dist/index.cjs +247 -25
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.esm.js +244 -26
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/types/components/Collapse.d.ts +13 -9
  10. package/dist/types/components/Collapses.d.ts +53 -0
  11. package/dist/types/components/collapsesContext.d.ts +19 -0
  12. package/dist/types/elements/Button.d.ts +5 -1
  13. package/dist/types/elements/Loader.d.ts +39 -0
  14. package/dist/types/form/Autocomplete.d.ts +5 -1
  15. package/dist/types/form/Control.d.ts +5 -1
  16. package/dist/types/form/DateInput.d.ts +5 -1
  17. package/dist/types/form/DateTimeInput.d.ts +5 -1
  18. package/dist/types/form/Input.d.ts +5 -1
  19. package/dist/types/form/Numberinput.d.ts +5 -1
  20. package/dist/types/form/Select.d.ts +5 -1
  21. package/dist/types/form/SelectBase.d.ts +5 -1
  22. package/dist/types/form/Taginput.d.ts +5 -1
  23. package/dist/types/form/TextArea.d.ts +5 -1
  24. package/dist/types/form/TimeInput.d.ts +5 -1
  25. package/dist/types/helpers/ClientOnly.d.ts +40 -0
  26. package/dist/types/helpers/inertProps.d.ts +11 -0
  27. package/dist/types/helpers/useIsHydrated.d.ts +5 -0
  28. package/dist/types/index.d.ts +5 -0
  29. package/dist/types-cjs/components/Collapse.d.ts +13 -9
  30. package/dist/types-cjs/components/Collapses.d.ts +53 -0
  31. package/dist/types-cjs/components/collapsesContext.d.ts +19 -0
  32. package/dist/types-cjs/elements/Button.d.ts +5 -1
  33. package/dist/types-cjs/elements/Loader.d.ts +39 -0
  34. package/dist/types-cjs/form/Autocomplete.d.ts +5 -1
  35. package/dist/types-cjs/form/Control.d.ts +5 -1
  36. package/dist/types-cjs/form/DateInput.d.ts +5 -1
  37. package/dist/types-cjs/form/DateTimeInput.d.ts +5 -1
  38. package/dist/types-cjs/form/Input.d.ts +5 -1
  39. package/dist/types-cjs/form/Numberinput.d.ts +5 -1
  40. package/dist/types-cjs/form/Select.d.ts +5 -1
  41. package/dist/types-cjs/form/SelectBase.d.ts +5 -1
  42. package/dist/types-cjs/form/Taginput.d.ts +5 -1
  43. package/dist/types-cjs/form/TextArea.d.ts +5 -1
  44. package/dist/types-cjs/form/TimeInput.d.ts +5 -1
  45. package/dist/types-cjs/helpers/ClientOnly.d.ts +40 -0
  46. package/dist/types-cjs/helpers/inertProps.d.ts +11 -0
  47. package/dist/types-cjs/helpers/useIsHydrated.d.ts +5 -0
  48. package/dist/types-cjs/index.d.ts +5 -0
  49. package/dist/versions/bestax-no-dark-mode.css +1 -1
  50. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  51. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  52. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  53. package/dist/versions/bestax-no-helpers.css +1 -1
  54. package/dist/versions/bestax-no-helpers.css.map +1 -1
  55. package/dist/versions/bestax-prefixed.css +1 -1
  56. package/dist/versions/bestax-prefixed.css.map +1 -1
  57. package/package.json +1 -1
  58. package/src/scss/components/_collapse.scss +13 -4
  59. package/src/scss/elements/_index.scss +1 -0
  60. package/src/scss/elements/_loader.scss +23 -0
@@ -6,14 +6,21 @@ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
6
6
  * @extraProp {string} [className] - Additional CSS classes.
7
7
  */
8
8
  export interface CollapseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
9
- /** Controlled open state. If provided, component is controlled. */
9
+ /**
10
+ * Controlled open state. If provided, component is controlled, and the
11
+ * trigger only reports through `onOpenChange`. Inside a `Collapses` group, a
12
+ * Collapse that sets `open` stays yours: the group neither overrides it nor
13
+ * closes it when another item opens.
14
+ */
10
15
  open?: boolean;
11
- /** Initial open state for uncontrolled usage. */
16
+ /** Initial open state for uncontrolled usage. Ignored inside a `Collapses` group, whose `defaultValue` decides. */
12
17
  defaultOpen?: boolean;
13
- /** Callback when collapse opens. */
18
+ /** Called when the trigger opens the Collapse. Fires only while the Collapse keeps its own state: not when `open` is set, and not when a `Collapses` group manages it. `onOpenChange` reports in every mode. */
14
19
  onOpen?: () => void;
15
- /** Callback when collapse closes. */
20
+ /** Called when the trigger closes the Collapse. Fires only while the Collapse keeps its own state: not when `open` is set, and not when a `Collapses` group manages it. `onOpenChange` reports in every mode. */
16
21
  onClose?: () => void;
22
+ /** Called with the state the trigger asks for (`true` to open) each time it is clicked or activated with Enter or Space, in every mode. Pair it with `open` to let the trigger drive a controlled Collapse. */
23
+ onOpenChange?: (open: boolean) => void;
17
24
  /** The clickable trigger element (header/button). */
18
25
  trigger?: React.ReactNode;
19
26
  /** Animation style, or `false` to disable. */
@@ -46,12 +53,9 @@ export interface CollapseProps extends Omit<React.HTMLAttributes<HTMLDivElement>
46
53
  * </Collapse>
47
54
  *
48
55
  * @example
49
- * // Controlled collapse
56
+ * // Controlled collapse, driven by its own trigger
50
57
  * const [isOpen, setIsOpen] = useState(false);
51
- * <Collapse
52
- * open={isOpen}
53
- * trigger={<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>}
54
- * >
58
+ * <Collapse open={isOpen} onOpenChange={setIsOpen} trigger={<strong>Toggle</strong>}>
55
59
  * <p>Content</p>
56
60
  * </Collapse>
57
61
  *
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props shared by both modes of the Collapses component.
5
+ */
6
+ interface CollapsesBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'defaultValue' | 'onChange'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
7
+ /** Joins the items into one block, with no gap between them and only the outer corners rounded. The joins show on `bordered` items. */
8
+ seamless?: boolean;
9
+ /** Additional CSS classes to apply. */
10
+ className?: string;
11
+ /** The `Collapse` items. Each child element is one item, indexed from 0 in order, with the children of a fragment counted one by one. A child that sets its own `open` keeps it: the group leaves that item alone. */
12
+ children?: React.ReactNode;
13
+ }
14
+ /**
15
+ * Props for Collapses in single mode, the accordion: opening one item closes the others.
16
+ */
17
+ export interface CollapsesSingleProps extends CollapsesBaseProps {
18
+ /**
19
+ * Lets items open independently. Without it, opening one item closes the others.
20
+ * @defaultValue false
21
+ */
22
+ multiple?: false;
23
+ /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility="hidden"`, or keep `value` in step yourself. */
24
+ value?: number | null;
25
+ /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */
26
+ defaultValue?: number | null;
27
+ /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */
28
+ onChange?: (value: number | null) => void;
29
+ }
30
+ /**
31
+ * Props for Collapses with `multiple`: items open and close independently.
32
+ */
33
+ export interface CollapsesMultipleProps extends CollapsesBaseProps {
34
+ /**
35
+ * Lets items open independently. Without it, opening one item closes the others.
36
+ * @defaultValue false
37
+ */
38
+ multiple: true;
39
+ /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility="hidden"`, or keep `value` in step yourself. */
40
+ value?: number[];
41
+ /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */
42
+ defaultValue?: number[];
43
+ /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */
44
+ onChange?: (value: number[]) => void;
45
+ }
46
+ /**
47
+ * Props for the Collapses component, a discriminated union on `multiple`: the open items are an index (or `null`) in single mode and an array of indexes with `multiple`.
48
+ */
49
+ export type CollapsesProps = CollapsesSingleProps | CollapsesMultipleProps;
50
+ export declare const Collapses: React.FC<CollapsesProps> & {
51
+ Collapse: React.FC<import("./Collapse.js").CollapseProps>;
52
+ };
53
+ export default Collapses;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * What a `Collapses` group hands the item it wraps: whether that item is open,
3
+ * and how to ask the group for a change.
4
+ *
5
+ * This module is internal. `index.ts` re-exports `Collapse` and `Collapses`
6
+ * whole, so the context lives here, where neither re-export reaches it.
7
+ */
8
+ export interface CollapsesItemContextValue {
9
+ /** Whether the group has this item open. */
10
+ open: boolean;
11
+ /** Asks the group to open (`true`) or close (`false`) this item. */
12
+ setOpen: (open: boolean) => void;
13
+ }
14
+ /**
15
+ * `null` outside a group. A `Collapse` also resets it to `null` for its own
16
+ * subtree, so a Collapse nested in an item's content keeps its own state
17
+ * instead of answering to its ancestor's slot in the group.
18
+ */
19
+ export declare const CollapsesItemContext: import("react").Context<CollapsesItemContextValue | null>;
@@ -21,7 +21,11 @@ export interface ButtonOwnProps extends Omit<BulmaClassesProps, 'color' | 'backg
21
21
  isLight?: boolean;
22
22
  /** Makes the button rounded. */
23
23
  isRounded?: boolean;
24
- /** Displays a loading spinner. */
24
+ /**
25
+ * Displays a loading spinner.
26
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
27
+ * drawn (with bestax's CSS loaded).
28
+ */
25
29
  isLoading?: boolean;
26
30
  /** Makes the button non-interactive. */
27
31
  isStatic?: boolean;
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props for the Loader component.
5
+ *
6
+ * There is no color prop, and the text and background color helpers are left
7
+ * out on purpose: Bulma draws the ring in `--bulma-border`, so a text color
8
+ * never reaches it. For a colored spinner over a region, use `Loading`.
9
+ *
10
+ * @extraProp {React.Ref<HTMLSpanElement>} [ref] - Ref forwarded to the loader element.
11
+ */
12
+ export interface LoaderProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'children'>, Omit<BulmaClassesProps, 'color' | 'colorShade' | 'backgroundColor' | 'backgroundColorShade'> {
13
+ /** Additional CSS classes to apply. */
14
+ className?: string;
15
+ /**
16
+ * Accessible name of the progress indicator. Name what is loading
17
+ * (`"Saving row"`) when more than one loader can be on screen at once.
18
+ */
19
+ ariaLabel?: string;
20
+ }
21
+ /**
22
+ * The `Loader` component renders Bulma's `.loader`, a small spinning ring for inline loading states.
23
+ *
24
+ * The ring is `1em` square, so `textSize` scales it. It is exposed as an
25
+ * indeterminate `progressbar` named by `ariaLabel`, and it stops spinning
26
+ * under `prefers-reduced-motion: reduce` while staying drawn.
27
+ *
28
+ * @function
29
+ * @param {LoaderProps} props - Props for the Loader component.
30
+ * @param {React.Ref<HTMLSpanElement>} ref - Forwarded ref to the loader element.
31
+ * @returns {JSX.Element} The rendered loader element.
32
+ *
33
+ * @example
34
+ * <Loader />
35
+ *
36
+ * @example
37
+ * <Loader textSize="3" ariaLabel="Saving" />
38
+ */
39
+ export declare const Loader: React.ForwardRefExoticComponent<LoaderProps & React.RefAttributes<HTMLSpanElement>>;
@@ -51,7 +51,11 @@ export interface AutocompleteProps extends Omit<React.HTMLAttributes<HTMLDivElem
51
51
  maxHeight?: number;
52
52
  /** Render as dropdown style. */
53
53
  dropdown?: boolean;
54
- /** Show loading state. */
54
+ /**
55
+ * Show a loading spinner in the input.
56
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
57
+ * drawn (with bestax's CSS loaded).
58
+ */
55
59
  loading?: boolean;
56
60
  /** Whether the input is disabled. */
57
61
  disabled?: boolean;
@@ -9,7 +9,11 @@ export interface ControlBaseProps extends React.HTMLAttributes<HTMLDivElement>,
9
9
  hasIconsLeft?: boolean;
10
10
  /** Adds right icon container. */
11
11
  hasIconsRight?: boolean;
12
- /** Shows loading indicator. */
12
+ /**
13
+ * Shows a loading spinner inside the control.
14
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
15
+ * drawn (with bestax's CSS loaded).
16
+ */
13
17
  isLoading?: boolean;
14
18
  /** Makes the control expand to fill available space. */
15
19
  isExpanded?: boolean;
@@ -34,7 +34,11 @@ export interface DateInputProps extends DateInputBaseProps {
34
34
  hasIconsLeft?: boolean;
35
35
  /** Force the right icon container. */
36
36
  hasIconsRight?: boolean;
37
- /** Show a loading indicator on the control. */
37
+ /**
38
+ * Show a loading spinner on the control.
39
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
40
+ * drawn (with bestax's CSS loaded).
41
+ */
38
42
  isLoading?: boolean;
39
43
  /** Expand the control to fill its container. */
40
44
  isExpanded?: boolean;
@@ -32,7 +32,11 @@ export interface DateTimeInputProps extends DateTimeInputBaseProps {
32
32
  hasIconsLeft?: boolean;
33
33
  /** Force the right icon container. */
34
34
  hasIconsRight?: boolean;
35
- /** Show a loading indicator on the control. */
35
+ /**
36
+ * Show a loading spinner on the control.
37
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
38
+ * drawn (with bestax's CSS loaded).
39
+ */
36
40
  isLoading?: boolean;
37
41
  /** Expand the control to fill its container. */
38
42
  isExpanded?: boolean;
@@ -34,7 +34,11 @@ export interface InputProps extends InputBaseProps {
34
34
  hasIconsLeft?: boolean;
35
35
  /** Force right icon container. */
36
36
  hasIconsRight?: boolean;
37
- /** Shows loading indicator. */
37
+ /**
38
+ * Shows a loading spinner on the wrapping Control.
39
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
40
+ * drawn (with bestax's CSS loaded).
41
+ */
38
42
  isLoading?: boolean;
39
43
  /** Expand the control. */
40
44
  isExpanded?: boolean;
@@ -53,7 +53,11 @@ export interface NumberinputProps extends Omit<React.InputHTMLAttributes<HTMLInp
53
53
  disabled?: boolean;
54
54
  /** Whether the input can be typed in. */
55
55
  editable?: boolean;
56
- /** Shows a loading state. */
56
+ /**
57
+ * Shows a loading spinner on the input's control.
58
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
59
+ * drawn (with bestax's CSS loaded).
60
+ */
57
61
  isLoading?: boolean;
58
62
  /** Enables exponential step increments when holding buttons. */
59
63
  exponential?: boolean;
@@ -26,7 +26,11 @@ export interface SelectProps extends SelectBaseProps {
26
26
  iconLeftSize?: ControlBaseProps['iconLeftSize'];
27
27
  /** Force left icon container. */
28
28
  hasIconsLeft?: boolean;
29
- /** Shows loading indicator. */
29
+ /**
30
+ * Replaces the chevron with a loading spinner.
31
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
32
+ * drawn (with bestax's CSS loaded).
33
+ */
30
34
  isLoading?: boolean;
31
35
  /** Expand the control. */
32
36
  isExpanded?: boolean;
@@ -10,7 +10,11 @@ export interface SelectBaseProps extends Omit<React.SelectHTMLAttributes<HTMLSel
10
10
  size?: 'small' | 'medium' | 'large';
11
11
  /** Rounded select corners. */
12
12
  isRounded?: boolean;
13
- /** Shows loading indicator. */
13
+ /**
14
+ * Replaces the chevron with a loading spinner.
15
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
16
+ * drawn (with bestax's CSS loaded).
17
+ */
14
18
  isLoading?: boolean;
15
19
  /** Applies Bulma's is-active modifier. */
16
20
  isActive?: boolean;
@@ -76,7 +76,11 @@ export interface TaginputProps extends Omit<React.HTMLAttributes<HTMLDivElement>
76
76
  keepFirst?: boolean;
77
77
  /** Keeps the autocomplete dropdown open after selection. */
78
78
  keepOpen?: boolean;
79
- /** Shows a loading indicator. */
79
+ /**
80
+ * Shows a loading spinner in the input.
81
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
82
+ * drawn (with bestax's CSS loaded).
83
+ */
80
84
  loading?: boolean;
81
85
  /** ARIA label for tag close buttons. */
82
86
  ariaCloseLabel?: string;
@@ -18,7 +18,11 @@ export interface TextAreaProps extends TextAreaBaseProps {
18
18
  labelProps?: FieldProps['labelProps'];
19
19
  /** Horizontal field layout. */
20
20
  horizontal?: boolean;
21
- /** Shows loading indicator on the wrapping Control. */
21
+ /**
22
+ * Shows a loading spinner on the wrapping Control.
23
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
24
+ * drawn (with bestax's CSS loaded).
25
+ */
22
26
  isLoading?: boolean;
23
27
  /** Control size. */
24
28
  controlSize?: ControlBaseProps['size'];
@@ -34,7 +34,11 @@ export interface TimeInputProps extends TimeInputBaseProps {
34
34
  hasIconsLeft?: boolean;
35
35
  /** Force the right icon container. */
36
36
  hasIconsRight?: boolean;
37
- /** Show a loading indicator on the control. */
37
+ /**
38
+ * Show a loading spinner on the control.
39
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
40
+ * drawn (with bestax's CSS loaded).
41
+ */
38
42
  isLoading?: boolean;
39
43
  /** Expand the control to fill its container. */
40
44
  isExpanded?: boolean;
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ /**
3
+ * Props for the ClientOnly component.
4
+ */
5
+ export interface ClientOnlyProps {
6
+ /**
7
+ * Content to render once the page has hydrated. A function is called only
8
+ * then, so an inline expression that reads `window`, `document` or
9
+ * `localStorage` never runs on the server.
10
+ */
11
+ children?: React.ReactNode | (() => React.ReactNode);
12
+ /**
13
+ * Rendered on the server and during hydration instead of `children`, such
14
+ * as a placeholder the same size as the content so the layout doesn't
15
+ * shift when it arrives.
16
+ * @defaultValue null
17
+ */
18
+ fallback?: React.ReactNode;
19
+ }
20
+ /**
21
+ * Renders its children only in the browser, after hydration, and a `fallback` until then, so content that depends on browser-only state doesn't cause a hydration mismatch.
22
+ *
23
+ * The server render and the hydrating client render both show `fallback`,
24
+ * which keeps them identical; the children replace it in the commit that
25
+ * follows. In an app without server rendering the children show on the first
26
+ * render.
27
+ *
28
+ * @function
29
+ * @param {ClientOnlyProps} props - Props for the ClientOnly component.
30
+ * @returns The children once hydrated, otherwise the fallback.
31
+ *
32
+ * @example
33
+ * // The server's time zone is not the reader's.
34
+ * <ClientOnly fallback={<Skeleton variant="lines" lines={1} />}>
35
+ * {() => (
36
+ * <p>Times are shown in {Intl.DateTimeFormat().resolvedOptions().timeZone}.</p>
37
+ * )}
38
+ * </ClientOnly>
39
+ */
40
+ export declare function ClientOnly({ children, fallback }: ClientOnlyProps): React.JSX.Element;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ /**
3
+ * The prop that makes an element inert, spelled for the React in use, or
4
+ * nothing when `inert` is false.
5
+ *
6
+ * Both majors must render `inert=""`, and each warns on the other's spelling
7
+ * and then drops the attribute. React 19 treats `inert` as a boolean and
8
+ * rejects the empty string. React 18 does not know the attribute, so it
9
+ * passes a string through and rejects `true`.
10
+ */
11
+ export declare const inertProps: (inert: boolean, major?: number) => React.HTMLAttributes<HTMLElement>;
@@ -6,6 +6,11 @@
6
6
  * DOM-only behaviour (such as portalling) past hydration so the first client
7
7
  * render matches the server markup instead of tripping hydration recovery.
8
8
  *
9
+ * Only a component that hydrates ever sees `false` on the client. One that
10
+ * mounts later (after a route change, or in an app with no server rendering)
11
+ * gets `true` on its first render, so it pays for no extra render. It
12
+ * subscribes to nothing, so no later render flips it back.
13
+ *
9
14
  * @function useIsHydrated
10
15
  * @returns `true` once the hydrating render has completed, otherwise `false`.
11
16
  */
@@ -15,6 +15,7 @@ export * from './components/Panel.js';
15
15
  export * from './components/Tabs.js';
16
16
  export * from './components/Loading.js';
17
17
  export * from './components/Collapse.js';
18
+ export * from './components/Collapses.js';
18
19
  export * from './components/Tooltip.js';
19
20
  export * from './components/Steps.js';
20
21
  export * from './components/Sidebar.js';
@@ -38,6 +39,7 @@ export * from './elements/IconText.js';
38
39
  export * from './elements/Image.js';
39
40
  export * from './elements/Link.js';
40
41
  export * from './elements/ListItem.js';
42
+ export * from './elements/Loader.js';
41
43
  export * from './elements/Notification.js';
42
44
  export * from './elements/OrderedList.js';
43
45
  export * from './elements/Paragraph.js';
@@ -105,6 +107,9 @@ export * from './helpers/mergeBulmaStyles.js';
105
107
  export * from './helpers/useBulmaClasses.js';
106
108
  export * from './helpers/Theme.js';
107
109
  export * from './helpers/Config.js';
110
+ export { ClientOnly } from './helpers/ClientOnly.js';
111
+ export type { ClientOnlyProps } from './helpers/ClientOnly.js';
112
+ export { useIsHydrated } from './helpers/useIsHydrated.js';
108
113
  export * from './layout/Container.js';
109
114
  export * from './layout/Footer.js';
110
115
  export * from './layout/Hero.js';
@@ -6,14 +6,21 @@ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
6
6
  * @extraProp {string} [className] - Additional CSS classes.
7
7
  */
8
8
  export interface CollapseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
9
- /** Controlled open state. If provided, component is controlled. */
9
+ /**
10
+ * Controlled open state. If provided, component is controlled, and the
11
+ * trigger only reports through `onOpenChange`. Inside a `Collapses` group, a
12
+ * Collapse that sets `open` stays yours: the group neither overrides it nor
13
+ * closes it when another item opens.
14
+ */
10
15
  open?: boolean;
11
- /** Initial open state for uncontrolled usage. */
16
+ /** Initial open state for uncontrolled usage. Ignored inside a `Collapses` group, whose `defaultValue` decides. */
12
17
  defaultOpen?: boolean;
13
- /** Callback when collapse opens. */
18
+ /** Called when the trigger opens the Collapse. Fires only while the Collapse keeps its own state: not when `open` is set, and not when a `Collapses` group manages it. `onOpenChange` reports in every mode. */
14
19
  onOpen?: () => void;
15
- /** Callback when collapse closes. */
20
+ /** Called when the trigger closes the Collapse. Fires only while the Collapse keeps its own state: not when `open` is set, and not when a `Collapses` group manages it. `onOpenChange` reports in every mode. */
16
21
  onClose?: () => void;
22
+ /** Called with the state the trigger asks for (`true` to open) each time it is clicked or activated with Enter or Space, in every mode. Pair it with `open` to let the trigger drive a controlled Collapse. */
23
+ onOpenChange?: (open: boolean) => void;
17
24
  /** The clickable trigger element (header/button). */
18
25
  trigger?: React.ReactNode;
19
26
  /** Animation style, or `false` to disable. */
@@ -46,12 +53,9 @@ export interface CollapseProps extends Omit<React.HTMLAttributes<HTMLDivElement>
46
53
  * </Collapse>
47
54
  *
48
55
  * @example
49
- * // Controlled collapse
56
+ * // Controlled collapse, driven by its own trigger
50
57
  * const [isOpen, setIsOpen] = useState(false);
51
- * <Collapse
52
- * open={isOpen}
53
- * trigger={<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>}
54
- * >
58
+ * <Collapse open={isOpen} onOpenChange={setIsOpen} trigger={<strong>Toggle</strong>}>
55
59
  * <p>Content</p>
56
60
  * </Collapse>
57
61
  *
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props shared by both modes of the Collapses component.
5
+ */
6
+ interface CollapsesBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'defaultValue' | 'onChange'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
7
+ /** Joins the items into one block, with no gap between them and only the outer corners rounded. The joins show on `bordered` items. */
8
+ seamless?: boolean;
9
+ /** Additional CSS classes to apply. */
10
+ className?: string;
11
+ /** The `Collapse` items. Each child element is one item, indexed from 0 in order, with the children of a fragment counted one by one. A child that sets its own `open` keeps it: the group leaves that item alone. */
12
+ children?: React.ReactNode;
13
+ }
14
+ /**
15
+ * Props for Collapses in single mode, the accordion: opening one item closes the others.
16
+ */
17
+ export interface CollapsesSingleProps extends CollapsesBaseProps {
18
+ /**
19
+ * Lets items open independently. Without it, opening one item closes the others.
20
+ * @defaultValue false
21
+ */
22
+ multiple?: false;
23
+ /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility="hidden"`, or keep `value` in step yourself. */
24
+ value?: number | null;
25
+ /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */
26
+ defaultValue?: number | null;
27
+ /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */
28
+ onChange?: (value: number | null) => void;
29
+ }
30
+ /**
31
+ * Props for Collapses with `multiple`: items open and close independently.
32
+ */
33
+ export interface CollapsesMultipleProps extends CollapsesBaseProps {
34
+ /**
35
+ * Lets items open independently. Without it, opening one item closes the others.
36
+ * @defaultValue false
37
+ */
38
+ multiple: true;
39
+ /** Controlled open items: the index of the open item, or `null` for none. With `multiple`, an array of indexes. An index is a position among the children, so rendering an item conditionally or reordering them moves the open state onto a neighbour: render every item and hide one with `visibility="hidden"`, or keep `value` in step yourself. */
40
+ value?: number[];
41
+ /** Open items for uncontrolled use, as an index or `null` (the default, none open). With `multiple`, an array of indexes, empty by default. Indexes are positions among the children, as for `value`. */
42
+ defaultValue?: number[];
43
+ /** Called with the new open items each time a trigger asks for a change, whether or not `value` is set: an index or `null`, or with `multiple` an array of indexes in ascending order. Indexes are positions among the children, as for `value`. */
44
+ onChange?: (value: number[]) => void;
45
+ }
46
+ /**
47
+ * Props for the Collapses component, a discriminated union on `multiple`: the open items are an index (or `null`) in single mode and an array of indexes with `multiple`.
48
+ */
49
+ export type CollapsesProps = CollapsesSingleProps | CollapsesMultipleProps;
50
+ export declare const Collapses: React.FC<CollapsesProps> & {
51
+ Collapse: React.FC<import("./Collapse.js").CollapseProps>;
52
+ };
53
+ export default Collapses;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * What a `Collapses` group hands the item it wraps: whether that item is open,
3
+ * and how to ask the group for a change.
4
+ *
5
+ * This module is internal. `index.ts` re-exports `Collapse` and `Collapses`
6
+ * whole, so the context lives here, where neither re-export reaches it.
7
+ */
8
+ export interface CollapsesItemContextValue {
9
+ /** Whether the group has this item open. */
10
+ open: boolean;
11
+ /** Asks the group to open (`true`) or close (`false`) this item. */
12
+ setOpen: (open: boolean) => void;
13
+ }
14
+ /**
15
+ * `null` outside a group. A `Collapse` also resets it to `null` for its own
16
+ * subtree, so a Collapse nested in an item's content keeps its own state
17
+ * instead of answering to its ancestor's slot in the group.
18
+ */
19
+ export declare const CollapsesItemContext: import("react").Context<CollapsesItemContextValue | null>;
@@ -21,7 +21,11 @@ export interface ButtonOwnProps extends Omit<BulmaClassesProps, 'color' | 'backg
21
21
  isLight?: boolean;
22
22
  /** Makes the button rounded. */
23
23
  isRounded?: boolean;
24
- /** Displays a loading spinner. */
24
+ /**
25
+ * Displays a loading spinner.
26
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
27
+ * drawn (with bestax's CSS loaded).
28
+ */
25
29
  isLoading?: boolean;
26
30
  /** Makes the button non-interactive. */
27
31
  isStatic?: boolean;
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props for the Loader component.
5
+ *
6
+ * There is no color prop, and the text and background color helpers are left
7
+ * out on purpose: Bulma draws the ring in `--bulma-border`, so a text color
8
+ * never reaches it. For a colored spinner over a region, use `Loading`.
9
+ *
10
+ * @extraProp {React.Ref<HTMLSpanElement>} [ref] - Ref forwarded to the loader element.
11
+ */
12
+ export interface LoaderProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'children'>, Omit<BulmaClassesProps, 'color' | 'colorShade' | 'backgroundColor' | 'backgroundColorShade'> {
13
+ /** Additional CSS classes to apply. */
14
+ className?: string;
15
+ /**
16
+ * Accessible name of the progress indicator. Name what is loading
17
+ * (`"Saving row"`) when more than one loader can be on screen at once.
18
+ */
19
+ ariaLabel?: string;
20
+ }
21
+ /**
22
+ * The `Loader` component renders Bulma's `.loader`, a small spinning ring for inline loading states.
23
+ *
24
+ * The ring is `1em` square, so `textSize` scales it. It is exposed as an
25
+ * indeterminate `progressbar` named by `ariaLabel`, and it stops spinning
26
+ * under `prefers-reduced-motion: reduce` while staying drawn.
27
+ *
28
+ * @function
29
+ * @param {LoaderProps} props - Props for the Loader component.
30
+ * @param {React.Ref<HTMLSpanElement>} ref - Forwarded ref to the loader element.
31
+ * @returns {JSX.Element} The rendered loader element.
32
+ *
33
+ * @example
34
+ * <Loader />
35
+ *
36
+ * @example
37
+ * <Loader textSize="3" ariaLabel="Saving" />
38
+ */
39
+ export declare const Loader: React.ForwardRefExoticComponent<LoaderProps & React.RefAttributes<HTMLSpanElement>>;
@@ -51,7 +51,11 @@ export interface AutocompleteProps extends Omit<React.HTMLAttributes<HTMLDivElem
51
51
  maxHeight?: number;
52
52
  /** Render as dropdown style. */
53
53
  dropdown?: boolean;
54
- /** Show loading state. */
54
+ /**
55
+ * Show a loading spinner in the input.
56
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
57
+ * drawn (with bestax's CSS loaded).
58
+ */
55
59
  loading?: boolean;
56
60
  /** Whether the input is disabled. */
57
61
  disabled?: boolean;
@@ -9,7 +9,11 @@ export interface ControlBaseProps extends React.HTMLAttributes<HTMLDivElement>,
9
9
  hasIconsLeft?: boolean;
10
10
  /** Adds right icon container. */
11
11
  hasIconsRight?: boolean;
12
- /** Shows loading indicator. */
12
+ /**
13
+ * Shows a loading spinner inside the control.
14
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
15
+ * drawn (with bestax's CSS loaded).
16
+ */
13
17
  isLoading?: boolean;
14
18
  /** Makes the control expand to fill available space. */
15
19
  isExpanded?: boolean;
@@ -34,7 +34,11 @@ export interface DateInputProps extends DateInputBaseProps {
34
34
  hasIconsLeft?: boolean;
35
35
  /** Force the right icon container. */
36
36
  hasIconsRight?: boolean;
37
- /** Show a loading indicator on the control. */
37
+ /**
38
+ * Show a loading spinner on the control.
39
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
40
+ * drawn (with bestax's CSS loaded).
41
+ */
38
42
  isLoading?: boolean;
39
43
  /** Expand the control to fill its container. */
40
44
  isExpanded?: boolean;
@@ -32,7 +32,11 @@ export interface DateTimeInputProps extends DateTimeInputBaseProps {
32
32
  hasIconsLeft?: boolean;
33
33
  /** Force the right icon container. */
34
34
  hasIconsRight?: boolean;
35
- /** Show a loading indicator on the control. */
35
+ /**
36
+ * Show a loading spinner on the control.
37
+ * Under `prefers-reduced-motion: reduce` the spinner stops and stays
38
+ * drawn (with bestax's CSS loaded).
39
+ */
36
40
  isLoading?: boolean;
37
41
  /** Expand the control to fill its container. */
38
42
  isExpanded?: boolean;