@jsenv/navi 0.29.96 → 0.29.97
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/jsenv_navi.js +258 -44
- package/dist/jsenv_navi.js.map +13 -6
- package/docs/control_object.md +20 -1
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -24717,6 +24717,16 @@ const useUIGroupStateController = (
|
|
|
24717
24717
|
// between them, from here on.
|
|
24718
24718
|
controller.stateGivenFromAbove = false;
|
|
24719
24719
|
if (resolvedDistributeChildStates) {
|
|
24720
|
+
if (compareTwoJsValues(groupUIState, controller.uiState)) {
|
|
24721
|
+
// The aggregate answered what the group already holds, which is
|
|
24722
|
+
// how such a group says "not yet, ask me again". Some gestures
|
|
24723
|
+
// cannot avoid an in-between — two people swapping seats means one
|
|
24724
|
+
// leaves before the other arrives — and the aggregate is where
|
|
24725
|
+
// that half-state is recognised. Placing the children from it
|
|
24726
|
+
// would undo the half of the gesture that has already landed, and
|
|
24727
|
+
// publishing it would hand a half-answer to the row above.
|
|
24728
|
+
return;
|
|
24729
|
+
}
|
|
24720
24730
|
// A group answering for all its children at once holds ONE answer
|
|
24721
24731
|
// its children are views OF, rather than a value that IS what they
|
|
24722
24732
|
// said: a list saying who plays and four seats saying who sits
|
|
@@ -75271,19 +75281,42 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
75271
75281
|
* — read off the vnodes (toChildArray, so a .map() or a fragment is fine; a
|
|
75272
75282
|
* component of your own wrapping an Item is not seen). The Item renders its
|
|
75273
75283
|
* label; everything positional is this component's business.
|
|
75284
|
+
*
|
|
75285
|
+
* `slideContainer` connects the list to a <SlideContainer> by id, both ways:
|
|
75286
|
+
* pressing a step travels there (--navi-go-to-slide), and the position is
|
|
75287
|
+
* READ off the container rather than said by a prop — including mid-travel:
|
|
75288
|
+
* the container paints --slide-travel-progress on this element (it is a
|
|
75289
|
+
* follower, same mechanism as <Nav slideContainer>), so the halo rides the
|
|
75290
|
+
* drag under the finger, in CSS alone. The path then follows the position
|
|
75291
|
+
* too, clamped between `reached` (never retracts) and `reachable` (never
|
|
75292
|
+
* ahead of the answers): dragging towards a step whose way is earned fills
|
|
75293
|
+
* the line under the finger, dragging past the answers does not.
|
|
75274
75294
|
*/
|
|
75275
75295
|
const css$2 = /* css */`
|
|
75276
75296
|
.navi_step_list {
|
|
75277
|
-
/* The knobs
|
|
75278
|
-
|
|
75297
|
+
/* The knobs: accent is the path, muted is what the path has not
|
|
75298
|
+
reached, on-accent writes on filled dots, and --step-list-path-line
|
|
75279
75299
|
exists apart from the accent for a dark band where the walked line
|
|
75280
|
-
reads better plain white.
|
|
75281
|
-
|
|
75282
|
-
|
|
75283
|
-
|
|
75284
|
-
|
|
75285
|
-
--step-list-
|
|
75286
|
-
--step-list-
|
|
75300
|
+
reads better plain white. Said from OUTSIDE (any ancestor — a dark
|
|
75301
|
+
band, a themed app) on the plain names; resolved here through an
|
|
75302
|
+
indirection (--x-…, the way Button does), because a default written
|
|
75303
|
+
on the plain name on this very element would beat anything an
|
|
75304
|
+
ancestor says. */
|
|
75305
|
+
--x-step-list-accent: var(--step-list-accent, #4f8ef7);
|
|
75306
|
+
--x-step-list-on-accent: var(--step-list-on-accent, white);
|
|
75307
|
+
--x-step-list-muted: var(--step-list-muted, light-dark(#8a93a8, #8b99b8));
|
|
75308
|
+
--x-step-list-line: var(
|
|
75309
|
+
--step-list-line,
|
|
75310
|
+
light-dark(#c9d0dd, rgba(255, 255, 255, 0.35))
|
|
75311
|
+
);
|
|
75312
|
+
--x-step-list-current-color: var(
|
|
75313
|
+
--step-list-current-color,
|
|
75314
|
+
light-dark(#1c2433, white)
|
|
75315
|
+
);
|
|
75316
|
+
--x-step-list-path-line: var(
|
|
75317
|
+
--step-list-path-line,
|
|
75318
|
+
var(--x-step-list-accent)
|
|
75319
|
+
);
|
|
75287
75320
|
|
|
75288
75321
|
position: relative;
|
|
75289
75322
|
display: block;
|
|
@@ -75297,19 +75330,29 @@ const css$2 = /* css */`
|
|
|
75297
75330
|
}
|
|
75298
75331
|
/* The road not walked yet. */
|
|
75299
75332
|
.navi_step_list_rail line {
|
|
75300
|
-
stroke: var(--step-list-line);
|
|
75333
|
+
stroke: var(--x-step-list-line);
|
|
75301
75334
|
stroke-width: 2;
|
|
75302
75335
|
stroke-dasharray: 4 5;
|
|
75303
75336
|
}
|
|
75304
75337
|
.navi_step_list_rail circle {
|
|
75305
75338
|
fill: none;
|
|
75306
|
-
stroke: var(--step-list-muted);
|
|
75339
|
+
stroke: var(--x-step-list-muted);
|
|
75307
75340
|
stroke-width: 1.5;
|
|
75308
75341
|
}
|
|
75309
75342
|
.navi_step_list_rail text {
|
|
75310
75343
|
font-weight: 600;
|
|
75311
75344
|
font-size: 12px;
|
|
75312
|
-
fill: var(--step-list-muted);
|
|
75345
|
+
fill: var(--x-step-list-muted);
|
|
75346
|
+
}
|
|
75347
|
+
/* The current dot says so in the drawing itself, not only by its halo: on
|
|
75348
|
+
a dark band a muted number under a faint ring reads as nothing. Said in
|
|
75349
|
+
the base layer only (see renderRail) — a current dot the path has
|
|
75350
|
+
covered keeps the filled colors. */
|
|
75351
|
+
.navi_step_list_rail g[data-current] circle {
|
|
75352
|
+
stroke: var(--x-step-list-current-color);
|
|
75353
|
+
}
|
|
75354
|
+
.navi_step_list_rail g[data-current] text {
|
|
75355
|
+
fill: var(--x-step-list-current-color);
|
|
75313
75356
|
}
|
|
75314
75357
|
/* The path: same drawing, filled, revealed up to the step it has come to.
|
|
75315
75358
|
The clip is set inline (a width in px); transitioning it is what makes
|
|
@@ -75318,15 +75361,15 @@ const css$2 = /* css */`
|
|
|
75318
75361
|
transition: clip-path 300ms ease;
|
|
75319
75362
|
}
|
|
75320
75363
|
.navi_step_list_rail_filled line {
|
|
75321
|
-
stroke: var(--step-list-path-line);
|
|
75364
|
+
stroke: var(--x-step-list-path-line);
|
|
75322
75365
|
stroke-dasharray: none;
|
|
75323
75366
|
}
|
|
75324
75367
|
.navi_step_list_rail_filled circle {
|
|
75325
|
-
fill: var(--step-list-accent);
|
|
75326
|
-
stroke: var(--step-list-accent);
|
|
75368
|
+
fill: var(--x-step-list-accent);
|
|
75369
|
+
stroke: var(--x-step-list-accent);
|
|
75327
75370
|
}
|
|
75328
75371
|
.navi_step_list_rail_filled text {
|
|
75329
|
-
fill: var(--step-list-on-accent);
|
|
75372
|
+
fill: var(--x-step-list-on-accent);
|
|
75330
75373
|
}
|
|
75331
75374
|
/* The position: a halo around the dot being looked at. It slides from dot
|
|
75332
75375
|
to dot (transform, transitioned) — the g moves, the circle inside is
|
|
@@ -75336,9 +75379,53 @@ const css$2 = /* css */`
|
|
|
75336
75379
|
}
|
|
75337
75380
|
.navi_step_list_marker circle {
|
|
75338
75381
|
fill: none;
|
|
75339
|
-
stroke: color-mix(in srgb, var(--step-list-accent) 65%, transparent);
|
|
75382
|
+
stroke: color-mix(in srgb, var(--x-step-list-accent) 65%, transparent);
|
|
75340
75383
|
stroke-width: 1.5;
|
|
75341
75384
|
}
|
|
75385
|
+
|
|
75386
|
+
/* Connected to slides: the movement is not this component's anymore. The
|
|
75387
|
+
container paints --slide-travel-progress here (this element follows it,
|
|
75388
|
+
see data-slide-container-follows) — an asked-for travel animates it, a
|
|
75389
|
+
finger drags it — and everything below is a calc() of that number, so
|
|
75390
|
+
the halo and the path move per frame in CSS alone. The transitions are
|
|
75391
|
+
off: they would chase a finger that is already the pace.
|
|
75392
|
+
Position, in dots-x px: where the picture is right now. */
|
|
75393
|
+
.navi_step_list[data-slide-container-follows] {
|
|
75394
|
+
--step-list-position: calc(
|
|
75395
|
+
var(--step-list-pos-x, 0) + var(--slide-travel-progress) *
|
|
75396
|
+
var(--step-list-pos-dx, 0)
|
|
75397
|
+
);
|
|
75398
|
+
}
|
|
75399
|
+
.navi_step_list[data-slide-container-follows] .navi_step_list_marker {
|
|
75400
|
+
transform: translateX(calc(var(--step-list-position) * 1px));
|
|
75401
|
+
transition: none;
|
|
75402
|
+
}
|
|
75403
|
+
/* The path follows the position, clamped: never back below what was
|
|
75404
|
+
earned (--step-list-reached-x), never ahead of what the answers allow
|
|
75405
|
+
(--step-list-reachable-x). The +14 covers the dot it stands on (radius
|
|
75406
|
+
plus stroke). */
|
|
75407
|
+
.navi_step_list[data-slide-container-follows] .navi_step_list_rail_filled {
|
|
75408
|
+
clip-path: inset(
|
|
75409
|
+
0
|
|
75410
|
+
calc(
|
|
75411
|
+
(
|
|
75412
|
+
var(--step-list-w, 0) -
|
|
75413
|
+
(
|
|
75414
|
+
clamp(
|
|
75415
|
+
var(--step-list-reached-x, -9999),
|
|
75416
|
+
var(--step-list-position),
|
|
75417
|
+
var(--step-list-reachable-x, -9999)
|
|
75418
|
+
) +
|
|
75419
|
+
14
|
|
75420
|
+
)
|
|
75421
|
+
) *
|
|
75422
|
+
1px
|
|
75423
|
+
)
|
|
75424
|
+
0 0
|
|
75425
|
+
);
|
|
75426
|
+
transition: none;
|
|
75427
|
+
}
|
|
75428
|
+
|
|
75342
75429
|
/* One press target per step, covering the dot AND the label under it. The
|
|
75343
75430
|
feedback is NOT the whole surface: a rectangle would say the whole band
|
|
75344
75431
|
is a button, when the affordance is the dot — so hover and focus land on
|
|
@@ -75352,9 +75439,9 @@ const css$2 = /* css */`
|
|
|
75352
75439
|
box-sizing: border-box;
|
|
75353
75440
|
height: 100%;
|
|
75354
75441
|
}
|
|
75355
|
-
/* Doubled selector: the
|
|
75356
|
-
|
|
75357
|
-
what makes these values the ones read. */
|
|
75442
|
+
/* Doubled selector: the button's own state formulas (a readonly color
|
|
75443
|
+
mixed at the variant level) are declared in navi's stylesheet, injected
|
|
75444
|
+
after this one — specificity is what makes these values the ones read. */
|
|
75358
75445
|
.navi_step_list .navi_step_list_step {
|
|
75359
75446
|
position: relative;
|
|
75360
75447
|
display: block;
|
|
@@ -75363,11 +75450,13 @@ const css$2 = /* css */`
|
|
|
75363
75450
|
padding: 0;
|
|
75364
75451
|
font-size: 12px;
|
|
75365
75452
|
outline: none;
|
|
75366
|
-
--button-color: var(--step-list-muted);
|
|
75367
|
-
--button-color-readonly: var(--step-list-muted);
|
|
75368
|
-
|
|
75369
|
-
|
|
75370
|
-
|
|
75453
|
+
--button-color: var(--x-step-list-muted);
|
|
75454
|
+
--button-color-readonly: var(--x-step-list-muted);
|
|
75455
|
+
/* The button's own focus ring, silenced: it would outline the whole
|
|
75456
|
+
press surface, and the ring this list draws is the one around the dot
|
|
75457
|
+
(see the ::before rules below) — two rings read as a mistake. Width
|
|
75458
|
+
rather than style, because the ::before sets its own style in full. */
|
|
75459
|
+
--button-outline-width: 0px;
|
|
75371
75460
|
}
|
|
75372
75461
|
/* Centered on the dot: same vertical middle as the rail (top 0, height 34,
|
|
75373
75462
|
cy 17). */
|
|
@@ -75383,11 +75472,11 @@ const css$2 = /* css */`
|
|
|
75383
75472
|
}
|
|
75384
75473
|
.navi_step_list_step:hover::before,
|
|
75385
75474
|
.navi_step_list_step[data-hover]::before {
|
|
75386
|
-
background: color-mix(in srgb, var(--step-list-accent) 15%, transparent);
|
|
75475
|
+
background: color-mix(in srgb, var(--x-step-list-accent) 15%, transparent);
|
|
75387
75476
|
}
|
|
75388
75477
|
.navi_step_list .navi_step_list_step:hover,
|
|
75389
75478
|
.navi_step_list .navi_step_list_step[data-hover] {
|
|
75390
|
-
--button-color: var(--step-list-current-color);
|
|
75479
|
+
--button-color: var(--x-step-list-current-color);
|
|
75391
75480
|
}
|
|
75392
75481
|
.navi_step_list_step:focus-visible::before,
|
|
75393
75482
|
.navi_step_list_step[data-focus-visible]::before {
|
|
@@ -75405,8 +75494,8 @@ const css$2 = /* css */`
|
|
|
75405
75494
|
}
|
|
75406
75495
|
.navi_step_list .navi_step_list_step[data-current] {
|
|
75407
75496
|
font-weight: 600;
|
|
75408
|
-
--button-color: var(--step-list-current-color);
|
|
75409
|
-
--button-color-readonly: var(--step-list-current-color);
|
|
75497
|
+
--button-color: var(--x-step-list-current-color);
|
|
75498
|
+
--button-color-readonly: var(--x-step-list-current-color);
|
|
75410
75499
|
}
|
|
75411
75500
|
`;
|
|
75412
75501
|
const RAIL_H = 34;
|
|
@@ -75422,22 +75511,48 @@ const LINE_GAP = 5;
|
|
|
75422
75511
|
* @type {import("ignore:preact").FunctionComponent<{
|
|
75423
75512
|
* current?: string,
|
|
75424
75513
|
* reached?: string,
|
|
75425
|
-
*
|
|
75514
|
+
* reachable?: string,
|
|
75515
|
+
* slideContainer?: string,
|
|
75516
|
+
* travelByClick?: boolean,
|
|
75517
|
+
* travelByKeyboard?: boolean,
|
|
75426
75518
|
* [key: string]: any,
|
|
75427
75519
|
* }>}
|
|
75428
75520
|
* @param {string} [current] - the step being looked at: its dot gets the
|
|
75429
75521
|
* halo, its label the emphasis. Omit for "nowhere" — a confirmation
|
|
75430
|
-
* screen after the walk, say.
|
|
75522
|
+
* screen after the walk, say. With `slideContainer` the position is read
|
|
75523
|
+
* off the container instead, and this prop is ignored.
|
|
75431
75524
|
* @param {string} [reached] - the step the path has come to: the line is
|
|
75432
75525
|
* solid and the dots filled up to it, dashed past it. Omit for a path
|
|
75433
75526
|
* that has not started.
|
|
75434
|
-
* @param {
|
|
75435
|
-
*
|
|
75527
|
+
* @param {string} [reachable] - how far the path MAY go (with
|
|
75528
|
+
* `slideContainer` only): between `reached` and this step the path
|
|
75529
|
+
* follows the position — a drag towards a step whose way is earned fills
|
|
75530
|
+
* the line under the finger. Defaults to `reached`: the path then never
|
|
75531
|
+
* moves with the position at all.
|
|
75532
|
+
* @param {string} [slideContainer] - id of a <SlideContainer> these steps
|
|
75533
|
+
* are the slides of. Pressing a step travels there
|
|
75534
|
+
* (--navi-go-to-slide), the halo follows the container — drags included —
|
|
75535
|
+
* and this element becomes a follower of the container
|
|
75536
|
+
* (data-slide-container-follows), which is also what keeps the arrow keys
|
|
75537
|
+
* working from here.
|
|
75538
|
+
* @param {boolean} [travelByClick=true] - whether pressing a step goes
|
|
75539
|
+
* there. Off, the steps are read-only — shown, not offered. To DO
|
|
75540
|
+
* something on a press, say `onClick` on the Item itself: like every other
|
|
75541
|
+
* prop an Item carries, it lands on that step's button.
|
|
75542
|
+
* @param {boolean} [travelByKeyboard=true] - whether the arrow keys walk
|
|
75543
|
+
* from one step to the other (the focus moves, Enter presses). Only when
|
|
75544
|
+
* the list stands alone: connected to slides the arrows belong to the
|
|
75545
|
+
* CONTAINER — this element is a follower, so a press here already walks
|
|
75546
|
+
* the slides, and the container's own `travelByKeyboard` is the one that
|
|
75547
|
+
* says so. One owner per mode, or one arrow would do both.
|
|
75436
75548
|
*/
|
|
75437
75549
|
const StepList = ({
|
|
75438
75550
|
current,
|
|
75439
75551
|
reached,
|
|
75440
|
-
|
|
75552
|
+
reachable,
|
|
75553
|
+
slideContainer,
|
|
75554
|
+
travelByClick = true,
|
|
75555
|
+
travelByKeyboard = true,
|
|
75441
75556
|
children,
|
|
75442
75557
|
...rest
|
|
75443
75558
|
}) => {
|
|
@@ -75460,6 +75575,15 @@ const StepList = ({
|
|
|
75460
75575
|
};
|
|
75461
75576
|
}, []);
|
|
75462
75577
|
|
|
75578
|
+
// The arrows walk the steps — standing alone only: connected, this element
|
|
75579
|
+
// follows the container, whose own keydown listener already walks the
|
|
75580
|
+
// slides from here (and whose travelByKeyboard says whether to). A focus
|
|
75581
|
+
// group on top of that would make one arrow do both.
|
|
75582
|
+
useFocusGroup(rootRef, {
|
|
75583
|
+
enabled: Boolean(travelByKeyboard) && !slideContainer,
|
|
75584
|
+
direction: "x"
|
|
75585
|
+
});
|
|
75586
|
+
|
|
75463
75587
|
// The steps, read off the children: each <StepList.Item> vnode says which
|
|
75464
75588
|
// step it is (value) and is rendered as the label under its dot.
|
|
75465
75589
|
const stepVNodes = toChildArray(children).filter(child => child && child.props);
|
|
@@ -75475,8 +75599,68 @@ const StepList = ({
|
|
|
75475
75599
|
}
|
|
75476
75600
|
}
|
|
75477
75601
|
const indexOf = value => stepVNodes.findIndex((vnode, index) => valueOf(vnode, index) === value);
|
|
75478
|
-
|
|
75602
|
+
|
|
75603
|
+
// Where the slides are, read off the container: which slide is current,
|
|
75604
|
+
// and — while a travel or a drag is playing — which one the picture leans
|
|
75605
|
+
// towards. The current area re-renders this component (the emphasized
|
|
75606
|
+
// label, the data-current dot); the in-between positions never do: they
|
|
75607
|
+
// are written as numbers on this element and interpolated by the CSS
|
|
75608
|
+
// above, at the pace of --slide-travel-progress.
|
|
75609
|
+
const [containerCurrent, setContainerCurrent] = useState(undefined);
|
|
75610
|
+
useLayoutEffect(() => {
|
|
75611
|
+
if (!slideContainer || dotXs.length === 0) {
|
|
75612
|
+
return undefined;
|
|
75613
|
+
}
|
|
75614
|
+
const containerElement = document.getElementById(slideContainer);
|
|
75615
|
+
if (!containerElement) {
|
|
75616
|
+
console.warn(`<StepList slideContainer="${slideContainer}"> but no element with that id found`);
|
|
75617
|
+
return undefined;
|
|
75618
|
+
}
|
|
75619
|
+
const rootElement = rootRef.current;
|
|
75620
|
+
const read = () => {
|
|
75621
|
+
const currentArea = containerElement.getAttribute("data-slide-current");
|
|
75622
|
+
const towardArea = containerElement.getAttribute("data-slide-travel-toward");
|
|
75623
|
+
setContainerCurrent(currentArea ?? undefined);
|
|
75624
|
+
const currentIdx = currentArea === null ? -1 : indexOf(currentArea);
|
|
75625
|
+
if (currentIdx === -1) {
|
|
75626
|
+
// A slide no step names (a confirmation screen): the halo is not
|
|
75627
|
+
// rendered, and the last position is left standing for the path.
|
|
75628
|
+
return;
|
|
75629
|
+
}
|
|
75630
|
+
const x = dotXs[currentIdx];
|
|
75631
|
+
let dx = 0;
|
|
75632
|
+
if (towardArea && towardArea !== currentArea) {
|
|
75633
|
+
const towardIdx = indexOf(towardArea);
|
|
75634
|
+
if (towardIdx !== -1 && towardIdx !== currentIdx) {
|
|
75635
|
+
// The container counts +1 when the picture leans on a slide BEFORE
|
|
75636
|
+
// the current one, -1 after: the delta is signed the same way, so
|
|
75637
|
+
// progress × delta lands exactly on the other dot.
|
|
75638
|
+
const sign = towardIdx > currentIdx ? -1 : 1;
|
|
75639
|
+
dx = (dotXs[towardIdx] - x) * sign;
|
|
75640
|
+
}
|
|
75641
|
+
}
|
|
75642
|
+
rootElement.style.setProperty("--step-list-pos-x", x);
|
|
75643
|
+
rootElement.style.setProperty("--step-list-pos-dx", dx);
|
|
75644
|
+
};
|
|
75645
|
+
read();
|
|
75646
|
+
const observer = new MutationObserver(read);
|
|
75647
|
+
observer.observe(containerElement, {
|
|
75648
|
+
attributes: true,
|
|
75649
|
+
attributeFilter: ["data-slide-current", "data-slide-travel-toward"]
|
|
75650
|
+
});
|
|
75651
|
+
return () => {
|
|
75652
|
+
observer.disconnect();
|
|
75653
|
+
};
|
|
75654
|
+
// width: the dots move when the room does, and the written positions are
|
|
75655
|
+
// pixels of those dots.
|
|
75656
|
+
}, [slideContainer, width, stepCount]);
|
|
75657
|
+
const resolvedCurrent = slideContainer ? containerCurrent : current;
|
|
75658
|
+
const currentIndex = resolvedCurrent === undefined ? -1 : indexOf(resolvedCurrent);
|
|
75479
75659
|
const reachedIndex = reached === undefined ? -1 : indexOf(reached);
|
|
75660
|
+
let reachableIndex = reachable === undefined ? -1 : indexOf(reachable);
|
|
75661
|
+
if (reachableIndex < reachedIndex) {
|
|
75662
|
+
reachableIndex = reachedIndex;
|
|
75663
|
+
}
|
|
75480
75664
|
// Covers the reached dot entirely (radius plus stroke), and nothing when
|
|
75481
75665
|
// the path has not started.
|
|
75482
75666
|
const fillX = reachedIndex === -1 ? 0 : dotXs[reachedIndex] + DOT_R + 3;
|
|
@@ -75484,7 +75668,7 @@ const StepList = ({
|
|
|
75484
75668
|
const slotWidth = dotXs.length > 1 ? dotXs[1] - dotXs[0] : width;
|
|
75485
75669
|
const renderRail = filled => jsx("svg", {
|
|
75486
75670
|
className: filled ? "navi_step_list_rail navi_step_list_rail_filled" : "navi_step_list_rail",
|
|
75487
|
-
style: filled ? {
|
|
75671
|
+
style: filled && !slideContainer ? {
|
|
75488
75672
|
clipPath: `inset(0 ${width - fillX}px 0 0)`
|
|
75489
75673
|
} : undefined,
|
|
75490
75674
|
width: width,
|
|
@@ -75492,6 +75676,9 @@ const StepList = ({
|
|
|
75492
75676
|
viewBox: `0 0 ${width} ${RAIL_H}`,
|
|
75493
75677
|
"aria-hidden": "true",
|
|
75494
75678
|
children: dotXs.map((x, index) => jsxs("g", {
|
|
75679
|
+
// Base layer only: a current dot the path covers keeps the filled
|
|
75680
|
+
// colors (see the css).
|
|
75681
|
+
"data-current": !filled && index === currentIndex ? "" : undefined,
|
|
75495
75682
|
children: [index > 0 ? jsx("line", {
|
|
75496
75683
|
x1: dotXs[index - 1] + DOT_R + LINE_GAP,
|
|
75497
75684
|
y1: cy,
|
|
@@ -75514,7 +75701,21 @@ const StepList = ({
|
|
|
75514
75701
|
...rest,
|
|
75515
75702
|
ref: rootRef,
|
|
75516
75703
|
baseClassName: "navi_step_list",
|
|
75517
|
-
"data-step-list": ""
|
|
75704
|
+
"data-step-list": ""
|
|
75705
|
+
// A follower of the container: the travel's progress is painted here
|
|
75706
|
+
// for the CSS to draw with, and the arrow keys keep walking the slides
|
|
75707
|
+
// from this element.
|
|
75708
|
+
,
|
|
75709
|
+
|
|
75710
|
+
"data-slide-container-follows": slideContainer,
|
|
75711
|
+
style: {
|
|
75712
|
+
...rest.style,
|
|
75713
|
+
...(slideContainer ? {
|
|
75714
|
+
"--step-list-w": width,
|
|
75715
|
+
"--step-list-reached-x": reachedIndex === -1 ? -9999 : dotXs[reachedIndex],
|
|
75716
|
+
"--step-list-reachable-x": reachableIndex === -1 ? -9999 : dotXs[reachableIndex]
|
|
75717
|
+
} : undefined)
|
|
75718
|
+
},
|
|
75518
75719
|
children: width > 0 && stepCount > 0 ? jsxs(Fragment$1, {
|
|
75519
75720
|
children: [renderRail(false), renderRail(true), currentIndex !== -1 && dotXs[currentIndex] !== undefined ? jsx("svg", {
|
|
75520
75721
|
className: "navi_step_list_rail",
|
|
@@ -75523,8 +75724,12 @@ const StepList = ({
|
|
|
75523
75724
|
viewBox: `0 0 ${width} ${RAIL_H}`,
|
|
75524
75725
|
"aria-hidden": "true",
|
|
75525
75726
|
children: jsx("g", {
|
|
75526
|
-
className: "navi_step_list_marker"
|
|
75527
|
-
|
|
75727
|
+
className: "navi_step_list_marker"
|
|
75728
|
+
// Connected to slides, the position comes from the CSS calc
|
|
75729
|
+
// above — an inline transform would override it.
|
|
75730
|
+
,
|
|
75731
|
+
|
|
75732
|
+
style: slideContainer ? undefined : {
|
|
75528
75733
|
transform: `translateX(${dotXs[currentIndex]}px)`
|
|
75529
75734
|
},
|
|
75530
75735
|
children: jsx("circle", {
|
|
@@ -75559,14 +75764,23 @@ const StepList = ({
|
|
|
75559
75764
|
},
|
|
75560
75765
|
children: jsx(Button, {
|
|
75561
75766
|
...itemRest,
|
|
75562
|
-
|
|
75767
|
+
// bare, not discrete: what is drawn IS the dot and its
|
|
75768
|
+
// label — the hover wash a discrete button paints over its
|
|
75769
|
+
// whole surface is exactly what must not appear here (the
|
|
75770
|
+
// feedback is the circle over the dot, see the css).
|
|
75771
|
+
variant: "bare",
|
|
75563
75772
|
className: "navi_step_list_step",
|
|
75564
75773
|
"aria-current": index === currentIndex ? "step" : undefined,
|
|
75565
75774
|
"data-current": index === currentIndex ? "" : undefined,
|
|
75566
|
-
readOnly: !
|
|
75567
|
-
|
|
75568
|
-
|
|
75569
|
-
|
|
75775
|
+
readOnly: !travelByClick
|
|
75776
|
+
// Towards the slides when connected, by name: the command
|
|
75777
|
+
// reaches the container wherever this list sits on the
|
|
75778
|
+
// page. What else a press should do is the Item's own
|
|
75779
|
+
// onClick, which arrived through itemRest.
|
|
75780
|
+
,
|
|
75781
|
+
|
|
75782
|
+
command: slideContainer && travelByClick ? `--navi-go-to-slide:${value}` : undefined,
|
|
75783
|
+
commandFor: slideContainer,
|
|
75570
75784
|
children: jsx("span", {
|
|
75571
75785
|
className: "navi_step_list_label",
|
|
75572
75786
|
children: stepVNode
|