@endfield-ui/react 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -326,7 +326,7 @@ function Alert({ tone = "info", title, action, onClose, open = true, onExited, c
326
326
  ref: mergeRefs(rootRef, ref),
327
327
  "data-tone": tone,
328
328
  inert: leaving,
329
- className: cn("flex items-start gap-3 border border-l-4 border-line bg-surface-raised py-3 pr-3 pl-3 text-sm text-ink", toneBar[tone], leaving && ["pointer-events-none overflow-hidden", "transition-[height,padding,margin,border-width,opacity] duration-(--duration-fast) ease-standard"], className),
329
+ className: cn("flex items-start gap-3 border-l-4 bg-surface-raised py-3 pr-3 pl-3 text-sm text-ink", toneBar[tone], leaving && ["pointer-events-none overflow-hidden", "transition-[height,padding,margin,border-width,opacity] duration-(--duration-fast) ease-standard"], className),
330
330
  children: [
331
331
  graphic !== null && /* @__PURE__ */ jsx("span", {
332
332
  "aria-hidden": "true",
@@ -1974,6 +1974,10 @@ const MenuVariantContext = createContext("plain");
1974
1974
  /**
1975
1975
  * 面板:直角、1px 线、环境阴影;顶部一条半宽的行动色细条,展开时从 0 伸到一半宽。
1976
1976
  *
1977
+ * 细条上挂一个朝下的小三角,和它是同一个伪元素裁出来的:条高 3px,三角露出 8×4px,
1978
+ * 中心距条的左端 32px(实机风格弹窗分隔条的一半大)。它是条上的记号,不指向触发处——
1979
+ * 面板翻到上面、在侧边时照旧在顶上、朝下。三角探进第一行 2px,所以压在各行的底色之上
1980
+ *
1977
1981
  * 进场:淡入(200ms),同时从触发处那一侧挪过来 4px(300ms,和细条同一拍)。
1978
1982
  * 退场只淡出——位移只写在起点上。两个时长、两条缓动按属性一一对应
1979
1983
  */
@@ -1982,7 +1986,8 @@ const menuPanel = [
1982
1986
  "origin-(--transform-origin) transition-[opacity,translate] duration-[var(--duration-fast),var(--duration-base)] ease-[var(--ease-standard),var(--ease-exit)]",
1983
1987
  "data-ending-style:opacity-0 data-starting-style:opacity-0",
1984
1988
  enterFromSide,
1985
- "before:pointer-events-none before:absolute before:-top-px before:-left-px before:h-[3px] before:w-1/2 before:origin-left before:bg-action before:content-['']",
1989
+ "before:pointer-events-none before:absolute before:-top-px before:-left-px before:z-1 before:h-[7px] before:w-1/2 before:origin-left before:bg-action before:content-['']",
1990
+ "before:[clip-path:polygon(0_0,100%_0,100%_3px,36px_3px,32px_100%,28px_3px,0_3px)]",
1986
1991
  "before:transition-transform before:duration-(--duration-base) before:ease-exit data-starting-style:before:scale-x-0",
1987
1992
  "forced-colors:before:hidden"
1988
1993
  ].join(" ");
@@ -2157,8 +2162,21 @@ const fill$1 = {
2157
2162
  sunken: "bg-surface-sunken",
2158
2163
  outline: "bg-surface"
2159
2164
  };
2165
+ const lineFrame = {
2166
+ sunken: "before:pointer-events-none before:absolute before:inset-x-0 before:-bottom-[2px] before:h-[2px] before:origin-left before:scale-x-0 before:bg-ink before:content-[''] forced-colors:before:bg-[Highlight]",
2167
+ outline: "before:pointer-events-none before:absolute before:-inset-px before:border before:border-ink before:[clip-path:inset(0_100%_0_0)] before:content-['']"
2168
+ };
2169
+ const lineOpen = {
2170
+ sunken: "focus-within:before:scale-x-100 has-data-popup-open:before:scale-x-100",
2171
+ outline: "focus-within:before:[clip-path:inset(0)] has-data-popup-open:before:[clip-path:inset(0)]"
2172
+ };
2173
+ const lineMotion = "before:transition-[scale,clip-path] before:duration-(--duration-fast) before:ease-standard focus-within:before:duration-(--duration-base) focus-within:before:ease-exit has-data-popup-open:before:duration-(--duration-base) has-data-popup-open:before:ease-exit";
2174
+ /** 聚焦的墨线,接在带 `relative` 的外框上用 */
2175
+ function controlLine(variant = "sunken") {
2176
+ return cn(lineFrame[variant], lineOpen[variant], lineMotion);
2177
+ }
2160
2178
  function controlBox({ variant = "sunken", invalid, disabled, readOnly }) {
2161
- return cn("flex w-full min-w-0 text-ink", frame[variant], "transition-colors duration-(--duration-fast) ease-standard", focusRingWithin, readOnly ? "border-transparent bg-transparent" : fill$1[variant], readOnly && !disabled && !invalid && "forced-colors:border-[Canvas]", disabled ? "cursor-not-allowed border-line text-ink-disabled" : invalid ? "border-danger" : !readOnly && "border-line-strong hover:not-focus-within:border-ink-secondary focus-within:border-ink");
2179
+ return cn("relative flex w-full min-w-0 text-ink", frame[variant], "transition-colors duration-(--duration-fast) ease-standard", focusRingWithin, readOnly ? "border-transparent bg-transparent" : fill$1[variant], readOnly && !disabled && !invalid && "forced-colors:border-[Canvas]", disabled ? "cursor-not-allowed border-line text-ink-disabled" : invalid ? "border-danger" : !readOnly && "border-line-strong hover:not-focus-within:border-ink-secondary", !disabled && !invalid && !readOnly && controlLine(variant));
2162
2180
  }
2163
2181
  /**
2164
2182
  * 框里真正的 `<input>` / `<textarea>`:没有自己的底和边,焦点环画在外框上。
@@ -2848,7 +2866,7 @@ function DateField({ display, placeholder, fields, variant, size, invalid, disab
2848
2866
  invalid,
2849
2867
  disabled,
2850
2868
  readOnly: false
2851
- }), !disabled && !invalid && "has-data-popup-open:border-ink", controlSize$1[size], className),
2869
+ }), controlSize$1[size], className),
2852
2870
  children: [/* @__PURE__ */ jsxs(Popover$1.Trigger, {
2853
2871
  ref,
2854
2872
  id,
@@ -3950,7 +3968,7 @@ function FileUpload({ value, defaultValue, onValueChange, multiple = false, acce
3950
3968
  } catch {}
3951
3969
  }, [files, revision]);
3952
3970
  const pendingFocus = useRef(null);
3953
- useEffect(() => {
3971
+ useLayoutEffect(() => {
3954
3972
  const index = pendingFocus.current;
3955
3973
  if (index === null) return;
3956
3974
  pendingFocus.current = null;
@@ -5481,17 +5499,14 @@ function Navigator({ items, index, defaultIndex = 0, onIndexChange, loop = false
5481
5499
  //#endregion
5482
5500
  //#region src/components/otp-input/OtpInput.tsx
5483
5501
  const slotSize = {
5484
- sm: "h-8 w-8 text-base",
5485
- md: "h-10 w-10 text-lg",
5486
- lg: "h-14 w-14 text-2xl"
5487
- };
5488
- const slotFrame = {
5489
- sunken: "border-b-2",
5490
- outline: "border"
5502
+ sm: "h-8 w-8",
5503
+ md: "h-10 w-10",
5504
+ lg: "h-14 w-14"
5491
5505
  };
5492
- const slotFill = {
5493
- sunken: "bg-surface-sunken",
5494
- outline: "bg-surface"
5506
+ const slotText = {
5507
+ sm: "text-base",
5508
+ md: "text-lg",
5509
+ lg: "text-2xl"
5495
5510
  };
5496
5511
  const gapClass = {
5497
5512
  sm: "gap-1.5",
@@ -5520,7 +5535,7 @@ function OtpInput({ length = 6, value, defaultValue, onValueChange, onComplete,
5520
5535
  const labelId = useId();
5521
5536
  const ownLabel = ariaLabelledBy ?? (ariaLabel ? labelId : void 0);
5522
5537
  const groupLabel = ownLabel ?? fieldContext?.labelId;
5523
- const slotClass = cn("min-w-0 shrink text-center font-tech font-medium tabular-nums text-transparent caret-ink", "transition-colors duration-(--duration-fast) ease-standard", disabled ? "data-filled:text-ink-disabled" : "data-filled:text-ink", focusRing, slotSize[size], slotFrame[variant], readOnly ? "border-transparent bg-transparent" : slotFill[variant], readOnly && !disabled && !invalid && "forced-colors:border-[Canvas]", disabled ? "cursor-not-allowed border-line" : invalid ? "border-danger" : !readOnly && "border-line-strong hover:not-focus:border-ink-secondary focus:border-ink");
5538
+ const inputClass = cn(controlElement, "h-full w-full text-center font-tech font-medium tabular-nums caret-ink text-transparent", "transition-colors duration-(--duration-fast) ease-standard", disabled ? "data-filled:text-ink-disabled" : "data-filled:text-ink", slotText[size]);
5524
5539
  const group = groupSize !== void 0 && groupSize > 0 ? groupSize : 0;
5525
5540
  return /* @__PURE__ */ jsxs(OTPField.Root, {
5526
5541
  ...props,
@@ -5553,15 +5568,23 @@ function OtpInput({ length = 6, value, defaultValue, onValueChange, onComplete,
5553
5568
  "aria-hidden": "true",
5554
5569
  "data-separator": "",
5555
5570
  className: "h-0.5 w-2 shrink-0 bg-line-strong forced-colors:bg-[CanvasText]"
5556
- }), /* @__PURE__ */ jsx(OTPField.Input, {
5557
- ...index === 0 ? {
5558
- "aria-labelledby": ownLabel,
5559
- "aria-describedby": describedBy
5560
- } : { "aria-label": slotLabel(index + 1, length) },
5561
- "aria-invalid": invalid || void 0,
5562
- autoFocus: autoFocus && index === 0,
5563
- autoCapitalize: uppercase ? "characters" : "none",
5564
- className: slotClass
5571
+ }), /* @__PURE__ */ jsx("span", {
5572
+ className: cn(controlBox({
5573
+ variant,
5574
+ invalid,
5575
+ disabled,
5576
+ readOnly
5577
+ }), "shrink items-center justify-center", slotSize[size]),
5578
+ children: /* @__PURE__ */ jsx(OTPField.Input, {
5579
+ ...index === 0 ? {
5580
+ "aria-labelledby": ownLabel,
5581
+ "aria-describedby": describedBy
5582
+ } : { "aria-label": slotLabel(index + 1, length) },
5583
+ "aria-invalid": invalid || void 0,
5584
+ autoFocus: autoFocus && index === 0,
5585
+ autoCapitalize: uppercase ? "characters" : "none",
5586
+ className: inputClass
5587
+ })
5565
5588
  })] }, index))]
5566
5589
  });
5567
5590
  }
@@ -6758,7 +6781,7 @@ function SegmentedControl({ value, defaultValue, onValueChange, name, size = "md
6758
6781
  ref: mergeRefs(trackRef, ref),
6759
6782
  "data-variant": variant,
6760
6783
  "data-size": size,
6761
- className: cn("inline-grid max-w-full auto-cols-fr grid-flow-col p-0.5 text-ink", "transition-colors duration-(--duration-fast) ease-standard", indicator, indicatorBox, "after:bg-surface-inverse has-[[data-selected][data-disabled]]:after:bg-disabled", "forced-colors:after:bg-[Highlight] forced-colors:has-[[data-selected][data-disabled]]:after:bg-[GrayText]", track[variant], controlSize$1[size], disabled ? "border-line" : invalid ? "border-danger" : "border-line-strong focus-within:border-ink", className)
6784
+ className: cn("inline-grid max-w-full auto-cols-fr grid-flow-col p-0.5 text-ink", "transition-colors duration-(--duration-fast) ease-standard", indicator, indicatorBox, "after:bg-surface-inverse has-[[data-selected][data-disabled]]:after:bg-disabled", "forced-colors:after:bg-[Highlight] forced-colors:has-[[data-selected][data-disabled]]:after:bg-[GrayText]", track[variant], controlSize$1[size], disabled ? "border-line" : invalid ? "border-danger" : ["border-line-strong", controlLine(variant)], className)
6762
6785
  })
6763
6786
  });
6764
6787
  }
@@ -6857,7 +6880,7 @@ function Select(props) {
6857
6880
  invalid,
6858
6881
  disabled,
6859
6882
  readOnly: false
6860
- }), !disabled && !invalid && "has-data-popup-open:border-ink", controlSize$1[size], className),
6883
+ }), controlSize$1[size], className),
6861
6884
  children: /* @__PURE__ */ jsxs(Select$1.Trigger, {
6862
6885
  ref,
6863
6886
  id,
@@ -7401,6 +7424,206 @@ function Slider(props) {
7401
7424
  });
7402
7425
  }
7403
7426
  //#endregion
7427
+ //#region src/components/splash-screen/SplashScreen.tsx
7428
+ const progressTransition = "[transition:--ef-splash-progress_500ms_var(--ease-exit),--ef-splash-percent_500ms_var(--ease-exit)]";
7429
+ const leavingTransition = "[transition:--ef-splash-progress_500ms_var(--ease-exit),--ef-splash-percent_500ms_var(--ease-exit),opacity_1s_var(--ease-standard)_1.4s]";
7430
+ /** 三角标:三个朝下的小三角拼成一个倒三角 */
7431
+ function Mark() {
7432
+ return /* @__PURE__ */ jsx("svg", {
7433
+ viewBox: "0 0 24 21",
7434
+ "aria-hidden": "true",
7435
+ className: cn(decor, "absolute -top-[calc(var(--ef-splash-unit)*2.5)] -left-[calc(var(--ef-splash-unit)*3.375)] h-[calc(var(--ef-splash-unit)*1.3125)] w-[calc(var(--ef-splash-unit)*1.4375)] fill-action cq-portrait:hidden"),
7436
+ children: /* @__PURE__ */ jsx("path", { d: "M0 0h11.6L5.8 10zM12.4 0H24l-5.8 10zM6.2 11h11.6L12 21z" })
7437
+ });
7438
+ }
7439
+ /**
7440
+ * 代码画的那组微标:带框的加号、微文字、两排方点。至少占官网那张图的高度(4 个单位);
7441
+ * 微文字有字号的下限,多出来的往上长。竖排时上面紧挨着进度条的读数,放不下微文字
7442
+ */
7443
+ function DefaultDecor({ caption }) {
7444
+ return /* @__PURE__ */ jsxs("div", {
7445
+ className: "flex min-h-[calc(var(--ef-splash-unit)*4)] flex-col items-start justify-between gap-[calc(var(--ef-splash-unit)*0.5)] text-neutral-600",
7446
+ children: [
7447
+ /* @__PURE__ */ jsx("svg", {
7448
+ viewBox: "0 0 12 12",
7449
+ fill: "none",
7450
+ stroke: "currentColor",
7451
+ className: "size-[calc(var(--ef-splash-unit)*1.125)]",
7452
+ children: /* @__PURE__ */ jsx("path", { d: "M.5.5h11v11H.5zM6 3v6M3 6h6" })
7453
+ }),
7454
+ caption !== void 0 && /* @__PURE__ */ jsx("p", {
7455
+ className: "font-latin text-[length:max(calc(var(--ef-splash-unit)*0.75),var(--text-micro))] leading-[1.2] font-medium tracking-label whitespace-pre-line text-ink-tertiary uppercase cq-portrait:hidden",
7456
+ children: caption
7457
+ }),
7458
+ /* @__PURE__ */ jsx("svg", {
7459
+ viewBox: "0 0 62 18",
7460
+ fill: "currentColor",
7461
+ className: "h-[calc(var(--ef-splash-unit)*1.125)] w-[calc(var(--ef-splash-unit)*3.875)]",
7462
+ children: [0, 11].flatMap((y) => [
7463
+ 0,
7464
+ 11,
7465
+ 22,
7466
+ 33,
7467
+ 44,
7468
+ 55
7469
+ ].map((x) => /* @__PURE__ */ jsx("rect", {
7470
+ x,
7471
+ y,
7472
+ width: "7",
7473
+ height: "7"
7474
+ }, `${x}-${y}`)))
7475
+ })
7476
+ ]
7477
+ });
7478
+ }
7479
+ /**
7480
+ * 开屏页:照官网首次载入的那一页排的。近黑底,一根贴边的黄色进度条,读数跟着条的末端走;
7481
+ * 画面偏右是标志,下面一组微标、一条分隔线和一行标语。就绪后黄色铺满整屏,再整层淡出。
7482
+ *
7483
+ * 标志和底图是插槽,库里不带任何图。横竖看它所在的那一块自己的宽高比,不看视口;
7484
+ * 尺寸跟着那一块的宽度等比缩放,插槽里的东西可以用 `--ef-splash-unit` 跟着缩。
7485
+ *
7486
+ * 只要一块盖住整页的等待、不要这些排场,用 `Loader`。
7487
+ */
7488
+ function SplashScreen({ value, logo, tagline, caption, decor: decor$1, status = "LOADING", backdrop, open = true, fullscreen = true, label = "加载中", onReveal, onExited, onKeyDown, className, style, ref, ...props }) {
7489
+ const [revealed, setRevealed] = useState(false);
7490
+ if (open && revealed) setRevealed(false);
7491
+ const handlers = useRef({ onReveal });
7492
+ const fired = useRef(false);
7493
+ useLayoutEffect(() => {
7494
+ handlers.current = { onReveal };
7495
+ if (open) fired.current = false;
7496
+ });
7497
+ const reveal = useCallback(() => {
7498
+ if (fired.current) return;
7499
+ fired.current = true;
7500
+ setRevealed(true);
7501
+ handlers.current.onReveal?.();
7502
+ }, []);
7503
+ const { ref: rootRef, mounted } = usePresence(open, { onExited: () => {
7504
+ reveal();
7505
+ onExited?.();
7506
+ } });
7507
+ const leaving = mounted && !open;
7508
+ useLayoutEffect(() => {
7509
+ const node = rootRef.current;
7510
+ if (!leaving || !node) return;
7511
+ const onStart = (event) => {
7512
+ if (event.target === node && event.propertyName === "opacity") reveal();
7513
+ };
7514
+ node.addEventListener("transitionstart", onStart);
7515
+ return () => node.removeEventListener("transitionstart", onStart);
7516
+ }, [
7517
+ leaving,
7518
+ rootRef,
7519
+ reveal
7520
+ ]);
7521
+ const blocking = mounted && (open || !revealed);
7522
+ useEffect(() => {
7523
+ if (!fullscreen || !blocking) return;
7524
+ const page = document.documentElement;
7525
+ const previousOverflow = page.style.overflow;
7526
+ const previousFocus = document.activeElement;
7527
+ page.style.overflow = "hidden";
7528
+ rootRef.current?.focus({ preventScroll: true });
7529
+ return () => {
7530
+ page.style.overflow = previousOverflow;
7531
+ if (previousFocus instanceof HTMLElement && previousFocus.isConnected) previousFocus.focus({ preventScroll: true });
7532
+ };
7533
+ }, [
7534
+ fullscreen,
7535
+ blocking,
7536
+ rootRef
7537
+ ]);
7538
+ if (!mounted) return null;
7539
+ const handleKeyDown = (event) => {
7540
+ onKeyDown?.(event);
7541
+ if (fullscreen && blocking && event.key === "Tab") event.preventDefault();
7542
+ };
7543
+ const indeterminate = value === void 0;
7544
+ const shown = open ? indeterminate ? 0 : Math.min(Math.max(value, 0), 100) : 100;
7545
+ const travelling = indeterminate && open;
7546
+ return /* @__PURE__ */ jsxs("div", {
7547
+ tabIndex: -1,
7548
+ ...props,
7549
+ ref: mergeRefs(rootRef, ref),
7550
+ "data-theme": "dark",
7551
+ "data-state": open ? "open" : "closing",
7552
+ onKeyDown: handleKeyDown,
7553
+ style: {
7554
+ ...style,
7555
+ "--ef-splash-progress": shown,
7556
+ "--ef-splash-percent": Math.round(shown)
7557
+ },
7558
+ className: cn("overflow-hidden bg-surface text-ink outline-none [container-type:size]", fullscreen ? "fixed inset-0 z-(--z-loader)" : "absolute inset-0", leaving ? leavingTransition : progressTransition, leaving && "opacity-0", !blocking && "pointer-events-none", className),
7559
+ children: [/* @__PURE__ */ jsxs("div", {
7560
+ className: "absolute inset-0 [--_status:max(var(--ef-splash-unit),var(--text-xs))] [--_tagline:max(calc(var(--ef-splash-unit)*1.5),var(--text-xs))] [--ef-splash-unit:0.625cqw] cq-portrait:[--ef-splash-unit:1.4815cqw]",
7561
+ children: [
7562
+ backdrop !== void 0 && /* @__PURE__ */ jsx("div", {
7563
+ "aria-hidden": "true",
7564
+ className: cn("pointer-events-none select-none forced-colors:hidden print:hidden", "absolute inset-0 blur-[calc((100_-_var(--ef-splash-progress))*0.08px)] *:size-full [&>img]:object-cover"),
7565
+ children: backdrop
7566
+ }),
7567
+ logo !== void 0 && /* @__PURE__ */ jsx("div", {
7568
+ className: "absolute top-[min(calc(var(--ef-splash-unit)*27.625),calc(100%_-_var(--ef-splash-unit)*44.25))] left-[64.4531%] flex h-[calc(var(--ef-splash-unit)*16.75)] w-[calc(var(--ef-splash-unit)*16.5)] items-center justify-center cq-portrait:top-[min(calc(var(--ef-splash-unit)*50),41.667%)] cq-portrait:left-1/2 cq-portrait:h-[calc(var(--ef-splash-unit)*20.9375)] cq-portrait:w-[calc(var(--ef-splash-unit)*19.3125)] cq-portrait:-translate-1/2 [&>:is(img,svg)]:size-full [&>img]:object-contain",
7569
+ children: logo
7570
+ }),
7571
+ /* @__PURE__ */ jsxs("div", {
7572
+ className: "absolute top-[min(calc(var(--ef-splash-unit)*63.375),calc(100%_-_var(--ef-splash-unit)*8.5))] right-[calc(var(--ef-splash-unit)*2)] left-[64.4531%] cq-portrait:top-auto cq-portrait:right-[calc(var(--ef-splash-unit)*4.625)] cq-portrait:bottom-[calc(var(--ef-splash-unit)*5.75)] cq-portrait:left-[calc(var(--ef-splash-unit)*4.625)]",
7573
+ children: [
7574
+ decor$1 === void 0 && /* @__PURE__ */ jsx(Mark, {}),
7575
+ decor$1 !== null && /* @__PURE__ */ jsx("div", {
7576
+ "aria-hidden": "true",
7577
+ className: cn("pointer-events-none select-none forced-colors:hidden print:hidden", "absolute bottom-full left-0"),
7578
+ children: decor$1 === void 0 ? /* @__PURE__ */ jsx(DefaultDecor, { caption }) : decor$1
7579
+ }),
7580
+ /* @__PURE__ */ jsx("span", {
7581
+ "aria-hidden": "true",
7582
+ className: cn(decor, "mt-[calc(var(--ef-splash-unit)*1.25)] mb-[calc(var(--ef-splash-unit))] -ml-[calc(var(--ef-splash-unit)*21.625)] block h-0.5 w-[calc(var(--ef-splash-unit)*70)] bg-linear-to-r from-transparent via-neutral-0/10 to-transparent")
7583
+ }),
7584
+ tagline !== void 0 && /* @__PURE__ */ jsx("p", {
7585
+ className: "text-[length:var(--_tagline)] leading-[1.35] wrap-anywhere",
7586
+ children: tagline
7587
+ })
7588
+ ]
7589
+ }),
7590
+ /* @__PURE__ */ jsxs("div", {
7591
+ role: "progressbar",
7592
+ "aria-label": label,
7593
+ "aria-valuemin": 0,
7594
+ "aria-valuemax": 100,
7595
+ "aria-valuenow": travelling ? void 0 : shown,
7596
+ className: "absolute top-0 left-0 h-full w-[calc(var(--ef-splash-unit)*1.25)] forced-colors:outline forced-colors:-outline-offset-1 forced-colors:outline-[CanvasText] cq-portrait:top-auto cq-portrait:bottom-[calc(var(--ef-splash-unit)*17.75_+_(var(--_status)_-_var(--ef-splash-unit))*1.25_+_(var(--_tagline)_-_var(--ef-splash-unit)*1.5)*1.35)] cq-portrait:h-[calc(var(--ef-splash-unit)*2.5)] cq-portrait:w-[82.4074%]",
7597
+ children: [travelling ? /* @__PURE__ */ jsx("span", {
7598
+ className: "absolute inset-0 overflow-hidden",
7599
+ children: /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 top-0 h-2/5 animate-indeterminate-y bg-action motion-reduce:translate-y-3/4 forced-colors:bg-[Highlight] cq-portrait:inset-x-auto cq-portrait:inset-y-0 cq-portrait:left-0 cq-portrait:h-auto cq-portrait:w-2/5 cq-portrait:animate-indeterminate cq-portrait:motion-reduce:translate-x-3/4 cq-portrait:motion-reduce:translate-y-0" })
7600
+ }) : /* @__PURE__ */ jsx("span", { className: "absolute top-0 left-0 h-[calc(var(--ef-splash-progress)*1%)] w-full bg-action forced-colors:bg-[Highlight] cq-portrait:h-full cq-portrait:w-[calc(var(--ef-splash-progress)*1%)]" }), /* @__PURE__ */ jsxs("div", {
7601
+ "aria-hidden": "true",
7602
+ className: cn("absolute top-[calc(var(--ef-splash-progress)*1%)] left-[calc(var(--ef-splash-unit)*3.125)] h-0 whitespace-nowrap cq-portrait:top-auto cq-portrait:-bottom-[calc(var(--ef-splash-unit)*1.75)] cq-portrait:left-[calc(var(--ef-splash-progress)*1%)] cq-portrait:ml-[calc(var(--ef-splash-unit)*0.75)]", travelling && "translate-y-[calc(var(--ef-splash-unit)*3)] cq-portrait:translate-y-0"),
7603
+ children: [!indeterminate && /* @__PURE__ */ jsxs("p", {
7604
+ className: "absolute bottom-[calc(var(--ef-splash-unit)*1.625)] left-0 leading-none text-action",
7605
+ children: [
7606
+ /* @__PURE__ */ jsx("span", { className: "mb-[calc(var(--ef-splash-unit)*0.25)] block h-[calc(var(--ef-splash-unit)*1.875)] w-[calc(var(--ef-splash-unit)*0.5)] rounded-[calc(var(--ef-splash-unit)*0.25)] bg-action" }),
7607
+ /* @__PURE__ */ jsx("span", { className: "text-[length:calc(var(--ef-splash-unit)*4.375)] font-medium tabular-nums [counter-reset:ef-splash_var(--ef-splash-percent)] before:content-[counter(ef-splash)]" }),
7608
+ /* @__PURE__ */ jsx("span", {
7609
+ className: "text-[length:calc(var(--ef-splash-unit)*3.25)]",
7610
+ children: "%"
7611
+ })
7612
+ ]
7613
+ }), /* @__PURE__ */ jsxs("p", {
7614
+ className: "absolute -top-[calc(var(--ef-splash-unit)*0.5)] left-0 text-[length:var(--_status)] leading-[1.25] text-ink-tertiary",
7615
+ children: [/* @__PURE__ */ jsx("span", { className: "block h-[calc(var(--ef-splash-unit)*0.5)] w-[calc(var(--ef-splash-unit)*1.25)] border-x-[length:calc(var(--ef-splash-unit)*0.5)] border-current" }), status]
7616
+ })]
7617
+ })]
7618
+ })
7619
+ ]
7620
+ }), leaving && /* @__PURE__ */ jsx("span", {
7621
+ "aria-hidden": "true",
7622
+ className: "absolute inset-0 origin-left animate-fill bg-action [animation-delay:500ms] [animation-timing-function:cubic-bezier(1,0,0.7,1)] motion-reduce:hidden forced-colors:bg-[Highlight]"
7623
+ })]
7624
+ });
7625
+ }
7626
+ //#endregion
7404
7627
  //#region src/components/stat/Stat.tsx
7405
7628
  const valueSize = {
7406
7629
  md: "text-4xl",
@@ -8501,7 +8724,7 @@ function TagInput({ value, defaultValue, onValueChange, name, max, validate, sep
8501
8724
  return () => clearTimeout(timer);
8502
8725
  }, [flash]);
8503
8726
  const pendingFocus = useRef(null);
8504
- useEffect(() => {
8727
+ useLayoutEffect(() => {
8505
8728
  const target = pendingFocus.current;
8506
8729
  if (target === null) return;
8507
8730
  pendingFocus.current = null;
@@ -8991,7 +9214,7 @@ function ToastHost({ placement, label, closeLabel, children }) {
8991
9214
  return /* @__PURE__ */ jsx(Toast.Root, {
8992
9215
  toast,
8993
9216
  "data-theme": "dark",
8994
- className: cn("pointer-events-auto absolute left-1/2 w-max max-w-full", "border border-line bg-black/80 text-base leading-[1.4] text-white", "transition-[opacity,translate,transform] duration-[var(--duration-fast),var(--duration-base),var(--duration-fast)] ease-[var(--ease-standard),var(--ease-exit),var(--ease-standard)]", "data-ending-style:opacity-0 data-starting-style:opacity-0", "data-swiping:select-none", focusRingInset, placementClass[placement].root),
9217
+ className: cn("pointer-events-auto absolute left-1/2 w-max max-w-full", "bg-black/80 shadow-sm text-base leading-[1.4] text-white", "forced-colors:border forced-colors:border-[CanvasText]", "transition-[opacity,translate,transform] duration-[var(--duration-fast),var(--duration-base),var(--duration-fast)] ease-[var(--ease-standard),var(--ease-exit),var(--ease-standard)]", "data-ending-style:opacity-0 data-starting-style:opacity-0", "data-swiping:select-none", focusRingInset, placementClass[placement].root),
8995
9218
  children: /* @__PURE__ */ jsxs(Toast.Content, {
8996
9219
  className: cn("flex items-center gap-3 py-2.5 pl-5", toast.data?.dismissible ? "pr-2" : "pr-5"),
8997
9220
  children: [
@@ -9623,4 +9846,4 @@ function useTheme() {
9623
9846
  /** 三条横线:打开菜单 */
9624
9847
  const Menu = createIcon("Menu", /* @__PURE__ */ jsx("path", { d: "M3 6h18M3 12h18M3 18h18" }));
9625
9848
  //#endregion
9626
- export { Accordion, AccordionItem, Alert, ArrowCorner, ArrowLeft, ArrowRight, Avatar, AvatarSwitcher, AvatarSwitcherItem, BackToTop, Badge, BracketTitle, Breadcrumb, BreadcrumbItem, Button, ButtonGroup, Calendar, CalendarIcon, Carousel, CarouselSlide, Check, Checkbox, ChevronDown, ChevronLeft, ChevronRight, Close, Combobox, CompletionBanner, ContextMenu, CornerBrackets, Countdown, Crosshair, DashIndicator, DataRow, DataRowList, DatePicker, DateRangePicker, Dialog, DialogClose, Drawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, EmptyState, Field, FileItem, FileUpload, FilterChip, FlyoutBar, FlyoutBarItem, GhostText, Hatch, HazardStripe, HoverCard, IconButton, ImageViewer, ImageViewerItem, Input, ItemGrid, ItemSlot, Kbd, List, ListRow, Loader, Lock, Marquee, MediaCard, Menu, Minus, NavAction, NavMenu, NavMenuItem, Navigator, OtpInput, PageHeader, PageHeaderBack, Pagination, Panel, PanelBody, PanelHeader, PanelRow, PanelRows, PlayButton, PlayMark, Plus, Popover, PopoverClose, Progress, ProgressRing, Radio, RadioGroup, RecIndicator, RegistrationStrip, ResourceChip, RollingNumber, Schedule, ScheduleItem, ScheduleTrack, ScrollArea, ScrollHint, SectionTitle, Segment, SegmentedControl, Select, SelectGroup, SelectItem, SelectSeparator, SideRail, SideRailGroup, SideRailItem, SideRailSub, SideRailSubItem, Skeleton, Slider, Sparkline, Spinner, Stat, StatusDanger, StatusInfo, StatusSuccess, StatusWarning, Step, Stepper, Steps, Switch, Tab, TabList, TabPanel, Table, TableBody, TableCell, TableExpander, TableHead, TableHeaderCell, TableRow, Tabs, Tag, TagInput, TagPair, Term, Textarea, Texture, TickRing, Timeline, TimelineItem, ToastProvider, Toc, TocItem, Toolbar, ToolbarButton, ToolbarGroup, ToolbarSeparator, ToolbarToggle, ToolbarToggleGroup, Tooltip, TooltipProvider, TopBar, TriangleRight, Upload, Viewfinder, cn, createIcon, useControllableState, useFieldContext, useFieldControl, useInView, usePortalScope, useReducedMotion, useTheme, useToast };
9849
+ export { Accordion, AccordionItem, Alert, ArrowCorner, ArrowLeft, ArrowRight, Avatar, AvatarSwitcher, AvatarSwitcherItem, BackToTop, Badge, BracketTitle, Breadcrumb, BreadcrumbItem, Button, ButtonGroup, Calendar, CalendarIcon, Carousel, CarouselSlide, Check, Checkbox, ChevronDown, ChevronLeft, ChevronRight, Close, Combobox, CompletionBanner, ContextMenu, CornerBrackets, Countdown, Crosshair, DashIndicator, DataRow, DataRowList, DatePicker, DateRangePicker, Dialog, DialogClose, Drawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, EmptyState, Field, FileItem, FileUpload, FilterChip, FlyoutBar, FlyoutBarItem, GhostText, Hatch, HazardStripe, HoverCard, IconButton, ImageViewer, ImageViewerItem, Input, ItemGrid, ItemSlot, Kbd, List, ListRow, Loader, Lock, Marquee, MediaCard, Menu, Minus, NavAction, NavMenu, NavMenuItem, Navigator, OtpInput, PageHeader, PageHeaderBack, Pagination, Panel, PanelBody, PanelHeader, PanelRow, PanelRows, PlayButton, PlayMark, Plus, Popover, PopoverClose, Progress, ProgressRing, Radio, RadioGroup, RecIndicator, RegistrationStrip, ResourceChip, RollingNumber, Schedule, ScheduleItem, ScheduleTrack, ScrollArea, ScrollHint, SectionTitle, Segment, SegmentedControl, Select, SelectGroup, SelectItem, SelectSeparator, SideRail, SideRailGroup, SideRailItem, SideRailSub, SideRailSubItem, Skeleton, Slider, Sparkline, Spinner, SplashScreen, Stat, StatusDanger, StatusInfo, StatusSuccess, StatusWarning, Step, Stepper, Steps, Switch, Tab, TabList, TabPanel, Table, TableBody, TableCell, TableExpander, TableHead, TableHeaderCell, TableRow, Tabs, Tag, TagInput, TagPair, Term, Textarea, Texture, TickRing, Timeline, TimelineItem, ToastProvider, Toc, TocItem, Toolbar, ToolbarButton, ToolbarGroup, ToolbarSeparator, ToolbarToggle, ToolbarToggleGroup, Tooltip, TooltipProvider, TopBar, TriangleRight, Upload, Viewfinder, cn, createIcon, useControllableState, useFieldContext, useFieldControl, useInView, usePortalScope, useReducedMotion, useTheme, useToast };