@ahrowe/ui 0.12.0 → 0.14.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/esm/common/alert/alert.mjs +2 -0
- package/dist/esm/common/alert/alert.mjs.map +1 -0
- package/dist/esm/common/alert/alert.module.mjs +2 -0
- package/dist/esm/common/alert/alert.module.mjs.map +1 -0
- package/dist/esm/common/alert/alert.types.mjs +2 -0
- package/dist/esm/common/alert/alert.types.mjs.map +1 -0
- package/dist/esm/common/animatedIcon/animatedIcon.mjs +2 -0
- package/dist/esm/common/animatedIcon/animatedIcon.mjs.map +1 -0
- package/dist/esm/common/animatedIcon/animatedIcon.module.mjs +2 -0
- package/dist/esm/common/animatedIcon/animatedIcon.module.mjs.map +1 -0
- package/dist/esm/common/breadcrumb/breadcrumb.mjs +2 -0
- package/dist/esm/common/breadcrumb/breadcrumb.mjs.map +1 -0
- package/dist/esm/common/breadcrumb/breadcrumb.module.mjs +2 -0
- package/dist/esm/common/breadcrumb/breadcrumb.module.mjs.map +1 -0
- package/dist/esm/common/buttonGroup/buttonGroup.mjs +2 -0
- package/dist/esm/common/buttonGroup/buttonGroup.mjs.map +1 -0
- package/dist/esm/common/buttonGroup/buttonGroup.module.mjs +2 -0
- package/dist/esm/common/buttonGroup/buttonGroup.module.mjs.map +1 -0
- package/dist/esm/common/buttonGroup/buttonGroup.types.mjs +2 -0
- package/dist/esm/common/buttonGroup/buttonGroup.types.mjs.map +1 -0
- package/dist/esm/common/carousel/carousel.mjs +2 -0
- package/dist/esm/common/carousel/carousel.mjs.map +1 -0
- package/dist/esm/common/carousel/carousel.module.mjs +2 -0
- package/dist/esm/common/carousel/carousel.module.mjs.map +1 -0
- package/dist/esm/common/divider/divider.mjs +1 -1
- package/dist/esm/common/divider/divider.mjs.map +1 -1
- package/dist/esm/common/divider/divider.module.mjs +1 -1
- package/dist/esm/common/divider/divider.module.mjs.map +1 -1
- package/dist/esm/common/divider/divider.types.mjs +1 -1
- package/dist/esm/common/divider/divider.types.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/fab/fab.mjs +1 -1
- package/dist/esm/common/fab/fab.mjs.map +1 -1
- package/dist/esm/common/floatingMenu/floatingMenu.mjs +1 -1
- package/dist/esm/common/floatingMenu/floatingMenu.mjs.map +1 -1
- package/dist/esm/common/floatingMenu/floatingMenu.module.mjs.map +1 -1
- package/dist/esm/common/hooks/useFocusBoundary.mjs +2 -0
- package/dist/esm/common/hooks/useFocusBoundary.mjs.map +1 -0
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/input/input.module.mjs +1 -1
- package/dist/esm/common/input/input.module.mjs.map +1 -1
- package/dist/esm/common/input/input.types.mjs +1 -1
- package/dist/esm/common/input/input.types.mjs.map +1 -1
- package/dist/esm/common/klipyPicker/klipyPicker.mjs +1 -1
- package/dist/esm/common/klipyPicker/klipyPicker.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/common/popover/popover.mjs +1 -1
- package/dist/esm/common/popover/popover.mjs.map +1 -1
- package/dist/esm/common/rating/rating.mjs +2 -0
- package/dist/esm/common/rating/rating.mjs.map +1 -0
- package/dist/esm/common/rating/rating.module.mjs +2 -0
- package/dist/esm/common/rating/rating.module.mjs.map +1 -0
- package/dist/esm/common/splitButton/splitButton.mjs +2 -0
- package/dist/esm/common/splitButton/splitButton.mjs.map +1 -0
- package/dist/esm/common/splitButton/splitButton.module.mjs +2 -0
- package/dist/esm/common/splitButton/splitButton.module.mjs.map +1 -0
- package/dist/esm/common/virtualList/useRowDrag.mjs +1 -1
- package/dist/esm/common/virtualList/useRowDrag.mjs.map +1 -1
- package/dist/esm/common/virtualList/useVirtualWindow.mjs +1 -1
- package/dist/esm/common/virtualList/useVirtualWindow.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/virtualRow.mjs +1 -1
- package/dist/esm/common/virtualList/virtualRow.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/package/common/alert/alert.d.ts +4 -0
- package/dist/types/package/common/alert/alert.types.d.ts +23 -0
- package/dist/types/package/common/alert/index.d.ts +2 -0
- package/dist/types/package/common/animatedIcon/animatedIcon.d.ts +3 -0
- package/dist/types/package/common/animatedIcon/animatedIcon.types.d.ts +25 -0
- package/dist/types/package/common/animatedIcon/index.d.ts +2 -0
- package/dist/types/package/common/breadcrumb/breadcrumb.d.ts +4 -0
- package/dist/types/package/common/breadcrumb/breadcrumb.types.d.ts +26 -0
- package/dist/types/package/common/breadcrumb/index.d.ts +2 -0
- package/dist/types/package/common/buttonGroup/buttonGroup.d.ts +4 -0
- package/dist/types/package/common/buttonGroup/buttonGroup.types.d.ts +12 -0
- package/dist/types/package/common/buttonGroup/index.d.ts +2 -0
- package/dist/types/package/common/carousel/carousel.d.ts +3 -0
- package/dist/types/package/common/carousel/carousel.types.d.ts +20 -0
- package/dist/types/package/common/carousel/index.d.ts +2 -0
- package/dist/types/package/common/configProvider/configProvider.types.d.ts +10 -0
- package/dist/types/package/common/divider/divider.types.d.ts +5 -0
- package/dist/types/package/common/hooks/useFocusBoundary.d.ts +20 -0
- package/dist/types/package/common/input/input.types.d.ts +5 -0
- package/dist/types/package/common/rating/index.d.ts +2 -0
- package/dist/types/package/common/rating/rating.d.ts +4 -0
- package/dist/types/package/common/rating/rating.types.d.ts +19 -0
- package/dist/types/package/common/splitButton/index.d.ts +2 -0
- package/dist/types/package/common/splitButton/splitButton.d.ts +3 -0
- package/dist/types/package/common/splitButton/splitButton.types.d.ts +28 -0
- package/dist/types/package/common/themeProvider/theme.types.d.ts +1 -0
- package/dist/types/package/common/virtualList/useRowDrag.d.ts +4 -0
- package/dist/types/package/common/virtualList/useVirtualWindow.d.ts +3 -1
- package/dist/types/package/common/virtualList/virtualList.types.d.ts +5 -1
- package/dist/types/package/common/virtualList/virtualRow.d.ts +8 -1
- package/dist/types/package/index.d.ts +12 -0
- package/docs/Alert.md +64 -0
- package/docs/Breadcrumb.md +106 -0
- package/docs/ButtonGroup.md +90 -0
- package/docs/CLAUDE.md +6 -0
- package/docs/Carousel.md +67 -0
- package/docs/Divider.md +15 -3
- package/docs/FloatingMenu.md +7 -3
- package/docs/Input.md +30 -6
- package/docs/NumberInput.md +2 -0
- package/docs/Rating.md +72 -0
- package/docs/SearchInput.md +6 -0
- package/docs/SplitButton.md +79 -0
- package/docs/VirtualList.md +86 -3
- package/package.json +1 -1
|
@@ -18,6 +18,11 @@ import { SectionHeaderProps } from '../sectionHeader/sectionHeader.types';
|
|
|
18
18
|
import { SkeletonProps } from '../skeleton/skeleton.types';
|
|
19
19
|
import { AccordionProps } from '../accordion/accordion.types';
|
|
20
20
|
import { DividerProps } from '../divider/divider.types';
|
|
21
|
+
import { AlertProps } from '../alert/alert.types';
|
|
22
|
+
import { CarouselProps } from '../carousel/carousel.types';
|
|
23
|
+
import { BreadcrumbProps } from '../breadcrumb/breadcrumb.types';
|
|
24
|
+
import { RatingProps } from '../rating/rating.types';
|
|
25
|
+
import { SplitButtonProps } from '../splitButton/splitButton.types';
|
|
21
26
|
/**
|
|
22
27
|
* Global default props keyed by component name.
|
|
23
28
|
*
|
|
@@ -52,6 +57,11 @@ export interface ComponentDefaults {
|
|
|
52
57
|
Skeleton?: Partial<SkeletonProps>;
|
|
53
58
|
Accordion?: Partial<AccordionProps>;
|
|
54
59
|
Divider?: Partial<DividerProps>;
|
|
60
|
+
Alert?: Partial<AlertProps>;
|
|
61
|
+
Carousel?: Partial<CarouselProps>;
|
|
62
|
+
Breadcrumb?: Partial<BreadcrumbProps>;
|
|
63
|
+
Rating?: Partial<RatingProps>;
|
|
64
|
+
SplitButton?: Partial<SplitButtonProps>;
|
|
55
65
|
}
|
|
56
66
|
export interface ConfigProviderProps {
|
|
57
67
|
children: React.ReactNode;
|
|
@@ -5,10 +5,15 @@ export declare enum DividerTextPosition {
|
|
|
5
5
|
Center = "center",
|
|
6
6
|
Right = "right"
|
|
7
7
|
}
|
|
8
|
+
export declare enum DividerOrientation {
|
|
9
|
+
Horizontal = "horizontal",
|
|
10
|
+
Vertical = "vertical"
|
|
11
|
+
}
|
|
8
12
|
export type DividerSlots = 'root' | 'line' | 'content';
|
|
9
13
|
export interface DividerProps extends HtmlProps {
|
|
10
14
|
text?: ReactNode;
|
|
11
15
|
textPosition?: DividerTextPosition;
|
|
16
|
+
orientation?: DividerOrientation;
|
|
12
17
|
className?: string;
|
|
13
18
|
style?: CSSProperties;
|
|
14
19
|
classNames?: SlotClassNames<DividerSlots>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
/** Tabbable descendants of `root`, in DOM order. */
|
|
3
|
+
export declare function tabbablesIn(root: ParentNode | null): HTMLElement[];
|
|
4
|
+
export interface UseFocusBoundaryArgs {
|
|
5
|
+
/** The trigger element focus returns to on Escape / Shift+Tab out of the content's top. */
|
|
6
|
+
triggerRef: RefObject<HTMLElement | null>;
|
|
7
|
+
/** The portaled content root — tabbables inside it define the Tab boundary. */
|
|
8
|
+
contentRef: RefObject<HTMLElement | null>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Focus helpers for content portaled to the end of the DOM (e.g. via BodyEnd), where Tab can't
|
|
12
|
+
* reach it in visual document order on its own. Shared by FloatingMenu and Popover, which both
|
|
13
|
+
* need to hand focus back to the trigger on Escape / Shift+Tab out of the top, and continue
|
|
14
|
+
* focus naturally past the trigger when Tab exits the bottom.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useFocusBoundary({ triggerRef, contentRef }: UseFocusBoundaryArgs): {
|
|
17
|
+
firstTriggerFocusable: () => HTMLElement | null;
|
|
18
|
+
restoreFocusToTrigger: () => void;
|
|
19
|
+
focusAfterTrigger: () => void;
|
|
20
|
+
};
|
|
@@ -11,6 +11,10 @@ export declare enum InputType {
|
|
|
11
11
|
Search = "searchInput",
|
|
12
12
|
Password = "password"
|
|
13
13
|
}
|
|
14
|
+
export declare enum InputIconPosition {
|
|
15
|
+
Left = "left",
|
|
16
|
+
Right = "right"
|
|
17
|
+
}
|
|
14
18
|
export type InputSlots = 'label' | 'container' | 'input' | 'suffix' | 'upperRightLabel' | 'fieldset';
|
|
15
19
|
type OverriddenInputAttributes = 'onChange' | 'onFocus' | 'onBlur' | 'onMouseEnter' | 'onMouseLeave' | 'onClick' | 'type' | 'value' | 'min' | 'max' | 'autoComplete';
|
|
16
20
|
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, OverriddenInputAttributes>, HtmlProps {
|
|
@@ -28,6 +32,7 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
|
|
|
28
32
|
style?: React.CSSProperties;
|
|
29
33
|
value?: string | number;
|
|
30
34
|
icon?: React.ReactElement | null;
|
|
35
|
+
iconPosition?: InputIconPosition;
|
|
31
36
|
isUppercase?: boolean;
|
|
32
37
|
isRow?: boolean;
|
|
33
38
|
tabIndex?: number;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
3
|
+
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';
|
|
4
|
+
export type RatingSlots = 'root' | 'item' | 'iconEmpty' | 'iconFilled';
|
|
5
|
+
export interface RatingProps extends HtmlProps {
|
|
6
|
+
value?: number;
|
|
7
|
+
defaultValue?: number;
|
|
8
|
+
onChange?: (value: number) => void;
|
|
9
|
+
max?: number;
|
|
10
|
+
allowHalf?: boolean;
|
|
11
|
+
allowClear?: boolean;
|
|
12
|
+
readOnly?: boolean;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
icon?: IconDefinition;
|
|
15
|
+
className?: string;
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
classNames?: SlotClassNames<RatingSlots>;
|
|
18
|
+
styles?: SlotStyles<RatingSlots>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
3
|
+
import { ButtonStyleType, ButtonSize } from '../button/button.types';
|
|
4
|
+
import { Align } from '../floatingMenu/floatingMenu.types';
|
|
5
|
+
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';
|
|
6
|
+
export interface SplitButtonAction {
|
|
7
|
+
id: string;
|
|
8
|
+
label: ReactNode;
|
|
9
|
+
onClick: () => void;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
icon?: IconDefinition;
|
|
12
|
+
}
|
|
13
|
+
export type SplitButtonSlots = 'root' | 'primaryButton' | 'triggerButton' | 'menu' | 'menuItem';
|
|
14
|
+
export interface SplitButtonProps extends HtmlProps {
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;
|
|
17
|
+
actions: SplitButtonAction[];
|
|
18
|
+
styleType?: ButtonStyleType;
|
|
19
|
+
size?: ButtonSize;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
isLoading?: boolean;
|
|
22
|
+
/** Alignment of the actions menu relative to the trigger button (default `Align.Right`) */
|
|
23
|
+
align?: Align;
|
|
24
|
+
className?: string;
|
|
25
|
+
style?: CSSProperties;
|
|
26
|
+
classNames?: SlotClassNames<SplitButtonSlots>;
|
|
27
|
+
styles?: SlotStyles<SplitButtonSlots>;
|
|
28
|
+
}
|
|
@@ -56,6 +56,7 @@ export interface ThemeVariables {
|
|
|
56
56
|
'--error-border-color'?: string;
|
|
57
57
|
'--input-label-resting-color'?: string;
|
|
58
58
|
'--input-label-floating-color'?: string;
|
|
59
|
+
'--search-input-color'?: string;
|
|
59
60
|
'--default-border-radius'?: string;
|
|
60
61
|
'--padding-sides'?: string;
|
|
61
62
|
'--margin-top'?: string;
|
|
@@ -19,9 +19,13 @@ interface UseRowDragArgs {
|
|
|
19
19
|
/** The drag-related props the parent spreads onto a given row. */
|
|
20
20
|
export interface RowDragProps {
|
|
21
21
|
reorderable: boolean;
|
|
22
|
+
/** Native mouse DnD is active for the list (independent of which row is armed). */
|
|
23
|
+
mouseDragEnabled: boolean;
|
|
22
24
|
draggable: boolean | undefined;
|
|
23
25
|
isDragging: boolean;
|
|
24
26
|
onMouseDown: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;
|
|
27
|
+
onMouseOver: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;
|
|
28
|
+
onMouseLeave: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;
|
|
25
29
|
onDragStart: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;
|
|
26
30
|
onDragOver: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;
|
|
27
31
|
onDragEnd: (() => void) | undefined;
|
|
@@ -10,6 +10,8 @@ interface UseVirtualWindowArgs<T> {
|
|
|
10
10
|
overscan: number;
|
|
11
11
|
onLoadMore?: () => Promise<void>;
|
|
12
12
|
loadMoreThreshold: number;
|
|
13
|
+
/** Initial/filter load in progress — the body is replaced by a spinner. */
|
|
14
|
+
isLoading: boolean;
|
|
13
15
|
}
|
|
14
16
|
interface UseVirtualWindowResult {
|
|
15
17
|
rootRef: React.RefObject<HTMLDivElement | null>;
|
|
@@ -37,5 +39,5 @@ interface UseVirtualWindowResult {
|
|
|
37
39
|
* scroll handle. Mode-agnostic — knows nothing about columns, selection or
|
|
38
40
|
* dragging.
|
|
39
41
|
*/
|
|
40
|
-
export declare function useVirtualWindow<T>({ items, keys, getItemKey, estimatedRowHeight, rowGap, overscan, onLoadMore, loadMoreThreshold, }: UseVirtualWindowArgs<T>): UseVirtualWindowResult;
|
|
42
|
+
export declare function useVirtualWindow<T>({ items, keys, getItemKey, estimatedRowHeight, rowGap, overscan, onLoadMore, loadMoreThreshold, isLoading, }: UseVirtualWindowArgs<T>): UseVirtualWindowResult;
|
|
41
43
|
export {};
|
|
@@ -132,7 +132,11 @@ export interface VirtualListProps<T> extends HtmlProps {
|
|
|
132
132
|
/** Show the gear column-toggle button in the header. Default: true when columns present. */
|
|
133
133
|
showColumnToggle?: boolean;
|
|
134
134
|
/**
|
|
135
|
-
* Called when the user scrolls within `loadMoreThreshold` px of the bottom
|
|
135
|
+
* Called when the user scrolls within `loadMoreThreshold` px of the bottom, and
|
|
136
|
+
* repeatedly while the rows don't fill the viewport — a list too short to scroll
|
|
137
|
+
* would otherwise never ask for a second batch. Each row count is asked at most
|
|
138
|
+
* once, so the loop ends as soon as a call appends nothing; pass `undefined`
|
|
139
|
+
* once the source is exhausted to skip even that final probe.
|
|
136
140
|
* Must return a Promise that resolves once new items have been appended to `items`.
|
|
137
141
|
* A spinner is shown at the bottom while the Promise is pending.
|
|
138
142
|
*/
|
|
@@ -16,10 +16,17 @@ export interface VirtualRowProps {
|
|
|
16
16
|
ariaSetSize?: number;
|
|
17
17
|
rowRole: 'row' | 'listitem';
|
|
18
18
|
reorderable?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Native mouse DnD is active for the list. Distinct from `draggable`, which in
|
|
21
|
+
* `dragHandle` mode is only set on the row the pointer has armed.
|
|
22
|
+
*/
|
|
23
|
+
mouseDragEnabled?: boolean;
|
|
19
24
|
draggable?: boolean;
|
|
20
25
|
isDragging?: boolean;
|
|
21
26
|
reserveToggleGutter?: boolean;
|
|
22
27
|
onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
28
|
+
onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
29
|
+
onMouseLeave?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
23
30
|
onDragStart?: (e: React.DragEvent<HTMLDivElement>) => void;
|
|
24
31
|
onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;
|
|
25
32
|
onDragEnd?: () => void;
|
|
@@ -38,5 +45,5 @@ export interface VirtualRowProps {
|
|
|
38
45
|
* grid (table mode), registering itself with the shared ResizeObserver and
|
|
39
46
|
* carrying all the drag / drop-indicator wiring the parent assigns it.
|
|
40
47
|
*/
|
|
41
|
-
declare function VirtualRow({ index, top, padding, columnTemplate, isSelected, showDivider, hover, onClick, observer, ariaRowIndex, ariaPosInSet, ariaSetSize, rowRole, reorderable, draggable, isDragging, reserveToggleGutter, onMouseDown, onDragStart, onDragOver, onDragEnd, onDrop, onTouchStart, dropPosition, dropIndentPx, dropIndicatorClassName, dropIndicatorStyle, rowClassName, rowStyle, children, }: VirtualRowProps): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
declare function VirtualRow({ index, top, padding, columnTemplate, isSelected, showDivider, hover, onClick, observer, ariaRowIndex, ariaPosInSet, ariaSetSize, rowRole, reorderable, mouseDragEnabled, draggable, isDragging, reserveToggleGutter, onMouseDown, onMouseOver, onMouseLeave, onDragStart, onDragOver, onDragEnd, onDrop, onTouchStart, dropPosition, dropIndentPx, dropIndicatorClassName, dropIndicatorStyle, rowClassName, rowStyle, children, }: VirtualRowProps): import("react/jsx-runtime").JSX.Element;
|
|
42
49
|
export default VirtualRow;
|
|
@@ -3,6 +3,8 @@ export * from './common/accordion';
|
|
|
3
3
|
export * from './common/actionButtons';
|
|
4
4
|
export { default as ActionIcon } from './common/actionIcon';
|
|
5
5
|
export * from './common/actionIcon';
|
|
6
|
+
export { default as Alert } from './common/alert';
|
|
7
|
+
export * from './common/alert';
|
|
6
8
|
export { default as AnimatedLogo } from './common/animatedLogo';
|
|
7
9
|
export * from './common/animatedLogo';
|
|
8
10
|
export { default as AnimatedText } from './common/animatedText';
|
|
@@ -13,10 +15,16 @@ export { default as Badge } from './common/badge';
|
|
|
13
15
|
export * from './common/badge';
|
|
14
16
|
export { default as BodyEnd } from './common/bodyEnd';
|
|
15
17
|
export * from './common/bodyEnd';
|
|
18
|
+
export { default as Breadcrumb } from './common/breadcrumb';
|
|
19
|
+
export * from './common/breadcrumb';
|
|
16
20
|
export { default as Button } from './common/button';
|
|
17
21
|
export * from './common/button';
|
|
22
|
+
export { default as ButtonGroup } from './common/buttonGroup';
|
|
23
|
+
export * from './common/buttonGroup';
|
|
18
24
|
export { default as Card } from './common/card';
|
|
19
25
|
export * from './common/card';
|
|
26
|
+
export { default as Carousel } from './common/carousel';
|
|
27
|
+
export * from './common/carousel';
|
|
20
28
|
export { default as Checkbox } from './common/checkbox';
|
|
21
29
|
export * from './common/checkbox';
|
|
22
30
|
export { default as Chip } from './common/chip';
|
|
@@ -74,6 +82,8 @@ export { default as ProgressBar } from './common/progressBar';
|
|
|
74
82
|
export * from './common/progressBar';
|
|
75
83
|
export { default as RadioGroup } from './common/radioGroup';
|
|
76
84
|
export * from './common/radioGroup';
|
|
85
|
+
export { default as Rating } from './common/rating';
|
|
86
|
+
export * from './common/rating';
|
|
77
87
|
export { default as Ripple } from './common/ripple';
|
|
78
88
|
export * from './common/ripple';
|
|
79
89
|
export { default as RoomDrawer } from './common/roomDrawer';
|
|
@@ -90,6 +100,8 @@ export { default as Skeleton } from './common/skeleton';
|
|
|
90
100
|
export * from './common/skeleton';
|
|
91
101
|
export { default as Slider } from './common/slider';
|
|
92
102
|
export * from './common/slider';
|
|
103
|
+
export { default as SplitButton } from './common/splitButton';
|
|
104
|
+
export * from './common/splitButton';
|
|
93
105
|
export { default as Stepper } from './common/stepper';
|
|
94
106
|
export * from './common/stepper';
|
|
95
107
|
export { default as Sticky } from './common/sticky';
|
package/docs/Alert.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Alert
|
|
2
|
+
|
|
3
|
+
**When to use:** A persistent inline status message, used for form-level errors, page/section banners, empty-config warnings, and "here's what changed" notices. Unlike `Toast`, it isn't portaled or auto-dismissed, and it stays in the page's normal flow for as long as its consumer renders it. Use `Toast` instead for a transient, corner-anchored notification.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { Alert, AlertStyleType } from '@ahrowe/ui'`
|
|
6
|
+
|
|
7
|
+
**Style variants:** `AlertStyleType.Default` | `AlertStyleType.Info` | `AlertStyleType.Success` | `AlertStyleType.Warn` | `AlertStyleType.Error`
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Alert, AlertStyleType } from '@ahrowe/ui';
|
|
11
|
+
|
|
12
|
+
// Default, neutral message
|
|
13
|
+
<Alert>A default, neutral message.</Alert>
|
|
14
|
+
|
|
15
|
+
// Semantic variants
|
|
16
|
+
<Alert styleType={AlertStyleType.Info}>Here's something worth knowing.</Alert>
|
|
17
|
+
<Alert styleType={AlertStyleType.Success}>Your changes were saved.</Alert>
|
|
18
|
+
<Alert styleType={AlertStyleType.Warn}>Your storage is almost full.</Alert>
|
|
19
|
+
<Alert styleType={AlertStyleType.Error}>Something went wrong. Please try again.</Alert>
|
|
20
|
+
|
|
21
|
+
// With a title
|
|
22
|
+
<Alert styleType={AlertStyleType.Warn} title="Storage almost full">
|
|
23
|
+
You've used 92% of your available space. Free up room or upgrade your plan.
|
|
24
|
+
</Alert>
|
|
25
|
+
|
|
26
|
+
// Dismissible: the consumer owns visibility. onClose is called on click,
|
|
27
|
+
// so stop rendering the Alert (or flip your own state) to actually hide it
|
|
28
|
+
const [visible, setVisible] = useState(true);
|
|
29
|
+
{visible && (
|
|
30
|
+
<Alert
|
|
31
|
+
styleType={AlertStyleType.Info}
|
|
32
|
+
title="New feature available"
|
|
33
|
+
onClose={() => setVisible(false)}
|
|
34
|
+
>
|
|
35
|
+
Try out the new dashboard layout from your account settings.
|
|
36
|
+
</Alert>
|
|
37
|
+
)}
|
|
38
|
+
|
|
39
|
+
// Without the leading icon
|
|
40
|
+
<Alert styleType={AlertStyleType.Success} hideIcon>
|
|
41
|
+
A minimal message with no leading icon.
|
|
42
|
+
</Alert>
|
|
43
|
+
|
|
44
|
+
// Custom icon, overriding the styleType default
|
|
45
|
+
import { faRocket } from '@fortawesome/free-solid-svg-icons';
|
|
46
|
+
<Alert styleType={AlertStyleType.Info} icon={faRocket}>
|
|
47
|
+
Shipping a new release tonight.
|
|
48
|
+
</Alert>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Key props:**
|
|
52
|
+
|
|
53
|
+
| Prop | Type | Description |
|
|
54
|
+
|------|------|-------------|
|
|
55
|
+
| `title` | `ReactNode` | Optional bold heading above the description |
|
|
56
|
+
| `children` | `ReactNode` | The message body |
|
|
57
|
+
| `styleType` | `AlertStyleType` | Colour variant and default icon (default `Default`) |
|
|
58
|
+
| `icon` | `IconDefinition` | Overrides the default FontAwesome icon for `styleType` |
|
|
59
|
+
| `hideIcon` | `boolean` | Hide the leading icon entirely |
|
|
60
|
+
| `onClose` | `() => void` | Shows a close button and is called when it's clicked. `Alert` doesn't hide itself, so stop rendering it (or update your own state) in the handler |
|
|
61
|
+
|
|
62
|
+
**Global defaults:** adopts `ConfigProvider`, e.g. `defaultProps={{ Alert: { hideIcon: true } }}`. See [ConfigProvider.md](ConfigProvider.md).
|
|
63
|
+
|
|
64
|
+
**Slots:** `root` `icon` `content` `title` `description` `closeButton`
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
**When to use:** A trail showing the current page's position within a hierarchy, with links back to each ancestor, such as a file browser path, a category/subcategory drill-down, or a multi-level settings page. The last item is always rendered as the current page and isn't clickable.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { Breadcrumb } from '@ahrowe/ui'`
|
|
6
|
+
**Types:** `import type { BreadcrumbItem, BreadcrumbProps } from '@ahrowe/ui'`
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { Breadcrumb } from '@ahrowe/ui';
|
|
10
|
+
import type { BreadcrumbItem } from '@ahrowe/ui';
|
|
11
|
+
|
|
12
|
+
const items: BreadcrumbItem[] = [
|
|
13
|
+
{ label: 'Home', href: '/' },
|
|
14
|
+
{ label: 'Documents', href: '/documents' },
|
|
15
|
+
{ label: 'Report.pdf' }, // last item: rendered as the current page, not a link
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
<Breadcrumb items={items} />
|
|
19
|
+
|
|
20
|
+
// With leading icons
|
|
21
|
+
import { faHouse, faFolder } from '@fortawesome/free-solid-svg-icons';
|
|
22
|
+
|
|
23
|
+
<Breadcrumb
|
|
24
|
+
items={[
|
|
25
|
+
{ label: 'Home', href: '/', icon: faHouse },
|
|
26
|
+
{ label: 'Projects', href: '/projects', icon: faFolder },
|
|
27
|
+
{ label: 'Current project' },
|
|
28
|
+
]}
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
// Client-side routing (e.g. react-router): keep href for a real, right-clickable link,
|
|
32
|
+
// and use onClick to intercept the native navigation with the router's own navigate()
|
|
33
|
+
import { useNavigate } from 'react-router-dom';
|
|
34
|
+
|
|
35
|
+
function Example() {
|
|
36
|
+
const navigate = useNavigate();
|
|
37
|
+
return (
|
|
38
|
+
<Breadcrumb
|
|
39
|
+
items={[
|
|
40
|
+
{
|
|
41
|
+
label: 'Home',
|
|
42
|
+
href: '/',
|
|
43
|
+
onClick: (event) => {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
navigate('/');
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{ label: 'Current page' },
|
|
49
|
+
]}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// A disabled crumb: dimmed, not clickable, regardless of href/onClick
|
|
55
|
+
<Breadcrumb
|
|
56
|
+
items={[
|
|
57
|
+
{ label: 'Home', href: '/' },
|
|
58
|
+
{ label: 'Archived', href: '/archived', disabled: true },
|
|
59
|
+
{ label: 'Old report' },
|
|
60
|
+
]}
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
// Custom separator (default is a chevron icon)
|
|
64
|
+
<Breadcrumb items={items} separator="/" />
|
|
65
|
+
|
|
66
|
+
// Long trails: collapse the middle behind a clickable ellipsis once items.length
|
|
67
|
+
// exceeds maxItems. The ellipsis counts as one of the visible slots, so maxItems={3}
|
|
68
|
+
// on a 4-item trail shows: Home / ... / Settings. Clicking the ellipsis opens a menu
|
|
69
|
+
// (via FloatingMenu) listing the hidden items.
|
|
70
|
+
<Breadcrumb
|
|
71
|
+
items={[
|
|
72
|
+
{ label: 'Home', href: '/' },
|
|
73
|
+
{ label: 'Invoices', href: '/invoices' },
|
|
74
|
+
{ label: 'Editor', href: '/invoices/editor' },
|
|
75
|
+
{ label: 'Settings' },
|
|
76
|
+
]}
|
|
77
|
+
maxItems={3}
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Requires:** `<div id="bodyEnd"></div>` in your HTML when `maxItems` is used and the trail actually collapses (the hidden-items menu is a `FloatingMenu`, which renders via portal).
|
|
82
|
+
|
|
83
|
+
**BreadcrumbItem:**
|
|
84
|
+
|
|
85
|
+
| Field | Type | Description |
|
|
86
|
+
|-------|------|-------------|
|
|
87
|
+
| `id` | `string` | Optional stable key; falls back to the item's index |
|
|
88
|
+
| `label` | `ReactNode` | The crumb's text |
|
|
89
|
+
| `href` | `string` | Renders the crumb as a real `<a>`. Omit to render a plain clickable element (with `onClick`) or static text |
|
|
90
|
+
| `icon` | `IconDefinition` | Optional leading FontAwesome icon |
|
|
91
|
+
| `onClick` | `(event: MouseEvent) => void` | Click handler. Works alongside `href`: call `event.preventDefault()` to stop the native navigation and hand off to a client-side router's own navigate function (see the react-router example above). Also works on its own, with no `href` |
|
|
92
|
+
| `disabled` | `boolean` | Dims the crumb and makes it non-interactive, regardless of `href`/`onClick` |
|
|
93
|
+
|
|
94
|
+
**Key props:**
|
|
95
|
+
|
|
96
|
+
| Prop | Type | Description |
|
|
97
|
+
|------|------|-------------|
|
|
98
|
+
| `items` | `BreadcrumbItem[]` | The crumbs, in order. The last one is always rendered as the current page |
|
|
99
|
+
| `separator` | `ReactNode` | Overrides the default chevron separator between items |
|
|
100
|
+
| `maxItems` | `number` | Collapses the middle items behind a clickable ellipsis once `items.length` exceeds this. The ellipsis counts as one of the visible slots, alongside the always-shown first item (so `maxItems={3}` shows first item, ellipsis, last item) |
|
|
101
|
+
|
|
102
|
+
**Collapsing behaviour:** the hidden count grows and shrinks by exactly however many items are actually over the limit, rather than always jumping to the same minimal first/ellipsis/last shape. A trail with 11 items and `maxItems={10}` hides only 2 items, not the whole middle, so the trail doesn't visually lurch as one more level of navigation pushes it just over the limit.
|
|
103
|
+
|
|
104
|
+
**Global defaults:** adopts `ConfigProvider`, e.g. `defaultProps={{ Breadcrumb: { separator: '/' } }}`. See [ConfigProvider.md](ConfigProvider.md).
|
|
105
|
+
|
|
106
|
+
**Slots:** `root` `list` `item` `link` `icon` `separator` `current` `ellipsis` `hiddenList` `hiddenItem`
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# ButtonGroup
|
|
2
|
+
|
|
3
|
+
**When to use:** Joins a row (or column) of buttons into a single seamless control, merging their borders and rounding only the outer corners. Use for a segmented toggle ("Day / Week / Month"), an icon toolbar (bold/italic/underline), or any set of related actions that should read as one control rather than separate buttons. Purely a layout wrapper, no interaction logic of its own, so any button-like children work, not just `Button`.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { ButtonGroup, ButtonGroupOrientation } from '@ahrowe/ui'`
|
|
6
|
+
|
|
7
|
+
**Orientation:** `ButtonGroupOrientation.Horizontal` (default) | `ButtonGroupOrientation.Vertical`
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ButtonGroup, ButtonGroupOrientation, Button, ButtonStyleType } from '@ahrowe/ui';
|
|
11
|
+
|
|
12
|
+
// Segmented toggle
|
|
13
|
+
<ButtonGroup>
|
|
14
|
+
<Button styleType={ButtonStyleType.Default}>Day</Button>
|
|
15
|
+
<Button styleType={ButtonStyleType.Default}>Week</Button>
|
|
16
|
+
<Button styleType={ButtonStyleType.Default}>Month</Button>
|
|
17
|
+
</ButtonGroup>
|
|
18
|
+
|
|
19
|
+
// Icon toolbar
|
|
20
|
+
<ButtonGroup>
|
|
21
|
+
<Button styleType={ButtonStyleType.Default} icon={faBold} aria-label="Bold" />
|
|
22
|
+
<Button styleType={ButtonStyleType.Default} icon={faItalic} aria-label="Italic" />
|
|
23
|
+
<Button styleType={ButtonStyleType.Default} icon={faUnderline} aria-label="Underline" />
|
|
24
|
+
</ButtonGroup>
|
|
25
|
+
|
|
26
|
+
// Vertical
|
|
27
|
+
<ButtonGroup orientation={ButtonGroupOrientation.Vertical}>
|
|
28
|
+
<Button styleType={ButtonStyleType.Default}>Bold</Button>
|
|
29
|
+
<Button styleType={ButtonStyleType.Default}>Italic</Button>
|
|
30
|
+
<Button styleType={ButtonStyleType.Default}>Underline</Button>
|
|
31
|
+
</ButtonGroup>
|
|
32
|
+
|
|
33
|
+
// With a separator — filled styles (Primary/Delete) have no border of their own to merge,
|
|
34
|
+
// so a vertical Divider gives adjacent buttons a visible seam instead of blending together
|
|
35
|
+
import { Divider, DividerOrientation } from '@ahrowe/ui';
|
|
36
|
+
|
|
37
|
+
<ButtonGroup>
|
|
38
|
+
<Button styleType={ButtonStyleType.Primary}>Save</Button>
|
|
39
|
+
<Divider orientation={DividerOrientation.Vertical} />
|
|
40
|
+
<Button styleType={ButtonStyleType.Primary}>Save & new</Button>
|
|
41
|
+
</ButtonGroup>
|
|
42
|
+
|
|
43
|
+
// Nested groups — a toolbar made of two self-contained sub-groups, spaced apart rather
|
|
44
|
+
// than merged into one continuous strip
|
|
45
|
+
<ButtonGroup>
|
|
46
|
+
<ButtonGroup>
|
|
47
|
+
<Button styleType={ButtonStyleType.Default} icon={faBold} aria-label="Bold" />
|
|
48
|
+
<Button styleType={ButtonStyleType.Default} icon={faItalic} aria-label="Italic" />
|
|
49
|
+
<Button styleType={ButtonStyleType.Default} icon={faUnderline} aria-label="Underline" />
|
|
50
|
+
</ButtonGroup>
|
|
51
|
+
<ButtonGroup>
|
|
52
|
+
<Button styleType={ButtonStyleType.Default} icon={faAlignLeft} aria-label="Align left" />
|
|
53
|
+
<Button styleType={ButtonStyleType.Default} icon={faAlignCenter} aria-label="Align center" />
|
|
54
|
+
<Button styleType={ButtonStyleType.Default} icon={faAlignRight} aria-label="Align right" />
|
|
55
|
+
</ButtonGroup>
|
|
56
|
+
</ButtonGroup>
|
|
57
|
+
|
|
58
|
+
// With an Input — a search bar. Input's visible border lives on its own container/fieldset
|
|
59
|
+
// elements, not its root, so (like SplitButton) the side touching the button needs a manual
|
|
60
|
+
// corner override via Input's own slots rather than ButtonGroup's automatic ones
|
|
61
|
+
import { Input } from '@ahrowe/ui';
|
|
62
|
+
|
|
63
|
+
const groupedInputStyle = { borderTopRightRadius: 0, borderBottomRightRadius: 0 };
|
|
64
|
+
|
|
65
|
+
<ButtonGroup>
|
|
66
|
+
<Input
|
|
67
|
+
placeholder="Search…"
|
|
68
|
+
useMatLabelStyle={false}
|
|
69
|
+
value={search}
|
|
70
|
+
onChange={setSearch}
|
|
71
|
+
styles={{ container: groupedInputStyle, fieldset: groupedInputStyle }}
|
|
72
|
+
/>
|
|
73
|
+
<Button styleType={ButtonStyleType.Primary} icon={faMagnifyingGlass} aria-label="Search" />
|
|
74
|
+
</ButtonGroup>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Key props:**
|
|
78
|
+
|
|
79
|
+
| Prop | Type | Description |
|
|
80
|
+
|------|------|-------------|
|
|
81
|
+
| `children` | `ReactNode` | The buttons (or button-like elements) to join, in order |
|
|
82
|
+
| `orientation` | `ButtonGroupOrientation` | Layout direction (default `Horizontal`) |
|
|
83
|
+
|
|
84
|
+
**How it works:** the first and last children keep rounded outer corners; every child in between is flattened on both sides. Adjacent borders are collapsed with a `-1px` margin so two 1px borders don't stack into a visible double line, and whichever child is hovered/focused gets a `z-index` bump so its border/focus ring isn't clipped by its neighbors.
|
|
85
|
+
|
|
86
|
+
**Separators:** any child with `role="separator"` (what `Divider` sets) is excluded from that border-collapsing margin, on both sides — it stays fully visible between its neighbors instead of being partially hidden under one of them. Use a vertical `Divider` (see [Divider.md](Divider.md)) between two buttons when their style has no visible border of its own to merge (`Primary`, `Delete`), so there's still a clear seam between them.
|
|
87
|
+
|
|
88
|
+
**Note:** the corner-flattening rules key off DOM position (`:first-child`/`:last-child`), so they work for direct `Button` children out of the box. A child that renders as a wrapper around its own button (e.g. a component that portals its real content elsewhere) won't get the flattening automatically. `SplitButton` is exactly that case (its second child is a `FloatingMenu`-wrapped button), which is why it sets its own corner overrides directly rather than relying on `ButtonGroup`'s automatic ones. See [SplitButton.md](SplitButton.md).
|
|
89
|
+
|
|
90
|
+
**Slots:** none — `ButtonGroup` has no named inner elements, only `className`/`style` on the root.
|
package/docs/CLAUDE.md
CHANGED
|
@@ -95,13 +95,17 @@ Slot keys per component are documented in each component's doc file below.
|
|
|
95
95
|
@Accordion.md
|
|
96
96
|
@ActionButtons.md
|
|
97
97
|
@ActionIcon.md
|
|
98
|
+
@Alert.md
|
|
98
99
|
@AnimatedLogo.md
|
|
99
100
|
@AnimatedText.md
|
|
100
101
|
@Avatar.md
|
|
101
102
|
@Badge.md
|
|
102
103
|
@BodyEnd.md
|
|
104
|
+
@Breadcrumb.md
|
|
103
105
|
@Button.md
|
|
106
|
+
@ButtonGroup.md
|
|
104
107
|
@Card.md
|
|
108
|
+
@Carousel.md
|
|
105
109
|
@Checkbox.md
|
|
106
110
|
@Chip.md
|
|
107
111
|
@ColorPicker.md
|
|
@@ -133,6 +137,7 @@ Slot keys per component are documented in each component's doc file below.
|
|
|
133
137
|
@Popover.md
|
|
134
138
|
@ProgressBar.md
|
|
135
139
|
@RadioGroup.md
|
|
140
|
+
@Rating.md
|
|
136
141
|
@Ripple.md
|
|
137
142
|
@RoomDrawer.md
|
|
138
143
|
@RoomViewer.md
|
|
@@ -141,6 +146,7 @@ Slot keys per component are documented in each component's doc file below.
|
|
|
141
146
|
@SectionHeader.md
|
|
142
147
|
@Skeleton.md
|
|
143
148
|
@Slider.md
|
|
149
|
+
@SplitButton.md
|
|
144
150
|
@Stepper.md
|
|
145
151
|
@Sticky.md
|
|
146
152
|
@Switch.md
|
package/docs/Carousel.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Carousel
|
|
2
|
+
|
|
3
|
+
**When to use:** A slide track for stepping through a set of items one at a time, with arrows, dots, and drag/swipe support, plus optional autoplay. Slides are plain children, so any content works (images, cards, mixed content), not just a fixed image-gallery shape.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { Carousel } from '@ahrowe/ui'`
|
|
6
|
+
**Types:** `import type { CarouselProps } from '@ahrowe/ui'`
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { Carousel } from '@ahrowe/ui';
|
|
10
|
+
|
|
11
|
+
// Uncontrolled, looping by default, with arrows, dots, and swipe all on
|
|
12
|
+
<Carousel>
|
|
13
|
+
<div>Slide 1</div>
|
|
14
|
+
<div>Slide 2</div>
|
|
15
|
+
<div>Slide 3</div>
|
|
16
|
+
</Carousel>
|
|
17
|
+
|
|
18
|
+
// Controlled
|
|
19
|
+
const [index, setIndex] = useState(0);
|
|
20
|
+
<Carousel currentIndex={index} onChange={setIndex}>
|
|
21
|
+
<div>Slide 1</div>
|
|
22
|
+
<div>Slide 2</div>
|
|
23
|
+
<div>Slide 3</div>
|
|
24
|
+
</Carousel>
|
|
25
|
+
|
|
26
|
+
// Autoplay, paused on hover/focus by default, with dots hidden
|
|
27
|
+
<Carousel autoPlay autoPlayInterval={4000} showDots={false}>
|
|
28
|
+
<div>Slide 1</div>
|
|
29
|
+
<div>Slide 2</div>
|
|
30
|
+
</Carousel>
|
|
31
|
+
|
|
32
|
+
// Bounded instead of looping: arrows disable at the first/last slide
|
|
33
|
+
<Carousel loop={false}>
|
|
34
|
+
<div>Slide 1</div>
|
|
35
|
+
<div>Slide 2</div>
|
|
36
|
+
</Carousel>
|
|
37
|
+
|
|
38
|
+
// No swipe/drag, arrows only
|
|
39
|
+
<Carousel swipeable={false} showDots={false}>
|
|
40
|
+
<div>Slide 1</div>
|
|
41
|
+
<div>Slide 2</div>
|
|
42
|
+
</Carousel>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Pass slides as direct children (an array or a set of sibling elements), not through a component that returns a fragment internally. `Carousel` reads its immediate children via `React.Children`, so a wrapper component's own children aren't visible to it. If slides come from a `.map()`, spread the array straight into `Carousel`, the same way `children` normally works in React.
|
|
46
|
+
|
|
47
|
+
**Interaction:** drag or swipe the track to move between slides (committing past roughly 20% of the container's width, or releasing further than that snaps to the next/previous slide; a shorter drag springs back). Left/right arrow keys move between slides when focus is anywhere inside the carousel.
|
|
48
|
+
|
|
49
|
+
**Key props:**
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Description |
|
|
52
|
+
|------|------|-------------|
|
|
53
|
+
| `children` | `ReactNode` | The slides, one per direct child |
|
|
54
|
+
| `currentIndex` | `number` | Controlled active slide index |
|
|
55
|
+
| `defaultIndex` | `number` | Initial active slide index when uncontrolled (default `0`) |
|
|
56
|
+
| `onChange` | `(index: number) => void` | Called whenever the active slide changes, from arrows, dots, keyboard, drag, or autoplay |
|
|
57
|
+
| `loop` | `boolean` | Wrap from the last slide to the first and back (default `true`) |
|
|
58
|
+
| `autoPlay` | `boolean` | Automatically advance on a timer (default `false`) |
|
|
59
|
+
| `autoPlayInterval` | `number` | Autoplay delay in ms (default `4000`) |
|
|
60
|
+
| `pauseOnHover` | `boolean` | Pause autoplay while hovered or focused (default `true`) |
|
|
61
|
+
| `showArrows` | `boolean` | Show the prev/next buttons (default `true`); hidden automatically with one slide or none |
|
|
62
|
+
| `showDots` | `boolean` | Show the position dots (default `true`); hidden automatically with one slide or none |
|
|
63
|
+
| `swipeable` | `boolean` | Allow dragging/swiping the track (default `true`) |
|
|
64
|
+
|
|
65
|
+
**Global defaults:** adopts `ConfigProvider`, e.g. `defaultProps={{ Carousel: { autoPlay: true } }}`. See [ConfigProvider.md](ConfigProvider.md).
|
|
66
|
+
|
|
67
|
+
**Slots:** `root` `track` `slide` `prevButton` `nextButton` `dots` `dot`
|