@central-ui/react 0.1.2 → 0.3.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/LICENSE +49 -0
- package/dist/components/accordion/index.d.ts +4 -3
- package/dist/components/accordion/index.js +7 -4
- package/dist/components/autocomplete/index.d.ts +23 -30
- package/dist/components/autocomplete/index.js +81 -56
- package/dist/components/avatar/index.d.ts +1 -2
- package/dist/components/avatar/index.js +0 -1
- package/dist/components/badge/index.d.ts +0 -1
- package/dist/components/badge/index.js +2 -2
- package/dist/components/banner/index.d.ts +1 -1
- package/dist/components/banner/index.js +23 -25
- package/dist/components/barchart/index.d.ts +106 -0
- package/dist/components/barchart/index.js +122 -0
- package/dist/components/breadcrumb/index.d.ts +0 -1
- package/dist/components/breadcrumb/index.js +6 -7
- package/dist/components/button/index.d.ts +2 -3
- package/dist/components/button/index.js +11 -12
- package/dist/components/card/index.d.ts +0 -1
- package/dist/components/card/index.js +0 -1
- package/dist/components/carousel/index.d.ts +169 -0
- package/dist/components/carousel/index.js +299 -0
- package/dist/components/checkbox/index.d.ts +13 -11
- package/dist/components/checkbox/index.js +51 -31
- package/dist/components/chip/index.d.ts +1 -1
- package/dist/components/chip/index.js +2 -3
- package/dist/components/combobox/index.d.ts +33 -49
- package/dist/components/combobox/index.js +102 -70
- package/dist/components/datepicker/index.d.ts +18 -31
- package/dist/components/datepicker/index.js +81 -99
- package/dist/components/dialog/index.d.ts +14 -27
- package/dist/components/dialog/index.js +17 -18
- package/dist/components/divider/index.d.ts +0 -1
- package/dist/components/divider/index.js +0 -1
- package/dist/components/donutchart/index.d.ts +100 -0
- package/dist/components/donutchart/index.js +178 -0
- package/dist/components/drawer/index.d.ts +12 -21
- package/dist/components/drawer/index.js +34 -36
- package/dist/components/empty/index.d.ts +3 -3
- package/dist/components/empty/index.js +4 -5
- package/dist/components/exception/index.d.ts +86 -0
- package/dist/components/exception/index.js +116 -0
- package/dist/components/fileupload/index.d.ts +4 -9
- package/dist/components/fileupload/index.js +26 -38
- package/dist/components/form/index.d.ts +0 -1
- package/dist/components/form/index.js +0 -1
- package/dist/components/horizontalbarchart/index.d.ts +120 -0
- package/dist/components/horizontalbarchart/index.js +193 -0
- package/dist/components/input/index.d.ts +22 -22
- package/dist/components/input/index.js +76 -105
- package/dist/components/linechart/index.d.ts +114 -0
- package/dist/components/linechart/index.js +139 -0
- package/dist/components/menu/index.d.ts +9 -11
- package/dist/components/menu/index.js +42 -39
- package/dist/components/metric/index.d.ts +0 -1
- package/dist/components/metric/index.js +0 -1
- package/dist/components/numberinput/index.d.ts +14 -21
- package/dist/components/numberinput/index.js +40 -53
- package/dist/components/otpinput/index.d.ts +14 -9
- package/dist/components/otpinput/index.js +25 -18
- package/dist/components/page/index.d.ts +0 -1
- package/dist/components/page/index.js +1 -3
- package/dist/components/passwordinput/index.d.ts +14 -11
- package/dist/components/passwordinput/index.js +36 -45
- package/dist/components/popover/index.d.ts +21 -19
- package/dist/components/popover/index.js +34 -15
- package/dist/components/radio/index.d.ts +13 -9
- package/dist/components/radio/index.js +69 -60
- package/dist/components/ratinginput/index.d.ts +13 -8
- package/dist/components/ratinginput/index.js +37 -17
- package/dist/components/select/index.d.ts +30 -30
- package/dist/components/select/index.js +80 -41
- package/dist/components/skeleton/index.d.ts +0 -1
- package/dist/components/skeleton/index.js +0 -1
- package/dist/components/slider/index.d.ts +14 -9
- package/dist/components/slider/index.js +64 -63
- package/dist/components/spinner/index.d.ts +1 -2
- package/dist/components/spinner/index.js +2 -3
- package/dist/components/splitter/index.d.ts +1 -2
- package/dist/components/splitter/index.js +5 -6
- package/dist/components/stepper/index.d.ts +8 -20
- package/dist/components/stepper/index.js +15 -16
- package/dist/components/switch/index.d.ts +12 -10
- package/dist/components/switch/index.js +46 -30
- package/dist/components/table/index.d.ts +3 -3
- package/dist/components/table/index.js +14 -13
- package/dist/components/tabs/index.d.ts +0 -1
- package/dist/components/tabs/index.js +1 -2
- package/dist/components/textarea/index.d.ts +14 -11
- package/dist/components/textarea/index.js +37 -46
- package/dist/components/textlink/index.d.ts +3 -1
- package/dist/components/textlink/index.js +4 -1
- package/dist/components/toast/index.d.ts +8 -14
- package/dist/components/toast/index.js +48 -48
- package/dist/components/toggle/index.d.ts +0 -1
- package/dist/components/toggle/index.js +17 -24
- package/dist/components/tooltip/index.d.ts +11 -13
- package/dist/components/tooltip/index.js +12 -9
- package/dist/components/tour/index.d.ts +154 -0
- package/dist/components/tour/index.js +280 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -1
- package/dist/types/Icon.d.ts +0 -1
- package/dist/types/Icon.js +0 -1
- package/dist/types/Style.d.ts +0 -1
- package/dist/types/Style.js +0 -1
- package/dist/types/Validation.d.ts +12 -0
- package/dist/types/Validation.js +1 -0
- package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
- package/dist/utils/ArkStateToDataAttributes.js +0 -1
- package/dist/utils/Validation.d.ts +14 -0
- package/dist/utils/Validation.js +23 -0
- package/dist/utils/asChild.d.ts +41 -0
- package/dist/utils/asChild.js +15 -0
- package/dist/utils/icons.d.ts +24 -0
- package/dist/utils/icons.js +160 -0
- package/dist/utils/useForwardClickToInput.d.ts +0 -1
- package/dist/utils/useForwardClickToInput.js +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
- package/package.json +14 -11
- package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
- package/src/presets/shopify-polaris/shopify-polaris-carousel.css +62 -0
- package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-combobox.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +4 -4
- package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
- package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-exception.css +40 -0
- package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
- package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
- package/src/presets/shopify-polaris/shopify-polaris-input.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
- package/src/presets/shopify-polaris/shopify-polaris-menu.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
- package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-select.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-textarea.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris.css +6 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-carousel.css +55 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-exception.css +40 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +6 -0
- package/dist/components/accordion/index.d.ts.map +0 -1
- package/dist/components/accordion/index.js.map +0 -1
- package/dist/components/autocomplete/index.d.ts.map +0 -1
- package/dist/components/autocomplete/index.js.map +0 -1
- package/dist/components/avatar/index.d.ts.map +0 -1
- package/dist/components/avatar/index.js.map +0 -1
- package/dist/components/badge/index.d.ts.map +0 -1
- package/dist/components/badge/index.js.map +0 -1
- package/dist/components/banner/index.d.ts.map +0 -1
- package/dist/components/banner/index.js.map +0 -1
- package/dist/components/breadcrumb/index.d.ts.map +0 -1
- package/dist/components/breadcrumb/index.js.map +0 -1
- package/dist/components/button/index.d.ts.map +0 -1
- package/dist/components/button/index.js.map +0 -1
- package/dist/components/card/index.d.ts.map +0 -1
- package/dist/components/card/index.js.map +0 -1
- package/dist/components/checkbox/index.d.ts.map +0 -1
- package/dist/components/checkbox/index.js.map +0 -1
- package/dist/components/chip/index.d.ts.map +0 -1
- package/dist/components/chip/index.js.map +0 -1
- package/dist/components/combobox/index.d.ts.map +0 -1
- package/dist/components/combobox/index.js.map +0 -1
- package/dist/components/datepicker/index.d.ts.map +0 -1
- package/dist/components/datepicker/index.js.map +0 -1
- package/dist/components/dialog/index.d.ts.map +0 -1
- package/dist/components/dialog/index.js.map +0 -1
- package/dist/components/divider/index.d.ts.map +0 -1
- package/dist/components/divider/index.js.map +0 -1
- package/dist/components/drawer/index.d.ts.map +0 -1
- package/dist/components/drawer/index.js.map +0 -1
- package/dist/components/empty/index.d.ts.map +0 -1
- package/dist/components/empty/index.js.map +0 -1
- package/dist/components/fileupload/index.d.ts.map +0 -1
- package/dist/components/fileupload/index.js.map +0 -1
- package/dist/components/form/index.d.ts.map +0 -1
- package/dist/components/form/index.js.map +0 -1
- package/dist/components/input/index.d.ts.map +0 -1
- package/dist/components/input/index.js.map +0 -1
- package/dist/components/menu/index.d.ts.map +0 -1
- package/dist/components/menu/index.js.map +0 -1
- package/dist/components/metric/index.d.ts.map +0 -1
- package/dist/components/metric/index.js.map +0 -1
- package/dist/components/numberinput/index.d.ts.map +0 -1
- package/dist/components/numberinput/index.js.map +0 -1
- package/dist/components/otpinput/index.d.ts.map +0 -1
- package/dist/components/otpinput/index.js.map +0 -1
- package/dist/components/page/index.d.ts.map +0 -1
- package/dist/components/page/index.js.map +0 -1
- package/dist/components/passwordinput/index.d.ts.map +0 -1
- package/dist/components/passwordinput/index.js.map +0 -1
- package/dist/components/popover/index.d.ts.map +0 -1
- package/dist/components/popover/index.js.map +0 -1
- package/dist/components/radio/index.d.ts.map +0 -1
- package/dist/components/radio/index.js.map +0 -1
- package/dist/components/ratinginput/index.d.ts.map +0 -1
- package/dist/components/ratinginput/index.js.map +0 -1
- package/dist/components/select/index.d.ts.map +0 -1
- package/dist/components/select/index.js.map +0 -1
- package/dist/components/skeleton/index.d.ts.map +0 -1
- package/dist/components/skeleton/index.js.map +0 -1
- package/dist/components/slider/index.d.ts.map +0 -1
- package/dist/components/slider/index.js.map +0 -1
- package/dist/components/spinner/index.d.ts.map +0 -1
- package/dist/components/spinner/index.js.map +0 -1
- package/dist/components/splitter/index.d.ts.map +0 -1
- package/dist/components/splitter/index.js.map +0 -1
- package/dist/components/stepper/index.d.ts.map +0 -1
- package/dist/components/stepper/index.js.map +0 -1
- package/dist/components/switch/index.d.ts.map +0 -1
- package/dist/components/switch/index.js.map +0 -1
- package/dist/components/table/index.d.ts.map +0 -1
- package/dist/components/table/index.js.map +0 -1
- package/dist/components/tabs/index.d.ts.map +0 -1
- package/dist/components/tabs/index.js.map +0 -1
- package/dist/components/textarea/index.d.ts.map +0 -1
- package/dist/components/textarea/index.js.map +0 -1
- package/dist/components/textlink/index.d.ts.map +0 -1
- package/dist/components/textlink/index.js.map +0 -1
- package/dist/components/toast/index.d.ts.map +0 -1
- package/dist/components/toast/index.js.map +0 -1
- package/dist/components/toggle/index.d.ts.map +0 -1
- package/dist/components/toggle/index.js.map +0 -1
- package/dist/components/tooltip/index.d.ts.map +0 -1
- package/dist/components/tooltip/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/Icon.d.ts.map +0 -1
- package/dist/types/Icon.js.map +0 -1
- package/dist/types/Style.d.ts.map +0 -1
- package/dist/types/Style.js.map +0 -1
- package/dist/types/Tone.d.ts +0 -4
- package/dist/types/Tone.d.ts.map +0 -1
- package/dist/types/Tone.js +0 -2
- package/dist/types/Tone.js.map +0 -1
- package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
- package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
- package/dist/utils/Tone.d.ts +0 -3
- package/dist/utils/Tone.d.ts.map +0 -1
- package/dist/utils/Tone.js +0 -7
- package/dist/utils/Tone.js.map +0 -1
- package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
- package/dist/utils/useForwardClickToInput.js.map +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
import { PieChart as RechartsPieChart } from 'recharts';
|
|
3
|
+
import type { TooltipProps as RechartsTooltipProps } from 'recharts';
|
|
4
|
+
import type { StyleProps } from '../../types/Style.ts';
|
|
5
|
+
/** Every record needs a unique `label` (the slice name) and a numeric `value` (its share). Extra fields are kept for the tooltip and legend. */
|
|
6
|
+
type Datum = {
|
|
7
|
+
label: string;
|
|
8
|
+
value: number;
|
|
9
|
+
};
|
|
10
|
+
export type RootProps<Data extends Datum = Datum> = Pick<ComponentProps<typeof RechartsPieChart>, 'accessibilityLayer' | 'desc'> & {
|
|
11
|
+
/** Slices are drawn clockwise from 12 o'clock in this order, so sort the records first (e.g. largest first). */
|
|
12
|
+
data: readonly Data[];
|
|
13
|
+
'aria-label': string;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a record's `label` into display text.
|
|
17
|
+
* Used by the body, the legend, and the tooltip, so all read the same.
|
|
18
|
+
* @default (label) => label
|
|
19
|
+
*/
|
|
20
|
+
labelToString?: (label: string) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Converts a record's `value` (and the total) into display text.
|
|
23
|
+
* Used by the body, the legend, and the tooltip, so all read the same.
|
|
24
|
+
* Use it for currency, percentages, or units (e.g. `74678.2` → `'$74.6K'`).
|
|
25
|
+
* @default (value) => value.toLocaleString()
|
|
26
|
+
*/
|
|
27
|
+
valueToString?: (value: number) => string;
|
|
28
|
+
};
|
|
29
|
+
/** Provides the chart data, formatting, and accessibility settings to its parts. Renders no element. */
|
|
30
|
+
export declare function Root<Data extends Datum>({ children, labelToString, valueToString, ...chart }: RootProps<Data>): import("react").JSX.Element;
|
|
31
|
+
export type ContainerProps = Pick<ComponentProps<typeof RechartsPieChart>, 'children' | 'height' | 'className' | 'style' | 'id' | 'ref' | 'tabIndex'>;
|
|
32
|
+
/** Recharts supplies its own responsive container, so no extra wrapper is needed. */
|
|
33
|
+
export declare function Container({ height, className, style, children, ...props }: ContainerProps): import("react").JSX.Element;
|
|
34
|
+
export type TrackProps = {
|
|
35
|
+
/** Classes for the full ring behind the slices, e.g. `fill-neutral-100`. */
|
|
36
|
+
className?: string;
|
|
37
|
+
};
|
|
38
|
+
/** Optional full ring behind the slices. It keeps the donut visible when every value is 0. */
|
|
39
|
+
export declare function Track({ className }: TrackProps): import("react").JSX.Element;
|
|
40
|
+
export type SlicesProps = {
|
|
41
|
+
/**
|
|
42
|
+
* Classes for every slice. Colors come only from here or from a preset; there is no built-in color.
|
|
43
|
+
* Target one slice with `data-[index=0]:`, the hovered one with `data-active:`, and the others with `data-inactive:`
|
|
44
|
+
* (e.g. `data-[index=0]:fill-sky-500 data-[index=1]:fill-violet-200 data-inactive:opacity-40`).
|
|
45
|
+
*/
|
|
46
|
+
className?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Degrees of empty space between slices.
|
|
49
|
+
* @default 2
|
|
50
|
+
*/
|
|
51
|
+
gap?: number;
|
|
52
|
+
};
|
|
53
|
+
export declare function Slices({ className, gap }: SlicesProps): import("react").JSX.Element;
|
|
54
|
+
/**
|
|
55
|
+
* HTML laid over the donut's hole, so its content is ordinary JSX: Tailwind, fonts, and truncation all work.
|
|
56
|
+
* Rendered through an SVG foreignObject, which keeps it inside the chart and its hover state.
|
|
57
|
+
*/
|
|
58
|
+
export declare function Body({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element | null;
|
|
59
|
+
/**
|
|
60
|
+
* Shows the hovered slice's label, formatted by `labelToString` on Root.
|
|
61
|
+
* While nothing is hovered it shows its children: name the measure the total stands for, e.g. `Total sales`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function BodyTitle({ disableStyle, className, children, ...props }: ComponentProps<'p'> & StyleProps): import("react").JSX.Element;
|
|
64
|
+
/** Shows the hovered slice's value, or the sum of every value while nothing is hovered. */
|
|
65
|
+
export declare function BodyValue({ disableStyle, className, ...props }: Omit<ComponentProps<'p'>, 'children'> & StyleProps): import("react").JSX.Element;
|
|
66
|
+
export type LegendListProps<Data extends Datum = Datum> = Omit<ComponentProps<'ul'>, 'children'> & StyleProps & {
|
|
67
|
+
/** Receives each record with its position in data, and returns its row, like Combobox.List. */
|
|
68
|
+
children: (datum: Data, index: number) => ReactNode;
|
|
69
|
+
/**
|
|
70
|
+
* Where the legend sits.
|
|
71
|
+
* - `'right'`: beside the donut, vertically centered. The usual choice in cards with room to spare.
|
|
72
|
+
* - `'bottom'`: under the donut. Use it in narrow cards.
|
|
73
|
+
* @default 'right'
|
|
74
|
+
*/
|
|
75
|
+
position?: 'right' | 'bottom';
|
|
76
|
+
};
|
|
77
|
+
/** The legend's list of rows. Recharts' native Legend places and sizes it; its content slot renders this list. */
|
|
78
|
+
export declare function LegendList<Data extends Datum = Datum>({ children, position, className, disableStyle, ...props }: LegendListProps<Data>): import("react").JSX.Element;
|
|
79
|
+
/** One legend row. Dims along with its slice while another slice is hovered. */
|
|
80
|
+
export declare function LegendItem({ disableStyle, className, ...props }: ComponentProps<'li'> & StyleProps): import("react").JSX.Element;
|
|
81
|
+
export declare function LegendColorIndicator({ disableStyle, className, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
|
|
82
|
+
/** Shows the row's label, formatted by `labelToString` on Root. */
|
|
83
|
+
export declare function LegendLabel({ disableStyle, className, ...props }: Omit<ComponentProps<'span'>, 'children'> & StyleProps): import("react").JSX.Element;
|
|
84
|
+
/** Shows the row's value, formatted by `valueToString` on Root. */
|
|
85
|
+
export declare function LegendValue({ disableStyle, className, ...props }: Omit<ComponentProps<'span'>, 'children'> & StyleProps): import("react").JSX.Element;
|
|
86
|
+
export type TooltipProps<Data extends Datum = Datum> = Pick<RechartsTooltipProps<number, string>, 'offset' | 'allowEscapeViewBox' | 'portal'> & {
|
|
87
|
+
/** Receives the hovered record and returns the popup. */
|
|
88
|
+
children: (datum: Data) => ReactNode;
|
|
89
|
+
};
|
|
90
|
+
/** Renders no element: hands its popup to the Container. For extra fields, specify the record type: Tooltip<(typeof data)[number]>. */
|
|
91
|
+
export declare function Tooltip<Data extends Datum = Datum>({ children, offset, allowEscapeViewBox, portal, }: TooltipProps<Data>): null;
|
|
92
|
+
export declare function TooltipPopup({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
|
|
93
|
+
export declare function TooltipTitle({ disableStyle, className, ...props }: ComponentProps<'p'> & StyleProps): import("react").JSX.Element;
|
|
94
|
+
/** Shows the hovered slice's label, formatted by `labelToString` on Root. */
|
|
95
|
+
export declare function TooltipLabel({ disableStyle, className, ...props }: Omit<ComponentProps<'p'>, 'children'> & StyleProps): import("react").JSX.Element;
|
|
96
|
+
/** Shows the hovered slice's value, formatted by `valueToString` on Root. */
|
|
97
|
+
export declare function TooltipValue({ disableStyle, className, ...props }: Omit<ComponentProps<'p'>, 'children'> & StyleProps): import("react").JSX.Element;
|
|
98
|
+
/** Carries the hovered slice's `data-index`, so it can match that slice's color. */
|
|
99
|
+
export declare function TooltipColorIndicator({ disableStyle, className, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
|
|
100
|
+
export {};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useLayoutEffect, useState } from 'react';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { Legend as RechartsLegend, Pie as RechartsPie, PieChart as RechartsPieChart, Sector as RechartsSector, Tooltip as RechartsTooltip, useActiveTooltipDataPoints, usePlotArea, } from 'recharts';
|
|
5
|
+
/** Inner radius as a share of the outer one: the ring is 16% of the radius thick. */
|
|
6
|
+
const INNER_RADIUS = 0.84;
|
|
7
|
+
const ChartContext = /* @__PURE__ */ createContext(null);
|
|
8
|
+
/** Provides the chart data, formatting, and accessibility settings to its parts. Renders no element. */
|
|
9
|
+
export function Root({ children, labelToString = (label) => label, valueToString = (value) => value.toLocaleString(), ...chart }) {
|
|
10
|
+
return (_jsx(ChartContext.Provider, { value: { ...chart, labelToString, valueToString }, children: children }));
|
|
11
|
+
}
|
|
12
|
+
function useChart(part) {
|
|
13
|
+
const chart = useContext(ChartContext);
|
|
14
|
+
if (!chart)
|
|
15
|
+
throw new Error(`DonutChart.${part} must be inside DonutChart.Root`);
|
|
16
|
+
return chart;
|
|
17
|
+
}
|
|
18
|
+
/** The hovered slice's record and position in data, read from Recharts' own hover state. */
|
|
19
|
+
function useActiveSlice(part) {
|
|
20
|
+
const chart = useChart(part);
|
|
21
|
+
const [point] = useActiveTooltipDataPoints() ?? [];
|
|
22
|
+
const index = point
|
|
23
|
+
? chart.data.findIndex((datum) => datum.label === point.label)
|
|
24
|
+
: -1;
|
|
25
|
+
return index < 0 ? null : { datum: chart.data[index], index };
|
|
26
|
+
}
|
|
27
|
+
/** Lets a Tooltip part hand its content to the Container, which owns the single Recharts tooltip. */
|
|
28
|
+
const TooltipSlotContext = /* @__PURE__ */ createContext(null);
|
|
29
|
+
/** Recharts supplies its own responsive container, so no extra wrapper is needed. */
|
|
30
|
+
export function Container({ height = 240, className, style, children, ...props }) {
|
|
31
|
+
const chart = useChart('Container');
|
|
32
|
+
const [tooltip, setTooltip] = useState(null);
|
|
33
|
+
return (_jsxs(RechartsPieChart, { margin: { top: 0, right: 0, bottom: 0, left: 0 }, ...props, data: chart.data, accessibilityLayer: chart.accessibilityLayer, desc: chart.desc, title: chart['aria-label'], className: twMerge('min-w-0 w-full', className), style: { ...style, background: 'transparent' }, height: height, width: "100%", responsive: true, children: [_jsx(TooltipSlotContext.Provider, { value: setTooltip, children: children }), _jsx(RechartsTooltip, { offset: 12, ...tooltip?.props, animationDuration: 200, animationEasing: "ease-out", content: (state) => {
|
|
34
|
+
if (!tooltip || !state.active || !state.payload.length)
|
|
35
|
+
return null;
|
|
36
|
+
// Recharts types the payload as unknown; payload[0] is always the hovered record.
|
|
37
|
+
const datum = state.payload[0].payload;
|
|
38
|
+
return (_jsx(TooltipContext.Provider, { value: datum, children: tooltip.render(datum) }));
|
|
39
|
+
} })] }));
|
|
40
|
+
}
|
|
41
|
+
/** Shared ring geometry, so the track and the slices always line up. */
|
|
42
|
+
const ring = {
|
|
43
|
+
cx: '50%',
|
|
44
|
+
cy: '50%',
|
|
45
|
+
innerRadius: `${INNER_RADIUS * 100}%`,
|
|
46
|
+
outerRadius: '100%',
|
|
47
|
+
startAngle: 90,
|
|
48
|
+
endAngle: -270,
|
|
49
|
+
stroke: 'none',
|
|
50
|
+
isAnimationActive: false,
|
|
51
|
+
};
|
|
52
|
+
/** Optional full ring behind the slices. It keeps the donut visible when every value is 0. */
|
|
53
|
+
export function Track({ className }) {
|
|
54
|
+
return (_jsx(RechartsPie, { ...ring, data: [{ value: 1 }], dataKey: "value", tooltipType: "none", legendType: "none",
|
|
55
|
+
// The track is a backdrop: it never takes the pointer from the slices.
|
|
56
|
+
pointerEvents: "none", shape: (sector) => (_jsx(RechartsSector, { ...sector, className: className, "data-component": "donutchart-track" })) }));
|
|
57
|
+
}
|
|
58
|
+
export function Slices({ className, gap = 2 }) {
|
|
59
|
+
const chart = useChart('Slices');
|
|
60
|
+
return (_jsx(RechartsPie, { ...ring, data: chart.data, dataKey: "value", nameKey: "label", paddingAngle: gap,
|
|
61
|
+
// Recharts' native shape slot renders each slice ourselves, so className and data attributes land on the drawn element.
|
|
62
|
+
shape: (sector) => (_jsx(Slice, { ...sector, className: className })) }));
|
|
63
|
+
}
|
|
64
|
+
function Slice({ className, ...sector }) {
|
|
65
|
+
const active = useActiveSlice('Slices');
|
|
66
|
+
return (_jsx(RechartsSector, { ...sector, className: className, "data-component": "donutchart-slice", "data-index": sector.index, "data-active": active?.index === sector.index ? '' : undefined, "data-inactive": active && active.index !== sector.index ? '' : undefined }));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* HTML laid over the donut's hole, so its content is ordinary JSX: Tailwind, fonts, and truncation all work.
|
|
70
|
+
* Rendered through an SVG foreignObject, which keeps it inside the chart and its hover state.
|
|
71
|
+
*/
|
|
72
|
+
export function Body({ disableStyle, className, ...props }) {
|
|
73
|
+
const plotArea = usePlotArea();
|
|
74
|
+
const active = useActiveSlice('Body');
|
|
75
|
+
if (!plotArea)
|
|
76
|
+
return null;
|
|
77
|
+
const radius = (Math.min(plotArea.width, plotArea.height) / 2) * INNER_RADIUS;
|
|
78
|
+
// The largest square that fits in the hole.
|
|
79
|
+
const side = radius * Math.SQRT2;
|
|
80
|
+
return (_jsx("foreignObject", { x: plotArea.x + plotArea.width / 2 - side / 2, y: plotArea.y + plotArea.height / 2 - side / 2, width: side, height: side,
|
|
81
|
+
// The hole stays transparent to the pointer, so hovering it never blocks a slice.
|
|
82
|
+
pointerEvents: "none", children: _jsx("div", { ...props, "data-component": "donutchart-body", "data-active": active ? '' : undefined, "data-style-disabled": disableStyle ? '' : undefined, className: className }) }));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Shows the hovered slice's label, formatted by `labelToString` on Root.
|
|
86
|
+
* While nothing is hovered it shows its children: name the measure the total stands for, e.g. `Total sales`.
|
|
87
|
+
*/
|
|
88
|
+
export function BodyTitle({ disableStyle, className, children, ...props }) {
|
|
89
|
+
const chart = useChart('BodyTitle');
|
|
90
|
+
const active = useActiveSlice('BodyTitle');
|
|
91
|
+
return (_jsx("p", { ...props, "data-component": "donutchart-bodytitle", "data-index": active?.index, "data-active": active ? '' : undefined, "data-style-disabled": disableStyle ? '' : undefined, className: className, children: active ? chart.labelToString(active.datum.label) : children }));
|
|
92
|
+
}
|
|
93
|
+
/** Shows the hovered slice's value, or the sum of every value while nothing is hovered. */
|
|
94
|
+
export function BodyValue({ disableStyle, className, ...props }) {
|
|
95
|
+
const chart = useChart('BodyValue');
|
|
96
|
+
const active = useActiveSlice('BodyValue');
|
|
97
|
+
const total = chart.data.reduce((sum, datum) => sum + datum.value, 0);
|
|
98
|
+
return (_jsx("p", { ...props, "data-component": "donutchart-bodyvalue", "data-index": active?.index, "data-active": active ? '' : undefined, "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.valueToString(active ? active.datum.value : total) }));
|
|
99
|
+
}
|
|
100
|
+
/** The legend's list of rows. Recharts' native Legend places and sizes it; its content slot renders this list. */
|
|
101
|
+
export function LegendList({ children, position = 'right', className, disableStyle, ...props }) {
|
|
102
|
+
const chart = useChart('LegendList');
|
|
103
|
+
return (_jsx(RechartsLegend, { layout: "vertical", align: position === 'right' ? 'right' : 'center', verticalAlign: position === 'right' ? 'middle' : 'bottom', content: () => (_jsx("ul", { ...props, "data-component": "donutchart-legendlist", "data-position": position, "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.data.map((datum, index) => (_jsx(LegendContext.Provider, { value: { datum, index }, children: children(datum, index) }, datum.label))) })) }));
|
|
104
|
+
}
|
|
105
|
+
const LegendContext = /* @__PURE__ */ createContext(null);
|
|
106
|
+
function useLegendRow(part) {
|
|
107
|
+
const row = useContext(LegendContext);
|
|
108
|
+
if (!row)
|
|
109
|
+
throw new Error(`DonutChart.${part} must be inside DonutChart.LegendList`);
|
|
110
|
+
return row;
|
|
111
|
+
}
|
|
112
|
+
/** One legend row. Dims along with its slice while another slice is hovered. */
|
|
113
|
+
export function LegendItem({ disableStyle, className, ...props }) {
|
|
114
|
+
const row = useLegendRow('LegendItem');
|
|
115
|
+
const active = useActiveSlice('LegendItem');
|
|
116
|
+
return (_jsx("li", { ...props, "data-component": "donutchart-legenditem", "data-index": row.index, "data-active": active?.index === row.index ? '' : undefined, "data-inactive": active && active.index !== row.index ? '' : undefined, "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
117
|
+
}
|
|
118
|
+
export function LegendColorIndicator({ disableStyle, className, ...props }) {
|
|
119
|
+
const row = useLegendRow('LegendColorIndicator');
|
|
120
|
+
return (_jsx("span", { "aria-hidden": "true", ...props, "data-component": "donutchart-legendcolorindicator", "data-index": row.index, "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
121
|
+
}
|
|
122
|
+
/** Shows the row's label, formatted by `labelToString` on Root. */
|
|
123
|
+
export function LegendLabel({ disableStyle, className, ...props }) {
|
|
124
|
+
const chart = useChart('LegendLabel');
|
|
125
|
+
const row = useLegendRow('LegendLabel');
|
|
126
|
+
return (_jsx("span", { ...props, "data-component": "donutchart-legendlabel", "data-index": row.index, "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.labelToString(row.datum.label) }));
|
|
127
|
+
}
|
|
128
|
+
/** Shows the row's value, formatted by `valueToString` on Root. */
|
|
129
|
+
export function LegendValue({ disableStyle, className, ...props }) {
|
|
130
|
+
const chart = useChart('LegendValue');
|
|
131
|
+
const row = useLegendRow('LegendValue');
|
|
132
|
+
return (_jsx("span", { ...props, "data-component": "donutchart-legendvalue", "data-index": row.index, "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.valueToString(row.datum.value) }));
|
|
133
|
+
}
|
|
134
|
+
const TooltipContext = /* @__PURE__ */ createContext(null);
|
|
135
|
+
/** Renders no element: hands its popup to the Container. For extra fields, specify the record type: Tooltip<(typeof data)[number]>. */
|
|
136
|
+
export function Tooltip({ children, offset, allowEscapeViewBox, portal, }) {
|
|
137
|
+
const setTooltip = useContext(TooltipSlotContext);
|
|
138
|
+
if (!setTooltip)
|
|
139
|
+
throw new Error('DonutChart.Tooltip must be inside DonutChart.Container');
|
|
140
|
+
useLayoutEffect(() => {
|
|
141
|
+
setTooltip({
|
|
142
|
+
render: children,
|
|
143
|
+
props: { offset, allowEscapeViewBox, portal },
|
|
144
|
+
});
|
|
145
|
+
return () => setTooltip(null);
|
|
146
|
+
}, [setTooltip, children, offset, allowEscapeViewBox, portal]);
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
function useTooltipDatum(part) {
|
|
150
|
+
const datum = useContext(TooltipContext);
|
|
151
|
+
if (!datum)
|
|
152
|
+
throw new Error(`DonutChart.${part} must be inside DonutChart.Tooltip`);
|
|
153
|
+
return datum;
|
|
154
|
+
}
|
|
155
|
+
export function TooltipPopup({ disableStyle, className, ...props }) {
|
|
156
|
+
return (_jsx("div", { ...props, "data-component": "donutchart-tooltip", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
157
|
+
}
|
|
158
|
+
export function TooltipTitle({ disableStyle, className, ...props }) {
|
|
159
|
+
return (_jsx("p", { ...props, "data-component": "donutchart-tooltiptitle", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
160
|
+
}
|
|
161
|
+
/** Shows the hovered slice's label, formatted by `labelToString` on Root. */
|
|
162
|
+
export function TooltipLabel({ disableStyle, className, ...props }) {
|
|
163
|
+
const chart = useChart('TooltipLabel');
|
|
164
|
+
const datum = useTooltipDatum('TooltipLabel');
|
|
165
|
+
return (_jsx("p", { ...props, "data-component": "donutchart-tooltiplabel", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.labelToString(datum.label) }));
|
|
166
|
+
}
|
|
167
|
+
/** Shows the hovered slice's value, formatted by `valueToString` on Root. */
|
|
168
|
+
export function TooltipValue({ disableStyle, className, ...props }) {
|
|
169
|
+
const chart = useChart('TooltipValue');
|
|
170
|
+
const datum = useTooltipDatum('TooltipValue');
|
|
171
|
+
return (_jsx("p", { ...props, "data-component": "donutchart-tooltipvalue", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.valueToString(datum.value) }));
|
|
172
|
+
}
|
|
173
|
+
/** Carries the hovered slice's `data-index`, so it can match that slice's color. */
|
|
174
|
+
export function TooltipColorIndicator({ disableStyle, className, ...props }) {
|
|
175
|
+
const chart = useChart('TooltipColorIndicator');
|
|
176
|
+
const datum = useTooltipDatum('TooltipColorIndicator');
|
|
177
|
+
return (_jsx("span", { "aria-hidden": "true", ...props, "data-component": "donutchart-tooltipcolorindicator", "data-index": chart.data.findIndex((item) => item.label === datum.label), "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
178
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StyleProps } from '../../types/Style.ts';
|
|
2
|
+
import type { AsChildProps } from '../../utils/asChild.ts';
|
|
2
3
|
import { Drawer as BaseDrawer } from '@base-ui/react/drawer';
|
|
3
4
|
import type { ReactElement } from 'react';
|
|
4
5
|
import type { SVGIconProps } from '../../types/Icon.ts';
|
|
@@ -11,9 +12,9 @@ import type { SVGIconProps } from '../../types/Icon.ts';
|
|
|
11
12
|
* function Example() {
|
|
12
13
|
* return (
|
|
13
14
|
* <Drawer.Root swipeDirection="right">
|
|
14
|
-
* <Drawer.
|
|
15
|
+
* <Drawer.OpenButton asChild>
|
|
15
16
|
* <Button.default variant="secondary">Open account</Button.default>
|
|
16
|
-
* </Drawer.
|
|
17
|
+
* </Drawer.OpenButton>
|
|
17
18
|
* <Drawer.Backdrop />
|
|
18
19
|
* <Drawer.Popup>
|
|
19
20
|
* <Drawer.Header>
|
|
@@ -25,9 +26,9 @@ import type { SVGIconProps } from '../../types/Icon.ts';
|
|
|
25
26
|
* </Drawer.Header>
|
|
26
27
|
* <Drawer.Body>Account information goes here.</Drawer.Body>
|
|
27
28
|
* <Drawer.Footer>
|
|
28
|
-
* <Drawer.
|
|
29
|
+
* <Drawer.CloseButton asChild>
|
|
29
30
|
* <Button.default variant="primary">Done</Button.default>
|
|
30
|
-
* </Drawer.
|
|
31
|
+
* </Drawer.CloseButton>
|
|
31
32
|
* </Drawer.Footer>
|
|
32
33
|
* </Drawer.Popup>
|
|
33
34
|
* </Drawer.Root>
|
|
@@ -57,25 +58,15 @@ export declare const Indent: import("react").ForwardRefExoticComponent<Omit<Omit
|
|
|
57
58
|
export declare const SwipeArea: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").DrawerSwipeAreaProps, "className"> & {
|
|
58
59
|
className?: string;
|
|
59
60
|
} & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
60
|
-
/**
|
|
61
|
-
export declare const
|
|
62
|
-
className?: string;
|
|
63
|
-
/** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
|
|
64
|
-
children: ReactElement;
|
|
65
|
-
}, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
66
|
-
/** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
|
|
67
|
-
export declare const CloseHandler: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").DrawerCloseProps, "children" | "className" | "render"> & {
|
|
61
|
+
/** Opens the drawer. Pass asChild to give this behavior to your own element, like your app's Button. */
|
|
62
|
+
export declare const OpenButton: import("react").ForwardRefExoticComponent<Omit<Omit<BaseDrawer.Trigger.Props<unknown>, "className" | "render"> & {
|
|
68
63
|
className?: string;
|
|
69
|
-
|
|
70
|
-
children: ReactElement;
|
|
71
|
-
}, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
64
|
+
} & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
72
65
|
export type PopupProps = Omit<BaseDrawer.Popup.Props, 'className'> & {
|
|
73
66
|
className?: string;
|
|
74
67
|
} & Pick<BaseDrawer.Portal.Props, 'container' | 'keepMounted'> & StyleProps;
|
|
75
68
|
/** Already includes the portal. Keep it in the matching Root and let the native open state control visibility. */
|
|
76
|
-
export declare const Popup: import("react").ForwardRefExoticComponent<Omit<
|
|
77
|
-
className?: string;
|
|
78
|
-
} & Pick<import("@base-ui/react").DrawerPortalProps, "keepMounted" | "container"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
69
|
+
export declare const Popup: import("react").ForwardRefExoticComponent<Omit<PopupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
79
70
|
export declare const Backdrop: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").DrawerBackdropProps, "className"> & {
|
|
80
71
|
className?: string;
|
|
81
72
|
} & Pick<import("@base-ui/react").DrawerPortalProps, "keepMounted" | "container"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -88,12 +79,12 @@ export declare const Title: import("react").ForwardRefExoticComponent<Omit<Omit<
|
|
|
88
79
|
export declare const Description: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").DrawerDescriptionProps, "className"> & {
|
|
89
80
|
className?: string;
|
|
90
81
|
} & StyleProps, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
|
|
91
|
-
|
|
82
|
+
/** Icon-only: put just a CloseButtonIcon inside, never text like "Close". Name it for screen readers with aria-label instead, e.g. aria-label="Close drawer". Pass asChild to give closing behavior to your own button instead, like a "Done" Button. */
|
|
83
|
+
export declare const CloseButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").DrawerCloseProps, "className" | "render"> & {
|
|
92
84
|
className?: string;
|
|
93
|
-
} & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
85
|
+
} & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
94
86
|
/** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
|
|
95
87
|
export declare const CloseButtonIcon: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & {
|
|
96
88
|
/** Omit for the supplied default icon; pass a child only to replace it. */
|
|
97
89
|
children?: ReactElement<SVGIconProps>;
|
|
98
90
|
} & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
99
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { asChildRendering } from "../../utils/asChild.js";
|
|
2
3
|
import { Drawer as BaseDrawer } from '@base-ui/react/drawer';
|
|
3
4
|
import { cloneElement, forwardRef } from 'react';
|
|
4
5
|
import { twMerge } from 'tailwind-merge';
|
|
5
|
-
import { X } from
|
|
6
|
+
import { X } from "../../utils/icons.js";
|
|
6
7
|
/**
|
|
7
8
|
* Choose swipeDirection on Root and keep trigger and Popup in that Root. Popup already includes its portal. Provider and Indent parts are for an optional indented-background composition, not required for a basic drawer.
|
|
8
9
|
*
|
|
@@ -12,9 +13,9 @@ import { X } from 'lucide-react';
|
|
|
12
13
|
* function Example() {
|
|
13
14
|
* return (
|
|
14
15
|
* <Drawer.Root swipeDirection="right">
|
|
15
|
-
* <Drawer.
|
|
16
|
+
* <Drawer.OpenButton asChild>
|
|
16
17
|
* <Button.default variant="secondary">Open account</Button.default>
|
|
17
|
-
* </Drawer.
|
|
18
|
+
* </Drawer.OpenButton>
|
|
18
19
|
* <Drawer.Backdrop />
|
|
19
20
|
* <Drawer.Popup>
|
|
20
21
|
* <Drawer.Header>
|
|
@@ -26,9 +27,9 @@ import { X } from 'lucide-react';
|
|
|
26
27
|
* </Drawer.Header>
|
|
27
28
|
* <Drawer.Body>Account information goes here.</Drawer.Body>
|
|
28
29
|
* <Drawer.Footer>
|
|
29
|
-
* <Drawer.
|
|
30
|
+
* <Drawer.CloseButton asChild>
|
|
30
31
|
* <Button.default variant="primary">Done</Button.default>
|
|
31
|
-
* </Drawer.
|
|
32
|
+
* </Drawer.CloseButton>
|
|
32
33
|
* </Drawer.Footer>
|
|
33
34
|
* </Drawer.Popup>
|
|
34
35
|
* </Drawer.Root>
|
|
@@ -60,42 +61,38 @@ export const Indent = /* @__PURE__ */ forwardRef(function Indent({ disableStyle,
|
|
|
60
61
|
export const SwipeArea = /* @__PURE__ */ forwardRef(function SwipeArea({ disableStyle, className, ...props }, ref) {
|
|
61
62
|
return (_jsx(BaseDrawer.SwipeArea, { ...props, ref: ref, "data-component": "drawer-swipearea", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
62
63
|
});
|
|
63
|
-
/**
|
|
64
|
-
export const
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
/** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
|
|
68
|
-
export const CloseHandler = /* @__PURE__ */ forwardRef(function CloseHandler({ children, ...props }, ref) {
|
|
69
|
-
return _jsx(BaseDrawer.Close, { ...props, ref: ref, render: children });
|
|
64
|
+
/** Opens the drawer. Pass asChild to give this behavior to your own element, like your app's Button. */
|
|
65
|
+
export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ asChild, disableStyle, children, ...props }, ref) {
|
|
66
|
+
const rendering = asChildRendering({ asChild, children, component: 'drawer-openbutton', disableStyle });
|
|
67
|
+
return _jsx(BaseDrawer.Trigger, { ...props, ref: ref, ...rendering });
|
|
70
68
|
});
|
|
71
69
|
/** Already includes the portal. Keep it in the matching Root and let the native open state control visibility. */
|
|
72
70
|
export const Popup = /* @__PURE__ */ forwardRef(function Popup({ disableStyle, container, keepMounted, className, style, ...props }, ref) {
|
|
73
71
|
return (_jsx(BaseDrawer.Portal, { container: container, keepMounted: keepMounted, children: _jsx(BaseDrawer.Viewport, { children: _jsx(BaseDrawer.Popup, { ...props, ref: ref, "data-component": "drawer-popup", "data-style-disabled": disableStyle ? '' : undefined, className: className, style: (state) => {
|
|
74
|
-
const offset = state.swipeDirection === 'left' || state.swipeDirection === 'up'
|
|
75
|
-
? '-100%'
|
|
76
|
-
: '100%';
|
|
77
72
|
const vertical = state.swipeDirection === 'up' || state.swipeDirection === 'down';
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
// Sliding in and out from the side it swipes towards, otherwise following the finger (and the snap point, vertically)
|
|
74
|
+
const transform = (() => {
|
|
75
|
+
const offset = state.swipeDirection === 'left' || state.swipeDirection === 'up' ? '-100%' : '100%';
|
|
76
|
+
if (state.transitionStatus === 'starting' || state.transitionStatus === 'ending')
|
|
77
|
+
return vertical ? 'translateY(' + offset + ')' : 'translateX(' + offset + ')';
|
|
78
|
+
if (vertical)
|
|
79
|
+
return 'translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)))';
|
|
80
|
+
return 'translateX(var(--drawer-swipe-movement-x, 0px))';
|
|
81
|
+
})();
|
|
82
|
+
// No transition while the finger drags it, and a faster close after a strong swipe
|
|
83
|
+
const transitionDuration = (() => {
|
|
84
|
+
if (state.swiping)
|
|
85
|
+
return '0ms';
|
|
86
|
+
if (state.transitionStatus === 'ending')
|
|
87
|
+
return 'calc(var(--drawer-swipe-strength, 1) * 300ms)';
|
|
88
|
+
return '300ms';
|
|
89
|
+
})();
|
|
90
|
+
return {
|
|
81
91
|
zIndex: 40,
|
|
82
|
-
transform
|
|
83
|
-
? vertical
|
|
84
|
-
? 'translateY(' + offset + ')'
|
|
85
|
-
: 'translateX(' + offset + ')'
|
|
86
|
-
: vertical
|
|
87
|
-
? 'translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)))'
|
|
88
|
-
: 'translateX(var(--drawer-swipe-movement-x, 0px))',
|
|
92
|
+
transform,
|
|
89
93
|
transitionProperty: 'transform',
|
|
90
|
-
transitionDuration
|
|
91
|
-
? '0ms'
|
|
92
|
-
: state.transitionStatus === 'ending'
|
|
93
|
-
? 'calc(var(--drawer-swipe-strength, 1) * 300ms)'
|
|
94
|
-
: '300ms',
|
|
94
|
+
transitionDuration,
|
|
95
95
|
transitionTimingFunction: 'ease-out',
|
|
96
|
-
};
|
|
97
|
-
return {
|
|
98
|
-
...baseStyle,
|
|
99
96
|
...(typeof style === 'function' ? style(state) : style),
|
|
100
97
|
};
|
|
101
98
|
} }) }) }));
|
|
@@ -118,8 +115,10 @@ export const Title = /* @__PURE__ */ forwardRef(function Title({ disableStyle, c
|
|
|
118
115
|
export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, ...props }, ref) {
|
|
119
116
|
return (_jsx(BaseDrawer.Description, { ...props, ref: ref, "data-component": "drawer-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
120
117
|
});
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
/** Icon-only: put just a CloseButtonIcon inside, never text like "Close". Name it for screen readers with aria-label instead, e.g. aria-label="Close drawer". Pass asChild to give closing behavior to your own button instead, like a "Done" Button. */
|
|
119
|
+
export const CloseButton = /* @__PURE__ */ forwardRef(function CloseButton({ asChild, disableStyle, children, ...props }, ref) {
|
|
120
|
+
const rendering = asChildRendering({ asChild, children, component: 'drawer-closebutton', disableStyle });
|
|
121
|
+
return _jsx(BaseDrawer.Close, { ...props, ref: ref, ...rendering });
|
|
123
122
|
});
|
|
124
123
|
/** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
|
|
125
124
|
export const CloseButtonIcon = /* @__PURE__ */ forwardRef(function CloseButtonIcon({ disableStyle, children, className, ...props }, ref) {
|
|
@@ -134,4 +133,3 @@ export const CloseButtonIcon = /* @__PURE__ */ forwardRef(function CloseButtonIc
|
|
|
134
133
|
className: twMerge(children?.props.className, className),
|
|
135
134
|
});
|
|
136
135
|
});
|
|
137
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -26,9 +26,10 @@ import type { ComponentProps, HTMLAttributes, ImgHTMLAttributes, ReactElement }
|
|
|
26
26
|
* )
|
|
27
27
|
* }
|
|
28
28
|
*/
|
|
29
|
-
export declare function Surface({ disableStyle, className,
|
|
29
|
+
export declare function Surface({ disableStyle, className, ...props }: HTMLAttributes<HTMLDivElement> & StyleProps): import("react").JSX.Element;
|
|
30
30
|
export declare function Body({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
|
|
31
|
-
|
|
31
|
+
/** Renders an h2, so screen-reader users find it when jumping between headings, whether the panel fills a page or one section of it. */
|
|
32
|
+
export declare function Title({ disableStyle, className, ...props }: HTMLAttributes<HTMLHeadingElement> & StyleProps): import("react").JSX.Element;
|
|
32
33
|
export declare function Description({ disableStyle, className, ...props }: HTMLAttributes<HTMLParagraphElement> & StyleProps): import("react").JSX.Element;
|
|
33
34
|
export declare function Image({ disableStyle, className, ...props }: ImgHTMLAttributes<HTMLImageElement> & StyleProps): import("react").JSX.Element;
|
|
34
35
|
/** Supply the decorative icon as a child. Its classes are preserved; interaction belongs to the surrounding control. */
|
|
@@ -37,4 +38,3 @@ export declare function Icon({ disableStyle, children, className, ...props }: (O
|
|
|
37
38
|
children: ReactElement<ComponentProps<'svg'>>;
|
|
38
39
|
}) & StyleProps): ReactElement<import("react").SVGProps<SVGSVGElement>, string | import("react").JSXElementConstructor<any>>;
|
|
39
40
|
export declare function ActionsList({ disableStyle, className, ...props }: HTMLAttributes<HTMLDivElement> & StyleProps): import("react").JSX.Element;
|
|
40
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -27,14 +27,15 @@ import { twMerge } from 'tailwind-merge';
|
|
|
27
27
|
* )
|
|
28
28
|
* }
|
|
29
29
|
*/
|
|
30
|
-
export function Surface({ disableStyle, className,
|
|
31
|
-
return (_jsx("div", { "data-component": "empty-surface", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props
|
|
30
|
+
export function Surface({ disableStyle, className, ...props }) {
|
|
31
|
+
return (_jsx("div", { "data-component": "empty-surface", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
|
|
32
32
|
}
|
|
33
33
|
export function Body({ disableStyle, className, ...props }) {
|
|
34
34
|
return (_jsx("div", { ...props, "data-component": "empty-body", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
|
|
35
35
|
}
|
|
36
|
+
/** Renders an h2, so screen-reader users find it when jumping between headings, whether the panel fills a page or one section of it. */
|
|
36
37
|
export function Title({ disableStyle, className, ...props }) {
|
|
37
|
-
return (_jsx("
|
|
38
|
+
return (_jsx("h2", { "data-component": "empty-title", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
|
|
38
39
|
}
|
|
39
40
|
export function Description({ disableStyle, className, ...props }) {
|
|
40
41
|
return (_jsx("p", { "data-component": "empty-description", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
|
|
@@ -45,7 +46,6 @@ export function Image({ disableStyle, className, ...props }) {
|
|
|
45
46
|
/** Supply the decorative icon as a child. Its classes are preserved; interaction belongs to the surrounding control. */
|
|
46
47
|
export function Icon({ disableStyle, children, className, ...props }) {
|
|
47
48
|
return cloneElement(children, {
|
|
48
|
-
...children.props,
|
|
49
49
|
...props,
|
|
50
50
|
...{
|
|
51
51
|
'data-component': 'empty-icon',
|
|
@@ -58,4 +58,3 @@ export function Icon({ disableStyle, children, className, ...props }) {
|
|
|
58
58
|
export function ActionsList({ disableStyle, className, ...props }) {
|
|
59
59
|
return (_jsx("div", { "data-component": "empty-actionslist", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
|
|
60
60
|
}
|
|
61
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { StyleProps } from '../../types/Style.ts';
|
|
2
|
+
import type { ComponentProps, HTMLAttributes, ImgHTMLAttributes, ReactElement, ReactNode } from 'react';
|
|
3
|
+
type Tone = 'neutral' | 'critical';
|
|
4
|
+
/**
|
|
5
|
+
* Explains why something can't be shown, like a page that doesn't exist or a section the user isn't allowed to see. It isn't an error, just a normal state of the app.
|
|
6
|
+
* Root holds the tone and renders nothing itself; Surface and Body render the panel. You decide when it appears. It's a section: put it where the missing content would have been, and it fills that container's height.
|
|
7
|
+
* Image/Icon, ActionsList and HelpText are optional. ActionsList takes your own buttons, since the actions belong to your app.
|
|
8
|
+
*
|
|
9
|
+
* @example A page the user can't access
|
|
10
|
+
* import { Button, Exception, TextLink } from '@central-ui/react'
|
|
11
|
+
* import { Link } from '@tanstack/react-router'
|
|
12
|
+
* import { Lock } from 'lucide-react'
|
|
13
|
+
*
|
|
14
|
+
* function Example() {
|
|
15
|
+
* return (
|
|
16
|
+
* // Inside the body of some page. That page's header shows no title or back button,
|
|
17
|
+
* // since they would describe something the user can't see.
|
|
18
|
+
* <Exception.Root>
|
|
19
|
+
* <Exception.Surface>
|
|
20
|
+
* <Exception.Body>
|
|
21
|
+
* <Exception.Icon>
|
|
22
|
+
* <Lock aria-hidden="true" />
|
|
23
|
+
* </Exception.Icon>
|
|
24
|
+
* <Exception.Title>You don't have access to this page</Exception.Title>
|
|
25
|
+
* <Exception.Description>Ask a store owner to give your account the Orders permission.</Exception.Description>
|
|
26
|
+
* <Exception.ActionsList>
|
|
27
|
+
* <Button.default variant="primary">Go to dashboard</Button.default>
|
|
28
|
+
* </Exception.ActionsList>
|
|
29
|
+
* <Exception.HelpText>
|
|
30
|
+
* Still stuck?{' '}
|
|
31
|
+
* <TextLink.default>
|
|
32
|
+
* <Link to="/support">Contact support</Link>
|
|
33
|
+
* </TextLink.default>
|
|
34
|
+
* </Exception.HelpText>
|
|
35
|
+
* </Exception.Body>
|
|
36
|
+
* </Exception.Surface>
|
|
37
|
+
* </Exception.Root>
|
|
38
|
+
* )
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* @example A page that doesn't exist
|
|
42
|
+
* // Also inside the body of some page with no title in its header; the code goes in the Title.
|
|
43
|
+
* ;<Exception.Root>
|
|
44
|
+
* <Exception.Surface>
|
|
45
|
+
* <Exception.Body>
|
|
46
|
+
* <Exception.Title>404 · Page not found</Exception.Title>
|
|
47
|
+
* <Exception.Description>The page may have moved, or the link is wrong.</Exception.Description>
|
|
48
|
+
* </Exception.Body>
|
|
49
|
+
* </Exception.Surface>
|
|
50
|
+
* </Exception.Root>
|
|
51
|
+
*
|
|
52
|
+
* @example A section that failed to load, inside a page that otherwise works
|
|
53
|
+
* // In place of that section only; the rest of the page stays.
|
|
54
|
+
* ;<Exception.Root tone="critical">
|
|
55
|
+
* {
|
|
56
|
+
* // Rest of components here
|
|
57
|
+
* }
|
|
58
|
+
* </Exception.Root>
|
|
59
|
+
*/
|
|
60
|
+
export declare function Root({ tone, children, }: {
|
|
61
|
+
/**
|
|
62
|
+
* Neutral for expected situations, like no access or a missing page. Critical for failures, like a section that couldn't load; it turns the Title red.
|
|
63
|
+
* Every part carries it as data-tone.
|
|
64
|
+
* @default 'neutral'
|
|
65
|
+
*/
|
|
66
|
+
tone?: Tone;
|
|
67
|
+
/** The Surface. */
|
|
68
|
+
children: ReactNode;
|
|
69
|
+
}): import("react").JSX.Element;
|
|
70
|
+
/** Centers the panel and fills its container's height. */
|
|
71
|
+
export declare const Surface: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & StyleProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
72
|
+
export declare const Body: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
73
|
+
/** Renders an h2, so screen-reader users find it when jumping between headings, whether the panel fills a page or one section of it. */
|
|
74
|
+
export declare const Title: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLHeadingElement> & StyleProps & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
75
|
+
export declare const Description: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & StyleProps & import("react").RefAttributes<HTMLParagraphElement>>;
|
|
76
|
+
export declare const Image: import("react").ForwardRefExoticComponent<ImgHTMLAttributes<HTMLImageElement> & StyleProps & import("react").RefAttributes<HTMLImageElement>>;
|
|
77
|
+
/** Supply the decorative icon as a child. Its classes are preserved; interaction belongs to the surrounding control. */
|
|
78
|
+
export declare const Icon: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").SVGProps<SVGSVGElement>, "children"> & {
|
|
79
|
+
/** Supply the decorative icon; the wrapper forwards the relevant state and preserves its classes. */
|
|
80
|
+
children: ReactElement<ComponentProps<"svg">>;
|
|
81
|
+
} & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
82
|
+
/** Takes your own buttons, like a primary "Go to dashboard"; it creates no actions itself. */
|
|
83
|
+
export declare const ActionsList: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & StyleProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
84
|
+
/** A small footnote below the actions, like "Still stuck? Contact support" with a link. */
|
|
85
|
+
export declare const HelpText: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & StyleProps & import("react").RefAttributes<HTMLParagraphElement>>;
|
|
86
|
+
export {};
|