@allxsmith/bestax-bulma 5.37.0 → 5.38.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.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/Card.js +2 -2
- package/dist/esm/components/Carousel.js +14 -6
- package/dist/esm/components/Carousel.js.map +1 -1
- package/dist/esm/components/Dropdown.js +7 -2
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/Loading.js +7 -1
- package/dist/esm/components/Loading.js.map +1 -1
- package/dist/esm/components/Panel.js +34 -4
- package/dist/esm/components/Panel.js.map +1 -1
- package/dist/esm/components/Popover.js +7 -2
- package/dist/esm/components/Popover.js.map +1 -1
- package/dist/esm/components/Sidebar.js +46 -17
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/form/Autocomplete.js +28 -18
- package/dist/esm/form/Autocomplete.js.map +1 -1
- package/dist/esm/form/Combobox.js +592 -0
- package/dist/esm/form/Combobox.js.map +1 -0
- package/dist/esm/form/Field.js +3 -3
- package/dist/esm/form/Field.js.map +1 -1
- package/dist/esm/form/_pickerInternals/PickerPopover.js +10 -5
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
- package/dist/esm/form/useAutoLabelId.js.map +1 -1
- package/dist/esm/helpers/Theme.js.map +1 -1
- package/dist/esm/helpers/useAnchoredPosition.js +35 -6
- package/dist/esm/helpers/useAnchoredPosition.js.map +1 -1
- package/dist/esm/helpers/useComboboxEngine.js +331 -0
- package/dist/esm/helpers/useComboboxEngine.js.map +1 -0
- package/dist/esm/helpers/useFocusTrap.js +87 -49
- package/dist/esm/helpers/useFocusTrap.js.map +1 -1
- package/dist/esm/helpers/useInertSiblings.js +106 -0
- package/dist/esm/helpers/useInertSiblings.js.map +1 -0
- package/dist/esm/helpers/useTreeView.js +2 -2
- package/dist/esm/layout/Container.js +2 -2
- package/dist/esm/layout/Container.js.map +1 -1
- package/dist/esm/layout/Hero.js +6 -6
- package/dist/esm/layout/Hero.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +1504 -351
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Loading.d.ts +16 -2
- package/dist/types/components/Panel.d.ts +45 -5
- package/dist/types/components/Sidebar.d.ts +17 -2
- package/dist/types/form/Combobox.d.ts +416 -0
- package/dist/types/form/Field.d.ts +5 -5
- package/dist/types/form/useAutoLabelId.d.ts +3 -2
- package/dist/types/helpers/Theme.d.ts +6 -0
- package/dist/types/helpers/useAnchoredPosition.d.ts +25 -2
- package/dist/types/helpers/useComboboxEngine.d.ts +111 -0
- package/dist/types/helpers/useFocusTrap.d.ts +15 -2
- package/dist/types/helpers/useInertSiblings.d.ts +30 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/layout/Container.d.ts +9 -1
- package/dist/types/layout/Hero.d.ts +27 -2
- package/dist/types-cjs/components/Loading.d.ts +16 -2
- package/dist/types-cjs/components/Panel.d.ts +45 -5
- package/dist/types-cjs/components/Sidebar.d.ts +17 -2
- package/dist/types-cjs/form/Combobox.d.ts +416 -0
- package/dist/types-cjs/form/Field.d.ts +5 -5
- package/dist/types-cjs/form/useAutoLabelId.d.ts +3 -2
- package/dist/types-cjs/helpers/Theme.d.ts +6 -0
- package/dist/types-cjs/helpers/useAnchoredPosition.d.ts +25 -2
- package/dist/types-cjs/helpers/useComboboxEngine.d.ts +111 -0
- package/dist/types-cjs/helpers/useFocusTrap.d.ts +15 -2
- package/dist/types-cjs/helpers/useInertSiblings.d.ts +30 -0
- package/dist/types-cjs/index.d.ts +1 -0
- package/dist/types-cjs/layout/Container.d.ts +9 -1
- package/dist/types-cjs/layout/Hero.d.ts +27 -2
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/form/_combobox.scss +323 -0
- package/src/scss/form/_index.scss +1 -0
|
@@ -10,6 +10,11 @@ export interface AnchoredPosition {
|
|
|
10
10
|
position: AnchoredCorner;
|
|
11
11
|
top?: number;
|
|
12
12
|
left?: number;
|
|
13
|
+
/**
|
|
14
|
+
* With `matchWidth`, the anchor's width, which a fixed panel takes as its
|
|
15
|
+
* `min-width`.
|
|
16
|
+
*/
|
|
17
|
+
minWidth?: number;
|
|
13
18
|
}
|
|
14
19
|
/**
|
|
15
20
|
* Options for `useAnchoredPosition`.
|
|
@@ -41,6 +46,23 @@ export interface UseAnchoredPositionOptions {
|
|
|
41
46
|
* well; the coordinates don't include it, because the stylesheet applies it.
|
|
42
47
|
*/
|
|
43
48
|
styledGap?: (panel: HTMLElement) => number;
|
|
49
|
+
/**
|
|
50
|
+
* Whether the panel is at least as wide as the anchor, as a list under its
|
|
51
|
+
* field is. A panel in place gets that from its stylesheet. A fixed one
|
|
52
|
+
* can't, so its placement carries the anchor's width as `minWidth` for the
|
|
53
|
+
* panel to set, and its coordinates and `auto` already allow for it.
|
|
54
|
+
* @defaultValue false
|
|
55
|
+
*/
|
|
56
|
+
matchWidth?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Measures again after each render of the component holding the hook, for
|
|
59
|
+
* a panel whose content changes while it's open, as a filtered list's
|
|
60
|
+
* does. A fixed panel above its anchor is placed from its height, and
|
|
61
|
+
* `auto` reads the height too, so a measurement taken when it opened goes
|
|
62
|
+
* stale as the content changes.
|
|
63
|
+
* @defaultValue false
|
|
64
|
+
*/
|
|
65
|
+
followContent?: boolean;
|
|
44
66
|
}
|
|
45
67
|
/**
|
|
46
68
|
* A `styledGap` for a panel whose stylesheet puts the gap in a margin on the
|
|
@@ -53,7 +75,8 @@ export declare function marginGap(panel: HTMLElement): number;
|
|
|
53
75
|
* and, for a panel fixed to the viewport, works out its coordinates. It
|
|
54
76
|
* measures again on resize and on any scroll of the anchor's window (an
|
|
55
77
|
* iframe's, when the anchor renders into one), so a fixed panel follows its
|
|
56
|
-
* anchor
|
|
78
|
+
* anchor, and with `followContent` after each render too. A measurement that
|
|
79
|
+
* changes nothing doesn't render again.
|
|
57
80
|
*
|
|
58
81
|
* Measuring happens in a layout effect, so the panel is placed before it
|
|
59
82
|
* paints. It needs both elements on the page while `active` is on, and
|
|
@@ -65,4 +88,4 @@ export declare function marginGap(panel: HTMLElement): number;
|
|
|
65
88
|
* @param options - Whether to measure, the corner asked for, and how the panel is placed.
|
|
66
89
|
* @returns The corner the panel opens from, with coordinates when it is fixed.
|
|
67
90
|
*/
|
|
68
|
-
export declare function useAnchoredPosition(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { active, position, fixed, offset, styledGap }: UseAnchoredPositionOptions): AnchoredPosition;
|
|
91
|
+
export declare function useAnchoredPosition(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { active, position, fixed, offset, styledGap, matchWidth, followContent, }: UseAnchoredPositionOptions): AnchoredPosition;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
/** What an item tells the engine about itself. */
|
|
3
|
+
export interface ComboboxItemState {
|
|
4
|
+
/** What a pick hands back. Unique within the combobox. */
|
|
5
|
+
value: string;
|
|
6
|
+
/** Reachable with the arrows, never picked. */
|
|
7
|
+
disabled: boolean;
|
|
8
|
+
/** The value, or one of them. */
|
|
9
|
+
checked: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Options for `useComboboxEngine`. */
|
|
12
|
+
export interface ComboboxEngineOptions {
|
|
13
|
+
/** Controlled open state. When set, opening and closing only report through `onOpenChange`. */
|
|
14
|
+
open?: boolean;
|
|
15
|
+
/** Initial open state when uncontrolled. */
|
|
16
|
+
defaultOpen: boolean;
|
|
17
|
+
/** Called with the open state asked for, when it differs from the current one. */
|
|
18
|
+
onOpenChange?: (open: boolean) => void;
|
|
19
|
+
/** Called with an item's `value` when it's picked. */
|
|
20
|
+
onSelect?: (value: string) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Called when Enter goes on to the form with nothing to pick, before the
|
|
23
|
+
* list closes, so an owner that shows something other than the typing can
|
|
24
|
+
* put it back before the form reads the field. An `inline` list doesn't
|
|
25
|
+
* close, so this is the one word it gets.
|
|
26
|
+
*/
|
|
27
|
+
onSettle?: () => void;
|
|
28
|
+
/** Highlights the first enabled item whenever the list opens or its items change. */
|
|
29
|
+
keepFirst: boolean;
|
|
30
|
+
/** Several values: a pick keeps the list open. */
|
|
31
|
+
multiple: boolean;
|
|
32
|
+
/** The list is always on screen, so nothing opens or closes it. */
|
|
33
|
+
inline: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The list's panel is portaled, so it has no server markup and shows only
|
|
36
|
+
* from the commit after hydration. Until it has rendered, an open list
|
|
37
|
+
* isn't taken to be on the page, so no `aria-controls` names it early.
|
|
38
|
+
*/
|
|
39
|
+
deferred: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** What `useComboboxEngine` hands the parts of a combobox. */
|
|
42
|
+
export interface ComboboxEngine {
|
|
43
|
+
/** Whether the list is open. Always, with `inline`. */
|
|
44
|
+
open: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The field's `aria-expanded`: open, with a listbox that has an option in
|
|
47
|
+
* it on the page. Until the open list has rendered, it's taken to have
|
|
48
|
+
* one, so server markup for an open list in place says it's expanded. A
|
|
49
|
+
* `deferred` list isn't in server markup, so it's taken to have none.
|
|
50
|
+
*/
|
|
51
|
+
expanded: boolean;
|
|
52
|
+
/** The highlighted option's value, if any. */
|
|
53
|
+
highlighted: string | null;
|
|
54
|
+
/** Whether the user has typed since the list opened. */
|
|
55
|
+
typed: boolean;
|
|
56
|
+
/** The listbox's id. */
|
|
57
|
+
listboxId: string;
|
|
58
|
+
/** An item's id, which follows from its value. */
|
|
59
|
+
itemId: (value: string) => string;
|
|
60
|
+
/** For the element around the field and, unless it's portaled, the list. */
|
|
61
|
+
rootRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
62
|
+
/** For the field. */
|
|
63
|
+
inputRef: React.MutableRefObject<HTMLInputElement | null>;
|
|
64
|
+
/** For the listbox. */
|
|
65
|
+
listboxRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Records the floating panel while it's on screen, which makes it count as
|
|
68
|
+
* inside, and makes an Escape that closes it stop there. Returns the
|
|
69
|
+
* function that forgets it.
|
|
70
|
+
*/
|
|
71
|
+
registerPopup: (element: HTMLElement) => () => void;
|
|
72
|
+
/** Records an item's element. Returns the function that forgets it. */
|
|
73
|
+
registerItem: (element: HTMLElement, state: ComboboxItemState) => () => void;
|
|
74
|
+
/** The field's keys, to run after the caller's own handler. */
|
|
75
|
+
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
76
|
+
/** A change to the field's value: the user typed. */
|
|
77
|
+
onChange: () => void;
|
|
78
|
+
/** A click in the field. */
|
|
79
|
+
onClick: () => void;
|
|
80
|
+
/** Focus leaving the field. */
|
|
81
|
+
onBlur: (event: React.FocusEvent<HTMLInputElement>) => void;
|
|
82
|
+
/** The pointer moved over an enabled option. */
|
|
83
|
+
hover: (value: string) => void;
|
|
84
|
+
/** A click on an enabled option. Focus ends up in the field. */
|
|
85
|
+
pick: (value: string) => void;
|
|
86
|
+
/** For anything in the list: a press there doesn't take focus from the field. */
|
|
87
|
+
keepFocus: (event: React.MouseEvent) => void;
|
|
88
|
+
/**
|
|
89
|
+
* For the floating panel: marks a press as inside, which React reports from
|
|
90
|
+
* content the panel portals elsewhere as well.
|
|
91
|
+
*/
|
|
92
|
+
markInside: (event: React.PointerEvent) => void;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The keys, the open state, the highlight and the ARIA of an editable
|
|
96
|
+
* combobox whose list the app renders and filters (#1083). DOM focus stays
|
|
97
|
+
* in the field the whole time: the highlight is `aria-activedescendant`, as
|
|
98
|
+
* the ARIA Authoring Practices ask of a combobox, where `useMenuKeys` moves
|
|
99
|
+
* real focus, as a menu should.
|
|
100
|
+
*
|
|
101
|
+
* The options are read from the listbox in document order whenever they're
|
|
102
|
+
* needed, so options in groups and options that come and go are found, and
|
|
103
|
+
* the highlight is remembered by value, so it survives a re-render. The text
|
|
104
|
+
* in the field and any value are the app's: a pick only calls
|
|
105
|
+
* `onSelect`.
|
|
106
|
+
*
|
|
107
|
+
* @function useComboboxEngine
|
|
108
|
+
* @param options - The open state, the pick callback and the shape.
|
|
109
|
+
* @returns The state and handlers the parts wire up.
|
|
110
|
+
*/
|
|
111
|
+
export declare function useComboboxEngine({ open: controlledOpen, defaultOpen, onOpenChange, onSelect, onSettle, keepFirst, multiple, inline, deferred, }: ComboboxEngineOptions): ComboboxEngine;
|
|
@@ -11,10 +11,23 @@ export declare function isTabbableKind(el: Element): boolean;
|
|
|
11
11
|
/**
|
|
12
12
|
* The first tab stop inside `container`, found the way the trap finds it, or
|
|
13
13
|
* `null` when there is none. For a component that moves focus into a panel
|
|
14
|
-
*
|
|
15
|
-
* module, so this one stays internal.
|
|
14
|
+
* itself rather than through the hook. `src/index.ts` names its exports from
|
|
15
|
+
* this module, so this one stays internal.
|
|
16
16
|
*/
|
|
17
17
|
export declare function firstTabStop(container: HTMLElement): HTMLElement | null;
|
|
18
|
+
/**
|
|
19
|
+
* Holds Tab inside `container` until the returned function is called. Tab
|
|
20
|
+
* and Shift+Tab heard on `keyTarget` wrap at the ends, unless something
|
|
21
|
+
* already marked the key used, and if a Tab the trap let through still takes
|
|
22
|
+
* focus out, it sends focus back to the other end.
|
|
23
|
+
*
|
|
24
|
+
* `holds` is asked on every Tab, and the trap leaves the key alone while it
|
|
25
|
+
* says no. Internal like `firstTabStop`. It's for an overlay that holds Tab
|
|
26
|
+
* from a listener of its own on `window` and asks the overlay stack first,
|
|
27
|
+
* so it stands aside while another overlay is open over it, which a trap
|
|
28
|
+
* listening on the container can't do.
|
|
29
|
+
*/
|
|
30
|
+
export declare function trapTab(container: HTMLElement, keyTarget?: EventTarget, holds?: () => boolean): () => void;
|
|
18
31
|
/**
|
|
19
32
|
* Options for `useFocusTrap`.
|
|
20
33
|
*/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Makes the elements beside `ref`'s element inert while `active` is true,
|
|
4
|
+
* and takes it off again when `active` turns false or the caller unmounts.
|
|
5
|
+
* With `wholePage`, it does the same beside each element above it up to
|
|
6
|
+
* `<body>`, so everything on the page but `ref`'s element is inert, the way a
|
|
7
|
+
* modal layer leaves it. The element itself and its own content are never
|
|
8
|
+
* touched.
|
|
9
|
+
*
|
|
10
|
+
* It sets the `inert` attribute through the DOM in an effect, so it works the
|
|
11
|
+
* same on React 18 and 19 and a server render has nothing to show for it. An
|
|
12
|
+
* element that was inert already is left alone, and keeps its `inert` once
|
|
13
|
+
* this lets go. It makes inert what's there when it turns on: an element that
|
|
14
|
+
* mounts beside it afterwards isn't. It follows the DOM, so content a web
|
|
15
|
+
* component renders around a slot this sits in, and text with no element of
|
|
16
|
+
* its own, stays as it is.
|
|
17
|
+
*
|
|
18
|
+
* Focus on an element that turns inert is lost: the browser moves it to
|
|
19
|
+
* `<body>`. So when focus was inside what this made inert, and is still on
|
|
20
|
+
* `<body>` when this lets go, it goes back to the element that had it. Focus
|
|
21
|
+
* this never took isn't handed anywhere, and focus the user or the app has
|
|
22
|
+
* put somewhere else meanwhile stays there.
|
|
23
|
+
*
|
|
24
|
+
* @function useInertSiblings
|
|
25
|
+
* @param ref - Ref to the element that stays reachable.
|
|
26
|
+
* @param active - Whether what's beside it is inert.
|
|
27
|
+
* @param wholePage - Whether that goes for the whole page rather than only
|
|
28
|
+
* the element's siblings.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useInertSiblings(ref: RefObject<Element | null>, active: boolean, wholePage: boolean): void;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ export * from './form/Slider.js';
|
|
|
81
81
|
export * from './form/Numberinput.js';
|
|
82
82
|
export * from './form/Rate.js';
|
|
83
83
|
export * from './form/Autocomplete.js';
|
|
84
|
+
export * from './form/Combobox.js';
|
|
84
85
|
export * from './form/Taginput.js';
|
|
85
86
|
export { InputBase } from './form/InputBase.js';
|
|
86
87
|
export type { InputBaseProps } from './form/InputBase.js';
|
|
@@ -7,7 +7,15 @@ export type ContainerBreakpoint = 'tablet' | 'desktop' | 'widescreen';
|
|
|
7
7
|
/**
|
|
8
8
|
* Props for the Container component.
|
|
9
9
|
*/
|
|
10
|
-
export interface ContainerProps extends React.HTMLAttributes<
|
|
10
|
+
export interface ContainerProps extends React.HTMLAttributes<HTMLElement>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
11
|
+
/**
|
|
12
|
+
* HTML element to render (default: `div`). Bulma pages often put the
|
|
13
|
+
* container on a landmark, such as `<main class="container">` or
|
|
14
|
+
* `<footer class="container">`. A page has only one visible `main`, and a
|
|
15
|
+
* `section` is a `region` landmark only once it has an accessible name
|
|
16
|
+
* (`aria-label`, or `aria-labelledby` pointing at its heading).
|
|
17
|
+
*/
|
|
18
|
+
as?: 'div' | 'main' | 'section' | 'article' | 'aside' | 'header' | 'footer' | 'nav';
|
|
11
19
|
/** Additional CSS classes. */
|
|
12
20
|
className?: string;
|
|
13
21
|
/** Text color helper. */
|
|
@@ -8,6 +8,15 @@ export type HeroSize = 'small' | 'medium' | 'large' | 'fullheight' | 'fullheight
|
|
|
8
8
|
* Props for the Hero component.
|
|
9
9
|
*/
|
|
10
10
|
export interface HeroProps extends React.HTMLAttributes<HTMLElement>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
11
|
+
/**
|
|
12
|
+
* HTML element to render (default: `section`). Bulma pages often put the
|
|
13
|
+
* hero on a landmark: `main` when the hero is the page's main content,
|
|
14
|
+
* `header` for a banner above it, `footer` for one below it. A page has
|
|
15
|
+
* only one visible `main`, and a `section` is a `region` landmark only once
|
|
16
|
+
* it has an accessible name (`aria-label`, or `aria-labelledby` pointing at
|
|
17
|
+
* its heading).
|
|
18
|
+
*/
|
|
19
|
+
as?: 'section' | 'div' | 'main' | 'header' | 'footer' | 'article' | 'aside';
|
|
11
20
|
/** Additional CSS classes. */
|
|
12
21
|
className?: string;
|
|
13
22
|
/**
|
|
@@ -37,7 +46,15 @@ export interface HeroProps extends React.HTMLAttributes<HTMLElement>, Omit<Bulma
|
|
|
37
46
|
/**
|
|
38
47
|
* Props for the HeroHead component.
|
|
39
48
|
*/
|
|
40
|
-
export interface HeroHeadProps extends React.HTMLAttributes<
|
|
49
|
+
export interface HeroHeadProps extends React.HTMLAttributes<HTMLElement>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
50
|
+
/**
|
|
51
|
+
* HTML element to render (default: `div`). `nav` suits a head that holds
|
|
52
|
+
* only the site's navigation. A `header` is a `banner` landmark only when
|
|
53
|
+
* no `section`, `article`, `aside`, `nav` or `main` is around it, so inside
|
|
54
|
+
* the default `<section>` hero it is not one: render the hero as a `div`
|
|
55
|
+
* for that. A `header` may not sit inside another `header` or a `footer`.
|
|
56
|
+
*/
|
|
57
|
+
as?: 'div' | 'header' | 'nav';
|
|
41
58
|
/** Additional CSS classes. */
|
|
42
59
|
className?: string;
|
|
43
60
|
/** Bulma color modifier for text. */
|
|
@@ -93,7 +110,15 @@ export declare const HeroBody: React.FC<HeroBodyProps>;
|
|
|
93
110
|
/**
|
|
94
111
|
* Props for the HeroFoot component.
|
|
95
112
|
*/
|
|
96
|
-
export interface HeroFootProps extends React.HTMLAttributes<
|
|
113
|
+
export interface HeroFootProps extends React.HTMLAttributes<HTMLElement>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
114
|
+
/**
|
|
115
|
+
* HTML element to render (default: `div`). `nav` suits a foot that holds
|
|
116
|
+
* tabs or links. A `footer` is a `contentinfo` landmark only when no
|
|
117
|
+
* `section`, `article`, `aside`, `nav` or `main` is around it, so inside
|
|
118
|
+
* the default `<section>` hero it is not one: render the hero as a `div`
|
|
119
|
+
* for that. A `footer` may not sit inside another `footer` or a `header`.
|
|
120
|
+
*/
|
|
121
|
+
as?: 'div' | 'footer' | 'nav';
|
|
97
122
|
/** Additional CSS classes. */
|
|
98
123
|
className?: string;
|
|
99
124
|
/** Bulma color modifier for text. */
|
|
@@ -14,10 +14,24 @@ export type LoadingColor = 'primary' | 'link' | 'info' | 'success' | 'warning' |
|
|
|
14
14
|
* @extraProp {string} [className] - Additional CSS classes.
|
|
15
15
|
*/
|
|
16
16
|
export interface LoadingProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size' | 'overlay'> {
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Whether the loading overlay is visible. While it is, what it covers is
|
|
19
|
+
* inert, out of reach of Tab, Enter, Space and screen readers as well as
|
|
20
|
+
* the mouse: the other children of the element it's rendered in, so render
|
|
21
|
+
* it directly inside the element it covers, or with `isFullPage` the rest
|
|
22
|
+
* of the page. Its own content, the cancel button included, stays
|
|
23
|
+
* reachable. Only what's there when it turns on is made inert, and an
|
|
24
|
+
* element that was inert already is left as it was. A control under it
|
|
25
|
+
* that had focus loses it, and gets it back when the loading goes away,
|
|
26
|
+
* unless focus has moved on in the meantime. Show one at a time over the
|
|
27
|
+
* same content: two that cover each other, such as two in one container
|
|
28
|
+
* or two full-page ones, make each other inert, cancel buttons and all.
|
|
29
|
+
*/
|
|
18
30
|
active?: boolean;
|
|
19
31
|
/**
|
|
20
|
-
* Cover the entire viewport.
|
|
32
|
+
* Cover the entire viewport. While it's active, the rest of the page is
|
|
33
|
+
* inert, as it is under a modal, rather than only the element it's
|
|
34
|
+
* rendered in. A full-page loading also takes its turn with
|
|
21
35
|
* Modal and Sidebar for Escape: while it's the topmost open overlay, the
|
|
22
36
|
* Modal or Sidebar under it doesn't answer Escape or hold Tab, whether or
|
|
23
37
|
* not the loading can be cancelled.
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
|
|
3
|
+
import type { ConstrainedPolymorphicComponentWithoutRef } from '../helpers/polymorphic.js';
|
|
3
4
|
import { IconChildrenProps, IconDeprecatedProps, IconNameProps } from '../elements/Icon.js';
|
|
4
5
|
/**
|
|
5
6
|
* Props for the Panel component.
|
|
6
7
|
*/
|
|
7
8
|
export interface PanelProps extends React.HTMLAttributes<HTMLElement>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
|
|
9
|
+
/**
|
|
10
|
+
* HTML element to render (default: `nav`). A `nav` is a `navigation`
|
|
11
|
+
* landmark, which suits a panel of links; a panel that is not navigation
|
|
12
|
+
* takes another tag. Bulma's own colored panels use `article`. A `section`
|
|
13
|
+
* is a `region` landmark only once it has an accessible name, such as
|
|
14
|
+
* `aria-labelledby` pointing at the `id` of its `Panel.Heading`.
|
|
15
|
+
*/
|
|
16
|
+
as?: 'nav' | 'article' | 'section' | 'aside' | 'div';
|
|
8
17
|
/** Bulma color modifier for the panel. */
|
|
9
18
|
color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger' | 'black' | 'dark' | 'light' | 'white';
|
|
10
19
|
/** Additional CSS classes. */
|
|
@@ -31,9 +40,14 @@ export interface PanelTabsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
31
40
|
children?: React.ReactNode;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
|
-
*
|
|
43
|
+
* The elements a panel block may render as: the tags Bulma's panel markup
|
|
44
|
+
* puts `.panel-block` on.
|
|
35
45
|
*/
|
|
36
|
-
export
|
|
46
|
+
export type PanelBlockElement = 'a' | 'div' | 'label';
|
|
47
|
+
/**
|
|
48
|
+
* The PanelBlock component's own props.
|
|
49
|
+
*/
|
|
50
|
+
export interface PanelBlockOwnProps {
|
|
37
51
|
/** Additional CSS classes. */
|
|
38
52
|
className?: string;
|
|
39
53
|
/** Whether the block is active. */
|
|
@@ -41,6 +55,32 @@ export interface PanelBlockProps extends React.AnchorHTMLAttributes<HTMLAnchorEl
|
|
|
41
55
|
/** Block content. */
|
|
42
56
|
children?: React.ReactNode;
|
|
43
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Props for the PanelBlock component. Everything the block does not own
|
|
60
|
+
* follows `as`: the anchor's attributes and an `HTMLAnchorElement`
|
|
61
|
+
* `currentTarget` under the default `'a'`, `htmlFor` under `'label'`, and the
|
|
62
|
+
* shared HTML attributes under any of them.
|
|
63
|
+
*
|
|
64
|
+
* The type parameter defaults to `'a'`, the element a block renders with no
|
|
65
|
+
* `as`, rather than to the whole union the way `DropdownItemProps` does. Before
|
|
66
|
+
* `as` existed this type was the anchor's attributes, so bare
|
|
67
|
+
* `PanelBlockProps` stays exactly that, `href` and anchor-typed handlers
|
|
68
|
+
* included. Write `PanelBlockProps<'div'>` or `PanelBlockProps<'label'>` for
|
|
69
|
+
* the others.
|
|
70
|
+
*/
|
|
71
|
+
export type PanelBlockProps<T extends PanelBlockElement = 'a'> = PanelBlockOwnProps & Omit<React.ComponentPropsWithoutRef<T>, keyof PanelBlockOwnProps | 'as'> & {
|
|
72
|
+
/**
|
|
73
|
+
* HTML element to render (default: `a`). Bulma styles a `label` block
|
|
74
|
+
* as clickable, like an `a`, and a `div` block as static content, such
|
|
75
|
+
* as a table. The props follow the tag, so the anchor attributes
|
|
76
|
+
* (`href`, `target`, `download` and the rest) are typed only on an `a`
|
|
77
|
+
* and `htmlFor` only on a `label`; at runtime the block also drops them,
|
|
78
|
+
* and `rel`, on the other tags. `Panel.CheckboxBlock`,
|
|
79
|
+
* `Panel.InputBlock` and `Panel.ButtonBlock` render the usual `label`
|
|
80
|
+
* and `div` blocks with their contents.
|
|
81
|
+
*/
|
|
82
|
+
as?: T;
|
|
83
|
+
};
|
|
44
84
|
/**
|
|
45
85
|
* Props for the PanelIcon component.
|
|
46
86
|
* Extends IconProps but uses 'panel-icon' as the container class.
|
|
@@ -94,13 +134,13 @@ export declare const PanelHeading: React.FC<PanelHeadingProps>;
|
|
|
94
134
|
*/
|
|
95
135
|
export declare const PanelTabs: React.FC<PanelTabsProps>;
|
|
96
136
|
/**
|
|
97
|
-
* Individual panel block (renders as `<a class="panel-block">`)
|
|
137
|
+
* Individual panel block (renders as `<a class="panel-block">` unless `as` says otherwise)
|
|
98
138
|
*
|
|
99
139
|
* @function
|
|
100
140
|
* @param {PanelBlockProps} props - Props for the PanelBlock component.
|
|
101
141
|
* @returns {JSX.Element} The rendered panel block.
|
|
102
142
|
*/
|
|
103
|
-
export declare const PanelBlock:
|
|
143
|
+
export declare const PanelBlock: ConstrainedPolymorphicComponentWithoutRef<PanelBlockOwnProps, PanelBlockElement, "a">;
|
|
104
144
|
/**
|
|
105
145
|
* Icon wrapper with panel styling (renders as `<span class="panel-icon">`, containing an
|
|
106
146
|
* `<i/>` when a `name` is given, or the custom node passed as `children`).
|
|
@@ -138,7 +178,7 @@ export declare const PanelButtonBlock: React.FC<PanelButtonBlockProps>;
|
|
|
138
178
|
export declare const Panel: React.FC<PanelProps> & {
|
|
139
179
|
Heading: React.FC<PanelHeadingProps>;
|
|
140
180
|
Tabs: React.FC<PanelTabsProps>;
|
|
141
|
-
Block:
|
|
181
|
+
Block: ConstrainedPolymorphicComponentWithoutRef<PanelBlockOwnProps, PanelBlockElement, "a", never>;
|
|
142
182
|
Icon: React.FC<PanelIconProps>;
|
|
143
183
|
InputBlock: React.FC<PanelInputBlockProps>;
|
|
144
184
|
CheckboxBlock: React.FC<PanelCheckboxBlockProps>;
|
|
@@ -8,7 +8,15 @@ export type SidebarPosition = 'left' | 'right';
|
|
|
8
8
|
* @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the sidebar element.
|
|
9
9
|
*/
|
|
10
10
|
export interface SidebarProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children' | 'color'>, BulmaClassesProps {
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Whether the sidebar is open (required). Opening moves focus into the
|
|
13
|
+
* sidebar, to its first tab stop or the sidebar itself. Closing hands focus
|
|
14
|
+
* back to whatever had it when the sidebar opened, unless focus has already
|
|
15
|
+
* left the sidebar, as it does for an overlay opened over it. A closed
|
|
16
|
+
* sidebar stays in the page, so it can slide out, and is `inert` and
|
|
17
|
+
* `aria-hidden` there: Tab passes over its content and assistive
|
|
18
|
+
* technology doesn't read it.
|
|
19
|
+
*/
|
|
12
20
|
isOpen: boolean;
|
|
13
21
|
/** Callback when sidebar should close. */
|
|
14
22
|
onClose?: () => void;
|
|
@@ -20,7 +28,14 @@ export interface SidebarProps extends Omit<React.HTMLAttributes<HTMLElement>, 'c
|
|
|
20
28
|
isFullwidth?: boolean;
|
|
21
29
|
/** Sidebar takes full width (mobile-style). @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */
|
|
22
30
|
fullWidth?: boolean;
|
|
23
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Show an overlay behind the sidebar, which makes it modal: it gets
|
|
33
|
+
* `aria-modal="true"`, locks body scroll, and keeps Tab and Shift+Tab
|
|
34
|
+
* inside it while it is the topmost overlay. A Modal or Dialog opened over
|
|
35
|
+
* it, even one rendered inside it, holds Tab until it closes. Without an
|
|
36
|
+
* overlay the sidebar isn't modal, and Tab moves in and out of it freely.
|
|
37
|
+
* Default: true.
|
|
38
|
+
*/
|
|
24
39
|
overlay?: boolean;
|
|
25
40
|
/** Close sidebar when overlay is clicked. Default: true. */
|
|
26
41
|
overlayClose?: boolean;
|