reshaped 2.10.4 → 2.10.6
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 +2 -0
- package/bundle.css +1 -1
- package/bundle.d.ts +2 -2
- package/bundle.js +8 -8
- package/components/Toast/Toast.constants.d.ts +1 -0
- package/components/Toast/Toast.constants.js +1 -0
- package/components/Toast/Toast.module.css +1 -1
- package/components/Toast/Toast.types.d.ts +2 -0
- package/components/Toast/ToastProvider.js +6 -2
- package/components/Toast/ToastRegion.js +2 -2
- package/components/Toast/tests/Toast.stories.js +26 -9
- package/components/Toast/useToast.d.ts +1 -0
- package/components/Toast/useToast.js +2 -2
- package/components/View/View.js +7 -0
- package/components/View/tests/View.stories.js +11 -1
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/package.json +1 -1
@@ -3,6 +3,7 @@ export declare const timeouts: Record<T.Timeout, number>;
|
|
3
3
|
export declare const positions: T.Position[];
|
4
4
|
export declare const defaultContextData: {
|
5
5
|
queues: Record<T.Position, T.ContainerProps[]>;
|
6
|
+
id: string;
|
6
7
|
show: () => void;
|
7
8
|
hide: () => void;
|
8
9
|
remove: () => void;
|
@@ -13,6 +13,7 @@ export const positions = [
|
|
13
13
|
const defaultPositionData = positions.reduce((acc, cur) => (Object.assign({ [cur]: [] }, acc)), {});
|
14
14
|
export const defaultContextData = {
|
15
15
|
queues: defaultPositionData,
|
16
|
+
id: "",
|
16
17
|
show: () => { },
|
17
18
|
hide: () => { },
|
18
19
|
remove: () => { },
|
@@ -1 +1 @@
|
|
1
|
-
.container{display:block;opacity:0;position:relative;transition:var(--rs-duration-medium) ease-out;transition-property:transform,height,opacity;width:100%}.container--visible{opacity:1}.container--visible .wrapper{height:calc(100% - var(--rs-unit-x2))}.container--index-0{z-index:var(--rs-z-index-raised)}.container--index-1{height:var(--rs-unit-x2)!important}.container--index-1 .wrapper{height:100%;transform:translateY(calc(var(--rs-unit-x1) * -1)) translateZ(0) scaleX(.9)}.container--index-2{height:var(--rs-unit-x2)!important}.container--index-2 .wrapper{height:100%;transform:translateY(calc(var(--rs-unit-x2) * -1)) translateZ(0) scaleX(.8)}.container--index-overflow{height:0!important}.container--index-overflow .wrapper{height:100%;opacity:0;transform:translateY(calc(var(--rs-unit-x3) * -1)) translateZ(0) scaleX(.8)}.wrapper{border-radius:var(--rs-unit-radius-medium);box-shadow:var(--rs-shadow-overlay);height:100%;margin-top:var(--rs-unit-x2);overflow:hidden;transform-origin:50% 0;transition:var(--rs-duration-medium) ease-out;transition-property:height,transform,opacity}.region,.wrapper{display:flex;flex-direction:column}.region{max-width:100%;padding:var(--rs-unit-x4);position:fixed;width:100%;z-index:var(--rs-z-index-notification)}.region--position-top{align-items:center;left:50%;top:0;transform:translateX(-50%)}.region--position-top-start{align-items:start;inset-inline-start:0;top:0}.region--position-top-end{inset-inline-end:0;top:0}.region--position-top,.region--position-top-end,.region--position-top-start{flex-direction:column-reverse}.region--position-top .wrapper,.region--position-top-end .wrapper,.region--position-top-start .wrapper{justify-content:flex-end;margin-bottom:var(--rs-unit-x2);margin-top:0;transform-origin:bottom}.region--position-top .container--index-2 .wrapper,.region--position-top-end .container--index-2 .wrapper,.region--position-top-start .container--index-2 .wrapper{transform:translateY(0) translateZ(0) scaleX(.8)}.region--position-top .container--index-overflow .wrapper,.region--position-top-end .container--index-overflow .wrapper,.region--position-top-start .container--index-overflow .wrapper{transform:translateY(var(--rs-unit-x1)) translateZ(0) scaleX(.8)}.region--position-bottom{align-items:center;bottom:0;left:50%;transform:translateX(-50%)}.region--position-bottom-start{align-items:start;bottom:0;inset-inline-start:0}.region--position-bottom-end{align-items:end;bottom:0;inset-inline-end:0}@media (--rs-viewport-m ){.region{width:360px}}
|
1
|
+
.container{display:block;opacity:0;position:relative;transition:var(--rs-duration-medium) ease-out;transition-property:transform,height,opacity;width:100%}.container--visible{opacity:1}.container--visible .wrapper{height:calc(100% - var(--rs-unit-x2))}.container--index-0{z-index:var(--rs-z-index-raised)}.container--index-1{height:var(--rs-unit-x2)!important}.container--index-1 .wrapper{height:100%;transform:translateY(calc(var(--rs-unit-x1) * -1)) translateZ(0) scaleX(.9)}.container--index-2{height:var(--rs-unit-x2)!important}.container--index-2 .wrapper{height:100%;transform:translateY(calc(var(--rs-unit-x2) * -1)) translateZ(0) scaleX(.8)}.container--index-overflow{height:0!important}.container--index-overflow .wrapper{height:100%;opacity:0;transform:translateY(calc(var(--rs-unit-x3) * -1)) translateZ(0) scaleX(.8)}.wrapper{border-radius:var(--rs-unit-radius-medium);box-shadow:var(--rs-shadow-overlay);height:100%;margin-top:var(--rs-unit-x2);overflow:hidden;transform-origin:50% 0;transition:var(--rs-duration-medium) ease-out;transition-property:height,transform,opacity}.region,.wrapper{display:flex;flex-direction:column}.region{max-width:100%;padding:var(--rs-unit-x4);position:fixed;width:100%;z-index:var(--rs-z-index-notification)}.region--nested{position:absolute}.region--position-top{align-items:center;left:50%;top:0;transform:translateX(-50%)}.region--position-top-start{align-items:start;inset-inline-start:0;top:0}.region--position-top-end{inset-inline-end:0;top:0}.region--position-top,.region--position-top-end,.region--position-top-start{flex-direction:column-reverse}.region--position-top .wrapper,.region--position-top-end .wrapper,.region--position-top-start .wrapper{justify-content:flex-end;margin-bottom:var(--rs-unit-x2);margin-top:0;transform-origin:bottom}.region--position-top .container--index-2 .wrapper,.region--position-top-end .container--index-2 .wrapper,.region--position-top-start .container--index-2 .wrapper{transform:translateY(0) translateZ(0) scaleX(.8)}.region--position-top .container--index-overflow .wrapper,.region--position-top-end .container--index-overflow .wrapper,.region--position-top-start .container--index-overflow .wrapper{transform:translateY(var(--rs-unit-x1)) translateZ(0) scaleX(.8)}.region--position-bottom{align-items:center;bottom:0;left:50%;transform:translateX(-50%)}.region--position-bottom-start{align-items:start;bottom:0;inset-inline-start:0}.region--position-bottom-end{align-items:end;bottom:0;inset-inline-end:0}@media (--rs-viewport-m ){.region{width:360px}}
|
@@ -26,6 +26,7 @@ export type ProviderProps = {
|
|
26
26
|
};
|
27
27
|
export type RegionProps = {
|
28
28
|
position: Position;
|
29
|
+
nested?: boolean;
|
29
30
|
};
|
30
31
|
export type ContainerProps = {
|
31
32
|
id: string;
|
@@ -43,6 +44,7 @@ export type Context = {
|
|
43
44
|
show: (id: string) => void;
|
44
45
|
hide: (id: string) => void;
|
45
46
|
remove: (id: string) => void;
|
47
|
+
id: string;
|
46
48
|
};
|
47
49
|
export type ShowOptions = {
|
48
50
|
timeout?: Timeout;
|
@@ -14,6 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import React from "react";
|
15
15
|
import ToastContext from "./Toast.context.js";
|
16
16
|
import ToastRegion from "./ToastRegion.js";
|
17
|
+
import useToast from "./useToast.js";
|
17
18
|
import { positions, defaultContextData } from "./Toast.constants.js";
|
18
19
|
let counter = 0;
|
19
20
|
const generateId = () => `__rs-toast-${counter++}`;
|
@@ -52,6 +53,8 @@ const toastReducer = (state, action) => {
|
|
52
53
|
};
|
53
54
|
const ToastProvider = (props) => {
|
54
55
|
const { children, options } = props;
|
56
|
+
const toast = useToast();
|
57
|
+
const id = React.useId();
|
55
58
|
const [data, dispatch] = React.useReducer(toastReducer, defaultContextData.queues);
|
56
59
|
const add = React.useCallback((toastProps) => {
|
57
60
|
const id = generateId();
|
@@ -69,13 +72,14 @@ const ToastProvider = (props) => {
|
|
69
72
|
}, []);
|
70
73
|
const value = React.useMemo(() => ({
|
71
74
|
queues: data,
|
75
|
+
id,
|
72
76
|
add,
|
73
77
|
show,
|
74
78
|
hide,
|
75
79
|
remove,
|
76
80
|
inspecting: false,
|
77
81
|
options,
|
78
|
-
}), [data, show, hide, add, remove, options]);
|
79
|
-
return (_jsxs(ToastContext.Provider, { value: value, children: [children, positions.map((position) => (_jsx(ToastRegion, { position: position }, position)))] }));
|
82
|
+
}), [data, show, hide, add, remove, id, options]);
|
83
|
+
return (_jsxs(ToastContext.Provider, { value: value, children: [children, positions.map((position) => (_jsx(ToastRegion, { position: position, nested: !!toast.id }, position)))] }));
|
80
84
|
};
|
81
85
|
export default ToastProvider;
|
@@ -7,14 +7,14 @@ import ToastContainer from "./ToastContainer.js";
|
|
7
7
|
import ToastContext from "./Toast.context.js";
|
8
8
|
import s from "./Toast.module.css";
|
9
9
|
const ToastRegion = (props) => {
|
10
|
-
const { position } = props;
|
10
|
+
const { position, nested } = props;
|
11
11
|
const { queues, options } = React.useContext(ToastContext);
|
12
12
|
const [inspecting, setInspecting] = React.useState(false);
|
13
13
|
const ignoreHoverRef = React.useRef(false);
|
14
14
|
const rootRef = React.useRef(null);
|
15
15
|
const queue = queues[position];
|
16
16
|
const { width, expanded } = (options === null || options === void 0 ? void 0 : options[position]) || {};
|
17
|
-
const regionClassNames = classNames(s.region, s[`region--position-${position}`]);
|
17
|
+
const regionClassNames = classNames(s.region, s[`region--position-${position}`], nested && s["region--nested"]);
|
18
18
|
const filteredLength = queue.filter((item) => item.status === "entered").length;
|
19
19
|
let hiddenCount = 0;
|
20
20
|
// If touch event was triggered – ignore hover events
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Example } from "../../../utilities/storybook/index.js";
|
2
|
-
import { useToast } from "../index.js";
|
2
|
+
import { useToast, ToastProvider } from "../index.js";
|
3
3
|
import Button from "../../Button/index.js";
|
4
4
|
import View from "../../View/index.js";
|
5
5
|
import Image from "../../Image/index.js";
|
@@ -295,16 +295,33 @@ const Slots = () => {
|
|
295
295
|
export const slots = () => <Slots />;
|
296
296
|
const Multiline = () => {
|
297
297
|
const toast = useToast();
|
298
|
-
return (<
|
299
|
-
<Example.Item title="Multiline, should support dynamic height">
|
300
|
-
<Button onClick={() => {
|
298
|
+
return (<Button onClick={() => {
|
301
299
|
toast.show({
|
302
300
|
text: "Very long event completed notification message",
|
303
301
|
});
|
304
302
|
}}>
|
305
|
-
|
306
|
-
|
307
|
-
</Example.Item>
|
308
|
-
</Example>);
|
303
|
+
Show toast
|
304
|
+
</Button>);
|
309
305
|
};
|
310
|
-
|
306
|
+
const Nested = () => {
|
307
|
+
const toast = useToast();
|
308
|
+
return (<View height="300px">
|
309
|
+
<Button onClick={() => {
|
310
|
+
toast.show({
|
311
|
+
text: "Notification sent",
|
312
|
+
});
|
313
|
+
}}>
|
314
|
+
Show toast
|
315
|
+
</Button>
|
316
|
+
</View>);
|
317
|
+
};
|
318
|
+
export const edgeCases = () => (<Example>
|
319
|
+
<Example.Item title="Multiline, should support dynamic height">
|
320
|
+
<Multiline />
|
321
|
+
</Example.Item>
|
322
|
+
<Example.Item title="Nested ToastProvider">
|
323
|
+
<ToastProvider>
|
324
|
+
<Nested />
|
325
|
+
</ToastProvider>
|
326
|
+
</Example.Item>
|
327
|
+
</Example>);
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import React from "react";
|
3
3
|
import ToastContext from "./Toast.context.js";
|
4
4
|
const useToast = () => {
|
5
|
-
const { add, hide } = React.useContext(ToastContext);
|
6
|
-
return React.useMemo(() => ({ show: add, hide }), [add, hide]);
|
5
|
+
const { add, hide, id } = React.useContext(ToastContext);
|
6
|
+
return React.useMemo(() => ({ show: add, hide, id }), [add, hide, id]);
|
7
7
|
};
|
8
8
|
export default useToast;
|
package/components/View/View.js
CHANGED
@@ -127,6 +127,13 @@ const View = (props) => {
|
|
127
127
|
const key = child.key || index;
|
128
128
|
return (_createElement(Hidden, Object.assign({}, hiddenProps, { key: key }), (className) => renderItem({ className, child: hiddenChild, index: renderedIndex })));
|
129
129
|
}
|
130
|
+
if (child.type === React.Fragment) {
|
131
|
+
return child.props.children.map((child) => {
|
132
|
+
const index = renderedIndex;
|
133
|
+
renderedItemIndex += 1;
|
134
|
+
return renderItem({ child, index });
|
135
|
+
});
|
136
|
+
}
|
130
137
|
return renderItem({ child, index: renderedIndex });
|
131
138
|
});
|
132
139
|
// Classnames and attributes are written here so we can assign nowrap to the root element based on the children
|
@@ -134,9 +134,10 @@ export const direction = () => (<Example title="Item 1 is another component, Ite
|
|
134
134
|
</Example>);
|
135
135
|
export const gap = () => (<Example>
|
136
136
|
<Example.Item title="gap: 4, direction: row">
|
137
|
-
<View direction="row" gap={4}>
|
137
|
+
<View direction="row" gap={4} divided>
|
138
138
|
<Placeholder>Item 1</Placeholder>
|
139
139
|
<Placeholder>Item 2</Placeholder>
|
140
|
+
<Placeholder>Item 3</Placeholder>
|
140
141
|
</View>
|
141
142
|
</Example.Item>
|
142
143
|
<Example.Item title="gap: 0, direction: row">
|
@@ -202,6 +203,15 @@ export const divided = () => (<Example>
|
|
202
203
|
</View.Item>
|
203
204
|
</View>
|
204
205
|
</Example.Item>
|
206
|
+
<Example.Item title="with React.Fragment">
|
207
|
+
<View direction="row" gap={4} divided>
|
208
|
+
<Placeholder>Item 1</Placeholder>
|
209
|
+
<>
|
210
|
+
<Placeholder>Item 2</Placeholder>
|
211
|
+
<Placeholder>Item 3</Placeholder>
|
212
|
+
</>
|
213
|
+
</View>
|
214
|
+
</Example.Item>
|
205
215
|
</Example>);
|
206
216
|
export const bleed = () => (<Example title="Removes side borders and border radius when applied">
|
207
217
|
<Example.Item title="bleed: 4">
|
package/index.d.ts
CHANGED
@@ -99,8 +99,8 @@ export { default as TextField } from "./components/TextField";
|
|
99
99
|
export type { TextFieldProps } from "./components/TextField";
|
100
100
|
export { default as Timeline } from "./components/Timeline";
|
101
101
|
export type { TimelineProps, TimelineItemProps } from "./components/Timeline";
|
102
|
-
export { useToast } from "./components/Toast";
|
103
|
-
export type { ToastProps } from "./components/Toast";
|
102
|
+
export { useToast, ToastProvider } from "./components/Toast";
|
103
|
+
export type { ToastProps, ToastProviderProps } from "./components/Toast";
|
104
104
|
export { default as Tooltip } from "./components/Tooltip";
|
105
105
|
export type { TooltipProps } from "./components/Tooltip";
|
106
106
|
export { default as View } from "./components/View";
|
package/index.js
CHANGED
@@ -50,7 +50,7 @@ export { default as Text } from "./components/Text/index.js";
|
|
50
50
|
export { default as TextArea } from "./components/TextArea/index.js";
|
51
51
|
export { default as TextField } from "./components/TextField/index.js";
|
52
52
|
export { default as Timeline } from "./components/Timeline/index.js";
|
53
|
-
export { useToast } from "./components/Toast/index.js";
|
53
|
+
export { useToast, ToastProvider } from "./components/Toast/index.js";
|
54
54
|
export { default as Tooltip } from "./components/Tooltip/index.js";
|
55
55
|
export { default as View } from "./components/View/index.js";
|
56
56
|
/**
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "reshaped",
|
3
3
|
"description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
|
4
|
-
"version": "2.10.
|
4
|
+
"version": "2.10.6",
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
6
6
|
"email": "hello@reshaped.so",
|
7
7
|
"homepage": "https://reshaped.so",
|