@inkra/react 0.1.0 → 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/README.md +186 -1
- package/dist/PencilIcon.js +14 -16
- package/dist/PencilLine.js +18 -12
- package/dist/PencilText.js +192 -59
- package/dist/alert-dialog/index.d.ts +64 -0
- package/dist/alert-dialog/index.js +111 -0
- package/dist/audio-player/index.d.ts +60 -0
- package/dist/audio-player/index.js +101 -0
- package/dist/carousel/index.d.ts +51 -0
- package/dist/carousel/index.js +290 -0
- package/dist/choice-grid/index.d.ts +38 -0
- package/dist/choice-grid/index.js +85 -0
- package/dist/color-picker/color.d.ts +15 -0
- package/dist/color-picker/color.js +55 -0
- package/dist/color-picker/index.d.ts +31 -0
- package/dist/color-picker/index.js +69 -0
- package/dist/command/index.d.ts +45 -0
- package/dist/command/index.js +39 -0
- package/dist/context-menu/index.d.ts +76 -0
- package/dist/context-menu/index.js +241 -0
- package/dist/data-table/index.d.ts +47 -0
- package/dist/data-table/index.js +91 -0
- package/dist/date-picker/index.d.ts +50 -0
- package/dist/date-picker/index.js +180 -0
- package/dist/display/ProgressRing.d.ts +6 -0
- package/dist/display/ProgressRing.js +146 -0
- package/dist/display/index.d.ts +27 -0
- package/dist/display/index.js +18 -2
- package/dist/dockable-panel/index.d.ts +41 -0
- package/dist/dockable-panel/index.js +253 -0
- package/dist/dockable-panel/model.d.ts +21 -0
- package/dist/dockable-panel/model.js +61 -0
- package/dist/drawer/index.d.ts +63 -0
- package/dist/drawer/index.js +88 -0
- package/dist/dropdown-menu/index.d.ts +1 -1
- package/dist/dropdown-menu/index.js +3 -2
- package/dist/editable/index.d.ts +53 -0
- package/dist/editable/index.js +162 -0
- package/dist/empty/index.d.ts +21 -0
- package/dist/empty/index.js +23 -0
- package/dist/flip/index.d.ts +49 -0
- package/dist/flip/index.js +138 -0
- package/dist/form/EditablePencilText.js +188 -143
- package/dist/form/Input.js +1 -1
- package/dist/form/Textarea.d.ts +12 -0
- package/dist/form/Textarea.js +83 -4
- package/dist/form/index.d.ts +1 -1
- package/dist/heatmap/index.d.ts +59 -0
- package/dist/heatmap/index.js +248 -0
- package/dist/hotkey/index.d.ts +37 -0
- package/dist/hotkey/index.js +130 -0
- package/dist/hotkey/model.d.ts +27 -0
- package/dist/hotkey/model.js +97 -0
- package/dist/hover-card/index.d.ts +33 -0
- package/dist/hover-card/index.js +141 -0
- package/dist/image-cropper/index.d.ts +82 -0
- package/dist/image-cropper/index.js +261 -0
- package/dist/image-cropper/model.d.ts +42 -0
- package/dist/image-cropper/model.js +94 -0
- package/dist/image-viewer/index.d.ts +79 -0
- package/dist/image-viewer/index.js +220 -0
- package/dist/image-viewer/model.d.ts +9 -0
- package/dist/image-viewer/model.js +18 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +47 -0
- package/dist/input-number/index.d.ts +6 -0
- package/dist/input-number/index.js +126 -15
- package/dist/input-number/model.d.ts +13 -0
- package/dist/input-number/model.js +50 -0
- package/dist/internal/cache.d.ts +1 -1
- package/dist/internal/cache.js +1 -1
- package/dist/internal/renderTokens.d.ts +10 -0
- package/dist/internal/renderTokens.js +13 -0
- package/dist/internal/surfaceRenderer.d.ts +14 -6
- package/dist/internal/surfaceRenderer.js +15 -12
- package/dist/internal/textRenderer.d.ts +1 -0
- package/dist/internal/textRenderer.js +33 -7
- package/dist/internal/usePencilSurface.js +16 -8
- package/dist/internal/useSelectionDrawing.js +15 -11
- package/dist/journey-map/MapScale.js +3 -1
- package/dist/journey-map/index.js +3 -1
- package/dist/keypad/index.d.ts +23 -0
- package/dist/keypad/index.js +63 -0
- package/dist/keypad/model.d.ts +20 -0
- package/dist/keypad/model.js +33 -0
- package/dist/layout/index.d.ts +63 -0
- package/dist/layout/index.js +62 -0
- package/dist/log/index.d.ts +45 -0
- package/dist/log/index.js +159 -0
- package/dist/log/model.d.ts +16 -0
- package/dist/log/model.js +13 -0
- package/dist/node-graph/index.d.ts +123 -0
- package/dist/node-graph/index.js +304 -0
- package/dist/number-ticker/index.d.ts +31 -0
- package/dist/number-ticker/index.js +135 -0
- package/dist/number-ticker/model.d.ts +41 -0
- package/dist/number-ticker/model.js +163 -0
- package/dist/number-ticker/precision.d.ts +7 -0
- package/dist/number-ticker/precision.js +134 -0
- package/dist/overflow-list/index.d.ts +39 -0
- package/dist/overflow-list/index.js +230 -0
- package/dist/overflow-list/layout.d.ts +19 -0
- package/dist/overflow-list/layout.js +44 -0
- package/dist/overlay/Overlay.d.ts +1 -1
- package/dist/overlay/Overlay.js +4 -2
- package/dist/overlay/Popover.d.ts +1 -1
- package/dist/overlay/Popover.js +3 -2
- package/dist/overlay/themeBridge.d.ts +12 -1
- package/dist/overlay/themeBridge.js +27 -1
- package/dist/pagination/index.d.ts +23 -0
- package/dist/pagination/index.js +41 -0
- package/dist/pagination/model.d.ts +4 -0
- package/dist/pagination/model.js +42 -0
- package/dist/pan-zoom/index.d.ts +71 -0
- package/dist/pan-zoom/index.js +175 -0
- package/dist/radar/index.d.ts +56 -0
- package/dist/radar/index.js +220 -0
- package/dist/range-slider/index.d.ts +16 -0
- package/dist/range-slider/index.js +22 -0
- package/dist/rating/index.d.ts +28 -0
- package/dist/rating/index.js +127 -0
- package/dist/resizable/index.d.ts +32 -0
- package/dist/resizable/index.js +50 -0
- package/dist/scroll-area/index.d.ts +36 -0
- package/dist/scroll-area/index.js +44 -0
- package/dist/segmented-progress/SegmentedProgress.d.ts +17 -0
- package/dist/segmented-progress/SegmentedProgress.js +42 -0
- package/dist/slider/index.js +1 -1
- package/dist/slot/index.d.ts +24 -0
- package/dist/slot/index.js +29 -0
- package/dist/sortable/index.d.ts +50 -0
- package/dist/sortable/index.js +283 -0
- package/dist/sortable/model.d.ts +30 -0
- package/dist/sortable/model.js +64 -0
- package/dist/sparkline/index.d.ts +19 -0
- package/dist/sparkline/index.js +240 -0
- package/dist/sparkline/model.d.ts +16 -0
- package/dist/sparkline/model.js +28 -0
- package/dist/steps/index.d.ts +16 -0
- package/dist/steps/index.js +37 -0
- package/dist/styles.css +4957 -269
- package/dist/tag-input/index.d.ts +69 -0
- package/dist/tag-input/index.js +325 -0
- package/dist/tag-input/model.d.ts +14 -0
- package/dist/tag-input/model.js +38 -0
- package/dist/time-picker/index.d.ts +15 -0
- package/dist/time-picker/index.js +168 -0
- package/dist/timeline/index.d.ts +14 -0
- package/dist/timeline/index.js +16 -0
- package/dist/toast/index.d.ts +27 -0
- package/dist/toast/index.js +36 -0
- package/dist/toggle-group/index.d.ts +17 -0
- package/dist/toggle-group/index.js +26 -0
- package/dist/tokens.css +10 -9
- package/dist/tooltip/Tooltip.d.ts +1 -1
- package/dist/tooltip/Tooltip.js +3 -2
- package/dist/transfer/index.d.ts +64 -0
- package/dist/transfer/index.js +174 -0
- package/dist/transfer/model.d.ts +12 -0
- package/dist/transfer/model.js +33 -0
- package/dist/tree/index.d.ts +39 -0
- package/dist/tree/index.js +36 -0
- package/dist/tree-select/index.d.ts +59 -0
- package/dist/tree-select/index.js +142 -0
- package/dist/tree-select/model.d.ts +31 -0
- package/dist/tree-select/model.js +135 -0
- package/dist/typewriter/index.d.ts +21 -0
- package/dist/typewriter/index.js +101 -0
- package/dist/typewriter/model.d.ts +7 -0
- package/dist/typewriter/model.js +45 -0
- package/dist/upload/index.d.ts +59 -0
- package/dist/upload/index.js +230 -0
- package/dist/virtual-list/index.d.ts +44 -0
- package/dist/virtual-list/index.js +129 -0
- package/dist/virtual-list/model.d.ts +7 -0
- package/dist/virtual-list/model.js +27 -0
- package/package.json +23 -3
package/dist/overlay/Overlay.js
CHANGED
|
@@ -8,7 +8,7 @@ import { PencilLine } from '../PencilLine.js';
|
|
|
8
8
|
import { PencilSurface } from '../PencilSurface.js';
|
|
9
9
|
import { PencilText } from '../PencilText.js';
|
|
10
10
|
import { Tooltip } from '../tooltip/Tooltip.js';
|
|
11
|
-
import {
|
|
11
|
+
import { mapPortalChildren, PortalThemeProvider, usePortalThemeProps, usePortalTriggerRef, } from './themeBridge.js';
|
|
12
12
|
function classes(...values) {
|
|
13
13
|
return values.filter(Boolean).join(' ');
|
|
14
14
|
}
|
|
@@ -20,13 +20,15 @@ export const OverlayTrigger = forwardRef(function OverlayTrigger(props, forwarde
|
|
|
20
20
|
return _jsx(DialogPrimitive.Trigger, { ...props, ref: ref });
|
|
21
21
|
});
|
|
22
22
|
export function OverlayPortal({ children, ...props }) {
|
|
23
|
-
return (_jsx(DialogPrimitive.Portal, { ...props, children:
|
|
23
|
+
return mapPortalChildren(children, child => _jsx(DialogPrimitive.Portal, { ...props, children: child }));
|
|
24
24
|
}
|
|
25
25
|
export const OverlayBackdrop = forwardRef(function OverlayBackdrop({ className, ...props }, ref) {
|
|
26
|
+
props = usePortalThemeProps(props);
|
|
26
27
|
return (_jsx(DialogPrimitive.Overlay, { ...props, className: classes('inkra-overlay__backdrop', className), ref: ref }));
|
|
27
28
|
});
|
|
28
29
|
export const OverlayContent = forwardRef(function OverlayContent({ children, className, layout = 'plain', seed, surfaceClassName, surfaceRadius = 8, surfaceVariant = 'paper', ...props }, ref) {
|
|
29
30
|
const id = useId();
|
|
31
|
+
props = usePortalThemeProps(props);
|
|
30
32
|
return (_jsx(DialogPrimitive.Content, { ...props, className: classes('inkra-overlay__content', className), "data-layout": layout, ref: ref, children: _jsx(PencilSurface, { className: classes('inkra-overlay__surface', surfaceClassName), radius: surfaceRadius, seed: seed ?? `inkra-overlay-${id}`, variant: surfaceVariant, children: _jsx("div", { className: "inkra-overlay__content-body", children: children }) }) }));
|
|
31
33
|
});
|
|
32
34
|
export const OverlayTitle = forwardRef(function OverlayTitle({ children, className, seed, ...props }, ref) {
|
|
@@ -8,7 +8,7 @@ export declare const PopoverAnchor: import("react").ForwardRefExoticComponent<Po
|
|
|
8
8
|
export type PopoverTriggerProps = PopoverPrimitive.PopoverTriggerProps;
|
|
9
9
|
export declare const PopoverTrigger: import("react").ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
10
10
|
export type PopoverPortalProps = PopoverPrimitive.PopoverPortalProps;
|
|
11
|
-
export declare function PopoverPortal({ children, ...props }: PopoverPortalProps): import("react").
|
|
11
|
+
export declare function PopoverPortal({ children, ...props }: PopoverPortalProps): import("react").ReactNode;
|
|
12
12
|
export interface PopoverContentProps extends PopoverPrimitive.PopoverContentProps {
|
|
13
13
|
arrowProps?: PopoverArrowProps;
|
|
14
14
|
seed?: string | number;
|
package/dist/overlay/Popover.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
|
3
3
|
import { forwardRef, useId } from 'react';
|
|
4
4
|
import { PencilSurface } from '../PencilSurface.js';
|
|
5
5
|
import { PencilText } from '../PencilText.js';
|
|
6
|
-
import {
|
|
6
|
+
import { mapPortalChildren, PortalThemeProvider, usePortalThemeProps, usePortalTriggerRef, } from './themeBridge.js';
|
|
7
7
|
function classes(...values) {
|
|
8
8
|
return values.filter(Boolean).join(' ');
|
|
9
9
|
}
|
|
@@ -16,10 +16,11 @@ export const PopoverTrigger = forwardRef(function PopoverTrigger(props, forwarde
|
|
|
16
16
|
return _jsx(PopoverPrimitive.Trigger, { ...props, ref: ref });
|
|
17
17
|
});
|
|
18
18
|
export function PopoverPortal({ children, ...props }) {
|
|
19
|
-
return (_jsx(PopoverPrimitive.Portal, { ...props, children:
|
|
19
|
+
return mapPortalChildren(children, child => _jsx(PopoverPrimitive.Portal, { ...props, children: child }));
|
|
20
20
|
}
|
|
21
21
|
export const PopoverContent = forwardRef(function PopoverContent({ arrowProps, children, className, seed, showArrow = false, surfaceClassName, surfaceRadius = 8, surfaceVariant = 'paper', ...props }, ref) {
|
|
22
22
|
const id = useId();
|
|
23
|
+
props = usePortalThemeProps(props);
|
|
23
24
|
return (_jsxs(PopoverPrimitive.Content, { ...props, className: classes('inkra-popover__content', className), ref: ref, children: [_jsx(PencilSurface, { className: classes('inkra-popover__surface', surfaceClassName), radius: surfaceRadius, seed: seed ?? `inkra-popover-${id}`, variant: surfaceVariant, children: _jsx("div", { className: "inkra-popover__content-body", children: children }) }), showArrow ? (_jsx(PopoverPrimitive.Arrow, { ...arrowProps, className: classes('inkra-popover__arrow', arrowProps?.className) })) : null] }));
|
|
24
25
|
});
|
|
25
26
|
export const PopoverTitle = forwardRef(function PopoverTitle({ children, className, seed, ...props }, ref) {
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import type { ForwardedRef, ReactNode } from 'react';
|
|
1
|
+
import type { CSSProperties, ForwardedRef, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
type InkraStyle = CSSProperties & Record<`--inkra-${string}`, string>;
|
|
2
3
|
export declare function PortalThemeProvider({ children }: {
|
|
3
4
|
children: ReactNode;
|
|
4
5
|
}): import("react").JSX.Element;
|
|
5
6
|
export declare function usePortalTriggerRef<Element extends HTMLElement>(forwardedRef: ForwardedRef<Element>): (node: Element | null) => void;
|
|
7
|
+
export declare function mapPortalChildren(children: ReactNode, render: (child: ReactNode) => ReactNode): ReactNode;
|
|
8
|
+
export declare function usePortalThemeProps<Props extends HTMLAttributes<HTMLElement>>(props: Props): {
|
|
9
|
+
'data-inkra-theme': string | undefined;
|
|
10
|
+
'data-theme': string | undefined;
|
|
11
|
+
dir: "ltr" | "rtl";
|
|
12
|
+
lang: string | undefined;
|
|
13
|
+
} & Props & {
|
|
14
|
+
style: InkraStyle;
|
|
15
|
+
};
|
|
6
16
|
export declare const PortalThemeBridge: import("react").ForwardRefExoticComponent<{
|
|
7
17
|
children: ReactNode;
|
|
8
18
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
19
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, forwardRef, useCallback, useContext, useEffect, useMemo, useState, } from 'react';
|
|
2
|
+
import { Children, Fragment, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useMemo, useState, } from 'react';
|
|
3
3
|
const emptySnapshot = {
|
|
4
4
|
direction: 'ltr',
|
|
5
5
|
style: {},
|
|
@@ -86,6 +86,32 @@ export function usePortalTriggerRef(forwardedRef) {
|
|
|
86
86
|
captureTrigger?.(node);
|
|
87
87
|
}, [captureTrigger, forwardedRef]);
|
|
88
88
|
}
|
|
89
|
+
// Presence must receive each animated DOM node, not a display:contents wrapper.
|
|
90
|
+
export function mapPortalChildren(children, render) {
|
|
91
|
+
return Children.map(children, child => {
|
|
92
|
+
if (isValidElement(child) && child.type === Fragment) {
|
|
93
|
+
return mapPortalChildren(child.props.children, render);
|
|
94
|
+
}
|
|
95
|
+
return child == null ? null : render(child);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
export function usePortalThemeProps(props) {
|
|
99
|
+
const context = useContext(PortalThemeContext);
|
|
100
|
+
const depth = context?.depth ?? 0;
|
|
101
|
+
const snapshot = context?.snapshot ?? emptySnapshot;
|
|
102
|
+
return {
|
|
103
|
+
'data-inkra-theme': snapshot.inkraTheme,
|
|
104
|
+
'data-theme': snapshot.theme,
|
|
105
|
+
dir: snapshot.direction,
|
|
106
|
+
lang: snapshot.language,
|
|
107
|
+
...props,
|
|
108
|
+
style: {
|
|
109
|
+
...snapshot.style,
|
|
110
|
+
'--inkra-floating-layer-offset': `${depth * 20}`,
|
|
111
|
+
...props.style,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
89
115
|
export const PortalThemeBridge = forwardRef(function PortalThemeBridge({ children }, ref) {
|
|
90
116
|
const context = useContext(PortalThemeContext);
|
|
91
117
|
const depth = context?.depth ?? 0;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
export interface PaginationLabels {
|
|
3
|
+
nav: string;
|
|
4
|
+
first: string;
|
|
5
|
+
previous: string;
|
|
6
|
+
next: string;
|
|
7
|
+
last: string;
|
|
8
|
+
page: (page: number) => string;
|
|
9
|
+
ellipsis: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'children' | 'onChange'> {
|
|
12
|
+
totalPages: number;
|
|
13
|
+
page?: number;
|
|
14
|
+
defaultPage?: number;
|
|
15
|
+
onPageChange?: (page: number) => void;
|
|
16
|
+
siblingCount?: number;
|
|
17
|
+
boundaryCount?: number;
|
|
18
|
+
showFirstLast?: boolean;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
size?: 'sm' | 'md' | 'lg';
|
|
21
|
+
labels?: Partial<PaginationLabels>;
|
|
22
|
+
}
|
|
23
|
+
export declare const Pagination: import("react").ForwardRefExoticComponent<PaginationProps & import("react").RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useEffect, useState } from 'react';
|
|
3
|
+
import { Button } from '../Button.js';
|
|
4
|
+
import { PencilIcon } from '../PencilIcon.js';
|
|
5
|
+
import { PencilSurface } from '../PencilSurface.js';
|
|
6
|
+
import { PencilText } from '../PencilText.js';
|
|
7
|
+
import { clampPage, getPaginationEntries, normalizeTotal } from './model.js';
|
|
8
|
+
const defaultLabels = {
|
|
9
|
+
nav: 'Pagination', first: 'First page', previous: 'Previous page', next: 'Next page', last: 'Last page',
|
|
10
|
+
page: page => `Page ${page}`, ellipsis: 'More pages',
|
|
11
|
+
};
|
|
12
|
+
export const Pagination = forwardRef(function Pagination({ totalPages, page, defaultPage = 1, onPageChange, siblingCount = 1, boundaryCount = 1, showFirstLast = false, disabled = false, size = 'md', labels, className, ...props }, ref) {
|
|
13
|
+
const total = normalizeTotal(totalPages);
|
|
14
|
+
const [internalPage, setInternalPage] = useState(() => clampPage(defaultPage, total));
|
|
15
|
+
const current = clampPage(page ?? internalPage, total);
|
|
16
|
+
const text = { ...defaultLabels, ...labels };
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (page === undefined)
|
|
19
|
+
setInternalPage(value => clampPage(value, total));
|
|
20
|
+
}, [page, total]);
|
|
21
|
+
function select(next) {
|
|
22
|
+
const target = clampPage(next, total);
|
|
23
|
+
if (disabled || !total || target === current)
|
|
24
|
+
return;
|
|
25
|
+
if (page === undefined)
|
|
26
|
+
setInternalPage(target);
|
|
27
|
+
onPageChange?.(target);
|
|
28
|
+
}
|
|
29
|
+
const arrow = (kind, target, unavailable) => {
|
|
30
|
+
const backwards = kind === 'first' || kind === 'previous';
|
|
31
|
+
const paths = [{ d: backwards ? 'm15 18-6-6 6-6' : 'm9 18 6-6-6-6' }];
|
|
32
|
+
if (kind === 'first')
|
|
33
|
+
paths.push({ d: 'M5 6v12' });
|
|
34
|
+
if (kind === 'last')
|
|
35
|
+
paths.push({ d: 'M19 6v12' });
|
|
36
|
+
return _jsx("li", { children: _jsx(Button, { variant: "ghost", size: size === 'md' ? 'icon' : `icon-${size}`, "aria-label": text[kind], title: text[kind], disabled: disabled || unavailable, onClick: () => select(target), children: _jsx(PencilIcon, { className: "inkra-pagination__arrow", paths: paths, size: 20, sourceSize: 24 }) }) }, kind);
|
|
37
|
+
};
|
|
38
|
+
return _jsx("nav", { "aria-label": text.nav, ...props, ref: ref, className: ['inkra-pagination', className].filter(Boolean).join(' '), "data-empty": !total || undefined, children: _jsxs("ul", { className: "inkra-pagination__list", children: [showFirstLast && arrow('first', 1, current <= 1), arrow('previous', current - 1, current <= 1), getPaginationEntries(total, current, siblingCount, boundaryCount).map(entry => typeof entry === 'number'
|
|
39
|
+
? _jsx("li", { children: _jsxs(Button, { size: size, variant: "ghost", className: "inkra-pagination__page", "aria-label": text.page(entry), "aria-current": entry === current ? 'page' : undefined, disabled: disabled, onClick: () => select(entry), children: [entry === current && _jsx(PencilSurface, { as: "span", "aria-hidden": "true", variant: "selection", className: "inkra-pagination__selection", seed: `page-${entry}` }), _jsx(PencilText, { children: String(entry) })] }) }, entry)
|
|
40
|
+
: _jsxs("li", { className: "inkra-pagination__ellipsis", children: [_jsx("span", { className: "inkra-pagination__sr-only", children: text.ellipsis }), _jsx(PencilText, { "aria-hidden": "true", children: "..." })] }, entry)), arrow('next', current + 1, !total || current >= total), showFirstLast && arrow('last', total, !total || current >= total)] }) });
|
|
41
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type PaginationEntry = number | 'ellipsis-start' | 'ellipsis-end';
|
|
2
|
+
export declare function normalizeTotal(total: number): number;
|
|
3
|
+
export declare function clampPage(page: number, total: number): number;
|
|
4
|
+
export declare function getPaginationEntries(total: number, page: number, siblings?: number, boundaries?: number): PaginationEntry[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function normalizeTotal(total) {
|
|
2
|
+
return Number.isFinite(total) ? Math.max(0, Math.min(Number.MAX_SAFE_INTEGER, Math.floor(total))) : 0;
|
|
3
|
+
}
|
|
4
|
+
export function clampPage(page, total) {
|
|
5
|
+
if (total === 0)
|
|
6
|
+
return 0;
|
|
7
|
+
return Math.min(total, Math.max(1, Number.isFinite(page) ? Math.floor(page) : 1));
|
|
8
|
+
}
|
|
9
|
+
function windowCount(value) {
|
|
10
|
+
return Number.isFinite(value) ? Math.max(0, Math.min(3, Math.floor(value))) : 1;
|
|
11
|
+
}
|
|
12
|
+
export function getPaginationEntries(total, page, siblings = 1, boundaries = 1) {
|
|
13
|
+
total = normalizeTotal(total);
|
|
14
|
+
if (!total)
|
|
15
|
+
return [];
|
|
16
|
+
page = clampPage(page, total);
|
|
17
|
+
siblings = windowCount(siblings);
|
|
18
|
+
boundaries = windowCount(boundaries);
|
|
19
|
+
const visible = new Set([page]);
|
|
20
|
+
for (let offset = 1; offset <= boundaries; offset += 1) {
|
|
21
|
+
visible.add(offset);
|
|
22
|
+
visible.add(total - offset + 1);
|
|
23
|
+
}
|
|
24
|
+
for (let offset = -siblings; offset <= siblings; offset += 1)
|
|
25
|
+
visible.add(page + offset);
|
|
26
|
+
const pages = [...visible].filter(value => value >= 1 && value <= total).sort((a, b) => a - b);
|
|
27
|
+
const entries = [];
|
|
28
|
+
let previous = 0;
|
|
29
|
+
for (const value of pages) {
|
|
30
|
+
if (previous && value - previous === 2)
|
|
31
|
+
entries.push(previous + 1);
|
|
32
|
+
else if (previous && value - previous > 2)
|
|
33
|
+
entries.push(value <= page ? 'ellipsis-start' : 'ellipsis-end');
|
|
34
|
+
else if (!previous && value > 1)
|
|
35
|
+
entries.push('ellipsis-start');
|
|
36
|
+
entries.push(value);
|
|
37
|
+
previous = value;
|
|
38
|
+
}
|
|
39
|
+
if (previous < total)
|
|
40
|
+
entries.push('ellipsis-end');
|
|
41
|
+
return entries;
|
|
42
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { FitToViewMode, ZoomToElementOptions, ZoomToElementTarget } from 'react-zoom-pan-pinch';
|
|
2
|
+
import type { CSSProperties, HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
export interface PanZoomTransform {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
scale: number;
|
|
7
|
+
}
|
|
8
|
+
export interface PanZoomChangeDetails {
|
|
9
|
+
reason: 'gesture' | 'programmatic';
|
|
10
|
+
}
|
|
11
|
+
export interface PanZoomPoint {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PanZoomAnimationOptions {
|
|
16
|
+
duration?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface PanZoomFitOptions extends PanZoomAnimationOptions {
|
|
19
|
+
mode?: FitToViewMode;
|
|
20
|
+
minScale?: number;
|
|
21
|
+
maxScale?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface PanZoomZoomToOptions extends PanZoomAnimationOptions {
|
|
24
|
+
anchor?: PanZoomPoint;
|
|
25
|
+
}
|
|
26
|
+
export type PanZoomZoomToElementOptions = ZoomToElementOptions;
|
|
27
|
+
export interface PanZoomRef {
|
|
28
|
+
reset: (options?: PanZoomAnimationOptions) => Promise<void>;
|
|
29
|
+
fit: (options?: PanZoomFitOptions) => Promise<void>;
|
|
30
|
+
setTransform: (transform: PanZoomTransform, options?: PanZoomAnimationOptions) => Promise<void>;
|
|
31
|
+
zoomIn: (step?: number, options?: PanZoomAnimationOptions) => Promise<void>;
|
|
32
|
+
zoomOut: (step?: number, options?: PanZoomAnimationOptions) => Promise<void>;
|
|
33
|
+
zoomTo: (scale: number, options?: PanZoomZoomToOptions) => Promise<void>;
|
|
34
|
+
zoomToElement: (target: ZoomToElementTarget | ZoomToElementTarget[], options?: PanZoomZoomToElementOptions) => Promise<void>;
|
|
35
|
+
panBy: (deltaX: number, deltaY: number, options?: PanZoomAnimationOptions) => Promise<void>;
|
|
36
|
+
clientToContent: (clientX: number, clientY: number) => PanZoomPoint;
|
|
37
|
+
contentToClient: (x: number, y: number) => PanZoomPoint;
|
|
38
|
+
getTransform: () => PanZoomTransform;
|
|
39
|
+
getViewportElement: () => HTMLDivElement | null;
|
|
40
|
+
getContentElement: () => HTMLDivElement | null;
|
|
41
|
+
}
|
|
42
|
+
export type PanZoomWheelMode = 'modifier' | 'always' | 'disabled';
|
|
43
|
+
export interface PanZoomProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'defaultValue' | 'onChange'> {
|
|
44
|
+
children: ReactNode;
|
|
45
|
+
value?: PanZoomTransform;
|
|
46
|
+
defaultValue?: PanZoomTransform;
|
|
47
|
+
onTransformChange?: (transform: PanZoomTransform, details: PanZoomChangeDetails) => void;
|
|
48
|
+
minScale?: number;
|
|
49
|
+
maxScale?: number;
|
|
50
|
+
wheel?: PanZoomWheelMode;
|
|
51
|
+
pinch?: boolean;
|
|
52
|
+
pan?: boolean;
|
|
53
|
+
keyboard?: boolean;
|
|
54
|
+
keyboardPanStep?: number;
|
|
55
|
+
keyboardZoomStep?: number;
|
|
56
|
+
doubleClickZoom?: boolean;
|
|
57
|
+
disabled?: boolean;
|
|
58
|
+
readOnly?: boolean;
|
|
59
|
+
limitToBounds?: boolean;
|
|
60
|
+
centerZoomedOut?: boolean;
|
|
61
|
+
centerOnInit?: boolean;
|
|
62
|
+
fitOnInit?: boolean | FitToViewMode;
|
|
63
|
+
viewportClassName?: string;
|
|
64
|
+
contentClassName?: string;
|
|
65
|
+
viewportStyle?: CSSProperties;
|
|
66
|
+
contentStyle?: CSSProperties;
|
|
67
|
+
viewportProps?: Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'>;
|
|
68
|
+
contentProps?: Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'>;
|
|
69
|
+
instructions?: string;
|
|
70
|
+
}
|
|
71
|
+
export declare const PanZoom: import("react").ForwardRefExoticComponent<PanZoomProps & import("react").RefAttributes<PanZoomRef>>;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
|
|
3
|
+
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useRef, useState, } from 'react';
|
|
4
|
+
import { PencilSurface } from '../PencilSurface.js';
|
|
5
|
+
const defaultTransform = { x: 0, y: 0, scale: 1 };
|
|
6
|
+
const interactionExclusions = [
|
|
7
|
+
'button',
|
|
8
|
+
'a',
|
|
9
|
+
'input',
|
|
10
|
+
'select',
|
|
11
|
+
'textarea',
|
|
12
|
+
];
|
|
13
|
+
function clampScale(value, minScale, maxScale) {
|
|
14
|
+
return Math.min(maxScale, Math.max(minScale, value));
|
|
15
|
+
}
|
|
16
|
+
function normalizedTransform(value, minScale, maxScale) {
|
|
17
|
+
return {
|
|
18
|
+
x: Number.isFinite(value.x) ? value.x : 0,
|
|
19
|
+
y: Number.isFinite(value.y) ? value.y : 0,
|
|
20
|
+
scale: clampScale(Number.isFinite(value.scale) ? value.scale : 1, minScale, maxScale),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function transformsEqual(left, right) {
|
|
24
|
+
return left.x === right.x && left.y === right.y && left.scale === right.scale;
|
|
25
|
+
}
|
|
26
|
+
function prefersReducedMotion(element) {
|
|
27
|
+
return element?.ownerDocument.defaultView?.matchMedia('(prefers-reduced-motion: reduce)').matches ?? false;
|
|
28
|
+
}
|
|
29
|
+
function PanZoomRoot({ children, value, defaultValue = defaultTransform, onTransformChange, minScale = 0.25, maxScale = 8, wheel = 'modifier', pinch = true, pan = true, keyboard = true, keyboardPanStep = 48, keyboardZoomStep = 0.25, doubleClickZoom = false, disabled = false, readOnly = false, limitToBounds = true, centerZoomedOut = true, centerOnInit = false, fitOnInit = false, className, viewportClassName, contentClassName, style, viewportStyle, contentStyle, viewportProps, contentProps, instructions, 'aria-label': ariaLabel = 'Pan and zoom content', ...props }, forwardedRef) {
|
|
30
|
+
const resolvedMinScale = Math.max(Number.isFinite(minScale) ? minScale : 0.25, 0.0001);
|
|
31
|
+
const resolvedMaxScale = Math.max(Number.isFinite(maxScale) ? maxScale : 8, resolvedMinScale);
|
|
32
|
+
const controlled = value !== undefined;
|
|
33
|
+
const initialTransform = normalizedTransform(value ?? defaultValue, resolvedMinScale, resolvedMaxScale);
|
|
34
|
+
const [uncontrolledTransform, setUncontrolledTransform] = useState(initialTransform);
|
|
35
|
+
const visibleTransform = normalizedTransform(value ?? uncontrolledTransform, resolvedMinScale, resolvedMaxScale);
|
|
36
|
+
const engineRef = useRef(null);
|
|
37
|
+
const instructionsId = useId();
|
|
38
|
+
const committedRef = useRef(initialTransform);
|
|
39
|
+
const programmaticRef = useRef(false);
|
|
40
|
+
const pointerBlocksPanRef = useRef(false);
|
|
41
|
+
const wheelTargetBlocksZoomRef = useRef(false);
|
|
42
|
+
const animationDuration = useCallback((duration, fallback) => {
|
|
43
|
+
if (duration !== undefined)
|
|
44
|
+
return duration;
|
|
45
|
+
return prefersReducedMotion(engineRef.current?.instance.wrapperComponent ?? null) ? 0 : fallback;
|
|
46
|
+
}, []);
|
|
47
|
+
const syncExternalTransform = useCallback((next, duration = 0) => {
|
|
48
|
+
const normalized = normalizedTransform(next, resolvedMinScale, resolvedMaxScale);
|
|
49
|
+
committedRef.current = normalized;
|
|
50
|
+
programmaticRef.current = true;
|
|
51
|
+
const engine = engineRef.current;
|
|
52
|
+
if (!engine)
|
|
53
|
+
return;
|
|
54
|
+
void engine.setTransform(normalized.x, normalized.y, normalized.scale, duration)
|
|
55
|
+
.finally(() => {
|
|
56
|
+
programmaticRef.current = false;
|
|
57
|
+
});
|
|
58
|
+
}, [resolvedMaxScale, resolvedMinScale]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (!controlled || transformsEqual(visibleTransform, committedRef.current))
|
|
61
|
+
return;
|
|
62
|
+
syncExternalTransform(visibleTransform);
|
|
63
|
+
}, [controlled, syncExternalTransform, visibleTransform.x, visibleTransform.y, visibleTransform.scale]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const clamped = normalizedTransform(committedRef.current, resolvedMinScale, resolvedMaxScale);
|
|
66
|
+
if (!transformsEqual(clamped, committedRef.current))
|
|
67
|
+
syncExternalTransform(clamped);
|
|
68
|
+
}, [resolvedMaxScale, resolvedMinScale, syncExternalTransform]);
|
|
69
|
+
const runProgrammatic = useCallback(async (action) => {
|
|
70
|
+
const engine = engineRef.current;
|
|
71
|
+
if (!engine || disabled)
|
|
72
|
+
return;
|
|
73
|
+
programmaticRef.current = true;
|
|
74
|
+
try {
|
|
75
|
+
await action(engine);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
programmaticRef.current = false;
|
|
79
|
+
}
|
|
80
|
+
}, [disabled]);
|
|
81
|
+
const reconcileControlled = useCallback(() => {
|
|
82
|
+
if (controlled && !transformsEqual(visibleTransform, committedRef.current)) {
|
|
83
|
+
syncExternalTransform(visibleTransform, animationDuration(undefined, 100));
|
|
84
|
+
}
|
|
85
|
+
}, [animationDuration, controlled, syncExternalTransform, visibleTransform.x, visibleTransform.y, visibleTransform.scale]);
|
|
86
|
+
useImperativeHandle(forwardedRef, () => ({
|
|
87
|
+
reset: options => runProgrammatic(engine => engine.resetTransform(animationDuration(options?.duration, 200))),
|
|
88
|
+
fit: options => runProgrammatic(engine => engine.fitToView({
|
|
89
|
+
mode: options?.mode,
|
|
90
|
+
minScale: options?.minScale,
|
|
91
|
+
maxScale: options?.maxScale,
|
|
92
|
+
animationTime: animationDuration(options?.duration, 200),
|
|
93
|
+
})),
|
|
94
|
+
setTransform: (transform, options) => runProgrammatic(engine => {
|
|
95
|
+
const next = normalizedTransform(transform, resolvedMinScale, resolvedMaxScale);
|
|
96
|
+
return engine.setTransform(next.x, next.y, next.scale, animationDuration(options?.duration, 200));
|
|
97
|
+
}),
|
|
98
|
+
zoomIn: (step = keyboardZoomStep, options) => runProgrammatic(engine => engine.zoomIn(step, animationDuration(options?.duration, 200))),
|
|
99
|
+
zoomOut: (step = keyboardZoomStep, options) => runProgrammatic(engine => engine.zoomOut(step, animationDuration(options?.duration, 200))),
|
|
100
|
+
zoomTo: (scale, options) => runProgrammatic((engine) => {
|
|
101
|
+
const nextScale = clampScale(scale, resolvedMinScale, resolvedMaxScale);
|
|
102
|
+
if (options?.anchor) {
|
|
103
|
+
return engine.zoomToPoint(nextScale, options.anchor.x, options.anchor.y, animationDuration(options.duration, 200));
|
|
104
|
+
}
|
|
105
|
+
return engine.centerView(nextScale, animationDuration(options?.duration, 200));
|
|
106
|
+
}),
|
|
107
|
+
zoomToElement: (target, options) => runProgrammatic(engine => engine.zoomToElement(target, {
|
|
108
|
+
...options,
|
|
109
|
+
animationTime: animationDuration(options?.animationTime, 300),
|
|
110
|
+
})),
|
|
111
|
+
panBy: (deltaX, deltaY, options) => runProgrammatic(engine => engine.panBy(deltaX, deltaY, animationDuration(options?.duration, 160))),
|
|
112
|
+
clientToContent: (clientX, clientY) => engineRef.current?.clientToContent(clientX, clientY) ?? { x: clientX, y: clientY },
|
|
113
|
+
contentToClient: (x, y) => engineRef.current?.contentToClient(x, y) ?? { x, y },
|
|
114
|
+
getTransform: () => committedRef.current,
|
|
115
|
+
getViewportElement: () => engineRef.current?.instance.wrapperComponent ?? null,
|
|
116
|
+
getContentElement: () => engineRef.current?.instance.contentComponent ?? null,
|
|
117
|
+
}), [animationDuration, keyboardZoomStep, resolvedMaxScale, resolvedMinScale, runProgrammatic]);
|
|
118
|
+
const userInteractionDisabled = disabled || readOnly;
|
|
119
|
+
const wheelActivation = wheel === 'modifier'
|
|
120
|
+
? (keys) => !wheelTargetBlocksZoomRef.current && (keys.includes('Control') || keys.includes('Meta'))
|
|
121
|
+
: () => !wheelTargetBlocksZoomRef.current;
|
|
122
|
+
const defaultInstructions = wheel === 'modifier'
|
|
123
|
+
? 'Use Control or Command with the mouse wheel to zoom. Use arrow keys to pan, plus or minus to zoom, and 0 to reset.'
|
|
124
|
+
: 'Use arrow keys to pan, plus or minus to zoom, and 0 to reset.';
|
|
125
|
+
const wheelHint = instructions ?? defaultInstructions;
|
|
126
|
+
const mergedViewportLabel = viewportProps?.['aria-label'] ?? ariaLabel;
|
|
127
|
+
const describedBy = [viewportProps?.['aria-describedby'], keyboard && !disabled ? instructionsId : null]
|
|
128
|
+
.filter(Boolean)
|
|
129
|
+
.join(' ') || undefined;
|
|
130
|
+
return _jsxs("div", { ...props, className: ['inkra-pan-zoom', className].filter(Boolean).join(' '), "data-disabled": disabled || undefined, "data-gestures": !userInteractionDisabled && (pan || pinch) || undefined, "data-read-only": readOnly || undefined, "data-wheel": wheel, style: style, children: [_jsx(PencilSurface, { "aria-hidden": "true", className: "inkra-pan-zoom__surface", radius: 8, variant: "paper" }), _jsx("div", { className: "inkra-pan-zoom__clip", children: _jsx(TransformWrapper, { ref: engineRef, initialScale: initialTransform.scale, initialPositionX: initialTransform.x, initialPositionY: initialTransform.y, minScale: resolvedMinScale, maxScale: resolvedMaxScale, limitToBounds: limitToBounds, centerZoomedOut: centerZoomedOut, centerOnInit: centerOnInit, fitOnInit: fitOnInit, smooth: true, panning: {
|
|
131
|
+
disabled: userInteractionDisabled || !pan,
|
|
132
|
+
excluded: interactionExclusions,
|
|
133
|
+
activationKeys: () => !pointerBlocksPanRef.current,
|
|
134
|
+
}, pinch: { disabled: userInteractionDisabled || !pinch, excluded: interactionExclusions }, wheel: {
|
|
135
|
+
disabled: userInteractionDisabled || wheel === 'disabled',
|
|
136
|
+
activationKeys: wheelActivation,
|
|
137
|
+
excluded: interactionExclusions,
|
|
138
|
+
}, trackPadPanning: { disabled: true }, keyboard: {
|
|
139
|
+
disabled: userInteractionDisabled || !keyboard,
|
|
140
|
+
panStep: keyboardPanStep,
|
|
141
|
+
zoomStep: keyboardZoomStep,
|
|
142
|
+
animationTime: 100,
|
|
143
|
+
excluded: interactionExclusions,
|
|
144
|
+
}, doubleClick: { disabled: userInteractionDisabled || !doubleClickZoom, mode: 'zoomIn', excluded: interactionExclusions }, zoomAnimation: { disabled: false, animationTime: 200 }, velocityAnimation: { disabled: prefersReducedMotion(engineRef.current?.instance.wrapperComponent ?? null) }, onPanningStop: reconcileControlled, onPinchStop: reconcileControlled, onWheelStop: reconcileControlled, onZoomStop: reconcileControlled, onTransform: (_, state) => {
|
|
145
|
+
const next = normalizedTransform({ x: state.positionX, y: state.positionY, scale: state.scale }, resolvedMinScale, resolvedMaxScale);
|
|
146
|
+
committedRef.current = next;
|
|
147
|
+
if (!controlled)
|
|
148
|
+
setUncontrolledTransform(next);
|
|
149
|
+
onTransformChange?.(next, { reason: programmaticRef.current ? 'programmatic' : 'gesture' });
|
|
150
|
+
}, children: _jsx(TransformComponent, { wrapperClass: ['inkra-pan-zoom__viewport', viewportClassName].filter(Boolean).join(' '), contentClass: ['inkra-pan-zoom__content', contentClassName].filter(Boolean).join(' '), wrapperStyle: viewportStyle, contentStyle: contentStyle, wrapperProps: {
|
|
151
|
+
...viewportProps,
|
|
152
|
+
role: viewportProps?.role ?? 'region',
|
|
153
|
+
'aria-label': mergedViewportLabel,
|
|
154
|
+
'aria-disabled': disabled || undefined,
|
|
155
|
+
'aria-readonly': readOnly || undefined,
|
|
156
|
+
'aria-describedby': describedBy,
|
|
157
|
+
onPointerDownCapture: event => {
|
|
158
|
+
pointerBlocksPanRef.current = Boolean(event.target.closest?.('[data-pan-zoom-no-drag]'));
|
|
159
|
+
viewportProps?.onPointerDownCapture?.(event);
|
|
160
|
+
},
|
|
161
|
+
onPointerUpCapture: event => {
|
|
162
|
+
pointerBlocksPanRef.current = false;
|
|
163
|
+
viewportProps?.onPointerUpCapture?.(event);
|
|
164
|
+
},
|
|
165
|
+
onPointerCancelCapture: event => {
|
|
166
|
+
pointerBlocksPanRef.current = false;
|
|
167
|
+
viewportProps?.onPointerCancelCapture?.(event);
|
|
168
|
+
},
|
|
169
|
+
onWheelCapture: event => {
|
|
170
|
+
wheelTargetBlocksZoomRef.current = Boolean(event.target.closest?.('[contenteditable], [data-pan-zoom-no-drag]'));
|
|
171
|
+
viewportProps?.onWheelCapture?.(event);
|
|
172
|
+
},
|
|
173
|
+
}, contentProps: contentProps, children: children }) }) }), _jsx(PencilSurface, { "aria-hidden": "true", className: "inkra-pan-zoom__focus-ring", radius: 8, seed: "pan-zoom-focus", variant: "outline" }), keyboard && !disabled && _jsx("span", { className: "inkra-pan-zoom__instructions visually-hidden", id: instructionsId, children: wheelHint })] });
|
|
174
|
+
}
|
|
175
|
+
export const PanZoom = forwardRef(PanZoomRoot);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type RadarKey = string | number;
|
|
3
|
+
export interface RadarAxis {
|
|
4
|
+
id: RadarKey;
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
min?: number;
|
|
7
|
+
max?: number;
|
|
8
|
+
ariaLabel?: string;
|
|
9
|
+
formatValue?: (value: number) => string;
|
|
10
|
+
}
|
|
11
|
+
export interface RadarPoint {
|
|
12
|
+
axisId: RadarKey;
|
|
13
|
+
value?: number | null;
|
|
14
|
+
label?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export interface RadarSeries {
|
|
17
|
+
id: RadarKey;
|
|
18
|
+
label: ReactNode;
|
|
19
|
+
data: readonly RadarPoint[];
|
|
20
|
+
color?: string;
|
|
21
|
+
pattern?: 'solid' | 'dash' | 'dot';
|
|
22
|
+
hidden?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface RadarValueContext {
|
|
25
|
+
axis: RadarAxis;
|
|
26
|
+
series: RadarSeries;
|
|
27
|
+
point: RadarPoint;
|
|
28
|
+
value: number | null;
|
|
29
|
+
missing: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface RadarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'onChange'> {
|
|
32
|
+
axes: readonly RadarAxis[];
|
|
33
|
+
series: readonly RadarSeries[];
|
|
34
|
+
label: ReactNode;
|
|
35
|
+
description?: ReactNode;
|
|
36
|
+
size?: number | string;
|
|
37
|
+
maxRadius?: number;
|
|
38
|
+
levels?: number;
|
|
39
|
+
showAxes?: boolean;
|
|
40
|
+
showLabels?: boolean;
|
|
41
|
+
showLegend?: boolean;
|
|
42
|
+
showValues?: boolean;
|
|
43
|
+
showTable?: boolean;
|
|
44
|
+
legendLabel?: ReactNode;
|
|
45
|
+
tableCaption?: ReactNode;
|
|
46
|
+
seriesLabel?: ReactNode;
|
|
47
|
+
missingLabel?: string;
|
|
48
|
+
emptyMessage?: ReactNode;
|
|
49
|
+
selectedSeries?: RadarKey | null;
|
|
50
|
+
defaultSelectedSeries?: RadarKey | null;
|
|
51
|
+
onSelectedSeriesChange?: (id: RadarKey | null, series: RadarSeries | null) => void;
|
|
52
|
+
renderAxisLabel?: (axis: RadarAxis) => ReactNode;
|
|
53
|
+
renderValueLabel?: (context: RadarValueContext) => ReactNode;
|
|
54
|
+
getValueLabel?: (value: number, axis: RadarAxis) => string;
|
|
55
|
+
}
|
|
56
|
+
export declare const Radar: import("react").ForwardRefExoticComponent<RadarProps & import("react").RefAttributes<HTMLDivElement>>;
|