@allxsmith/bestax-bulma 5.63.0 → 5.64.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 (44) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/ScrollArea.js +7 -7
  4. package/dist/esm/components/ScrollArea.js.map +1 -1
  5. package/dist/esm/components/TableOfContents.js +85 -0
  6. package/dist/esm/components/TableOfContents.js.map +1 -0
  7. package/dist/esm/form/PasswordInput.js +105 -0
  8. package/dist/esm/form/PasswordInput.js.map +1 -0
  9. package/dist/esm/form/PasswordInputBase.js +177 -0
  10. package/dist/esm/form/PasswordInputBase.js.map +1 -0
  11. package/dist/esm/helpers/useScrollSpy.js +286 -0
  12. package/dist/esm/helpers/useScrollSpy.js.map +1 -0
  13. package/dist/extras.css +1 -1
  14. package/dist/extras.css.map +1 -1
  15. package/dist/index.cjs +616 -7
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.esm.js +4 -0
  18. package/dist/index.esm.js.map +1 -1
  19. package/dist/types/components/TableOfContents.d.ts +87 -0
  20. package/dist/types/form/PasswordInput.d.ts +98 -0
  21. package/dist/types/form/PasswordInputBase.d.ts +91 -0
  22. package/dist/types/helpers/useScrollSpy.d.ts +61 -0
  23. package/dist/types/index.d.ts +5 -0
  24. package/dist/types-cjs/components/TableOfContents.d.ts +87 -0
  25. package/dist/types-cjs/form/PasswordInput.d.ts +98 -0
  26. package/dist/types-cjs/form/PasswordInputBase.d.ts +91 -0
  27. package/dist/types-cjs/helpers/useScrollSpy.d.ts +61 -0
  28. package/dist/types-cjs/index.d.ts +5 -0
  29. package/dist/versions/bestax-no-dark-mode.css +1 -1
  30. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  31. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  32. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  33. package/dist/versions/bestax-no-helpers.css +1 -1
  34. package/dist/versions/bestax-no-helpers.css.map +1 -1
  35. package/dist/versions/bestax-prefixed.css +1 -1
  36. package/dist/versions/bestax-prefixed.css.map +1 -1
  37. package/package.json +1 -1
  38. package/src/scss/CLAUDE.md +3 -0
  39. package/src/scss/_input-trigger.scss +76 -0
  40. package/src/scss/components/_index.scss +1 -0
  41. package/src/scss/components/_tableofcontents.scss +42 -0
  42. package/src/scss/form/_index.scss +1 -0
  43. package/src/scss/form/_passwordinput.scss +112 -0
  44. package/src/scss/form/_picker-popover.scss +24 -63
package/dist/index.esm.js CHANGED
@@ -35,6 +35,7 @@ export { ScrollArea } from './esm/components/ScrollArea.js';
35
35
  export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from './esm/components/Command.js';
36
36
  export { DataTable } from './esm/components/DataTable.js';
37
37
  export { Affix } from './esm/components/Affix.js';
38
+ export { TableOfContents } from './esm/components/TableOfContents.js';
38
39
  export { Block } from './esm/elements/Block.js';
39
40
  export { Box } from './esm/elements/Box.js';
40
41
  export { Button } from './esm/elements/Button.js';
@@ -106,9 +107,11 @@ export { ColorPicker, ColorPickerAlphaSlider, ColorPickerArea, ColorPickerHueSli
106
107
  export { InputBase } from './esm/form/InputBase.js';
107
108
  export { SelectBase } from './esm/form/SelectBase.js';
108
109
  export { TextAreaBase } from './esm/form/TextAreaBase.js';
110
+ export { PasswordInputBase } from './esm/form/PasswordInputBase.js';
109
111
  export { Input } from './esm/form/Input.js';
110
112
  export { Select } from './esm/form/Select.js';
111
113
  export { TextArea } from './esm/form/TextArea.js';
114
+ export { PasswordInput } from './esm/form/PasswordInput.js';
112
115
  export { DateInputBase } from './esm/form/DateInputBase.js';
113
116
  export { DateInput } from './esm/form/DateInput.js';
114
117
  export { TimeInputBase } from './esm/form/TimeInputBase.js';
@@ -150,6 +153,7 @@ export { useColorClasses, useColorStyles } from './esm/helpers/useColorClasses.j
150
153
  export { useDataTable } from './esm/components/useDataTable.js';
151
154
  export { useFlexboxClasses } from './esm/helpers/useFlexboxClasses.js';
152
155
  export { useOtherClasses } from './esm/helpers/useOtherClasses.js';
156
+ export { useScrollSpy } from './esm/helpers/useScrollSpy.js';
153
157
  export { useSpacingClasses } from './esm/helpers/useSpacingClasses.js';
154
158
  export { useTypographyClasses } from './esm/helpers/useTypographyClasses.js';
155
159
  export { useVisibilityClasses } from './esm/helpers/useVisibilityClasses.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,87 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps, validColors } from '../helpers/useBulmaClasses.js';
3
+ export { useScrollSpy } from '../helpers/useScrollSpy.js';
4
+ export type { UseScrollSpyOptions } from '../helpers/useScrollSpy.js';
5
+ /** One entry in a TableOfContents. */
6
+ export interface TableOfContentsItem {
7
+ /** **Required.** The `id` of the section or heading it links to, without the `#`. Unique on the page. */
8
+ id: string;
9
+ /** **Required.** What the link says, usually the heading's own text. */
10
+ label: React.ReactNode;
11
+ /** Entries under this one, drawn as a nested list. */
12
+ children?: TableOfContentsItem[];
13
+ }
14
+ /** The visible strings, in your app's language. */
15
+ export interface TableOfContentsLabels {
16
+ /**
17
+ * The list's visible title, which also names its `<nav>`.
18
+ * @defaultValue 'On this page'
19
+ */
20
+ title?: string;
21
+ }
22
+ /**
23
+ * Props for the TableOfContents component. The helper props, the other
24
+ * attributes and the `ref` land on the `<nav>`.
25
+ *
26
+ * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the `<nav>`.
27
+ */
28
+ export interface TableOfContentsProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color' | 'children'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
29
+ /** Additional CSS classes to apply. */
30
+ className?: string;
31
+ /**
32
+ * **Required.** The sections, in page order, as links to their ids. Each
33
+ * link is a plain `<a href="#id">`, so following one is the browser's own
34
+ * jump: put `scroll-padding-top` on the page to land clear of a sticky
35
+ * header, and smooth scrolling, if you want it, in page CSS inside
36
+ * `@media (prefers-reduced-motion: no-preference)`.
37
+ */
38
+ items: TableOfContentsItem[];
39
+ /**
40
+ * Called with the current section's id when it changes, or `null` above
41
+ * the first section. Never called on the server or before hydration.
42
+ */
43
+ onCurrentChange?: (id: string | null) => void;
44
+ /**
45
+ * Pixels from the viewport's top where a section counts as reached.
46
+ * Unset, it's the page's `scroll-padding-top`, so the highlight agrees
47
+ * with where a jump lands under a sticky header.
48
+ */
49
+ offset?: number;
50
+ /**
51
+ * Sticks to the top of the viewport as the page scrolls, at
52
+ * `--bulma-table-of-contents-sticky-top`, and scrolls itself when it's
53
+ * taller than the viewport. Adds `is-sticky`.
54
+ */
55
+ isSticky?: boolean;
56
+ /** The visible strings, in your app's language. */
57
+ labels?: TableOfContentsLabels;
58
+ /** Text color helper. */
59
+ textColor?: (typeof validColors)[number] | 'inherit' | 'current';
60
+ /** Background color helper. */
61
+ bgColor?: (typeof validColors)[number] | 'inherit' | 'current';
62
+ }
63
+ /**
64
+ * The `TableOfContents` component lists a long page's sections as links in Bulma's menu look, and marks the one being read.
65
+ *
66
+ * It's a `<nav>` named by its title, holding `MenuList` and `MenuItem` links
67
+ * to each `#id`, rendered in full on the server. `useScrollSpy` picks the
68
+ * current section, and its link alone gets `is-active` and
69
+ * `aria-current="location"`. Use the hook on its own to mark the section in
70
+ * view somewhere else, such as an app's nav `Menu`.
71
+ *
72
+ * @function
73
+ * @param {TableOfContentsProps} props - Props for the TableOfContents component.
74
+ * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the `<nav>`.
75
+ * @returns {JSX.Element} The rendered table of contents.
76
+ *
77
+ * @example
78
+ * <TableOfContents
79
+ * isSticky
80
+ * items={[
81
+ * { id: 'install', label: 'Install' },
82
+ * { id: 'usage', label: 'Usage', children: [{ id: 'props', label: 'Props' }] },
83
+ * ]}
84
+ * />
85
+ */
86
+ export declare const TableOfContents: React.ForwardRefExoticComponent<TableOfContentsProps & React.RefAttributes<HTMLElement>>;
87
+ export default TableOfContents;
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import { FieldProps } from './Field.js';
3
+ import { ControlBaseProps } from './Control.js';
4
+ import { PasswordInputBaseProps } from './PasswordInputBase.js';
5
+ /**
6
+ * Props for the PasswordInput component: PasswordInputBase's, plus Input's
7
+ * Field and Control props, except the right icon, whose place the toggle
8
+ * takes. Inside an existing `Control` it renders no `Control` of its own, so
9
+ * its Control-level props do nothing there and warn in development; set them
10
+ * on that `Control` instead. Inside an outer `Field`, or a `Control` with no
11
+ * `Field` around it, it renders no `Field` of its own either. The exception
12
+ * is `label`, `message`, `horizontal` or `fieldClassName` in that bare
13
+ * `Control`: it keeps a `Field` for them, nested in the `.control`, and warns
14
+ * in development. Wrap the `Control` in a `Field` instead, and set the
15
+ * `label`, `horizontal` and class name on that `Field`.
16
+ *
17
+ * @helperProps Helper props go on the `.password-input-container` `<div>`, with
18
+ * `className` and `style`, so they move and size the field and its toggle
19
+ * together. The other attributes go on the `<input>`.
20
+ * @extraProp {string} [autoComplete="current-password"] - Tells the browser and password managers this is an existing password. Pass `"new-password"` where the user makes one up, on a sign-up or change-password form.
21
+ * @extraProp {boolean} [spellCheck=false] - Off, so a browser's spellcheck never sees the password once it shows.
22
+ * @extraProp {string} [autoCorrect="off"] - Off, so a phone's keyboard doesn't change what's typed.
23
+ * @extraProp {string} [autoCapitalize="none"] - Off, so a phone's keyboard doesn't capitalize the first letter.
24
+ * @extraProp {string} [value] - The password, controlled. React writes a controlled input's value into its `value` attribute, as it does on any input, so the password sits in the page's markup. Uncontrolled, read with `FormData`, the field never puts what's typed there.
25
+ * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the `<input>`.
26
+ */
27
+ export interface PasswordInputProps extends PasswordInputBaseProps {
28
+ /** Field label. Automatically associated with the input via `htmlFor`, using your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */
29
+ label?: React.ReactNode;
30
+ /** Size for the label. */
31
+ labelSize?: FieldProps['labelSize'];
32
+ /** Props for the label element when the component renders its own `Field`; dropped inside an outer `Field` (use that `Field`'s `labelProps` instead). An explicit `htmlFor` key, even `undefined`, overrides the automatic association and no id is generated. */
33
+ labelProps?: FieldProps['labelProps'];
34
+ /** Horizontal field layout. */
35
+ horizontal?: boolean;
36
+ /**
37
+ * Icon props for the left icon.
38
+ * Bulma gives control icons `pointer-events: none`, so a clickable node here
39
+ * never receives a click.
40
+ */
41
+ iconLeft?: ControlBaseProps['iconLeft'];
42
+ /** Shortcut for the left icon's name. */
43
+ iconLeftName?: string;
44
+ /** Shortcut for the left icon's size. */
45
+ iconLeftSize?: ControlBaseProps['iconLeftSize'];
46
+ /** Force the left icon container. */
47
+ hasIconsLeft?: boolean;
48
+ /**
49
+ * Shows a loading spinner on the `Control` it renders, at the edge the
50
+ * toggle uses, so the toggle isn't drawn meanwhile, and a shown password is
51
+ * hidden until it's back. Inside your own
52
+ * `Control` it renders none, so this draws nothing and warns in
53
+ * development; set `isLoading` on that `Control`, which hides the toggle
54
+ * too.
55
+ */
56
+ isLoading?: boolean;
57
+ /** Expand the control. */
58
+ isExpanded?: boolean;
59
+ /** Control size. */
60
+ controlSize?: ControlBaseProps['size'];
61
+ /** Help/validation message below the input. */
62
+ message?: React.ReactNode;
63
+ /** Bulma color for the message. */
64
+ messageColor?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
65
+ /** Additional CSS classes for the Field. */
66
+ fieldClassName?: string;
67
+ /** Additional CSS classes for the Control. */
68
+ controlClassName?: string;
69
+ /** Not offered: the toggle takes the right icon's place. Warns in development if passed. @internal */
70
+ iconRight?: never;
71
+ /** Not offered, as `iconRight`. @internal */
72
+ iconRightName?: never;
73
+ /** Not offered, as `iconRight`. @internal */
74
+ iconRightSize?: never;
75
+ /** Not offered, as `iconRight`. @internal */
76
+ hasIconsRight?: never;
77
+ }
78
+ /**
79
+ * The `PasswordInput` component is a password field with a button inside it that shows what was typed.
80
+ *
81
+ * By default the button is an eye named "Show password" that reports
82
+ * whether the password shows with `aria-pressed`; `variant="text"` makes it
83
+ * the words "Show" and "Hide". The field asks for
84
+ * `autocomplete="current-password"` and no spellcheck, and hides the
85
+ * password again when its form submits.
86
+ *
87
+ * @function
88
+ * @param {PasswordInputProps} props - Props for PasswordInput.
89
+ * @returns {JSX.Element} The composed field element.
90
+ *
91
+ * @example
92
+ * <PasswordInput label="Password" />
93
+ *
94
+ * @example
95
+ * <PasswordInput label="New password" autoComplete="new-password" variant="text" />
96
+ */
97
+ export declare const PasswordInput: React.ForwardRefExoticComponent<PasswordInputProps & React.RefAttributes<HTMLInputElement>>;
98
+ export default PasswordInput;
@@ -0,0 +1,91 @@
1
+ import { InputBaseProps } from './InputBase.js';
2
+ /** How PasswordInput's visibility toggle draws itself. */
3
+ export type PasswordInputVariant = 'icon' | 'text';
4
+ /** The strings PasswordInput's toggle shows and announces, for translating. */
5
+ export interface PasswordInputLabels {
6
+ /**
7
+ * The toggle's name. With the `icon` variant it's the name in both states,
8
+ * and `aria-pressed` says whether the password shows. With `text`, it's the
9
+ * name while the password is hidden, and it has to contain `show`, the word
10
+ * on the button.
11
+ * @defaultValue 'Show password'
12
+ */
13
+ showPassword?: string;
14
+ /**
15
+ * The `text` variant's name while the password shows. It has to contain
16
+ * `hide`.
17
+ * @defaultValue 'Hide password'
18
+ */
19
+ hidePassword?: string;
20
+ /**
21
+ * The `text` variant's word while the password is hidden.
22
+ * @defaultValue 'Show'
23
+ */
24
+ show?: string;
25
+ /**
26
+ * The `text` variant's word while the password shows.
27
+ * @defaultValue 'Hide'
28
+ */
29
+ hide?: string;
30
+ }
31
+ /**
32
+ * Props for PasswordInputBase, the input and its toggle without a Field or a
33
+ * Control.
34
+ *
35
+ * @helperProps Helper props go on the `.password-input-container` `<div>`, with
36
+ * `className` and `style`, so they move and size the field and its toggle
37
+ * together. The other attributes go on the `<input>`.
38
+ * @extraProp {string} [autoComplete="current-password"] - Tells the browser and password managers this is an existing password. Pass `"new-password"` where the user makes one up, on a sign-up or change-password form.
39
+ * @extraProp {boolean} [spellCheck=false] - Off, so a browser's spellcheck never sees the password once it shows.
40
+ * @extraProp {string} [autoCorrect="off"] - Off, so a phone's keyboard doesn't change what's typed.
41
+ * @extraProp {string} [autoCapitalize="none"] - Off, so a phone's keyboard doesn't capitalize the first letter.
42
+ * @extraProp {string} [value] - The password, controlled. React writes a controlled input's value into its `value` attribute, as it does on any input, so the password sits in the page's markup. Uncontrolled, read with `FormData`, the field never puts what's typed there.
43
+ * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the `<input>`.
44
+ */
45
+ export interface PasswordInputBaseProps extends Omit<InputBaseProps, 'type'> {
46
+ /**
47
+ * Whether the password shows, when you hold the state. Setting it makes
48
+ * the visibility controlled: the toggle only calls `onVisibleChange`, and
49
+ * so does hiding again on its own. Apply that `false` and the field is a
50
+ * password field by the time the form reads it; keep `visible` true and
51
+ * the field stays shown.
52
+ */
53
+ visible?: boolean;
54
+ /**
55
+ * Whether the password shows at first, when the input holds its own state.
56
+ * @defaultValue false
57
+ */
58
+ defaultVisible?: boolean;
59
+ /**
60
+ * Called with the new visibility on each toggle, and with `false` when the
61
+ * form submits or resets, or the page is left, which it also is on the way
62
+ * into the back-forward cache. React renders those hides at once, a state
63
+ * update you make here included, so the form reads a password field. One
64
+ * that fires while React is rendering or committing, which includes your
65
+ * `useEffect` and `useLayoutEffect` callbacks, such as a `requestSubmit()`
66
+ * from an effect, can't render there, and lands just after the form is
67
+ * read: hide the password first, or submit from an event handler.
68
+ */
69
+ onVisibleChange?: (visible: boolean) => void;
70
+ /**
71
+ * How the toggle draws itself: an eye icon with a fixed name and
72
+ * `aria-pressed`, or the words "Show" and "Hide" with a name that follows
73
+ * them.
74
+ * @defaultValue 'icon'
75
+ */
76
+ variant?: PasswordInputVariant;
77
+ /** Translations for the toggle. */
78
+ labels?: PasswordInputLabels;
79
+ }
80
+ /**
81
+ * The raw PasswordInput: a password field with a button inside it that shows what was typed, without Field/Control wrapping.
82
+ *
83
+ * Use `PasswordInput` for the convenience wrapper.
84
+ *
85
+ * @function
86
+ * @param {PasswordInputBaseProps} props - Props for PasswordInputBase.
87
+ * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the `<input>`.
88
+ * @returns {JSX.Element} The input and its toggle, in a container.
89
+ */
90
+ export declare const PasswordInputBase: import("react").ForwardRefExoticComponent<PasswordInputBaseProps & import("react").RefAttributes<HTMLInputElement>>;
91
+ export default PasswordInputBase;
@@ -0,0 +1,61 @@
1
+ /** Options for useScrollSpy. */
2
+ export interface UseScrollSpyOptions {
3
+ /**
4
+ * **Required.** The ids of the sections to watch, without the `#`, in the
5
+ * order they come on the page. Each one is looked up each time the hook
6
+ * checks, so an id with no element on the page is skipped until one
7
+ * appears, and a section replaced under the same id keeps working.
8
+ */
9
+ ids: string[];
10
+ /**
11
+ * Pixels from the viewport's top where a section counts as reached. Unset,
12
+ * it's the page's `scroll-padding-top`, read when the hook mounts and on
13
+ * resize, so the highlight agrees with where a jump lands under a sticky
14
+ * header. A `scroll-padding-top` that mixes a percentage with a length in
15
+ * `calc()` isn't read: pass `offset` then.
16
+ */
17
+ offset?: number;
18
+ /** Called with the new current id when it changes, or `null` above the first section. */
19
+ onCurrentChange?: (id: string | null) => void;
20
+ }
21
+ /**
22
+ * The `useScrollSpy` hook returns the id of the section being read: the last
23
+ * of `ids` whose top is at or above the offset line, or the last one once the
24
+ * page is scrolled to its end. After a jump to one of them, it's that one
25
+ * until the reader scrolls on. `null` above the first section, on the server
26
+ * and until the page hydrates.
27
+ *
28
+ * It checks once per frame while the page scrolls, and on resize. A jump is
29
+ * a plain click on a link to one of the ids (the main button, no modifier
30
+ * key, opening in this page), noted and never stopped, so the browser jumps
31
+ * as it always does; and the `#id` a page opened afresh opens at. Back,
32
+ * Forward and a reload aren't jumps. That `#id` is read once, when `ids`
33
+ * first has some: a section rendered after that isn't held, even if the
34
+ * page opened at it, and the reading rule marks where the page is. Once the
35
+ * page has been still for a
36
+ * moment, the section stays current only if it's where a jump puts it: its
37
+ * top at the line, give or take a shift of the layout smaller than its own
38
+ * height, or, at the end of the page, on screen below the line. Otherwise,
39
+ * as after a flick right after the click, the reading rule takes over. The
40
+ * next scroll after that lets it go, the browser's own included, so when
41
+ * content loading above it makes the browser scroll to keep the reader's
42
+ * place, the rule takes over too.
43
+ *
44
+ * A section that isn't drawn (`display: none`) is never current. A section
45
+ * that moves while nothing scrolls is seen at the next scroll or resize. It
46
+ * watches the document only: not a panel that scrolls inside it, and not
47
+ * sections inside a shadow root, which an `#id` link can't reach either.
48
+ * Whether a page was opened afresh is read from how the document loaded, so
49
+ * in an app that changes routes on the client, a route change can briefly
50
+ * mark the address bar's section until the page settles, when the reading
51
+ * rule takes over, and after a reload a route change to an `#id` holds
52
+ * nothing.
53
+ *
54
+ * @function
55
+ * @param {UseScrollSpyOptions} options - The ids to watch, the offset, and a change callback.
56
+ * @returns {string | null} The current section's id, or `null`.
57
+ *
58
+ * @example
59
+ * const current = useScrollSpy({ ids: ['profile', 'security', 'billing'] });
60
+ */
61
+ export declare function useScrollSpy({ ids, offset, onCurrentChange, }: UseScrollSpyOptions): string | null;
@@ -34,6 +34,7 @@ export * from './components/ScrollArea.js';
34
34
  export * from './components/Command.js';
35
35
  export * from './components/DataTable.js';
36
36
  export * from './components/Affix.js';
37
+ export * from './components/TableOfContents.js';
37
38
  export * from './elements/Block.js';
38
39
  export * from './elements/Box.js';
39
40
  export * from './elements/Button.js';
@@ -108,12 +109,16 @@ export { SelectBase } from './form/SelectBase.js';
108
109
  export type { SelectBaseProps } from './form/SelectBase.js';
109
110
  export { TextAreaBase } from './form/TextAreaBase.js';
110
111
  export type { TextAreaBaseProps } from './form/TextAreaBase.js';
112
+ export { PasswordInputBase } from './form/PasswordInputBase.js';
113
+ export type { PasswordInputBaseProps, PasswordInputLabels, PasswordInputVariant, } from './form/PasswordInputBase.js';
111
114
  export { Input } from './form/Input.js';
112
115
  export type { InputProps } from './form/Input.js';
113
116
  export { Select } from './form/Select.js';
114
117
  export type { SelectProps } from './form/Select.js';
115
118
  export { TextArea } from './form/TextArea.js';
116
119
  export type { TextAreaProps } from './form/TextArea.js';
120
+ export { PasswordInput } from './form/PasswordInput.js';
121
+ export type { PasswordInputProps } from './form/PasswordInput.js';
117
122
  export { DateInputBase } from './form/DateInputBase.js';
118
123
  export type { DateInputBaseProps } from './form/DateInputBase.js';
119
124
  export { DateInput } from './form/DateInput.js';
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import { BulmaClassesProps, validColors } from '../helpers/useBulmaClasses.js';
3
+ export { useScrollSpy } from '../helpers/useScrollSpy.js';
4
+ export type { UseScrollSpyOptions } from '../helpers/useScrollSpy.js';
5
+ /** One entry in a TableOfContents. */
6
+ export interface TableOfContentsItem {
7
+ /** **Required.** The `id` of the section or heading it links to, without the `#`. Unique on the page. */
8
+ id: string;
9
+ /** **Required.** What the link says, usually the heading's own text. */
10
+ label: React.ReactNode;
11
+ /** Entries under this one, drawn as a nested list. */
12
+ children?: TableOfContentsItem[];
13
+ }
14
+ /** The visible strings, in your app's language. */
15
+ export interface TableOfContentsLabels {
16
+ /**
17
+ * The list's visible title, which also names its `<nav>`.
18
+ * @defaultValue 'On this page'
19
+ */
20
+ title?: string;
21
+ }
22
+ /**
23
+ * Props for the TableOfContents component. The helper props, the other
24
+ * attributes and the `ref` land on the `<nav>`.
25
+ *
26
+ * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the `<nav>`.
27
+ */
28
+ export interface TableOfContentsProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color' | 'children'>, Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {
29
+ /** Additional CSS classes to apply. */
30
+ className?: string;
31
+ /**
32
+ * **Required.** The sections, in page order, as links to their ids. Each
33
+ * link is a plain `<a href="#id">`, so following one is the browser's own
34
+ * jump: put `scroll-padding-top` on the page to land clear of a sticky
35
+ * header, and smooth scrolling, if you want it, in page CSS inside
36
+ * `@media (prefers-reduced-motion: no-preference)`.
37
+ */
38
+ items: TableOfContentsItem[];
39
+ /**
40
+ * Called with the current section's id when it changes, or `null` above
41
+ * the first section. Never called on the server or before hydration.
42
+ */
43
+ onCurrentChange?: (id: string | null) => void;
44
+ /**
45
+ * Pixels from the viewport's top where a section counts as reached.
46
+ * Unset, it's the page's `scroll-padding-top`, so the highlight agrees
47
+ * with where a jump lands under a sticky header.
48
+ */
49
+ offset?: number;
50
+ /**
51
+ * Sticks to the top of the viewport as the page scrolls, at
52
+ * `--bulma-table-of-contents-sticky-top`, and scrolls itself when it's
53
+ * taller than the viewport. Adds `is-sticky`.
54
+ */
55
+ isSticky?: boolean;
56
+ /** The visible strings, in your app's language. */
57
+ labels?: TableOfContentsLabels;
58
+ /** Text color helper. */
59
+ textColor?: (typeof validColors)[number] | 'inherit' | 'current';
60
+ /** Background color helper. */
61
+ bgColor?: (typeof validColors)[number] | 'inherit' | 'current';
62
+ }
63
+ /**
64
+ * The `TableOfContents` component lists a long page's sections as links in Bulma's menu look, and marks the one being read.
65
+ *
66
+ * It's a `<nav>` named by its title, holding `MenuList` and `MenuItem` links
67
+ * to each `#id`, rendered in full on the server. `useScrollSpy` picks the
68
+ * current section, and its link alone gets `is-active` and
69
+ * `aria-current="location"`. Use the hook on its own to mark the section in
70
+ * view somewhere else, such as an app's nav `Menu`.
71
+ *
72
+ * @function
73
+ * @param {TableOfContentsProps} props - Props for the TableOfContents component.
74
+ * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the `<nav>`.
75
+ * @returns {JSX.Element} The rendered table of contents.
76
+ *
77
+ * @example
78
+ * <TableOfContents
79
+ * isSticky
80
+ * items={[
81
+ * { id: 'install', label: 'Install' },
82
+ * { id: 'usage', label: 'Usage', children: [{ id: 'props', label: 'Props' }] },
83
+ * ]}
84
+ * />
85
+ */
86
+ export declare const TableOfContents: React.ForwardRefExoticComponent<TableOfContentsProps & React.RefAttributes<HTMLElement>>;
87
+ export default TableOfContents;
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import { FieldProps } from './Field.js';
3
+ import { ControlBaseProps } from './Control.js';
4
+ import { PasswordInputBaseProps } from './PasswordInputBase.js';
5
+ /**
6
+ * Props for the PasswordInput component: PasswordInputBase's, plus Input's
7
+ * Field and Control props, except the right icon, whose place the toggle
8
+ * takes. Inside an existing `Control` it renders no `Control` of its own, so
9
+ * its Control-level props do nothing there and warn in development; set them
10
+ * on that `Control` instead. Inside an outer `Field`, or a `Control` with no
11
+ * `Field` around it, it renders no `Field` of its own either. The exception
12
+ * is `label`, `message`, `horizontal` or `fieldClassName` in that bare
13
+ * `Control`: it keeps a `Field` for them, nested in the `.control`, and warns
14
+ * in development. Wrap the `Control` in a `Field` instead, and set the
15
+ * `label`, `horizontal` and class name on that `Field`.
16
+ *
17
+ * @helperProps Helper props go on the `.password-input-container` `<div>`, with
18
+ * `className` and `style`, so they move and size the field and its toggle
19
+ * together. The other attributes go on the `<input>`.
20
+ * @extraProp {string} [autoComplete="current-password"] - Tells the browser and password managers this is an existing password. Pass `"new-password"` where the user makes one up, on a sign-up or change-password form.
21
+ * @extraProp {boolean} [spellCheck=false] - Off, so a browser's spellcheck never sees the password once it shows.
22
+ * @extraProp {string} [autoCorrect="off"] - Off, so a phone's keyboard doesn't change what's typed.
23
+ * @extraProp {string} [autoCapitalize="none"] - Off, so a phone's keyboard doesn't capitalize the first letter.
24
+ * @extraProp {string} [value] - The password, controlled. React writes a controlled input's value into its `value` attribute, as it does on any input, so the password sits in the page's markup. Uncontrolled, read with `FormData`, the field never puts what's typed there.
25
+ * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the `<input>`.
26
+ */
27
+ export interface PasswordInputProps extends PasswordInputBaseProps {
28
+ /** Field label. Automatically associated with the input via `htmlFor`, using your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */
29
+ label?: React.ReactNode;
30
+ /** Size for the label. */
31
+ labelSize?: FieldProps['labelSize'];
32
+ /** Props for the label element when the component renders its own `Field`; dropped inside an outer `Field` (use that `Field`'s `labelProps` instead). An explicit `htmlFor` key, even `undefined`, overrides the automatic association and no id is generated. */
33
+ labelProps?: FieldProps['labelProps'];
34
+ /** Horizontal field layout. */
35
+ horizontal?: boolean;
36
+ /**
37
+ * Icon props for the left icon.
38
+ * Bulma gives control icons `pointer-events: none`, so a clickable node here
39
+ * never receives a click.
40
+ */
41
+ iconLeft?: ControlBaseProps['iconLeft'];
42
+ /** Shortcut for the left icon's name. */
43
+ iconLeftName?: string;
44
+ /** Shortcut for the left icon's size. */
45
+ iconLeftSize?: ControlBaseProps['iconLeftSize'];
46
+ /** Force the left icon container. */
47
+ hasIconsLeft?: boolean;
48
+ /**
49
+ * Shows a loading spinner on the `Control` it renders, at the edge the
50
+ * toggle uses, so the toggle isn't drawn meanwhile, and a shown password is
51
+ * hidden until it's back. Inside your own
52
+ * `Control` it renders none, so this draws nothing and warns in
53
+ * development; set `isLoading` on that `Control`, which hides the toggle
54
+ * too.
55
+ */
56
+ isLoading?: boolean;
57
+ /** Expand the control. */
58
+ isExpanded?: boolean;
59
+ /** Control size. */
60
+ controlSize?: ControlBaseProps['size'];
61
+ /** Help/validation message below the input. */
62
+ message?: React.ReactNode;
63
+ /** Bulma color for the message. */
64
+ messageColor?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
65
+ /** Additional CSS classes for the Field. */
66
+ fieldClassName?: string;
67
+ /** Additional CSS classes for the Control. */
68
+ controlClassName?: string;
69
+ /** Not offered: the toggle takes the right icon's place. Warns in development if passed. @internal */
70
+ iconRight?: never;
71
+ /** Not offered, as `iconRight`. @internal */
72
+ iconRightName?: never;
73
+ /** Not offered, as `iconRight`. @internal */
74
+ iconRightSize?: never;
75
+ /** Not offered, as `iconRight`. @internal */
76
+ hasIconsRight?: never;
77
+ }
78
+ /**
79
+ * The `PasswordInput` component is a password field with a button inside it that shows what was typed.
80
+ *
81
+ * By default the button is an eye named "Show password" that reports
82
+ * whether the password shows with `aria-pressed`; `variant="text"` makes it
83
+ * the words "Show" and "Hide". The field asks for
84
+ * `autocomplete="current-password"` and no spellcheck, and hides the
85
+ * password again when its form submits.
86
+ *
87
+ * @function
88
+ * @param {PasswordInputProps} props - Props for PasswordInput.
89
+ * @returns {JSX.Element} The composed field element.
90
+ *
91
+ * @example
92
+ * <PasswordInput label="Password" />
93
+ *
94
+ * @example
95
+ * <PasswordInput label="New password" autoComplete="new-password" variant="text" />
96
+ */
97
+ export declare const PasswordInput: React.ForwardRefExoticComponent<PasswordInputProps & React.RefAttributes<HTMLInputElement>>;
98
+ export default PasswordInput;