@allxsmith/bestax-bulma 5.28.0 → 5.30.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 (94) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/ContextMenu.js +244 -0
  4. package/dist/esm/components/ContextMenu.js.map +1 -0
  5. package/dist/esm/components/Dialog.js +8 -4
  6. package/dist/esm/components/Dialog.js.map +1 -1
  7. package/dist/esm/components/HoverCard.js +3 -10
  8. package/dist/esm/components/HoverCard.js.map +1 -1
  9. package/dist/esm/components/Modal.js +19 -11
  10. package/dist/esm/components/Modal.js.map +1 -1
  11. package/dist/esm/components/Popover.js.map +1 -1
  12. package/dist/esm/components/Sidebar.js +12 -3
  13. package/dist/esm/components/Sidebar.js.map +1 -1
  14. package/dist/esm/components/Toast.js +5 -3
  15. package/dist/esm/components/Toast.js.map +1 -1
  16. package/dist/esm/components/Tooltip.js +36 -61
  17. package/dist/esm/components/Tooltip.js.map +1 -1
  18. package/dist/esm/elements/Button.js.map +1 -1
  19. package/dist/esm/elements/Notification.js +3 -1
  20. package/dist/esm/elements/Notification.js.map +1 -1
  21. package/dist/esm/elements/ToggleButton.js +60 -0
  22. package/dist/esm/elements/ToggleButton.js.map +1 -0
  23. package/dist/esm/form/DateInputBase.js.map +1 -1
  24. package/dist/esm/form/DateRangeInputBase.js.map +1 -1
  25. package/dist/esm/form/DateTimeInputBase.js.map +1 -1
  26. package/dist/esm/form/TimeInputBase.js.map +1 -1
  27. package/dist/esm/form/_pickerInternals/PickerPopover.js +3 -1
  28. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
  29. package/dist/esm/form/_pickerInternals/pickerTypes.js +14 -6
  30. package/dist/esm/form/_pickerInternals/pickerTypes.js.map +1 -1
  31. package/dist/esm/helpers/Config.js +5 -2
  32. package/dist/esm/helpers/Config.js.map +1 -1
  33. package/dist/esm/helpers/portal.js +30 -5
  34. package/dist/esm/helpers/portal.js.map +1 -1
  35. package/dist/esm/helpers/useContextMenuTrigger.js +166 -0
  36. package/dist/esm/helpers/useContextMenuTrigger.js.map +1 -0
  37. package/dist/esm/helpers/useHoverOpen.js +40 -6
  38. package/dist/esm/helpers/useHoverOpen.js.map +1 -1
  39. package/dist/esm/helpers/useMenuKeys.js +182 -0
  40. package/dist/esm/helpers/useMenuKeys.js.map +1 -0
  41. package/dist/extras.css +1 -1
  42. package/dist/extras.css.map +1 -1
  43. package/dist/index.cjs +2150 -1474
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.esm.js +2 -0
  46. package/dist/index.esm.js.map +1 -1
  47. package/dist/types/components/ContextMenu.d.ts +66 -0
  48. package/dist/types/components/HoverCard.d.ts +14 -12
  49. package/dist/types/components/Modal.d.ts +2 -1
  50. package/dist/types/components/Popover.d.ts +8 -7
  51. package/dist/types/components/Tooltip.d.ts +45 -4
  52. package/dist/types/elements/Button.d.ts +1 -1
  53. package/dist/types/elements/ToggleButton.d.ts +90 -0
  54. package/dist/types/form/DateInputBase.d.ts +4 -1
  55. package/dist/types/form/DateRangeInputBase.d.ts +4 -1
  56. package/dist/types/form/DateTimeInputBase.d.ts +8 -2
  57. package/dist/types/form/TimeInputBase.d.ts +7 -3
  58. package/dist/types/form/_pickerInternals/pickerTypes.d.ts +16 -1
  59. package/dist/types/helpers/Config.d.ts +34 -3
  60. package/dist/types/helpers/portal.d.ts +27 -5
  61. package/dist/types/helpers/useContextMenuTrigger.d.ts +67 -0
  62. package/dist/types/helpers/useHoverOpen.d.ts +19 -3
  63. package/dist/types/helpers/useMenuKeys.d.ts +57 -0
  64. package/dist/types/index.d.ts +2 -0
  65. package/dist/types-cjs/components/ContextMenu.d.ts +66 -0
  66. package/dist/types-cjs/components/HoverCard.d.ts +14 -12
  67. package/dist/types-cjs/components/Modal.d.ts +2 -1
  68. package/dist/types-cjs/components/Popover.d.ts +8 -7
  69. package/dist/types-cjs/components/Tooltip.d.ts +45 -4
  70. package/dist/types-cjs/elements/Button.d.ts +1 -1
  71. package/dist/types-cjs/elements/ToggleButton.d.ts +90 -0
  72. package/dist/types-cjs/form/DateInputBase.d.ts +4 -1
  73. package/dist/types-cjs/form/DateRangeInputBase.d.ts +4 -1
  74. package/dist/types-cjs/form/DateTimeInputBase.d.ts +8 -2
  75. package/dist/types-cjs/form/TimeInputBase.d.ts +7 -3
  76. package/dist/types-cjs/form/_pickerInternals/pickerTypes.d.ts +16 -1
  77. package/dist/types-cjs/helpers/Config.d.ts +34 -3
  78. package/dist/types-cjs/helpers/portal.d.ts +27 -5
  79. package/dist/types-cjs/helpers/useContextMenuTrigger.d.ts +67 -0
  80. package/dist/types-cjs/helpers/useHoverOpen.d.ts +19 -3
  81. package/dist/types-cjs/helpers/useMenuKeys.d.ts +57 -0
  82. package/dist/types-cjs/index.d.ts +2 -0
  83. package/dist/versions/bestax-no-dark-mode.css +1 -1
  84. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  85. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  86. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  87. package/dist/versions/bestax-no-helpers.css +1 -1
  88. package/dist/versions/bestax-no-helpers.css.map +1 -1
  89. package/dist/versions/bestax-prefixed.css +1 -1
  90. package/dist/versions/bestax-prefixed.css.map +1 -1
  91. package/package.json +1 -1
  92. package/src/scss/components/_contextmenu.scss +50 -0
  93. package/src/scss/components/_index.scss +1 -0
  94. package/src/scss/components/_tooltip.scss +76 -1
package/dist/index.esm.js CHANGED
@@ -20,6 +20,7 @@ export { Collapses } from './esm/components/Collapses.js';
20
20
  export { Tooltip } from './esm/components/Tooltip.js';
21
21
  export { Popover, PopoverBody, PopoverClose, PopoverFooter, PopoverHeader } from './esm/components/Popover.js';
22
22
  export { HoverCard } from './esm/components/HoverCard.js';
23
+ export { ContextMenu } from './esm/components/ContextMenu.js';
23
24
  export { Step, Steps } from './esm/components/Steps.js';
24
25
  export { Sidebar } from './esm/components/Sidebar.js';
25
26
  export { Toast, ToastContainer, toast } from './esm/components/Toast.js';
@@ -31,6 +32,7 @@ export { Box } from './esm/elements/Box.js';
31
32
  export { Button } from './esm/elements/Button.js';
32
33
  export { Buttons } from './esm/elements/Buttons.js';
33
34
  export { LinkButton } from './esm/elements/LinkButton.js';
35
+ export { ToggleButton } from './esm/elements/ToggleButton.js';
34
36
  export { Code } from './esm/elements/Code.js';
35
37
  export { Content } from './esm/elements/Content.js';
36
38
  export { Delete } from './esm/elements/Delete.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props for the ContextMenu component. `className`, `id`, `aria-label`, the
5
+ * other HTML attributes and the helper props land on the menu
6
+ * (`role="menu"`). The trigger keeps its own.
7
+ * @extraProp {string} [aria-label] - The menu's accessible name, such as "Actions for report.pdf". There's no button to borrow a name from, so pass this or `aria-labelledby`, and a development build warns when the menu opens with neither.
8
+ * @extraProp {string} [className] - Additional classes for the menu (`role="menu"`). The trigger keeps its own.
9
+ */
10
+ export interface ContextMenuProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'children'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
11
+ /**
12
+ * The element a right-click, Shift+F10, the context menu key or a long
13
+ * press opens the menu from: a table row, a card, an image. It's cloned,
14
+ * not wrapped, so a row stays a row, which means it has to be a single
15
+ * element that passes `className` and the `onContextMenu`,
16
+ * `onPointerDown`, `onPointerMove`, `onPointerUp`, `onPointerCancel` and
17
+ * `onTouchEnd` handlers to its DOM node. Its own handlers for those run
18
+ * first, and one that calls `preventDefault()` on `contextmenu` keeps the
19
+ * menu closed. A `ContextMenu` inside it opens instead of this one.
20
+ *
21
+ * It gets no ARIA and no tab stop, since it can be any element and a
22
+ * right-click isn't an activation. Keyboard users reach it through
23
+ * something focusable inside it, such as the row's own `Dropdown` button,
24
+ * or a `tabIndex={0}` you give it, and press Shift+F10 or the context menu
25
+ * key there. It gets `-webkit-touch-callout: none`, so iOS doesn't put its
26
+ * own callout for a link or an image over the menu. A long press still
27
+ * selects text the way it does anywhere, so give a region where it
28
+ * shouldn't `interaction="unselectable"`.
29
+ */
30
+ trigger: React.ReactElement;
31
+ /**
32
+ * The menu's items: `ContextMenu.Item` and `ContextMenu.Divider`, the same
33
+ * components as `Dropdown.Item` and `Dropdown.Divider`. Every action in it
34
+ * needs a visible way in as well, such as a `Dropdown` on the same row:
35
+ * nothing tells a screen reader user the menu is there, and on macOS only
36
+ * VoiceOver opens it from the keyboard.
37
+ */
38
+ children: React.ReactNode;
39
+ /**
40
+ * Called with `true` when the menu opens and `false` when it closes,
41
+ * whatever closed it, such as for highlighting the row whose menu is open.
42
+ * Nothing fires after ContextMenu unmounts. There's no `open` prop to go
43
+ * with it: a menu opened from code has no point to open at.
44
+ */
45
+ onOpenChange?: (open: boolean) => void;
46
+ /**
47
+ * Close the menu when an item is clicked, or activated with Enter or
48
+ * Space. A click on a divider or between items leaves it open either way.
49
+ */
50
+ closeOnClick?: boolean;
51
+ /**
52
+ * Leave the trigger to the browser: a right-click shows the browser's own
53
+ * menu, a long press does what it does anywhere, and an open menu closes.
54
+ */
55
+ disabled?: boolean;
56
+ }
57
+ /**
58
+ * ContextMenu with Item and Divider sub-components, which are `Dropdown.Item`
59
+ * and `Dropdown.Divider`, so items written for a Dropdown work here
60
+ * unchanged.
61
+ */
62
+ export declare const ContextMenu: React.FC<ContextMenuProps> & {
63
+ Item: import("../index.js").ConstrainedPolymorphicComponentWithoutRef<import("./Dropdown.js").DropdownItemOwnProps, import("./Dropdown.js").DropdownItemElement, "a", never>;
64
+ Divider: React.FC<{}>;
65
+ };
66
+ export default ContextMenu;
@@ -80,18 +80,20 @@ export interface HoverCardProps extends Omit<React.HTMLAttributes<HTMLSpanElemen
80
80
  */
81
81
  position?: HoverCardPosition;
82
82
  /**
83
- * Render the card at the end of `document.body` through `Portal`, fixed to
84
- * the viewport, so an ancestor's `overflow`, `transform` or stacking
85
- * context can't clip it. A trigger in running text needs it too, since the
86
- * card's block content can't sit inside a `<p>`. The card then shows from
87
- * the commit after hydration, never in server markup, and it sits last in
88
- * the Tab order, at the end of `<body>`. Tab reaches it only after the rest
89
- * of the page, and focus leaving the trigger on the way closes it, so
90
- * keyboard users can open it, read it and close it with Escape, and
91
- * whatever it links to has to be reachable from the page as well. It is
92
- * measured against the trigger when it opens and on resize and scroll, so
93
- * it doesn't follow content that changes size while it is open. Theming
94
- * variables set on an ancestor of the trigger don't reach it there.
83
+ * Render the card through `Portal`, into the `portalContainer` a
84
+ * `ConfigProvider` sets, `document.body` by default, fixed to the viewport,
85
+ * so an ancestor's `overflow`, `transform` or stacking context can't clip
86
+ * it. A trigger in running text needs it too, since the card's block
87
+ * content can't sit inside a `<p>`. The card then shows from the commit
88
+ * after hydration, never in server markup, and it sits in the Tab order
89
+ * where its container is. At the end of `<body>`, the default, Tab reaches
90
+ * it only after the rest of the page, and focus leaving the trigger on the
91
+ * way closes it, so keyboard users can open it, read it and close it with
92
+ * Escape, and whatever it links to has to be reachable from the page as
93
+ * well. It is measured against the trigger when it opens and on resize and
94
+ * scroll, so it doesn't follow content that changes size while it is open.
95
+ * Theming variables set on an ancestor of the trigger reach it only when its
96
+ * container is inside that ancestor.
95
97
  * @defaultValue false
96
98
  */
97
99
  appendToBody?: boolean;
@@ -44,7 +44,8 @@ export interface ModalProps extends Omit<React.HTMLAttributes<HTMLDivElement>, '
44
44
  /**
45
45
  * Renders the modal into a portal target instead of inline, so it isn't
46
46
  * clipped by an ancestor with `overflow: hidden`, `filter` or `transform`.
47
- * `true` portals to `document.body`; a string is used as a
47
+ * `true` portals to the `portalContainer` a `ConfigProvider` sets,
48
+ * `document.body` by default; a string is used as a
48
49
  * `document.querySelector` selector; an element is used directly. Renders
49
50
  * inline on the server and while hydrating, moving into the portal once the
50
51
  * client takes over, so hydration matches.
@@ -53,13 +53,14 @@ export interface PopoverProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
53
53
  */
54
54
  position?: PopoverPosition;
55
55
  /**
56
- * Render the panel at the end of `document.body` through `Portal`, fixed to
57
- * the viewport, so an ancestor's `overflow`, `transform` or stacking context
58
- * can't clip it. The panel then shows from the commit after hydration,
59
- * never in server markup. It is measured against the trigger when it opens
60
- * and on resize and scroll, so it doesn't follow content that changes size
61
- * while it is open. Theming variables set on an ancestor of the trigger
62
- * don't reach it there.
56
+ * Render the panel through `Portal`, into the `portalContainer` a
57
+ * `ConfigProvider` sets, `document.body` by default, fixed to the viewport,
58
+ * so an ancestor's `overflow`, `transform` or stacking context can't clip
59
+ * it. The panel then shows from the commit after hydration, never in server
60
+ * markup. It is measured against the trigger when it opens and on resize
61
+ * and scroll, so it doesn't follow content that changes size while it is
62
+ * open. Theming variables set on an ancestor of the trigger reach it only
63
+ * when its container is inside that ancestor.
63
64
  * @defaultValue false
64
65
  */
65
66
  appendToBody?: boolean;
@@ -14,7 +14,13 @@ export type TooltipSize = 'small' | 'medium' | 'large';
14
14
  export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'content'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
15
15
  /** The tooltip text content. */
16
16
  label?: string;
17
- /** Rich tooltip content (alternative to `label`). */
17
+ /**
18
+ * Rich tooltip content (alternative to `label`), to read rather than use.
19
+ * Nothing in it should take focus or a click: it isn't in the Tab order
20
+ * while hidden, focus there isn't counted as being in the tooltip, and
21
+ * Escape hiding it would drop that focus. For links or buttons, use
22
+ * `HoverCard` or `Popover`.
23
+ */
18
24
  content?: React.ReactNode;
19
25
  /** Position of the tooltip. Default: 'top'. */
20
26
  position?: TooltipPosition;
@@ -22,7 +28,11 @@ export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>
22
28
  color?: TooltipColor;
23
29
  /** Size of the tooltip. */
24
30
  size?: TooltipSize;
25
- /** Force tooltip to be always visible. */
31
+ /**
32
+ * Force tooltip to be always visible. Hover, focus and Escape leave it
33
+ * shown, so Escape goes on to whatever has focus, or to a `Modal` or
34
+ * `Popover` around it.
35
+ */
26
36
  active?: boolean;
27
37
  /** Allow tooltip to wrap to multiple lines. */
28
38
  multiline?: boolean;
@@ -32,16 +42,47 @@ export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>
32
42
  square?: boolean;
33
43
  /** Show dashed underline on trigger. */
34
44
  dashed?: boolean;
35
- /** Delay before showing tooltip (ms). */
45
+ /**
46
+ * How long the pointer or keyboard focus waits on the trigger before the
47
+ * tooltip shows, in milliseconds.
48
+ */
36
49
  delay?: number;
37
- /** Delay in ms before hiding the tooltip. */
50
+ /**
51
+ * How long the tooltip stays after the pointer and focus have left the
52
+ * trigger and the tooltip, in milliseconds. The pointer can move from the
53
+ * trigger onto a shown tooltip without one, across the default gap. A
54
+ * theme that raises `--bulma-tooltip-arrow-size` or
55
+ * `--bulma-tooltip-arrow-margin` widens the gap past what the pointer can
56
+ * cross on its own, so give it a `closeDelay` long enough to cross the
57
+ * rest.
58
+ */
38
59
  closeDelay?: number;
60
+ /**
61
+ * Show the tooltip with a tap on a touch screen. Touch has no hover, so
62
+ * without this a phone or tablet never shows it. With it, a tap on the
63
+ * trigger shows it at once, and it stays until another tap on the trigger
64
+ * or the tooltip, a tap anywhere else, or Escape. The tap still does
65
+ * whatever the trigger does, so turn this on only for a trigger with no
66
+ * tap action of its own. Mouse and pen work the same either way.
67
+ * @defaultValue false
68
+ */
69
+ openOnTap?: boolean;
39
70
  /** Additional classes for the tooltip element. */
40
71
  tooltipClassName?: string;
41
72
  }
42
73
  /**
43
74
  * The `Tooltip` component displays helpful information when users hover over or focus on an element.
44
75
  *
76
+ * Hovering the trigger or giving it keyboard focus shows it. Touch doesn't,
77
+ * unless `openOnTap` is on, and neither does focus a click or a tap brings,
78
+ * so tapping the trigger just does what the trigger does. The pointer can
79
+ * move onto a shown tooltip. Escape hides it wherever focus is, without
80
+ * moving the pointer or focus, and it stays hidden until one of them leaves
81
+ * the trigger and comes back, or, with `openOnTap`, until the next tap on
82
+ * the trigger. The key always goes on too, to whatever has focus or a
83
+ * `Modal` or `Popover` around it, since a tooltip only adds to what's
84
+ * there.
85
+ *
45
86
  * @function
46
87
  * @param {TooltipProps} props - Props for the Tooltip component.
47
88
  * @returns {JSX.Element} The rendered tooltip wrapper.
@@ -39,7 +39,7 @@ export interface ButtonOwnProps extends Omit<BulmaClassesProps, 'color' | 'backg
39
39
  isInverted?: boolean;
40
40
  /** Applies focused styling (visual only). */
41
41
  isFocused?: boolean;
42
- /** Applies active styling (visual only). */
42
+ /** Applies active styling (visual only), with no `aria-pressed`. For a button that stays pressed, use `ToggleButton`. */
43
43
  isActive?: boolean;
44
44
  /** Applies hovered styling (visual only). */
45
45
  isHovered?: boolean;
@@ -0,0 +1,90 @@
1
+ import React from 'react';
2
+ import { type ButtonOwnProps } from './Button.js';
3
+ /**
4
+ * The fills a pressed `ToggleButton` takes: `Button`'s colors, minus `text`
5
+ * and `ghost`, which don't fill, and `white`, `light`, `dark` and `black`.
6
+ * Bulma's color modifier fills the button and drops its border, and those four
7
+ * fill it with about the lightness a plain button already has in one theme or
8
+ * the other, so pressed would look like off without its border.
9
+ */
10
+ export type ToggleButtonColor = 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
11
+ /**
12
+ * Props for the ToggleButton component. The helper props, the other button
13
+ * attributes and the `ref` all land on the `<button>`.
14
+ *
15
+ * Some of `Button`'s props are left out on purpose. `as`, since only a button
16
+ * can be pressed, and `type`, which is always `button`. `isActive`, which is
17
+ * `pressed` here, and `isStatic`, a toggle you couldn't press. And the props
18
+ * that change the fill (`isLight`, `isOutlined`, `isInverted`, `textColor`,
19
+ * `bgColor` and their shades), since each would color the button in both
20
+ * states or turn "on" into a faint tint. `color` takes only the fills that
21
+ * stand out from a plain button: see `ToggleButtonColor`.
22
+ *
23
+ * @extraProp {React.Ref<HTMLButtonElement>} [ref] - Ref forwarded to the `<button>`.
24
+ */
25
+ export interface ToggleButtonProps extends Omit<ButtonOwnProps, 'color' | 'isActive' | 'isStatic' | 'isLight' | 'isOutlined' | 'isInverted' | 'textColor' | 'bgColor' | 'colorShade' | 'backgroundColorShade'>, Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps | 'type' | 'aria-pressed'> {
26
+ /**
27
+ * Whether it's pressed, when you hold the state. Setting it makes the toggle
28
+ * controlled: a click only calls `onPressedChange`, and nothing changes until
29
+ * you pass the new value. Pick this or `defaultPressed` for the button's
30
+ * lifetime.
31
+ */
32
+ pressed?: boolean;
33
+ /** Whether it starts pressed, when it holds its own state. */
34
+ defaultPressed?: boolean;
35
+ /**
36
+ * Called with the new state each time it's toggled, by a click, Enter or
37
+ * Space, whether or not `pressed` is set. An `onClick` that calls
38
+ * `preventDefault()` stops the toggle, and this doesn't fire.
39
+ */
40
+ onPressedChange?: (pressed: boolean) => void;
41
+ /**
42
+ * The fill while it's pressed. Not pressed, it's a plain button, so the fill
43
+ * is the difference people see. `white`, `light`, `dark` and `black` aren't
44
+ * offered, since in one theme or the other each fills about as light or dark
45
+ * as a plain button already is. Of the rest, a pale one such as `warning`
46
+ * changes less than the default `link`.
47
+ */
48
+ color?: ToggleButtonColor;
49
+ /**
50
+ * The label, which stays the same in both states: a screen reader announces
51
+ * whether it's pressed, so "Mute" stays "Mute". An icon can swap, but an
52
+ * icon-only toggle needs an `aria-label` that doesn't. A label that changes
53
+ * ("Play", then "Pause") belongs on a plain `Button`.
54
+ */
55
+ children?: React.ReactNode;
56
+ /**
57
+ * Not accepted: `aria-pressed` follows the state. Declared because JSX lets a
58
+ * hyphenated attribute through when the props don't name it, so leaving it
59
+ * out of the type alone would not reject `aria-pressed="mixed"`.
60
+ * @internal
61
+ */
62
+ 'aria-pressed'?: never;
63
+ }
64
+ /**
65
+ * The `ToggleButton` component renders a button that stays pressed until it's pressed again, and says whether it's on through `aria-pressed`.
66
+ *
67
+ * It's always a `<button type="button">`, so it never submits a form and
68
+ * carries no form value: a setting saved with a form is a `Checkbox` or a
69
+ * `Switch`. A set of toggles that each turn on and off on their own goes in
70
+ * `Buttons hasAddons` with `role="group"` and an `aria-label`. A set where only
71
+ * one can be on is a radio group rather than a row of these: use `Radios`.
72
+ *
73
+ * @function
74
+ * @param {ToggleButtonProps} props - Props for the ToggleButton component.
75
+ * @param {React.Ref<HTMLButtonElement>} ref - Forwarded ref to the `<button>`.
76
+ * @returns {JSX.Element} The rendered toggle button.
77
+ * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/button/ | APG button pattern}
78
+ *
79
+ * @example
80
+ * <ToggleButton onPressedChange={setMuted}>Mute</ToggleButton>
81
+ *
82
+ * @example
83
+ * <Buttons hasAddons role="group" aria-label="Text style">
84
+ * <ToggleButton aria-label="Bold" pressed={bold} onPressedChange={setBold}>
85
+ * <Icon name="bold" />
86
+ * </ToggleButton>
87
+ * </Buttons>
88
+ */
89
+ export declare const ToggleButton: React.ForwardRefExoticComponent<ToggleButtonProps & React.RefAttributes<HTMLButtonElement>>;
90
+ export default ToggleButton;
@@ -97,7 +97,10 @@ export interface DateInputBaseProps extends Omit<React.InputHTMLAttributes<HTMLI
97
97
  closeOnSelect?: boolean;
98
98
  /** Popover anchor position relative to the input. */
99
99
  position?: PickerPosition;
100
- /** Render the popover into `document.body` via portal. */
100
+ /**
101
+ * Render the popover through a portal, into the `portalContainer` a
102
+ * `ConfigProvider` sets, `document.body` by default.
103
+ */
101
104
  appendToBody?: boolean;
102
105
  /**
103
106
  * Bulma color modifier for the input, also carried by the calendar, where it
@@ -84,7 +84,10 @@ export interface DateRangeInputBaseProps extends Omit<React.HTMLAttributes<HTMLD
84
84
  closeOnSelect?: boolean;
85
85
  /** Popover anchor position relative to the field. */
86
86
  position?: PickerPosition;
87
- /** Render the popover into `document.body` via portal. */
87
+ /**
88
+ * Render the popover through a portal, into the `portalContainer` a
89
+ * `ConfigProvider` sets, `document.body` by default.
90
+ */
88
91
  appendToBody?: boolean;
89
92
  /**
90
93
  * Bulma color modifier for the field, also carried by the calendar, where it
@@ -70,7 +70,10 @@ export interface DateTimeInputBaseProps extends Omit<React.InputHTMLAttributes<H
70
70
  closeOnSelect?: boolean;
71
71
  /** Popover anchor position. */
72
72
  position?: PickerPosition;
73
- /** Render the popover into `document.body` via portal. */
73
+ /**
74
+ * Render the popover through a portal, into the `portalContainer` a
75
+ * `ConfigProvider` sets, `document.body` by default.
76
+ */
74
77
  appendToBody?: boolean;
75
78
  /**
76
79
  * Bulma color modifier for the input, also carried by the calendar and the
@@ -128,7 +131,10 @@ export interface DateTimeInputBaseProps extends Omit<React.InputHTMLAttributes<H
128
131
  audioTick?: boolean;
129
132
  /** Auto-route tactile feedback per wheel tick (vibrate on Android, audio thunk on iOS). Default `false`. */
130
133
  haptics?: boolean;
131
- /** Optional translatable string overrides. */
134
+ /**
135
+ * Optional translatable string overrides. In a 12-hour picker, `ampm`
136
+ * names the AM/PM column, `'AM/PM'` by default.
137
+ */
132
138
  labels?: PickerLabels;
133
139
  }
134
140
  /**
@@ -64,7 +64,8 @@ export interface TimeInputBaseProps extends Omit<React.InputHTMLAttributes<HTMLI
64
64
  /** Popover anchor position relative to the input. */
65
65
  position?: PickerPosition;
66
66
  /**
67
- * Render the popover into `document.body` via portal. On a narrow screen
67
+ * Render the popover through a portal, into the `portalContainer` a
68
+ * `ConfigProvider` sets, `document.body` by default. On a narrow screen
68
69
  * an in-place popover spans the bottom of the viewport, while a portaled
69
70
  * one stays on its `position` corner.
70
71
  */
@@ -81,7 +82,7 @@ export interface TimeInputBaseProps extends Omit<React.InputHTMLAttributes<HTMLI
81
82
  size?: 'small' | 'medium' | 'large';
82
83
  /** Render the input with rounded corners. */
83
84
  isRounded?: boolean;
84
- /** Hour format. `'12'` shows an AM/PM toggle. */
85
+ /** Hour format. `'12'` adds an AM/PM column to the wheels. */
85
86
  hourFormat?: HourFormat;
86
87
  /** Show a seconds column. Note: iOS Safari's native time picker UI does not include a seconds wheel; pass `mobileNative={false}` if you need one on iOS. */
87
88
  enableSeconds?: boolean;
@@ -104,7 +105,10 @@ export interface TimeInputBaseProps extends Omit<React.InputHTMLAttributes<HTMLI
104
105
  triggerIcon?: boolean;
105
106
  /** Glyph for the right launcher button. */
106
107
  triggerIconName?: string;
107
- /** Optional translatable string overrides. */
108
+ /**
109
+ * Optional translatable string overrides. In a 12-hour picker, `ampm`
110
+ * names the AM/PM column, `'AM/PM'` by default.
111
+ */
108
112
  labels?: PickerLabels;
109
113
  /** Play a short audible click on each wheel-item crossing. Substitute for haptic feedback on iOS Safari (which has no web haptic API as of May 2026); on Android, `navigator.vibrate(5)` fires automatically regardless. */
110
114
  audioTick?: boolean;
@@ -49,13 +49,24 @@ export interface PickerLabels {
49
49
  hours?: string;
50
50
  minutes?: string;
51
51
  seconds?: string;
52
+ /**
53
+ * Time wheels: names the AM/PM column a 12-hour picker shows.
54
+ * @defaultValue 'AM/PM'
55
+ */
52
56
  ampm?: string;
57
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
53
58
  increaseHours?: string;
59
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
54
60
  decreaseHours?: string;
61
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
55
62
  increaseMinutes?: string;
63
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
56
64
  decreaseMinutes?: string;
65
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
57
66
  increaseSeconds?: string;
67
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
58
68
  decreaseSeconds?: string;
69
+ /** @deprecated Rendered nowhere: no picker reads it. It goes in the next major. */
59
70
  toggleAmPm?: string;
60
71
  chooseTime?: string;
61
72
  chooseDateTime?: string;
@@ -72,5 +83,9 @@ export interface PickerLabels {
72
83
  time?: string;
73
84
  }
74
85
  export declare const DEFAULT_PICKER_LABELS: Required<PickerLabels>;
75
- /** Merge user-supplied label overrides with the defaults. */
86
+ /**
87
+ * Merge user-supplied label overrides with the defaults. A key set to
88
+ * `undefined` keeps its default, so a locale table that is missing a string
89
+ * still names its control instead of leaving it with no accessible name.
90
+ */
76
91
  export declare const mergeLabels: (overrides?: PickerLabels) => Required<PickerLabels>;
@@ -3,13 +3,14 @@ import React, { ReactNode } from 'react';
3
3
  type IconLibrary = 'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols';
4
4
  /**
5
5
  * Shape of the configuration context value.
6
- *
7
- * @property {string} [classPrefix] - Prefix applied to all Bulma class names.
8
- * @property {IconLibrary} [iconLibrary] - Default icon library for Icon components.
9
6
  */
10
7
  export interface ConfigContextProps {
8
+ /** Prefix applied to all Bulma class names. */
11
9
  classPrefix?: string;
10
+ /** Default icon library for Icon components. */
12
11
  iconLibrary?: IconLibrary;
12
+ /** Where portaled content goes when it has no target of its own. */
13
+ portalContainer?: string | HTMLElement;
13
14
  }
14
15
  /**
15
16
  * Hook to access the bulma-ui configuration context.
@@ -28,10 +29,40 @@ export interface ConfigProviderProps {
28
29
  classPrefix?: string;
29
30
  /** Default icon library for Icon components. */
30
31
  iconLibrary?: IconLibrary;
32
+ /**
33
+ * Where portaled content goes when it has no target of its own: what a
34
+ * `Portal` without a `container` renders, and what the library's components
35
+ * portal, such as Popover's `appendToBody` panel, a `Modal` with `portal`
36
+ * set to `true`, or a `Toast`. An element, or a `document.querySelector`
37
+ * selector. Unset, or a selector that matches nothing, that content goes to
38
+ * `document.body`. A target a component is given, such as a `Toast`'s
39
+ * `container`, still wins, and nothing portals that would otherwise render
40
+ * in place.
41
+ *
42
+ * The overlays and panels this moves are `position: fixed`, so pick an
43
+ * element with no ancestor that has a `transform`, `filter`,
44
+ * `backdrop-filter`, `perspective`, `will-change: transform`, or a
45
+ * `contain` that includes `paint` or `layout`. That ancestor becomes their
46
+ * containing block, and they cover or line up against it instead of the
47
+ * viewport. An ancestor that starts a stacking context, with a `z-index` or
48
+ * `isolation: isolate`, keeps them inside it, under anything the page
49
+ * stacks above it. `NotificationContainer`'s status region moves too, so
50
+ * this also decides where its announcements come from, and an `aria-hidden`
51
+ * ancestor silences them.
52
+ *
53
+ * A selector can't find an element inside a shadow root, so pass the
54
+ * element itself there, held in state from a ref callback. Content that
55
+ * portals before the element is set goes to `document.body` and moves when
56
+ * it is, which remounts it, as `Portal`'s `container` describes.
57
+ */
58
+ portalContainer?: string | HTMLElement;
31
59
  }
32
60
  /**
33
61
  * ConfigProvider injects configuration into all child components via React context.
34
62
  *
63
+ * A nested provider replaces the outer one's settings rather than adding to
64
+ * them, so inside it any setting it leaves out is back to its default.
65
+ *
35
66
  * @function
36
67
  * @param {ConfigProviderProps} props - Provider props.
37
68
  * @returns {JSX.Element} The context provider wrapping children.
@@ -14,6 +14,22 @@ import React from 'react';
14
14
  * @returns The resolved DOM node to portal into.
15
15
  */
16
16
  export declare function resolvePortalContainer(container?: string | HTMLElement): HTMLElement;
17
+ /**
18
+ * Where a component's portal goes, as a function to call when the portal is
19
+ * created: the target the component was given, else the `portalContainer` a
20
+ * `ConfigProvider` sets, else `document.body`, each read as
21
+ * `resolvePortalContainer` reads it. A component that portals resolves its
22
+ * target through this, so the provider's default reaches it.
23
+ *
24
+ * The hook only reads context, so it is safe to call on the server, ahead of
25
+ * any early return. The function it returns reads the DOM, so call it only
26
+ * where the portal is created, which the server never reaches.
27
+ *
28
+ * @function usePortalContainer
29
+ * @returns A function that takes the component's own target, if any, and
30
+ * returns the DOM node to portal into.
31
+ */
32
+ export declare function usePortalContainer(): (container?: string | HTMLElement) => HTMLElement;
17
33
  /**
18
34
  * Props for the Portal component.
19
35
  */
@@ -22,8 +38,10 @@ export interface PortalProps {
22
38
  children?: React.ReactNode;
23
39
  /**
24
40
  * Where the content goes: an element, or a `document.querySelector`
25
- * selector. Omitted, empty, or a selector that matches nothing, it goes to
26
- * `document.body`. A selector is looked up again on each render, so the
41
+ * selector. Omitted or empty, it goes to the `portalContainer` a
42
+ * `ConfigProvider` sets, and to `document.body` when none is set. A
43
+ * selector that matches nothing means `document.body` too. A selector is
44
+ * looked up again on each render, so the
27
45
  * content follows the target when it changes. Moving to another target
28
46
  * remounts the children and resets their state, which includes a selector
29
47
  * that only starts matching after the content has shown in `document.body`.
@@ -39,7 +57,7 @@ export interface PortalProps {
39
57
  disabled?: boolean;
40
58
  }
41
59
  /**
42
- * Renders its children into another part of the page, `document.body` unless `container` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.
60
+ * Renders its children into another part of the page, `document.body` unless `container` or a `ConfigProvider` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.
43
61
  *
44
62
  * React's server renderer can't render a portal, so `Portal` renders nothing
45
63
  * on the server and during hydration, and mounts its children in the commit
@@ -50,8 +68,12 @@ export interface PortalProps {
50
68
  * portaled children, and their React events bubble through the React tree.
51
69
  * CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`
52
70
  * sets its variables on a wrapper element the portaled content has left, so
53
- * that content sees the page-level theme. Point `container` at an element
54
- * inside the themed area to keep it.
71
+ * that content sees the page-level theme, and styles scoped to a shadow root
72
+ * don't reach `document.body` at all. To keep them, portal into an element
73
+ * inside the themed area or the shadow root: pass it as `container`, or as
74
+ * the `portalContainer` of a `ConfigProvider` around that area. The second
75
+ * also reaches what the library's components portal, such as Popover's
76
+ * `appendToBody` panel or a `Modal` with `portal`.
55
77
  *
56
78
  * Tab order and focus follow the DOM too. Content portaled from inside a
57
79
  * focus trap is no longer inside the trapped element, so the trap neither