@allxsmith/bestax-bulma 5.31.0 → 5.33.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 (41) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Avatars.js +4 -21
  4. package/dist/esm/components/Avatars.js.map +1 -1
  5. package/dist/esm/components/Collapses.js +1 -20
  6. package/dist/esm/components/Collapses.js.map +1 -1
  7. package/dist/esm/components/SegmentedControl.js +230 -0
  8. package/dist/esm/components/SegmentedControl.js.map +1 -0
  9. package/dist/esm/elements/Kbd.js +86 -0
  10. package/dist/esm/elements/Kbd.js.map +1 -0
  11. package/dist/esm/elements/ToggleButton.js +2 -1
  12. package/dist/esm/elements/ToggleButton.js.map +1 -1
  13. package/dist/esm/helpers/flattenChildren.js +35 -0
  14. package/dist/esm/helpers/flattenChildren.js.map +1 -0
  15. package/dist/extras.css +1 -1
  16. package/dist/extras.css.map +1 -1
  17. package/dist/index.cjs +535 -246
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.esm.js +2 -0
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/types/components/SegmentedControl.d.ts +116 -0
  22. package/dist/types/elements/Kbd.d.ts +100 -0
  23. package/dist/types/elements/ToggleButton.d.ts +2 -1
  24. package/dist/types/helpers/flattenChildren.d.ts +16 -0
  25. package/dist/types/index.d.ts +2 -0
  26. package/dist/types-cjs/components/SegmentedControl.d.ts +116 -0
  27. package/dist/types-cjs/elements/Kbd.d.ts +100 -0
  28. package/dist/types-cjs/elements/ToggleButton.d.ts +2 -1
  29. package/dist/types-cjs/helpers/flattenChildren.d.ts +16 -0
  30. package/dist/types-cjs/index.d.ts +2 -0
  31. package/dist/versions/bestax-no-dark-mode.css +1 -1
  32. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  33. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  34. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  35. package/dist/versions/bestax-no-helpers.css +1 -1
  36. package/dist/versions/bestax-no-helpers.css.map +1 -1
  37. package/dist/versions/bestax-prefixed.css +1 -1
  38. package/dist/versions/bestax-prefixed.css.map +1 -1
  39. package/package.json +1 -1
  40. package/src/scss/elements/_index.scss +1 -0
  41. package/src/scss/elements/_kbd.scss +86 -0
package/dist/index.esm.js CHANGED
@@ -14,6 +14,7 @@ export { Navbar, NavbarBrand, NavbarBurger, NavbarDivider, NavbarDropdown, Navba
14
14
  export { Pagination, PaginationEllipsis, PaginationLink, PaginationList, PaginationNext, PaginationPrevious } from './esm/components/Pagination.js';
15
15
  export { Panel, PanelBlock, PanelButtonBlock, PanelCheckboxBlock, PanelHeading, PanelIcon, PanelInputBlock, PanelTabs } from './esm/components/Panel.js';
16
16
  export { Tab, TabContentItem, TabItem, TabList, Tabs, TabsContent } from './esm/components/Tabs.js';
17
+ export { SegmentedControl } from './esm/components/SegmentedControl.js';
17
18
  export { Loading } from './esm/components/Loading.js';
18
19
  export { Collapse } from './esm/components/Collapse.js';
19
20
  export { Collapses } from './esm/components/Collapses.js';
@@ -42,6 +43,7 @@ export { Figure } from './esm/elements/Figure.js';
42
43
  export { Icon } from './esm/elements/Icon.js';
43
44
  export { IconText } from './esm/elements/IconText.js';
44
45
  export { Image } from './esm/elements/Image.js';
46
+ export { Kbd, KbdGroup } from './esm/elements/Kbd.js';
45
47
  export { Link } from './esm/elements/Link.js';
46
48
  export { ListItem } from './esm/elements/ListItem.js';
47
49
  export { Loader } from './esm/elements/Loader.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,116 @@
1
+ import React from 'react';
2
+ import { type ButtonOwnProps } from '../elements/Button.js';
3
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
4
+ /**
5
+ * The fills the checked segment takes: `Button`'s colors, minus `text` and
6
+ * `ghost`, which don't fill, and `white`, `light`, `dark` and `black`, which in
7
+ * one theme or the other fill about as light or dark as an unchecked segment
8
+ * already is. The same set `ToggleButton` takes.
9
+ */
10
+ export type SegmentedControlColor = 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
11
+ /**
12
+ * Props for the SegmentedControl component. The helper props, the other `<div>`
13
+ * attributes and the `ref` all land on the row.
14
+ *
15
+ * @extraProp {string} [aria-label] - Names the group for a screen reader, such as "Text alignment". A radio group needs a name, so pass this or `aria-labelledby`, and a development build warns when it has neither.
16
+ * @extraProp {string} [aria-labelledby] - The id of a visible heading or label that names the group, in place of `aria-label`.
17
+ * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the row's `<div>`.
18
+ */
19
+ export interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | 'color' | 'role'>, Omit<BulmaClassesProps, 'color' | 'colorShade' | 'backgroundColor' | 'backgroundColorShade'> {
20
+ /**
21
+ * The checked segment's `value`, when you hold the state. Setting it makes
22
+ * the group controlled: picking a segment only calls `onChange`, and nothing
23
+ * changes until you pass the new value. `null` checks nothing, with the
24
+ * tab stop `defaultValue` describes for that. Pick this or `defaultValue`
25
+ * for the group's lifetime.
26
+ */
27
+ value?: string | null;
28
+ /**
29
+ * The segment checked to begin with, when the group holds its own state.
30
+ * Leave it out and nothing is checked until someone picks one, and Tab
31
+ * lands on the first enabled segment meanwhile. That fallback takes hold
32
+ * once the row has rendered in the browser: server markup with nothing
33
+ * checked has no tab stop until then, while a checked segment is the stop
34
+ * from the server markup on.
35
+ */
36
+ defaultValue?: string;
37
+ /**
38
+ * Called with the newly checked segment's `value`, whether or not `value`
39
+ * is set. The arrow keys, Home and End check the segment they move to, so
40
+ * each of those calls it too: the check follows focus, as in a native radio
41
+ * group. Pressing the checked segment again doesn't call it, since a
42
+ * segmented control can't be cleared: one stays checked once one is.
43
+ */
44
+ onChange?: (value: string) => void;
45
+ /**
46
+ * The checked segment's fill. The others are plain buttons, so the fill is
47
+ * the difference people see. Takes the same colors as `ToggleButton`, for
48
+ * the same reason: `white`, `light`, `dark` and `black` fill about as light
49
+ * or dark as a plain button already is in one theme or the other.
50
+ */
51
+ color?: SegmentedControlColor;
52
+ /** Size of every segment, through Bulma's `are-<size>` on the row. */
53
+ size?: 'small' | 'medium' | 'large';
54
+ /**
55
+ * Joins the segments into one row with no gap between them, Bulma's
56
+ * `has-addons`. Set it to `false` for separate buttons.
57
+ */
58
+ hasAddons?: boolean;
59
+ /** Centers the row. */
60
+ isCentered?: boolean;
61
+ /** Aligns the row to the right. */
62
+ isRight?: boolean;
63
+ /** Additional CSS classes to apply. */
64
+ className?: string;
65
+ /** The `SegmentedControl.Segment`s, each with a `value` of its own. */
66
+ children?: React.ReactNode;
67
+ }
68
+ /**
69
+ * Props for SegmentedControl.Segment. The helper props, the other button
70
+ * attributes and the `ref` all land on the `<button>`.
71
+ *
72
+ * Some of `Button`'s props are left out on purpose. `as`, `type`, `role` and
73
+ * `tabIndex`, since a segment is always a `<button type="button" role="radio">`
74
+ * and the group decides which segment Tab reaches. `color`, which the group
75
+ * sets for the checked segment, and the props that change the fill
76
+ * (`isActive`, `isLight`, `isOutlined`, `isInverted`, `textColor`, `bgColor`
77
+ * and their shades), since each would color it whether checked or not. `size`
78
+ * and the width and shape props, which the row sets for every segment. And
79
+ * `isStatic` and `isLoading`, a segment you couldn't pick.
80
+ *
81
+ * @extraProp {React.Ref<HTMLButtonElement>} [ref] - Ref forwarded to the `<button>`.
82
+ */
83
+ export interface SegmentedControlSegmentProps extends Omit<ButtonOwnProps, 'color' | 'size' | 'isActive' | 'isStatic' | 'isLoading' | 'isLight' | 'isOutlined' | 'isInverted' | 'isRounded' | 'isFullwidth' | 'isFullWidth' | 'textColor' | 'bgColor' | 'colorShade' | 'backgroundColorShade'>, Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps | 'type' | 'value' | 'role' | 'tabIndex' | 'aria-checked' | 'aria-pressed'> {
84
+ /**
85
+ * **Required.** What `onChange` reports when this segment is checked, and
86
+ * what the group's `value` and `defaultValue` name it by. Unique within the
87
+ * group.
88
+ */
89
+ value: string;
90
+ /**
91
+ * The label. An icon on its own needs an `aria-label`, so a screen reader
92
+ * has something to say.
93
+ */
94
+ children?: React.ReactNode;
95
+ /**
96
+ * Disables the segment, the same as `disabled`: it can't be clicked, the
97
+ * arrow keys, Home and End skip it, and it never holds the row's tab stop.
98
+ * A checked one keeps its fill under Bulma's disabled look.
99
+ */
100
+ isDisabled?: boolean;
101
+ /**
102
+ * Not accepted: `aria-checked` follows the group's value. Declared because
103
+ * JSX lets a hyphenated attribute through when the props don't name it.
104
+ * @internal
105
+ */
106
+ 'aria-checked'?: never;
107
+ /**
108
+ * Not accepted: a segment is a radio, which says checked, not pressed.
109
+ * @internal
110
+ */
111
+ 'aria-pressed'?: never;
112
+ }
113
+ export declare const SegmentedControl: React.ForwardRefExoticComponent<SegmentedControlProps & React.RefAttributes<HTMLDivElement>> & {
114
+ Segment: React.ForwardRefExoticComponent<SegmentedControlSegmentProps & React.RefAttributes<HTMLButtonElement>>;
115
+ };
116
+ export default SegmentedControl;
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps, validColors } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props for the Kbd component. The helper props, the other attributes and
5
+ * the `ref` land on the `<kbd>`.
6
+ *
7
+ * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the `<kbd>`.
8
+ */
9
+ export interface KbdProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
10
+ /** Additional CSS classes to apply. */
11
+ className?: string;
12
+ /**
13
+ * The key as it's printed on the keyboard: a word (`Ctrl`, `Esc`), a
14
+ * letter, or a symbol (`⌘`).
15
+ */
16
+ children?: React.ReactNode;
17
+ /**
18
+ * What a screen reader says in place of a symbol, in your app's language:
19
+ * `label="Command"` on `⌘`. The symbol is hidden from assistive tech with
20
+ * `aria-hidden`, and the label is read in its place, from text that's
21
+ * visually hidden. Use it for a glyph that isn't a word, such as `⌘`, `⌥`,
22
+ * `⇧`, `⌃` or `⏎`, and leave it off a key written as a word. Copying the
23
+ * key copies the label along with the glyph. Don't reach for `aria-label`
24
+ * instead: ARIA in HTML prohibits naming a `<kbd>`, so nothing obliges a
25
+ * screen reader to read it.
26
+ */
27
+ label?: string;
28
+ /**
29
+ * Text color helper. The key's edge and fill are mixed from its text
30
+ * color, so they follow it.
31
+ */
32
+ textColor?: (typeof validColors)[number] | 'inherit' | 'current';
33
+ /**
34
+ * Background color helper. It replaces the key's faint fill, and the text
35
+ * still follows the text around it, which turns light in dark mode, so pair
36
+ * it with a `textColor` that reads on that color in both schemes, such as
37
+ * `textColor="black"` on `bgColor="warning"`.
38
+ */
39
+ bgColor?: (typeof validColors)[number] | 'inherit' | 'current';
40
+ }
41
+ /**
42
+ * Props for Kbd.Group, keys pressed together or one after another. The
43
+ * group renders the outer `<kbd>` of a combination, and the helper props,
44
+ * the other attributes and the `ref` land on it.
45
+ *
46
+ * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the outer `<kbd>`.
47
+ */
48
+ export interface KbdGroupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
49
+ /** Additional CSS classes to apply. */
50
+ className?: string;
51
+ /**
52
+ * The keys, a `Kbd` each, in the order they're pressed. The group renders
53
+ * the outer `<kbd>` around them, so it doesn't go inside a `Kbd` of its
54
+ * own, and it puts the separator between them, so don't type one: a `+`
55
+ * of your own doubles up. A `null` or `false` child, or an empty Fragment,
56
+ * gets no separator, and the keys in a Fragment are separated like the
57
+ * rest. A component that renders nothing still gets one, since the group
58
+ * can't see what a child renders, so write a conditional key inline
59
+ * (`{isMac && <Kbd label="Command">⌘</Kbd>}`), not in a component of its
60
+ * own.
61
+ */
62
+ children?: React.ReactNode;
63
+ /**
64
+ * What goes between the keys, shown and read aloud, with a space either
65
+ * side. Use `'then'` for a sequence pressed one key after another. It's a
66
+ * string because a screen reader has to read it.
67
+ */
68
+ separator?: string;
69
+ /** Text color helper. The keys and separators inside follow it. */
70
+ textColor?: (typeof validColors)[number] | 'inherit' | 'current';
71
+ }
72
+ /**
73
+ * Keys pressed together or one after another, in the outer `<kbd>` HTML gives a combination, with the separator between each pair as text.
74
+ *
75
+ * It doesn't wrap in the middle and isn't drawn as a key itself. It sets no
76
+ * font size, so the keys in it are the size of a key on its own.
77
+ *
78
+ * @function
79
+ * @param {KbdGroupProps} props - Props for Kbd.Group.
80
+ * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the outer `<kbd>`.
81
+ * @returns {JSX.Element} The rendered combination.
82
+ *
83
+ * @example
84
+ * <Kbd.Group>
85
+ * <Kbd>Ctrl</Kbd>
86
+ * <Kbd>Shift</Kbd>
87
+ * <Kbd>P</Kbd>
88
+ * </Kbd.Group>
89
+ *
90
+ * @example
91
+ * <Kbd.Group separator="then">
92
+ * <Kbd>G</Kbd>
93
+ * <Kbd>I</Kbd>
94
+ * </Kbd.Group>
95
+ */
96
+ export declare const KbdGroup: React.ForwardRefExoticComponent<KbdGroupProps & React.RefAttributes<HTMLElement>>;
97
+ export declare const Kbd: React.ForwardRefExoticComponent<KbdProps & React.RefAttributes<HTMLElement>> & {
98
+ Group: React.ForwardRefExoticComponent<KbdGroupProps & React.RefAttributes<HTMLElement>>;
99
+ };
100
+ export default Kbd;
@@ -78,7 +78,8 @@ export interface ToggleButtonProps extends Omit<ButtonOwnProps, 'color' | 'isAct
78
78
  * carries no form value: a setting saved with a form is a `Checkbox` or a
79
79
  * `Switch`. A set of toggles that each turn on and off on their own goes in
80
80
  * `Buttons hasAddons` with `role="group"` and an `aria-label`. A set where only
81
- * one can be on is a radio group rather than a row of these: use `Radios`.
81
+ * one can be on is a radio group rather than a row of these: use
82
+ * `SegmentedControl`, or `Radios` for a choice that's sent with a form.
82
83
  *
83
84
  * @function
84
85
  * @param {ToggleButtonProps} props - Props for the ToggleButton component.
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ /**
3
+ * A component's children as a flat list, with each Fragment opened up
4
+ * (recursively) so the items inside one count one by one rather than as the
5
+ * Fragment. `Children.toArray` already drops `null`, `undefined` and
6
+ * booleans and flattens arrays, but it keeps a Fragment whole, so an empty
7
+ * one would still count as an item and two items in one would count as one.
8
+ *
9
+ * `Children.toArray` keys restart at ".0" inside each Fragment, so the items
10
+ * in one are re-keyed with the Fragment's own key as a prefix. Otherwise an
11
+ * item in a Fragment and a sibling outside it could share a key.
12
+ *
13
+ * Text and numbers pass through as they are, so a caller that wants only
14
+ * elements filters with `React.isValidElement`.
15
+ */
16
+ export declare function flattenChildren(children: React.ReactNode, keyPrefix?: string): React.ReactNode[];
@@ -13,6 +13,7 @@ export * from './components/Navbar.js';
13
13
  export * from './components/Pagination.js';
14
14
  export * from './components/Panel.js';
15
15
  export * from './components/Tabs.js';
16
+ export * from './components/SegmentedControl.js';
16
17
  export * from './components/Loading.js';
17
18
  export * from './components/Collapse.js';
18
19
  export * from './components/Collapses.js';
@@ -41,6 +42,7 @@ export * from './elements/Figure.js';
41
42
  export * from './elements/Icon.js';
42
43
  export * from './elements/IconText.js';
43
44
  export * from './elements/Image.js';
45
+ export * from './elements/Kbd.js';
44
46
  export * from './elements/Link.js';
45
47
  export * from './elements/ListItem.js';
46
48
  export * from './elements/Loader.js';
@@ -0,0 +1,116 @@
1
+ import React from 'react';
2
+ import { type ButtonOwnProps } from '../elements/Button.js';
3
+ import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
4
+ /**
5
+ * The fills the checked segment takes: `Button`'s colors, minus `text` and
6
+ * `ghost`, which don't fill, and `white`, `light`, `dark` and `black`, which in
7
+ * one theme or the other fill about as light or dark as an unchecked segment
8
+ * already is. The same set `ToggleButton` takes.
9
+ */
10
+ export type SegmentedControlColor = 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
11
+ /**
12
+ * Props for the SegmentedControl component. The helper props, the other `<div>`
13
+ * attributes and the `ref` all land on the row.
14
+ *
15
+ * @extraProp {string} [aria-label] - Names the group for a screen reader, such as "Text alignment". A radio group needs a name, so pass this or `aria-labelledby`, and a development build warns when it has neither.
16
+ * @extraProp {string} [aria-labelledby] - The id of a visible heading or label that names the group, in place of `aria-label`.
17
+ * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the row's `<div>`.
18
+ */
19
+ export interface SegmentedControlProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | 'color' | 'role'>, Omit<BulmaClassesProps, 'color' | 'colorShade' | 'backgroundColor' | 'backgroundColorShade'> {
20
+ /**
21
+ * The checked segment's `value`, when you hold the state. Setting it makes
22
+ * the group controlled: picking a segment only calls `onChange`, and nothing
23
+ * changes until you pass the new value. `null` checks nothing, with the
24
+ * tab stop `defaultValue` describes for that. Pick this or `defaultValue`
25
+ * for the group's lifetime.
26
+ */
27
+ value?: string | null;
28
+ /**
29
+ * The segment checked to begin with, when the group holds its own state.
30
+ * Leave it out and nothing is checked until someone picks one, and Tab
31
+ * lands on the first enabled segment meanwhile. That fallback takes hold
32
+ * once the row has rendered in the browser: server markup with nothing
33
+ * checked has no tab stop until then, while a checked segment is the stop
34
+ * from the server markup on.
35
+ */
36
+ defaultValue?: string;
37
+ /**
38
+ * Called with the newly checked segment's `value`, whether or not `value`
39
+ * is set. The arrow keys, Home and End check the segment they move to, so
40
+ * each of those calls it too: the check follows focus, as in a native radio
41
+ * group. Pressing the checked segment again doesn't call it, since a
42
+ * segmented control can't be cleared: one stays checked once one is.
43
+ */
44
+ onChange?: (value: string) => void;
45
+ /**
46
+ * The checked segment's fill. The others are plain buttons, so the fill is
47
+ * the difference people see. Takes the same colors as `ToggleButton`, for
48
+ * the same reason: `white`, `light`, `dark` and `black` fill about as light
49
+ * or dark as a plain button already is in one theme or the other.
50
+ */
51
+ color?: SegmentedControlColor;
52
+ /** Size of every segment, through Bulma's `are-<size>` on the row. */
53
+ size?: 'small' | 'medium' | 'large';
54
+ /**
55
+ * Joins the segments into one row with no gap between them, Bulma's
56
+ * `has-addons`. Set it to `false` for separate buttons.
57
+ */
58
+ hasAddons?: boolean;
59
+ /** Centers the row. */
60
+ isCentered?: boolean;
61
+ /** Aligns the row to the right. */
62
+ isRight?: boolean;
63
+ /** Additional CSS classes to apply. */
64
+ className?: string;
65
+ /** The `SegmentedControl.Segment`s, each with a `value` of its own. */
66
+ children?: React.ReactNode;
67
+ }
68
+ /**
69
+ * Props for SegmentedControl.Segment. The helper props, the other button
70
+ * attributes and the `ref` all land on the `<button>`.
71
+ *
72
+ * Some of `Button`'s props are left out on purpose. `as`, `type`, `role` and
73
+ * `tabIndex`, since a segment is always a `<button type="button" role="radio">`
74
+ * and the group decides which segment Tab reaches. `color`, which the group
75
+ * sets for the checked segment, and the props that change the fill
76
+ * (`isActive`, `isLight`, `isOutlined`, `isInverted`, `textColor`, `bgColor`
77
+ * and their shades), since each would color it whether checked or not. `size`
78
+ * and the width and shape props, which the row sets for every segment. And
79
+ * `isStatic` and `isLoading`, a segment you couldn't pick.
80
+ *
81
+ * @extraProp {React.Ref<HTMLButtonElement>} [ref] - Ref forwarded to the `<button>`.
82
+ */
83
+ export interface SegmentedControlSegmentProps extends Omit<ButtonOwnProps, 'color' | 'size' | 'isActive' | 'isStatic' | 'isLoading' | 'isLight' | 'isOutlined' | 'isInverted' | 'isRounded' | 'isFullwidth' | 'isFullWidth' | 'textColor' | 'bgColor' | 'colorShade' | 'backgroundColorShade'>, Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps | 'type' | 'value' | 'role' | 'tabIndex' | 'aria-checked' | 'aria-pressed'> {
84
+ /**
85
+ * **Required.** What `onChange` reports when this segment is checked, and
86
+ * what the group's `value` and `defaultValue` name it by. Unique within the
87
+ * group.
88
+ */
89
+ value: string;
90
+ /**
91
+ * The label. An icon on its own needs an `aria-label`, so a screen reader
92
+ * has something to say.
93
+ */
94
+ children?: React.ReactNode;
95
+ /**
96
+ * Disables the segment, the same as `disabled`: it can't be clicked, the
97
+ * arrow keys, Home and End skip it, and it never holds the row's tab stop.
98
+ * A checked one keeps its fill under Bulma's disabled look.
99
+ */
100
+ isDisabled?: boolean;
101
+ /**
102
+ * Not accepted: `aria-checked` follows the group's value. Declared because
103
+ * JSX lets a hyphenated attribute through when the props don't name it.
104
+ * @internal
105
+ */
106
+ 'aria-checked'?: never;
107
+ /**
108
+ * Not accepted: a segment is a radio, which says checked, not pressed.
109
+ * @internal
110
+ */
111
+ 'aria-pressed'?: never;
112
+ }
113
+ export declare const SegmentedControl: React.ForwardRefExoticComponent<SegmentedControlProps & React.RefAttributes<HTMLDivElement>> & {
114
+ Segment: React.ForwardRefExoticComponent<SegmentedControlSegmentProps & React.RefAttributes<HTMLButtonElement>>;
115
+ };
116
+ export default SegmentedControl;
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps, validColors } from '../helpers/useBulmaClasses.js';
3
+ /**
4
+ * Props for the Kbd component. The helper props, the other attributes and
5
+ * the `ref` land on the `<kbd>`.
6
+ *
7
+ * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the `<kbd>`.
8
+ */
9
+ export interface KbdProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
10
+ /** Additional CSS classes to apply. */
11
+ className?: string;
12
+ /**
13
+ * The key as it's printed on the keyboard: a word (`Ctrl`, `Esc`), a
14
+ * letter, or a symbol (`⌘`).
15
+ */
16
+ children?: React.ReactNode;
17
+ /**
18
+ * What a screen reader says in place of a symbol, in your app's language:
19
+ * `label="Command"` on `⌘`. The symbol is hidden from assistive tech with
20
+ * `aria-hidden`, and the label is read in its place, from text that's
21
+ * visually hidden. Use it for a glyph that isn't a word, such as `⌘`, `⌥`,
22
+ * `⇧`, `⌃` or `⏎`, and leave it off a key written as a word. Copying the
23
+ * key copies the label along with the glyph. Don't reach for `aria-label`
24
+ * instead: ARIA in HTML prohibits naming a `<kbd>`, so nothing obliges a
25
+ * screen reader to read it.
26
+ */
27
+ label?: string;
28
+ /**
29
+ * Text color helper. The key's edge and fill are mixed from its text
30
+ * color, so they follow it.
31
+ */
32
+ textColor?: (typeof validColors)[number] | 'inherit' | 'current';
33
+ /**
34
+ * Background color helper. It replaces the key's faint fill, and the text
35
+ * still follows the text around it, which turns light in dark mode, so pair
36
+ * it with a `textColor` that reads on that color in both schemes, such as
37
+ * `textColor="black"` on `bgColor="warning"`.
38
+ */
39
+ bgColor?: (typeof validColors)[number] | 'inherit' | 'current';
40
+ }
41
+ /**
42
+ * Props for Kbd.Group, keys pressed together or one after another. The
43
+ * group renders the outer `<kbd>` of a combination, and the helper props,
44
+ * the other attributes and the `ref` land on it.
45
+ *
46
+ * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the outer `<kbd>`.
47
+ */
48
+ export interface KbdGroupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
49
+ /** Additional CSS classes to apply. */
50
+ className?: string;
51
+ /**
52
+ * The keys, a `Kbd` each, in the order they're pressed. The group renders
53
+ * the outer `<kbd>` around them, so it doesn't go inside a `Kbd` of its
54
+ * own, and it puts the separator between them, so don't type one: a `+`
55
+ * of your own doubles up. A `null` or `false` child, or an empty Fragment,
56
+ * gets no separator, and the keys in a Fragment are separated like the
57
+ * rest. A component that renders nothing still gets one, since the group
58
+ * can't see what a child renders, so write a conditional key inline
59
+ * (`{isMac && <Kbd label="Command">⌘</Kbd>}`), not in a component of its
60
+ * own.
61
+ */
62
+ children?: React.ReactNode;
63
+ /**
64
+ * What goes between the keys, shown and read aloud, with a space either
65
+ * side. Use `'then'` for a sequence pressed one key after another. It's a
66
+ * string because a screen reader has to read it.
67
+ */
68
+ separator?: string;
69
+ /** Text color helper. The keys and separators inside follow it. */
70
+ textColor?: (typeof validColors)[number] | 'inherit' | 'current';
71
+ }
72
+ /**
73
+ * Keys pressed together or one after another, in the outer `<kbd>` HTML gives a combination, with the separator between each pair as text.
74
+ *
75
+ * It doesn't wrap in the middle and isn't drawn as a key itself. It sets no
76
+ * font size, so the keys in it are the size of a key on its own.
77
+ *
78
+ * @function
79
+ * @param {KbdGroupProps} props - Props for Kbd.Group.
80
+ * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the outer `<kbd>`.
81
+ * @returns {JSX.Element} The rendered combination.
82
+ *
83
+ * @example
84
+ * <Kbd.Group>
85
+ * <Kbd>Ctrl</Kbd>
86
+ * <Kbd>Shift</Kbd>
87
+ * <Kbd>P</Kbd>
88
+ * </Kbd.Group>
89
+ *
90
+ * @example
91
+ * <Kbd.Group separator="then">
92
+ * <Kbd>G</Kbd>
93
+ * <Kbd>I</Kbd>
94
+ * </Kbd.Group>
95
+ */
96
+ export declare const KbdGroup: React.ForwardRefExoticComponent<KbdGroupProps & React.RefAttributes<HTMLElement>>;
97
+ export declare const Kbd: React.ForwardRefExoticComponent<KbdProps & React.RefAttributes<HTMLElement>> & {
98
+ Group: React.ForwardRefExoticComponent<KbdGroupProps & React.RefAttributes<HTMLElement>>;
99
+ };
100
+ export default Kbd;
@@ -78,7 +78,8 @@ export interface ToggleButtonProps extends Omit<ButtonOwnProps, 'color' | 'isAct
78
78
  * carries no form value: a setting saved with a form is a `Checkbox` or a
79
79
  * `Switch`. A set of toggles that each turn on and off on their own goes in
80
80
  * `Buttons hasAddons` with `role="group"` and an `aria-label`. A set where only
81
- * one can be on is a radio group rather than a row of these: use `Radios`.
81
+ * one can be on is a radio group rather than a row of these: use
82
+ * `SegmentedControl`, or `Radios` for a choice that's sent with a form.
82
83
  *
83
84
  * @function
84
85
  * @param {ToggleButtonProps} props - Props for the ToggleButton component.
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ /**
3
+ * A component's children as a flat list, with each Fragment opened up
4
+ * (recursively) so the items inside one count one by one rather than as the
5
+ * Fragment. `Children.toArray` already drops `null`, `undefined` and
6
+ * booleans and flattens arrays, but it keeps a Fragment whole, so an empty
7
+ * one would still count as an item and two items in one would count as one.
8
+ *
9
+ * `Children.toArray` keys restart at ".0" inside each Fragment, so the items
10
+ * in one are re-keyed with the Fragment's own key as a prefix. Otherwise an
11
+ * item in a Fragment and a sibling outside it could share a key.
12
+ *
13
+ * Text and numbers pass through as they are, so a caller that wants only
14
+ * elements filters with `React.isValidElement`.
15
+ */
16
+ export declare function flattenChildren(children: React.ReactNode, keyPrefix?: string): React.ReactNode[];
@@ -13,6 +13,7 @@ export * from './components/Navbar.js';
13
13
  export * from './components/Pagination.js';
14
14
  export * from './components/Panel.js';
15
15
  export * from './components/Tabs.js';
16
+ export * from './components/SegmentedControl.js';
16
17
  export * from './components/Loading.js';
17
18
  export * from './components/Collapse.js';
18
19
  export * from './components/Collapses.js';
@@ -41,6 +42,7 @@ export * from './elements/Figure.js';
41
42
  export * from './elements/Icon.js';
42
43
  export * from './elements/IconText.js';
43
44
  export * from './elements/Image.js';
45
+ export * from './elements/Kbd.js';
44
46
  export * from './elements/Link.js';
45
47
  export * from './elements/ListItem.js';
46
48
  export * from './elements/Loader.js';