@ahrowe/ui 0.43.0 → 0.45.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/CHANGELOG.md +29 -0
- package/README.md +4 -3
- package/dist/cjs-types/common/button/button.types.d.ts +1 -1
- package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +6 -0
- package/dist/cjs-types/common/loader/index.d.ts +2 -0
- package/dist/cjs-types/common/loader/loader.d.ts +4 -0
- package/dist/cjs-types/common/loader/loader.types.d.ts +31 -0
- package/dist/cjs-types/common/loadingOverlay/index.d.ts +2 -0
- package/dist/cjs-types/common/loadingOverlay/loadingOverlay.d.ts +4 -0
- package/dist/cjs-types/common/loadingOverlay/loadingOverlay.types.d.ts +21 -0
- package/dist/cjs-types/common/stepper/stepper.d.ts +1 -1
- package/dist/cjs-types/common/stepper/stepper.types.d.ts +28 -12
- package/dist/cjs-types/common/themeProvider/theme.types.d.ts +4 -12
- package/dist/cjs-types/index.d.ts +4 -1
- package/dist/esm/common/button/button.mjs +1 -1
- package/dist/esm/common/button/button.mjs.map +1 -1
- package/dist/esm/common/button/button.module.mjs +1 -1
- package/dist/esm/common/button/button.module.mjs.map +1 -1
- package/dist/esm/common/button/button.types.mjs +1 -1
- package/dist/esm/common/button/button.types.mjs.map +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
- package/dist/esm/common/checkbox/checkbox.module.mjs +1 -1
- package/dist/esm/common/checkbox/checkbox.module.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.module.mjs +1 -1
- package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
- package/dist/esm/common/kanbanBoard/KanbanColumn.mjs +1 -1
- package/dist/esm/common/kanbanBoard/KanbanColumn.mjs.map +1 -1
- package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs +1 -1
- package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs.map +1 -1
- package/dist/esm/common/loader/loader.mjs +2 -0
- package/dist/esm/common/loader/loader.mjs.map +1 -0
- package/dist/esm/common/loader/loader.module.mjs +2 -0
- package/dist/esm/common/loader/loader.module.mjs.map +1 -0
- package/dist/esm/common/loader/loader.types.mjs +2 -0
- package/dist/esm/common/loader/loader.types.mjs.map +1 -0
- package/dist/esm/common/loadingOverlay/loadingOverlay.mjs +2 -0
- package/dist/esm/common/loadingOverlay/loadingOverlay.mjs.map +1 -0
- package/dist/esm/common/loadingOverlay/loadingOverlay.module.mjs +2 -0
- package/dist/esm/common/loadingOverlay/loadingOverlay.module.mjs.map +1 -0
- package/dist/esm/common/splitButton/splitButton.mjs +1 -1
- package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
- package/dist/esm/common/stepper/stepper.mjs +1 -1
- package/dist/esm/common/stepper/stepper.mjs.map +1 -1
- package/dist/esm/common/stepper/stepper.module.mjs +1 -1
- package/dist/esm/common/stepper/stepper.module.mjs.map +1 -1
- package/dist/esm/common/stepper/stepper.types.mjs +1 -1
- package/dist/esm/common/stepper/stepper.types.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.module.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/common/button/button.types.d.ts +1 -1
- package/dist/types/common/configProvider/configProvider.types.d.ts +6 -0
- package/dist/types/common/loader/index.d.ts +2 -0
- package/dist/types/common/loader/loader.d.ts +4 -0
- package/dist/types/common/loader/loader.types.d.ts +31 -0
- package/dist/types/common/loadingOverlay/index.d.ts +2 -0
- package/dist/types/common/loadingOverlay/loadingOverlay.d.ts +4 -0
- package/dist/types/common/loadingOverlay/loadingOverlay.types.d.ts +21 -0
- package/dist/types/common/stepper/stepper.d.ts +1 -1
- package/dist/types/common/stepper/stepper.types.d.ts +28 -12
- package/dist/types/common/themeProvider/theme.types.d.ts +4 -12
- package/dist/types/index.d.ts +4 -1
- package/docs/Button.md +9 -3
- package/docs/CLAUDE.md +4 -3
- package/docs/Checkbox.md +1 -1
- package/docs/ConfigProvider.md +1 -1
- package/docs/Loader.md +95 -0
- package/docs/LoadingOverlay.md +85 -0
- package/docs/Skeleton.md +1 -1
- package/docs/SplitButton.md +1 -1
- package/docs/Stepper.md +57 -29
- package/docs/ThemeColor.md +1 -1
- package/package.json +1 -1
- package/dist/cjs-types/common/loading/index.d.ts +0 -1
- package/dist/cjs-types/common/loading/spinnerLoading/index.d.ts +0 -2
- package/dist/cjs-types/common/loading/spinnerLoading/spinnerLoading.d.ts +0 -6
- package/dist/esm/common/loading/spinnerLoading/index.mjs +0 -2
- package/dist/esm/common/loading/spinnerLoading/index.mjs.map +0 -1
- package/dist/esm/common/loading/spinnerLoading/spinnerLoading.mjs +0 -2
- package/dist/esm/common/loading/spinnerLoading/spinnerLoading.mjs.map +0 -1
- package/dist/esm/common/loading/spinnerLoading/spinnerLoading.module.mjs +0 -2
- package/dist/esm/common/loading/spinnerLoading/spinnerLoading.module.mjs.map +0 -1
- package/dist/types/common/loading/index.d.ts +0 -1
- package/dist/types/common/loading/spinnerLoading/index.d.ts +0 -2
- package/dist/types/common/loading/spinnerLoading/spinnerLoading.d.ts +0 -6
- package/docs/Loading.md +0 -68
|
@@ -14,8 +14,8 @@ export declare enum ButtonStyleType {
|
|
|
14
14
|
Plain = "plain"
|
|
15
15
|
}
|
|
16
16
|
export declare enum ButtonSize {
|
|
17
|
-
Default = "default",
|
|
18
17
|
Small = "small",
|
|
18
|
+
/** The default. */
|
|
19
19
|
Medium = "medium",
|
|
20
20
|
Large = "large",
|
|
21
21
|
/** Square, padding-free button for a lone icon. Give it its own width/height. */
|
|
@@ -26,6 +26,8 @@ import { ChipProps } from '../chip/chip.types.js';
|
|
|
26
26
|
import { CardProps } from '../card/card.types.js';
|
|
27
27
|
import { SectionHeaderProps } from '../sectionHeader/sectionHeader.types.js';
|
|
28
28
|
import { SkeletonProps } from '../skeleton/skeleton.types.js';
|
|
29
|
+
import { LoaderProps } from '../loader/loader.types.js';
|
|
30
|
+
import { LoadingOverlayProps } from '../loadingOverlay/loadingOverlay.types.js';
|
|
29
31
|
import { AccordionProps } from '../accordion/accordion.types.js';
|
|
30
32
|
import { DividerProps } from '../divider/divider.types.js';
|
|
31
33
|
import { AlertProps } from '../alert/alert.types.js';
|
|
@@ -46,6 +48,7 @@ import { RoomDrawerProps } from '../roomDrawer/roomDrawer.types.js';
|
|
|
46
48
|
import { RoomViewerProps } from '../roomViewer/roomViewer.types.js';
|
|
47
49
|
import { PopoverProps } from '../popover/popover.types.js';
|
|
48
50
|
import { ModalProps } from '../modal/modal.types.js';
|
|
51
|
+
import { StepperProps } from '../stepper/stepper.types.js';
|
|
49
52
|
import { Presentation } from '../configProvider/presentation.types.js';
|
|
50
53
|
/**
|
|
51
54
|
* Global default props keyed by component name.
|
|
@@ -105,6 +108,8 @@ export interface ComponentDefaults {
|
|
|
105
108
|
Card?: Partial<CardProps>;
|
|
106
109
|
SectionHeader?: Partial<SectionHeaderProps>;
|
|
107
110
|
Skeleton?: Partial<SkeletonProps>;
|
|
111
|
+
Loader?: Partial<LoaderProps>;
|
|
112
|
+
LoadingOverlay?: Partial<LoadingOverlayProps>;
|
|
108
113
|
Accordion?: Partial<AccordionProps>;
|
|
109
114
|
Divider?: Partial<DividerProps>;
|
|
110
115
|
Alert?: Partial<AlertProps>;
|
|
@@ -127,6 +132,7 @@ export interface ComponentDefaults {
|
|
|
127
132
|
Modal?: Partial<ModalProps>;
|
|
128
133
|
CommandPalette?: Partial<CommandPaletteProps>;
|
|
129
134
|
WeatherIcon?: Partial<WeatherIconProps>;
|
|
135
|
+
Stepper?: Partial<StepperProps>;
|
|
130
136
|
}
|
|
131
137
|
export interface ConfigProviderProps {
|
|
132
138
|
children: React.ReactNode;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
import { HtmlProps } from '../types/slots.types.js';
|
|
3
|
+
import { ColorValue } from '../themeProvider/color.types.js';
|
|
4
|
+
export declare enum LoaderType {
|
|
5
|
+
/** An arc that grows and shrinks on a faint track. The default, and the one that reads at any size. */
|
|
6
|
+
Spinner = "spinner",
|
|
7
|
+
/** A glowing head trailing a fading tail round a ring. For a hero spot: a page, a panel, an overlay. */
|
|
8
|
+
Comet = "comet",
|
|
9
|
+
/** Three dots in a wave. For a line of text or a chat reply being written. */
|
|
10
|
+
Dots = "dots",
|
|
11
|
+
/** Bars rising and falling like an equaliser. For media, uploads and data being processed. */
|
|
12
|
+
Bars = "bars",
|
|
13
|
+
/** Rings rippling out from a core. For waiting on something outside the app: a device, a connection, a search. */
|
|
14
|
+
Pulse = "pulse"
|
|
15
|
+
}
|
|
16
|
+
export interface LoaderLabels {
|
|
17
|
+
/** The loader's accessible name. */
|
|
18
|
+
loading?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface LoaderProps extends HtmlProps<HTMLSpanElement> {
|
|
21
|
+
/** The animation. Defaults to `LoaderType.Spinner`. */
|
|
22
|
+
type?: LoaderType;
|
|
23
|
+
/** Width and height: any CSS length, or a number of pixels. Defaults to `'2.5em'`, so it follows the font size around it. */
|
|
24
|
+
size?: number | string;
|
|
25
|
+
/** A `ThemeColor` or any CSS colour. Defaults to `ThemeColor.Primary`; `ThemeColor.Neutral` takes the colour of the text around it. */
|
|
26
|
+
color?: ColorValue;
|
|
27
|
+
/** Text the loader produces itself. See `LoaderLabels`. */
|
|
28
|
+
labels?: LoaderLabels;
|
|
29
|
+
className?: string;
|
|
30
|
+
style?: CSSProperties;
|
|
31
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
|
|
3
|
+
export type LoadingOverlaySlots = 'content' | 'backdrop' | 'panel' | 'message';
|
|
4
|
+
export interface LoadingOverlayProps extends HtmlProps<HTMLDivElement> {
|
|
5
|
+
/** Covers the content, blocks the pointer and marks it `aria-busy`. Defaults to `false`. */
|
|
6
|
+
isLoading?: boolean;
|
|
7
|
+
/** What the overlay covers. */
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
/** Shown in place of the default `Loader`: a `Loader` of another type, an `AnimatedLogo`, anything. */
|
|
10
|
+
loader?: ReactNode;
|
|
11
|
+
/** Text under the loader, with a highlight sweeping across it. Also the default loader's accessible name. */
|
|
12
|
+
message?: ReactNode;
|
|
13
|
+
/** Milliseconds `isLoading` has to stay true before the overlay shows, so a fast load never flashes it. Once shown, it stays at least 400ms. Defaults to `200`. */
|
|
14
|
+
delay?: number;
|
|
15
|
+
className?: string;
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
/** Classes for the inner elements. See `LoadingOverlaySlots`. */
|
|
18
|
+
classNames?: SlotClassNames<LoadingOverlaySlots>;
|
|
19
|
+
/** Inline styles for the inner elements. See `LoadingOverlaySlots`. */
|
|
20
|
+
styles?: SlotStyles<LoadingOverlaySlots>;
|
|
21
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { StepperProps } from './stepper.types.js';
|
|
3
|
-
export default function Stepper(
|
|
3
|
+
export default function Stepper(props: StepperProps): React.JSX.Element;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { IconContent } from '../types/icon.types.js';
|
|
3
3
|
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { ColorValue } from '../themeProvider/color.types.js';
|
|
5
|
+
/** Direction the steps run in. */
|
|
6
|
+
export declare enum StepperOrientation {
|
|
6
7
|
Horizontal = "horizontal",
|
|
7
8
|
Vertical = "vertical"
|
|
8
9
|
}
|
|
9
|
-
/**
|
|
10
|
+
/** How the step markers are drawn. */
|
|
10
11
|
export declare enum StepperStyleType {
|
|
11
|
-
/** Numbered markers, filled solid on completion
|
|
12
|
-
|
|
13
|
-
/** Numbered markers that stay ringed when completed
|
|
12
|
+
/** Numbered markers, filled solid on completion. The default. */
|
|
13
|
+
Filled = "filled",
|
|
14
|
+
/** Numbered markers that stay ringed when completed, with a check in the colour. */
|
|
14
15
|
Outlined = "outlined",
|
|
15
16
|
/** Minimal dots without numbers, for a compact onboarding or carousel style. */
|
|
16
17
|
Dots = "dots"
|
|
@@ -39,6 +40,16 @@ export declare enum StepperLabelPlacement {
|
|
|
39
40
|
Right = "right"
|
|
40
41
|
}
|
|
41
42
|
export type StepperSlots = 'root' | 'entry' | 'entryNumber' | 'entryLabel' | 'connector' | 'description' | 'content' | 'optional' | 'icon';
|
|
43
|
+
export interface StepperLabels {
|
|
44
|
+
/** Hint under the label of a step with `optional: true`. */
|
|
45
|
+
optional?: string;
|
|
46
|
+
/** Status of a completed step, read out by screen readers. */
|
|
47
|
+
completed?: string;
|
|
48
|
+
/** Status of a step not reached yet, read out by screen readers. */
|
|
49
|
+
notCompleted?: string;
|
|
50
|
+
/** Status of a step with `error`, read out by screen readers. */
|
|
51
|
+
error?: string;
|
|
52
|
+
}
|
|
42
53
|
export interface StepperStep {
|
|
43
54
|
/** Primary label for the step. */
|
|
44
55
|
label: React.ReactNode;
|
|
@@ -48,28 +59,33 @@ export interface StepperStep {
|
|
|
48
59
|
content?: React.ReactNode;
|
|
49
60
|
/** Icon shown in the marker instead of the step number — a FontAwesome icon or any node. */
|
|
50
61
|
icon?: IconContent;
|
|
51
|
-
/** Marks the step as errored,
|
|
62
|
+
/** Marks the step as errored, drawing its marker in the theme's `--error-color`. */
|
|
52
63
|
error?: boolean;
|
|
53
|
-
/** `true` renders
|
|
64
|
+
/** `true` renders the `optional` label as a hint; a node renders custom hint text. */
|
|
54
65
|
optional?: boolean | React.ReactNode;
|
|
55
66
|
/** Disables this step: never clickable, dimmed. */
|
|
56
67
|
disabled?: boolean;
|
|
57
68
|
}
|
|
58
|
-
export interface StepperProps extends HtmlProps {
|
|
69
|
+
export interface StepperProps extends HtmlProps<HTMLOListElement> {
|
|
59
70
|
steps?: StepperStep[];
|
|
71
|
+
/** Zero-based index of the current step. `steps.length` marks every step completed. */
|
|
60
72
|
currentStep?: number;
|
|
61
|
-
|
|
73
|
+
/** Direction the steps run in (default `Horizontal`). */
|
|
74
|
+
orientation?: StepperOrientation;
|
|
62
75
|
onStepClicked?: ((index: number) => void) | null;
|
|
63
76
|
/** Allow clicking any step, not just completed ones. */
|
|
64
77
|
nonLinear?: boolean;
|
|
65
|
-
/** Hide
|
|
78
|
+
/** Hide each step's label, description and hint visually. Screen readers still read them. */
|
|
66
79
|
hideLabels?: boolean;
|
|
67
|
-
/**
|
|
80
|
+
/** How the markers are drawn (default `Filled`). */
|
|
68
81
|
styleType?: StepperStyleType;
|
|
82
|
+
/** A `ThemeColor` (default `Primary`) or any CSS colour, such as `'var(--brand)'`. */
|
|
83
|
+
color?: ColorValue;
|
|
69
84
|
/** Which step bodies are expanded. Vertical `content` only (default `None`). */
|
|
70
85
|
collapse?: StepperCollapse;
|
|
71
86
|
/** Label position relative to the marker (default: horizontal `Bottom`, vertical `Right`). */
|
|
72
87
|
labelPlacement?: StepperLabelPlacement;
|
|
88
|
+
labels?: StepperLabels;
|
|
73
89
|
className?: string;
|
|
74
90
|
style?: React.CSSProperties;
|
|
75
91
|
classNames?: SlotClassNames<StepperSlots>;
|
|
@@ -125,24 +125,12 @@ export interface ThemeVariables {
|
|
|
125
125
|
'--stepper-marker-size'?: string;
|
|
126
126
|
/** Step marker corner radius. Falls back to --default-border-radius. */
|
|
127
127
|
'--stepper-marker-radius'?: string;
|
|
128
|
-
/** Idle (upcoming) marker/connector colour. Falls back to --primary-lighter. */
|
|
129
|
-
'--stepper-idle-color'?: string;
|
|
130
|
-
/** Current-step marker colour. Falls back to --primary-color. */
|
|
131
|
-
'--stepper-active-color'?: string;
|
|
132
|
-
/** Completed-step marker fill/colour. Falls back to --primary-color. */
|
|
133
|
-
'--stepper-done-color'?: string;
|
|
134
|
-
/** Errored-step marker colour. Falls back to --error-color. */
|
|
135
|
-
'--stepper-error-color'?: string;
|
|
136
|
-
/** Completed connector colour. Falls back to --primary-color. */
|
|
137
|
-
'--stepper-connector-color'?: string;
|
|
138
128
|
/** Completed connector thickness. Falls back to 3px. */
|
|
139
129
|
'--stepper-connector-thickness'?: string;
|
|
140
130
|
/** Not-yet-reached connector thickness. Falls back to 1px. */
|
|
141
131
|
'--stepper-connector-idle-thickness'?: string;
|
|
142
132
|
/** Gap between marker and label, and grid column gap. Falls back to 12px. */
|
|
143
133
|
'--stepper-gap'?: string;
|
|
144
|
-
/** Text/check colour on a filled marker. Falls back to --text-on-primary. */
|
|
145
|
-
'--stepper-text-on-marker'?: string;
|
|
146
134
|
/** Timer ring track (unfilled) colour. Falls back to --background-accent-light. */
|
|
147
135
|
'--timer-track-color'?: string;
|
|
148
136
|
/** Timer ring progress (remaining time) colour. Falls back to --primary-color. */
|
|
@@ -232,6 +220,10 @@ export interface ThemeVariables {
|
|
|
232
220
|
/** Width a column collapses to once it has no cards (see `collapseEmptyColumns`). Falls back to 140px. */
|
|
233
221
|
'--kanban-empty-column-width'?: string;
|
|
234
222
|
'--option-picker-padding'?: string;
|
|
223
|
+
/** Veil over the content while it loads. Falls back to --background at 50%. */
|
|
224
|
+
'--loading-overlay-background'?: string;
|
|
225
|
+
/** How far the content under the veil is blurred. Falls back to 4px; 0px turns the blur off. */
|
|
226
|
+
'--loading-overlay-blur'?: string;
|
|
235
227
|
/** Track (unfilled) background colour. Falls back to --background-accent. */
|
|
236
228
|
'--progress-bar-track-color'?: string;
|
|
237
229
|
/** Canvas behind the plan. Falls back to --background. */
|
package/dist/types/index.d.ts
CHANGED
|
@@ -76,7 +76,10 @@ export { default as KanbanBoard } from './common/kanbanBoard/index.js';
|
|
|
76
76
|
export * from './common/kanbanBoard/index.js';
|
|
77
77
|
export { default as KlipyPicker } from './common/klipyPicker/index.js';
|
|
78
78
|
export * from './common/klipyPicker/index.js';
|
|
79
|
-
export
|
|
79
|
+
export { default as Loader } from './common/loader/index.js';
|
|
80
|
+
export * from './common/loader/index.js';
|
|
81
|
+
export { default as LoadingOverlay } from './common/loadingOverlay/index.js';
|
|
82
|
+
export * from './common/loadingOverlay/index.js';
|
|
80
83
|
export { default as Menu } from './common/menu/index.js';
|
|
81
84
|
export * from './common/menu/index.js';
|
|
82
85
|
export { default as Modal } from './common/modal/index.js';
|
package/docs/Button.md
CHANGED
|
@@ -69,7 +69,7 @@ import { faPlus, faSave, faTrash, faXmark } from '@fortawesome/free-solid-svg-ic
|
|
|
69
69
|
|
|
70
70
|
- `ButtonStyleType`: `Filled` | `Light` | `Outlined` (default) | `Plain`
|
|
71
71
|
- `ThemeColor`: `Primary` (default) | `Neutral` | `Success` | `Info` | `Warn` | `Error`
|
|
72
|
-
- `ButtonSize`: `
|
|
72
|
+
- `ButtonSize`: `Small` | `Medium` (default) | `Large` | `Icon`
|
|
73
73
|
- `ButtonType`: `Button` | `Reset` | `Submit`
|
|
74
74
|
|
|
75
75
|
**Key props:**
|
|
@@ -81,7 +81,7 @@ import { faPlus, faSave, faTrash, faXmark } from '@fortawesome/free-solid-svg-ic
|
|
|
81
81
|
| `size` | `ButtonSize` | Size variant. `Icon` strips all padding, inherits the surrounding text size, and centres a lone icon — set the width/height yourself |
|
|
82
82
|
| `type` | `ButtonType` | HTML button type |
|
|
83
83
|
| `icon` | `IconDefinition \| ReactElement` | FontAwesome icon or any React element, shown before label |
|
|
84
|
-
| `isLoading` | `boolean` | Replaces content with a
|
|
84
|
+
| `isLoading` | `boolean` | Replaces content with a [Loader](Loader.md) in the button's text colour. Blocks clicks like `disabled` but keeps full colour |
|
|
85
85
|
| `disabled` | `boolean` | Fades the button to half opacity |
|
|
86
86
|
| `onClick` | `(e: MouseEvent) => void \| Promise<void>` | |
|
|
87
87
|
|
|
@@ -119,10 +119,16 @@ so an icon is never cut off by a flexible sibling. A multi-word label still wrap
|
|
|
119
119
|
|
|
120
120
|
## Sizing
|
|
121
121
|
|
|
122
|
-
A Button is sized by its font. `--default-font-size` is the base, and `Small` and `Large` are multiples of it (0.75x and 1.25x), so a theme with a smaller base font gets proportionally smaller controls everywhere. Padding and the icon gap are in `em`, so the whole box grows with the label rather than a large button wearing a
|
|
122
|
+
A Button is sized by its font. `--default-font-size` is the base, `Medium` is that size, and `Small` and `Large` are multiples of it (0.75x and 1.25x), so a theme with a smaller base font gets proportionally smaller controls everywhere. Padding and the icon gap are in `em`, so the whole box grows with the label rather than a large button wearing a medium button's padding.
|
|
123
123
|
|
|
124
124
|
`ButtonSize.Icon` is the exception: it inherits the surrounding text size and has no padding at all, because the caller sets the box.
|
|
125
125
|
|
|
126
|
+
## Migration from `ButtonSize.Default`
|
|
127
|
+
|
|
128
|
+
Before 0.45, `ButtonSize.Default` was a second name for `Medium`, which is now the default. Replace
|
|
129
|
+
`size={ButtonSize.Default}` with `size={ButtonSize.Medium}`, or leave the prop out. The look does
|
|
130
|
+
not change.
|
|
131
|
+
|
|
126
132
|
## Migration from `Primary`, `Default` and `Delete`
|
|
127
133
|
|
|
128
134
|
Before 0.43, `styleType` set emphasis and colour in one value. `Primary`, `Default` and `Delete` no
|
package/docs/CLAUDE.md
CHANGED
|
@@ -103,7 +103,8 @@ enums and slot names. Do not infer props from a component's name.
|
|
|
103
103
|
| InteractableDiv.md | InteractableDiv | Accessible `<div>` that behaves like a button — click and keyboard (Enter/Space) events, with proper ARIA semantics |
|
|
104
104
|
| KanbanBoard.md | KanbanBoard, KanbanColumn | Drag-and-drop board with columns — task management, workflow stages, status boards (e.g. Todo / In Progress / Done) |
|
|
105
105
|
| KlipyPicker.md | KlipyPicker | GIF picker backed by the Klipy API — chat reactions, message composers, content authoring tools |
|
|
106
|
-
|
|
|
106
|
+
| Loader.md | Loader, LoaderType, ThemeColor | A loading indicator for something in progress with no known end: a fetch, a save, a connection |
|
|
107
|
+
| LoadingOverlay.md | LoadingOverlay, Loader, LoaderType | Covering content while it reloads: a table refreshing, a form saving, a panel fetching its next page |
|
|
107
108
|
| Menu.md | Menu, menuHotkeys | A list of actions hanging off a trigger — a row's "more" button, a toolbar overflow, a context menu on a card |
|
|
108
109
|
| Modal.md | Modal | Full overlay dialog — forms, detail views, confirmations, wizards that need to block the rest of the UI |
|
|
109
110
|
| MultiSelect.md | MultiSelect | Pick several options from a list |
|
|
@@ -124,10 +125,10 @@ enums and slot names. Do not infer props from a component's name.
|
|
|
124
125
|
| ScrollbarProvider.md | ScrollbarProvider | Applies custom scrollbar styling to a scrollable region — use to keep scrollbar appearance consistent with the theme |
|
|
125
126
|
| SearchInput.md | SearchInput | Search field with built-in debouncing and an optional result count line — list filters, search-as-you-type pages |
|
|
126
127
|
| SectionHeader.md | SectionHeader, SectionHeaderSize | A reusable heading block for the top of a page, panel, card, or any section — a title with an optional subtitle, a leading icon or thumbnail, and a trailing actions area |
|
|
127
|
-
| Skeleton.md | Skeleton, SkeletonVariant, SkeletonAnimation | Content-shaped loading placeholder, shown while real content is being fetched — more polished than a
|
|
128
|
+
| Skeleton.md | Skeleton, SkeletonVariant, SkeletonAnimation | Content-shaped loading placeholder, shown while real content is being fetched — more polished than a Loader for content-heavy pages (lists, cards, profile headers) |
|
|
128
129
|
| Slider.md | Slider | Let the user pick a number from a continuous or stepped range by dragging a thumb: volume, brightness, price ranges, zoom, quality presets |
|
|
129
130
|
| SplitButton.md | SplitButton | A primary action button with a small attached dropdown for closely related secondary actions, e.g. "Save ▾" opening "Save as draft" / "Save and close" |
|
|
130
|
-
| Stepper.md | Stepper | Step progress indicator for multi-step forms, onboarding flows, and checkout wizards |
|
|
131
|
+
| Stepper.md | Stepper, StepperOrientation, StepperStyleType, StepperCollapse, StepperLabelPlacement, ThemeColor | Step progress indicator for multi-step forms, onboarding flows, and checkout wizards |
|
|
131
132
|
| Sticky.md | Sticky | Pin a piece of content to the top of the viewport once the page scrolls past it — section headers, toolbars, filter bars, table headers |
|
|
132
133
|
| Switch.md | Switch | Sliding boolean toggle — settings panels, feature flags, preference lists |
|
|
133
134
|
| TabHeader.md | TabHeader | A horizontal row of tabs to switch between sibling views or sections — settings panels, dashboards, detail pages |
|
package/docs/Checkbox.md
CHANGED
|
@@ -33,7 +33,7 @@ const agreedValidator = new FormValidator(false, [Validators.required()]);
|
|
|
33
33
|
| `onToggle` | `(isToggled: boolean, event?) => void` | Change handler |
|
|
34
34
|
| `formValidator` | `FormValidator` | Connects to form validation |
|
|
35
35
|
| `disabled` | `boolean` | |
|
|
36
|
-
| `isLoading` | `boolean` | Shows
|
|
36
|
+
| `isLoading` | `boolean` | Shows a [Loader](Loader.md) in place of the box and ignores clicks |
|
|
37
37
|
| `children` | `ReactNode` | Custom label content |
|
|
38
38
|
| `cursorDefault` | `boolean` | Use default cursor instead of pointer |
|
|
39
39
|
| `ref` | `Ref<HTMLDivElement>` | Ref to the root element |
|
package/docs/ConfigProvider.md
CHANGED
|
@@ -95,7 +95,7 @@ A nested provider inherits it unless it sets its own, the same way `defaultProps
|
|
|
95
95
|
Each entry is a `Partial<...Props>`, so any of that component's props can be defaulted:
|
|
96
96
|
|
|
97
97
|
- **Form inputs:** `Input` · `Textarea` · `NumberInput` · `Dropdown` · `InputDropdown` · `Checkbox` · `Switch` · `RadioGroup` · `DatePicker` · `OptionPicker` · `OtpInput`
|
|
98
|
-
- **Display:** `Button` · `CopyButton` · `ActionButtons` · `Badge` · `Chip` · `Card` · `SectionHeader` · `Skeleton` · `Accordion` · `Divider` · `Timer` · `WeatherIcon`
|
|
98
|
+
- **Display:** `Button` · `CopyButton` · `ActionButtons` · `Badge` · `Chip` · `Card` · `SectionHeader` · `Skeleton` · `Loader` · `LoadingOverlay` · `Accordion` · `Divider` · `Timer` · `WeatherIcon` · `Stepper`
|
|
99
99
|
- **Overlays:** `ConfirmModal` · `Modal` · `CommandPalette` · `Popover`
|
|
100
100
|
- **Editors:** `RoomDrawer`, `RoomViewer`
|
|
101
101
|
- **Scheduling:** `Calendar`, for `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays`, `scrollToHour`, `workingHours` and `showWeekNumbers` only (see below)
|
package/docs/Loader.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Loader
|
|
2
|
+
|
|
3
|
+
**When to use:** A loading indicator for something in progress with no known end: a fetch, a save, a connection. To cover content while it reloads use [LoadingOverlay.md](LoadingOverlay.md), for a button use `Button`'s own `isLoading`, and for content not there yet a [Skeleton.md](Skeleton.md) in its shape reads better. For progress you can measure, use [ProgressBar.md](ProgressBar.md).
|
|
4
|
+
|
|
5
|
+
**Keywords:** busy, waiting, activity indicator, throbber, async, fetching, typing indicator, equalizer, radar, ripple
|
|
6
|
+
|
|
7
|
+
**Import:** `import { Loader, LoaderType, ThemeColor } from '@ahrowe/ui'`
|
|
8
|
+
**Types:** `import type { LoaderProps, LoaderLabels } from '@ahrowe/ui'`
|
|
9
|
+
|
|
10
|
+
**Enums:** `LoaderType.Spinner` (default) | `LoaderType.Comet` | `LoaderType.Dots` | `LoaderType.Bars` | `LoaderType.Pulse`
|
|
11
|
+
|
|
12
|
+
- `Spinner`: an arc that grows and shrinks on a faint track. Reads at any size, down to 16px
|
|
13
|
+
- `Comet`: a glowing head trailing a tapering tail round a ring. For a hero spot: a page, a panel, an overlay
|
|
14
|
+
- `Dots`: three dots in a wave. For a line of text or a reply being written
|
|
15
|
+
- `Bars`: bars rising and falling like an equaliser. For media, uploads and data being processed
|
|
16
|
+
- `Pulse`: rings rippling out from a core. For waiting on something outside the app: a device, a connection, a search
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { Loader, LoaderType, ThemeColor } from '@ahrowe/ui';
|
|
20
|
+
|
|
21
|
+
// Default: a Spinner in --primary-color, 2.5em square
|
|
22
|
+
{isLoading && <Loader />}
|
|
23
|
+
|
|
24
|
+
<Loader type={LoaderType.Comet} size='4em' />
|
|
25
|
+
<Loader type={LoaderType.Pulse} color={ThemeColor.Success} />
|
|
26
|
+
<Loader type={LoaderType.Bars} color='#e879f9' size={24} />
|
|
27
|
+
|
|
28
|
+
// In a line of text: Neutral takes the text's own colour, 1em its size. Dots rest on the
|
|
29
|
+
// baseline like an ellipsis; the round types sit centred on the text like an icon
|
|
30
|
+
<p>Ava is typing <Loader type={LoaderType.Dots} size='1em' color={ThemeColor.Neutral} /></p>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Sizing:** `size` sets width and height, which are always equal. It is `2.5em` by default, so a
|
|
34
|
+
loader follows the font size of what it sits in; pass any CSS length, or a number of pixels. Size it
|
|
35
|
+
with `size` rather than a `width` in a class: the stylesheet reads `size`, and a class would tie with
|
|
36
|
+
it on specificity.
|
|
37
|
+
|
|
38
|
+
**Colour:** `color` takes a `ThemeColor` (default `Primary`) or any CSS colour, see
|
|
39
|
+
[ThemeColor.md](ThemeColor.md). `ThemeColor.Neutral` takes the colour of the text around it, which
|
|
40
|
+
is what a loader on a coloured surface wants.
|
|
41
|
+
|
|
42
|
+
## One type for the whole app
|
|
43
|
+
|
|
44
|
+
Every component with a loading state draws it with this `Loader`: `Button` (and so `SplitButton`,
|
|
45
|
+
`ActionButtons` and `ConfirmModal`), `Checkbox`, `VirtualList`, `Dropdown`, `KanbanBoard` and
|
|
46
|
+
`LoadingOverlay`. A default set once reaches all of them:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<AhroweProvider defaultProps={{ Loader: { type: LoaderType.Dots } }}>
|
|
50
|
+
<App />
|
|
51
|
+
</AhroweProvider>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
An app-wide `type` and `labels` reach all of them. `color` reaches all but Button's, which keeps
|
|
55
|
+
the button's text colour. `size` reaches only `LoadingOverlay`'s default loader and the ones you
|
|
56
|
+
place yourself; the others size theirs to fit.
|
|
57
|
+
|
|
58
|
+
**Accessibility:** the root is a `role="progressbar"` with no value, which is how an indeterminate
|
|
59
|
+
progress indicator is announced, named "Loading" (`labels.loading`). Pass `aria-labelledby` to name
|
|
60
|
+
it after visible text instead, as `LoadingOverlay` does with its `message`. Inside something whose
|
|
61
|
+
name comes from its content (a custom checkbox) or that may only hold its own items (a list), pass
|
|
62
|
+
`aria-hidden` and mark the container `aria-busy` instead, as `Checkbox` and `VirtualList` do.
|
|
63
|
+
|
|
64
|
+
**Note:** a loader keeps moving under `prefers-reduced-motion`. One that stands still says the app
|
|
65
|
+
has hung, which is the opposite of what it is there to say.
|
|
66
|
+
|
|
67
|
+
**Key props:**
|
|
68
|
+
|
|
69
|
+
| Prop | Type | Description |
|
|
70
|
+
|------|------|-------------|
|
|
71
|
+
| `type` | `LoaderType` | The animation (default `Spinner`) |
|
|
72
|
+
| `size` | `number \| string` | Width and height, any CSS length or a number of pixels (default `'2.5em'`) |
|
|
73
|
+
| `color` | `ColorValue` | A `ThemeColor` or any CSS colour (default `ThemeColor.Primary`) |
|
|
74
|
+
| `labels` | `LoaderLabels` | Text the loader produces itself, see below |
|
|
75
|
+
| `className` / `style` | | Root `span` |
|
|
76
|
+
|
|
77
|
+
**Labels:** `loading`, the accessible name. Pass `labels` to override it, on the component or app-wide through `ConfigProvider`; keys merge individually. Type: `LoaderLabels`.
|
|
78
|
+
|
|
79
|
+
## Migration from `SpinnerLoading`
|
|
80
|
+
|
|
81
|
+
`SpinnerLoading` was removed in favour of `Loader`, whose default type is the same kind of spinner.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
// Before
|
|
85
|
+
<SpinnerLoading className="my-spinner" /> // .my-spinner { width: 24px; height: 24px }
|
|
86
|
+
|
|
87
|
+
// After
|
|
88
|
+
<Loader size={24} />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
It used to be 70px by default and is `2.5em` now (40px at a 16px base), and it is a `span` rather
|
|
92
|
+
than an `svg`. It is announced as a progressbar named "Loading", where `SpinnerLoading` was not
|
|
93
|
+
announced at all.
|
|
94
|
+
|
|
95
|
+
**Slots:** none. The root `span` takes `className` and `style`.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# LoadingOverlay
|
|
2
|
+
|
|
3
|
+
**When to use:** Covering content while it reloads: a table refreshing, a form saving, a panel fetching its next page. It frosts over what it wraps and keeps its shape in view. For content not there yet a [Skeleton.md](Skeleton.md) in its shape reads better, and a lone indicator with nothing to cover is a [Loader.md](Loader.md).
|
|
4
|
+
|
|
5
|
+
**Keywords:** spinner, frosted glass, scrim, dim, disable interaction, pending, mask
|
|
6
|
+
|
|
7
|
+
**Import:** `import { LoadingOverlay, Loader, LoaderType } from '@ahrowe/ui'`
|
|
8
|
+
**Types:** `import type { LoadingOverlayProps } from '@ahrowe/ui'`
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { LoadingOverlay, Loader, LoaderType, AnimatedLogo, ThemeColor } from '@ahrowe/ui';
|
|
12
|
+
|
|
13
|
+
// Wrap what is loading. It needs no positioned parent: it is one
|
|
14
|
+
<LoadingOverlay isLoading={isFetching}>
|
|
15
|
+
<InvoiceTable rows={rows} />
|
|
16
|
+
</LoadingOverlay>
|
|
17
|
+
|
|
18
|
+
// A message under the loader, with a highlight sweeping across it
|
|
19
|
+
<LoadingOverlay isLoading={isSaving} message="Saving changes…">
|
|
20
|
+
<ProfileForm />
|
|
21
|
+
</LoadingOverlay>
|
|
22
|
+
|
|
23
|
+
// Any loader in place of the default one
|
|
24
|
+
<LoadingOverlay
|
|
25
|
+
isLoading={isConnecting}
|
|
26
|
+
message="Connecting to the printer…"
|
|
27
|
+
loader={<Loader type={LoaderType.Pulse} color={ThemeColor.Success} size="3.5em" />}
|
|
28
|
+
>
|
|
29
|
+
<PrinterPanel />
|
|
30
|
+
</LoadingOverlay>
|
|
31
|
+
|
|
32
|
+
// A branded one
|
|
33
|
+
<LoadingOverlay isLoading={isBooting} loader={<AnimatedLogo size="4em" />}>
|
|
34
|
+
<Dashboard />
|
|
35
|
+
</LoadingOverlay>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Timing
|
|
39
|
+
|
|
40
|
+
The overlay waits `delay` (200ms) after `isLoading` turns true before it shows, so a load that
|
|
41
|
+
finishes faster never flashes it. Once shown it stays at least 400ms, so one that finishes just
|
|
42
|
+
after it appeared does not flash it either, then fades out. Loading again while it fades brings it
|
|
43
|
+
straight back. `delay={0}` shows it at once, from the first render on.
|
|
44
|
+
|
|
45
|
+
The content is marked `aria-busy` the moment `isLoading` is true, delay or not.
|
|
46
|
+
|
|
47
|
+
## What it blocks
|
|
48
|
+
|
|
49
|
+
The backdrop takes every pointer event over the content and shows a `progress` cursor. It does not
|
|
50
|
+
take the focus or block the keyboard: making the content `inert` would drop the focus of whoever
|
|
51
|
+
pressed the button that started the load. An action that must not run twice should still check its
|
|
52
|
+
own loading state.
|
|
53
|
+
|
|
54
|
+
**Wrapping:** the root is a `div` with `position: relative`, and the content sits in a `div` of its
|
|
55
|
+
own, so anything inside with a `z-index` (a sticky header) stays under the backdrop. The backdrop
|
|
56
|
+
takes the root's `border-radius`, so a `className` that rounds the root rounds the overlay too.
|
|
57
|
+
Content taller than the screen keeps the loader in view rather than at its middle.
|
|
58
|
+
|
|
59
|
+
**Scrolling content:** give the scrolling to `classNames.content` (its `overflow` and its height
|
|
60
|
+
limit), not to the root. The backdrop covers the root's box, so in a root that scrolls it would
|
|
61
|
+
scroll away with the content and leave the rest uncovered.
|
|
62
|
+
|
|
63
|
+
**Theme variables:** `--loading-overlay-background` (the veil, default `--background` at 50%) and
|
|
64
|
+
`--loading-overlay-blur` (default `4px`, `0px` turns the blur off). See
|
|
65
|
+
[ThemeProvider.md](ThemeProvider.md).
|
|
66
|
+
|
|
67
|
+
**App-wide:** `LoadingOverlay` takes `defaultProps` like any other component, so one
|
|
68
|
+
`AhroweProvider` can give every overlay the same `loader` or `delay`. Its default loader is a
|
|
69
|
+
`Loader`, which follows `defaultProps.Loader` as well.
|
|
70
|
+
|
|
71
|
+
**Key props:**
|
|
72
|
+
|
|
73
|
+
| Prop | Type | Description |
|
|
74
|
+
|------|------|-------------|
|
|
75
|
+
| `isLoading` | `boolean` | Covers the content, blocks the pointer and marks it `aria-busy` (default `false`) |
|
|
76
|
+
| `children` | `ReactNode` | What the overlay covers |
|
|
77
|
+
| `message` | `ReactNode` | Text under the loader. Also the default loader's accessible name |
|
|
78
|
+
| `loader` | `ReactNode` | Shown in place of the default `<Loader />` |
|
|
79
|
+
| `delay` | `number` | Milliseconds before it shows (default `200`) |
|
|
80
|
+
| `className` / `style` | | Root `div` |
|
|
81
|
+
|
|
82
|
+
**Note:** under `prefers-reduced-motion` the panel fades in without rising and the message stands
|
|
83
|
+
still. The loader itself keeps moving, see [Loader.md](Loader.md).
|
|
84
|
+
|
|
85
|
+
**Slots:** `content` (the `div` around `children`) `backdrop` (the veil over it) `panel` (the column holding the loader and the message, for a card behind them) `message`
|
package/docs/Skeleton.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Skeleton
|
|
2
2
|
|
|
3
|
-
**When to use:** Content-shaped loading placeholder, shown while real content is being fetched — more polished than a
|
|
3
|
+
**When to use:** Content-shaped loading placeholder, shown while real content is being fetched — more polished than a [Loader](Loader.md) for content-heavy pages (lists, cards, profile headers). Pick the `variant` that matches the shape of what's loading.
|
|
4
4
|
|
|
5
5
|
**Keywords:** shimmer placeholder, content placeholder
|
|
6
6
|
|
package/docs/SplitButton.md
CHANGED
|
@@ -70,7 +70,7 @@ import { ButtonStyleType } from '@ahrowe/ui';
|
|
|
70
70
|
| `actions` | `SplitButtonAction[]` | Secondary actions shown in the dropdown |
|
|
71
71
|
| `styleType` | `ButtonStyleType` | Shared by both the primary and trigger button (default `Filled`) |
|
|
72
72
|
| `color` | `ColorValue` | Shared by both buttons (default `Primary`); or any CSS colour, as on Button |
|
|
73
|
-
| `size` | `ButtonSize` | Size variant, shared by both buttons |
|
|
73
|
+
| `size` | `ButtonSize` | Size variant, shared by both buttons (default `Medium`) |
|
|
74
74
|
| `disabled` | `boolean` | Disables both the primary and trigger button |
|
|
75
75
|
| `isLoading` | `boolean` | Shows a spinner on the primary button (same as `Button`'s own `isLoading`) |
|
|
76
76
|
| `align` | `PopoverAlign` | Which edge of the group the menu lines up with (default `End`, the chevron's side). The menu is a [Menu](Menu.md), hence `Popover`'s enum |
|