concertina 0.11.0 → 0.12.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 +27 -1
- package/dist/accordion.cjs +6 -5
- package/dist/accordion.js +1 -1
- package/dist/{chunk-4DDADLSW.js → chunk-OGJMPKZX.js} +6 -5
- package/dist/index.cjs +90 -66
- package/dist/index.d.cts +36 -6
- package/dist/index.d.ts +36 -6
- package/dist/index.js +38 -18
- package/dist/styles.css +6 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -188,14 +188,39 @@ import { Hum } from "concertina";
|
|
|
188
188
|
|
|
189
189
|
The `className` is passed through to the shimmer so `1lh` inherits the correct font metrics. The shimmer is exactly as tall as the text it replaces because `1lh` resolves to the element's computed line-height. Not font-size, not a token, not a guess.
|
|
190
190
|
|
|
191
|
+
#### Vamp: ambient loading for entire subtrees
|
|
192
|
+
|
|
193
|
+
When many Hum instances share the same loading state (e.g. every cell in a table), threading `loading` to each one is boilerplate. Wrap the subtree in `<Vamp>` and every nested `<Hum>` picks it up automatically.
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
import { Vamp, Hum } from "concertina";
|
|
197
|
+
|
|
198
|
+
<Vamp loading={isLoading}>
|
|
199
|
+
<h2><Hum className="text-xl font-bold">{user?.name}</Hum></h2>
|
|
200
|
+
<p><Hum className="text-sm text-stone">{user?.email}</Hum></p>
|
|
201
|
+
<p><Hum className="text-sm">{user?.bio}</Hum></p>
|
|
202
|
+
</Vamp>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
No `loading` prop on any Hum. They all read from Vamp. An explicit `loading` prop on any individual Hum still overrides context.
|
|
206
|
+
|
|
207
|
+
Named after musical **vamping** — repeating a pattern while waiting for a cue.
|
|
208
|
+
|
|
191
209
|
#### Hum props
|
|
192
210
|
|
|
193
211
|
| Prop | Type | Default | Description |
|
|
194
212
|
|------|------|---------|-------------|
|
|
195
|
-
| `loading` | `boolean` | | Show shimmer (true) or children (false) |
|
|
213
|
+
| `loading` | `boolean` | Vamp context | Show shimmer (true) or children (false). Falls back to nearest `<Vamp>` when omitted. |
|
|
196
214
|
| `as` | `ElementType` | `"span"` | HTML element to render |
|
|
197
215
|
| `className` | `string` | | Applied to both shimmer and content states |
|
|
198
216
|
|
|
217
|
+
#### Vamp props
|
|
218
|
+
|
|
219
|
+
| Prop | Type | Description |
|
|
220
|
+
|------|------|-------------|
|
|
221
|
+
| `loading` | `boolean` | Whether the subtree is in a loading/warmup state |
|
|
222
|
+
| `children` | `ReactNode` | Content to wrap |
|
|
223
|
+
|
|
199
224
|
> `StableText` is an alias for `Hum`.
|
|
200
225
|
|
|
201
226
|
---
|
|
@@ -382,6 +407,7 @@ Scrolls an element to the top of its nearest scrollable ancestor. Only touches `
|
|
|
382
407
|
|---------|------|
|
|
383
408
|
| Two variants swap in one slot | Bellows + Slot |
|
|
384
409
|
| Line of text loading from API | Hum |
|
|
410
|
+
| Many Hum instances share one loading state | Vamp + Hum |
|
|
385
411
|
| List loading from API | Ensemble |
|
|
386
412
|
| Spinner replaced by loaded content | Gigbag + Warmup |
|
|
387
413
|
| Accordion/table shimmer rows | Stub data + WarmupLine (wrapper-once pattern) |
|
package/dist/accordion.cjs
CHANGED
|
@@ -1229,12 +1229,13 @@ var styles_default = `/* concertina \u2014 Radix Accordion expand/collapse with
|
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
1231
|
/* Inactive Slot hiding \u2014 belt and suspenders.
|
|
1232
|
-
|
|
1233
|
-
|
|
1232
|
+
Primary: inline style on the Slot element (visibility: hidden + opacity: 0).
|
|
1233
|
+
Inline styles can't be overridden by any CSS cascade \u2014 this is the
|
|
1234
|
+
bulletproof layer.
|
|
1235
|
+
Backup: CSS rules below catch edge cases (e.g. if inline styles are
|
|
1236
|
+
stripped by a framework or test harness).
|
|
1234
1237
|
transition: none on descendants prevents children with transition-all
|
|
1235
|
-
from animating the inherited visibility change
|
|
1236
|
-
inherited; transition-all transitions it over the child's duration
|
|
1237
|
-
instead of hiding instantly). */
|
|
1238
|
+
from animating the inherited visibility change. */
|
|
1238
1239
|
.concertina-stable-slot > [inert] {
|
|
1239
1240
|
visibility: hidden;
|
|
1240
1241
|
opacity: 0;
|
package/dist/accordion.js
CHANGED
|
@@ -1190,12 +1190,13 @@ var styles_default = `/* concertina \u2014 Radix Accordion expand/collapse with
|
|
|
1190
1190
|
}
|
|
1191
1191
|
|
|
1192
1192
|
/* Inactive Slot hiding \u2014 belt and suspenders.
|
|
1193
|
-
|
|
1194
|
-
|
|
1193
|
+
Primary: inline style on the Slot element (visibility: hidden + opacity: 0).
|
|
1194
|
+
Inline styles can't be overridden by any CSS cascade \u2014 this is the
|
|
1195
|
+
bulletproof layer.
|
|
1196
|
+
Backup: CSS rules below catch edge cases (e.g. if inline styles are
|
|
1197
|
+
stripped by a framework or test harness).
|
|
1195
1198
|
transition: none on descendants prevents children with transition-all
|
|
1196
|
-
from animating the inherited visibility change
|
|
1197
|
-
inherited; transition-all transitions it over the child's duration
|
|
1198
|
-
instead of hiding instantly). */
|
|
1199
|
+
from animating the inherited visibility change. */
|
|
1199
1200
|
.concertina-stable-slot > [inert] {
|
|
1200
1201
|
visibility: hidden;
|
|
1201
1202
|
opacity: 0;
|
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,8 @@ __export(index_exports, {
|
|
|
46
46
|
StableSlot: () => Bellows,
|
|
47
47
|
StableText: () => Hum,
|
|
48
48
|
Trigger: () => Trigger2,
|
|
49
|
+
Vamp: () => Vamp,
|
|
50
|
+
VampContext: () => VampContext,
|
|
49
51
|
Warmup: () => Warmup,
|
|
50
52
|
WarmupLine: () => WarmupLine,
|
|
51
53
|
pinToScrollTop: () => pinToScrollTop,
|
|
@@ -56,6 +58,7 @@ __export(index_exports, {
|
|
|
56
58
|
useSize: () => useSize,
|
|
57
59
|
useStableSlot: () => useStableSlot,
|
|
58
60
|
useTransitionLock: () => useTransitionLock,
|
|
61
|
+
useVamp: () => useVamp,
|
|
59
62
|
useWarmupExit: () => useWarmupExit
|
|
60
63
|
});
|
|
61
64
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1247,12 +1250,13 @@ var styles_default = `/* concertina \u2014 Radix Accordion expand/collapse with
|
|
|
1247
1250
|
}
|
|
1248
1251
|
|
|
1249
1252
|
/* Inactive Slot hiding \u2014 belt and suspenders.
|
|
1250
|
-
|
|
1251
|
-
|
|
1253
|
+
Primary: inline style on the Slot element (visibility: hidden + opacity: 0).
|
|
1254
|
+
Inline styles can't be overridden by any CSS cascade \u2014 this is the
|
|
1255
|
+
bulletproof layer.
|
|
1256
|
+
Backup: CSS rules below catch edge cases (e.g. if inline styles are
|
|
1257
|
+
stripped by a framework or test harness).
|
|
1252
1258
|
transition: none on descendants prevents children with transition-all
|
|
1253
|
-
from animating the inherited visibility change
|
|
1254
|
-
inherited; transition-all transitions it over the child's duration
|
|
1255
|
-
instead of hiding instantly). */
|
|
1259
|
+
from animating the inherited visibility change. */
|
|
1256
1260
|
.concertina-stable-slot > [inert] {
|
|
1257
1261
|
visibility: hidden;
|
|
1258
1262
|
opacity: 0;
|
|
@@ -1412,18 +1416,20 @@ var Bellows = (0, import_react11.forwardRef)(
|
|
|
1412
1416
|
// src/components/slot.tsx
|
|
1413
1417
|
var import_react12 = require("react");
|
|
1414
1418
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1419
|
+
var HIDDEN_STYLE = { visibility: "hidden", opacity: 0 };
|
|
1415
1420
|
var Slot = (0, import_react12.forwardRef)(
|
|
1416
1421
|
function Slot2({ active, note, as: Tag = "div", style, children, ...props }, ref) {
|
|
1417
1422
|
(0, import_react12.useInsertionEffect)(injectStyles, []);
|
|
1418
1423
|
(0, import_react12.useContext)(AxisContext);
|
|
1419
1424
|
const activeNote = (0, import_react12.useContext)(ActiveNoteContext);
|
|
1420
|
-
const isActive = active ?? (note != null
|
|
1425
|
+
const isActive = active ?? (note != null ? note === activeNote : true);
|
|
1426
|
+
const merged = isActive ? style : style ? { ...style, ...HIDDEN_STYLE } : HIDDEN_STYLE;
|
|
1421
1427
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1422
1428
|
Tag,
|
|
1423
1429
|
{
|
|
1424
1430
|
ref,
|
|
1425
1431
|
inert: !isActive || void 0,
|
|
1426
|
-
style,
|
|
1432
|
+
style: merged,
|
|
1427
1433
|
...props,
|
|
1428
1434
|
children
|
|
1429
1435
|
}
|
|
@@ -1432,34 +1438,49 @@ var Slot = (0, import_react12.forwardRef)(
|
|
|
1432
1438
|
);
|
|
1433
1439
|
|
|
1434
1440
|
// src/components/hum.tsx
|
|
1441
|
+
var import_react14 = require("react");
|
|
1442
|
+
|
|
1443
|
+
// src/components/vamp.tsx
|
|
1435
1444
|
var import_react13 = require("react");
|
|
1436
1445
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1437
|
-
var
|
|
1446
|
+
var VampContext = (0, import_react13.createContext)(false);
|
|
1447
|
+
function useVamp() {
|
|
1448
|
+
return (0, import_react13.useContext)(VampContext);
|
|
1449
|
+
}
|
|
1450
|
+
function Vamp({ loading, children }) {
|
|
1451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(VampContext.Provider, { value: loading, children });
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
// src/components/hum.tsx
|
|
1455
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1456
|
+
var Hum = (0, import_react14.forwardRef)(
|
|
1438
1457
|
function Hum2({ loading, as: Tag = "span", className, children, ...props }, ref) {
|
|
1439
|
-
(0,
|
|
1440
|
-
|
|
1458
|
+
(0, import_react14.useInsertionEffect)(injectStyles, []);
|
|
1459
|
+
const vampLoading = useVamp();
|
|
1460
|
+
const isLoading = loading ?? vampLoading;
|
|
1461
|
+
if (isLoading) {
|
|
1441
1462
|
const merged = className ? `concertina-warmup-line ${className}` : "concertina-warmup-line";
|
|
1442
|
-
return /* @__PURE__ */ (0,
|
|
1463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tag, { ref, className: merged, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tag, { inert: true, children }) });
|
|
1443
1464
|
}
|
|
1444
|
-
return /* @__PURE__ */ (0,
|
|
1465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tag, { ref, className, ...props, children });
|
|
1445
1466
|
}
|
|
1446
1467
|
);
|
|
1447
1468
|
|
|
1448
1469
|
// src/components/ensemble.tsx
|
|
1449
|
-
var
|
|
1470
|
+
var import_react19 = require("react");
|
|
1450
1471
|
|
|
1451
1472
|
// src/components/gigbag.tsx
|
|
1452
|
-
var
|
|
1473
|
+
var import_react16 = require("react");
|
|
1453
1474
|
|
|
1454
1475
|
// src/primitives/use-stable-slot.ts
|
|
1455
|
-
var
|
|
1476
|
+
var import_react15 = require("react");
|
|
1456
1477
|
var RATCHET_FLOOR = -Infinity;
|
|
1457
1478
|
function useStableSlot(options = {}) {
|
|
1458
1479
|
const { axis = "both" } = options;
|
|
1459
|
-
const [style, setStyle] = (0,
|
|
1460
|
-
const maxRef = (0,
|
|
1461
|
-
const observerRef = (0,
|
|
1462
|
-
const ref = (0,
|
|
1480
|
+
const [style, setStyle] = (0, import_react15.useState)({});
|
|
1481
|
+
const maxRef = (0, import_react15.useRef)({ w: RATCHET_FLOOR, h: RATCHET_FLOOR });
|
|
1482
|
+
const observerRef = (0, import_react15.useRef)(null);
|
|
1483
|
+
const ref = (0, import_react15.useCallback)(
|
|
1463
1484
|
(el) => {
|
|
1464
1485
|
if (observerRef.current) {
|
|
1465
1486
|
observerRef.current.disconnect();
|
|
@@ -1506,13 +1527,13 @@ function useStableSlot(options = {}) {
|
|
|
1506
1527
|
}
|
|
1507
1528
|
|
|
1508
1529
|
// src/components/gigbag.tsx
|
|
1509
|
-
var
|
|
1510
|
-
var Gigbag = (0,
|
|
1530
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1531
|
+
var Gigbag = (0, import_react16.forwardRef)(
|
|
1511
1532
|
function Gigbag2({ axis = "height", as: Tag = "div", className, style, children, ...props }, fwdRef) {
|
|
1512
|
-
(0,
|
|
1533
|
+
(0, import_react16.useInsertionEffect)(injectStyles, []);
|
|
1513
1534
|
const { ref: ratchetRef, style: ratchetStyle } = useStableSlot({ axis });
|
|
1514
1535
|
const merged = className ? `concertina-gigbag ${className}` : "concertina-gigbag";
|
|
1515
|
-
return /* @__PURE__ */ (0,
|
|
1536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1516
1537
|
Tag,
|
|
1517
1538
|
{
|
|
1518
1539
|
ref: mergeRefs(ratchetRef, fwdRef),
|
|
@@ -1526,19 +1547,19 @@ var Gigbag = (0, import_react15.forwardRef)(
|
|
|
1526
1547
|
);
|
|
1527
1548
|
|
|
1528
1549
|
// src/components/warmup.tsx
|
|
1529
|
-
var
|
|
1530
|
-
var
|
|
1531
|
-
var Warmup = (0,
|
|
1550
|
+
var import_react17 = require("react");
|
|
1551
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1552
|
+
var Warmup = (0, import_react17.forwardRef)(
|
|
1532
1553
|
function Warmup2({ rows, columns, as: Tag = "div", className, children, ...props }, ref) {
|
|
1533
|
-
(0,
|
|
1554
|
+
(0, import_react17.useInsertionEffect)(injectStyles, []);
|
|
1534
1555
|
const merged = className ? `concertina-warmup ${className}` : "concertina-warmup";
|
|
1535
1556
|
const count2 = columns ? rows * columns : rows;
|
|
1536
|
-
const cells = Array.from({ length: count2 }, (_, i) => /* @__PURE__ */ (0,
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1557
|
+
const cells = Array.from({ length: count2 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "concertina-warmup-bone", children: [
|
|
1558
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "concertina-warmup-line" }),
|
|
1559
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "concertina-warmup-line" })
|
|
1539
1560
|
] }, i));
|
|
1540
1561
|
const gridStyle = columns ? { gridTemplateColumns: `repeat(${columns}, auto)`, gridTemplateAreas: `'${"chamber ".repeat(columns).trim()}'` } : { gridTemplateAreas: "'chamber'" };
|
|
1541
|
-
return /* @__PURE__ */ (0,
|
|
1562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1542
1563
|
Tag,
|
|
1543
1564
|
{
|
|
1544
1565
|
ref,
|
|
@@ -1552,11 +1573,11 @@ var Warmup = (0, import_react16.forwardRef)(
|
|
|
1552
1573
|
);
|
|
1553
1574
|
|
|
1554
1575
|
// src/primitives/use-warmup-exit.ts
|
|
1555
|
-
var
|
|
1576
|
+
var import_react18 = require("react");
|
|
1556
1577
|
function useWarmupExit(loading, duration) {
|
|
1557
|
-
const [exiting, setExiting] = (0,
|
|
1558
|
-
const prevLoading = (0,
|
|
1559
|
-
(0,
|
|
1578
|
+
const [exiting, setExiting] = (0, import_react18.useState)(false);
|
|
1579
|
+
const prevLoading = (0, import_react18.useRef)(loading);
|
|
1580
|
+
(0, import_react18.useEffect)(() => {
|
|
1560
1581
|
if (prevLoading.current && !loading) {
|
|
1561
1582
|
setExiting(true);
|
|
1562
1583
|
const id = setTimeout(() => setExiting(false), duration);
|
|
@@ -1574,7 +1595,7 @@ function useWarmupExit(loading, duration) {
|
|
|
1574
1595
|
}
|
|
1575
1596
|
|
|
1576
1597
|
// src/components/ensemble.tsx
|
|
1577
|
-
var
|
|
1598
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1578
1599
|
function EnsembleInner({
|
|
1579
1600
|
items,
|
|
1580
1601
|
loading,
|
|
@@ -1585,33 +1606,33 @@ function EnsembleInner({
|
|
|
1585
1606
|
className,
|
|
1586
1607
|
...props
|
|
1587
1608
|
}, ref) {
|
|
1588
|
-
(0,
|
|
1609
|
+
(0, import_react19.useInsertionEffect)(injectStyles, []);
|
|
1589
1610
|
const { showWarmup, exiting } = useWarmupExit(loading, exitDuration);
|
|
1590
1611
|
const warmupClass = exiting ? className ? `concertina-warmup-exiting ${className}` : "concertina-warmup-exiting" : className;
|
|
1591
|
-
return /* @__PURE__ */ (0,
|
|
1612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Gigbag, { ref, axis: "height", as: Tag, ...props, children: showWarmup ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Warmup, { rows: stubCount, className: warmupClass }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Tag, { className, children: items.map(renderItem) }) });
|
|
1592
1613
|
}
|
|
1593
|
-
var Ensemble = (0,
|
|
1614
|
+
var Ensemble = (0, import_react19.forwardRef)(EnsembleInner);
|
|
1594
1615
|
|
|
1595
1616
|
// src/components/warmup-line.tsx
|
|
1596
|
-
var
|
|
1597
|
-
var
|
|
1598
|
-
var WarmupLine = (0,
|
|
1617
|
+
var import_react20 = require("react");
|
|
1618
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1619
|
+
var WarmupLine = (0, import_react20.forwardRef)(
|
|
1599
1620
|
function WarmupLine2({ as: Tag = "div", className, ...props }, ref) {
|
|
1600
|
-
(0,
|
|
1621
|
+
(0, import_react20.useInsertionEffect)(injectStyles, []);
|
|
1601
1622
|
const merged = className ? `concertina-warmup-line ${className}` : "concertina-warmup-line";
|
|
1602
|
-
return /* @__PURE__ */ (0,
|
|
1623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Tag, { ref, className: merged, ...props });
|
|
1603
1624
|
}
|
|
1604
1625
|
);
|
|
1605
1626
|
|
|
1606
1627
|
// src/components/glide.tsx
|
|
1607
|
-
var
|
|
1628
|
+
var import_react22 = require("react");
|
|
1608
1629
|
|
|
1609
1630
|
// src/primitives/use-presence.ts
|
|
1610
|
-
var
|
|
1631
|
+
var import_react21 = require("react");
|
|
1611
1632
|
function usePresence2(show) {
|
|
1612
|
-
const [mounted, setMounted] = (0,
|
|
1613
|
-
const [phase, setPhase] = (0,
|
|
1614
|
-
(0,
|
|
1633
|
+
const [mounted, setMounted] = (0, import_react21.useState)(show);
|
|
1634
|
+
const [phase, setPhase] = (0, import_react21.useState)(show ? "entered" : "exiting");
|
|
1635
|
+
(0, import_react21.useEffect)(() => {
|
|
1615
1636
|
if (show) {
|
|
1616
1637
|
setMounted(true);
|
|
1617
1638
|
setPhase("entering");
|
|
@@ -1619,7 +1640,7 @@ function usePresence2(show) {
|
|
|
1619
1640
|
setPhase("exiting");
|
|
1620
1641
|
}
|
|
1621
1642
|
}, [show]);
|
|
1622
|
-
const onAnimationEnd = (0,
|
|
1643
|
+
const onAnimationEnd = (0, import_react21.useCallback)(
|
|
1623
1644
|
(e) => {
|
|
1624
1645
|
if (e.target !== e.currentTarget) return;
|
|
1625
1646
|
if (phase === "entering") setPhase("entered");
|
|
@@ -1631,15 +1652,15 @@ function usePresence2(show) {
|
|
|
1631
1652
|
}
|
|
1632
1653
|
|
|
1633
1654
|
// src/components/glide.tsx
|
|
1634
|
-
var
|
|
1635
|
-
var Glide = (0,
|
|
1655
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1656
|
+
var Glide = (0, import_react22.forwardRef)(
|
|
1636
1657
|
function Glide2({ show, as: Tag = "div", className, children, ...props }, ref) {
|
|
1637
|
-
(0,
|
|
1658
|
+
(0, import_react22.useInsertionEffect)(injectStyles, []);
|
|
1638
1659
|
const { mounted, phase, onAnimationEnd } = usePresence2(show);
|
|
1639
1660
|
if (!mounted) return null;
|
|
1640
1661
|
const phaseClass = phase === "entering" ? "concertina-glide-entering" : phase === "exiting" ? "concertina-glide-exiting" : "";
|
|
1641
1662
|
const merged = ["concertina-glide", phaseClass, className].filter(Boolean).join(" ");
|
|
1642
|
-
return /* @__PURE__ */ (0,
|
|
1663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1643
1664
|
Tag,
|
|
1644
1665
|
{
|
|
1645
1666
|
ref,
|
|
@@ -1653,12 +1674,12 @@ var Glide = (0, import_react21.forwardRef)(
|
|
|
1653
1674
|
);
|
|
1654
1675
|
|
|
1655
1676
|
// src/primitives/use-size.ts
|
|
1656
|
-
var
|
|
1677
|
+
var import_react23 = require("react");
|
|
1657
1678
|
var NO_OBSERVATION = { width: Number.NaN, height: Number.NaN };
|
|
1658
1679
|
function useSize() {
|
|
1659
|
-
const [size, setSize] = (0,
|
|
1660
|
-
const observerRef = (0,
|
|
1661
|
-
const ref = (0,
|
|
1680
|
+
const [size, setSize] = (0, import_react23.useState)(NO_OBSERVATION);
|
|
1681
|
+
const observerRef = (0, import_react23.useRef)(null);
|
|
1682
|
+
const ref = (0, import_react23.useCallback)((el) => {
|
|
1662
1683
|
if (observerRef.current) {
|
|
1663
1684
|
observerRef.current.disconnect();
|
|
1664
1685
|
observerRef.current = null;
|
|
@@ -1687,12 +1708,12 @@ function useSize() {
|
|
|
1687
1708
|
}
|
|
1688
1709
|
|
|
1689
1710
|
// src/accordion/use-concertina.ts
|
|
1690
|
-
var
|
|
1711
|
+
var import_react24 = require("react");
|
|
1691
1712
|
function useConcertina() {
|
|
1692
|
-
const [value, setValue] = (0,
|
|
1693
|
-
const [switching, setSwitching] = (0,
|
|
1694
|
-
const itemRefs = (0,
|
|
1695
|
-
const onValueChange = (0,
|
|
1713
|
+
const [value, setValue] = (0, import_react24.useState)("");
|
|
1714
|
+
const [switching, setSwitching] = (0, import_react24.useState)(false);
|
|
1715
|
+
const itemRefs = (0, import_react24.useRef)({});
|
|
1716
|
+
const onValueChange = (0, import_react24.useCallback)(
|
|
1696
1717
|
(newValue) => {
|
|
1697
1718
|
if (!newValue) {
|
|
1698
1719
|
setSwitching(false);
|
|
@@ -1704,14 +1725,14 @@ function useConcertina() {
|
|
|
1704
1725
|
},
|
|
1705
1726
|
[value]
|
|
1706
1727
|
);
|
|
1707
|
-
(0,
|
|
1728
|
+
(0, import_react24.useLayoutEffect)(() => {
|
|
1708
1729
|
if (!value) return;
|
|
1709
1730
|
pinToScrollTop(itemRefs.current[value]);
|
|
1710
1731
|
}, [value]);
|
|
1711
|
-
(0,
|
|
1732
|
+
(0, import_react24.useEffect)(() => {
|
|
1712
1733
|
if (switching) setSwitching(false);
|
|
1713
1734
|
}, [switching]);
|
|
1714
|
-
const getItemRef = (0,
|
|
1735
|
+
const getItemRef = (0, import_react24.useCallback)(
|
|
1715
1736
|
(id) => (el) => {
|
|
1716
1737
|
itemRefs.current[id] = el;
|
|
1717
1738
|
},
|
|
@@ -1742,6 +1763,8 @@ function useConcertina() {
|
|
|
1742
1763
|
StableSlot,
|
|
1743
1764
|
StableText,
|
|
1744
1765
|
Trigger,
|
|
1766
|
+
Vamp,
|
|
1767
|
+
VampContext,
|
|
1745
1768
|
Warmup,
|
|
1746
1769
|
WarmupLine,
|
|
1747
1770
|
pinToScrollTop,
|
|
@@ -1752,5 +1775,6 @@ function useConcertina() {
|
|
|
1752
1775
|
useSize,
|
|
1753
1776
|
useStableSlot,
|
|
1754
1777
|
useTransitionLock,
|
|
1778
|
+
useVamp,
|
|
1755
1779
|
useWarmupExit
|
|
1756
1780
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -2,6 +2,7 @@ export { ConcertinaContext, ConcertinaRootProps, ConcertinaStore, Content, Item,
|
|
|
2
2
|
export { Header, Trigger } from '@radix-ui/react-accordion';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { HTMLAttributes, ElementType, ReactNode, Ref, ReactElement, AnimationEvent, DependencyList, CSSProperties } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
type Axis = "width" | "height" | "both";
|
|
7
8
|
interface BellowsProps extends HTMLAttributes<HTMLElement> {
|
|
@@ -34,15 +35,18 @@ interface SlotProps extends HTMLAttributes<HTMLElement> {
|
|
|
34
35
|
* All slots overlap via CSS grid. Inactive slots are hidden
|
|
35
36
|
* but still contribute to grid cell sizing.
|
|
36
37
|
*
|
|
37
|
-
* Inactive hiding
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* Inactive hiding uses inline styles (can't be overridden by CSS cascade)
|
|
39
|
+
* plus the [inert] attribute for accessibility (non-focusable, non-interactive).
|
|
40
|
+
* CSS `.concertina-stable-slot > [inert]` serves as a backup.
|
|
40
41
|
*/
|
|
41
42
|
declare const Slot: react.ForwardRefExoticComponent<SlotProps & react.RefAttributes<HTMLElement>>;
|
|
42
43
|
|
|
43
44
|
interface HumProps extends HTMLAttributes<HTMLElement> {
|
|
44
|
-
/**
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Whether data is loading. Shows shimmer when true, children when false.
|
|
47
|
+
* When omitted, falls back to the nearest `<Vamp>` ancestor's loading state.
|
|
48
|
+
*/
|
|
49
|
+
loading?: boolean;
|
|
46
50
|
/** HTML element to render. Default: "span". */
|
|
47
51
|
as?: ElementType;
|
|
48
52
|
}
|
|
@@ -56,9 +60,35 @@ interface HumProps extends HTMLAttributes<HTMLElement> {
|
|
|
56
60
|
*
|
|
57
61
|
* The className is passed through so `1lh` inherits the correct font
|
|
58
62
|
* metrics from the consuming context.
|
|
63
|
+
*
|
|
64
|
+
* When no explicit `loading` prop is provided, Hum reads from the
|
|
65
|
+
* nearest `<Vamp>` ancestor. This lets a single provider control
|
|
66
|
+
* shimmer state for an entire subtree.
|
|
59
67
|
*/
|
|
60
68
|
declare const Hum: react.ForwardRefExoticComponent<HumProps & react.RefAttributes<HTMLElement>>;
|
|
61
69
|
|
|
70
|
+
/** Context carrying the ambient loading state set by Vamp. */
|
|
71
|
+
declare const VampContext: react.Context<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Read the nearest Vamp's loading state.
|
|
74
|
+
* Returns `false` when no Vamp ancestor exists.
|
|
75
|
+
*/
|
|
76
|
+
declare function useVamp(): boolean;
|
|
77
|
+
interface VampProps {
|
|
78
|
+
/** Whether the subtree is in a loading/warmup state. */
|
|
79
|
+
loading: boolean;
|
|
80
|
+
children: ReactNode;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Ambient loading provider — musical "vamping" (repeating a pattern
|
|
84
|
+
* while waiting for a cue).
|
|
85
|
+
*
|
|
86
|
+
* Wrapping a subtree in `<Vamp loading>` lets every nested `<Hum>`
|
|
87
|
+
* pick up the loading state automatically, without threading an
|
|
88
|
+
* explicit `loading` prop through every cell.
|
|
89
|
+
*/
|
|
90
|
+
declare function Vamp({ loading, children }: VampProps): react_jsx_runtime.JSX.Element;
|
|
91
|
+
|
|
62
92
|
interface EnsembleProps<T> extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
63
93
|
/** Data items to render. */
|
|
64
94
|
items: T[];
|
|
@@ -286,4 +316,4 @@ declare function useWarmupExit(loading: boolean, duration: number): {
|
|
|
286
316
|
exiting: boolean;
|
|
287
317
|
};
|
|
288
318
|
|
|
289
|
-
export { type Axis, Bellows, type BellowsProps, Ensemble, type EnsembleProps, Gigbag, type GigbagProps, Glide, type GlideProps, Hum, type HumProps, type Phase, type Size, Slot, type SlotProps, Ensemble as StableCollection, type EnsembleProps as StableCollectionProps, Bellows as StableSlot, type BellowsProps as StableSlotProps, Hum as StableText, type HumProps as StableTextProps, type UsePresenceReturn, Warmup, WarmupLine, type WarmupLineProps, type WarmupProps, pinToScrollTop, usePresence, useScrollPin, useSize, useStableSlot, useTransitionLock, useWarmupExit };
|
|
319
|
+
export { type Axis, Bellows, type BellowsProps, Ensemble, type EnsembleProps, Gigbag, type GigbagProps, Glide, type GlideProps, Hum, type HumProps, type Phase, type Size, Slot, type SlotProps, Ensemble as StableCollection, type EnsembleProps as StableCollectionProps, Bellows as StableSlot, type BellowsProps as StableSlotProps, Hum as StableText, type HumProps as StableTextProps, type UsePresenceReturn, Vamp, VampContext, type VampProps, Warmup, WarmupLine, type WarmupLineProps, type WarmupProps, pinToScrollTop, usePresence, useScrollPin, useSize, useStableSlot, useTransitionLock, useVamp, useWarmupExit };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { ConcertinaContext, ConcertinaRootProps, ConcertinaStore, Content, Item,
|
|
|
2
2
|
export { Header, Trigger } from '@radix-ui/react-accordion';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { HTMLAttributes, ElementType, ReactNode, Ref, ReactElement, AnimationEvent, DependencyList, CSSProperties } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
type Axis = "width" | "height" | "both";
|
|
7
8
|
interface BellowsProps extends HTMLAttributes<HTMLElement> {
|
|
@@ -34,15 +35,18 @@ interface SlotProps extends HTMLAttributes<HTMLElement> {
|
|
|
34
35
|
* All slots overlap via CSS grid. Inactive slots are hidden
|
|
35
36
|
* but still contribute to grid cell sizing.
|
|
36
37
|
*
|
|
37
|
-
* Inactive hiding
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* Inactive hiding uses inline styles (can't be overridden by CSS cascade)
|
|
39
|
+
* plus the [inert] attribute for accessibility (non-focusable, non-interactive).
|
|
40
|
+
* CSS `.concertina-stable-slot > [inert]` serves as a backup.
|
|
40
41
|
*/
|
|
41
42
|
declare const Slot: react.ForwardRefExoticComponent<SlotProps & react.RefAttributes<HTMLElement>>;
|
|
42
43
|
|
|
43
44
|
interface HumProps extends HTMLAttributes<HTMLElement> {
|
|
44
|
-
/**
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Whether data is loading. Shows shimmer when true, children when false.
|
|
47
|
+
* When omitted, falls back to the nearest `<Vamp>` ancestor's loading state.
|
|
48
|
+
*/
|
|
49
|
+
loading?: boolean;
|
|
46
50
|
/** HTML element to render. Default: "span". */
|
|
47
51
|
as?: ElementType;
|
|
48
52
|
}
|
|
@@ -56,9 +60,35 @@ interface HumProps extends HTMLAttributes<HTMLElement> {
|
|
|
56
60
|
*
|
|
57
61
|
* The className is passed through so `1lh` inherits the correct font
|
|
58
62
|
* metrics from the consuming context.
|
|
63
|
+
*
|
|
64
|
+
* When no explicit `loading` prop is provided, Hum reads from the
|
|
65
|
+
* nearest `<Vamp>` ancestor. This lets a single provider control
|
|
66
|
+
* shimmer state for an entire subtree.
|
|
59
67
|
*/
|
|
60
68
|
declare const Hum: react.ForwardRefExoticComponent<HumProps & react.RefAttributes<HTMLElement>>;
|
|
61
69
|
|
|
70
|
+
/** Context carrying the ambient loading state set by Vamp. */
|
|
71
|
+
declare const VampContext: react.Context<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Read the nearest Vamp's loading state.
|
|
74
|
+
* Returns `false` when no Vamp ancestor exists.
|
|
75
|
+
*/
|
|
76
|
+
declare function useVamp(): boolean;
|
|
77
|
+
interface VampProps {
|
|
78
|
+
/** Whether the subtree is in a loading/warmup state. */
|
|
79
|
+
loading: boolean;
|
|
80
|
+
children: ReactNode;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Ambient loading provider — musical "vamping" (repeating a pattern
|
|
84
|
+
* while waiting for a cue).
|
|
85
|
+
*
|
|
86
|
+
* Wrapping a subtree in `<Vamp loading>` lets every nested `<Hum>`
|
|
87
|
+
* pick up the loading state automatically, without threading an
|
|
88
|
+
* explicit `loading` prop through every cell.
|
|
89
|
+
*/
|
|
90
|
+
declare function Vamp({ loading, children }: VampProps): react_jsx_runtime.JSX.Element;
|
|
91
|
+
|
|
62
92
|
interface EnsembleProps<T> extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
63
93
|
/** Data items to render. */
|
|
64
94
|
items: T[];
|
|
@@ -286,4 +316,4 @@ declare function useWarmupExit(loading: boolean, duration: number): {
|
|
|
286
316
|
exiting: boolean;
|
|
287
317
|
};
|
|
288
318
|
|
|
289
|
-
export { type Axis, Bellows, type BellowsProps, Ensemble, type EnsembleProps, Gigbag, type GigbagProps, Glide, type GlideProps, Hum, type HumProps, type Phase, type Size, Slot, type SlotProps, Ensemble as StableCollection, type EnsembleProps as StableCollectionProps, Bellows as StableSlot, type BellowsProps as StableSlotProps, Hum as StableText, type HumProps as StableTextProps, type UsePresenceReturn, Warmup, WarmupLine, type WarmupLineProps, type WarmupProps, pinToScrollTop, usePresence, useScrollPin, useSize, useStableSlot, useTransitionLock, useWarmupExit };
|
|
319
|
+
export { type Axis, Bellows, type BellowsProps, Ensemble, type EnsembleProps, Gigbag, type GigbagProps, Glide, type GlideProps, Hum, type HumProps, type Phase, type Size, Slot, type SlotProps, Ensemble as StableCollection, type EnsembleProps as StableCollectionProps, Bellows as StableSlot, type BellowsProps as StableSlotProps, Hum as StableText, type HumProps as StableTextProps, type UsePresenceReturn, Vamp, VampContext, type VampProps, Warmup, WarmupLine, type WarmupLineProps, type WarmupProps, pinToScrollTop, usePresence, useScrollPin, useSize, useStableSlot, useTransitionLock, useVamp, useWarmupExit };
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
useExpanded,
|
|
14
14
|
useScrollPin,
|
|
15
15
|
useTransitionLock
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-OGJMPKZX.js";
|
|
17
17
|
|
|
18
18
|
// src/components/bellows.tsx
|
|
19
19
|
import {
|
|
@@ -39,18 +39,20 @@ import {
|
|
|
39
39
|
useInsertionEffect as useInsertionEffect2
|
|
40
40
|
} from "react";
|
|
41
41
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
42
|
+
var HIDDEN_STYLE = { visibility: "hidden", opacity: 0 };
|
|
42
43
|
var Slot = forwardRef2(
|
|
43
44
|
function Slot2({ active, note, as: Tag = "div", style, children, ...props }, ref) {
|
|
44
45
|
useInsertionEffect2(injectStyles, []);
|
|
45
46
|
useContext(AxisContext);
|
|
46
47
|
const activeNote = useContext(ActiveNoteContext);
|
|
47
|
-
const isActive = active ?? (note != null
|
|
48
|
+
const isActive = active ?? (note != null ? note === activeNote : true);
|
|
49
|
+
const merged = isActive ? style : style ? { ...style, ...HIDDEN_STYLE } : HIDDEN_STYLE;
|
|
48
50
|
return /* @__PURE__ */ jsx2(
|
|
49
51
|
Tag,
|
|
50
52
|
{
|
|
51
53
|
ref,
|
|
52
54
|
inert: !isActive || void 0,
|
|
53
|
-
style,
|
|
55
|
+
style: merged,
|
|
54
56
|
...props,
|
|
55
57
|
children
|
|
56
58
|
}
|
|
@@ -63,15 +65,30 @@ import {
|
|
|
63
65
|
forwardRef as forwardRef3,
|
|
64
66
|
useInsertionEffect as useInsertionEffect3
|
|
65
67
|
} from "react";
|
|
68
|
+
|
|
69
|
+
// src/components/vamp.tsx
|
|
70
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
66
71
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
72
|
+
var VampContext = createContext2(false);
|
|
73
|
+
function useVamp() {
|
|
74
|
+
return useContext2(VampContext);
|
|
75
|
+
}
|
|
76
|
+
function Vamp({ loading, children }) {
|
|
77
|
+
return /* @__PURE__ */ jsx3(VampContext.Provider, { value: loading, children });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/components/hum.tsx
|
|
81
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
67
82
|
var Hum = forwardRef3(
|
|
68
83
|
function Hum2({ loading, as: Tag = "span", className, children, ...props }, ref) {
|
|
69
84
|
useInsertionEffect3(injectStyles, []);
|
|
70
|
-
|
|
85
|
+
const vampLoading = useVamp();
|
|
86
|
+
const isLoading = loading ?? vampLoading;
|
|
87
|
+
if (isLoading) {
|
|
71
88
|
const merged = className ? `concertina-warmup-line ${className}` : "concertina-warmup-line";
|
|
72
|
-
return /* @__PURE__ */
|
|
89
|
+
return /* @__PURE__ */ jsx4(Tag, { ref, className: merged, ...props, children: /* @__PURE__ */ jsx4(Tag, { inert: true, children }) });
|
|
73
90
|
}
|
|
74
|
-
return /* @__PURE__ */
|
|
91
|
+
return /* @__PURE__ */ jsx4(Tag, { ref, className, ...props, children });
|
|
75
92
|
}
|
|
76
93
|
);
|
|
77
94
|
|
|
@@ -139,13 +156,13 @@ function useStableSlot(options = {}) {
|
|
|
139
156
|
}
|
|
140
157
|
|
|
141
158
|
// src/components/gigbag.tsx
|
|
142
|
-
import { jsx as
|
|
159
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
143
160
|
var Gigbag = forwardRef4(
|
|
144
161
|
function Gigbag2({ axis = "height", as: Tag = "div", className, style, children, ...props }, fwdRef) {
|
|
145
162
|
useInsertionEffect4(injectStyles, []);
|
|
146
163
|
const { ref: ratchetRef, style: ratchetStyle } = useStableSlot({ axis });
|
|
147
164
|
const merged = className ? `concertina-gigbag ${className}` : "concertina-gigbag";
|
|
148
|
-
return /* @__PURE__ */
|
|
165
|
+
return /* @__PURE__ */ jsx5(
|
|
149
166
|
Tag,
|
|
150
167
|
{
|
|
151
168
|
ref: mergeRefs(ratchetRef, fwdRef),
|
|
@@ -160,18 +177,18 @@ var Gigbag = forwardRef4(
|
|
|
160
177
|
|
|
161
178
|
// src/components/warmup.tsx
|
|
162
179
|
import { forwardRef as forwardRef5, useInsertionEffect as useInsertionEffect5 } from "react";
|
|
163
|
-
import { jsx as
|
|
180
|
+
import { jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
164
181
|
var Warmup = forwardRef5(
|
|
165
182
|
function Warmup2({ rows, columns, as: Tag = "div", className, children, ...props }, ref) {
|
|
166
183
|
useInsertionEffect5(injectStyles, []);
|
|
167
184
|
const merged = className ? `concertina-warmup ${className}` : "concertina-warmup";
|
|
168
185
|
const count = columns ? rows * columns : rows;
|
|
169
186
|
const cells = Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsxs("div", { className: "concertina-warmup-bone", children: [
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ jsx6("div", { className: "concertina-warmup-line" }),
|
|
188
|
+
/* @__PURE__ */ jsx6("div", { className: "concertina-warmup-line" })
|
|
172
189
|
] }, i));
|
|
173
190
|
const gridStyle = columns ? { gridTemplateColumns: `repeat(${columns}, auto)`, gridTemplateAreas: `'${"chamber ".repeat(columns).trim()}'` } : { gridTemplateAreas: "'chamber'" };
|
|
174
|
-
return /* @__PURE__ */
|
|
191
|
+
return /* @__PURE__ */ jsx6(
|
|
175
192
|
Tag,
|
|
176
193
|
{
|
|
177
194
|
ref,
|
|
@@ -207,7 +224,7 @@ function useWarmupExit(loading, duration) {
|
|
|
207
224
|
}
|
|
208
225
|
|
|
209
226
|
// src/components/ensemble.tsx
|
|
210
|
-
import { jsx as
|
|
227
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
211
228
|
function EnsembleInner({
|
|
212
229
|
items,
|
|
213
230
|
loading,
|
|
@@ -221,18 +238,18 @@ function EnsembleInner({
|
|
|
221
238
|
useInsertionEffect6(injectStyles, []);
|
|
222
239
|
const { showWarmup, exiting } = useWarmupExit(loading, exitDuration);
|
|
223
240
|
const warmupClass = exiting ? className ? `concertina-warmup-exiting ${className}` : "concertina-warmup-exiting" : className;
|
|
224
|
-
return /* @__PURE__ */
|
|
241
|
+
return /* @__PURE__ */ jsx7(Gigbag, { ref, axis: "height", as: Tag, ...props, children: showWarmup ? /* @__PURE__ */ jsx7(Warmup, { rows: stubCount, className: warmupClass }) : /* @__PURE__ */ jsx7(Tag, { className, children: items.map(renderItem) }) });
|
|
225
242
|
}
|
|
226
243
|
var Ensemble = forwardRef6(EnsembleInner);
|
|
227
244
|
|
|
228
245
|
// src/components/warmup-line.tsx
|
|
229
246
|
import { forwardRef as forwardRef7, useInsertionEffect as useInsertionEffect7 } from "react";
|
|
230
|
-
import { jsx as
|
|
247
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
231
248
|
var WarmupLine = forwardRef7(
|
|
232
249
|
function WarmupLine2({ as: Tag = "div", className, ...props }, ref) {
|
|
233
250
|
useInsertionEffect7(injectStyles, []);
|
|
234
251
|
const merged = className ? `concertina-warmup-line ${className}` : "concertina-warmup-line";
|
|
235
|
-
return /* @__PURE__ */
|
|
252
|
+
return /* @__PURE__ */ jsx8(Tag, { ref, className: merged, ...props });
|
|
236
253
|
}
|
|
237
254
|
);
|
|
238
255
|
|
|
@@ -271,7 +288,7 @@ function usePresence(show) {
|
|
|
271
288
|
}
|
|
272
289
|
|
|
273
290
|
// src/components/glide.tsx
|
|
274
|
-
import { jsx as
|
|
291
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
275
292
|
var Glide = forwardRef8(
|
|
276
293
|
function Glide2({ show, as: Tag = "div", className, children, ...props }, ref) {
|
|
277
294
|
useInsertionEffect8(injectStyles, []);
|
|
@@ -279,7 +296,7 @@ var Glide = forwardRef8(
|
|
|
279
296
|
if (!mounted) return null;
|
|
280
297
|
const phaseClass = phase === "entering" ? "concertina-glide-entering" : phase === "exiting" ? "concertina-glide-exiting" : "";
|
|
281
298
|
const merged = ["concertina-glide", phaseClass, className].filter(Boolean).join(" ");
|
|
282
|
-
return /* @__PURE__ */
|
|
299
|
+
return /* @__PURE__ */ jsx9(
|
|
283
300
|
Tag,
|
|
284
301
|
{
|
|
285
302
|
ref,
|
|
@@ -342,6 +359,8 @@ export {
|
|
|
342
359
|
Bellows as StableSlot,
|
|
343
360
|
Hum as StableText,
|
|
344
361
|
Trigger2 as Trigger,
|
|
362
|
+
Vamp,
|
|
363
|
+
VampContext,
|
|
345
364
|
Warmup,
|
|
346
365
|
WarmupLine,
|
|
347
366
|
pinToScrollTop,
|
|
@@ -352,5 +371,6 @@ export {
|
|
|
352
371
|
useSize,
|
|
353
372
|
useStableSlot,
|
|
354
373
|
useTransitionLock,
|
|
374
|
+
useVamp,
|
|
355
375
|
useWarmupExit
|
|
356
376
|
};
|
package/dist/styles.css
CHANGED
|
@@ -67,12 +67,13 @@
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/* Inactive Slot hiding — belt and suspenders.
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
Primary: inline style on the Slot element (visibility: hidden + opacity: 0).
|
|
71
|
+
Inline styles can't be overridden by any CSS cascade — this is the
|
|
72
|
+
bulletproof layer.
|
|
73
|
+
Backup: CSS rules below catch edge cases (e.g. if inline styles are
|
|
74
|
+
stripped by a framework or test harness).
|
|
72
75
|
transition: none on descendants prevents children with transition-all
|
|
73
|
-
from animating the inherited visibility change
|
|
74
|
-
inherited; transition-all transitions it over the child's duration
|
|
75
|
-
instead of hiding instantly). */
|
|
76
|
+
from animating the inherited visibility change. */
|
|
76
77
|
.concertina-stable-slot > [inert] {
|
|
77
78
|
visibility: hidden;
|
|
78
79
|
opacity: 0;
|