reshaped 3.0.8-rc.1 → 3.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/bin/cli.js +0 -1
- package/dist/bundle.css +1 -1
- package/dist/bundle.d.ts +3 -1
- package/dist/bundle.js +10 -10
- package/dist/cjs/themes/_generator/utilities/color.d.ts +16 -0
- package/dist/cjs/themes/_generator/utilities/color.js +57 -7
- package/dist/cjs/themes/_generator/utilities/generateBackgroundColors.js +4 -0
- package/dist/cjs/themes/_generator/utilities/tests/color.test.js +73 -42
- package/dist/cjs/themes/index.d.ts +17 -0
- package/dist/cjs/themes/index.js +3 -0
- package/dist/cjs/types/config.d.ts +1 -0
- package/dist/components/Button/Button.module.css +1 -1
- package/dist/components/Button/tests/Button.stories.js +3 -1
- package/dist/components/Card/Card.module.css +1 -1
- package/dist/components/Checkbox/Checkbox.module.css +1 -1
- package/dist/components/Dismissible/Dismissible.module.css +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.d.ts +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.module.css +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +1 -1
- package/dist/components/DropdownMenu/tests/DropdownMenu.stories.d.ts +1 -0
- package/dist/components/Modal/Modal.js +4 -3
- package/dist/components/Modal/tests/Modal.stories.js +1 -1
- package/dist/components/Overlay/Overlay.js +7 -7
- package/dist/components/Overlay/tests/Overlay.stories.js +3 -1
- package/dist/components/Popover/Popover.d.ts +2 -0
- package/dist/components/Popover/Popover.js +9 -3
- package/dist/components/Popover/Popover.types.d.ts +1 -1
- package/dist/components/Popover/tests/Popover.stories.d.ts +2 -0
- package/dist/components/Popover/tests/Popover.stories.js +16 -0
- package/dist/components/Radio/Radio.module.css +1 -1
- package/dist/components/Resizable/Resizable.d.ts +8 -0
- package/dist/components/Resizable/Resizable.js +149 -0
- package/dist/components/Resizable/Resizable.module.css +1 -0
- package/dist/components/Resizable/Resizable.types.d.ts +29 -0
- package/dist/components/Resizable/Resizable.types.js +1 -0
- package/dist/components/Resizable/index.d.ts +2 -0
- package/dist/components/Resizable/index.js +1 -0
- package/dist/components/Resizable/tests/Resizable.stories.d.ts +15 -0
- package/dist/components/Resizable/tests/Resizable.stories.js +58 -0
- package/dist/components/ScrollArea/ScrollArea.js +4 -4
- package/dist/components/Slider/Slider.module.css +1 -1
- package/dist/components/Slider/Slider.types.d.ts +2 -2
- package/dist/components/Slider/Slider.utilities.js +4 -4
- package/dist/components/Slider/SliderControlled.js +11 -9
- package/dist/components/Slider/SliderThumb.js +1 -1
- package/dist/components/Slider/tests/Slider.stories.js +4 -0
- package/dist/components/Switch/Switch.module.css +1 -1
- package/dist/components/Toast/Toast.types.d.ts +7 -6
- package/dist/components/Toast/index.d.ts +1 -1
- package/dist/components/Toast/useToast.d.ts +1 -1
- package/dist/components/Tooltip/tests/Tooltip.stories.js +31 -0
- package/dist/components/_private/Flyout/Flyout.context.d.ts +3 -1
- package/dist/components/_private/Flyout/Flyout.context.js +4 -1
- package/dist/components/_private/Flyout/Flyout.types.d.ts +1 -0
- package/dist/components/_private/Flyout/FlyoutContent.js +5 -7
- package/dist/components/_private/Flyout/FlyoutControlled.js +20 -14
- package/dist/components/_private/Flyout/FlyoutTrigger.js +3 -2
- package/dist/components/_private/Flyout/tests/Flyout.stories.d.ts +2 -7
- package/dist/components/_private/Flyout/tests/Flyout.stories.js +125 -49
- package/dist/components/_private/Portal/Portal.module.css +1 -1
- package/dist/hooks/_private/useOnClickOutside.js +5 -3
- package/dist/hooks/tests/useDrag.stories.d.ts +6 -0
- package/dist/hooks/tests/useDrag.stories.js +29 -0
- package/dist/hooks/useDrag.d.ts +17 -0
- package/dist/hooks/useDrag.js +116 -0
- package/dist/hooks/useHandlerRef.d.ts +8 -0
- package/dist/hooks/useHandlerRef.js +16 -0
- package/dist/hooks/useScrollLock.js +4 -3
- package/dist/hooks/useToggle.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/themes/_generator/tests/themes.stories.js +23 -0
- package/dist/themes/_generator/utilities/color.d.ts +16 -0
- package/dist/themes/_generator/utilities/color.js +54 -6
- package/dist/themes/_generator/utilities/generateBackgroundColors.js +4 -0
- package/dist/themes/index.d.ts +17 -0
- package/dist/themes/index.js +3 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/global.d.ts +1 -1
- package/package.json +1 -1
@@ -1,18 +1,24 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
2
|
import { classNames } from "../../utilities/helpers.js";
|
3
|
-
import Flyout from "../_private/Flyout/index.js";
|
3
|
+
import Flyout, { useFlyoutContext } from "../_private/Flyout/index.js";
|
4
|
+
import Dismissible from "../Dismissible/index.js";
|
4
5
|
import s from "./Popover.module.css";
|
5
6
|
import getPaddingStyles from "../../styles/padding/index.js";
|
6
7
|
const Popover = (props) => {
|
7
|
-
const { id, forcePosition, onOpen, onClose, active, defaultActive, children, width, contentGap, variant = "elevated", triggerType = "click", position = "bottom", disableHideAnimation, disableContentHover, instanceRef, containerRef, } = props;
|
8
|
+
const { id, forcePosition, onOpen, onClose, active, defaultActive, children, width, contentGap, variant = "elevated", triggerType = "click", position = "bottom", disableHideAnimation, disableContentHover, disableCloseOnOutsideClick, instanceRef, containerRef, } = props;
|
8
9
|
const padding = props.padding ?? (variant === "headless" ? 0 : 4);
|
9
10
|
const trapFocusMode = props.trapFocusMode || (triggerType === "hover" ? "content-menu" : undefined);
|
10
11
|
const paddingStyles = getPaddingStyles(padding);
|
11
12
|
const contentClassName = classNames(s.content, !!width && s["content--has-width"], variant && s[`content--variant-${variant}`], paddingStyles?.classNames);
|
12
13
|
return (
|
13
14
|
// @ts-ignore
|
14
|
-
_jsx(Flyout, { id: id, instanceRef: instanceRef, position: position, forcePosition: forcePosition, onOpen: onOpen, onClose: onClose, trapFocusMode: trapFocusMode, triggerType: triggerType, active: active, defaultActive: defaultActive, width: width, disableHideAnimation: disableHideAnimation, disableContentHover: disableContentHover, contentGap: contentGap, containerRef: containerRef, contentClassName: contentClassName, contentAttributes: { style: { ...paddingStyles?.variables } }, children: children }));
|
15
|
+
_jsx(Flyout, { id: id, instanceRef: instanceRef, position: position, forcePosition: forcePosition, onOpen: onOpen, onClose: onClose, trapFocusMode: trapFocusMode, triggerType: triggerType, active: active, defaultActive: defaultActive, width: width, disableHideAnimation: disableHideAnimation, disableContentHover: disableContentHover, disableCloseOnOutsideClick: disableCloseOnOutsideClick, contentGap: contentGap, containerRef: containerRef, contentClassName: contentClassName, contentAttributes: { style: { ...paddingStyles?.variables } }, children: children }));
|
15
16
|
};
|
17
|
+
const PopoverDismissible = (props) => {
|
18
|
+
const { handleClose } = useFlyoutContext();
|
19
|
+
return _jsx(Dismissible, { ...props, onClose: handleClose });
|
20
|
+
};
|
21
|
+
Popover.Dismissible = PopoverDismissible;
|
16
22
|
Popover.Trigger = Flyout.Trigger;
|
17
23
|
Popover.Content = Flyout.Content;
|
18
24
|
export default Popover;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type React from "react";
|
2
2
|
import type { FlyoutProps, FlyoutInstance } from "../_private/Flyout";
|
3
3
|
export type Instance = FlyoutInstance;
|
4
|
-
export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "onOpen" | "onClose" | "width" | "trapFocusMode" | "active" | "defaultActive" | "contentGap" | "instanceRef" | "triggerType" | "disableHideAnimation" | "disableContentHover" | "containerRef"> & {
|
4
|
+
export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "onOpen" | "onClose" | "width" | "trapFocusMode" | "active" | "defaultActive" | "contentGap" | "instanceRef" | "triggerType" | "disableHideAnimation" | "disableContentHover" | "disableCloseOnOutsideClick" | "containerRef"> & {
|
5
5
|
children?: React.ReactNode;
|
6
6
|
padding?: number;
|
7
7
|
variant?: "elevated" | "headless";
|
@@ -2,6 +2,7 @@ declare const _default: {
|
|
2
2
|
title: string;
|
3
3
|
component: {
|
4
4
|
(props: import("./..").PopoverProps): import("react").JSX.Element;
|
5
|
+
Dismissible: (props: import("../../Dismissible").DismissibleProps) => import("react").JSX.Element;
|
5
6
|
Trigger: (props: import("../../_private/Flyout").FlyoutTriggerProps) => import("react").JSX.Element;
|
6
7
|
Content: (props: import("../../_private/Flyout").FlyoutContentProps) => import("react").JSX.Element | null;
|
7
8
|
};
|
@@ -17,4 +18,5 @@ export declare const width: () => import("react").JSX.Element;
|
|
17
18
|
export declare const variant: () => import("react").JSX.Element;
|
18
19
|
export declare const padding: () => import("react").JSX.Element;
|
19
20
|
export declare const triggerType: () => import("react").JSX.Element;
|
21
|
+
export declare const dismissible: () => import("react").JSX.Element;
|
20
22
|
export declare const edgeCases: () => import("react").JSX.Element;
|
@@ -94,6 +94,22 @@ export const triggerType = () => (<Example>
|
|
94
94
|
<Demo triggerType="hover"/>
|
95
95
|
</Example.Item>
|
96
96
|
</Example>);
|
97
|
+
export const dismissible = () => {
|
98
|
+
return (<Example>
|
99
|
+
<Example.Item title="with dismissible">
|
100
|
+
<Popover>
|
101
|
+
<Popover.Trigger>
|
102
|
+
{(attributes) => <Button attributes={attributes}>Open</Button>}
|
103
|
+
</Popover.Trigger>
|
104
|
+
<Popover.Content>
|
105
|
+
<Popover.Dismissible closeAriaLabel="Close" align="center">
|
106
|
+
Popover content
|
107
|
+
</Popover.Dismissible>
|
108
|
+
</Popover.Content>
|
109
|
+
</Popover>
|
110
|
+
</Example.Item>
|
111
|
+
</Example>);
|
112
|
+
};
|
97
113
|
export const edgeCases = () => (<Example>
|
98
114
|
<Example.Item title="Popover with tooltip">
|
99
115
|
<Tooltip position="top" text="Hello">
|
@@ -1 +1 @@
|
|
1
|
-
.root{align-items:center;cursor:pointer;display:inline-flex;user-select:none;vertical-align:top;-webkit-tap-highlight-color:transparent}.root:hover .input:not(:checked)+.decorator{background:var(--rs-color-background-neutral-faded)}.field{position:relative}.decorator{--rs-radio-decorator-size:var(--rs-line-height-body-3);background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);border-radius:50%;height:var(--rs-radio-decorator-size);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:background-color,border-color;width:var(--rs-radio-decorator-size)}.decorator:after{background:var(--rs-color-on-background-primary);border-radius:50%;content:"";height:calc(var(--rs-radio-decorator-size) * .4);left:50%;opacity:0;position:absolute;top:50%;transform:translate(-50%,-50%) scale(0);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;width:calc(var(--rs-radio-decorator-size) * .4)}
|
1
|
+
.root{align-items:center;cursor:pointer;display:inline-flex;user-select:none;vertical-align:top;-webkit-tap-highlight-color:transparent}.root:hover .input:not(:checked)+.decorator{background:var(--rs-color-background-neutral-faded)}.field{position:relative}.decorator{--rs-radio-decorator-size:var(--rs-line-height-body-3);background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);border-radius:50%;height:var(--rs-radio-decorator-size);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:background-color,border-color;width:var(--rs-radio-decorator-size)}.decorator:after{background:var(--rs-color-on-background-primary);border-radius:50%;content:"";height:calc(var(--rs-radio-decorator-size) * .4);left:50%;opacity:0;position:absolute;top:50%;transform:translate(-50%,-50%) scale(0);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;width:calc(var(--rs-radio-decorator-size) * .4)}.input:focus-visible+.decorator{box-shadow:var(--rs-focus-shadow)}.input:checked+.decorator,.root.--error .input:checked+.decorator,.root.--error:hover .input:checked+.decorator{background:var(--rs-color-background-primary);border-color:var(--rs-color-background-primary);border-width:2px}.input:checked+.decorator:after,.root.--error .input:checked+.decorator:after,.root.--error:hover .input:checked+.decorator:after{opacity:1;transform:translate(-50%,-50%) scale(1)}.text{margin-inline-start:var(--rs-unit-x2)}.root.--error .decorator,.root.--error:hover .input+.decorator{border-color:var(--rs-color-border-critical)}.root.--disabled{color:var(--rs-color-foreground-disabled);cursor:not-allowed}.root.--disabled .decorator,.root.--disabled .input:checked+.decorator,.root.--disabled:hover .input+.decorator{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled .input:checked+.decorator{border-color:transparent}.root.--disabled .input:checked+.decorator:after{background:var(--rs-color-border-disabled)}
|
@@ -0,0 +1,149 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
import React from "react";
|
4
|
+
import { classNames } from "../../utilities/helpers.js";
|
5
|
+
import useDrag from "../../hooks/useDrag.js";
|
6
|
+
import View from "../View/index.js";
|
7
|
+
import s from "./Resizable.module.css";
|
8
|
+
const PrivateResizableHandle = (props) => {
|
9
|
+
const { containerRef, onDrag, index, direction, children } = props;
|
10
|
+
const { ref, active } = useDrag((args) => {
|
11
|
+
onDrag({ ...args, index });
|
12
|
+
}, {
|
13
|
+
containerRef,
|
14
|
+
orientation: direction === "row" ? "horizontal" : "vertical",
|
15
|
+
});
|
16
|
+
const handleClassNames = classNames(s.handle, active && s["handle--dragging"]);
|
17
|
+
if (children)
|
18
|
+
return _jsx(View.Item, { children: children({ ref }) });
|
19
|
+
return (_jsx(View.Item, { className: handleClassNames, attributes: {
|
20
|
+
role: "button",
|
21
|
+
tabIndex: 0,
|
22
|
+
ref: (el) => {
|
23
|
+
// @ts-ignore
|
24
|
+
ref.current = el;
|
25
|
+
},
|
26
|
+
} }));
|
27
|
+
};
|
28
|
+
const PrivateResizableItem = React.forwardRef((props, ref) => {
|
29
|
+
const { children, defaultSize, minSize, maxSize } = props;
|
30
|
+
const itemRef = React.useRef(null);
|
31
|
+
return (_jsx(View.Item, { grow: true, className: s.item, attributes: {
|
32
|
+
ref: (el) => {
|
33
|
+
if (typeof ref === "function")
|
34
|
+
ref(el);
|
35
|
+
itemRef.current = el;
|
36
|
+
},
|
37
|
+
style: {
|
38
|
+
"--rs-resizable-default-size": defaultSize,
|
39
|
+
"--rs-resizable-min-size": minSize,
|
40
|
+
"--rs-resizable-max-size": maxSize,
|
41
|
+
},
|
42
|
+
}, children: children }));
|
43
|
+
});
|
44
|
+
const Resizable = (props) => {
|
45
|
+
const { children, height, direction = "row", gap = 2, className, attributes } = props;
|
46
|
+
const rootClassNames = classNames(s.root, s[`--direction-${direction}`], className);
|
47
|
+
const containerRef = React.useRef(null);
|
48
|
+
const itemsRef = React.useRef([]);
|
49
|
+
const horizontal = direction === "row";
|
50
|
+
let currentHandleIndex = 0;
|
51
|
+
let currentItemIndex = 0;
|
52
|
+
itemsRef.current = [];
|
53
|
+
const checkedCrossedBoundaries = (args) => {
|
54
|
+
const { item, grow, itemsSize, itemsCount } = args;
|
55
|
+
const { minSize, maxSize } = item.props;
|
56
|
+
const nextPx = (grow / itemsCount / 100) * itemsSize;
|
57
|
+
const minPx = minSize && Number(minSize.replace("px", ""));
|
58
|
+
const maxPx = maxSize && Number(maxSize?.replace("px", ""));
|
59
|
+
if (minPx && minPx > nextPx)
|
60
|
+
return true;
|
61
|
+
if (maxPx && maxPx < nextPx)
|
62
|
+
return true;
|
63
|
+
return false;
|
64
|
+
};
|
65
|
+
const onDrag = (args) => {
|
66
|
+
const { index, x, y, triggerX, triggerY } = args;
|
67
|
+
const startItem = itemsRef.current[index];
|
68
|
+
const endItem = itemsRef.current[index + 1];
|
69
|
+
if (!startItem.el || !endItem.el)
|
70
|
+
return;
|
71
|
+
const itemsCount = itemsRef.current.length;
|
72
|
+
// Each item has a flex-grow of 1 as default and these values get updated while dragging for the items around the handle
|
73
|
+
// Grow value of all items besides currently updating ones
|
74
|
+
let currentItemsGrow = itemsCount * 100;
|
75
|
+
let itemsSize = 0;
|
76
|
+
itemsRef.current.forEach((item, i) => {
|
77
|
+
if (!item.el)
|
78
|
+
return;
|
79
|
+
itemsSize += horizontal ? item.el.clientWidth : item.el.clientHeight;
|
80
|
+
if (i === index || i === index + 1)
|
81
|
+
return;
|
82
|
+
currentItemsGrow -= Number(item.el.style.flexGrow || 100);
|
83
|
+
}, 0);
|
84
|
+
const startSize = horizontal ? startItem.el.clientWidth : startItem.el.clientHeight;
|
85
|
+
const startOffset = horizontal ? startItem.el.offsetLeft : startItem.el.offsetTop;
|
86
|
+
const endSize = horizontal ? endItem.el.clientWidth : endItem.el.clientHeight;
|
87
|
+
// Handles containing triggers are located lower based on the gap and padding inside the handle
|
88
|
+
const gapCompensation = (horizontal ? triggerX : triggerY) - startSize - startOffset;
|
89
|
+
const dragCoord = (horizontal ? x : y) - gapCompensation;
|
90
|
+
// Total size of the dragging area
|
91
|
+
const currentItemsSize = startSize + endSize;
|
92
|
+
// x is calculated based on container but we're changing grow based on current items
|
93
|
+
const percent = Math.min(1, Math.max(0, (dragCoord - startOffset) / currentItemsSize));
|
94
|
+
const nextStartGrow = Math.floor(percent * currentItemsGrow);
|
95
|
+
const nextEndGrow = Math.floor(currentItemsGrow - nextStartGrow);
|
96
|
+
// Validate that next grow values won't break the min/max size values
|
97
|
+
if (checkedCrossedBoundaries({ item: startItem, itemsSize, grow: nextStartGrow, itemsCount })) {
|
98
|
+
return;
|
99
|
+
}
|
100
|
+
if (checkedCrossedBoundaries({ item: endItem, itemsSize, grow: nextEndGrow, itemsCount })) {
|
101
|
+
return;
|
102
|
+
}
|
103
|
+
startItem.el.style.flexGrow = nextStartGrow.toString();
|
104
|
+
endItem.el.style.flexGrow = nextEndGrow.toString();
|
105
|
+
};
|
106
|
+
/**
|
107
|
+
* When passing sizes, items first get rendered with css
|
108
|
+
* and then have to be hydrated with flexGrow to enable correct resizing
|
109
|
+
*/
|
110
|
+
React.useEffect(() => {
|
111
|
+
const growValues = [];
|
112
|
+
// Calculate total size of items excluding gaps
|
113
|
+
let totalItemsSize = 0;
|
114
|
+
itemsRef.current.forEach((item) => {
|
115
|
+
if (!item.el)
|
116
|
+
return;
|
117
|
+
totalItemsSize += horizontal ? item.el.clientWidth : item.el.clientHeight;
|
118
|
+
});
|
119
|
+
// Calculate flex grow values of all items rendered by css originally
|
120
|
+
itemsRef.current.forEach((item, i) => {
|
121
|
+
if (!item.el)
|
122
|
+
return;
|
123
|
+
const itemSizePercent = (horizontal ? item.el.clientWidth : item.el.clientHeight) / totalItemsSize;
|
124
|
+
growValues[i] = itemsRef.current.length * itemSizePercent * 100;
|
125
|
+
});
|
126
|
+
// Apply flex grow after calculation is done to avoid layout shifts during the calculation
|
127
|
+
itemsRef.current.forEach((item, i) => {
|
128
|
+
if (!item.el || !growValues[i])
|
129
|
+
return;
|
130
|
+
item.el.style.flexGrow = growValues[i].toString();
|
131
|
+
item.el.setAttribute("data-rs-resizable-item-mounted", "");
|
132
|
+
});
|
133
|
+
}, [horizontal]);
|
134
|
+
const output = React.Children.map(children, (child) => {
|
135
|
+
const isComponent = React.isValidElement(child);
|
136
|
+
if (isComponent && child.type === Resizable.Handle && child.props) {
|
137
|
+
return (_jsx(PrivateResizableHandle, { ...child.props, containerRef: containerRef, index: currentHandleIndex++, onDrag: onDrag, direction: direction }));
|
138
|
+
}
|
139
|
+
if (isComponent && child.type === Resizable.Item && child.props) {
|
140
|
+
const index = currentHandleIndex;
|
141
|
+
return (_jsx(PrivateResizableItem, { ...child.props, index: currentItemIndex++, ref: (el) => (itemsRef.current[index] = { el, props: child.props }) }));
|
142
|
+
}
|
143
|
+
return null;
|
144
|
+
});
|
145
|
+
return (_jsx(View, { attributes: { ...attributes, ref: containerRef }, className: rootClassNames, height: height, direction: direction, align: "stretch", gap: gap, children: output }));
|
146
|
+
};
|
147
|
+
Resizable.Item = (() => null);
|
148
|
+
Resizable.Handle = (() => null);
|
149
|
+
export default Resizable;
|
@@ -0,0 +1 @@
|
|
1
|
+
.item{--rs-resizable-default-size:none;--rs-resizable-min-size:0;--rs-resizable-max-size:100%;flex-grow:100;max-width:var(--rs-resizable-default-size);min-width:var(--rs-resizable-default-size);overflow:hidden}.handle{flex-shrink:0;position:relative}.handle:after,.handle:before{border-radius:999px;content:"";position:absolute}.handle:after{background:var(--rs-color-border-neutral);opacity:0;transition:opacity var(--rs-duration-fast) var(--rs-easing-standard)}.handle--dragging:after,.handle:focus-visible:after,.handle:hover:after{opacity:.6}body:has(.handle--dragging) .handle:not(.handle--dragging){opacity:0}body:has(.--direction-row>.handle--dragging){cursor:ew-resize}body:has(.--direction-column>.handle--dragging){cursor:ns-resize}.--direction-row>.handle{cursor:ew-resize;height:100%}.--direction-row>.handle:after,.--direction-row>.handle:before{inset-block:0;inset-inline-start:50%;transform:translateX(-50%)}.--direction-row>.handle:before{width:var(--rs-unit-x4)}.--direction-row>.handle:after{width:var(--rs-unit-x1)}.--direction-row>.item[data-rs-resizable-item-mounted]{max-width:var(--rs-resizable-max-size);min-width:var(--rs-resizable-min-size)}.--direction-column>.handle{cursor:ns-resize;width:100%}.--direction-column>.handle:after,.--direction-column>.handle:before{inset-block-start:50%;inset-inline:0;transform:translateY(-50%)}.--direction-column>.handle:before{height:var(--rs-unit-x4)}.--direction-column>.handle:after{height:var(--rs-unit-x1)}.--direction-column>.item[data-rs-resizable-item-mounted]{max-height:var(--rs-resizable-max-size);min-height:var(--rs-resizable-min-size)}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import type React from "react";
|
2
|
+
import type { ViewProps } from "../View";
|
3
|
+
import type { UseDragCallbackArgs } from "../../hooks/useDrag";
|
4
|
+
export type Props = Pick<ViewProps, "children" | "className" | "attributes" | "height" | "direction" | "gap">;
|
5
|
+
export type ItemProps = {
|
6
|
+
children: React.ReactNode;
|
7
|
+
minSize?: `${number}px`;
|
8
|
+
maxSize?: `${number}px`;
|
9
|
+
defaultSize?: `${number}px`;
|
10
|
+
};
|
11
|
+
export type PrivateItemProps = ItemProps & {
|
12
|
+
index: number;
|
13
|
+
};
|
14
|
+
export type HandleProps = {
|
15
|
+
children?: (attributes: {
|
16
|
+
ref: React.RefObject<HTMLButtonElement>;
|
17
|
+
}) => React.ReactNode;
|
18
|
+
};
|
19
|
+
export type PrivateHandleProps = HandleProps & {
|
20
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
21
|
+
index: number;
|
22
|
+
onDrag: (args: UseDragCallbackArgs & {
|
23
|
+
index: number;
|
24
|
+
}) => void;
|
25
|
+
} & Pick<Props, "direction">;
|
26
|
+
export type ItemsRefProps = {
|
27
|
+
el: HTMLDivElement | null;
|
28
|
+
props: ItemProps;
|
29
|
+
}[];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from "./Resizable.js";
|
@@ -0,0 +1,15 @@
|
|
1
|
+
declare const _default: {
|
2
|
+
title: string;
|
3
|
+
component: {
|
4
|
+
(props: import("./..").ResizableProps): import("react").JSX.Element;
|
5
|
+
Item: import("react").FC<import("./..").ResizableItemProps>;
|
6
|
+
Handle: import("react").FC<import("./..").ResizableHandleProps>;
|
7
|
+
};
|
8
|
+
parameters: {
|
9
|
+
iframe: {
|
10
|
+
url: string;
|
11
|
+
};
|
12
|
+
};
|
13
|
+
};
|
14
|
+
export default _default;
|
15
|
+
export declare const base: () => import("react").JSX.Element;
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import { Example } from "../../../utilities/storybook/index.js";
|
2
|
+
import Resizable from "../index.js";
|
3
|
+
import View from "../../View/index.js";
|
4
|
+
import Button from "../../Button/index.js";
|
5
|
+
export default {
|
6
|
+
title: "Components/Resizable",
|
7
|
+
component: Resizable,
|
8
|
+
parameters: {
|
9
|
+
iframe: {
|
10
|
+
url: "https://reshaped.so/docs/utilities/Resizable",
|
11
|
+
},
|
12
|
+
},
|
13
|
+
};
|
14
|
+
export const base = () => (<Example>
|
15
|
+
<Example.Item>
|
16
|
+
<Resizable height="300px" gap={4}>
|
17
|
+
<Resizable.Item minSize="100px" defaultSize="200px">
|
18
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" align="center" justify="center" height="100%">
|
19
|
+
Panel
|
20
|
+
</View>
|
21
|
+
</Resizable.Item>
|
22
|
+
<Resizable.Handle />
|
23
|
+
<Resizable.Item>
|
24
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" align="center" justify="center" height="100%">
|
25
|
+
Panel
|
26
|
+
</View>
|
27
|
+
</Resizable.Item>
|
28
|
+
<Resizable.Handle />
|
29
|
+
<Resizable.Item>
|
30
|
+
<Resizable height="100%" direction="column">
|
31
|
+
<Resizable.Item minSize="50px" maxSize="100px">
|
32
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" align="center" justify="center" height="100%">
|
33
|
+
Panel
|
34
|
+
</View>
|
35
|
+
</Resizable.Item>
|
36
|
+
<Resizable.Handle />
|
37
|
+
<Resizable.Item>
|
38
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" align="center" justify="center" height="100%">
|
39
|
+
Panel
|
40
|
+
</View>
|
41
|
+
</Resizable.Item>
|
42
|
+
<Resizable.Handle>
|
43
|
+
{(attributes) => (<View backgroundColor="primary-faded" padding={1} align="center" borderRadius="small">
|
44
|
+
<Button attributes={attributes} type="button">
|
45
|
+
Drag me
|
46
|
+
</Button>
|
47
|
+
</View>)}
|
48
|
+
</Resizable.Handle>
|
49
|
+
<Resizable.Item>
|
50
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" align="center" justify="center" height="100%">
|
51
|
+
Panel
|
52
|
+
</View>
|
53
|
+
</Resizable.Item>
|
54
|
+
</Resizable>
|
55
|
+
</Resizable.Item>
|
56
|
+
</Resizable>
|
57
|
+
</Example.Item>
|
58
|
+
</Example>);
|
@@ -7,8 +7,10 @@ import getHeightStyles from "../../styles/height/index.js";
|
|
7
7
|
import getMaxHeightStyles from "../../styles/maxHeight/index.js";
|
8
8
|
import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js";
|
9
9
|
import s from "./ScrollArea.module.css";
|
10
|
+
import useHandlerRef from "../../hooks/useHandlerRef.js";
|
10
11
|
const ScrollAreaBar = (props) => {
|
11
12
|
const { ratio, position, vertical, onThumbMove } = props;
|
13
|
+
const onThumbMoveRef = useHandlerRef(onThumbMove);
|
12
14
|
const [dragging, setDragging] = React.useState(false);
|
13
15
|
const dragStartPositionRef = React.useRef(0);
|
14
16
|
const barRef = React.useRef(null);
|
@@ -38,10 +40,8 @@ const ScrollAreaBar = (props) => {
|
|
38
40
|
return;
|
39
41
|
const diff = vertical ? e.movementY : e.movementX;
|
40
42
|
const total = vertical ? elBar.scrollHeight : elBar.scrollWidth;
|
41
|
-
|
42
|
-
},
|
43
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
44
|
-
[ratio, vertical, dragging]);
|
43
|
+
onThumbMoveRef.current?.({ value: diff / total, type: "relative" });
|
44
|
+
}, [vertical, dragging, onThumbMoveRef]);
|
45
45
|
const handleDragEnd = React.useCallback(() => {
|
46
46
|
setDragging(false);
|
47
47
|
enableUserSelect();
|
@@ -1 +1 @@
|
|
1
|
-
.root{--rs-slider-overflow-gap:var(--rs-unit-x1);--rs-slider-thumb-size:var(--rs-unit-x4);align-items:center;cursor:pointer;display:flex;position:relative;user-select:none;-webkit-tap-highlight-color:transparent}.root:has(.thumb:hover,.thumb--active,.input:focus){overflow:visible}.bar{background:var(--rs-color-background-neutral);border-radius:var(--rs-radius-small);position:relative}.bar,.input{overflow:hidden}.input{height:1px;opacity:0;pointer-events:none;position:absolute;width:1px}.selection{background:var(--rs-color-background-primary);position:absolute}.tooltip{--rs-slider-tooltip-translate:calc(-50% + var(--rs-slider-tooltip-offset, 0px));background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-small);box-shadow:var(--rs-shadow-overlay);box-sizing:initial;color:var(--rs-color-foreground-neutral);font-variant-numeric:tabular-nums;min-width:var(--rs-line-height-caption-1);opacity:0;padding:calc(var(--rs-unit-x1) / 2) var(--rs-unit-x1);pointer-events:none;text-align:center;transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;user-select:none;white-space:nowrap;will-change:transform}.thumb,.thumbs,.tooltip{position:absolute}.thumb:before{background:var(--rs-color-background-primary);border-radius:999px;box-shadow:0 0 0 2px var(--rs-color-background-elevation-base);box-sizing:border-box;height:var(--rs-slider-thumb-size);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:box-shadow;width:var(--rs-slider-thumb-size)}.thumb:after,.thumb:before{content:"";position:absolute}.thumb:after{cursor:grab;height:var(--rs-unit-x7);width:var(--rs-unit-x7)}.thumb:hover .tooltip{opacity:1}.input:focus+.thumb:after,.thumb--active:after{cursor:grabbing}.input:focus+.thumb:before,.thumb--active:before{box-shadow:0 0 0 1px var(--rs-color-background-elevation-base)}.input:focus+.thumb .tooltip,.thumb--active .tooltip{opacity:1}.input:focus+.thumb:before{box-shadow:var(--rs-focus-shadow)}.--orientation-horizontal{height:var(--rs-slider-thumb-size);margin-inline:calc(var(--rs-slider-overflow-gap) * -1);overflow-x:clip;padding-inline:var(--rs-slider-overflow-gap)}.--orientation-horizontal .bar{height:var(--rs-unit-x1);width:100%}.--orientation-horizontal .selection{height:100%;inset-inline-start:var(--rs-slider-selection-start);width:var(--rs-slider-selection-size)}.--orientation-horizontal .tooltip{bottom:100%;left:50%;transform:translate(var(--rs-slider-tooltip-translate))}.--orientation-horizontal .thumbs{height:100%;inset-inline:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap))}.--orientation-horizontal .thumb{height:100%;inset-inline-start:var(--ts-slider-thumb-position);width:0}.--orientation-horizontal .thumb:after,.--orientation-horizontal .thumb:before{left:0;top:50%;transform:translate(-50%,-50%)}.--orientation-horizontal .input:focus+.thumb .tooltip,.--orientation-horizontal .thumb--active .tooltip,.--orientation-horizontal .thumb:hover .tooltip{transform:translate(var(--rs-slider-tooltip-translate),calc(var(--rs-unit-x1) * -1.5))}.--orientation-vertical{flex-direction:column;height:100%;margin-block:calc(var(--rs-slider-overflow-gap) * -1);overflow-y:clip;padding-block:var(--rs-slider-overflow-gap);width:var(--rs-slider-thumb-size)}.--orientation-vertical .bar{height:100%;width:var(--rs-unit-x1)}.--orientation-vertical .selection{height:var(--rs-slider-selection-size);inset-block-end:var(--rs-slider-selection-start);inset-inline-start:auto;width:100%}.--orientation-vertical .tooltip{inset-inline-start:100%;top:50%;transform:translateY(var(--rs-slider-tooltip-translate))}.--orientation-vertical .thumbs{inset-block:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap));width:100%}.--orientation-vertical .thumb{height:0;inset-block-end:var(--ts-slider-thumb-position);width:100%}.--orientation-vertical .thumb:after,.--orientation-vertical .thumb:before{left:50%;top:0;transform:translate(-50%,-50%)}.--orientation-vertical .input:focus+.thumb .tooltip,.--orientation-vertical .thumb--active .tooltip,.--orientation-vertical .thumb:hover .tooltip{transform:translate(calc(var(--rs-unit-x1) * 1.5),-50%)}.--disabled{cursor:not-allowed}.--disabled .bar{background-color:var(--rs-color-background-disabled)}.--disabled .selection,.--disabled .thumb:before{background-color:var(--rs-color-foreground-disabled)}.--disabled .thumb:after{cursor:not-allowed}.--disabled .thumb:hover .tooltip{opacity:0}
|
1
|
+
.root{--rs-slider-overflow-gap:var(--rs-unit-x1);--rs-slider-thumb-size:var(--rs-unit-x4);align-items:center;cursor:pointer;display:flex;position:relative;user-select:none;-webkit-tap-highlight-color:transparent}.root:has(.thumb:hover,.thumb--active,.input:focus-visible){overflow:visible}.bar{background:var(--rs-color-background-neutral);border-radius:var(--rs-radius-small);position:relative}.bar,.input{overflow:hidden}.input{height:1px;opacity:0;pointer-events:none;position:absolute;width:1px}.selection{background:var(--rs-color-background-primary);position:absolute}.tooltip{--rs-slider-tooltip-translate:calc(-50% + var(--rs-slider-tooltip-offset, 0px));background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-small);box-shadow:var(--rs-shadow-overlay);box-sizing:initial;color:var(--rs-color-foreground-neutral);font-variant-numeric:tabular-nums;min-width:var(--rs-line-height-caption-1);opacity:0;padding:calc(var(--rs-unit-x1) / 2) var(--rs-unit-x1);pointer-events:none;text-align:center;transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;user-select:none;white-space:nowrap;will-change:transform}.thumb,.thumbs,.tooltip{position:absolute}.thumb:before{background:var(--rs-color-background-primary);border-radius:999px;box-shadow:0 0 0 2px var(--rs-color-background-elevation-base);box-sizing:border-box;height:var(--rs-slider-thumb-size);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:box-shadow;width:var(--rs-slider-thumb-size)}.thumb:after,.thumb:before{content:"";position:absolute}.thumb:after{cursor:grab;height:var(--rs-unit-x7);width:var(--rs-unit-x7)}.thumb:hover .tooltip{opacity:1}.input:focus-visible+.thumb:after,.thumb--active:after{cursor:grabbing}.input:focus-visible+.thumb:before,.thumb--active:before{box-shadow:0 0 0 1px var(--rs-color-background-elevation-base)}.input:focus-visible+.thumb .tooltip,.thumb--active .tooltip{opacity:1}.input:focus-visible+.thumb:before{box-shadow:var(--rs-focus-shadow)}.--orientation-horizontal{height:var(--rs-slider-thumb-size);margin-inline:calc(var(--rs-slider-overflow-gap) * -1);overflow-x:clip;padding-inline:var(--rs-slider-overflow-gap)}.--orientation-horizontal .bar{height:var(--rs-unit-x1);width:100%}.--orientation-horizontal .selection{height:100%;inset-inline-start:var(--rs-slider-selection-start);width:var(--rs-slider-selection-size)}.--orientation-horizontal .tooltip{bottom:100%;left:50%;transform:translate(var(--rs-slider-tooltip-translate))}.--orientation-horizontal .thumbs{height:100%;inset-inline:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap))}.--orientation-horizontal .thumb{height:100%;inset-inline-start:var(--ts-slider-thumb-position);width:0}.--orientation-horizontal .thumb:after,.--orientation-horizontal .thumb:before{left:0;top:50%;transform:translate(-50%,-50%)}.--orientation-horizontal .input:focus+.thumb .tooltip,.--orientation-horizontal .thumb--active .tooltip,.--orientation-horizontal .thumb:hover .tooltip{transform:translate(var(--rs-slider-tooltip-translate),calc(var(--rs-unit-x1) * -1.5))}.--orientation-vertical{flex-direction:column;height:100%;margin-block:calc(var(--rs-slider-overflow-gap) * -1);overflow-y:clip;padding-block:var(--rs-slider-overflow-gap);width:var(--rs-slider-thumb-size)}.--orientation-vertical .bar{height:100%;width:var(--rs-unit-x1)}.--orientation-vertical .selection{height:var(--rs-slider-selection-size);inset-block-end:var(--rs-slider-selection-start);inset-inline-start:auto;width:100%}.--orientation-vertical .tooltip{inset-inline-start:100%;top:50%;transform:translateY(var(--rs-slider-tooltip-translate))}.--orientation-vertical .thumbs{inset-block:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap));width:100%}.--orientation-vertical .thumb{height:0;inset-block-end:var(--ts-slider-thumb-position);width:100%}.--orientation-vertical .thumb:after,.--orientation-vertical .thumb:before{left:50%;top:0;transform:translate(-50%,-50%)}.--orientation-vertical .input:focus+.thumb .tooltip,.--orientation-vertical .thumb--active .tooltip,.--orientation-vertical .thumb:hover .tooltip{transform:translate(calc(var(--rs-unit-x1) * 1.5),-50%)}.--disabled{cursor:not-allowed}.--disabled .bar{background-color:var(--rs-color-background-disabled)}.--disabled .selection,.--disabled .thumb:before{background-color:var(--rs-color-foreground-disabled)}.--disabled .thumb:after{cursor:not-allowed}.--disabled .thumb:hover .tooltip{opacity:0}
|
@@ -48,9 +48,9 @@ type BaseProps = {
|
|
48
48
|
min?: number;
|
49
49
|
max?: number;
|
50
50
|
orientation?: "vertical" | "horizontal";
|
51
|
-
renderValue?: (args: {
|
51
|
+
renderValue?: ((args: {
|
52
52
|
value: number;
|
53
|
-
}) => string;
|
53
|
+
}) => string) | false;
|
54
54
|
className?: G.ClassName;
|
55
55
|
attributes?: G.Attributes<"div">;
|
56
56
|
};
|
@@ -15,10 +15,10 @@ export const applyStepToValue = (value, step) => {
|
|
15
15
|
export const getDragCoord = ({ event, vertical, }) => {
|
16
16
|
if (vertical) {
|
17
17
|
if (event instanceof MouseEvent)
|
18
|
-
return event.
|
19
|
-
return event.changedTouches[0].
|
18
|
+
return event.clientY;
|
19
|
+
return event.changedTouches[0].clientY;
|
20
20
|
}
|
21
21
|
if (event instanceof MouseEvent)
|
22
|
-
return event.
|
23
|
-
return event.changedTouches[0].
|
22
|
+
return event.clientX;
|
23
|
+
return event.changedTouches[0].clientX;
|
24
24
|
};
|
@@ -9,9 +9,12 @@ import { useFormControl } from "../FormControl/index.js";
|
|
9
9
|
import SliderThumb from "./SliderThumb.js";
|
10
10
|
import { applyStepToValue, getDragCoord } from "./Slider.utilities.js";
|
11
11
|
import s from "./Slider.module.css";
|
12
|
+
import useHandlerRef from "../../hooks/useHandlerRef.js";
|
12
13
|
const THUMB_SIZE = 16;
|
13
14
|
const SliderControlled = (props) => {
|
14
15
|
const { name, range, max, min, step = 1, onChange, onChangeCommit, renderValue, className, attributes, orientation = "horizontal", } = props;
|
16
|
+
const onChangeRef = useHandlerRef(onChange);
|
17
|
+
const onChangeCommitRef = useHandlerRef(onChangeCommit);
|
15
18
|
const vertical = orientation === "vertical";
|
16
19
|
const minValue = range && props.minValue !== undefined ? applyStepToValue(props.minValue, step) : undefined;
|
17
20
|
const maxValue = applyStepToValue(range ? props.maxValue : props.value, step);
|
@@ -79,22 +82,21 @@ const SliderControlled = (props) => {
|
|
79
82
|
const handleMinChange = React.useCallback((value, options) => {
|
80
83
|
if (!range)
|
81
84
|
return;
|
82
|
-
const method = options?.commit ?
|
85
|
+
const method = options?.commit ? onChangeCommitRef.current : onChangeRef.current;
|
86
|
+
// @ts-ignore - creating refs out of handler props loses connection to the range flag
|
83
87
|
method?.({ minValue: value, maxValue, name });
|
84
|
-
},
|
85
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
86
|
-
[maxValue, name, range]);
|
88
|
+
}, [maxValue, name, range, onChangeCommitRef, onChangeRef]);
|
87
89
|
const handleMaxChange = React.useCallback((value, options) => {
|
88
90
|
if (range) {
|
89
|
-
const method = options?.commit ?
|
91
|
+
const method = options?.commit ? onChangeCommitRef.current : onChangeRef.current;
|
92
|
+
// @ts-ignore - creating refs out of handler props loses connection to the range flag
|
90
93
|
method?.({ minValue: minValue, maxValue: value, name });
|
91
94
|
return;
|
92
95
|
}
|
93
|
-
const method = options?.commit ?
|
96
|
+
const method = options?.commit ? onChangeCommitRef.current : onChangeRef.current;
|
97
|
+
// @ts-ignore - creating refs out of handler props loses connection to the range flag
|
94
98
|
method?.({ value, name });
|
95
|
-
},
|
96
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
97
|
-
[minValue, name, range]);
|
99
|
+
}, [minValue, name, range, onChangeRef, onChangeCommitRef]);
|
98
100
|
const handleMouseDown = ({ nativeEvent }) => {
|
99
101
|
if (disabled)
|
100
102
|
return;
|
@@ -15,6 +15,6 @@ const SliderThumb = (props, ref) => {
|
|
15
15
|
const handleChange = (e) => {
|
16
16
|
onChange(+e.target.value);
|
17
17
|
};
|
18
|
-
return (_jsxs(_Fragment, { children: [_jsx("input", { className: s.input, type: "range", name: name, value: value, onChange: handleChange, disabled: disabled, max: max, min: min, step: step, "aria-labelledby": id, "aria-orientation": orientation }), _jsx("div", { ref: ref, className: thumbClassNames, onMouseDown: onDragStart, onTouchStart: onDragStart, style: { "--ts-slider-thumb-position": `${position}%` }, id: id, "aria-hidden": "true", children: _jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", weight: "medium", className: s.tooltip, attributes: { ref: tooltipRef }, children: tooltipValue }) }) })] }));
|
18
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { className: s.input, type: "range", name: name, value: value, onChange: handleChange, disabled: disabled, max: max, min: min, step: step, "aria-labelledby": id, "aria-orientation": orientation }), _jsx("div", { ref: ref, className: thumbClassNames, onMouseDown: onDragStart, onTouchStart: onDragStart, style: { "--ts-slider-thumb-position": `${position}%` }, id: id, "aria-hidden": "true", children: renderValue !== false && (_jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", weight: "medium", className: s.tooltip, attributes: { ref: tooltipRef }, children: tooltipValue }) })) })] }));
|
19
19
|
};
|
20
20
|
export default React.forwardRef(SliderThumb);
|
@@ -22,6 +22,7 @@ export const direction = () => (<Example>
|
|
22
22
|
<View height="200px">
|
23
23
|
<Slider range name="slider" defaultMinValue={30} defaultMaxValue={100} orientation="vertical"/>
|
24
24
|
</View>
|
25
|
+
<View height="2000px"/>
|
25
26
|
</Example.Item>
|
26
27
|
</Example>);
|
27
28
|
export const step = () => (<Example>
|
@@ -49,6 +50,9 @@ export const customRender = () => (<Example>
|
|
49
50
|
<Example.Item title="custom render">
|
50
51
|
<Slider name="slider" defaultValue={30} renderValue={(args) => `$${args.value}`}/>
|
51
52
|
</Example.Item>
|
53
|
+
<Example.Item title="no tooltip">
|
54
|
+
<Slider name="slider" defaultValue={30} renderValue={false}/>
|
55
|
+
</Example.Item>
|
52
56
|
</Example>);
|
53
57
|
export const formControl = () => (<Example>
|
54
58
|
<Example.Item title="form control, disabled">
|
@@ -1 +1 @@
|
|
1
|
-
.root{align-items:center;display:inline-flex;gap:var(--rs-unit-x2);position:relative;vertical-align:top;-webkit-tap-highlight-color:transparent}.input{border:0;height:1px;left:0;opacity:0;outline:none;position:absolute;top:0;width:1px}.input:checked+.area{background:var(--rs-color-background-primary);border-color:transparent}.input:checked+.area .thumb{transform:translateX(var(--rs-unit-x3))}[dir=rtl] .input:checked+.area .thumb{transform:translateX(calc(var(--rs-unit-x3) * -1))}
|
1
|
+
.root{align-items:center;display:inline-flex;gap:var(--rs-unit-x2);position:relative;vertical-align:top;-webkit-tap-highlight-color:transparent}.input{border:0;height:1px;left:0;opacity:0;outline:none;position:absolute;top:0;width:1px}.input:checked+.area{background:var(--rs-color-background-primary);border-color:transparent}.input:checked+.area .thumb{transform:translateX(var(--rs-unit-x3))}[dir=rtl] .input:checked+.area .thumb{transform:translateX(calc(var(--rs-unit-x3) * -1))}.input:focus-visible+.area{box-shadow:var(--rs-focus-shadow)}.input[disabled]+.area{background:var(--rs-color-background-disabled);cursor:not-allowed}.input[disabled]+.area .thumb{opacity:.8}.input[disabled]:checked+.area{background:var(--rs-color-background-primary);opacity:.4}.input[disabled]:checked+.area .thumb{opacity:1}.area{align-items:center;background:var(--rs-color-background-neutral);border:2px solid transparent;box-sizing:border-box;cursor:pointer;display:flex;height:calc(var(--rs-unit-x1) * 5);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:background,border;width:calc(var(--rs-unit-x1) * 8)}.area,.thumb{border-radius:999px}.thumb{background:var(--rs-color-white);box-shadow:var(--rs-shadow-raised);height:var(--rs-unit-x4);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:transform;width:var(--rs-unit-x4)}.root--size-small .area{height:calc(var(--rs-unit-x1) * 4);width:calc(var(--rs-unit-x1) * 6)}.root--size-small .thumb{height:var(--rs-unit-x3);width:var(--rs-unit-x3)}.root--size-small .input:checked+.area .thumb{transform:translateX(var(--rs-unit-x2))}[dir=rtl] .root--size-small .input:checked+.area .thumb{transform:translateX(calc(var(--rs-unit-x2) * -1))}.root--size-large .area{height:calc(var(--rs-unit-x1) * 6);width:calc(var(--rs-unit-x1) * 10)}.root--size-large .thumb{height:var(--rs-unit-x5);width:var(--rs-unit-x5)}.root--size-large .input:checked+.area .thumb{transform:translateX(var(--rs-unit-x4))}[dir=rtl] .root--size-large .input:checked+.area .thumb{transform:translateX(calc(var(--rs-unit-x4) * -1))}.root--reversed{flex-direction:row-reverse}
|
@@ -37,23 +37,24 @@ export type ContainerProps = {
|
|
37
37
|
status?: "entering" | "entered" | "exiting";
|
38
38
|
inspected: boolean;
|
39
39
|
};
|
40
|
+
export type ShowOptions = {
|
41
|
+
timeout?: Timeout;
|
42
|
+
position?: Position;
|
43
|
+
};
|
44
|
+
export type ShowProps = Props & ShowOptions;
|
40
45
|
export type Context = {
|
41
46
|
options?: ProviderProps["options"];
|
42
47
|
queues: Record<RegionProps["position"], Array<ContainerProps>>;
|
43
|
-
add: (toast:
|
48
|
+
add: (toast: ShowProps) => string;
|
44
49
|
show: (id: string) => void;
|
45
50
|
hide: (id: string) => void;
|
46
51
|
remove: (id: string) => void;
|
47
52
|
id: string;
|
48
53
|
};
|
49
|
-
export type ShowOptions = {
|
50
|
-
timeout?: Timeout;
|
51
|
-
position?: Position;
|
52
|
-
};
|
53
54
|
type AddAction = {
|
54
55
|
type: "add";
|
55
56
|
payload: {
|
56
|
-
toastProps:
|
57
|
+
toastProps: ShowProps;
|
57
58
|
id: string;
|
58
59
|
};
|
59
60
|
};
|
@@ -1,3 +1,3 @@
|
|
1
1
|
export { default as useToast } from "./useToast";
|
2
2
|
export { default as ToastProvider } from "./ToastProvider";
|
3
|
-
export type { Props as ToastProps, ProviderProps as ToastProviderProps } from "./Toast.types";
|
3
|
+
export type { Props as ToastProps, ProviderProps as ToastProviderProps, ShowProps as ToastShowProps, } from "./Toast.types";
|
@@ -121,4 +121,35 @@ export const edgeCases = () => (<Example>
|
|
121
121
|
</Actionable>)}
|
122
122
|
</Tooltip>
|
123
123
|
</Example.Item>
|
124
|
+
|
125
|
+
<Example.Item title="nested popovers inside a tooltip">
|
126
|
+
<Tooltip position="top" text="Hello">
|
127
|
+
{(tooltipAttributes) => (<Popover position="bottom">
|
128
|
+
<Popover.Trigger>
|
129
|
+
{(attributes) => (<Button color="primary" attributes={{
|
130
|
+
...tooltipAttributes,
|
131
|
+
...attributes,
|
132
|
+
}}>
|
133
|
+
Open
|
134
|
+
</Button>)}
|
135
|
+
</Popover.Trigger>
|
136
|
+
<Popover.Content>
|
137
|
+
<View gap={2} align="start">
|
138
|
+
Popover content
|
139
|
+
<Popover position="bottom">
|
140
|
+
<Popover.Trigger>
|
141
|
+
{(attributes) => <Button attributes={attributes}>Open</Button>}
|
142
|
+
</Popover.Trigger>
|
143
|
+
<Popover.Content>
|
144
|
+
<View gap={2} align="start">
|
145
|
+
Popover content
|
146
|
+
<Button onClick={() => { }}>Button</Button>
|
147
|
+
</View>
|
148
|
+
</Popover.Content>
|
149
|
+
</Popover>
|
150
|
+
</View>
|
151
|
+
</Popover.Content>
|
152
|
+
</Popover>)}
|
153
|
+
</Tooltip>
|
154
|
+
</Example.Item>
|
124
155
|
</Example>);
|
@@ -3,7 +3,9 @@ import type * as T from "./Flyout.types";
|
|
3
3
|
declare const FlyoutContext: React.Context<T.ContextProps>;
|
4
4
|
declare const useFlyoutContext: () => T.ContextProps;
|
5
5
|
declare const useFlyoutTriggerContext: () => T.TriggerContextProps;
|
6
|
+
declare const useFlyoutContentContext: () => boolean;
|
6
7
|
declare const Provider: React.Provider<T.ContextProps>;
|
7
8
|
declare const TriggerProvider: React.Provider<T.TriggerContextProps>;
|
8
|
-
|
9
|
+
declare const ContentProvider: React.Provider<boolean>;
|
10
|
+
export { Provider, TriggerProvider, ContentProvider, useFlyoutContext, useFlyoutTriggerContext, useFlyoutContentContext, };
|
9
11
|
export default FlyoutContext;
|