@structuralists/scaffolding 0.1.1 → 0.1.3
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/bun.lock
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"eslint": "^10.3.0",
|
|
24
24
|
"eslint-plugin-boundaries": "^6.0.2",
|
|
25
25
|
"eslint-plugin-storybook": "10.3.6",
|
|
26
|
+
"prettier": "^3.8.3",
|
|
26
27
|
"react-router": "^7.14.2",
|
|
27
28
|
"storybook": "^10.3.6",
|
|
28
29
|
"typescript": "^6.0.3",
|
|
@@ -755,6 +756,8 @@
|
|
|
755
756
|
|
|
756
757
|
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
|
757
758
|
|
|
759
|
+
"prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="],
|
|
760
|
+
|
|
758
761
|
"pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="],
|
|
759
762
|
|
|
760
763
|
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@structuralists/scaffolding",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"main": "./index.ts",
|
|
5
5
|
"types": "./index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"eslint": "^10.3.0",
|
|
43
43
|
"eslint-plugin-boundaries": "^6.0.2",
|
|
44
44
|
"eslint-plugin-storybook": "10.3.6",
|
|
45
|
+
"prettier": "^3.8.3",
|
|
45
46
|
"react-router": "^7.14.2",
|
|
46
47
|
"storybook": "^10.3.6",
|
|
47
48
|
"typescript": "^6.0.3",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useEffect,
|
|
3
|
+
useRef,
|
|
3
4
|
useState,
|
|
4
5
|
type CSSProperties,
|
|
5
6
|
type ReactNode,
|
|
@@ -52,6 +53,11 @@ export const Panels = (props: PanelsProps) => {
|
|
|
52
53
|
|
|
53
54
|
const [renderedOverlay, setRenderedOverlay] = useState<ReactNode>(rightOverlay ?? null);
|
|
54
55
|
const [isOverlayClosing, setIsOverlayClosing] = useState(false);
|
|
56
|
+
// True only when the overlay is freshly mounting so the slide-in animation
|
|
57
|
+
// plays. Not set when a close is cancelled mid-animation (rapid reopen),
|
|
58
|
+
// which would otherwise re-trigger the slide-in unintentionally.
|
|
59
|
+
const [isOverlayEntering, setIsOverlayEntering] = useState(rightOverlay != null);
|
|
60
|
+
const renderedOverlayRef = useRef<ReactNode>(rightOverlay ?? null);
|
|
55
61
|
|
|
56
62
|
// Outside-click dismissal. Gated to the open state so the close
|
|
57
63
|
// animation window — where `rightOverlay` is null but `renderedOverlay`
|
|
@@ -63,12 +69,21 @@ export const Panels = (props: PanelsProps) => {
|
|
|
63
69
|
|
|
64
70
|
useEffect(() => {
|
|
65
71
|
if (rightOverlay != null) {
|
|
72
|
+
// If renderedOverlayRef still has content, the close animation was
|
|
73
|
+
// interrupted (rapid reopen). Cancel without replaying the slide-in.
|
|
74
|
+
const isCancellingClose = renderedOverlayRef.current != null;
|
|
75
|
+
renderedOverlayRef.current = rightOverlay;
|
|
66
76
|
setRenderedOverlay(rightOverlay);
|
|
67
77
|
setIsOverlayClosing(false);
|
|
78
|
+
if (!isCancellingClose) {
|
|
79
|
+
setIsOverlayEntering(true);
|
|
80
|
+
}
|
|
68
81
|
return;
|
|
69
82
|
}
|
|
83
|
+
setIsOverlayEntering(false);
|
|
70
84
|
setIsOverlayClosing(true);
|
|
71
85
|
const timer = setTimeout(() => {
|
|
86
|
+
renderedOverlayRef.current = null;
|
|
72
87
|
setRenderedOverlay(null);
|
|
73
88
|
setIsOverlayClosing(false);
|
|
74
89
|
}, OVERLAY_CLOSE_ANIMATION_MS);
|
|
@@ -113,8 +128,13 @@ export const Panels = (props: PanelsProps) => {
|
|
|
113
128
|
{renderedOverlay != null && (
|
|
114
129
|
<div
|
|
115
130
|
ref={overlayRef}
|
|
116
|
-
className={cx(
|
|
131
|
+
className={cx(
|
|
132
|
+
styles.rightOverlay,
|
|
133
|
+
isOverlayEntering && !isOverlayClosing && styles.entering,
|
|
134
|
+
isOverlayClosing && styles.closing,
|
|
135
|
+
)}
|
|
117
136
|
style={rightOverlayStyle}
|
|
137
|
+
onAnimationEnd={() => setIsOverlayEntering(false)}
|
|
118
138
|
>
|
|
119
139
|
{renderedOverlay}
|
|
120
140
|
</div>
|
|
@@ -78,6 +78,9 @@
|
|
|
78
78
|
border-left: 1px solid var(--ui-border);
|
|
79
79
|
box-shadow: -4px 0 20px var(--ui-shadow);
|
|
80
80
|
z-index: 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.rightOverlay.entering {
|
|
81
84
|
animation: panels-overlay-in 200ms ease-out;
|
|
82
85
|
}
|
|
83
86
|
|
|
@@ -96,7 +99,7 @@
|
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
@media (prefers-reduced-motion: reduce) {
|
|
99
|
-
.rightOverlay,
|
|
102
|
+
.rightOverlay.entering,
|
|
100
103
|
.rightOverlay.closing {
|
|
101
104
|
animation: none;
|
|
102
105
|
}
|