@charcuterie/ui 3.14.4 → 3.15.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stepper.d.ts","sourceRoot":"","sources":["../../src/Stepper/Stepper.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Stepper.d.ts","sourceRoot":"","sources":["../../src/Stepper/Stepper.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,SAAS,GACT,MAAM,GACN,UAAU,CAAA;AAEd,MAAM,MAAM,IAAI,GAAG;IACjB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB;uCACmC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAA;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,UAAU,CAAA;AAE1D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACrC;2CACuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAA;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAA;CAChC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,OAAO,GAAI,yDAMrB,YAAY,gCAuId,CAAA"}
|
package/dist/Stepper/Stepper.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FLIP_KEY_ATTRIBUTE } from "@charcuterie/logic";
|
|
2
3
|
import { toClassName } from "../toClassName.js";
|
|
3
4
|
import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
4
5
|
/**
|
|
@@ -45,7 +46,7 @@ export const Stepper = ({ className, headingLevel = 3, label, orientation = "ver
|
|
|
45
46
|
isHorizontal && "cq-md:flex-row cq-md:gap-0"), children: steps.map((step, index) => {
|
|
46
47
|
const status = step.status ?? "upcoming";
|
|
47
48
|
const isLast = index === steps.length - 1;
|
|
48
|
-
return (_jsxs("li", { className: toClassName("relative grid grid-cols-[auto_minmax(0,1fr)] grid-rows-[auto_minmax(0,1fr)] gap-x-3", isHorizontal &&
|
|
49
|
+
return (_jsxs("li", { [FLIP_KEY_ATTRIBUTE]: step.key, className: toClassName("relative grid grid-cols-[auto_minmax(0,1fr)] grid-rows-[auto_minmax(0,1fr)] gap-x-3", isHorizontal &&
|
|
49
50
|
"cq-md:flex cq-md:min-w-0 cq-md:flex-1 cq-md:flex-col cq-md:gap-y-2",
|
|
50
51
|
// Blocked and upcoming recede; the step you can act
|
|
51
52
|
// on is the one that keeps full contrast. Opacity
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stepper.js","sourceRoot":"","sources":["../../src/Stepper/Stepper.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Stepper.js","sourceRoot":"","sources":["../../src/Stepper/Stepper.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAsC,CAAA;AAgErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,EACtB,SAAS,EACT,YAAY,GAAG,CAAC,EAChB,KAAK,EACL,WAAW,GAAG,UAAU,EACxB,KAAK,GACQ,EAAE,EAAE;IACjB,MAAM,OAAO,GAAG,IAAI,YAAY,EAAU,CAAA;IAC1C,MAAM,YAAY,GAAG,WAAW,KAAK,YAAY,CAAA;IAEjD,OAAO,CAaL,cAAK,SAAS,EAAE,WAAW,CAAC,YAAY,EAAE,SAAS,CAAC,YAClD,2BACc,KAAK,EACjB,SAAS,EAAE,WAAW,CACpB,mCAAmC;YACnC,yDAAyD;YACzD,mDAAmD;YACnD,qDAAqD;YACrD,oDAAoD;YACpD,0CAA0C;YAC1C,YAAY,IAAI,4BAA4B,CAC7C,YAEA,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAA;gBACxC,MAAM,MAAM,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;gBAEzC,OAAO,CAoBL,cACQ,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC,GAAG,EACpC,SAAS,EAAE,WAAW,CACpB,qFAAqF,EACrF,YAAY;wBACV,oEAAoE;oBACtE,oDAAoD;oBACpD,kDAAkD;oBAClD,8CAA8C;oBAC9C,sDAAsD;oBACtD,6CAA6C;oBAC7C,CAAC,MAAM,KAAK,SAAS;wBACnB,MAAM,KAAK,UAAU,CAAC;wBACtB,YAAY,CACf,aAGD,eACE,SAAS,EAAE,WAAW,CACpB,iGAAiG,EACjG,mBAAmB,CAAC,MAAM,CAAC,EAC3B,YAAY,IAAI,mBAAmB,CACpC,YAEA,IAAI,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,GACpB,EAIN,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACf,oCAEE,SAAS,EAAE,WAAW,CACpB,qEAAqE;4BACrE,iDAAiD;4BACjD,8CAA8C;4BAC9C,2BAA2B;4BAC3B,MAAM,KAAK,MAAM;gCACf,CAAC,CAAC,yBAAyB;gCAC3B,CAAC,CAAC,kBAAkB,EACtB,YAAY;gCACV,gGAAgG,CACnG,GACD,CACH,EAED,eACE,SAAS,EAAE,WAAW,CACpB,4CAA4C,EAC5C,YAAY,IAAI,mBAAmB,CACpC,aAED,MAAC,OAAO,IAAC,SAAS,EAAC,gFAAgF,aAChG,IAAI,CAAC,KAAK,EAOX,KAAC,cAAc,cACZ,YAAY,CAAC,MAAM,CAAC,GACN,IACT,EAET,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACjC,YAAG,SAAS,EAAC,4CAA4C,YACtD,IAAI,CAAC,WAAW,GACf,CACL,EAEA,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC7B,cAAK,SAAS,EAAC,MAAM,YAAE,IAAI,CAAC,OAAO,GAAO,CAC3C,IACG,KA3DD,IAAI,CAAC,GAAG,CA4DV,CACN,CAAA;YACH,CAAC,CAAC,GACC,GACD,CACP,CAAA;AACH,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,mBAAmB,GAA+B;IACtD,OAAO,EACL,oFAAoF;IACtF,OAAO,EACL,iFAAiF;IACnF,IAAI,EAAE,mFAAmF;IACzF,QAAQ,EACN,+DAA+D;CAClE,CAAA;AAED,MAAM,YAAY,GAA+B;IAC/C,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,aAAa;CACxB,CAAA"}
|
package/package.json
CHANGED
|
@@ -82,6 +82,23 @@ test("the last step draws no connector", async () => {
|
|
|
82
82
|
await expect(connectors[2]).toBeNull()
|
|
83
83
|
})
|
|
84
84
|
|
|
85
|
+
test("each step carries its key into the DOM, so a re-order can animate", async () => {
|
|
86
|
+
const { canvas } = await mountStory(Default)
|
|
87
|
+
|
|
88
|
+
// React's `key` never reaches the markup. Without this attribute
|
|
89
|
+
// a caller who re-orders `steps` has no way to say which `<li>`
|
|
90
|
+
// is which, and `useFlipList` — which matches on exactly this
|
|
91
|
+
// attribute — would fall back to pairing items by POSITION,
|
|
92
|
+
// measure a delta of zero for every one, and animate nothing.
|
|
93
|
+
await expect(
|
|
94
|
+
canvas
|
|
95
|
+
.getAllByRole("listitem")
|
|
96
|
+
.map((item: HTMLElement) =>
|
|
97
|
+
item.getAttribute("data-flip-key"),
|
|
98
|
+
),
|
|
99
|
+
).toEqual(["rip", "tag", "file"])
|
|
100
|
+
})
|
|
101
|
+
|
|
85
102
|
test("advancing moves which step is current", async () => {
|
|
86
103
|
const { canvas } = await mountStory(Interactive)
|
|
87
104
|
|
package/src/Stepper/Stepper.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FLIP_KEY_ATTRIBUTE } from "@charcuterie/logic"
|
|
1
2
|
import type { ReactNode } from "react"
|
|
2
3
|
|
|
3
4
|
import { toClassName } from "../toClassName.ts"
|
|
@@ -138,7 +139,27 @@ export const Stepper = ({
|
|
|
138
139
|
const isLast = index === steps.length - 1
|
|
139
140
|
|
|
140
141
|
return (
|
|
142
|
+
/*
|
|
143
|
+
* `data-flip-key` carries `step.key` into the DOM so a
|
|
144
|
+
* re-ordered stepper can animate with `useFlipList`
|
|
145
|
+
* from `@charcuterie/logic`, which matches items on
|
|
146
|
+
* exactly this attribute.
|
|
147
|
+
*
|
|
148
|
+
* Emitted always, not behind a prop. React's `key` is
|
|
149
|
+
* invisible to the DOM, so without this a caller who
|
|
150
|
+
* re-orders `steps` has no way to say which `<li>` is
|
|
151
|
+
* which — and FLIP matched by POSITION pairs every item
|
|
152
|
+
* with whatever now sits where it used to be, measures
|
|
153
|
+
* a delta of zero, and animates nothing. Docket's phase
|
|
154
|
+
* list is the case: the owner reported *"when I move
|
|
155
|
+
* them up and down, there's no animation"*, and the
|
|
156
|
+
* step's identity never reached the markup.
|
|
157
|
+
*
|
|
158
|
+
* A data attribute on a list item costs nothing when
|
|
159
|
+
* nobody reads it, which is why it is not opt-in.
|
|
160
|
+
*/
|
|
141
161
|
<li
|
|
162
|
+
{...{ [FLIP_KEY_ATTRIBUTE]: step.key }}
|
|
142
163
|
className={toClassName(
|
|
143
164
|
"relative grid grid-cols-[auto_minmax(0,1fr)] grid-rows-[auto_minmax(0,1fr)] gap-x-3",
|
|
144
165
|
isHorizontal &&
|