stablekit.ts 0.2.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 +207 -0
- package/dist/eslint.cjs +157 -0
- package/dist/eslint.d.cts +55 -0
- package/dist/eslint.d.ts +55 -0
- package/dist/eslint.js +132 -0
- package/dist/index.cjs +823 -0
- package/dist/index.d.cts +473 -0
- package/dist/index.d.ts +473 -0
- package/dist/index.js +816 -0
- package/dist/stylelint.cjs +117 -0
- package/dist/stylelint.d.cts +47 -0
- package/dist/stylelint.d.ts +47 -0
- package/dist/stylelint.js +92 -0
- package/dist/styles.css +178 -0
- package/llms.txt +463 -0
- package/package.json +92 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,823 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
CollectionSkeleton: () => CollectionSkeleton,
|
|
24
|
+
FadeTransition: () => FadeTransition,
|
|
25
|
+
LayoutGroup: () => LayoutGroup,
|
|
26
|
+
LayoutMap: () => LayoutMap,
|
|
27
|
+
LayoutView: () => LayoutView,
|
|
28
|
+
LoadingBoundary: () => LoadingBoundary,
|
|
29
|
+
LoadingContext: () => LoadingContext,
|
|
30
|
+
MediaSkeleton: () => MediaSkeleton,
|
|
31
|
+
SizeRatchet: () => SizeRatchet,
|
|
32
|
+
StableCounter: () => StableCounter,
|
|
33
|
+
StableField: () => StableField,
|
|
34
|
+
StableText: () => StableText,
|
|
35
|
+
StateSwap: () => StateSwap,
|
|
36
|
+
TextSkeleton: () => TextSkeleton,
|
|
37
|
+
createPrimitive: () => createPrimitive,
|
|
38
|
+
useLoadingState: () => useLoadingState
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/components/layout-group.tsx
|
|
43
|
+
var import_react = require("react");
|
|
44
|
+
|
|
45
|
+
// src/styles.css
|
|
46
|
+
var styles_default = `/* stablekit \u2014 layout stability toolkit for React
|
|
47
|
+
*
|
|
48
|
+
* CSS class prefix: sk-
|
|
49
|
+
* All animations use CSS custom properties for themability.
|
|
50
|
+
* Styles are auto-injected at import time (opt-out via meta tag).
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/* \u2500\u2500 LayoutGroup / LayoutView \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
54
|
+
|
|
55
|
+
/* All children overlap in the same grid cell.
|
|
56
|
+
Grid auto-sizes to the largest child.
|
|
57
|
+
Block-level groups use flex-column so content stretches to fill
|
|
58
|
+
the reserved width. Inline groups (data-inline) skip this \u2014 their
|
|
59
|
+
children are inline content that shouldn't be forced vertical. */
|
|
60
|
+
.sk-layout-group {
|
|
61
|
+
display: grid;
|
|
62
|
+
}
|
|
63
|
+
.sk-layout-group[data-inline] {
|
|
64
|
+
display: inline-grid;
|
|
65
|
+
}
|
|
66
|
+
.sk-layout-group > * {
|
|
67
|
+
grid-area: 1 / 1;
|
|
68
|
+
}
|
|
69
|
+
.sk-layout-group:not([data-inline]) > * {
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
}
|
|
73
|
+
/* Inline groups: children inherit the parent's inline flow.
|
|
74
|
+
Without this, grid items default to block and stack content. */
|
|
75
|
+
.sk-layout-group[data-inline] > * {
|
|
76
|
+
display: inline;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Inactive LayoutView hiding \u2014 CSS-driven via data-state attribute.
|
|
80
|
+
LayoutView sets data-state="active"|"inactive" so consumers can
|
|
81
|
+
override transitions on .sk-layout-view without specificity fights.
|
|
82
|
+
[inert] handles accessibility (non-focusable, non-interactive). */
|
|
83
|
+
.sk-layout-view[data-state="inactive"] {
|
|
84
|
+
opacity: 0;
|
|
85
|
+
visibility: hidden;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* \u2500\u2500 SizeRatchet \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
89
|
+
|
|
90
|
+
/* contain isolates internal reflow from ancestors. */
|
|
91
|
+
.sk-size-ratchet {
|
|
92
|
+
contain: layout style;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* \u2500\u2500 Shimmer / Skeleton \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
96
|
+
|
|
97
|
+
.sk-skeleton-grid {
|
|
98
|
+
display: grid;
|
|
99
|
+
gap: var(--sk-skeleton-gap, 0.75rem);
|
|
100
|
+
contain: layout style;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.sk-skeleton-bone {
|
|
104
|
+
display: flex;
|
|
105
|
+
flex-direction: column;
|
|
106
|
+
gap: var(--sk-skeleton-bone-gap, 0.125rem);
|
|
107
|
+
padding: var(--sk-skeleton-bone-padding, 0.375rem 0.5rem);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.sk-shimmer-line {
|
|
111
|
+
height: 1lh;
|
|
112
|
+
border-radius: var(--sk-shimmer-radius, 0.125rem);
|
|
113
|
+
background: linear-gradient(
|
|
114
|
+
90deg,
|
|
115
|
+
var(--sk-shimmer-color, #e5e7eb) 25%,
|
|
116
|
+
var(--sk-shimmer-highlight, #f3f4f6) 50%,
|
|
117
|
+
var(--sk-shimmer-color, #e5e7eb) 75%
|
|
118
|
+
);
|
|
119
|
+
background-size: 200% 100%;
|
|
120
|
+
animation: sk-shimmer var(--sk-shimmer-duration, 1.5s) ease-in-out infinite;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Inert ghost inside a shimmer-line \u2014 sizes the shimmer to match
|
|
124
|
+
content width exactly. Invisible and non-interactive via [inert]. */
|
|
125
|
+
.sk-shimmer-line > [inert] {
|
|
126
|
+
visibility: hidden;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@keyframes sk-shimmer {
|
|
130
|
+
0% { background-position: 200% 0; }
|
|
131
|
+
100% { background-position: -200% 0; }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* \u2500\u2500 MediaSkeleton \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
135
|
+
|
|
136
|
+
/* Loading-aware media container.
|
|
137
|
+
Reserves space via aspect-ratio (set inline by the component).
|
|
138
|
+
Child constraints enforced via React.cloneElement inline styles. */
|
|
139
|
+
.sk-media {
|
|
140
|
+
overflow: hidden;
|
|
141
|
+
}
|
|
142
|
+
.sk-media-shimmer {
|
|
143
|
+
position: absolute;
|
|
144
|
+
inset: 0;
|
|
145
|
+
border-radius: var(--sk-shimmer-radius, 0.125rem);
|
|
146
|
+
background: linear-gradient(
|
|
147
|
+
90deg,
|
|
148
|
+
var(--sk-shimmer-color, #e5e7eb) 25%,
|
|
149
|
+
var(--sk-shimmer-highlight, #f3f4f6) 50%,
|
|
150
|
+
var(--sk-shimmer-color, #e5e7eb) 75%
|
|
151
|
+
);
|
|
152
|
+
background-size: 200% 100%;
|
|
153
|
+
animation: sk-shimmer var(--sk-shimmer-duration, 1.5s) ease-in-out infinite;
|
|
154
|
+
transition: opacity var(--sk-loading-exit-duration, 400ms) var(--sk-ease-decelerate);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* \u2500\u2500 Shared easing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
158
|
+
|
|
159
|
+
/* Decelerate: fast start, gentle finish \u2014 for elements entering view. */
|
|
160
|
+
/* Standard: balanced ease \u2014 for general-purpose transitions. */
|
|
161
|
+
/* Accelerate: gentle start, fast finish \u2014 for elements leaving view. */
|
|
162
|
+
:root {
|
|
163
|
+
--sk-ease-decelerate: cubic-bezier(0.05, 0.7, 0.1, 1.0);
|
|
164
|
+
--sk-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
|
|
165
|
+
--sk-ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* \u2500\u2500 FadeTransition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
169
|
+
|
|
170
|
+
.sk-fade {
|
|
171
|
+
--sk-fade-duration: 400ms;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.sk-fade-entering {
|
|
175
|
+
animation: sk-emerge var(--sk-fade-duration) var(--sk-ease-decelerate) forwards;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.sk-fade-exiting {
|
|
179
|
+
animation: sk-collapse var(--sk-fade-duration) var(--sk-ease-accelerate) forwards;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@keyframes sk-emerge {
|
|
183
|
+
from {
|
|
184
|
+
opacity: 0;
|
|
185
|
+
transform: translateY(var(--sk-fade-offset-y, -12px)) scale(var(--sk-fade-offset-scale, 0.98));
|
|
186
|
+
}
|
|
187
|
+
to {
|
|
188
|
+
opacity: 1;
|
|
189
|
+
transform: translateY(0) scale(1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@keyframes sk-collapse {
|
|
194
|
+
from { opacity: 1; transform: scaleY(1); transform-origin: top; }
|
|
195
|
+
to { opacity: 0; transform: scaleY(0); transform-origin: top; }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* \u2500\u2500 Loading layers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
199
|
+
|
|
200
|
+
/* Shared by shimmer and content layers inside skeleton components.
|
|
201
|
+
Both layers permanently occupy the same grid cell; only opacity
|
|
202
|
+
and interactivity change. CSS transitions handle the crossfade. */
|
|
203
|
+
.sk-loading-layer {
|
|
204
|
+
grid-area: 1 / 1;
|
|
205
|
+
transition: opacity var(--sk-loading-exit-duration, 400ms) var(--sk-ease-decelerate);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* \u2500\u2500 Reduced motion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
209
|
+
|
|
210
|
+
/* Disables all animations \u2014 shimmer, fade, and loading exit.
|
|
211
|
+
Layout changes still happen instantly so functionality is preserved. */
|
|
212
|
+
@media (prefers-reduced-motion: reduce) {
|
|
213
|
+
.sk-fade-entering,
|
|
214
|
+
.sk-fade-exiting,
|
|
215
|
+
.sk-shimmer-line,
|
|
216
|
+
.sk-media-shimmer {
|
|
217
|
+
animation-duration: 0s !important;
|
|
218
|
+
}
|
|
219
|
+
.sk-loading-layer,
|
|
220
|
+
.sk-media-shimmer {
|
|
221
|
+
transition-duration: 0s !important;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
// src/internal/inject-styles.ts
|
|
227
|
+
var injected = false;
|
|
228
|
+
function injectStyles() {
|
|
229
|
+
if (injected || typeof document === "undefined") return;
|
|
230
|
+
if (document.querySelector('meta[name="stablekit-disable-injection"]')) {
|
|
231
|
+
injected = true;
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (document.querySelector("style[data-stablekit]")) {
|
|
235
|
+
injected = true;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const style = document.createElement("style");
|
|
239
|
+
style.setAttribute("data-stablekit", "");
|
|
240
|
+
const nonceMeta = document.querySelector('meta[name="stablekit-nonce"]');
|
|
241
|
+
if (nonceMeta) {
|
|
242
|
+
const nonce = nonceMeta.getAttribute("content");
|
|
243
|
+
if (nonce) style.setAttribute("nonce", nonce);
|
|
244
|
+
}
|
|
245
|
+
style.textContent = styles_default;
|
|
246
|
+
document.head.appendChild(style);
|
|
247
|
+
injected = true;
|
|
248
|
+
}
|
|
249
|
+
injectStyles();
|
|
250
|
+
|
|
251
|
+
// src/internal/merge-refs.ts
|
|
252
|
+
function mergeRefs(...refs) {
|
|
253
|
+
return (value) => {
|
|
254
|
+
for (const ref of refs) {
|
|
255
|
+
if (typeof ref === "function") {
|
|
256
|
+
ref(value);
|
|
257
|
+
} else if (ref != null) {
|
|
258
|
+
ref.current = value;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/internal/invariant.ts
|
|
265
|
+
function invariant(condition, message) {
|
|
266
|
+
if (condition) return;
|
|
267
|
+
if (process.env.NODE_ENV !== "production") {
|
|
268
|
+
throw new Error(`StableKit: ${message}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function warning(condition, message) {
|
|
272
|
+
if (condition) return;
|
|
273
|
+
if (process.env.NODE_ENV !== "production") {
|
|
274
|
+
console.warn(`StableKit Warning: ${message}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// src/components/layout-group.tsx
|
|
279
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
280
|
+
var AxisContext = (0, import_react.createContext)("both");
|
|
281
|
+
var NO_PROVIDER = /* @__PURE__ */ Symbol("sk-no-layout-group");
|
|
282
|
+
var ActiveValueContext = (0, import_react.createContext)(NO_PROVIDER);
|
|
283
|
+
var FocusHandoffContext = (0, import_react.createContext)(null);
|
|
284
|
+
var LayoutGroup = (0, import_react.forwardRef)(
|
|
285
|
+
function LayoutGroup2({ axis = "both", value, as: Tag = "div", className, style, children, ...props }, ref) {
|
|
286
|
+
(0, import_react.useInsertionEffect)(injectStyles, []);
|
|
287
|
+
warning(
|
|
288
|
+
value !== void 0,
|
|
289
|
+
"<LayoutGroup> rendered without a 'value' prop. All named <LayoutView> children will default to active, which may cause overlapping layouts."
|
|
290
|
+
);
|
|
291
|
+
const internalRef = (0, import_react.useRef)(null);
|
|
292
|
+
const hadFocusRef = (0, import_react.useRef)(false);
|
|
293
|
+
(0, import_react.useEffect)(() => {
|
|
294
|
+
const el = internalRef.current;
|
|
295
|
+
if (!el) return;
|
|
296
|
+
const onFocusIn = () => {
|
|
297
|
+
hadFocusRef.current = true;
|
|
298
|
+
};
|
|
299
|
+
const onFocusOut = (e) => {
|
|
300
|
+
const target = e.relatedTarget;
|
|
301
|
+
if (target && !el.contains(target)) {
|
|
302
|
+
hadFocusRef.current = false;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
el.addEventListener("focusin", onFocusIn);
|
|
306
|
+
el.addEventListener("focusout", onFocusOut);
|
|
307
|
+
return () => {
|
|
308
|
+
el.removeEventListener("focusin", onFocusIn);
|
|
309
|
+
el.removeEventListener("focusout", onFocusOut);
|
|
310
|
+
};
|
|
311
|
+
}, []);
|
|
312
|
+
const focusCtx = (0, import_react.useMemo)(() => ({ hadFocusRef }), []);
|
|
313
|
+
const merged = className ? `sk-layout-group ${className}` : "sk-layout-group";
|
|
314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AxisContext.Provider, { value: axis, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActiveValueContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FocusHandoffContext.Provider, { value: focusCtx, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag, { ref: mergeRefs(ref, internalRef), className: merged, style, ...props, children }) }) }) });
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
// src/components/layout-view.tsx
|
|
319
|
+
var import_react2 = require("react");
|
|
320
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
321
|
+
var LayoutView = (0, import_react2.forwardRef)(
|
|
322
|
+
function LayoutView2({ active, name, as: Tag = "div", style, className, children, ...props }, ref) {
|
|
323
|
+
(0, import_react2.useInsertionEffect)(injectStyles, []);
|
|
324
|
+
(0, import_react2.useContext)(AxisContext);
|
|
325
|
+
const rawActiveValue = (0, import_react2.useContext)(ActiveValueContext);
|
|
326
|
+
const focusCtx = (0, import_react2.useContext)(FocusHandoffContext);
|
|
327
|
+
invariant(
|
|
328
|
+
!(name != null && typeof rawActiveValue === "symbol"),
|
|
329
|
+
"<LayoutView> with a 'name' prop must be rendered inside a <LayoutGroup> or <LayoutMap>."
|
|
330
|
+
);
|
|
331
|
+
const activeValue = typeof rawActiveValue === "symbol" ? void 0 : rawActiveValue;
|
|
332
|
+
const isActive = active ?? (name != null ? name === activeValue : true);
|
|
333
|
+
const internalRef = (0, import_react2.useRef)(null);
|
|
334
|
+
const prevActiveRef = (0, import_react2.useRef)(isActive);
|
|
335
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
336
|
+
const wasActive = prevActiveRef.current;
|
|
337
|
+
prevActiveRef.current = isActive;
|
|
338
|
+
if (!isActive || wasActive) return;
|
|
339
|
+
if (!focusCtx?.hadFocusRef.current) return;
|
|
340
|
+
const current = document.activeElement;
|
|
341
|
+
if (current && current !== document.body && !current.closest?.("[inert]")) return;
|
|
342
|
+
internalRef.current?.focus({ preventScroll: true });
|
|
343
|
+
});
|
|
344
|
+
const viewClass = className ? `sk-layout-view ${className}` : "sk-layout-view";
|
|
345
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
346
|
+
Tag,
|
|
347
|
+
{
|
|
348
|
+
ref: mergeRefs(ref, internalRef),
|
|
349
|
+
className: viewClass,
|
|
350
|
+
"data-state": isActive ? "active" : "inactive",
|
|
351
|
+
tabIndex: isActive ? -1 : void 0,
|
|
352
|
+
inert: !isActive || void 0,
|
|
353
|
+
style,
|
|
354
|
+
...props,
|
|
355
|
+
children
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
// src/components/state-swap.tsx
|
|
362
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
363
|
+
function StateSwap({
|
|
364
|
+
state,
|
|
365
|
+
true: onTrue,
|
|
366
|
+
false: onFalse,
|
|
367
|
+
as: Tag = "span",
|
|
368
|
+
...props
|
|
369
|
+
}) {
|
|
370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(LayoutGroup, { as: Tag, value: state ? "true" : "false", axis: "both", "data-inline": true, ...props, children: [
|
|
371
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LayoutView, { as: "span", name: "true", children: onTrue }),
|
|
372
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LayoutView, { as: "span", name: "false", children: onFalse })
|
|
373
|
+
] });
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/components/layout-map.tsx
|
|
377
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
378
|
+
function LayoutMap({ value, map, ...props }) {
|
|
379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LayoutGroup, { value, ...props, children: Object.entries(map).map(([key, node]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LayoutView, { name: key, children: node }, key)) });
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/components/size-ratchet.tsx
|
|
383
|
+
var import_react4 = require("react");
|
|
384
|
+
|
|
385
|
+
// src/primitives/use-stable-slot.ts
|
|
386
|
+
var import_react3 = require("react");
|
|
387
|
+
var RATCHET_FLOOR = -Infinity;
|
|
388
|
+
function useStableSlot(options = {}) {
|
|
389
|
+
const { axis = "both", resetKey } = options;
|
|
390
|
+
const [style, setStyle] = (0, import_react3.useState)({});
|
|
391
|
+
const maxRef = (0, import_react3.useRef)({ w: RATCHET_FLOOR, h: RATCHET_FLOOR });
|
|
392
|
+
const observerRef = (0, import_react3.useRef)(null);
|
|
393
|
+
const prevResetKeyRef = (0, import_react3.useRef)(resetKey);
|
|
394
|
+
(0, import_react3.useEffect)(() => {
|
|
395
|
+
if (prevResetKeyRef.current !== resetKey) {
|
|
396
|
+
prevResetKeyRef.current = resetKey;
|
|
397
|
+
maxRef.current = { w: RATCHET_FLOOR, h: RATCHET_FLOOR };
|
|
398
|
+
setStyle({});
|
|
399
|
+
}
|
|
400
|
+
}, [resetKey]);
|
|
401
|
+
const ref = (0, import_react3.useCallback)(
|
|
402
|
+
(el) => {
|
|
403
|
+
if (observerRef.current) {
|
|
404
|
+
observerRef.current.disconnect();
|
|
405
|
+
observerRef.current = null;
|
|
406
|
+
}
|
|
407
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
408
|
+
const observer = new ResizeObserver((entries) => {
|
|
409
|
+
for (const entry of entries) {
|
|
410
|
+
let w;
|
|
411
|
+
let h;
|
|
412
|
+
if (entry.borderBoxSize?.length) {
|
|
413
|
+
const box = entry.borderBoxSize[0];
|
|
414
|
+
w = box.inlineSize;
|
|
415
|
+
h = box.blockSize;
|
|
416
|
+
} else {
|
|
417
|
+
const rect = entry.target.getBoundingClientRect();
|
|
418
|
+
w = rect.width;
|
|
419
|
+
h = rect.height;
|
|
420
|
+
}
|
|
421
|
+
const max = maxRef.current;
|
|
422
|
+
let grew = false;
|
|
423
|
+
if ((axis === "width" || axis === "both") && w > max.w) {
|
|
424
|
+
max.w = w;
|
|
425
|
+
grew = true;
|
|
426
|
+
}
|
|
427
|
+
if ((axis === "height" || axis === "both") && h > max.h) {
|
|
428
|
+
max.h = h;
|
|
429
|
+
grew = true;
|
|
430
|
+
}
|
|
431
|
+
if (grew) {
|
|
432
|
+
const next = {};
|
|
433
|
+
if (axis === "width" || axis === "both") next.minWidth = max.w;
|
|
434
|
+
if (axis === "height" || axis === "both") next.minHeight = max.h;
|
|
435
|
+
setStyle(next);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
observer.observe(el, { box: "border-box" });
|
|
440
|
+
observerRef.current = observer;
|
|
441
|
+
},
|
|
442
|
+
[axis]
|
|
443
|
+
);
|
|
444
|
+
return { ref, style };
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// src/components/size-ratchet.tsx
|
|
448
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
449
|
+
var SizeRatchet = (0, import_react4.forwardRef)(
|
|
450
|
+
function SizeRatchet2({ axis = "height", resetKey, as: Tag = "div", className, style, children, ...props }, fwdRef) {
|
|
451
|
+
(0, import_react4.useInsertionEffect)(injectStyles, []);
|
|
452
|
+
const { ref: ratchetRef, style: ratchetStyle } = useStableSlot({ axis, resetKey });
|
|
453
|
+
const merged = className ? `sk-size-ratchet ${className}` : "sk-size-ratchet";
|
|
454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
455
|
+
Tag,
|
|
456
|
+
{
|
|
457
|
+
ref: mergeRefs(ratchetRef, fwdRef),
|
|
458
|
+
className: merged,
|
|
459
|
+
style: { ...ratchetStyle, ...style },
|
|
460
|
+
...props,
|
|
461
|
+
children
|
|
462
|
+
}
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
// src/components/stable-counter.tsx
|
|
468
|
+
var import_react5 = require("react");
|
|
469
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
470
|
+
var GHOST_STYLE = {
|
|
471
|
+
visibility: "hidden",
|
|
472
|
+
gridArea: "1 / 1",
|
|
473
|
+
pointerEvents: "none"
|
|
474
|
+
};
|
|
475
|
+
var VALUE_STYLE = {
|
|
476
|
+
gridArea: "1 / 1"
|
|
477
|
+
};
|
|
478
|
+
var StableCounter = (0, import_react5.forwardRef)(
|
|
479
|
+
function StableCounter2({ value, reserve, as: Tag = "span", style, className, ...props }, ref) {
|
|
480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
481
|
+
Tag,
|
|
482
|
+
{
|
|
483
|
+
ref,
|
|
484
|
+
className,
|
|
485
|
+
style: { ...style, display: "inline-grid" },
|
|
486
|
+
...props,
|
|
487
|
+
children: [
|
|
488
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": "true", style: GHOST_STYLE, children: reserve }),
|
|
489
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: VALUE_STYLE, children: value })
|
|
490
|
+
]
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
// src/components/stable-field.tsx
|
|
497
|
+
var import_react6 = require("react");
|
|
498
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
499
|
+
var GHOST_STYLE2 = {
|
|
500
|
+
visibility: "hidden",
|
|
501
|
+
gridArea: "1 / 1",
|
|
502
|
+
pointerEvents: "none"
|
|
503
|
+
};
|
|
504
|
+
var ERROR_STYLE = {
|
|
505
|
+
gridArea: "1 / 1"
|
|
506
|
+
};
|
|
507
|
+
var ERROR_HIDDEN_STYLE = {
|
|
508
|
+
gridArea: "1 / 1",
|
|
509
|
+
visibility: "hidden"
|
|
510
|
+
};
|
|
511
|
+
var StableField = (0, import_react6.forwardRef)(
|
|
512
|
+
function StableField2({ error, reserve, children, style, className, ...props }, ref) {
|
|
513
|
+
const hasError = error != null && error !== false && error !== "";
|
|
514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref, className, style, ...props, children: [
|
|
515
|
+
children,
|
|
516
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "grid" }, children: [
|
|
517
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", style: GHOST_STYLE2, children: reserve }),
|
|
518
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
519
|
+
"span",
|
|
520
|
+
{
|
|
521
|
+
role: hasError ? "alert" : void 0,
|
|
522
|
+
style: hasError ? ERROR_STYLE : ERROR_HIDDEN_STYLE,
|
|
523
|
+
children: hasError ? error : null
|
|
524
|
+
}
|
|
525
|
+
)
|
|
526
|
+
] })
|
|
527
|
+
] });
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
// src/components/loading-boundary.tsx
|
|
532
|
+
var import_react8 = require("react");
|
|
533
|
+
|
|
534
|
+
// src/components/loading-context.tsx
|
|
535
|
+
var import_react7 = require("react");
|
|
536
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
537
|
+
var LoadingStateContext = (0, import_react7.createContext)(false);
|
|
538
|
+
function useLoadingState() {
|
|
539
|
+
return (0, import_react7.useContext)(LoadingStateContext);
|
|
540
|
+
}
|
|
541
|
+
function LoadingContext({ loading, children }) {
|
|
542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LoadingStateContext.Provider, { value: loading, children });
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// src/components/loading-boundary.tsx
|
|
546
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
547
|
+
var LoadingBoundary = (0, import_react8.forwardRef)(
|
|
548
|
+
function LoadingBoundary2({ loading, exitDuration, as: Tag = "div", className, style, children, ...props }, ref) {
|
|
549
|
+
(0, import_react8.useInsertionEffect)(injectStyles, []);
|
|
550
|
+
const merged = {
|
|
551
|
+
...style,
|
|
552
|
+
"--sk-loading-exit-duration": `${exitDuration}ms`
|
|
553
|
+
};
|
|
554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SizeRatchet, { ref, axis: "height", as: Tag, className, style: merged, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LoadingContext, { loading, children }) });
|
|
555
|
+
}
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
// src/components/text-skeleton.tsx
|
|
559
|
+
var import_react9 = require("react");
|
|
560
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
561
|
+
function TextSkeleton({ loading, as: Tag = "span", className, style, children, ...props }) {
|
|
562
|
+
(0, import_react9.useInsertionEffect)(injectStyles, []);
|
|
563
|
+
const contextLoading = useLoadingState();
|
|
564
|
+
const isLoading = loading ?? contextLoading;
|
|
565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tag, { className, style: { ...style, display: "inline-grid" }, ...props, children: [
|
|
566
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
567
|
+
"span",
|
|
568
|
+
{
|
|
569
|
+
className: "sk-shimmer-line sk-loading-layer",
|
|
570
|
+
"aria-hidden": "true",
|
|
571
|
+
style: { opacity: isLoading ? 1 : 0 },
|
|
572
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { inert: true, children })
|
|
573
|
+
}
|
|
574
|
+
),
|
|
575
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
576
|
+
"span",
|
|
577
|
+
{
|
|
578
|
+
className: "sk-loading-layer",
|
|
579
|
+
style: { opacity: isLoading ? 0 : 1 },
|
|
580
|
+
inert: isLoading || void 0,
|
|
581
|
+
children
|
|
582
|
+
}
|
|
583
|
+
)
|
|
584
|
+
] });
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// src/components/stable-text.tsx
|
|
588
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
589
|
+
function StableText({
|
|
590
|
+
as: Tag = "p",
|
|
591
|
+
loading,
|
|
592
|
+
children,
|
|
593
|
+
...props
|
|
594
|
+
}) {
|
|
595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Tag, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TextSkeleton, { loading, children }) });
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/components/media-skeleton.tsx
|
|
599
|
+
var import_react10 = require("react");
|
|
600
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
601
|
+
var CHILD_STYLE = {
|
|
602
|
+
position: "absolute",
|
|
603
|
+
inset: 0,
|
|
604
|
+
width: "100%",
|
|
605
|
+
height: "100%",
|
|
606
|
+
objectFit: "cover"
|
|
607
|
+
};
|
|
608
|
+
function MediaSkeleton({
|
|
609
|
+
aspectRatio,
|
|
610
|
+
loading,
|
|
611
|
+
className,
|
|
612
|
+
style,
|
|
613
|
+
children,
|
|
614
|
+
...props
|
|
615
|
+
}) {
|
|
616
|
+
(0, import_react10.useInsertionEffect)(injectStyles, []);
|
|
617
|
+
const contextLoading = useLoadingState();
|
|
618
|
+
const isLoading = loading ?? contextLoading;
|
|
619
|
+
const [mediaReady, setMediaReady] = (0, import_react10.useState)(false);
|
|
620
|
+
const childRef = (0, import_react10.useRef)(null);
|
|
621
|
+
(0, import_react10.useEffect)(() => {
|
|
622
|
+
if (isLoading) setMediaReady(false);
|
|
623
|
+
}, [isLoading]);
|
|
624
|
+
(0, import_react10.useEffect)(() => {
|
|
625
|
+
const el = childRef.current;
|
|
626
|
+
if (el instanceof HTMLImageElement && el.complete && el.naturalWidth > 0) {
|
|
627
|
+
setMediaReady(true);
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
const handleLoad = (0, import_react10.useCallback)(() => setMediaReady(true), []);
|
|
631
|
+
const showShimmer = isLoading || !mediaReady;
|
|
632
|
+
const containerStyle = {
|
|
633
|
+
position: "relative",
|
|
634
|
+
overflow: "hidden",
|
|
635
|
+
aspectRatio,
|
|
636
|
+
...style
|
|
637
|
+
};
|
|
638
|
+
const containerClass = showShimmer ? className ? `sk-media sk-media-loading ${className}` : "sk-media sk-media-loading" : className ? `sk-media ${className}` : "sk-media";
|
|
639
|
+
const child = import_react10.Children.only(children);
|
|
640
|
+
const existingOnLoad = child.props.onLoad;
|
|
641
|
+
const clonedChild = (0, import_react10.isValidElement)(child) ? (0, import_react10.cloneElement)(child, {
|
|
642
|
+
ref: childRef,
|
|
643
|
+
onLoad: (e) => {
|
|
644
|
+
handleLoad();
|
|
645
|
+
existingOnLoad?.(e);
|
|
646
|
+
},
|
|
647
|
+
style: {
|
|
648
|
+
...CHILD_STYLE,
|
|
649
|
+
opacity: showShimmer ? 0 : 1,
|
|
650
|
+
transition: "opacity var(--sk-loading-exit-duration, 400ms) var(--sk-ease-decelerate)",
|
|
651
|
+
...child.props.style
|
|
652
|
+
}
|
|
653
|
+
}) : child;
|
|
654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: containerClass, style: containerStyle, ...props, children: [
|
|
655
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
656
|
+
"div",
|
|
657
|
+
{
|
|
658
|
+
className: "sk-media-shimmer",
|
|
659
|
+
"aria-hidden": "true",
|
|
660
|
+
style: { opacity: showShimmer ? 1 : 0 }
|
|
661
|
+
}
|
|
662
|
+
),
|
|
663
|
+
clonedChild
|
|
664
|
+
] });
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// src/components/collection-skeleton.tsx
|
|
668
|
+
var import_react12 = require("react");
|
|
669
|
+
|
|
670
|
+
// src/components/skeleton-grid.tsx
|
|
671
|
+
var import_react11 = require("react");
|
|
672
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
673
|
+
var SkeletonGrid = (0, import_react11.forwardRef)(
|
|
674
|
+
function SkeletonGrid2({ rows, columns, as: Tag = "div", className, children, ...props }, ref) {
|
|
675
|
+
(0, import_react11.useInsertionEffect)(injectStyles, []);
|
|
676
|
+
const merged = className ? `sk-skeleton-grid ${className}` : "sk-skeleton-grid";
|
|
677
|
+
const count = columns ? rows * columns : rows;
|
|
678
|
+
const cells = Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sk-skeleton-bone", children: [
|
|
679
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sk-shimmer-line" }),
|
|
680
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sk-shimmer-line" })
|
|
681
|
+
] }, i));
|
|
682
|
+
const gridStyle = columns ? { gridTemplateColumns: `repeat(${columns}, auto)` } : void 0;
|
|
683
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
684
|
+
Tag,
|
|
685
|
+
{
|
|
686
|
+
ref,
|
|
687
|
+
className: merged,
|
|
688
|
+
style: gridStyle,
|
|
689
|
+
...props,
|
|
690
|
+
children: cells
|
|
691
|
+
}
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
// src/components/collection-skeleton.tsx
|
|
697
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
698
|
+
function CollectionSkeletonInner({
|
|
699
|
+
items,
|
|
700
|
+
loading,
|
|
701
|
+
renderItem,
|
|
702
|
+
stubCount,
|
|
703
|
+
exitDuration,
|
|
704
|
+
as: Tag = "div",
|
|
705
|
+
className,
|
|
706
|
+
style,
|
|
707
|
+
...props
|
|
708
|
+
}, ref) {
|
|
709
|
+
(0, import_react12.useInsertionEffect)(injectStyles, []);
|
|
710
|
+
const merged = {
|
|
711
|
+
...style,
|
|
712
|
+
display: "grid",
|
|
713
|
+
"--sk-loading-exit-duration": `${exitDuration}ms`
|
|
714
|
+
};
|
|
715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(SizeRatchet, { ref, axis: "height", as: Tag, className, style: merged, ...props, children: [
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
717
|
+
"div",
|
|
718
|
+
{
|
|
719
|
+
className: "sk-loading-layer",
|
|
720
|
+
"aria-hidden": "true",
|
|
721
|
+
style: { opacity: loading ? 1 : 0 },
|
|
722
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SkeletonGrid, { rows: stubCount })
|
|
723
|
+
}
|
|
724
|
+
),
|
|
725
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
726
|
+
"div",
|
|
727
|
+
{
|
|
728
|
+
className: "sk-loading-layer",
|
|
729
|
+
style: { opacity: loading ? 0 : 1 },
|
|
730
|
+
inert: loading || void 0,
|
|
731
|
+
children: items.map(renderItem)
|
|
732
|
+
}
|
|
733
|
+
)
|
|
734
|
+
] });
|
|
735
|
+
}
|
|
736
|
+
var CollectionSkeleton = (0, import_react12.forwardRef)(CollectionSkeletonInner);
|
|
737
|
+
|
|
738
|
+
// src/components/fade-transition.tsx
|
|
739
|
+
var import_react14 = require("react");
|
|
740
|
+
|
|
741
|
+
// src/primitives/use-presence.ts
|
|
742
|
+
var import_react13 = require("react");
|
|
743
|
+
function usePresence(show) {
|
|
744
|
+
const [mounted, setMounted] = (0, import_react13.useState)(show);
|
|
745
|
+
const [phase, setPhase] = (0, import_react13.useState)(show ? "entered" : "exiting");
|
|
746
|
+
(0, import_react13.useEffect)(() => {
|
|
747
|
+
if (show) {
|
|
748
|
+
setMounted(true);
|
|
749
|
+
setPhase("entering");
|
|
750
|
+
} else if (mounted) {
|
|
751
|
+
setPhase("exiting");
|
|
752
|
+
}
|
|
753
|
+
}, [show]);
|
|
754
|
+
const onAnimationEnd = (0, import_react13.useCallback)(
|
|
755
|
+
(e) => {
|
|
756
|
+
if (e.target !== e.currentTarget) return;
|
|
757
|
+
if (phase === "entering") setPhase("entered");
|
|
758
|
+
if (phase === "exiting") setMounted(false);
|
|
759
|
+
},
|
|
760
|
+
[phase]
|
|
761
|
+
);
|
|
762
|
+
return { mounted, phase, onAnimationEnd };
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// src/components/fade-transition.tsx
|
|
766
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
767
|
+
var FadeTransition = (0, import_react14.forwardRef)(
|
|
768
|
+
function FadeTransition2({ show, as: Tag = "div", className, style, children, ...props }, fwdRef) {
|
|
769
|
+
(0, import_react14.useInsertionEffect)(injectStyles, []);
|
|
770
|
+
const { mounted, phase, onAnimationEnd } = usePresence(show);
|
|
771
|
+
if (!mounted) return null;
|
|
772
|
+
const phaseClass = phase === "entering" ? "sk-fade-entering" : phase === "exiting" ? "sk-fade-exiting" : "";
|
|
773
|
+
const merged = ["sk-fade", phaseClass, className].filter(Boolean).join(" ");
|
|
774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
775
|
+
Tag,
|
|
776
|
+
{
|
|
777
|
+
ref: fwdRef,
|
|
778
|
+
className: merged,
|
|
779
|
+
style,
|
|
780
|
+
onAnimationEnd,
|
|
781
|
+
...props,
|
|
782
|
+
children
|
|
783
|
+
}
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
// src/create-primitive.tsx
|
|
789
|
+
var import_react15 = require("react");
|
|
790
|
+
function createPrimitive(tag, baseClass, variants) {
|
|
791
|
+
const variantKeys = new Set(variants ? Object.keys(variants) : []);
|
|
792
|
+
function Primitive(props) {
|
|
793
|
+
const htmlProps = { className: baseClass };
|
|
794
|
+
for (const [key, value] of Object.entries(props)) {
|
|
795
|
+
if (variantKeys.has(key)) {
|
|
796
|
+
htmlProps[`data-${key}`] = value;
|
|
797
|
+
} else {
|
|
798
|
+
htmlProps[key] = value;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return (0, import_react15.createElement)(tag, htmlProps);
|
|
802
|
+
}
|
|
803
|
+
return Primitive;
|
|
804
|
+
}
|
|
805
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
806
|
+
0 && (module.exports = {
|
|
807
|
+
CollectionSkeleton,
|
|
808
|
+
FadeTransition,
|
|
809
|
+
LayoutGroup,
|
|
810
|
+
LayoutMap,
|
|
811
|
+
LayoutView,
|
|
812
|
+
LoadingBoundary,
|
|
813
|
+
LoadingContext,
|
|
814
|
+
MediaSkeleton,
|
|
815
|
+
SizeRatchet,
|
|
816
|
+
StableCounter,
|
|
817
|
+
StableField,
|
|
818
|
+
StableText,
|
|
819
|
+
StateSwap,
|
|
820
|
+
TextSkeleton,
|
|
821
|
+
createPrimitive,
|
|
822
|
+
useLoadingState
|
|
823
|
+
});
|