concertina 0.7.1 → 0.8.1
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/dist/index.cjs +147 -82
- package/dist/index.d.cts +101 -49
- package/dist/index.d.ts +101 -49
- package/dist/index.js +112 -50
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -45,13 +45,16 @@ __export(index_exports, {
|
|
|
45
45
|
pinToScrollTop: () => pinToScrollTop,
|
|
46
46
|
useConcertina: () => useConcertina,
|
|
47
47
|
useExpanded: () => useExpanded,
|
|
48
|
+
usePresence: () => usePresence2,
|
|
49
|
+
useScrollPin: () => useScrollPin,
|
|
50
|
+
useSize: () => useSize,
|
|
48
51
|
useStableSlot: () => useStableSlot,
|
|
49
52
|
useTransitionLock: () => useTransitionLock
|
|
50
53
|
});
|
|
51
54
|
module.exports = __toCommonJS(index_exports);
|
|
52
55
|
|
|
53
|
-
// src/root.tsx
|
|
54
|
-
var
|
|
56
|
+
// src/accordion/root.tsx
|
|
57
|
+
var import_react7 = require("react");
|
|
55
58
|
|
|
56
59
|
// node_modules/@radix-ui/react-accordion/dist/index.mjs
|
|
57
60
|
var import_react3 = __toESM(require("react"), 1);
|
|
@@ -1012,7 +1015,7 @@ var Header = AccordionHeader;
|
|
|
1012
1015
|
var Trigger2 = AccordionTrigger;
|
|
1013
1016
|
var Content2 = AccordionContent;
|
|
1014
1017
|
|
|
1015
|
-
// src/store.ts
|
|
1018
|
+
// src/accordion/store.ts
|
|
1016
1019
|
var import_react4 = require("react");
|
|
1017
1020
|
var ConcertinaStore = class {
|
|
1018
1021
|
constructor() {
|
|
@@ -1041,7 +1044,10 @@ var ConcertinaStore = class {
|
|
|
1041
1044
|
};
|
|
1042
1045
|
var ConcertinaContext = (0, import_react4.createContext)(null);
|
|
1043
1046
|
|
|
1044
|
-
// src/
|
|
1047
|
+
// src/primitives/use-scroll-pin.ts
|
|
1048
|
+
var import_react5 = require("react");
|
|
1049
|
+
|
|
1050
|
+
// src/primitives/pin-to-scroll-top.ts
|
|
1045
1051
|
function pinToScrollTop(el) {
|
|
1046
1052
|
if (!el) return;
|
|
1047
1053
|
let parent = el.parentElement;
|
|
@@ -1071,33 +1077,42 @@ function pinToScrollTop(el) {
|
|
|
1071
1077
|
}
|
|
1072
1078
|
}
|
|
1073
1079
|
|
|
1074
|
-
// src/use-
|
|
1075
|
-
|
|
1080
|
+
// src/primitives/use-scroll-pin.ts
|
|
1081
|
+
function useScrollPin(getElement, deps) {
|
|
1082
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
1083
|
+
const el = getElement();
|
|
1084
|
+
if (!el) return;
|
|
1085
|
+
pinToScrollTop(el);
|
|
1086
|
+
}, deps);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// src/primitives/use-transition-lock.ts
|
|
1090
|
+
var import_react6 = require("react");
|
|
1076
1091
|
function useTransitionLock() {
|
|
1077
|
-
const [locked, setLocked] = (0,
|
|
1078
|
-
const lock = (0,
|
|
1079
|
-
(0,
|
|
1092
|
+
const [locked, setLocked] = (0, import_react6.useState)(false);
|
|
1093
|
+
const lock = (0, import_react6.useCallback)(() => setLocked(true), []);
|
|
1094
|
+
(0, import_react6.useEffect)(() => {
|
|
1080
1095
|
if (locked) setLocked(false);
|
|
1081
1096
|
}, [locked]);
|
|
1082
1097
|
return { locked, lock };
|
|
1083
1098
|
}
|
|
1084
1099
|
|
|
1085
|
-
// src/root.tsx
|
|
1100
|
+
// src/accordion/root.tsx
|
|
1086
1101
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1087
|
-
var Root3 = (0,
|
|
1102
|
+
var Root3 = (0, import_react7.forwardRef)(
|
|
1088
1103
|
function Root4({ collapsible = true, children, ...props }, forwardedRef) {
|
|
1089
|
-
const storeRef = (0,
|
|
1104
|
+
const storeRef = (0, import_react7.useRef)(null);
|
|
1090
1105
|
if (!storeRef.current) {
|
|
1091
1106
|
storeRef.current = new ConcertinaStore();
|
|
1092
1107
|
}
|
|
1093
1108
|
const store = storeRef.current;
|
|
1094
|
-
const value = (0,
|
|
1109
|
+
const value = (0, import_react7.useSyncExternalStore)(
|
|
1095
1110
|
store.subscribe,
|
|
1096
1111
|
store.getValue,
|
|
1097
1112
|
store.getValue
|
|
1098
1113
|
);
|
|
1099
1114
|
const { locked, lock } = useTransitionLock();
|
|
1100
|
-
const onValueChange = (0,
|
|
1115
|
+
const onValueChange = (0, import_react7.useCallback)(
|
|
1101
1116
|
(newValue) => {
|
|
1102
1117
|
const isSwitching = !!store.getValue() && store.getValue() !== newValue && !!newValue;
|
|
1103
1118
|
if (isSwitching) lock();
|
|
@@ -1105,10 +1120,10 @@ var Root3 = (0, import_react6.forwardRef)(
|
|
|
1105
1120
|
},
|
|
1106
1121
|
[store, lock]
|
|
1107
1122
|
);
|
|
1108
|
-
(
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1123
|
+
useScrollPin(
|
|
1124
|
+
() => value ? store.getItemRef(value) : null,
|
|
1125
|
+
[value, store]
|
|
1126
|
+
);
|
|
1112
1127
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ConcertinaContext.Provider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1113
1128
|
Root2,
|
|
1114
1129
|
{
|
|
@@ -1125,12 +1140,12 @@ var Root3 = (0, import_react6.forwardRef)(
|
|
|
1125
1140
|
}
|
|
1126
1141
|
);
|
|
1127
1142
|
|
|
1128
|
-
// src/item.tsx
|
|
1129
|
-
var
|
|
1143
|
+
// src/accordion/item.tsx
|
|
1144
|
+
var import_react8 = require("react");
|
|
1130
1145
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1131
|
-
var Item2 = (0,
|
|
1132
|
-
const store = (0,
|
|
1133
|
-
const mergedRef = (0,
|
|
1146
|
+
var Item2 = (0, import_react8.forwardRef)(function Item3({ value, ...props }, forwardedRef) {
|
|
1147
|
+
const store = (0, import_react8.useContext)(ConcertinaContext);
|
|
1148
|
+
const mergedRef = (0, import_react8.useCallback)(
|
|
1134
1149
|
(el) => {
|
|
1135
1150
|
if (typeof forwardedRef === "function") {
|
|
1136
1151
|
forwardedRef(el);
|
|
@@ -1144,18 +1159,18 @@ var Item2 = (0, import_react7.forwardRef)(function Item3({ value, ...props }, fo
|
|
|
1144
1159
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Item, { ref: mergedRef, value, ...props });
|
|
1145
1160
|
});
|
|
1146
1161
|
|
|
1147
|
-
// src/content.tsx
|
|
1148
|
-
var
|
|
1162
|
+
// src/accordion/content.tsx
|
|
1163
|
+
var import_react9 = require("react");
|
|
1149
1164
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1150
|
-
var Content3 = (0,
|
|
1165
|
+
var Content3 = (0, import_react9.forwardRef)(function Content4({ className, ...props }, ref) {
|
|
1151
1166
|
const merged = className ? `concertina-content ${className}` : "concertina-content";
|
|
1152
1167
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Content2, { ref, className: merged, ...props });
|
|
1153
1168
|
});
|
|
1154
1169
|
|
|
1155
|
-
// src/use-expanded.ts
|
|
1156
|
-
var
|
|
1170
|
+
// src/accordion/use-expanded.ts
|
|
1171
|
+
var import_react10 = require("react");
|
|
1157
1172
|
function useStore() {
|
|
1158
|
-
const store = (0,
|
|
1173
|
+
const store = (0, import_react10.useContext)(ConcertinaContext);
|
|
1159
1174
|
if (!store) {
|
|
1160
1175
|
throw new Error("useExpanded must be used inside <Concertina.Root>");
|
|
1161
1176
|
}
|
|
@@ -1163,7 +1178,7 @@ function useStore() {
|
|
|
1163
1178
|
}
|
|
1164
1179
|
function useExpanded(id) {
|
|
1165
1180
|
const store = useStore();
|
|
1166
|
-
return (0,
|
|
1181
|
+
return (0, import_react10.useSyncExternalStore)(
|
|
1167
1182
|
store.subscribe,
|
|
1168
1183
|
() => store.getValue() === id,
|
|
1169
1184
|
() => false
|
|
@@ -1171,26 +1186,26 @@ function useExpanded(id) {
|
|
|
1171
1186
|
);
|
|
1172
1187
|
}
|
|
1173
1188
|
|
|
1174
|
-
// src/stable-slot.tsx
|
|
1175
|
-
var
|
|
1189
|
+
// src/components/stable-slot.tsx
|
|
1190
|
+
var import_react11 = require("react");
|
|
1176
1191
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1177
|
-
var AxisContext = (0,
|
|
1178
|
-
var StableSlot = (0,
|
|
1192
|
+
var AxisContext = (0, import_react11.createContext)("both");
|
|
1193
|
+
var StableSlot = (0, import_react11.forwardRef)(
|
|
1179
1194
|
function StableSlot2({ axis = "both", as: Tag = "div", className, style, children, ...props }, ref) {
|
|
1180
1195
|
const merged = className ? `concertina-stable-slot ${className}` : "concertina-stable-slot";
|
|
1181
1196
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AxisContext.Provider, { value: axis, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tag, { ref, className: merged, style, ...props, children }) });
|
|
1182
1197
|
}
|
|
1183
1198
|
);
|
|
1184
1199
|
|
|
1185
|
-
// src/slot.tsx
|
|
1186
|
-
var
|
|
1200
|
+
// src/components/slot.tsx
|
|
1201
|
+
var import_react12 = require("react");
|
|
1187
1202
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1188
1203
|
function inactiveStyle(_axis) {
|
|
1189
1204
|
return { visibility: "hidden" };
|
|
1190
1205
|
}
|
|
1191
|
-
var Slot = (0,
|
|
1206
|
+
var Slot = (0, import_react12.forwardRef)(
|
|
1192
1207
|
function Slot2({ active, as: Tag = "div", style, children, ...props }, ref) {
|
|
1193
|
-
const axis = (0,
|
|
1208
|
+
const axis = (0, import_react12.useContext)(AxisContext);
|
|
1194
1209
|
const merged = active ? { ...style } : { ...inactiveStyle(axis), ...style };
|
|
1195
1210
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1196
1211
|
Tag,
|
|
@@ -1205,14 +1220,17 @@ var Slot = (0, import_react11.forwardRef)(
|
|
|
1205
1220
|
}
|
|
1206
1221
|
);
|
|
1207
1222
|
|
|
1208
|
-
// src/
|
|
1209
|
-
var
|
|
1223
|
+
// src/components/gigbag.tsx
|
|
1224
|
+
var import_react14 = require("react");
|
|
1225
|
+
|
|
1226
|
+
// src/primitives/use-stable-slot.ts
|
|
1227
|
+
var import_react13 = require("react");
|
|
1210
1228
|
function useStableSlot(options = {}) {
|
|
1211
1229
|
const { axis = "both" } = options;
|
|
1212
|
-
const [style, setStyle] = (0,
|
|
1213
|
-
const maxRef = (0,
|
|
1214
|
-
const observerRef = (0,
|
|
1215
|
-
const ref = (0,
|
|
1230
|
+
const [style, setStyle] = (0, import_react13.useState)({});
|
|
1231
|
+
const maxRef = (0, import_react13.useRef)({ w: 0, h: 0 });
|
|
1232
|
+
const observerRef = (0, import_react13.useRef)(null);
|
|
1233
|
+
const ref = (0, import_react13.useCallback)(
|
|
1216
1234
|
(el) => {
|
|
1217
1235
|
if (observerRef.current) {
|
|
1218
1236
|
observerRef.current.disconnect();
|
|
@@ -1258,10 +1276,9 @@ function useStableSlot(options = {}) {
|
|
|
1258
1276
|
return { ref, style };
|
|
1259
1277
|
}
|
|
1260
1278
|
|
|
1261
|
-
// src/gigbag.tsx
|
|
1262
|
-
var import_react13 = require("react");
|
|
1279
|
+
// src/components/gigbag.tsx
|
|
1263
1280
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1264
|
-
var Gigbag = (0,
|
|
1281
|
+
var Gigbag = (0, import_react14.forwardRef)(
|
|
1265
1282
|
function Gigbag2({ axis = "height", as: Tag = "div", className, style, children, ...props }, fwdRef) {
|
|
1266
1283
|
const { ref: ratchetRef, style: ratchetStyle } = useStableSlot({ axis });
|
|
1267
1284
|
const merged = className ? `concertina-gigbag ${className}` : "concertina-gigbag";
|
|
@@ -1282,52 +1299,64 @@ var Gigbag = (0, import_react13.forwardRef)(
|
|
|
1282
1299
|
}
|
|
1283
1300
|
);
|
|
1284
1301
|
|
|
1285
|
-
// src/warmup.tsx
|
|
1286
|
-
var
|
|
1302
|
+
// src/components/warmup.tsx
|
|
1303
|
+
var import_react15 = require("react");
|
|
1287
1304
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1288
|
-
var Warmup = (0,
|
|
1305
|
+
var Warmup = (0, import_react15.forwardRef)(
|
|
1289
1306
|
function Warmup2({ rows = 3, columns = 1, as: Tag = "div", className, children, ...props }, ref) {
|
|
1290
1307
|
const merged = className ? `concertina-warmup ${className}` : "concertina-warmup";
|
|
1291
1308
|
const cells = Array.from({ length: rows * columns }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "concertina-warmup-bone", children: [
|
|
1292
1309
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "concertina-warmup-line concertina-warmup-line-short" }),
|
|
1293
1310
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "concertina-warmup-line concertina-warmup-line-long" })
|
|
1294
1311
|
] }, i));
|
|
1295
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.
|
|
1312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1296
1313
|
Tag,
|
|
1297
1314
|
{
|
|
1298
1315
|
ref,
|
|
1299
1316
|
className: merged,
|
|
1300
1317
|
style: { gridTemplateColumns: `repeat(${columns}, 1fr)` },
|
|
1301
1318
|
...props,
|
|
1302
|
-
children:
|
|
1319
|
+
children: [
|
|
1320
|
+
children,
|
|
1321
|
+
cells
|
|
1322
|
+
]
|
|
1303
1323
|
}
|
|
1304
1324
|
);
|
|
1305
1325
|
}
|
|
1306
1326
|
);
|
|
1307
1327
|
|
|
1308
|
-
// src/glide.tsx
|
|
1309
|
-
var
|
|
1328
|
+
// src/components/glide.tsx
|
|
1329
|
+
var import_react17 = require("react");
|
|
1330
|
+
|
|
1331
|
+
// src/primitives/use-presence.ts
|
|
1332
|
+
var import_react16 = require("react");
|
|
1333
|
+
function usePresence2(show) {
|
|
1334
|
+
const [mounted, setMounted] = (0, import_react16.useState)(show);
|
|
1335
|
+
const [phase, setPhase] = (0, import_react16.useState)(show ? "entered" : "exiting");
|
|
1336
|
+
(0, import_react16.useEffect)(() => {
|
|
1337
|
+
if (show) {
|
|
1338
|
+
setMounted(true);
|
|
1339
|
+
setPhase("entering");
|
|
1340
|
+
} else if (mounted) {
|
|
1341
|
+
setPhase("exiting");
|
|
1342
|
+
}
|
|
1343
|
+
}, [show]);
|
|
1344
|
+
const onAnimationEnd = (0, import_react16.useCallback)(
|
|
1345
|
+
(e) => {
|
|
1346
|
+
if (e.target !== e.currentTarget) return;
|
|
1347
|
+
if (phase === "entering") setPhase("entered");
|
|
1348
|
+
if (phase === "exiting") setMounted(false);
|
|
1349
|
+
},
|
|
1350
|
+
[phase]
|
|
1351
|
+
);
|
|
1352
|
+
return { mounted, phase, onAnimationEnd };
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// src/components/glide.tsx
|
|
1310
1356
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1311
|
-
var Glide = (0,
|
|
1357
|
+
var Glide = (0, import_react17.forwardRef)(
|
|
1312
1358
|
function Glide2({ show, as: Tag = "div", className, children, ...props }, ref) {
|
|
1313
|
-
const
|
|
1314
|
-
const [phase, setPhase] = (0, import_react15.useState)(show ? "entered" : "exiting");
|
|
1315
|
-
(0, import_react15.useEffect)(() => {
|
|
1316
|
-
if (show) {
|
|
1317
|
-
setMounted(true);
|
|
1318
|
-
setPhase("entering");
|
|
1319
|
-
} else if (mounted) {
|
|
1320
|
-
setPhase("exiting");
|
|
1321
|
-
}
|
|
1322
|
-
}, [show]);
|
|
1323
|
-
const onAnimationEnd = (0, import_react15.useCallback)(
|
|
1324
|
-
(e) => {
|
|
1325
|
-
if (e.target !== e.currentTarget) return;
|
|
1326
|
-
if (phase === "entering") setPhase("entered");
|
|
1327
|
-
if (phase === "exiting") setMounted(false);
|
|
1328
|
-
},
|
|
1329
|
-
[phase]
|
|
1330
|
-
);
|
|
1359
|
+
const { mounted, phase, onAnimationEnd } = usePresence2(show);
|
|
1331
1360
|
if (!mounted) return null;
|
|
1332
1361
|
const phaseClass = phase === "entering" ? "concertina-glide-entering" : phase === "exiting" ? "concertina-glide-exiting" : "";
|
|
1333
1362
|
const merged = ["concertina-glide", phaseClass, className].filter(Boolean).join(" ");
|
|
@@ -1344,13 +1373,46 @@ var Glide = (0, import_react15.forwardRef)(
|
|
|
1344
1373
|
}
|
|
1345
1374
|
);
|
|
1346
1375
|
|
|
1347
|
-
// src/use-
|
|
1348
|
-
var
|
|
1376
|
+
// src/primitives/use-size.ts
|
|
1377
|
+
var import_react18 = require("react");
|
|
1378
|
+
function useSize() {
|
|
1379
|
+
const [size, setSize] = (0, import_react18.useState)({ width: 0, height: 0 });
|
|
1380
|
+
const observerRef = (0, import_react18.useRef)(null);
|
|
1381
|
+
const ref = (0, import_react18.useCallback)((el) => {
|
|
1382
|
+
if (observerRef.current) {
|
|
1383
|
+
observerRef.current.disconnect();
|
|
1384
|
+
observerRef.current = null;
|
|
1385
|
+
}
|
|
1386
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
1387
|
+
const observer = new ResizeObserver((entries) => {
|
|
1388
|
+
for (const entry of entries) {
|
|
1389
|
+
let w;
|
|
1390
|
+
let h;
|
|
1391
|
+
if (entry.borderBoxSize?.length) {
|
|
1392
|
+
const box = entry.borderBoxSize[0];
|
|
1393
|
+
w = box.inlineSize;
|
|
1394
|
+
h = box.blockSize;
|
|
1395
|
+
} else {
|
|
1396
|
+
const rect = entry.target.getBoundingClientRect();
|
|
1397
|
+
w = rect.width;
|
|
1398
|
+
h = rect.height;
|
|
1399
|
+
}
|
|
1400
|
+
setSize({ width: w, height: h });
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
observer.observe(el, { box: "border-box" });
|
|
1404
|
+
observerRef.current = observer;
|
|
1405
|
+
}, []);
|
|
1406
|
+
return { ref, size };
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
// src/accordion/use-concertina.ts
|
|
1410
|
+
var import_react19 = require("react");
|
|
1349
1411
|
function useConcertina() {
|
|
1350
|
-
const [value, setValue] = (0,
|
|
1351
|
-
const [switching, setSwitching] = (0,
|
|
1352
|
-
const itemRefs = (0,
|
|
1353
|
-
const onValueChange = (0,
|
|
1412
|
+
const [value, setValue] = (0, import_react19.useState)("");
|
|
1413
|
+
const [switching, setSwitching] = (0, import_react19.useState)(false);
|
|
1414
|
+
const itemRefs = (0, import_react19.useRef)({});
|
|
1415
|
+
const onValueChange = (0, import_react19.useCallback)(
|
|
1354
1416
|
(newValue) => {
|
|
1355
1417
|
if (!newValue) {
|
|
1356
1418
|
setSwitching(false);
|
|
@@ -1362,14 +1424,14 @@ function useConcertina() {
|
|
|
1362
1424
|
},
|
|
1363
1425
|
[value]
|
|
1364
1426
|
);
|
|
1365
|
-
(0,
|
|
1427
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
1366
1428
|
if (!value) return;
|
|
1367
1429
|
pinToScrollTop(itemRefs.current[value]);
|
|
1368
1430
|
}, [value]);
|
|
1369
|
-
(0,
|
|
1431
|
+
(0, import_react19.useEffect)(() => {
|
|
1370
1432
|
if (switching) setSwitching(false);
|
|
1371
1433
|
}, [switching]);
|
|
1372
|
-
const getItemRef = (0,
|
|
1434
|
+
const getItemRef = (0, import_react19.useCallback)(
|
|
1373
1435
|
(id) => (el) => {
|
|
1374
1436
|
itemRefs.current[id] = el;
|
|
1375
1437
|
},
|
|
@@ -1399,6 +1461,9 @@ function useConcertina() {
|
|
|
1399
1461
|
pinToScrollTop,
|
|
1400
1462
|
useConcertina,
|
|
1401
1463
|
useExpanded,
|
|
1464
|
+
usePresence,
|
|
1465
|
+
useScrollPin,
|
|
1466
|
+
useSize,
|
|
1402
1467
|
useStableSlot,
|
|
1403
1468
|
useTransitionLock
|
|
1404
1469
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { HTMLAttributes, ElementType, CSSProperties } from 'react';
|
|
2
|
+
import { HTMLAttributes, ElementType, AnimationEvent, DependencyList, CSSProperties } from 'react';
|
|
3
3
|
import * as Accordion from '@radix-ui/react-accordion';
|
|
4
4
|
export { Header, Trigger } from '@radix-ui/react-accordion';
|
|
5
5
|
|
|
@@ -73,48 +73,6 @@ interface SlotProps extends HTMLAttributes<HTMLElement> {
|
|
|
73
73
|
*/
|
|
74
74
|
declare const Slot: react.ForwardRefExoticComponent<SlotProps & react.RefAttributes<HTMLElement>>;
|
|
75
75
|
|
|
76
|
-
interface UseStableSlotOptions {
|
|
77
|
-
/** Which axis to ratchet. Default: "both". */
|
|
78
|
-
axis?: Axis;
|
|
79
|
-
}
|
|
80
|
-
interface UseStableSlotReturn {
|
|
81
|
-
/** RefCallback — attach to the container element. */
|
|
82
|
-
ref: (el: HTMLElement | null) => void;
|
|
83
|
-
/** Spread onto the element: { minWidth?, minHeight? } */
|
|
84
|
-
style: CSSProperties;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* ResizeObserver ratchet for dynamic content.
|
|
88
|
-
*
|
|
89
|
-
* Watches the element, tracks maximum width/height ever observed,
|
|
90
|
-
* applies min-width/min-height that only ratchets up.
|
|
91
|
-
*
|
|
92
|
-
* Five things work together:
|
|
93
|
-
* 1. ResizeObserver uses borderBoxSize — includes padding/border
|
|
94
|
-
* 2. Ratchet is one-way — max only increases, never resets
|
|
95
|
-
* 3. setStyle only called when ratchet grows — no infinite loops
|
|
96
|
-
* 4. RefCallback disconnects observer on unmount — no leak
|
|
97
|
-
* 5. SSR graceful no-op — typeof ResizeObserver guard
|
|
98
|
-
*/
|
|
99
|
-
declare function useStableSlot(options?: UseStableSlotOptions): UseStableSlotReturn;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Suppress CSS transitions during batched state changes.
|
|
103
|
-
*
|
|
104
|
-
* Three things work together:
|
|
105
|
-
* 1. lock() sets the flag synchronously — batched with state changes in React 18
|
|
106
|
-
* 2. After DOM commit (useLayoutEffect window) — consumer does measurement/scroll/pin work
|
|
107
|
-
* 3. useEffect auto-clears the flag after paint — transitions re-enable
|
|
108
|
-
*
|
|
109
|
-
* Usage:
|
|
110
|
-
* const { locked, lock } = useTransitionLock();
|
|
111
|
-
* <div data-locked={locked || undefined}>...</div>
|
|
112
|
-
*/
|
|
113
|
-
declare function useTransitionLock(): {
|
|
114
|
-
readonly locked: boolean;
|
|
115
|
-
readonly lock: () => void;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
76
|
interface GigbagProps extends HTMLAttributes<HTMLElement> {
|
|
119
77
|
/** Which axis to ratchet. Default: "height". */
|
|
120
78
|
axis?: Axis;
|
|
@@ -147,6 +105,9 @@ interface WarmupProps extends HTMLAttributes<HTMLElement> {
|
|
|
147
105
|
* dimensions of the real content. Pair with <Gigbag> so the
|
|
148
106
|
* container ratchets to the larger of placeholder vs real content.
|
|
149
107
|
*
|
|
108
|
+
* Pass children to inject structure before the generated bones
|
|
109
|
+
* (e.g. a toolbar placeholder that spans all grid columns).
|
|
110
|
+
*
|
|
150
111
|
* All dimensions are CSS custom properties — consuming apps theme
|
|
151
112
|
* without forking.
|
|
152
113
|
*/
|
|
@@ -161,14 +122,105 @@ interface GlideProps extends HTMLAttributes<HTMLElement> {
|
|
|
161
122
|
/**
|
|
162
123
|
* Enter/exit animation wrapper.
|
|
163
124
|
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* show=false -> "exiting" -> animationEnd -> unmount
|
|
167
|
-
*
|
|
168
|
-
* CSS classes: concertina-glide-entering, concertina-glide-exiting
|
|
125
|
+
* Thin composition over usePresence. Adds CSS class names:
|
|
126
|
+
* concertina-glide-entering, concertina-glide-exiting
|
|
169
127
|
*/
|
|
170
128
|
declare const Glide: react.ForwardRefExoticComponent<GlideProps & react.RefAttributes<HTMLElement>>;
|
|
171
129
|
|
|
130
|
+
interface Size {
|
|
131
|
+
width: number;
|
|
132
|
+
height: number;
|
|
133
|
+
}
|
|
134
|
+
interface UseSizeReturn {
|
|
135
|
+
/** RefCallback — attach to the element to observe. */
|
|
136
|
+
ref: (el: HTMLElement | null) => void;
|
|
137
|
+
/** Current border-box size. Starts at { width: 0, height: 0 }. */
|
|
138
|
+
size: Size;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Raw border-box size observation via ResizeObserver.
|
|
142
|
+
*
|
|
143
|
+
* Reports every resize — no ratchet, no policy. Use this when you
|
|
144
|
+
* need the actual current size for your own logic (e.g. breakpoints,
|
|
145
|
+
* conditional rendering, animations).
|
|
146
|
+
*
|
|
147
|
+
* For a ratcheting min-size that only grows, use useStableSlot instead.
|
|
148
|
+
*/
|
|
149
|
+
declare function useSize(): UseSizeReturn;
|
|
150
|
+
|
|
151
|
+
type Phase = "entering" | "entered" | "exiting";
|
|
152
|
+
interface UsePresenceReturn {
|
|
153
|
+
/** Whether the element should be in the DOM. */
|
|
154
|
+
mounted: boolean;
|
|
155
|
+
/** Current animation phase. */
|
|
156
|
+
phase: Phase;
|
|
157
|
+
/** Attach to the animating element's onAnimationEnd. */
|
|
158
|
+
onAnimationEnd: (e: AnimationEvent) => void;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Mount/unmount state machine for enter/exit animations.
|
|
162
|
+
*
|
|
163
|
+
* State transitions:
|
|
164
|
+
* show=true → mount + "entering" → animationEnd → "entered"
|
|
165
|
+
* show=false → "exiting" → animationEnd → unmount
|
|
166
|
+
*
|
|
167
|
+
* Extracted from Glide so any component can use animated presence.
|
|
168
|
+
*/
|
|
169
|
+
declare function usePresence(show: boolean): UsePresenceReturn;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Pin an element to the top of its scroll container after layout changes.
|
|
173
|
+
*
|
|
174
|
+
* Runs pinToScrollTop inside useLayoutEffect — after React commits
|
|
175
|
+
* the DOM but before the browser paints. This ensures scroll
|
|
176
|
+
* correction happens synchronously with layout changes.
|
|
177
|
+
*
|
|
178
|
+
* Extracted from accordion Root so any component can do scroll pinning.
|
|
179
|
+
*/
|
|
180
|
+
declare function useScrollPin(getElement: () => HTMLElement | null, deps: DependencyList): void;
|
|
181
|
+
|
|
182
|
+
interface UseStableSlotOptions {
|
|
183
|
+
/** Which axis to ratchet. Default: "both". */
|
|
184
|
+
axis?: Axis;
|
|
185
|
+
}
|
|
186
|
+
interface UseStableSlotReturn {
|
|
187
|
+
/** RefCallback — attach to the container element. */
|
|
188
|
+
ref: (el: HTMLElement | null) => void;
|
|
189
|
+
/** Spread onto the element: { minWidth?, minHeight? } */
|
|
190
|
+
style: CSSProperties;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* ResizeObserver ratchet for dynamic content.
|
|
194
|
+
*
|
|
195
|
+
* Watches the element, tracks maximum width/height ever observed,
|
|
196
|
+
* applies min-width/min-height that only ratchets up.
|
|
197
|
+
*
|
|
198
|
+
* Five things work together:
|
|
199
|
+
* 1. ResizeObserver uses borderBoxSize — includes padding/border
|
|
200
|
+
* 2. Ratchet is one-way — max only increases, never resets
|
|
201
|
+
* 3. setStyle only called when ratchet grows — no infinite loops
|
|
202
|
+
* 4. RefCallback disconnects observer on unmount — no leak
|
|
203
|
+
* 5. SSR graceful no-op — typeof ResizeObserver guard
|
|
204
|
+
*/
|
|
205
|
+
declare function useStableSlot(options?: UseStableSlotOptions): UseStableSlotReturn;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Suppress CSS transitions during batched state changes.
|
|
209
|
+
*
|
|
210
|
+
* Three things work together:
|
|
211
|
+
* 1. lock() sets the flag synchronously — batched with state changes in React 18
|
|
212
|
+
* 2. After DOM commit (useLayoutEffect window) — consumer does measurement/scroll/pin work
|
|
213
|
+
* 3. useEffect auto-clears the flag after paint — transitions re-enable
|
|
214
|
+
*
|
|
215
|
+
* Usage:
|
|
216
|
+
* const { locked, lock } = useTransitionLock();
|
|
217
|
+
* <div data-locked={locked || undefined}>...</div>
|
|
218
|
+
*/
|
|
219
|
+
declare function useTransitionLock(): {
|
|
220
|
+
readonly locked: boolean;
|
|
221
|
+
readonly lock: () => void;
|
|
222
|
+
};
|
|
223
|
+
|
|
172
224
|
/**
|
|
173
225
|
* Scroll `el` to the top of its nearest scrollable ancestor,
|
|
174
226
|
* clearing any sticky headers. Only adjusts one container's
|
|
@@ -211,4 +263,4 @@ interface UseConcertinaReturn {
|
|
|
211
263
|
*/
|
|
212
264
|
declare function useConcertina(): UseConcertinaReturn;
|
|
213
265
|
|
|
214
|
-
export { type Axis, ConcertinaContext, type ConcertinaRootProps, ConcertinaStore, Content, Gigbag, type GigbagProps, Glide, type GlideProps, Item, Root, Slot, type SlotProps, StableSlot, type StableSlotProps, type UseConcertinaReturn, Warmup, type WarmupProps, pinToScrollTop, useConcertina, useExpanded, useStableSlot, useTransitionLock };
|
|
266
|
+
export { type Axis, ConcertinaContext, type ConcertinaRootProps, ConcertinaStore, Content, Gigbag, type GigbagProps, Glide, type GlideProps, Item, type Phase, Root, type Size, Slot, type SlotProps, StableSlot, type StableSlotProps, type UseConcertinaReturn, type UsePresenceReturn, Warmup, type WarmupProps, pinToScrollTop, useConcertina, useExpanded, usePresence, useScrollPin, useSize, useStableSlot, useTransitionLock };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { HTMLAttributes, ElementType, CSSProperties } from 'react';
|
|
2
|
+
import { HTMLAttributes, ElementType, AnimationEvent, DependencyList, CSSProperties } from 'react';
|
|
3
3
|
import * as Accordion from '@radix-ui/react-accordion';
|
|
4
4
|
export { Header, Trigger } from '@radix-ui/react-accordion';
|
|
5
5
|
|
|
@@ -73,48 +73,6 @@ interface SlotProps extends HTMLAttributes<HTMLElement> {
|
|
|
73
73
|
*/
|
|
74
74
|
declare const Slot: react.ForwardRefExoticComponent<SlotProps & react.RefAttributes<HTMLElement>>;
|
|
75
75
|
|
|
76
|
-
interface UseStableSlotOptions {
|
|
77
|
-
/** Which axis to ratchet. Default: "both". */
|
|
78
|
-
axis?: Axis;
|
|
79
|
-
}
|
|
80
|
-
interface UseStableSlotReturn {
|
|
81
|
-
/** RefCallback — attach to the container element. */
|
|
82
|
-
ref: (el: HTMLElement | null) => void;
|
|
83
|
-
/** Spread onto the element: { minWidth?, minHeight? } */
|
|
84
|
-
style: CSSProperties;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* ResizeObserver ratchet for dynamic content.
|
|
88
|
-
*
|
|
89
|
-
* Watches the element, tracks maximum width/height ever observed,
|
|
90
|
-
* applies min-width/min-height that only ratchets up.
|
|
91
|
-
*
|
|
92
|
-
* Five things work together:
|
|
93
|
-
* 1. ResizeObserver uses borderBoxSize — includes padding/border
|
|
94
|
-
* 2. Ratchet is one-way — max only increases, never resets
|
|
95
|
-
* 3. setStyle only called when ratchet grows — no infinite loops
|
|
96
|
-
* 4. RefCallback disconnects observer on unmount — no leak
|
|
97
|
-
* 5. SSR graceful no-op — typeof ResizeObserver guard
|
|
98
|
-
*/
|
|
99
|
-
declare function useStableSlot(options?: UseStableSlotOptions): UseStableSlotReturn;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Suppress CSS transitions during batched state changes.
|
|
103
|
-
*
|
|
104
|
-
* Three things work together:
|
|
105
|
-
* 1. lock() sets the flag synchronously — batched with state changes in React 18
|
|
106
|
-
* 2. After DOM commit (useLayoutEffect window) — consumer does measurement/scroll/pin work
|
|
107
|
-
* 3. useEffect auto-clears the flag after paint — transitions re-enable
|
|
108
|
-
*
|
|
109
|
-
* Usage:
|
|
110
|
-
* const { locked, lock } = useTransitionLock();
|
|
111
|
-
* <div data-locked={locked || undefined}>...</div>
|
|
112
|
-
*/
|
|
113
|
-
declare function useTransitionLock(): {
|
|
114
|
-
readonly locked: boolean;
|
|
115
|
-
readonly lock: () => void;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
76
|
interface GigbagProps extends HTMLAttributes<HTMLElement> {
|
|
119
77
|
/** Which axis to ratchet. Default: "height". */
|
|
120
78
|
axis?: Axis;
|
|
@@ -147,6 +105,9 @@ interface WarmupProps extends HTMLAttributes<HTMLElement> {
|
|
|
147
105
|
* dimensions of the real content. Pair with <Gigbag> so the
|
|
148
106
|
* container ratchets to the larger of placeholder vs real content.
|
|
149
107
|
*
|
|
108
|
+
* Pass children to inject structure before the generated bones
|
|
109
|
+
* (e.g. a toolbar placeholder that spans all grid columns).
|
|
110
|
+
*
|
|
150
111
|
* All dimensions are CSS custom properties — consuming apps theme
|
|
151
112
|
* without forking.
|
|
152
113
|
*/
|
|
@@ -161,14 +122,105 @@ interface GlideProps extends HTMLAttributes<HTMLElement> {
|
|
|
161
122
|
/**
|
|
162
123
|
* Enter/exit animation wrapper.
|
|
163
124
|
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* show=false -> "exiting" -> animationEnd -> unmount
|
|
167
|
-
*
|
|
168
|
-
* CSS classes: concertina-glide-entering, concertina-glide-exiting
|
|
125
|
+
* Thin composition over usePresence. Adds CSS class names:
|
|
126
|
+
* concertina-glide-entering, concertina-glide-exiting
|
|
169
127
|
*/
|
|
170
128
|
declare const Glide: react.ForwardRefExoticComponent<GlideProps & react.RefAttributes<HTMLElement>>;
|
|
171
129
|
|
|
130
|
+
interface Size {
|
|
131
|
+
width: number;
|
|
132
|
+
height: number;
|
|
133
|
+
}
|
|
134
|
+
interface UseSizeReturn {
|
|
135
|
+
/** RefCallback — attach to the element to observe. */
|
|
136
|
+
ref: (el: HTMLElement | null) => void;
|
|
137
|
+
/** Current border-box size. Starts at { width: 0, height: 0 }. */
|
|
138
|
+
size: Size;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Raw border-box size observation via ResizeObserver.
|
|
142
|
+
*
|
|
143
|
+
* Reports every resize — no ratchet, no policy. Use this when you
|
|
144
|
+
* need the actual current size for your own logic (e.g. breakpoints,
|
|
145
|
+
* conditional rendering, animations).
|
|
146
|
+
*
|
|
147
|
+
* For a ratcheting min-size that only grows, use useStableSlot instead.
|
|
148
|
+
*/
|
|
149
|
+
declare function useSize(): UseSizeReturn;
|
|
150
|
+
|
|
151
|
+
type Phase = "entering" | "entered" | "exiting";
|
|
152
|
+
interface UsePresenceReturn {
|
|
153
|
+
/** Whether the element should be in the DOM. */
|
|
154
|
+
mounted: boolean;
|
|
155
|
+
/** Current animation phase. */
|
|
156
|
+
phase: Phase;
|
|
157
|
+
/** Attach to the animating element's onAnimationEnd. */
|
|
158
|
+
onAnimationEnd: (e: AnimationEvent) => void;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Mount/unmount state machine for enter/exit animations.
|
|
162
|
+
*
|
|
163
|
+
* State transitions:
|
|
164
|
+
* show=true → mount + "entering" → animationEnd → "entered"
|
|
165
|
+
* show=false → "exiting" → animationEnd → unmount
|
|
166
|
+
*
|
|
167
|
+
* Extracted from Glide so any component can use animated presence.
|
|
168
|
+
*/
|
|
169
|
+
declare function usePresence(show: boolean): UsePresenceReturn;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Pin an element to the top of its scroll container after layout changes.
|
|
173
|
+
*
|
|
174
|
+
* Runs pinToScrollTop inside useLayoutEffect — after React commits
|
|
175
|
+
* the DOM but before the browser paints. This ensures scroll
|
|
176
|
+
* correction happens synchronously with layout changes.
|
|
177
|
+
*
|
|
178
|
+
* Extracted from accordion Root so any component can do scroll pinning.
|
|
179
|
+
*/
|
|
180
|
+
declare function useScrollPin(getElement: () => HTMLElement | null, deps: DependencyList): void;
|
|
181
|
+
|
|
182
|
+
interface UseStableSlotOptions {
|
|
183
|
+
/** Which axis to ratchet. Default: "both". */
|
|
184
|
+
axis?: Axis;
|
|
185
|
+
}
|
|
186
|
+
interface UseStableSlotReturn {
|
|
187
|
+
/** RefCallback — attach to the container element. */
|
|
188
|
+
ref: (el: HTMLElement | null) => void;
|
|
189
|
+
/** Spread onto the element: { minWidth?, minHeight? } */
|
|
190
|
+
style: CSSProperties;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* ResizeObserver ratchet for dynamic content.
|
|
194
|
+
*
|
|
195
|
+
* Watches the element, tracks maximum width/height ever observed,
|
|
196
|
+
* applies min-width/min-height that only ratchets up.
|
|
197
|
+
*
|
|
198
|
+
* Five things work together:
|
|
199
|
+
* 1. ResizeObserver uses borderBoxSize — includes padding/border
|
|
200
|
+
* 2. Ratchet is one-way — max only increases, never resets
|
|
201
|
+
* 3. setStyle only called when ratchet grows — no infinite loops
|
|
202
|
+
* 4. RefCallback disconnects observer on unmount — no leak
|
|
203
|
+
* 5. SSR graceful no-op — typeof ResizeObserver guard
|
|
204
|
+
*/
|
|
205
|
+
declare function useStableSlot(options?: UseStableSlotOptions): UseStableSlotReturn;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Suppress CSS transitions during batched state changes.
|
|
209
|
+
*
|
|
210
|
+
* Three things work together:
|
|
211
|
+
* 1. lock() sets the flag synchronously — batched with state changes in React 18
|
|
212
|
+
* 2. After DOM commit (useLayoutEffect window) — consumer does measurement/scroll/pin work
|
|
213
|
+
* 3. useEffect auto-clears the flag after paint — transitions re-enable
|
|
214
|
+
*
|
|
215
|
+
* Usage:
|
|
216
|
+
* const { locked, lock } = useTransitionLock();
|
|
217
|
+
* <div data-locked={locked || undefined}>...</div>
|
|
218
|
+
*/
|
|
219
|
+
declare function useTransitionLock(): {
|
|
220
|
+
readonly locked: boolean;
|
|
221
|
+
readonly lock: () => void;
|
|
222
|
+
};
|
|
223
|
+
|
|
172
224
|
/**
|
|
173
225
|
* Scroll `el` to the top of its nearest scrollable ancestor,
|
|
174
226
|
* clearing any sticky headers. Only adjusts one container's
|
|
@@ -211,4 +263,4 @@ interface UseConcertinaReturn {
|
|
|
211
263
|
*/
|
|
212
264
|
declare function useConcertina(): UseConcertinaReturn;
|
|
213
265
|
|
|
214
|
-
export { type Axis, ConcertinaContext, type ConcertinaRootProps, ConcertinaStore, Content, Gigbag, type GigbagProps, Glide, type GlideProps, Item, Root, Slot, type SlotProps, StableSlot, type StableSlotProps, type UseConcertinaReturn, Warmup, type WarmupProps, pinToScrollTop, useConcertina, useExpanded, useStableSlot, useTransitionLock };
|
|
266
|
+
export { type Axis, ConcertinaContext, type ConcertinaRootProps, ConcertinaStore, Content, Gigbag, type GigbagProps, Glide, type GlideProps, Item, type Phase, Root, type Size, Slot, type SlotProps, StableSlot, type StableSlotProps, type UseConcertinaReturn, type UsePresenceReturn, Warmup, type WarmupProps, pinToScrollTop, useConcertina, useExpanded, usePresence, useScrollPin, useSize, useStableSlot, useTransitionLock };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
// src/root.tsx
|
|
1
|
+
// src/accordion/root.tsx
|
|
2
2
|
import {
|
|
3
3
|
forwardRef as forwardRef4,
|
|
4
4
|
useRef as useRef5,
|
|
5
|
-
useLayoutEffect as useLayoutEffect3,
|
|
6
5
|
useSyncExternalStore,
|
|
7
6
|
useCallback as useCallback6
|
|
8
7
|
} from "react";
|
|
@@ -966,7 +965,7 @@ var Header = AccordionHeader;
|
|
|
966
965
|
var Trigger2 = AccordionTrigger;
|
|
967
966
|
var Content2 = AccordionContent;
|
|
968
967
|
|
|
969
|
-
// src/store.ts
|
|
968
|
+
// src/accordion/store.ts
|
|
970
969
|
import { createContext as createContext3 } from "react";
|
|
971
970
|
var ConcertinaStore = class {
|
|
972
971
|
constructor() {
|
|
@@ -995,7 +994,10 @@ var ConcertinaStore = class {
|
|
|
995
994
|
};
|
|
996
995
|
var ConcertinaContext = createContext3(null);
|
|
997
996
|
|
|
998
|
-
// src/
|
|
997
|
+
// src/primitives/use-scroll-pin.ts
|
|
998
|
+
import { useLayoutEffect as useLayoutEffect3 } from "react";
|
|
999
|
+
|
|
1000
|
+
// src/primitives/pin-to-scroll-top.ts
|
|
999
1001
|
function pinToScrollTop(el) {
|
|
1000
1002
|
if (!el) return;
|
|
1001
1003
|
let parent = el.parentElement;
|
|
@@ -1025,7 +1027,16 @@ function pinToScrollTop(el) {
|
|
|
1025
1027
|
}
|
|
1026
1028
|
}
|
|
1027
1029
|
|
|
1028
|
-
// src/use-
|
|
1030
|
+
// src/primitives/use-scroll-pin.ts
|
|
1031
|
+
function useScrollPin(getElement, deps) {
|
|
1032
|
+
useLayoutEffect3(() => {
|
|
1033
|
+
const el = getElement();
|
|
1034
|
+
if (!el) return;
|
|
1035
|
+
pinToScrollTop(el);
|
|
1036
|
+
}, deps);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// src/primitives/use-transition-lock.ts
|
|
1029
1040
|
import { useState as useState5, useEffect as useEffect5, useCallback as useCallback5 } from "react";
|
|
1030
1041
|
function useTransitionLock() {
|
|
1031
1042
|
const [locked, setLocked] = useState5(false);
|
|
@@ -1036,7 +1047,7 @@ function useTransitionLock() {
|
|
|
1036
1047
|
return { locked, lock };
|
|
1037
1048
|
}
|
|
1038
1049
|
|
|
1039
|
-
// src/root.tsx
|
|
1050
|
+
// src/accordion/root.tsx
|
|
1040
1051
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1041
1052
|
var Root3 = forwardRef4(
|
|
1042
1053
|
function Root4({ collapsible = true, children, ...props }, forwardedRef) {
|
|
@@ -1059,10 +1070,10 @@ var Root3 = forwardRef4(
|
|
|
1059
1070
|
},
|
|
1060
1071
|
[store, lock]
|
|
1061
1072
|
);
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1073
|
+
useScrollPin(
|
|
1074
|
+
() => value ? store.getItemRef(value) : null,
|
|
1075
|
+
[value, store]
|
|
1076
|
+
);
|
|
1066
1077
|
return /* @__PURE__ */ jsx8(ConcertinaContext.Provider, { value: store, children: /* @__PURE__ */ jsx8(
|
|
1067
1078
|
Root2,
|
|
1068
1079
|
{
|
|
@@ -1079,7 +1090,7 @@ var Root3 = forwardRef4(
|
|
|
1079
1090
|
}
|
|
1080
1091
|
);
|
|
1081
1092
|
|
|
1082
|
-
// src/item.tsx
|
|
1093
|
+
// src/accordion/item.tsx
|
|
1083
1094
|
import {
|
|
1084
1095
|
forwardRef as forwardRef5,
|
|
1085
1096
|
useContext as useContext3,
|
|
@@ -1102,7 +1113,7 @@ var Item2 = forwardRef5(function Item3({ value, ...props }, forwardedRef) {
|
|
|
1102
1113
|
return /* @__PURE__ */ jsx9(Item, { ref: mergedRef, value, ...props });
|
|
1103
1114
|
});
|
|
1104
1115
|
|
|
1105
|
-
// src/content.tsx
|
|
1116
|
+
// src/accordion/content.tsx
|
|
1106
1117
|
import { forwardRef as forwardRef6 } from "react";
|
|
1107
1118
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1108
1119
|
var Content3 = forwardRef6(function Content4({ className, ...props }, ref) {
|
|
@@ -1110,7 +1121,7 @@ var Content3 = forwardRef6(function Content4({ className, ...props }, ref) {
|
|
|
1110
1121
|
return /* @__PURE__ */ jsx10(Content2, { ref, className: merged, ...props });
|
|
1111
1122
|
});
|
|
1112
1123
|
|
|
1113
|
-
// src/use-expanded.ts
|
|
1124
|
+
// src/accordion/use-expanded.ts
|
|
1114
1125
|
import { useContext as useContext4, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
1115
1126
|
function useStore() {
|
|
1116
1127
|
const store = useContext4(ConcertinaContext);
|
|
@@ -1129,7 +1140,7 @@ function useExpanded(id) {
|
|
|
1129
1140
|
);
|
|
1130
1141
|
}
|
|
1131
1142
|
|
|
1132
|
-
// src/stable-slot.tsx
|
|
1143
|
+
// src/components/stable-slot.tsx
|
|
1133
1144
|
import {
|
|
1134
1145
|
forwardRef as forwardRef7,
|
|
1135
1146
|
createContext as createContext4
|
|
@@ -1143,7 +1154,7 @@ var StableSlot = forwardRef7(
|
|
|
1143
1154
|
}
|
|
1144
1155
|
);
|
|
1145
1156
|
|
|
1146
|
-
// src/slot.tsx
|
|
1157
|
+
// src/components/slot.tsx
|
|
1147
1158
|
import {
|
|
1148
1159
|
forwardRef as forwardRef8,
|
|
1149
1160
|
useContext as useContext5
|
|
@@ -1169,7 +1180,10 @@ var Slot = forwardRef8(
|
|
|
1169
1180
|
}
|
|
1170
1181
|
);
|
|
1171
1182
|
|
|
1172
|
-
// src/
|
|
1183
|
+
// src/components/gigbag.tsx
|
|
1184
|
+
import { forwardRef as forwardRef9 } from "react";
|
|
1185
|
+
|
|
1186
|
+
// src/primitives/use-stable-slot.ts
|
|
1173
1187
|
import { useState as useState6, useCallback as useCallback8, useRef as useRef6 } from "react";
|
|
1174
1188
|
function useStableSlot(options = {}) {
|
|
1175
1189
|
const { axis = "both" } = options;
|
|
@@ -1222,8 +1236,7 @@ function useStableSlot(options = {}) {
|
|
|
1222
1236
|
return { ref, style };
|
|
1223
1237
|
}
|
|
1224
1238
|
|
|
1225
|
-
// src/gigbag.tsx
|
|
1226
|
-
import { forwardRef as forwardRef9 } from "react";
|
|
1239
|
+
// src/components/gigbag.tsx
|
|
1227
1240
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1228
1241
|
var Gigbag = forwardRef9(
|
|
1229
1242
|
function Gigbag2({ axis = "height", as: Tag = "div", className, style, children, ...props }, fwdRef) {
|
|
@@ -1246,7 +1259,7 @@ var Gigbag = forwardRef9(
|
|
|
1246
1259
|
}
|
|
1247
1260
|
);
|
|
1248
1261
|
|
|
1249
|
-
// src/warmup.tsx
|
|
1262
|
+
// src/components/warmup.tsx
|
|
1250
1263
|
import { forwardRef as forwardRef10 } from "react";
|
|
1251
1264
|
import { jsx as jsx14, jsxs } from "react/jsx-runtime";
|
|
1252
1265
|
var Warmup = forwardRef10(
|
|
@@ -1256,47 +1269,60 @@ var Warmup = forwardRef10(
|
|
|
1256
1269
|
/* @__PURE__ */ jsx14("div", { className: "concertina-warmup-line concertina-warmup-line-short" }),
|
|
1257
1270
|
/* @__PURE__ */ jsx14("div", { className: "concertina-warmup-line concertina-warmup-line-long" })
|
|
1258
1271
|
] }, i));
|
|
1259
|
-
return /* @__PURE__ */
|
|
1272
|
+
return /* @__PURE__ */ jsxs(
|
|
1260
1273
|
Tag,
|
|
1261
1274
|
{
|
|
1262
1275
|
ref,
|
|
1263
1276
|
className: merged,
|
|
1264
1277
|
style: { gridTemplateColumns: `repeat(${columns}, 1fr)` },
|
|
1265
1278
|
...props,
|
|
1266
|
-
children:
|
|
1279
|
+
children: [
|
|
1280
|
+
children,
|
|
1281
|
+
cells
|
|
1282
|
+
]
|
|
1267
1283
|
}
|
|
1268
1284
|
);
|
|
1269
1285
|
}
|
|
1270
1286
|
);
|
|
1271
1287
|
|
|
1272
|
-
// src/glide.tsx
|
|
1288
|
+
// src/components/glide.tsx
|
|
1289
|
+
import {
|
|
1290
|
+
forwardRef as forwardRef11
|
|
1291
|
+
} from "react";
|
|
1292
|
+
|
|
1293
|
+
// src/primitives/use-presence.ts
|
|
1273
1294
|
import {
|
|
1274
|
-
forwardRef as forwardRef11,
|
|
1275
1295
|
useState as useState7,
|
|
1276
1296
|
useEffect as useEffect6,
|
|
1277
1297
|
useCallback as useCallback9
|
|
1278
1298
|
} from "react";
|
|
1299
|
+
function usePresence2(show) {
|
|
1300
|
+
const [mounted, setMounted] = useState7(show);
|
|
1301
|
+
const [phase, setPhase] = useState7(show ? "entered" : "exiting");
|
|
1302
|
+
useEffect6(() => {
|
|
1303
|
+
if (show) {
|
|
1304
|
+
setMounted(true);
|
|
1305
|
+
setPhase("entering");
|
|
1306
|
+
} else if (mounted) {
|
|
1307
|
+
setPhase("exiting");
|
|
1308
|
+
}
|
|
1309
|
+
}, [show]);
|
|
1310
|
+
const onAnimationEnd = useCallback9(
|
|
1311
|
+
(e) => {
|
|
1312
|
+
if (e.target !== e.currentTarget) return;
|
|
1313
|
+
if (phase === "entering") setPhase("entered");
|
|
1314
|
+
if (phase === "exiting") setMounted(false);
|
|
1315
|
+
},
|
|
1316
|
+
[phase]
|
|
1317
|
+
);
|
|
1318
|
+
return { mounted, phase, onAnimationEnd };
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// src/components/glide.tsx
|
|
1279
1322
|
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1280
1323
|
var Glide = forwardRef11(
|
|
1281
1324
|
function Glide2({ show, as: Tag = "div", className, children, ...props }, ref) {
|
|
1282
|
-
const
|
|
1283
|
-
const [phase, setPhase] = useState7(show ? "entered" : "exiting");
|
|
1284
|
-
useEffect6(() => {
|
|
1285
|
-
if (show) {
|
|
1286
|
-
setMounted(true);
|
|
1287
|
-
setPhase("entering");
|
|
1288
|
-
} else if (mounted) {
|
|
1289
|
-
setPhase("exiting");
|
|
1290
|
-
}
|
|
1291
|
-
}, [show]);
|
|
1292
|
-
const onAnimationEnd = useCallback9(
|
|
1293
|
-
(e) => {
|
|
1294
|
-
if (e.target !== e.currentTarget) return;
|
|
1295
|
-
if (phase === "entering") setPhase("entered");
|
|
1296
|
-
if (phase === "exiting") setMounted(false);
|
|
1297
|
-
},
|
|
1298
|
-
[phase]
|
|
1299
|
-
);
|
|
1325
|
+
const { mounted, phase, onAnimationEnd } = usePresence2(show);
|
|
1300
1326
|
if (!mounted) return null;
|
|
1301
1327
|
const phaseClass = phase === "entering" ? "concertina-glide-entering" : phase === "exiting" ? "concertina-glide-exiting" : "";
|
|
1302
1328
|
const merged = ["concertina-glide", phaseClass, className].filter(Boolean).join(" ");
|
|
@@ -1313,19 +1339,52 @@ var Glide = forwardRef11(
|
|
|
1313
1339
|
}
|
|
1314
1340
|
);
|
|
1315
1341
|
|
|
1316
|
-
// src/use-
|
|
1342
|
+
// src/primitives/use-size.ts
|
|
1343
|
+
import { useState as useState8, useCallback as useCallback10, useRef as useRef7 } from "react";
|
|
1344
|
+
function useSize() {
|
|
1345
|
+
const [size, setSize] = useState8({ width: 0, height: 0 });
|
|
1346
|
+
const observerRef = useRef7(null);
|
|
1347
|
+
const ref = useCallback10((el) => {
|
|
1348
|
+
if (observerRef.current) {
|
|
1349
|
+
observerRef.current.disconnect();
|
|
1350
|
+
observerRef.current = null;
|
|
1351
|
+
}
|
|
1352
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
1353
|
+
const observer = new ResizeObserver((entries) => {
|
|
1354
|
+
for (const entry of entries) {
|
|
1355
|
+
let w;
|
|
1356
|
+
let h;
|
|
1357
|
+
if (entry.borderBoxSize?.length) {
|
|
1358
|
+
const box = entry.borderBoxSize[0];
|
|
1359
|
+
w = box.inlineSize;
|
|
1360
|
+
h = box.blockSize;
|
|
1361
|
+
} else {
|
|
1362
|
+
const rect = entry.target.getBoundingClientRect();
|
|
1363
|
+
w = rect.width;
|
|
1364
|
+
h = rect.height;
|
|
1365
|
+
}
|
|
1366
|
+
setSize({ width: w, height: h });
|
|
1367
|
+
}
|
|
1368
|
+
});
|
|
1369
|
+
observer.observe(el, { box: "border-box" });
|
|
1370
|
+
observerRef.current = observer;
|
|
1371
|
+
}, []);
|
|
1372
|
+
return { ref, size };
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
// src/accordion/use-concertina.ts
|
|
1317
1376
|
import {
|
|
1318
|
-
useState as
|
|
1319
|
-
useCallback as
|
|
1320
|
-
useRef as
|
|
1377
|
+
useState as useState9,
|
|
1378
|
+
useCallback as useCallback11,
|
|
1379
|
+
useRef as useRef8,
|
|
1321
1380
|
useLayoutEffect as useLayoutEffect4,
|
|
1322
1381
|
useEffect as useEffect7
|
|
1323
1382
|
} from "react";
|
|
1324
1383
|
function useConcertina() {
|
|
1325
|
-
const [value, setValue] =
|
|
1326
|
-
const [switching, setSwitching] =
|
|
1327
|
-
const itemRefs =
|
|
1328
|
-
const onValueChange =
|
|
1384
|
+
const [value, setValue] = useState9("");
|
|
1385
|
+
const [switching, setSwitching] = useState9(false);
|
|
1386
|
+
const itemRefs = useRef8({});
|
|
1387
|
+
const onValueChange = useCallback11(
|
|
1329
1388
|
(newValue) => {
|
|
1330
1389
|
if (!newValue) {
|
|
1331
1390
|
setSwitching(false);
|
|
@@ -1344,7 +1403,7 @@ function useConcertina() {
|
|
|
1344
1403
|
useEffect7(() => {
|
|
1345
1404
|
if (switching) setSwitching(false);
|
|
1346
1405
|
}, [switching]);
|
|
1347
|
-
const getItemRef =
|
|
1406
|
+
const getItemRef = useCallback11(
|
|
1348
1407
|
(id) => (el) => {
|
|
1349
1408
|
itemRefs.current[id] = el;
|
|
1350
1409
|
},
|
|
@@ -1373,6 +1432,9 @@ export {
|
|
|
1373
1432
|
pinToScrollTop,
|
|
1374
1433
|
useConcertina,
|
|
1375
1434
|
useExpanded,
|
|
1435
|
+
usePresence2 as usePresence,
|
|
1436
|
+
useScrollPin,
|
|
1437
|
+
useSize,
|
|
1376
1438
|
useStableSlot,
|
|
1377
1439
|
useTransitionLock
|
|
1378
1440
|
};
|