@kjun-ui/native 0.13.0 → 0.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.
Files changed (32) hide show
  1. package/dist/index.cjs +1038 -875
  2. package/dist/index.js +907 -741
  3. package/dist/index.web.cjs +1051 -888
  4. package/dist/index.web.js +913 -747
  5. package/dist/styles.css +73 -1
  6. package/dist/types/packages/native/src/card.d.cts +9 -2
  7. package/dist/types/packages/native/src/card.d.ts +9 -2
  8. package/dist/types/packages/native/src/collapse.d.cts +3 -1
  9. package/dist/types/packages/native/src/collapse.d.ts +3 -1
  10. package/dist/types/packages/native/src/display-primitives.d.cts +2 -1
  11. package/dist/types/packages/native/src/display-primitives.d.ts +2 -1
  12. package/dist/types/packages/native/src/drawer.d.cts +3 -1
  13. package/dist/types/packages/native/src/drawer.d.ts +3 -1
  14. package/dist/types/packages/native/src/feedback.d.cts +5 -1
  15. package/dist/types/packages/native/src/feedback.d.ts +5 -1
  16. package/dist/types/packages/native/src/layout-primitives.d.cts +5 -3
  17. package/dist/types/packages/native/src/layout-primitives.d.ts +5 -3
  18. package/dist/types/packages/native/src/list.d.cts +17 -2
  19. package/dist/types/packages/native/src/list.d.ts +17 -2
  20. package/dist/types/packages/native/src/media.d.cts +4 -2
  21. package/dist/types/packages/native/src/media.d.ts +4 -2
  22. package/dist/types/packages/native/src/modal.d.cts +3 -1
  23. package/dist/types/packages/native/src/modal.d.ts +3 -1
  24. package/dist/types/packages/native/src/navigation.d.cts +7 -1
  25. package/dist/types/packages/native/src/navigation.d.ts +7 -1
  26. package/dist/types/shared/package-runtime/layout-primitives.d.cts +1 -1
  27. package/dist/types/shared/package-runtime/layout-primitives.d.ts +1 -1
  28. package/dist/types/shared/package-runtime/progress-circle.d.cts +11 -0
  29. package/dist/types/shared/package-runtime/progress-circle.d.ts +11 -0
  30. package/dist/types/shared/package-runtime/use-after-close.d.cts +6 -0
  31. package/dist/types/shared/package-runtime/use-after-close.d.ts +6 -0
  32. package/package.json +3 -3
package/dist/index.web.js CHANGED
@@ -1818,6 +1818,18 @@ function KjunFormLayout({
1818
1818
  ) });
1819
1819
  }
1820
1820
 
1821
+ // shared/package-runtime/use-after-close.ts
1822
+ import { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef6 } from "react";
1823
+ function useAfterClose(present, onAfterClose, enabled2 = true) {
1824
+ const was = useRef6(present), callback = useRef6(onAfterClose);
1825
+ callback.current = onAfterClose;
1826
+ useEffect4(() => {
1827
+ var _a;
1828
+ if (was.current && !present && enabled2) (_a = callback.current) == null ? void 0 : _a.call(callback);
1829
+ was.current = present;
1830
+ }, [present, enabled2]);
1831
+ }
1832
+
1821
1833
  // shared/package-runtime/content-presence.ts
1822
1834
  import { Fragment as Fragment2, isValidElement as isValidElement2 } from "react";
1823
1835
  function hasContent(node) {
@@ -1859,8 +1871,9 @@ import {
1859
1871
  import {
1860
1872
  createContext as createContext14,
1861
1873
  useContext as useContext9,
1862
- useEffect as useEffect4,
1863
- useId as useId3
1874
+ useEffect as useEffect5,
1875
+ useId as useId3,
1876
+ useRef as useRef7
1864
1877
  } from "react";
1865
1878
  import { Platform as Platform9, View as View7 } from "react-native";
1866
1879
 
@@ -1892,13 +1905,14 @@ var FeedbackOverlayContext = createContext14(
1892
1905
  null
1893
1906
  );
1894
1907
  function ScopedNativeModal({ children, visible, ...props }) {
1895
- var _a;
1896
1908
  const layers = useLayerState(), scope = useContext9(LayerScope);
1897
1909
  const entry = scope ? layers.entries.get(scope) : void 0;
1898
- const generation = (_a = entry == null ? void 0 : entry.order) != null ? _a : 0;
1910
+ const last = useRef7(0);
1911
+ if (entry) last.current = entry.order;
1912
+ const generation = last.current;
1899
1913
  const inactive = !!scope && !layers.isActive(scope);
1900
1914
  const host = useContext9(FeedbackOverlayContext), id = "kjun-" + useId3(), register = host == null ? void 0 : host.register;
1901
- useEffect4(
1915
+ useEffect5(
1902
1916
  () => visible && register ? register(id) : void 0,
1903
1917
  [visible, register, id, generation]
1904
1918
  );
@@ -2023,6 +2037,7 @@ function KjunModal({
2023
2037
  open,
2024
2038
  onOpenChange,
2025
2039
  onClose,
2040
+ onAfterClose,
2026
2041
  onCancel,
2027
2042
  onConfirm,
2028
2043
  title = "",
@@ -2070,10 +2085,15 @@ function KjunModal({
2070
2085
  const layer = useLayer(open, motion.present, "window", () => {
2071
2086
  if (closeOnEsc) close();
2072
2087
  });
2088
+ const iosDismiss = Platform10.OS === "ios";
2089
+ useAfterClose(motion.present, onAfterClose, !iosDismiss);
2073
2090
  return /* @__PURE__ */ jsx13(LayerScope.Provider, { value: layer.id, children: /* @__PURE__ */ jsx13(
2074
2091
  ScopedNativeModal,
2075
2092
  {
2076
2093
  visible: motion.present,
2094
+ onDismiss: iosDismiss ? () => {
2095
+ if (!open) onAfterClose == null ? void 0 : onAfterClose();
2096
+ } : void 0,
2077
2097
  transparent: true,
2078
2098
  animationType: "none",
2079
2099
  onRequestClose: () => {
@@ -2250,7 +2270,11 @@ function KjunCard({
2250
2270
  border = false,
2251
2271
  dividers = false,
2252
2272
  children,
2253
- style
2273
+ style,
2274
+ pressable = false,
2275
+ disabled = false,
2276
+ ariaLabel,
2277
+ onPress
2254
2278
  }) {
2255
2279
  const { colors } = useKjunStyles();
2256
2280
  const id = "kjun-" + useId4().replace(/[^a-z0-9]/gi, "");
@@ -2261,7 +2285,7 @@ function KjunCard({
2261
2285
  const hasHeading = hasContent(header) || hasContent(title) || hasContent(subtitle);
2262
2286
  const hasHeader = hasHeading || hasContent(headerActions);
2263
2287
  const hasBody = hasContent(children), hasFooter = hasContent(footer), hasMedia = hasContent(media);
2264
- return /* @__PURE__ */ jsxs6(View9, { style: [
2288
+ const base = [
2265
2289
  {
2266
2290
  minWidth: 0,
2267
2291
  borderRadius: corner,
@@ -2270,7 +2294,8 @@ function KjunCard({
2270
2294
  },
2271
2295
  Platform11.OS === "web" && surface === "glass" ? { backdropFilter: `blur(${tokens10.card.glassBlur}px)` } : {},
2272
2296
  style
2273
- ], children: [
2297
+ ];
2298
+ const parts = /* @__PURE__ */ jsxs6(Fragment4, { children: [
2274
2299
  paint.gradientEnd && /* @__PURE__ */ jsx14(View9, { pointerEvents: "none", style: { position: "absolute", inset: 0, borderRadius: corner, overflow: "hidden" }, children: /* @__PURE__ */ jsxs6(Svg2, { width: "100%", height: "100%", children: [
2275
2300
  /* @__PURE__ */ jsx14(Defs, { children: /* @__PURE__ */ jsxs6(LinearGradient, { id, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
2276
2301
  /* @__PURE__ */ jsx14(Stop, { offset: "0", stopColor: colors[paint.background] }),
@@ -2313,6 +2338,18 @@ function KjunCard({
2313
2338
  boxShadow: [{ offsetX: 0, offsetY: 0, blurRadius: 0, spreadDistance: tokens10.card.borderWidth, inset: true, color: borderColor }]
2314
2339
  } })
2315
2340
  ] });
2341
+ return pressable ? /* @__PURE__ */ jsx14(
2342
+ AccessiblePressable,
2343
+ {
2344
+ accessibilityRole: "button",
2345
+ accessibilityLabel: ariaLabel != null ? ariaLabel : title,
2346
+ accessibilityState: { disabled },
2347
+ disabled,
2348
+ onPress,
2349
+ style: ({ pressed }) => [base, pressed ? { transform: [{ scale: 0.99 }] } : null, disabled ? { opacity: tokens10.states.opacity.disabled } : null],
2350
+ children: parts
2351
+ }
2352
+ ) : /* @__PURE__ */ jsx14(View9, { style: base, children: parts });
2316
2353
  }
2317
2354
 
2318
2355
  // shared/package-runtime/alert-live.ts
@@ -2323,8 +2360,8 @@ function alertRole(tone, live) {
2323
2360
  }
2324
2361
 
2325
2362
  // packages/native/src/display-primitives.tsx
2326
- import { tokens as tokens11 } from "@kjun-ui/tokens";
2327
- import { useContext as useContext10, useEffect as useEffect5, useRef as useRef6, useState as useState10 } from "react";
2363
+ import { tokens as tokens12 } from "@kjun-ui/tokens";
2364
+ import { useContext as useContext10, useEffect as useEffect6, useRef as useRef8, useState as useState10 } from "react";
2328
2365
  import {
2329
2366
  Animated as Animated5,
2330
2367
  Easing as Easing3,
@@ -2333,6 +2370,25 @@ import {
2333
2370
  View as View10
2334
2371
  } from "react-native";
2335
2372
  import Svg3, { Circle as Circle2, Path as Path2 } from "react-native-svg";
2373
+
2374
+ // shared/package-runtime/progress-circle.ts
2375
+ import { tokens as tokens11 } from "@kjun-ui/tokens";
2376
+ function progressCircle(size, percentage) {
2377
+ const { size: diameter, stroke } = tokens11.extensions.progress.circle[size];
2378
+ const radius = (diameter - stroke) / 2, circumference = 2 * Math.PI * radius;
2379
+ return {
2380
+ diameter,
2381
+ stroke,
2382
+ radius,
2383
+ centre: diameter / 2,
2384
+ circumference,
2385
+ offset: circumference * (1 - percentage / 100),
2386
+ // Small circles are too narrow for the centre percentage; screen readers still get the value.
2387
+ showsPercentage: size !== "sm"
2388
+ };
2389
+ }
2390
+
2391
+ // packages/native/src/display-primitives.tsx
2336
2392
  import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
2337
2393
  var badgeLayoutKeys = /* @__PURE__ */ new Set([
2338
2394
  "alignSelf",
@@ -2372,10 +2428,10 @@ function BadgeView({
2372
2428
  dot = false,
2373
2429
  children,
2374
2430
  style,
2375
- dotSize = tokens11.extensions.badge.dotSize
2431
+ dotSize = tokens12.extensions.badge.dotSize
2376
2432
  }) {
2377
2433
  const { colors, domainColors } = useKjunStyles();
2378
- const { x, y } = tokens11.extensions.badge.padding[size];
2434
+ const { x, y } = tokens12.extensions.badge.padding[size];
2379
2435
  const type = typeStyle(size === "xl" ? "controlLarge" : size === "lg" ? "control" : "controlSmall");
2380
2436
  const neutral = variant === "default" || variant === "secondary";
2381
2437
  const financial = variant.startsWith("price-");
@@ -2393,10 +2449,10 @@ function BadgeView({
2393
2449
  maxWidth: "100%",
2394
2450
  minWidth: 0,
2395
2451
  flexShrink: 1,
2396
- gap: tokens11.extensions.badge.gap,
2452
+ gap: tokens12.extensions.badge.gap,
2397
2453
  paddingHorizontal: x,
2398
2454
  paddingVertical: y,
2399
- borderRadius: tokens11.extensions.badge.radius,
2455
+ borderRadius: tokens12.extensions.badge.radius,
2400
2456
  backgroundColor: background
2401
2457
  },
2402
2458
  inner
@@ -2434,7 +2490,7 @@ function KjunEmpty({
2434
2490
  const m = useKjunMessages();
2435
2491
  text != null ? text : text = m.noData;
2436
2492
  const { colors } = useKjunStyles();
2437
- const spec = tokens11.extensions.empty;
2493
+ const spec = tokens12.extensions.empty;
2438
2494
  const stateContent = useContext10(DataStateContentContext);
2439
2495
  return /* @__PURE__ */ jsxs7(
2440
2496
  View10,
@@ -2442,7 +2498,7 @@ function KjunEmpty({
2442
2498
  style: {
2443
2499
  alignItems: "center",
2444
2500
  justifyContent: "center",
2445
- paddingVertical: stateContent === "empty" ? 0 : tokens11.dimension.value32
2501
+ paddingVertical: stateContent === "empty" ? 0 : tokens12.dimension.value32
2446
2502
  },
2447
2503
  children: [
2448
2504
  !!icon && /* @__PURE__ */ jsx15(View10, { style: { marginBottom: spec.iconGap }, children: /* @__PURE__ */ jsx15(KjunIcon, { name: icon, size: spec.iconSize, color: colors.textSecondary }) }),
@@ -2469,13 +2525,13 @@ function KjunEmpty({
2469
2525
  }
2470
2526
  function KjunSpinner({ size = "md", text }) {
2471
2527
  const m = useKjunMessages();
2472
- const { colors } = useKjunStyles(), reduced = useReducedMotion(), rotation = useRef6(new Animated5.Value(0)).current;
2473
- useEffect5(() => {
2528
+ const { colors } = useKjunStyles(), reduced = useReducedMotion(), rotation = useRef8(new Animated5.Value(0)).current;
2529
+ useEffect6(() => {
2474
2530
  if (reduced) return;
2475
2531
  const loop = Animated5.loop(
2476
2532
  Animated5.timing(rotation, {
2477
2533
  toValue: 1,
2478
- duration: tokens11.motion.spin,
2534
+ duration: tokens12.motion.spin,
2479
2535
  easing: Easing3.linear,
2480
2536
  useNativeDriver: Platform12.OS !== "web"
2481
2537
  })
@@ -2486,8 +2542,8 @@ function KjunSpinner({ size = "md", text }) {
2486
2542
  rotation.setValue(0);
2487
2543
  };
2488
2544
  }, [reduced, rotation]);
2489
- const dimension = tokens11.extensions.spinner.sizes[size];
2490
- const stroke = tokens11.extensions.spinner.strokeWidths[size] * 24 / dimension;
2545
+ const dimension = tokens12.extensions.spinner.sizes[size];
2546
+ const stroke = tokens12.extensions.spinner.strokeWidths[size] * 24 / dimension;
2491
2547
  return /* @__PURE__ */ jsxs7(
2492
2548
  View10,
2493
2549
  {
@@ -2541,7 +2597,7 @@ function KjunSpinner({ size = "md", text }) {
2541
2597
  )
2542
2598
  }
2543
2599
  ),
2544
- !!text && /* @__PURE__ */ jsx15(KText, { style: { marginLeft: tokens11.dimension.value8, color: colors.textSecondary }, children: text })
2600
+ !!text && /* @__PURE__ */ jsx15(KText, { style: { marginLeft: tokens12.dimension.value8, color: colors.textSecondary }, children: text })
2545
2601
  ]
2546
2602
  }
2547
2603
  );
@@ -2562,8 +2618,8 @@ function KjunAlert({
2562
2618
  const [visible, setVisible] = useState10(true);
2563
2619
  if (!visible) return null;
2564
2620
  const tone = variant || (type === "error" ? "danger" : type), small = size === "sm";
2565
- const geometry2 = tokens11.extensions.alert;
2566
- const lineHeight = tokens11.typography[small ? "controlSmall" : "control"].lineHeightPx;
2621
+ const geometry2 = tokens12.extensions.alert;
2622
+ const lineHeight = tokens12.typography[small ? "controlSmall" : "control"].lineHeightPx;
2567
2623
  const titled = hasContent(title);
2568
2624
  const closeSize = small ? geometry2.sm.closeSize : geometry2.closeSize;
2569
2625
  const pick = (suffix) => tone === "primary" ? suffix === "Bg" ? colors.brandSubtleBg : suffix === "Light" ? colors.brandLight : colors.brand : colors[tone + suffix];
@@ -2574,11 +2630,11 @@ function KjunAlert({
2574
2630
  style: {
2575
2631
  flexDirection: "row",
2576
2632
  alignItems: "flex-start",
2577
- gap: tokens11.extensions.alert[small ? "sm" : "md"].gap,
2578
- borderWidth: tokens11.border.defaultWidth,
2579
- borderRadius: tokens11.extensions.alert.radius,
2580
- paddingVertical: tokens11.extensions.alert[small ? "sm" : "md"].paddingY,
2581
- paddingHorizontal: tokens11.extensions.alert[small ? "sm" : "md"].paddingX,
2633
+ gap: tokens12.extensions.alert[small ? "sm" : "md"].gap,
2634
+ borderWidth: tokens12.border.defaultWidth,
2635
+ borderRadius: tokens12.extensions.alert.radius,
2636
+ paddingVertical: tokens12.extensions.alert[small ? "sm" : "md"].paddingY,
2637
+ paddingHorizontal: tokens12.extensions.alert[small ? "sm" : "md"].paddingX,
2582
2638
  backgroundColor: pick("Bg"),
2583
2639
  borderColor: pick("Light")
2584
2640
  },
@@ -2593,7 +2649,7 @@ function KjunAlert({
2593
2649
  warning: "alert-triangle",
2594
2650
  danger: "alert-circle"
2595
2651
  }[tone],
2596
- size: tokens11.extensions.alert.iconSizes[small ? "sm" : "md"],
2652
+ size: tokens12.extensions.alert.iconSizes[small ? "sm" : "md"],
2597
2653
  color: pick("Accent")
2598
2654
  }
2599
2655
  ) }),
@@ -2610,7 +2666,7 @@ function KjunAlert({
2610
2666
  {
2611
2667
  accessibilityRole: "button",
2612
2668
  accessibilityLabel: m.close,
2613
- hitSlop: Math.max(0, (tokens11.native.minimumTouchTarget - closeSize) / 2),
2669
+ hitSlop: Math.max(0, (tokens12.native.minimumTouchTarget - closeSize) / 2),
2614
2670
  style: ({ pressed, hovered }) => ({
2615
2671
  width: closeSize,
2616
2672
  height: closeSize,
@@ -2648,11 +2704,58 @@ function KjunProgress({
2648
2704
  variant = "primary",
2649
2705
  showLabel = false,
2650
2706
  label,
2651
- subLabel
2707
+ subLabel,
2708
+ shape = "bar"
2652
2709
  }) {
2653
2710
  const m = useKjunMessages();
2654
- const { colors } = useKjunStyles();
2711
+ const { colors, numericFontFamily, fontFamily } = useKjunStyles();
2655
2712
  const percentage = Number.isFinite(value) && max > 0 ? Math.min(100, Math.max(0, Math.round(value / max * 100))) : 0;
2713
+ const name = typeof label === "string" ? label : m.progress, color = variant === "primary" ? colors.brand : colors[variant];
2714
+ const semantics = {
2715
+ accessibilityRole: "progressbar",
2716
+ accessibilityLabel: name,
2717
+ accessibilityValue: { min: 0, max: 100, now: percentage },
2718
+ "aria-valuemin": 0,
2719
+ "aria-valuemax": 100,
2720
+ "aria-valuenow": percentage
2721
+ };
2722
+ if (shape === "circle") {
2723
+ const c = progressCircle(size, percentage);
2724
+ return /* @__PURE__ */ jsxs7(View10, { style: { alignSelf: "flex-start", alignItems: "center" }, children: [
2725
+ /* @__PURE__ */ jsxs7(View10, { ...semantics, style: { width: c.diameter, height: c.diameter, alignItems: "center", justifyContent: "center" }, children: [
2726
+ /* @__PURE__ */ jsxs7(Svg3, { width: c.diameter, height: c.diameter, viewBox: `0 0 ${c.diameter} ${c.diameter}`, style: StyleSheet4.absoluteFill, children: [
2727
+ /* @__PURE__ */ jsx15(Circle2, { cx: c.centre, cy: c.centre, r: c.radius, stroke: colors.secondary, strokeWidth: c.stroke, fill: "none" }),
2728
+ percentage > 0 && /* @__PURE__ */ jsx15(
2729
+ Circle2,
2730
+ {
2731
+ cx: c.centre,
2732
+ cy: c.centre,
2733
+ r: c.radius,
2734
+ stroke: color,
2735
+ strokeWidth: c.stroke,
2736
+ fill: "none",
2737
+ strokeLinecap: "round",
2738
+ strokeDasharray: c.circumference,
2739
+ strokeDashoffset: c.offset,
2740
+ rotation: -90,
2741
+ origin: `${c.centre}, ${c.centre}`
2742
+ }
2743
+ )
2744
+ ] }),
2745
+ showLabel && c.showsPercentage && /* @__PURE__ */ jsxs7(KText, { style: {
2746
+ ...typeStyle(size === "lg" ? "numberMd" : "meta"),
2747
+ fontFamily: numericFontFamily || fontFamily,
2748
+ fontVariant: ["tabular-nums"],
2749
+ color: colors.text
2750
+ }, children: [
2751
+ percentage,
2752
+ "%"
2753
+ ] })
2754
+ ] }),
2755
+ content(label, { ...typeStyle("caption"), marginTop: tokens12.dimension.value8, color: colors.textSecondary, textAlign: "center" }),
2756
+ content(subLabel, { ...typeStyle("caption"), marginTop: tokens12.dimension.value4, color: colors.textTertiary, textAlign: "center" })
2757
+ ] });
2758
+ }
2656
2759
  return /* @__PURE__ */ jsxs7(View10, { children: [
2657
2760
  !!(label || showLabel) && /* @__PURE__ */ jsxs7(
2658
2761
  View10,
@@ -2660,7 +2763,7 @@ function KjunProgress({
2660
2763
  style: {
2661
2764
  flexDirection: "row",
2662
2765
  justifyContent: "space-between",
2663
- marginBottom: tokens11.dimension.value8
2766
+ marginBottom: tokens12.dimension.value8
2664
2767
  },
2665
2768
  children: [
2666
2769
  content(label, {
@@ -2686,13 +2789,11 @@ function KjunProgress({
2686
2789
  /* @__PURE__ */ jsx15(
2687
2790
  View10,
2688
2791
  {
2689
- accessibilityRole: "progressbar",
2690
- accessibilityLabel: typeof label === "string" ? label : m.progress,
2691
- accessibilityValue: { min: 0, max: 100, now: percentage },
2792
+ ...semantics,
2692
2793
  style: {
2693
- height: tokens11.extensions.progress.heights[size],
2794
+ height: tokens12.extensions.progress.heights[size],
2694
2795
  backgroundColor: colors.secondary,
2695
- borderRadius: tokens11.radius.radius9999,
2796
+ borderRadius: tokens12.radius.radius9999,
2696
2797
  overflow: "hidden"
2697
2798
  },
2698
2799
  children: /* @__PURE__ */ jsx15(
@@ -2701,8 +2802,8 @@ function KjunProgress({
2701
2802
  style: {
2702
2803
  width: `${percentage}%`,
2703
2804
  height: "100%",
2704
- borderRadius: tokens11.radius.radius9999,
2705
- backgroundColor: variant === "primary" ? colors.brand : colors[variant]
2805
+ borderRadius: tokens12.radius.radius9999,
2806
+ backgroundColor: color
2706
2807
  }
2707
2808
  }
2708
2809
  )
@@ -2710,15 +2811,15 @@ function KjunProgress({
2710
2811
  ),
2711
2812
  content(subLabel, {
2712
2813
  ...typeStyle("caption"),
2713
- marginTop: tokens11.dimension.value4,
2814
+ marginTop: tokens12.dimension.value4,
2714
2815
  color: colors.textTertiary
2715
2816
  })
2716
2817
  ] });
2717
2818
  }
2718
2819
 
2719
2820
  // packages/native/src/skeleton-base.tsx
2720
- import { tokens as tokens12 } from "@kjun-ui/tokens";
2721
- import { useEffect as useEffect6, useRef as useRef7 } from "react";
2821
+ import { tokens as tokens13 } from "@kjun-ui/tokens";
2822
+ import { useEffect as useEffect7, useRef as useRef9 } from "react";
2722
2823
  import {
2723
2824
  Animated as Animated6,
2724
2825
  View as View11
@@ -2733,19 +2834,19 @@ function KjunSkeleton({
2733
2834
  animated = true,
2734
2835
  rounded = true
2735
2836
  }) {
2736
- const { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef7(new Animated6.Value(1)).current;
2737
- useEffect6(() => {
2837
+ const { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef9(new Animated6.Value(1)).current;
2838
+ useEffect7(() => {
2738
2839
  if (!animated || reduced) return;
2739
2840
  const loop = Animated6.loop(
2740
2841
  Animated6.sequence([
2741
2842
  Animated6.timing(opacity, {
2742
2843
  toValue: 0.6,
2743
- duration: tokens12.motion.shimmer / 2,
2844
+ duration: tokens13.motion.shimmer / 2,
2744
2845
  useNativeDriver: false
2745
2846
  }),
2746
2847
  Animated6.timing(opacity, {
2747
2848
  toValue: 1,
2748
- duration: tokens12.motion.shimmer / 2,
2849
+ duration: tokens13.motion.shimmer / 2,
2749
2850
  useNativeDriver: false
2750
2851
  })
2751
2852
  ])
@@ -2764,18 +2865,18 @@ function KjunSkeleton({
2764
2865
  width: w,
2765
2866
  height: h,
2766
2867
  backgroundColor: shimmer,
2767
- borderRadius: tokens12.extensions.skeleton.lineRadius,
2868
+ borderRadius: tokens13.extensions.skeleton.lineRadius,
2768
2869
  ...extra
2769
2870
  }
2770
2871
  }
2771
2872
  );
2772
2873
  const count = (n) => Array.from({ length: Math.max(0, Math.floor(n)) }, (_, i) => i + 1);
2773
- const line = (w, key, h = tokens12.extensions.skeleton.lineHeights.md) => /* @__PURE__ */ jsx16(View11, { style: { marginBottom: key === rows ? 0 : tokens12.extensions.skeleton.gap }, children: block(w, h) }, key);
2874
+ const line = (w, key, h = tokens13.extensions.skeleton.lineHeights.md) => /* @__PURE__ */ jsx16(View11, { style: { marginBottom: key === rows ? 0 : tokens13.extensions.skeleton.gap }, children: block(w, h) }, key);
2774
2875
  const frame = {
2775
- padding: tokens12.extensions.skeleton.padding,
2776
- borderWidth: tokens12.border.defaultWidth,
2876
+ padding: tokens13.extensions.skeleton.padding,
2877
+ borderWidth: tokens13.border.defaultWidth,
2777
2878
  borderColor: colors.border,
2778
- borderRadius: tokens12.extensions.skeleton.radius,
2879
+ borderRadius: tokens13.extensions.skeleton.radius,
2779
2880
  backgroundColor: colors.background
2780
2881
  };
2781
2882
  return /* @__PURE__ */ jsxs8(
@@ -2791,7 +2892,7 @@ function KjunSkeleton({
2791
2892
  i
2792
2893
  )
2793
2894
  ),
2794
- type === "avatar" && block(width || tokens12.extensions.skeleton.avatarSize, height || tokens12.extensions.skeleton.avatarSize, { borderRadius: rounded ? tokens12.radius.radius9999 : tokens12.extensions.skeleton.blockRadius }),
2895
+ type === "avatar" && block(width || tokens13.extensions.skeleton.avatarSize, height || tokens13.extensions.skeleton.avatarSize, { borderRadius: rounded ? tokens13.radius.radius9999 : tokens13.extensions.skeleton.blockRadius }),
2795
2896
  type === "card" && /* @__PURE__ */ jsxs8(View11, { style: frame, children: [
2796
2897
  /* @__PURE__ */ jsxs8(
2797
2898
  View11,
@@ -2799,19 +2900,19 @@ function KjunSkeleton({
2799
2900
  style: {
2800
2901
  flexDirection: "row",
2801
2902
  alignItems: "center",
2802
- gap: tokens12.extensions.skeleton.gap,
2803
- marginBottom: tokens12.dimension.value16
2903
+ gap: tokens13.extensions.skeleton.gap,
2904
+ marginBottom: tokens13.dimension.value16
2804
2905
  },
2805
2906
  children: [
2806
- block(tokens12.extensions.skeleton.cardAvatarSize, tokens12.extensions.skeleton.cardAvatarSize, { borderRadius: tokens12.radius.radius9999 }),
2807
- /* @__PURE__ */ jsxs8(View11, { style: { flex: 1, gap: tokens12.dimension.value8 }, children: [
2907
+ block(tokens13.extensions.skeleton.cardAvatarSize, tokens13.extensions.skeleton.cardAvatarSize, { borderRadius: tokens13.radius.radius9999 }),
2908
+ /* @__PURE__ */ jsxs8(View11, { style: { flex: 1, gap: tokens13.dimension.value8 }, children: [
2808
2909
  block("60%"),
2809
- block("40%", tokens12.extensions.skeleton.lineHeights.sm)
2910
+ block("40%", tokens13.extensions.skeleton.lineHeights.sm)
2810
2911
  ] })
2811
2912
  ]
2812
2913
  }
2813
2914
  ),
2814
- /* @__PURE__ */ jsxs8(View11, { style: { gap: tokens12.dimension.value10 }, children: [
2915
+ /* @__PURE__ */ jsxs8(View11, { style: { gap: tokens13.dimension.value10 }, children: [
2815
2916
  block("100%"),
2816
2917
  block("80%"),
2817
2918
  block("60%")
@@ -2821,9 +2922,9 @@ function KjunSkeleton({
2821
2922
  View11,
2822
2923
  {
2823
2924
  style: {
2824
- borderWidth: tokens12.border.defaultWidth,
2925
+ borderWidth: tokens13.border.defaultWidth,
2825
2926
  borderColor: colors.border,
2826
- borderRadius: tokens12.extensions.skeleton.blockRadius,
2927
+ borderRadius: tokens13.extensions.skeleton.blockRadius,
2827
2928
  overflow: "hidden"
2828
2929
  },
2829
2930
  children: [0, ...count(rows)].map((row) => /* @__PURE__ */ jsx16(
@@ -2832,7 +2933,7 @@ function KjunSkeleton({
2832
2933
  style: {
2833
2934
  flexDirection: "row",
2834
2935
  backgroundColor: row === 0 ? colors.secondary : void 0,
2835
- borderBottomWidth: row === rows ? 0 : tokens12.border.defaultWidth,
2936
+ borderBottomWidth: row === rows ? 0 : tokens13.border.defaultWidth,
2836
2937
  borderBottomColor: colors.border
2837
2938
  },
2838
2939
  children: count(columns).map((col) => /* @__PURE__ */ jsx16(
@@ -2840,8 +2941,8 @@ function KjunSkeleton({
2840
2941
  {
2841
2942
  style: {
2842
2943
  flex: 1,
2843
- paddingVertical: tokens12.dimension.value12,
2844
- paddingHorizontal: tokens12.dimension.value16
2944
+ paddingVertical: tokens13.dimension.value12,
2945
+ paddingHorizontal: tokens13.dimension.value16
2845
2946
  },
2846
2947
  children: block(
2847
2948
  row === 0 ? "70%" : [
@@ -2851,7 +2952,7 @@ function KjunSkeleton({
2851
2952
  "75%",
2852
2953
  "85%"
2853
2954
  ][(row + col) % 5],
2854
- tokens12.extensions.skeleton.tableLineHeight
2955
+ tokens13.extensions.skeleton.tableLineHeight
2855
2956
  )
2856
2957
  },
2857
2958
  col
@@ -2873,16 +2974,16 @@ function KjunSkeleton({
2873
2974
  }
2874
2975
  ],
2875
2976
  children: [
2876
- /* @__PURE__ */ jsxs8(View11, { style: { flex: 1, gap: tokens12.dimension.value8 }, children: [
2877
- block("40%", tokens12.extensions.skeleton.lineHeights.sm),
2878
- block("60%", tokens12.extensions.skeleton.lineHeights.lg),
2879
- block("30%", tokens12.extensions.skeleton.lineHeights.sm)
2977
+ /* @__PURE__ */ jsxs8(View11, { style: { flex: 1, gap: tokens13.dimension.value8 }, children: [
2978
+ block("40%", tokens13.extensions.skeleton.lineHeights.sm),
2979
+ block("60%", tokens13.extensions.skeleton.lineHeights.lg),
2980
+ block("30%", tokens13.extensions.skeleton.lineHeights.sm)
2880
2981
  ] }),
2881
- block(tokens12.extensions.skeleton.statWidth, tokens12.extensions.skeleton.statHeight)
2982
+ block(tokens13.extensions.skeleton.statWidth, tokens13.extensions.skeleton.statHeight)
2882
2983
  ]
2883
2984
  }
2884
2985
  ),
2885
- type === "block" && block(width || "100%", height != null ? height : tokens12.extensions.skeleton.blockHeight, { borderRadius: tokens12.extensions.skeleton.blockRadius })
2986
+ type === "block" && block(width || "100%", height != null ? height : tokens13.extensions.skeleton.blockHeight, { borderRadius: tokens13.extensions.skeleton.blockRadius })
2886
2987
  ]
2887
2988
  }
2888
2989
  );
@@ -2891,7 +2992,7 @@ function KjunSkeleton({
2891
2992
  // packages/native/src/layout-primitives.tsx
2892
2993
  import { Children as Children2, Fragment as Fragment5, cloneElement as cloneElement2, isValidElement as isValidElement3 } from "react";
2893
2994
  import { View as View12 } from "react-native";
2894
- import { tokens as tokens13 } from "@kjun-ui/tokens";
2995
+ import { tokens as tokens14 } from "@kjun-ui/tokens";
2895
2996
 
2896
2997
  // shared/package-runtime/layout-primitives.ts
2897
2998
  var titleVariants = ["pageTitle", "sectionTitle", "cardTitle"];
@@ -2900,15 +3001,27 @@ var isNumericVariant = (variant) => numeric.test(variant);
2900
3001
 
2901
3002
  // packages/native/src/layout-primitives.tsx
2902
3003
  import { jsx as jsx17 } from "react/jsx-runtime";
2903
- var toneRole = { default: "text", secondary: "textSecondary", tertiary: "textTertiary", disabled: "textDisabled" };
3004
+ var toneRole = {
3005
+ default: "text",
3006
+ secondary: "textSecondary",
3007
+ tertiary: "textTertiary",
3008
+ disabled: "textDisabled",
3009
+ brand: "brand",
3010
+ danger: "danger",
3011
+ success: "success",
3012
+ warning: "warning",
3013
+ inverse: "onBrand"
3014
+ };
2904
3015
  var textAlign = { start: "left", center: "center", end: "right" };
2905
- function KjunText({ variant = "body", tone = "default", align, maxLines, style, children }) {
3016
+ function KjunText({ variant = "body", tone = "default", align, maxLines, style, children, ...rest }) {
3017
+ var _a;
2906
3018
  const { colors, fontFamily, numericFontFamily } = useKjunStyles();
2907
3019
  const lines = maxLines && maxLines > 0 ? Math.floor(maxLines) : void 0;
2908
3020
  return /* @__PURE__ */ jsx17(
2909
3021
  KText,
2910
3022
  {
2911
- accessibilityRole: titleVariants.includes(variant) ? "header" : void 0,
3023
+ ...rest,
3024
+ accessibilityRole: (_a = rest.accessibilityRole) != null ? _a : titleVariants.includes(variant) ? "header" : void 0,
2912
3025
  numberOfLines: lines,
2913
3026
  ellipsizeMode: lines ? "tail" : void 0,
2914
3027
  style: [
@@ -2928,56 +3041,61 @@ function flatten(children, path = "") {
2928
3041
  return isValidElement3(child) && child.type === Fragment5 ? flatten(child.props.children, `${key}.`) : [[key, child]];
2929
3042
  });
2930
3043
  }
2931
- function items(children) {
3044
+ function items(children, childAlign) {
2932
3045
  return flatten(children).map(([key, child]) => {
2933
3046
  if (typeof child === "string" || typeof child === "number") return /* @__PURE__ */ jsx17(KText, { children: child }, key);
2934
3047
  if (isValidElement3(child) && child.type === KjunFormGroup) {
2935
3048
  const group = child;
2936
3049
  return cloneElement2(group, { key, style: [{ marginBottom: 0 }, group.props.style] });
2937
3050
  }
3051
+ if (childAlign && isValidElement3(child) && (child.type === KjunButton || child.type === KjunBadge)) {
3052
+ const control = child;
3053
+ return cloneElement2(control, { key, style: [{ alignSelf: childAlign }, control.props.style] });
3054
+ }
2938
3055
  return isValidElement3(child) ? cloneElement2(child, { key }) : child;
2939
3056
  });
2940
3057
  }
3058
+ var followed = (align) => align && align !== "stretch" ? crossAxis[align] : void 0;
2941
3059
  var stackGap = {
2942
3060
  none: 0,
2943
- sm: tokens13.space.stack.sm,
2944
- md: tokens13.space.stack.md,
2945
- lg: tokens13.space.stack.lg,
2946
- "section-sm": tokens13.space.section.sm,
2947
- "section-md": tokens13.space.section.md,
2948
- "section-lg": tokens13.space.section.lg
3061
+ sm: tokens14.space.stack.sm,
3062
+ md: tokens14.space.stack.md,
3063
+ lg: tokens14.space.stack.lg,
3064
+ "section-sm": tokens14.space.section.sm,
3065
+ "section-md": tokens14.space.section.md,
3066
+ "section-lg": tokens14.space.section.lg
2949
3067
  };
2950
3068
  var inlineGap = {
2951
3069
  none: 0,
2952
- xs: tokens13.space.inline.xs,
2953
- sm: tokens13.space.inline.sm,
2954
- md: tokens13.space.inline.md,
2955
- lg: tokens13.space.inline.lg
3070
+ xs: tokens14.space.inline.xs,
3071
+ sm: tokens14.space.inline.sm,
3072
+ md: tokens14.space.inline.md,
3073
+ lg: tokens14.space.inline.lg
2956
3074
  };
2957
3075
  var crossAxis = { stretch: "stretch", start: "flex-start", center: "center", end: "flex-end", baseline: "baseline" };
2958
3076
  var mainAxis = { start: "flex-start", center: "center", end: "flex-end", between: "space-between" };
2959
- function KjunStack({ gap = "md", align = "stretch", style, children }) {
2960
- return /* @__PURE__ */ jsx17(View12, { style: [{ flexDirection: "column", alignItems: crossAxis[align], gap: stackGap[gap], minWidth: 0 }, style], children: items(children) });
3077
+ function KjunStack({ gap = "md", align, style, children }) {
3078
+ return /* @__PURE__ */ jsx17(View12, { style: [{ flexDirection: "column", alignItems: crossAxis[align != null ? align : "stretch"], gap: stackGap[gap], minWidth: 0 }, style], children: items(children, followed(align)) });
2961
3079
  }
2962
- function KjunInline({ gap = "sm", align = "center", justify = "start", wrap = true, style, children }) {
3080
+ function KjunInline({ gap = "sm", align, justify = "start", wrap = true, style, children }) {
2963
3081
  return /* @__PURE__ */ jsx17(View12, { style: [{
2964
3082
  flexDirection: "row",
2965
3083
  flexWrap: wrap ? "wrap" : "nowrap",
2966
- alignItems: crossAxis[align],
3084
+ alignItems: crossAxis[align != null ? align : "center"],
2967
3085
  justifyContent: mainAxis[justify],
2968
3086
  gap: inlineGap[gap],
2969
3087
  minWidth: 0
2970
- }, style], children: items(children) });
3088
+ }, style], children: items(children, followed(align)) });
2971
3089
  }
2972
3090
 
2973
3091
  // shared/package-runtime/feedback-dialog.ts
2974
- import { useRef as useRef8, useState as useState11 } from "react";
3092
+ import { useRef as useRef10, useState as useState11 } from "react";
2975
3093
  function useFeedbackDialog(controller, request, messages = kjunMessagesKo) {
2976
3094
  const options = request.options;
2977
3095
  const [value, setValue] = useState11(options.initialValue || "");
2978
3096
  const [error, setError] = useState11("");
2979
3097
  const [busy, setBusy] = useState11(false);
2980
- const working = useRef8(false);
3098
+ const working = useRef10(false);
2981
3099
  const active = () => {
2982
3100
  var _a;
2983
3101
  return ((_a = controller.getSnapshot().current) == null ? void 0 : _a.id) === request.id;
@@ -3019,11 +3137,11 @@ function useFeedbackDialog(controller, request, messages = kjunMessagesKo) {
3019
3137
  }
3020
3138
 
3021
3139
  // shared/package-runtime/feedback-motion.ts
3022
- import { tokens as tokens14 } from "@kjun-ui/tokens";
3023
- import { useLayoutEffect as useLayoutEffect6, useRef as useRef9, useState as useState12 } from "react";
3140
+ import { tokens as tokens15 } from "@kjun-ui/tokens";
3141
+ import { useLayoutEffect as useLayoutEffect6, useRef as useRef11, useState as useState12 } from "react";
3024
3142
  function usePresentedToasts(toasts, reduced) {
3025
3143
  const [items2, setItems] = useState12([]);
3026
- const removals = useRef9(/* @__PURE__ */ new Map());
3144
+ const removals = useRef11(/* @__PURE__ */ new Map());
3027
3145
  useLayoutEffect6(() => {
3028
3146
  const ids = new Set(toasts.map((toast) => toast.id));
3029
3147
  setItems((previous) => {
@@ -3037,7 +3155,7 @@ function usePresentedToasts(toasts, reduced) {
3037
3155
  if (!removals.current.has(item.toast.id)) removals.current.set(item.toast.id, setTimeout(() => {
3038
3156
  removals.current.delete(item.toast.id);
3039
3157
  setItems((current) => current.filter((value) => value.toast.id !== item.toast.id));
3040
- }, tokens14.motion.toastExit));
3158
+ }, tokens15.motion.toastExit));
3041
3159
  }
3042
3160
  return next;
3043
3161
  });
@@ -3059,7 +3177,7 @@ function usePresentedRequest(current, reduced) {
3059
3177
  setRequest(current);
3060
3178
  return;
3061
3179
  }
3062
- const timer = setTimeout(() => setRequest(current), tokens14.motion.layerExit);
3180
+ const timer = setTimeout(() => setRequest(current), tokens15.motion.layerExit);
3063
3181
  return () => clearTimeout(timer);
3064
3182
  }, [current, request, reduced]);
3065
3183
  return { request, open: !!request && (current == null ? void 0 : current.id) === request.id };
@@ -3073,9 +3191,9 @@ function useOptionalKjunFeedback() {
3073
3191
  }
3074
3192
 
3075
3193
  // packages/native/src/toast-stack.tsx
3076
- import { useLayoutEffect as useLayoutEffect8, useRef as useRef12 } from "react";
3194
+ import { useLayoutEffect as useLayoutEffect8, useRef as useRef14 } from "react";
3077
3195
  import { Animated as Animated8, Platform as Platform13, View as View14 } from "react-native";
3078
- import { tokens as tokens17 } from "@kjun-ui/tokens";
3196
+ import { tokens as tokens18 } from "@kjun-ui/tokens";
3079
3197
 
3080
3198
  // shared/package-runtime/elevation.ts
3081
3199
  function directionalShadow(layers, direction) {
@@ -3090,8 +3208,8 @@ function shadowLayers(layers, colors) {
3090
3208
  }
3091
3209
 
3092
3210
  // packages/native/src/toast.tsx
3093
- import { tokens as tokens15 } from "@kjun-ui/tokens";
3094
- import { useEffect as useEffect7, useRef as useRef10 } from "react";
3211
+ import { tokens as tokens16 } from "@kjun-ui/tokens";
3212
+ import { useEffect as useEffect8, useRef as useRef12 } from "react";
3095
3213
  import { Animated as Animated7, View as View13 } from "react-native";
3096
3214
  import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
3097
3215
  function ToastView({
@@ -3099,14 +3217,14 @@ function ToastView({
3099
3217
  controller
3100
3218
  }) {
3101
3219
  const m = useKjunMessages();
3102
- const { colors } = useKjunStyles(), reduced = useReducedMotion(), progress = useRef10(new Animated7.Value(1)).current;
3103
- const reasons = useRef10({
3220
+ const { colors } = useKjunStyles(), reduced = useReducedMotion(), progress = useRef12(new Animated7.Value(1)).current;
3221
+ const reasons = useRef12({
3104
3222
  hover: /* @__PURE__ */ Symbol("hover"),
3105
3223
  actionHover: /* @__PURE__ */ Symbol("actionHover"),
3106
3224
  closeHover: /* @__PURE__ */ Symbol("closeHover"),
3107
3225
  focus: /* @__PURE__ */ Symbol("focus")
3108
3226
  }).current;
3109
- useEffect7(() => () => {
3227
+ useEffect8(() => () => {
3110
3228
  for (const reason of Object.values(reasons)) controller.resumeToast(toast.id, reason);
3111
3229
  }, [controller, toast.id, reasons]);
3112
3230
  const tone = toast.type === "error" ? "danger" : toast.type || "info", icon = {
@@ -3115,7 +3233,7 @@ function ToastView({
3115
3233
  warning: "alert-triangle",
3116
3234
  info: "info-circle"
3117
3235
  }[tone];
3118
- useEffect7(() => {
3236
+ useEffect8(() => {
3119
3237
  progress.stopAnimation();
3120
3238
  progress.setValue(toast.duration ? toast.remaining / toast.duration : 1);
3121
3239
  if (!toast.paused && !reduced) {
@@ -3134,7 +3252,7 @@ function ToastView({
3134
3252
  accessible: false,
3135
3253
  onHoverIn: () => controller.pauseToast(toast.id, reasons.hover),
3136
3254
  onHoverOut: () => controller.resumeToast(toast.id, reasons.hover),
3137
- style: { width: "100%", maxWidth: tokens15.extensions.toast.maxWidth, alignSelf: "flex-end" },
3255
+ style: { width: "100%", maxWidth: tokens16.extensions.toast.maxWidth, alignSelf: "flex-end" },
3138
3256
  children: /* @__PURE__ */ jsxs9(
3139
3257
  View13,
3140
3258
  {
@@ -3143,19 +3261,19 @@ function ToastView({
3143
3261
  style: {
3144
3262
  flexDirection: "row",
3145
3263
  alignItems: toast.title ? "flex-start" : "center",
3146
- gap: tokens15.extensions.toast.gap,
3147
- padding: tokens15.extensions.toast.padding,
3148
- borderRadius: tokens15.extensions.toast.radius,
3264
+ gap: tokens16.extensions.toast.gap,
3265
+ padding: tokens16.extensions.toast.padding,
3266
+ borderRadius: tokens16.extensions.toast.radius,
3149
3267
  backgroundColor: colors.surface,
3150
- boxShadow: shadowLayers(tokens15.extensions.toast.elevation, colors),
3151
- borderWidth: tokens15.border.defaultWidth,
3268
+ boxShadow: shadowLayers(tokens16.extensions.toast.elevation, colors),
3269
+ borderWidth: tokens16.border.defaultWidth,
3152
3270
  borderColor: colors.border,
3153
3271
  overflow: "hidden"
3154
3272
  },
3155
3273
  children: [
3156
3274
  /* @__PURE__ */ jsx18(KjunIcon, { name: icon, color: colors[`${tone}Accent`] }),
3157
3275
  /* @__PURE__ */ jsxs9(View13, { style: { flex: 1, minWidth: 0 }, children: [
3158
- !!toast.title && /* @__PURE__ */ jsx18(KText, { style: { fontWeight: typeStyle("control").fontWeight, marginBottom: tokens15.extensions.toast.titleGap }, children: toast.title }),
3276
+ !!toast.title && /* @__PURE__ */ jsx18(KText, { style: { fontWeight: typeStyle("control").fontWeight, marginBottom: tokens16.extensions.toast.titleGap }, children: toast.title }),
3159
3277
  /* @__PURE__ */ jsx18(KText, { style: { color: colors.textSecondary }, children: toast.message }),
3160
3278
  toast.action && /* @__PURE__ */ jsx18(
3161
3279
  AccessiblePressable,
@@ -3173,7 +3291,7 @@ function ToastView({
3173
3291
  dismiss();
3174
3292
  }
3175
3293
  },
3176
- style: { minHeight: tokens15.native.minimumTouchTarget, justifyContent: "center", marginTop: tokens15.extensions.toast.actionGap },
3294
+ style: { minHeight: tokens16.native.minimumTouchTarget, justifyContent: "center", marginTop: tokens16.extensions.toast.actionGap },
3177
3295
  children: /* @__PURE__ */ jsx18(
3178
3296
  KText,
3179
3297
  {
@@ -3195,11 +3313,11 @@ function ToastView({
3195
3313
  onBlur: () => controller.resumeToast(toast.id, reasons.focus),
3196
3314
  onPress: dismiss,
3197
3315
  style: {
3198
- minWidth: Math.max(tokens15.extensions.toast.closeSize, tokens15.native.minimumTouchTarget),
3199
- minHeight: Math.max(tokens15.extensions.toast.closeSize, tokens15.native.minimumTouchTarget),
3316
+ minWidth: Math.max(tokens16.extensions.toast.closeSize, tokens16.native.minimumTouchTarget),
3317
+ minHeight: Math.max(tokens16.extensions.toast.closeSize, tokens16.native.minimumTouchTarget),
3200
3318
  alignItems: "center",
3201
3319
  justifyContent: "center",
3202
- borderRadius: tokens15.extensions.toast.closeRadius
3320
+ borderRadius: tokens16.extensions.toast.closeRadius
3203
3321
  },
3204
3322
  children: /* @__PURE__ */ jsx18(KjunIcon, { name: "x", color: colors.textTertiary })
3205
3323
  }
@@ -3212,7 +3330,7 @@ function ToastView({
3212
3330
  position: "absolute",
3213
3331
  bottom: 0,
3214
3332
  left: 0,
3215
- height: tokens15.extensions.toast.progressHeight,
3333
+ height: tokens16.extensions.toast.progressHeight,
3216
3334
  width: progress.interpolate({
3217
3335
  inputRange: [0, 1],
3218
3336
  outputRange: ["0%", "100%"]
@@ -3229,10 +3347,10 @@ function ToastView({
3229
3347
  }
3230
3348
 
3231
3349
  // packages/native/src/toast-reflow.web.ts
3232
- import { useLayoutEffect as useLayoutEffect7, useRef as useRef11 } from "react";
3350
+ import { useLayoutEffect as useLayoutEffect7, useRef as useRef13 } from "react";
3233
3351
 
3234
3352
  // shared/package-runtime/toast-layout.ts
3235
- import { tokens as tokens16 } from "@kjun-ui/tokens";
3353
+ import { tokens as tokens17 } from "@kjun-ui/tokens";
3236
3354
  function createToastLayout() {
3237
3355
  let root = null;
3238
3356
  const boxes = /* @__PURE__ */ new Map();
@@ -3275,7 +3393,7 @@ function createToastLayout() {
3275
3393
  const top = node.offsetTop, left = node.offsetLeft;
3276
3394
  (_a = animations.get(node)) == null ? void 0 : _a.cancel();
3277
3395
  if (old && !reduced && Math.abs(old.top + offset - top) > 0.5) {
3278
- const animation = node.animate([{ transform: `translateY(${old.top + offset - top}px)` }, { transform: "translateY(0)" }], { duration: tokens16.motion.toastMove, easing: tokens16.motion.easeOut });
3396
+ const animation = node.animate([{ transform: `translateY(${old.top + offset - top}px)` }, { transform: "translateY(0)" }], { duration: tokens17.motion.toastMove, easing: tokens17.motion.easeOut });
3279
3397
  animations.set(node, animation);
3280
3398
  }
3281
3399
  boxes.set(id, { top, left, width: node.offsetWidth, height: node.offsetHeight });
@@ -3292,7 +3410,7 @@ function createToastLayout() {
3292
3410
 
3293
3411
  // packages/native/src/toast-reflow.web.ts
3294
3412
  function useToastReflow(root, reduced) {
3295
- const layout = useRef11(createToastLayout()).current;
3413
+ const layout = useRef13(createToastLayout()).current;
3296
3414
  useLayoutEffect7(() => {
3297
3415
  if (root.current) layout.update(root.current, reduced);
3298
3416
  });
@@ -3302,9 +3420,9 @@ function useToastReflow(root, reduced) {
3302
3420
  // packages/native/src/toast-stack.tsx
3303
3421
  import { jsx as jsx19 } from "react/jsx-runtime";
3304
3422
  function ToastSlot({ item, controller, boxes }) {
3305
- const born = useRef12(Math.min(tokens17.motion.toastEnter, Date.now() - item.born)).current;
3306
- const motion = useNativePresence(!item.exiting, tokens17.motion.toastEnter - born, tokens17.motion.toastExit, true, born / tokens17.motion.toastEnter);
3307
- const offset = useRef12(new Animated8.Value(0)).current;
3423
+ const born = useRef14(Math.min(tokens18.motion.toastEnter, Date.now() - item.born)).current;
3424
+ const motion = useNativePresence(!item.exiting, tokens18.motion.toastEnter - born, tokens18.motion.toastExit, true, born / tokens18.motion.toastEnter);
3425
+ const offset = useRef14(new Animated8.Value(0)).current;
3308
3426
  const box = boxes.get(item.toast.id);
3309
3427
  useLayoutEffect8(() => {
3310
3428
  if (motion.reduced) {
@@ -3324,7 +3442,7 @@ function ToastSlot({ item, controller, boxes }) {
3324
3442
  boxes.set(item.toast.id, next);
3325
3443
  if (old && old.y !== next.y && !motion.reduced) offset.stopAnimation((current) => {
3326
3444
  offset.setValue(current + old.y - next.y);
3327
- Animated8.timing(offset, { toValue: 0, duration: tokens17.motion.toastMove, easing: motionOut, useNativeDriver: nativeDriver }).start();
3445
+ Animated8.timing(offset, { toValue: 0, duration: tokens18.motion.toastMove, easing: motionOut, useNativeDriver: nativeDriver }).start();
3328
3446
  });
3329
3447
  },
3330
3448
  style: { transform: [{ translateY: offset }], ...item.exiting && box ? {
@@ -3341,7 +3459,7 @@ function ToastSlot({ item, controller, boxes }) {
3341
3459
  accessibilityElementsHidden: item.exiting,
3342
3460
  importantForAccessibility: item.exiting ? "no-hide-descendants" : "auto",
3343
3461
  ...item.exiting ? { inert: true } : {},
3344
- style: { opacity: motion.opacity, transform: [{ translateY: motion.progress.interpolate({ inputRange: [0, 1], outputRange: [-tokens17.motionDistance.toast, 0] }) }] },
3462
+ style: { opacity: motion.opacity, transform: [{ translateY: motion.progress.interpolate({ inputRange: [0, 1], outputRange: [-tokens18.motionDistance.toast, 0] }) }] },
3345
3463
  children: /* @__PURE__ */ jsx19(ToastView, { toast: item.toast, controller })
3346
3464
  }
3347
3465
  )
@@ -3351,16 +3469,16 @@ function ToastSlot({ item, controller, boxes }) {
3351
3469
  function ToastStack({ items: items2, controller }) {
3352
3470
  var _a;
3353
3471
  const layers = useLayerState();
3354
- const root = useRef12(null), reduced = useReducedMotion();
3472
+ const root = useRef14(null), reduced = useReducedMotion();
3355
3473
  useToastReflow(root, reduced);
3356
- const boxes = useRef12(/* @__PURE__ */ new Map()).current;
3474
+ const boxes = useRef14(/* @__PURE__ */ new Map()).current;
3357
3475
  for (const id of boxes.keys()) if (!items2.some((item) => item.toast.id === id)) boxes.delete(id);
3358
3476
  return /* @__PURE__ */ jsx19(View14, { ref: root, pointerEvents: "box-none", style: {
3359
3477
  position: "absolute",
3360
- top: tokens17.extensions.toast.inset,
3361
- right: tokens17.extensions.toast.inset,
3362
- left: tokens17.extensions.toast.inset,
3363
- gap: tokens17.extensions.toast.stackGap,
3478
+ top: tokens18.extensions.toast.inset,
3479
+ right: tokens18.extensions.toast.inset,
3480
+ left: tokens18.extensions.toast.inset,
3481
+ gap: tokens18.extensions.toast.stackGap,
3364
3482
  minHeight: items2.some((item) => item.exiting) ? Math.max(0, ...[...boxes.values()].map((box) => box.y + box.height)) : void 0,
3365
3483
  zIndex: layers.zIndex((_a = layers.topWindow()) == null ? void 0 : _a.id, "toast")
3366
3484
  }, children: items2.map((item) => /* @__PURE__ */ jsx19(ToastSlot, { item, controller, boxes }, item.toast.id)) });
@@ -3368,17 +3486,19 @@ function ToastStack({ items: items2, controller }) {
3368
3486
 
3369
3487
  // packages/native/src/feedback.tsx
3370
3488
  import {
3371
- tokens as tokens18,
3372
- createFeedbackController
3489
+ tokens as tokens19,
3490
+ createFeedbackController,
3491
+ feedbackControllerOf
3373
3492
  } from "@kjun-ui/tokens";
3374
3493
  import {
3375
- useCallback as useCallback3,
3376
- useEffect as useEffect8,
3377
- useRef as useRef13,
3494
+ useCallback as useCallback4,
3495
+ useEffect as useEffect9,
3496
+ useRef as useRef15,
3378
3497
  useState as useState13,
3379
3498
  useSyncExternalStore as useSyncExternalStore2
3380
3499
  } from "react";
3381
3500
  import { View as View15 } from "react-native";
3501
+ import { createKjunFeedback } from "@kjun-ui/tokens";
3382
3502
  import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
3383
3503
  function useKjunFeedback() {
3384
3504
  const value = useOptionalKjunFeedback();
@@ -3410,7 +3530,7 @@ function FeedbackDialog({
3410
3530
  onConfirm: submit,
3411
3531
  confirmVariant: options.type === "danger" ? "danger" : "primary",
3412
3532
  children: [
3413
- !!options.message && /* @__PURE__ */ jsx20(KText, { style: { marginBottom: tokens18.dimension.value16 }, children: options.message }),
3533
+ !!options.message && /* @__PURE__ */ jsx20(KText, { style: { marginBottom: tokens19.dimension.value16 }, children: options.message }),
3414
3534
  request.kind === "prompt" && /* @__PURE__ */ jsx20(
3415
3535
  KjunInput,
3416
3536
  {
@@ -3427,9 +3547,11 @@ function FeedbackDialog({
3427
3547
  }
3428
3548
  );
3429
3549
  }
3430
- function KjunFeedbackProvider({ children, style }) {
3431
- const [controller] = useState13(createFeedbackController);
3432
- const life = useRef13(0);
3550
+ function KjunFeedbackProvider({ children, style, controller: controllerProp }) {
3551
+ const [owned] = useState13(() => controllerProp ? void 0 : createFeedbackController());
3552
+ const controller = controllerProp ? feedbackControllerOf(controllerProp) : owned;
3553
+ useEffect9(() => controller.attach(), [controller]);
3554
+ const life = useRef15(0);
3433
3555
  const snapshot = useSyncExternalStore2(
3434
3556
  controller.subscribe,
3435
3557
  controller.getSnapshot,
@@ -3438,16 +3560,16 @@ function KjunFeedbackProvider({ children, style }) {
3438
3560
  const reduced = useReducedMotion();
3439
3561
  const toasts = usePresentedToasts(snapshot.toasts, reduced);
3440
3562
  const dialog = usePresentedRequest(snapshot.current, reduced);
3441
- useEffect8(() => {
3563
+ useEffect9(() => {
3442
3564
  const version = ++life.current;
3443
3565
  return () => {
3444
3566
  queueMicrotask(() => {
3445
- if (life.current === version) controller.dispose();
3567
+ if (life.current === version && !controllerProp) controller.dispose();
3446
3568
  });
3447
3569
  };
3448
3570
  }, [controller]);
3449
3571
  const [layers, setLayers] = useState13([]);
3450
- const register = useCallback3((id) => {
3572
+ const register = useCallback4((id) => {
3451
3573
  setLayers((previous) => [...previous, id]);
3452
3574
  return () => setLayers((previous) => previous.filter((item) => item !== id));
3453
3575
  }, []);
@@ -3477,13 +3599,13 @@ function KjunFeedbackProvider({ children, style }) {
3477
3599
 
3478
3600
  // packages/native/src/choice-controls.tsx
3479
3601
  import { Animated as Animated9 } from "react-native";
3480
- import { tokens as tokens19 } from "@kjun-ui/tokens";
3602
+ import { tokens as tokens20 } from "@kjun-ui/tokens";
3481
3603
  import {
3482
3604
  createContext as createContext16,
3483
3605
  useContext as useContext12,
3484
3606
  useState as useState14,
3485
- useEffect as useEffect9,
3486
- useRef as useRef14
3607
+ useEffect as useEffect10,
3608
+ useRef as useRef16
3487
3609
  } from "react";
3488
3610
  import {
3489
3611
  View as View16
@@ -3500,7 +3622,7 @@ function KjunCheckbox({
3500
3622
  onValueChange,
3501
3623
  onChange
3502
3624
  }) {
3503
- const { colors } = useKjunStyles(), checked = Array.isArray(value) ? value.includes(val) : value, dimension = tokens19.extensions.checkbox.sizes[size];
3625
+ const { colors } = useKjunStyles(), checked = Array.isArray(value) ? value.includes(val) : value, dimension = tokens20.extensions.checkbox.sizes[size];
3504
3626
  return /* @__PURE__ */ jsxs11(
3505
3627
  AccessiblePressable,
3506
3628
  {
@@ -3519,8 +3641,8 @@ function KjunCheckbox({
3519
3641
  flexDirection: "row",
3520
3642
  alignItems: "center",
3521
3643
  // Like Web's choice row on a mouse-like pointer; touch layouts keep the 44px target.
3522
- minHeight: finePointer() ? tokens19.extensions.choice.minimumHeight : tokens19.native.minimumTouchTarget,
3523
- opacity: disabled ? tokens19.states.opacity.disabled : pressed ? tokens19.states.opacity.pressed : 1
3644
+ minHeight: finePointer() ? tokens20.extensions.choice.minimumHeight : tokens20.native.minimumTouchTarget,
3645
+ opacity: disabled ? tokens20.states.opacity.disabled : pressed ? tokens20.states.opacity.pressed : 1
3524
3646
  }),
3525
3647
  children: [
3526
3648
  /* @__PURE__ */ jsx21(
@@ -3531,8 +3653,8 @@ function KjunCheckbox({
3531
3653
  justifyContent: "center",
3532
3654
  width: dimension,
3533
3655
  height: dimension,
3534
- borderRadius: tokens19.extensions.checkbox.radii[size],
3535
- borderWidth: tokens19.border.controlWidth,
3656
+ borderRadius: tokens20.extensions.checkbox.radii[size],
3657
+ borderWidth: tokens20.border.controlWidth,
3536
3658
  // Same boundary roles as Radio: strong while enabled, secondary once disabled.
3537
3659
  borderColor: checked ? colors.brand : disabled ? colors.borderSecondary : colors.borderStrong,
3538
3660
  backgroundColor: checked ? colors.brand : colors.surface
@@ -3541,14 +3663,14 @@ function KjunCheckbox({
3541
3663
  KjunIcon,
3542
3664
  {
3543
3665
  name: "check",
3544
- size: tokens19.extensions.checkbox.iconSizes[size],
3666
+ size: tokens20.extensions.checkbox.iconSizes[size],
3545
3667
  color: colors.onBrand
3546
3668
  }
3547
3669
  )
3548
3670
  }
3549
3671
  ),
3550
3672
  !!(children || label) && content(children || label, {
3551
- marginLeft: tokens19.extensions.checkbox.labelGap,
3673
+ marginLeft: tokens20.extensions.checkbox.labelGap,
3552
3674
  ...typeStyle("label")
3553
3675
  })
3554
3676
  ]
@@ -3564,7 +3686,7 @@ function useControlFocus(disabled) {
3564
3686
  onFocus: (event) => setFocused(focusVisible(event.currentTarget)),
3565
3687
  onBlur: () => setFocused(false)
3566
3688
  },
3567
- ring: focused && !disabled ? { outlineStyle: "solid", outlineWidth: tokens19.states.focus.width, outlineOffset: tokens19.states.focus.choiceOffset, outlineColor: colors.focusRing } : {}
3689
+ ring: focused && !disabled ? { outlineStyle: "solid", outlineWidth: tokens20.states.focus.width, outlineOffset: tokens20.states.focus.choiceOffset, outlineColor: colors.focusRing } : {}
3568
3690
  };
3569
3691
  }
3570
3692
  function KjunSwitch({
@@ -3579,10 +3701,10 @@ function KjunSwitch({
3579
3701
  onChange
3580
3702
  }) {
3581
3703
  const { colors } = useKjunStyles();
3582
- const width = tokens19.extensions.switch.widths[size];
3583
- const height = tokens19.extensions.switch.heights[size];
3584
- const thumb = height - 2 * tokens19.extensions.switch.padding;
3585
- const offScale = (thumb - 2 * tokens19.border.controlWidth) / thumb;
3704
+ const width = tokens20.extensions.switch.widths[size];
3705
+ const height = tokens20.extensions.switch.heights[size];
3706
+ const thumb = height - 2 * tokens20.extensions.switch.padding;
3707
+ const offScale = (thumb - 2 * tokens20.border.controlWidth) / thumb;
3586
3708
  const offset = width - height;
3587
3709
  const motion = useMotionValue(value ? 1 : 0);
3588
3710
  const focus = useControlFocus(disabled);
@@ -3611,8 +3733,8 @@ function KjunSwitch({
3611
3733
  flexDirection: "row",
3612
3734
  alignItems: "center",
3613
3735
  // Like Web's choice row on a mouse-like pointer; touch layouts keep the 44px target.
3614
- minHeight: finePointer() ? tokens19.extensions.choice.minimumHeight : tokens19.native.minimumTouchTarget,
3615
- opacity: disabled ? tokens19.states.opacity.disabled : 1
3736
+ minHeight: finePointer() ? tokens20.extensions.choice.minimumHeight : tokens20.native.minimumTouchTarget,
3737
+ opacity: disabled ? tokens20.states.opacity.disabled : 1
3616
3738
  },
3617
3739
  children: [
3618
3740
  /* @__PURE__ */ jsxs11(
@@ -3621,8 +3743,8 @@ function KjunSwitch({
3621
3743
  style: {
3622
3744
  width,
3623
3745
  height,
3624
- padding: tokens19.extensions.switch.padding,
3625
- borderRadius: tokens19.extensions.switch.radius,
3746
+ padding: tokens20.extensions.switch.padding,
3747
+ borderRadius: tokens20.extensions.switch.radius,
3626
3748
  backgroundColor: trackColor,
3627
3749
  ...focus.ring
3628
3750
  },
@@ -3634,8 +3756,8 @@ function KjunSwitch({
3634
3756
  style: {
3635
3757
  position: "absolute",
3636
3758
  inset: 0,
3637
- borderRadius: tokens19.extensions.switch.radius,
3638
- borderWidth: tokens19.border.controlWidth,
3759
+ borderRadius: tokens20.extensions.switch.radius,
3760
+ borderWidth: tokens20.border.controlWidth,
3639
3761
  // Hover turns the boundary to brand, like Checkbox on Web.
3640
3762
  borderColor: hovered && !disabled ? colors.brand : offRole,
3641
3763
  opacity: motion.interpolate({ inputRange: [0, 1], outputRange: [1, 0] })
@@ -3648,7 +3770,7 @@ function KjunSwitch({
3648
3770
  style: {
3649
3771
  width: thumb,
3650
3772
  height: thumb,
3651
- borderRadius: tokens19.extensions.switch.radius,
3773
+ borderRadius: tokens20.extensions.switch.radius,
3652
3774
  backgroundColor: thumbColor,
3653
3775
  transform: [
3654
3776
  { translateX: motion.interpolate({ inputRange: [0, 1], outputRange: [0, offset] }) },
@@ -3660,11 +3782,11 @@ function KjunSwitch({
3660
3782
  ]
3661
3783
  }
3662
3784
  ),
3663
- description ? /* @__PURE__ */ jsxs11(View16, { style: { marginLeft: tokens19.extensions.switch.labelGap, flexShrink: 1, minWidth: 0 }, children: [
3785
+ description ? /* @__PURE__ */ jsxs11(View16, { style: { marginLeft: tokens20.extensions.switch.labelGap, flexShrink: 1, minWidth: 0 }, children: [
3664
3786
  !!(children || label) && content(children || label, typeStyle("label")),
3665
- /* @__PURE__ */ jsx21(KText, { style: { ...typeStyle("caption"), marginTop: tokens19.dimension.value4, color: colors.textSecondary }, children: description })
3787
+ /* @__PURE__ */ jsx21(KText, { style: { ...typeStyle("caption"), marginTop: tokens20.dimension.value4, color: colors.textSecondary }, children: description })
3666
3788
  ] }) : !!(children || label) && content(children || label, {
3667
- marginLeft: tokens19.extensions.switch.labelGap,
3789
+ marginLeft: tokens20.extensions.switch.labelGap,
3668
3790
  ...typeStyle("label")
3669
3791
  })
3670
3792
  ]
@@ -3683,9 +3805,9 @@ function KjunRadio({
3683
3805
  onChange
3684
3806
  }) {
3685
3807
  const group = useContext12(RadioContext), { colors } = useKjunStyles(), selected = (group ? group.value : value) === val;
3686
- const geometry2 = tokens19.extensions.radio;
3808
+ const geometry2 = tokens20.extensions.radio;
3687
3809
  const [hovered, setHovered] = useState14(false);
3688
- useEffect9(() => {
3810
+ useEffect10(() => {
3689
3811
  if (disabled) setHovered(false);
3690
3812
  }, [disabled]);
3691
3813
  return /* @__PURE__ */ jsx21(
@@ -3710,8 +3832,8 @@ function KjunRadio({
3710
3832
  flexDirection: "row",
3711
3833
  alignItems: "center",
3712
3834
  // Like Web's choice row on a mouse-like pointer; touch layouts keep the 44px target.
3713
- minHeight: finePointer() ? tokens19.extensions.choice.minimumHeight : tokens19.native.minimumTouchTarget,
3714
- opacity: disabled ? tokens19.states.opacity.disabled : 1
3835
+ minHeight: finePointer() ? tokens20.extensions.choice.minimumHeight : tokens20.native.minimumTouchTarget,
3836
+ opacity: disabled ? tokens20.states.opacity.disabled : 1
3715
3837
  },
3716
3838
  children: ({ pressed }) => /* @__PURE__ */ jsxs11(Fragment6, { children: [
3717
3839
  /* @__PURE__ */ jsx21(
@@ -3721,7 +3843,7 @@ function KjunRadio({
3721
3843
  width: geometry2.size,
3722
3844
  height: geometry2.size,
3723
3845
  borderWidth: geometry2.borderWidth,
3724
- borderRadius: tokens19.radius.radius9999,
3846
+ borderRadius: tokens20.radius.radius9999,
3725
3847
  alignItems: "center",
3726
3848
  justifyContent: "center",
3727
3849
  borderColor: disabled ? selected ? colors.brand : colors.borderSecondary : pressed ? colors.brandActive : hovered ? colors.brandHover : selected ? colors.brand : colors.borderStrong,
@@ -3733,7 +3855,7 @@ function KjunRadio({
3733
3855
  style: {
3734
3856
  width: geometry2.dot,
3735
3857
  height: geometry2.dot,
3736
- borderRadius: tokens19.radius.radius9999,
3858
+ borderRadius: tokens20.radius.radius9999,
3737
3859
  backgroundColor: colors.brand
3738
3860
  }
3739
3861
  }
@@ -3757,7 +3879,7 @@ function KjunRadioGroup({
3757
3879
  onValueChange,
3758
3880
  onChange
3759
3881
  }) {
3760
- const root = useRef14(null);
3882
+ const root = useRef16(null);
3761
3883
  useRadioKeyboard(root);
3762
3884
  return /* @__PURE__ */ jsx21(
3763
3885
  RadioContext.Provider,
@@ -3778,7 +3900,7 @@ function KjunRadioGroup({
3778
3900
  style: {
3779
3901
  flexDirection: direction === "vertical" ? "column" : "row",
3780
3902
  flexWrap: direction === "vertical" ? "nowrap" : "wrap",
3781
- gap: direction === "vertical" ? tokens19.dimension.value8 : tokens19.dimension.value16
3903
+ gap: direction === "vertical" ? tokens20.dimension.value8 : tokens20.dimension.value16
3782
3904
  },
3783
3905
  children: children || options.map((option) => /* @__PURE__ */ jsx21(
3784
3906
  KjunRadio,
@@ -3796,8 +3918,8 @@ function KjunRadioGroup({
3796
3918
  }
3797
3919
 
3798
3920
  // packages/native/src/selection-groups.tsx
3799
- import { tokens as tokens21 } from "@kjun-ui/tokens";
3800
- import { useLayoutEffect as useLayoutEffect10, useRef as useRef16 } from "react";
3921
+ import { tokens as tokens22 } from "@kjun-ui/tokens";
3922
+ import { useLayoutEffect as useLayoutEffect10, useRef as useRef18 } from "react";
3801
3923
  import {
3802
3924
  Animated as Animated11,
3803
3925
  ScrollView as ScrollView2,
@@ -3806,24 +3928,24 @@ import {
3806
3928
  } from "react-native";
3807
3929
 
3808
3930
  // packages/native/src/button-group-motion.tsx
3809
- import { useCallback as useCallback4, useEffect as useEffect10, useLayoutEffect as useLayoutEffect9, useRef as useRef15, useState as useState15 } from "react";
3931
+ import { useCallback as useCallback5, useEffect as useEffect11, useLayoutEffect as useLayoutEffect9, useRef as useRef17, useState as useState15 } from "react";
3810
3932
  import { Animated as Animated10, Easing as Easing4, StyleSheet as StyleSheet5, View as View17 } from "react-native";
3811
- import { tokens as tokens20 } from "@kjun-ui/tokens";
3933
+ import { tokens as tokens21 } from "@kjun-ui/tokens";
3812
3934
  import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
3813
- var curve = tokens20.motion.easeOut.match(/-?\d*\.?\d+/g).map(Number);
3935
+ var curve = tokens21.motion.easeOut.match(/-?\d*\.?\d+/g).map(Number);
3814
3936
  var easing = Easing4.bezier(...curve);
3815
3937
  var sameBox = (a, b) => a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
3816
3938
  function useButtonGroupMotion(selected) {
3817
3939
  const reduced = useReducedMotion();
3818
3940
  const [layouts, setLayouts] = useState15(/* @__PURE__ */ new Map());
3819
- const x = useRef15(new Animated10.Value(0)).current;
3820
- const width = useRef15(new Animated10.Value(0)).current;
3821
- const previous = useRef15(null);
3941
+ const x = useRef17(new Animated10.Value(0)).current;
3942
+ const width = useRef17(new Animated10.Value(0)).current;
3943
+ const previous = useRef17(null);
3822
3944
  const layout = selected && layouts.get(selected.value);
3823
- const updateLayout = useCallback4((value, box) => {
3945
+ const updateLayout = useCallback5((value, box) => {
3824
3946
  setLayouts((old) => old.has(value) && sameBox(old.get(value), box) ? old : new Map(old).set(value, box));
3825
3947
  }, []);
3826
- const measure = useCallback4((value, event) => updateLayout(value, event.nativeEvent.layout), [updateLayout]);
3948
+ const measure = useCallback5((value, event) => updateLayout(value, event.nativeEvent.layout), [updateLayout]);
3827
3949
  useLayoutEffect9(() => {
3828
3950
  const old = previous.current;
3829
3951
  if (!selected || !layout) {
@@ -3837,8 +3959,8 @@ function useButtonGroupMotion(selected) {
3837
3959
  width.stopAnimation();
3838
3960
  if (old && old.value !== selected.value && !reduced) {
3839
3961
  Animated10.parallel([
3840
- Animated10.timing(x, { toValue: layout.x, duration: tokens20.motion.indicator, easing, useNativeDriver: false }),
3841
- Animated10.timing(width, { toValue: layout.width, duration: tokens20.motion.indicator, easing, useNativeDriver: false })
3962
+ Animated10.timing(x, { toValue: layout.x, duration: tokens21.motion.indicator, easing, useNativeDriver: false }),
3963
+ Animated10.timing(width, { toValue: layout.width, duration: tokens21.motion.indicator, easing, useNativeDriver: false })
3842
3964
  ]).start();
3843
3965
  } else {
3844
3966
  x.setValue(layout.x);
@@ -3846,7 +3968,7 @@ function useButtonGroupMotion(selected) {
3846
3968
  }
3847
3969
  previous.current = { value: selected.value, box: layout, reduced };
3848
3970
  }, [selected == null ? void 0 : selected.value, layout, reduced, x, width]);
3849
- useEffect10(() => () => {
3971
+ useEffect11(() => () => {
3850
3972
  x.stopAnimation();
3851
3973
  width.stopAnimation();
3852
3974
  }, [x, width]);
@@ -3854,12 +3976,12 @@ function useButtonGroupMotion(selected) {
3854
3976
  }
3855
3977
  function ButtonGroupLabel({ label, active, size, reduced }) {
3856
3978
  const { colors, fontFamily } = useKjunStyles();
3857
- const progress = useRef15(new Animated10.Value(active ? 1 : 0)).current;
3979
+ const progress = useRef17(new Animated10.Value(active ? 1 : 0)).current;
3858
3980
  const interpolate = typeof colors.textSecondary === "string" && typeof colors.text === "string";
3859
- useEffect10(() => {
3981
+ useEffect11(() => {
3860
3982
  progress.stopAnimation();
3861
3983
  if (reduced || !interpolate) progress.setValue(active ? 1 : 0);
3862
- else Animated10.timing(progress, { toValue: active ? 1 : 0, duration: tokens20.motion.indicator, easing, useNativeDriver: false }).start();
3984
+ else Animated10.timing(progress, { toValue: active ? 1 : 0, duration: tokens21.motion.indicator, easing, useNativeDriver: false }).start();
3863
3985
  return () => progress.stopAnimation();
3864
3986
  }, [active, reduced, interpolate, progress]);
3865
3987
  const resolveFont = useResolveFont();
@@ -3901,9 +4023,9 @@ function KjunButtonGroup({
3901
4023
  const { colors } = useKjunStyles();
3902
4024
  const selected = options.find((option) => option.value === value);
3903
4025
  const motion = useButtonGroupMotion(selected);
3904
- const padding = tokens21.buttonGroup.padding[size];
3905
- const itemRadius = tokens21.buttonGroup.itemRadii[size];
3906
- const itemRefs = useRef16(/* @__PURE__ */ new Map());
4026
+ const padding = tokens22.buttonGroup.padding[size];
4027
+ const itemRadius = tokens22.buttonGroup.itemRadii[size];
4028
+ const itemRefs = useRef18(/* @__PURE__ */ new Map());
3907
4029
  const { updateLayout } = motion;
3908
4030
  useLayoutEffect10(() => {
3909
4031
  for (const [value2, node] of itemRefs.current) {
@@ -3928,7 +4050,7 @@ function KjunButtonGroup({
3928
4050
  style: {
3929
4051
  flexDirection: "row",
3930
4052
  padding,
3931
- borderRadius: tokens21.buttonGroup.radii[size],
4053
+ borderRadius: tokens22.buttonGroup.radii[size],
3932
4054
  backgroundColor: colors.secondary,
3933
4055
  flexGrow: fullWidth ? 1 : 0
3934
4056
  },
@@ -3952,7 +4074,7 @@ function KjunButtonGroup({
3952
4074
  // Disabled options dim their own labels; the selected value stays readable. The edge keeps it
3953
4075
  // apart from the track when surface and secondary are close.
3954
4076
  backgroundColor: colors.surface,
3955
- borderWidth: tokens21.border.defaultWidth,
4077
+ borderWidth: tokens22.border.defaultWidth,
3956
4078
  borderColor: colors.border
3957
4079
  }
3958
4080
  }
@@ -3980,22 +4102,22 @@ function KjunButtonGroup({
3980
4102
  flexDirection: "row",
3981
4103
  alignItems: "center",
3982
4104
  justifyContent: "center",
3983
- gap: tokens21.dimension.value6,
4105
+ gap: tokens22.dimension.value6,
3984
4106
  flex: fullWidth ? 1 : void 0,
3985
- minWidth: tokens21.native.minimumTouchTarget,
3986
- minHeight: tokens21.native.minimumTouchTarget,
3987
- height: Math.max(tokens21.native.minimumTouchTarget, tokens21.buttonGroup.heights[size] - 2 * padding),
3988
- paddingHorizontal: tokens21.buttonGroup.itemPaddingX[size],
4107
+ minWidth: tokens22.native.minimumTouchTarget,
4108
+ minHeight: tokens22.native.minimumTouchTarget,
4109
+ height: Math.max(tokens22.native.minimumTouchTarget, tokens22.buttonGroup.heights[size] - 2 * padding),
4110
+ paddingHorizontal: tokens22.buttonGroup.itemPaddingX[size],
3989
4111
  borderRadius: itemRadius,
3990
4112
  backgroundColor: active && !motion.layout ? colors.surface : pressed && !active ? colors.hover : "transparent",
3991
- opacity: blocked ? tokens21.states.opacity.disabled : 1
4113
+ opacity: blocked ? tokens22.states.opacity.disabled : 1
3992
4114
  }),
3993
4115
  children: [
3994
4116
  !!option.icon && /* @__PURE__ */ jsx23(
3995
4117
  KjunIcon,
3996
4118
  {
3997
4119
  name: option.icon,
3998
- size: tokens21.extensions.selection.iconSize,
4120
+ size: tokens22.extensions.selection.iconSize,
3999
4121
  color: active ? colors.text : colors.textSecondary
4000
4122
  }
4001
4123
  ),
@@ -4031,7 +4153,7 @@ function KjunFilterGroup({
4031
4153
  onChange
4032
4154
  }) {
4033
4155
  const { colors } = useKjunStyles();
4034
- const wide = useWindowDimensions2().width >= tokens21.responsive.selection, roomy = wide && finePointer();
4156
+ const wide = useWindowDimensions2().width >= tokens22.responsive.selection, roomy = wide && finePointer();
4035
4157
  const selected = (v) => multiple ? Array.isArray(value) && (v === null ? value.length === 0 : value.includes(v)) : value === v;
4036
4158
  const children = /* @__PURE__ */ jsx23(
4037
4159
  View18,
@@ -4040,7 +4162,7 @@ function KjunFilterGroup({
4040
4162
  style: {
4041
4163
  flexDirection: "row",
4042
4164
  flexWrap: scroll ? "nowrap" : "wrap",
4043
- gap: tokens21.dimension.value8
4165
+ gap: tokens22.dimension.value8
4044
4166
  },
4045
4167
  children: options.map((option) => {
4046
4168
  const active = selected(option.value), blocked = disabled || option.disabled;
@@ -4057,9 +4179,9 @@ function KjunFilterGroup({
4057
4179
  onChange == null ? void 0 : onChange(next);
4058
4180
  },
4059
4181
  style: {
4060
- minHeight: roomy ? void 0 : tokens21.native.minimumTouchTarget,
4182
+ minHeight: roomy ? void 0 : tokens22.native.minimumTouchTarget,
4061
4183
  justifyContent: "center",
4062
- opacity: blocked ? tokens21.states.opacity.disabledStrong : 1
4184
+ opacity: blocked ? tokens22.states.opacity.disabledStrong : 1
4063
4185
  },
4064
4186
  children: /* @__PURE__ */ jsxs13(
4065
4187
  View18,
@@ -4068,12 +4190,12 @@ function KjunFilterGroup({
4068
4190
  flexDirection: "row",
4069
4191
  alignItems: "center",
4070
4192
  justifyContent: "center",
4071
- gap: tokens21.dimension.value4,
4072
- minHeight: roomy ? void 0 : tokens21.extensions.selection.minimumHeight,
4073
- height: roomy ? tokens21.button.heights[size] : Math.max(tokens21.extensions.selection.minimumHeight, tokens21.button.heights[size]),
4074
- paddingHorizontal: { xs: tokens21.dimension.value8, sm: tokens21.dimension.value12, md: tokens21.dimension.value12, lg: tokens21.dimension.value14, xl: tokens21.dimension.value16 }[size],
4193
+ gap: tokens22.dimension.value4,
4194
+ minHeight: roomy ? void 0 : tokens22.extensions.selection.minimumHeight,
4195
+ height: roomy ? tokens22.button.heights[size] : Math.max(tokens22.extensions.selection.minimumHeight, tokens22.button.heights[size]),
4196
+ paddingHorizontal: { xs: tokens22.dimension.value8, sm: tokens22.dimension.value12, md: tokens22.dimension.value12, lg: tokens22.dimension.value14, xl: tokens22.dimension.value16 }[size],
4075
4197
  // Corners follow the button scale with the height, so every size keeps the same shape.
4076
- borderRadius: tokens21.button.radii[size],
4198
+ borderRadius: tokens22.button.radii[size],
4077
4199
  backgroundColor: active ? colors.text : colors.secondary
4078
4200
  },
4079
4201
  children: [
@@ -4081,9 +4203,9 @@ function KjunFilterGroup({
4081
4203
  View18,
4082
4204
  {
4083
4205
  style: {
4084
- width: tokens21.extensions.selection.dotSize,
4085
- height: tokens21.extensions.selection.dotSize,
4086
- borderRadius: tokens21.radius.radius4,
4206
+ width: tokens22.extensions.selection.dotSize,
4207
+ height: tokens22.extensions.selection.dotSize,
4208
+ borderRadius: tokens22.radius.radius4,
4087
4209
  backgroundColor: option.dot
4088
4210
  }
4089
4211
  }
@@ -4092,7 +4214,7 @@ function KjunFilterGroup({
4092
4214
  KjunIcon,
4093
4215
  {
4094
4216
  name: option.icon,
4095
- size: tokens21.extensions.selection.iconSize,
4217
+ size: tokens22.extensions.selection.iconSize,
4096
4218
  color: active ? colors.inverse : colors.textSecondary
4097
4219
  }
4098
4220
  ),
@@ -4143,7 +4265,7 @@ function KjunFilterGroup({
4143
4265
  }
4144
4266
 
4145
4267
  // packages/native/src/textarea.tsx
4146
- import { tokens as tokens22 } from "@kjun-ui/tokens";
4268
+ import { tokens as tokens23 } from "@kjun-ui/tokens";
4147
4269
  import {
4148
4270
  forwardRef as forwardRef4
4149
4271
  } from "react";
@@ -4165,7 +4287,7 @@ var KjunTextarea = forwardRef4(
4165
4287
  onBlur,
4166
4288
  ...props
4167
4289
  }, ref) {
4168
- const field = useKjunField(), { colors, fontFamily } = useKjunStyles(), spec = tokens22.input[size];
4290
+ const field = useKjunField(), { colors, fontFamily } = useKjunStyles(), spec = tokens23.input[size];
4169
4291
  const invalid = error || !!(field == null ? void 0 : field.error);
4170
4292
  const surface = useFieldSurface(size, { disabled, readOnly: readonly || props.readOnly || props.editable === false, invalid });
4171
4293
  return /* @__PURE__ */ jsx24(
@@ -4206,8 +4328,8 @@ var KjunTextarea = forwardRef4(
4206
4328
  ...inputTypeStyle(size),
4207
4329
  ...surface.style,
4208
4330
  height: void 0,
4209
- minHeight: Math.max(spec.height, rows * spec.lineHeight + spec.textareaPaddingY * 2 + 2 * tokens22.border.controlWidth),
4210
- paddingHorizontal: spec.padding - tokens22.border.controlWidth,
4331
+ minHeight: Math.max(spec.height, rows * spec.lineHeight + spec.textareaPaddingY * 2 + 2 * tokens23.border.controlWidth),
4332
+ paddingHorizontal: spec.padding - tokens23.border.controlWidth,
4211
4333
  paddingVertical: spec.textareaPaddingY,
4212
4334
  textAlignVertical: "top",
4213
4335
  color: surface.ink
@@ -4220,8 +4342,8 @@ var KjunTextarea = forwardRef4(
4220
4342
  );
4221
4343
 
4222
4344
  // packages/native/src/drawer.tsx
4223
- import { tokens as tokens23 } from "@kjun-ui/tokens";
4224
- import { useEffect as useEffect11, useState as useState16 } from "react";
4345
+ import { tokens as tokens24 } from "@kjun-ui/tokens";
4346
+ import { useEffect as useEffect12, useState as useState16 } from "react";
4225
4347
  import { Animated as Animated12, Keyboard } from "react-native";
4226
4348
 
4227
4349
  // shared/package-runtime/drawer-geometry.ts
@@ -4256,7 +4378,7 @@ import {
4256
4378
  import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
4257
4379
  function useKeyboardOverlap(enabled2, windowHeight) {
4258
4380
  const [overlap, setOverlap] = useState16(0);
4259
- useEffect11(() => {
4381
+ useEffect12(() => {
4260
4382
  var _a, _b;
4261
4383
  setOverlap(0);
4262
4384
  const events = keyboardEvents(Platform15.OS);
@@ -4277,7 +4399,7 @@ function KjunDrawer({
4277
4399
  onOpenChange,
4278
4400
  title,
4279
4401
  position = "right",
4280
- width = tokens23.extensions.drawer.width,
4402
+ width = tokens24.extensions.drawer.width,
4281
4403
  closable = true,
4282
4404
  closeOnOverlay = true,
4283
4405
  closeOnEsc = true,
@@ -4286,6 +4408,7 @@ function KjunDrawer({
4286
4408
  footer,
4287
4409
  children,
4288
4410
  onClose,
4411
+ onAfterClose,
4289
4412
  ariaLabel,
4290
4413
  safeAreaTop = 0,
4291
4414
  safeAreaBottom = 0,
@@ -4301,13 +4424,13 @@ function KjunDrawer({
4301
4424
  windowHeight: rootHeight || window2.height,
4302
4425
  safeAreaTop: Math.max(0, safeAreaTop),
4303
4426
  safeAreaBottom: Math.max(0, safeAreaBottom),
4304
- gap: tokens23.extensions.drawer.sheetGap,
4427
+ gap: tokens24.extensions.drawer.sheetGap,
4305
4428
  keyboard,
4306
4429
  maxHeight
4307
4430
  });
4308
4431
  const [panelHeight, setPanelHeight] = useState16(0);
4309
- const motion = useNativePresence(open, tokens23.motion.layerEnter, tokens23.motion.layerExit, vertical || panelHeight > 0, 0, { enterEasing: motionEmphasized });
4310
- const backdrop = useNativePresence(open, tokens23.motion.backdrop, tokens23.motion.backdropExit, true, 0, { fade: tokens23.motion.backdropExit });
4432
+ const motion = useNativePresence(open, tokens24.motion.layerEnter, tokens24.motion.layerExit, vertical || panelHeight > 0, 0, { enterEasing: motionEmphasized });
4433
+ const backdrop = useNativePresence(open, tokens24.motion.backdrop, tokens24.motion.backdropExit, true, 0, { fade: tokens24.motion.backdropExit });
4311
4434
  const close = () => {
4312
4435
  if (!open) return;
4313
4436
  onOpenChange(false);
@@ -4316,10 +4439,15 @@ function KjunDrawer({
4316
4439
  const layer = useLayer(open, motion.present, "window", () => {
4317
4440
  if (closeOnEsc) close();
4318
4441
  });
4442
+ const iosDismiss = Platform15.OS === "ios";
4443
+ useAfterClose(motion.present, onAfterClose, !iosDismiss);
4319
4444
  return /* @__PURE__ */ jsx25(LayerScope.Provider, { value: layer.id, children: /* @__PURE__ */ jsx25(
4320
4445
  ScopedNativeModal,
4321
4446
  {
4322
4447
  visible: motion.present,
4448
+ onDismiss: iosDismiss ? () => {
4449
+ if (!open) onAfterClose == null ? void 0 : onAfterClose();
4450
+ } : void 0,
4323
4451
  transparent: true,
4324
4452
  onRequestClose: () => {
4325
4453
  if (closeOnEsc) close();
@@ -4372,10 +4500,10 @@ function KjunDrawer({
4372
4500
  paddingTop: frame.paddingTop,
4373
4501
  paddingBottom: frame.paddingBottom,
4374
4502
  marginBottom: frame.lift,
4375
- borderRadius: tokens23.extensions.drawer.radius,
4376
- borderTopLeftRadius: position === "bottom" ? tokens23.extensions.drawer.bottomRadius : tokens23.extensions.drawer.radius,
4377
- borderTopRightRadius: position === "bottom" ? tokens23.extensions.drawer.bottomRadius : tokens23.extensions.drawer.radius,
4378
- boxShadow: directionalShadow(tokens23.extensions.drawer.elevation, position).map(({ colorRole, ...layer2 }) => ({ ...layer2, color: colors[colorRole] })),
4503
+ borderRadius: tokens24.extensions.drawer.radius,
4504
+ borderTopLeftRadius: position === "bottom" ? tokens24.extensions.drawer.bottomRadius : tokens24.extensions.drawer.radius,
4505
+ borderTopRightRadius: position === "bottom" ? tokens24.extensions.drawer.bottomRadius : tokens24.extensions.drawer.radius,
4506
+ boxShadow: directionalShadow(tokens24.extensions.drawer.elevation, position).map(({ colorRole, ...layer2 }) => ({ ...layer2, color: colors[colorRole] })),
4379
4507
  backgroundColor: colors.surface
4380
4508
  },
4381
4509
  children: [
@@ -4386,9 +4514,9 @@ function KjunDrawer({
4386
4514
  flexDirection: "row",
4387
4515
  alignItems: "center",
4388
4516
  justifyContent: "space-between",
4389
- paddingVertical: tokens23.extensions.drawer.paddingY,
4390
- paddingHorizontal: tokens23.extensions.drawer.paddingX,
4391
- borderBottomWidth: tokens23.border.defaultWidth,
4517
+ paddingVertical: tokens24.extensions.drawer.paddingY,
4518
+ paddingHorizontal: tokens24.extensions.drawer.paddingX,
4519
+ borderBottomWidth: tokens24.border.defaultWidth,
4392
4520
  borderBottomColor: colors.border
4393
4521
  },
4394
4522
  children: [
@@ -4406,8 +4534,8 @@ function KjunDrawer({
4406
4534
  variant: "ghost",
4407
4535
  ariaLabel: m.close,
4408
4536
  onPress: close,
4409
- style: { borderRadius: tokens23.extensions.drawer.closeRadius, width: tokens23.extensions.drawer.closeSize, height: tokens23.extensions.drawer.closeSize, paddingHorizontal: 0, paddingVertical: 0 },
4410
- children: /* @__PURE__ */ jsx25(KjunIcon, { name: "x", size: tokens23.extensions.drawer.closeIconSize })
4537
+ style: { borderRadius: tokens24.extensions.drawer.closeRadius, width: tokens24.extensions.drawer.closeSize, height: tokens24.extensions.drawer.closeSize, paddingHorizontal: 0, paddingVertical: 0 },
4538
+ children: /* @__PURE__ */ jsx25(KjunIcon, { name: "x", size: tokens24.extensions.drawer.closeIconSize })
4411
4539
  }
4412
4540
  )
4413
4541
  ]
@@ -4418,7 +4546,7 @@ function KjunDrawer({
4418
4546
  {
4419
4547
  keyboardShouldPersistTaps: "handled",
4420
4548
  style: vertical ? { flex: 1 } : { flexGrow: 0, flexShrink: 1 },
4421
- contentContainerStyle: { padding: noPadding ? 0 : tokens23.extensions.drawer.bodyPadding },
4549
+ contentContainerStyle: { padding: noPadding ? 0 : tokens24.extensions.drawer.bodyPadding },
4422
4550
  children: content(children)
4423
4551
  }
4424
4552
  ),
@@ -4426,9 +4554,9 @@ function KjunDrawer({
4426
4554
  View19,
4427
4555
  {
4428
4556
  style: {
4429
- paddingVertical: tokens23.extensions.drawer.paddingY,
4430
- paddingHorizontal: tokens23.extensions.drawer.paddingX,
4431
- borderTopWidth: tokens23.border.defaultWidth,
4557
+ paddingVertical: tokens24.extensions.drawer.paddingY,
4558
+ paddingHorizontal: tokens24.extensions.drawer.paddingX,
4559
+ borderTopWidth: tokens24.border.defaultWidth,
4432
4560
  borderTopColor: colors.border
4433
4561
  },
4434
4562
  children: content(footer)
@@ -4445,15 +4573,15 @@ function KjunDrawer({
4445
4573
  }
4446
4574
 
4447
4575
  // packages/native/src/dropdown.tsx
4448
- import { tokens as tokens26 } from "@kjun-ui/tokens";
4576
+ import { tokens as tokens27 } from "@kjun-ui/tokens";
4449
4577
  import {
4450
4578
  Children as Children3,
4451
4579
  Fragment as Fragment8,
4452
4580
  createContext as createContext17,
4453
4581
  isValidElement as isValidElement6,
4454
4582
  useContext as useContext13,
4455
- useEffect as useEffect14,
4456
- useRef as useRef19,
4583
+ useEffect as useEffect15,
4584
+ useRef as useRef21,
4457
4585
  useState as useState19
4458
4586
  } from "react";
4459
4587
  import {
@@ -4462,13 +4590,13 @@ import {
4462
4590
 
4463
4591
  // packages/native/src/floating-panel.tsx
4464
4592
  import { Animated as Animated13 } from "react-native";
4465
- import { tokens as tokens24 } from "@kjun-ui/tokens";
4593
+ import { tokens as tokens25 } from "@kjun-ui/tokens";
4466
4594
  import {
4467
4595
  cloneElement as cloneElement3,
4468
4596
  isValidElement as isValidElement4,
4469
- useEffect as useEffect12,
4597
+ useEffect as useEffect13,
4470
4598
  useLayoutEffect as useLayoutEffect11,
4471
- useRef as useRef17,
4599
+ useRef as useRef19,
4472
4600
  useState as useState17
4473
4601
  } from "react";
4474
4602
  import {
@@ -4525,11 +4653,11 @@ function FloatingPanel({
4525
4653
  const m = useKjunMessages();
4526
4654
  ariaLabel != null ? ariaLabel : ariaLabel = m.select;
4527
4655
  const [headerHeight, setHeaderHeight] = useState17(0);
4528
- const panelRef = useRef17(null);
4529
- const scroll = useRef17(null), viewport = useRef17(0);
4656
+ const panelRef = useRef19(null);
4657
+ const scroll = useRef19(null), viewport = useRef19(0);
4530
4658
  const { colors } = useKjunStyles(), window2 = useWindowDimensions4(), [anchored, setAnchored] = useState17(false), [sized, setSized] = useState17(false), [anchor, setAnchor] = useState17({ x: 0, y: 0, width: 0, height: 0 }), [panel, setPanel] = useState17({ width: 0, height: 0 });
4531
- const measurement = useRef17(0);
4532
- const motion = useNativePresence(open, tooltip ? tokens24.motion.tooltipEnter : tokens24.motion.popupEnter, tooltip ? tokens24.motion.tooltipExit : tokens24.motion.popupExit, anchored && sized);
4659
+ const measurement = useRef19(0);
4660
+ const motion = useNativePresence(open, tooltip ? tokens25.motion.tooltipEnter : tokens25.motion.popupEnter, tooltip ? tokens25.motion.tooltipExit : tokens25.motion.popupExit, anchored && sized);
4533
4661
  const layer = useLayer(open, motion.present, tooltip ? "tooltip" : "popup", () => onOpenChange(false), triggerRef);
4534
4662
  useLayoutEffect11(() => {
4535
4663
  var _a;
@@ -4550,14 +4678,14 @@ function FloatingPanel({
4550
4678
  setAnchored(false);
4551
4679
  }
4552
4680
  }, [motion.present]);
4553
- useEffect12(() => {
4681
+ useEffect13(() => {
4554
4682
  var _a;
4555
4683
  const row = reveal == null ? void 0 : reveal.current;
4556
4684
  if (!open || !anchored || !sized || !row || !viewport.current) return;
4557
- const offset = row.y + row.height + (menu || field ? tokens24.extensions.menu.padding : 0) - viewport.current;
4685
+ const offset = row.y + row.height + (menu || field ? tokens25.extensions.menu.padding : 0) - viewport.current;
4558
4686
  if (offset > 0) (_a = scroll.current) == null ? void 0 : _a.scrollTo({ y: offset, animated: false });
4559
4687
  }, [open, anchored, sized, reveal, menu, field]);
4560
- useEffect12(() => {
4688
+ useEffect13(() => {
4561
4689
  if (!open || !anchored || !sized || !focusOnOpen || !panelRef.current) return;
4562
4690
  if (Platform16.OS === "web") {
4563
4691
  const node = panelRef.current;
@@ -4567,30 +4695,30 @@ function FloatingPanel({
4567
4695
  if (tag) AccessibilityInfo3.setAccessibilityFocus(tag);
4568
4696
  }
4569
4697
  }, [open, anchored, sized, focusOnOpen]);
4570
- const gap = field ? tokens24.extensions.floating.fieldGap : tokens24.extensions.floating.anchorGap;
4698
+ const gap = field ? tokens25.extensions.floating.fieldGap : tokens25.extensions.floating.anchorGap;
4571
4699
  const contentSizedMenu = menu && !matchTriggerWidth;
4572
- const tooltipWidth = Math.min(Math.max(0, window2.width - 2 * tokens24.extensions.floating.viewportInset), tokens24.extensions.tooltip.maxWidth);
4573
- const maximumWidth = Math.max(0, window2.width - 2 * tokens24.extensions.floating.viewportInset);
4700
+ const tooltipWidth = Math.min(Math.max(0, window2.width - 2 * tokens25.extensions.floating.viewportInset), tokens25.extensions.tooltip.maxWidth);
4701
+ const maximumWidth = Math.max(0, window2.width - 2 * tokens25.extensions.floating.viewportInset);
4574
4702
  const minimumPanelWidth = Math.min(
4575
4703
  maximumWidth,
4576
- Math.max(minimumWidth, menu || field ? tokens24.extensions.menu.minimumWidth : 0)
4704
+ Math.max(minimumWidth, menu || field ? tokens25.extensions.menu.minimumWidth : 0)
4577
4705
  );
4578
4706
  const width = tooltip ? Math.min(tooltipWidth, panel.width || tooltipWidth) : Math.min(
4579
4707
  maximumWidth,
4580
- Math.max(minimumPanelWidth, contentSizedMenu ? panel.width : matchTriggerWidth ? anchor.width : tokens24.extensions.popover.width)
4708
+ Math.max(minimumPanelWidth, contentSizedMenu ? panel.width : matchTriggerWidth ? anchor.width : tokens25.extensions.popover.width)
4581
4709
  );
4582
- const available = Math.min(maxHeight != null ? maxHeight : field ? tokens24.extensions.menu.listMaxHeight : tokens24.extensions.floating.maxHeight, window2.height - 2 * tokens24.extensions.floating.viewportInset), height = Math.min(panel.height + (header != null ? headerHeight : 0), available), roomAbove = anchor.y - gap - tokens24.extensions.floating.viewportInset, roomBelow = window2.height - anchor.y - anchor.height - gap - tokens24.extensions.floating.viewportInset, above = placement.startsWith("top") ? !(flip && height > roomAbove && roomBelow > roomAbove) : flip && height > roomBelow && roomAbove > roomBelow;
4710
+ const available = Math.min(maxHeight != null ? maxHeight : field ? tokens25.extensions.menu.listMaxHeight : tokens25.extensions.floating.maxHeight, window2.height - 2 * tokens25.extensions.floating.viewportInset), height = Math.min(panel.height + (header != null ? headerHeight : 0), available), roomAbove = anchor.y - gap - tokens25.extensions.floating.viewportInset, roomBelow = window2.height - anchor.y - anchor.height - gap - tokens25.extensions.floating.viewportInset, above = placement.startsWith("top") ? !(flip && height > roomAbove && roomBelow > roomAbove) : flip && height > roomBelow && roomAbove > roomBelow;
4583
4711
  let left = placement.endsWith("end") ? anchor.x + anchor.width - width : placement === "top" || placement === "bottom" ? anchor.x + (anchor.width - width) / 2 : anchor.x, top = above ? anchor.y - height - gap : anchor.y + anchor.height + gap;
4584
4712
  if (placement === "left" || placement === "right") {
4585
4713
  left = placement === "left" ? anchor.x - width - gap : anchor.x + anchor.width + gap;
4586
4714
  top = anchor.y + (anchor.height - height) / 2;
4587
4715
  }
4588
- left = Math.max(tokens24.extensions.floating.viewportInset, Math.min(window2.width - width - tokens24.extensions.floating.viewportInset, left));
4589
- top = Math.max(tokens24.extensions.floating.viewportInset, Math.min(window2.height - height - tokens24.extensions.floating.viewportInset, top));
4716
+ left = Math.max(tokens25.extensions.floating.viewportInset, Math.min(window2.width - width - tokens25.extensions.floating.viewportInset, left));
4717
+ top = Math.max(tokens25.extensions.floating.viewportInset, Math.min(window2.height - height - tokens25.extensions.floating.viewportInset, top));
4590
4718
  if (layer.blocked) return null;
4591
4719
  if (tooltip && Platform16.OS === "web") {
4592
4720
  if (!motion.present) return null;
4593
- const arrow = tokens24.extensions.tooltip.arrowSize, corner = tokens24.radius.radius6, side = placement === "left" ? "right" : placement === "right" ? "left" : above ? "bottom" : "top", along = side === "top" || side === "bottom" ? Math.max(corner, Math.min(width - corner - arrow, anchor.x + anchor.width / 2 - left - arrow / 2)) : Math.max(corner, Math.min(height - corner - arrow, anchor.y + anchor.height / 2 - top - arrow / 2));
4721
+ const arrow = tokens25.extensions.tooltip.arrowSize, corner = tokens25.radius.radius6, side = placement === "left" ? "right" : placement === "right" ? "left" : above ? "bottom" : "top", along = side === "top" || side === "bottom" ? Math.max(corner, Math.min(width - corner - arrow, anchor.x + anchor.width / 2 - left - arrow / 2)) : Math.max(corner, Math.min(height - corner - arrow, anchor.y + anchor.height / 2 - top - arrow / 2));
4594
4722
  return /* @__PURE__ */ jsxs15(
4595
4723
  Animated13.View,
4596
4724
  {
@@ -4617,7 +4745,7 @@ function FloatingPanel({
4617
4745
  borderRadius: corner,
4618
4746
  overflow: "hidden",
4619
4747
  backgroundColor: colors.chartTooltipBg,
4620
- boxShadow: shadowLayers(tokens24.extensions.tooltip.elevation, colors)
4748
+ boxShadow: shadowLayers(tokens25.extensions.tooltip.elevation, colors)
4621
4749
  },
4622
4750
  children
4623
4751
  }
@@ -4679,8 +4807,8 @@ function FloatingPanel({
4679
4807
  style: {
4680
4808
  opacity: anchored && sized ? motion.opacity : 0,
4681
4809
  transform: tooltip ? void 0 : [
4682
- { translateX: motion.progress.interpolate({ inputRange: [0, 1], outputRange: [placement === "left" ? tokens24.motionDistance.popup : placement === "right" ? -tokens24.motionDistance.popup : 0, 0] }) },
4683
- { translateY: motion.progress.interpolate({ inputRange: [0, 1], outputRange: [placement === "left" || placement === "right" ? 0 : above ? tokens24.motionDistance.popup : -tokens24.motionDistance.popup, 0] }) }
4810
+ { translateX: motion.progress.interpolate({ inputRange: [0, 1], outputRange: [placement === "left" ? tokens25.motionDistance.popup : placement === "right" ? -tokens25.motionDistance.popup : 0, 0] }) },
4811
+ { translateY: motion.progress.interpolate({ inputRange: [0, 1], outputRange: [placement === "left" || placement === "right" ? 0 : above ? tokens25.motionDistance.popup : -tokens25.motionDistance.popup, 0] }) }
4684
4812
  ],
4685
4813
  position: "absolute",
4686
4814
  top,
@@ -4689,11 +4817,11 @@ function FloatingPanel({
4689
4817
  minWidth: contentSizedMenu ? minimumPanelWidth : void 0,
4690
4818
  maxWidth: tooltip ? tooltipWidth : maximumWidth,
4691
4819
  maxHeight: available,
4692
- borderRadius: popover ? tokens24.extensions.popover.radius : field ? tokens24.radius.radius12 : tokens24.extensions.menu.radius,
4693
- borderWidth: popover ? 0 : tokens24.border.defaultWidth,
4820
+ borderRadius: popover ? tokens25.extensions.popover.radius : field ? tokens25.radius.radius12 : tokens25.extensions.menu.radius,
4821
+ borderWidth: popover ? 0 : tokens25.border.defaultWidth,
4694
4822
  borderColor: colors.border,
4695
4823
  backgroundColor: colors.surface,
4696
- boxShadow: (tooltip ? tokens24.extensions.tooltip.elevation : popover ? tokens24.extensions.popover.elevation : tokens24.extensions.menu.elevation).map(({ colorRole, ...layer2 }) => ({ ...layer2, color: colors[colorRole] })),
4824
+ boxShadow: (tooltip ? tokens25.extensions.tooltip.elevation : popover ? tokens25.extensions.popover.elevation : tokens25.extensions.menu.elevation).map(({ colorRole, ...layer2 }) => ({ ...layer2, color: colors[colorRole] })),
4697
4825
  overflow: "hidden"
4698
4826
  },
4699
4827
  children: [
@@ -4702,10 +4830,10 @@ function FloatingPanel({
4702
4830
  {
4703
4831
  onLayout: ({ nativeEvent: { layout } }) => setHeaderHeight(layout.height),
4704
4832
  style: {
4705
- paddingTop: tokens24.extensions.popover.padding,
4706
- paddingHorizontal: tokens24.extensions.popover.padding,
4707
- paddingBottom: tokens24.extensions.popover.headerPaddingBottom,
4708
- borderBottomWidth: tokens24.border.defaultWidth,
4833
+ paddingTop: tokens25.extensions.popover.padding,
4834
+ paddingHorizontal: tokens25.extensions.popover.padding,
4835
+ paddingBottom: tokens25.extensions.popover.headerPaddingBottom,
4836
+ borderBottomWidth: tokens25.border.defaultWidth,
4709
4837
  borderBottomColor: colors.divider
4710
4838
  },
4711
4839
  children: content(header, typeStyle("cardTitle"))
@@ -4720,7 +4848,7 @@ function FloatingPanel({
4720
4848
  },
4721
4849
  keyboardShouldPersistTaps: "handled",
4722
4850
  style: { maxHeight: available - (header != null ? headerHeight : 0), flexShrink: 1 },
4723
- contentContainerStyle: { padding: menu || field ? tokens24.extensions.menu.padding : 0 },
4851
+ contentContainerStyle: { padding: menu || field ? tokens25.extensions.menu.padding : 0 },
4724
4852
  onContentSizeChange: (width2, height2) => {
4725
4853
  if (contentSizedMenu) return;
4726
4854
  setSized(true);
@@ -4745,15 +4873,15 @@ function FloatingPanel({
4745
4873
  import {
4746
4874
  cloneElement as cloneElement4,
4747
4875
  isValidElement as isValidElement5,
4748
- useEffect as useEffect13,
4749
- useRef as useRef18,
4876
+ useEffect as useEffect14,
4877
+ useRef as useRef20,
4750
4878
  useState as useState18
4751
4879
  } from "react";
4752
4880
  import {
4753
4881
  Platform as Platform17,
4754
4882
  View as View21
4755
4883
  } from "react-native";
4756
- import { tokens as tokens25 } from "@kjun-ui/tokens";
4884
+ import { tokens as tokens26 } from "@kjun-ui/tokens";
4757
4885
  import { Fragment as Fragment7, jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
4758
4886
  function KjunPopover({
4759
4887
  noPadding = false,
@@ -4772,7 +4900,7 @@ function KjunPopover({
4772
4900
  children
4773
4901
  }) {
4774
4902
  const { colors } = useKjunStyles();
4775
- const [internal, setInternal] = useState18(false), open = controlled != null ? controlled : internal, ref = useRef18(null);
4903
+ const [internal, setInternal] = useState18(false), open = controlled != null ? controlled : internal, ref = useRef20(null);
4776
4904
  const change = (v) => {
4777
4905
  setInternal(v);
4778
4906
  onOpenChange == null ? void 0 : onOpenChange(v);
@@ -4802,7 +4930,7 @@ function KjunPopover({
4802
4930
  ariaLabel,
4803
4931
  header: header != null ? content(header, { ...typeStyle("cardTitle"), color: colors.text }) : void 0,
4804
4932
  nonModal: !modal,
4805
- children: /* @__PURE__ */ jsx27(View21, { style: { padding: noPadding ? 0 : tokens25.extensions.popover.padding, gap: noPadding ? 0 : tokens25.extensions.popover.gap }, children: content(
4933
+ children: /* @__PURE__ */ jsx27(View21, { style: { padding: noPadding ? 0 : tokens26.extensions.popover.padding, gap: noPadding ? 0 : tokens26.extensions.popover.gap }, children: content(
4806
4934
  typeof children === "function" ? children(() => change(false)) : children,
4807
4935
  Platform17.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : void 0
4808
4936
  ) })
@@ -4820,13 +4948,13 @@ function KjunTooltip({
4820
4948
  open: controlled,
4821
4949
  onOpenChange
4822
4950
  }) {
4823
- const { colors } = useKjunStyles(), [internal, setInternal] = useState18(false), open = controlled != null ? controlled : internal, latest = useRef18({ open, onOpenChange }), setOpen = (value) => {
4951
+ const { colors } = useKjunStyles(), [internal, setInternal] = useState18(false), open = controlled != null ? controlled : internal, latest = useRef20({ open, onOpenChange }), setOpen = (value) => {
4824
4952
  var _a, _b;
4825
4953
  if (latest.current.open === value) return;
4826
4954
  latest.current.open = value;
4827
4955
  setInternal(value);
4828
4956
  (_b = (_a = latest.current).onOpenChange) == null ? void 0 : _b.call(_a, value);
4829
- }, ref = useRef18(null), timer = useRef18(void 0);
4957
+ }, ref = useRef20(null), timer = useRef20(void 0);
4830
4958
  latest.current = { open, onOpenChange };
4831
4959
  const scopeActive = useActiveLayerScope();
4832
4960
  const hide = () => {
@@ -4838,11 +4966,11 @@ function KjunTooltip({
4838
4966
  clearTimeout(timer.current);
4839
4967
  timer.current = setTimeout(() => setOpen(true), delay);
4840
4968
  };
4841
- useEffect13(() => {
4969
+ useEffect14(() => {
4842
4970
  if (!scopeActive) hide();
4843
4971
  }, [scopeActive]);
4844
- useEffect13(() => () => clearTimeout(timer.current), []);
4845
- useEffect13(() => {
4972
+ useEffect14(() => () => clearTimeout(timer.current), []);
4973
+ useEffect14(() => {
4846
4974
  if (Platform17.OS !== "web" || !open) return;
4847
4975
  const escape = (event) => {
4848
4976
  if (event.key === "Escape") hide();
@@ -4909,9 +5037,9 @@ function KjunTooltip({
4909
5037
  View21,
4910
5038
  {
4911
5039
  style: {
4912
- paddingVertical: tokens25.extensions.tooltip.paddingY,
4913
- paddingHorizontal: tokens25.extensions.tooltip.paddingX,
4914
- maxWidth: tokens25.extensions.tooltip.maxWidth,
5040
+ paddingVertical: tokens26.extensions.tooltip.paddingY,
5041
+ paddingHorizontal: tokens26.extensions.tooltip.paddingX,
5042
+ maxWidth: tokens26.extensions.tooltip.maxWidth,
4915
5043
  backgroundColor: colors.chartTooltipBg
4916
5044
  },
4917
5045
  children: /* @__PURE__ */ jsx27(
@@ -4947,7 +5075,7 @@ function KjunDropdown({
4947
5075
  onClose
4948
5076
  }) {
4949
5077
  const m = useKjunMessages();
4950
- const [open, setOpen] = useState19(false), currentOpen = useRef19(false), ref = useRef19(null);
5078
+ const [open, setOpen] = useState19(false), currentOpen = useRef21(false), ref = useRef21(null);
4951
5079
  let control = trigger;
4952
5080
  while (isValidElement6(control) && control.type === KjunTooltip)
4953
5081
  control = control.props.children;
@@ -4959,7 +5087,7 @@ function KjunDropdown({
4959
5087
  if (v) onOpen == null ? void 0 : onOpen();
4960
5088
  else onClose == null ? void 0 : onClose();
4961
5089
  };
4962
- useEffect14(() => {
5090
+ useEffect15(() => {
4963
5091
  if (unavailable) change(false);
4964
5092
  }, [unavailable]);
4965
5093
  return /* @__PURE__ */ jsxs17(DropdownContext.Provider, { value: () => change(false), children: [
@@ -5014,18 +5142,18 @@ function KjunDropdownItem({
5014
5142
  style: ({ pressed }) => ({
5015
5143
  flexDirection: "row",
5016
5144
  alignItems: "center",
5017
- gap: tokens26.dimension.value8,
5018
- paddingVertical: tokens26.extensions.menu.optionPaddingY,
5019
- paddingHorizontal: tokens26.extensions.menu.optionPaddingX,
5020
- minHeight: tokens26.extensions.menu.optionHeight,
5021
- borderRadius: tokens26.extensions.menu.optionRadius,
5145
+ gap: tokens27.dimension.value8,
5146
+ paddingVertical: tokens27.extensions.menu.optionPaddingY,
5147
+ paddingHorizontal: tokens27.extensions.menu.optionPaddingX,
5148
+ minHeight: tokens27.extensions.menu.optionHeight,
5149
+ borderRadius: tokens27.extensions.menu.optionRadius,
5022
5150
  backgroundColor: selected ? colors.selectedBg : !disabled && (pressed || hovered) ? variant === "danger" ? colors.dangerBg : colors.hover : void 0,
5023
- opacity: disabled ? tokens26.states.opacity.disabled : 1
5151
+ opacity: disabled ? tokens27.states.opacity.disabled : 1
5024
5152
  }),
5025
5153
  children: [
5026
- icon ? /* @__PURE__ */ jsx28(KjunIcon, { name: icon, size: tokens26.extensions.menu.iconSize, color: iconColor }) : reserveIcon && /* @__PURE__ */ jsx28(View22, { style: { width: tokens26.extensions.menu.iconSize }, accessible: false }),
5027
- /* @__PURE__ */ jsx28(View22, { style: { flexGrow: 1, flexShrink: 1 }, children: content(children, { color, fontSize: tokens26.extensions.menu.optionFontSize, lineHeight: tokens26.extensions.menu.optionLineHeight }) }),
5028
- selected !== null && /* @__PURE__ */ jsx28(View22, { style: { opacity: selected ? 1 : 0 }, accessible: false, children: /* @__PURE__ */ jsx28(KjunIcon, { name: "check", size: tokens26.extensions.menu.iconSize, color: colors.brand }) })
5154
+ icon ? /* @__PURE__ */ jsx28(KjunIcon, { name: icon, size: tokens27.extensions.menu.iconSize, color: iconColor }) : reserveIcon && /* @__PURE__ */ jsx28(View22, { style: { width: tokens27.extensions.menu.iconSize }, accessible: false }),
5155
+ /* @__PURE__ */ jsx28(View22, { style: { flexGrow: 1, flexShrink: 1 }, children: content(children, { color, fontSize: tokens27.extensions.menu.optionFontSize, lineHeight: tokens27.extensions.menu.optionLineHeight }) }),
5156
+ selected !== null && /* @__PURE__ */ jsx28(View22, { style: { opacity: selected ? 1 : 0 }, accessible: false, children: /* @__PURE__ */ jsx28(KjunIcon, { name: "check", size: tokens27.extensions.menu.iconSize, color: colors.brand }) })
5029
5157
  ]
5030
5158
  }
5031
5159
  );
@@ -5036,7 +5164,7 @@ function KjunDropdownDivider() {
5036
5164
  View22,
5037
5165
  {
5038
5166
  role: "separator",
5039
- style: { height: tokens26.extensions.menu.dividerHeight, marginVertical: tokens26.dimension.value4, backgroundColor: colors.border }
5167
+ style: { height: tokens27.extensions.menu.dividerHeight, marginVertical: tokens27.dimension.value4, backgroundColor: colors.border }
5040
5168
  }
5041
5169
  );
5042
5170
  }
@@ -5095,7 +5223,7 @@ function KjunMenuButton({
5095
5223
  }
5096
5224
 
5097
5225
  // shared/package-runtime/combobox.ts
5098
- import { useEffect as useEffect15, useState as useState20 } from "react";
5226
+ import { useEffect as useEffect16, useState as useState20 } from "react";
5099
5227
 
5100
5228
  // shared/package-runtime/options.ts
5101
5229
  var optionValue = (option, key = "value") => typeof option === "object" ? option[key] : option;
@@ -5175,8 +5303,8 @@ function useComboboxModel({
5175
5303
  const selectedLabel = selected !== void 0 ? optionLabel(selected, labelKey) : "";
5176
5304
  const [query, setQuery] = useState20(selectedLabel);
5177
5305
  const [open, setOpen] = useState20(false);
5178
- useEffect15(() => setQuery(selectedLabel), [value, selectedLabel]);
5179
- useEffect15(() => {
5306
+ useEffect16(() => setQuery(selectedLabel), [value, selectedLabel]);
5307
+ useEffect16(() => {
5180
5308
  if (disabled) setOpen(false);
5181
5309
  }, [disabled]);
5182
5310
  const change = (next) => {
@@ -5209,12 +5337,12 @@ function useComboboxModel({
5209
5337
  }
5210
5338
 
5211
5339
  // packages/native/src/combobox.tsx
5212
- import { tokens as tokens28 } from "@kjun-ui/tokens";
5213
- import { useId as useId5, useRef as useRef20 } from "react";
5340
+ import { tokens as tokens29 } from "@kjun-ui/tokens";
5341
+ import { useId as useId5, useRef as useRef22 } from "react";
5214
5342
  import { Platform as Platform18, View as View24 } from "react-native";
5215
5343
 
5216
5344
  // packages/native/src/select-options.tsx
5217
- import { tokens as tokens27 } from "@kjun-ui/tokens";
5345
+ import { tokens as tokens28 } from "@kjun-ui/tokens";
5218
5346
  import { View as View23 } from "react-native";
5219
5347
  import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
5220
5348
  function OptionRow({
@@ -5237,20 +5365,20 @@ function OptionRow({
5237
5365
  onPress,
5238
5366
  onLayout,
5239
5367
  style: ({ pressed }) => ({
5240
- borderRadius: tokens27.radius.radius8,
5241
- minHeight: tokens27.extensions.menu.optionHeight,
5368
+ borderRadius: tokens28.radius.radius8,
5369
+ minHeight: tokens28.extensions.menu.optionHeight,
5242
5370
  flexDirection: "row",
5243
5371
  alignItems: "center",
5244
5372
  justifyContent: "space-between",
5245
- gap: tokens27.dimension.value8,
5246
- paddingVertical: tokens27.extensions.menu.optionPaddingY,
5247
- paddingHorizontal: tokens27.extensions.menu.optionPaddingX,
5373
+ gap: tokens28.dimension.value8,
5374
+ paddingVertical: tokens28.extensions.menu.optionPaddingY,
5375
+ paddingHorizontal: tokens28.extensions.menu.optionPaddingX,
5248
5376
  backgroundColor: selected ? colors.selectedBg : pressed ? colors.hover : void 0,
5249
- opacity: disabled ? tokens27.states.opacity.disabled : 1
5377
+ opacity: disabled ? tokens28.states.opacity.disabled : 1
5250
5378
  }),
5251
5379
  children: [
5252
- /* @__PURE__ */ jsx29(View23, { style: { flex: 1 }, children: content(children || label, { fontSize: tokens27.extensions.menu.optionFontSize, lineHeight: tokens27.extensions.menu.optionLineHeight }) }),
5253
- selected && /* @__PURE__ */ jsx29(KjunIcon, { name: "check", size: tokens27.extensions.menu.iconSize, color: colors.brand })
5380
+ /* @__PURE__ */ jsx29(View23, { style: { flex: 1 }, children: content(children || label, { fontSize: tokens28.extensions.menu.optionFontSize, lineHeight: tokens28.extensions.menu.optionLineHeight }) }),
5381
+ selected && /* @__PURE__ */ jsx29(KjunIcon, { name: "check", size: tokens28.extensions.menu.iconSize, color: colors.brand })
5254
5382
  ]
5255
5383
  }
5256
5384
  );
@@ -5340,8 +5468,8 @@ function SearchField({
5340
5468
  }) {
5341
5469
  const m = useKjunMessages();
5342
5470
  const searchId = "kjun-popup-search-" + useId5().replace(/:/g, "");
5343
- const clearing = useRef20(false);
5344
- const ref = useRef20(null), { colors } = useKjunStyles();
5471
+ const clearing = useRef22(false);
5472
+ const ref = useRef22(null), { colors } = useKjunStyles();
5345
5473
  const focusGuard = usePopupFocusGuard(ref);
5346
5474
  const openFromPress = () => {
5347
5475
  if (!disabled) {
@@ -5388,8 +5516,8 @@ function SearchField({
5388
5516
  View24,
5389
5517
  {
5390
5518
  style: {
5391
- padding: tokens28.dimension.value8,
5392
- borderBottomWidth: tokens28.border.defaultWidth,
5519
+ padding: tokens29.dimension.value8,
5520
+ borderBottomWidth: tokens29.border.defaultWidth,
5393
5521
  borderBottomColor: colors.border
5394
5522
  },
5395
5523
  children: /* @__PURE__ */ jsx30(KjunInput, { ...inputProps, nativeID: searchId, autoFocus: true })
@@ -5397,13 +5525,13 @@ function SearchField({
5397
5525
  ),
5398
5526
  loading ? (
5399
5527
  // Centered like the Select loading row on every platform.
5400
- /* @__PURE__ */ jsx30(View24, { style: { padding: tokens28.dimension.value12, alignItems: "center" }, children: /* @__PURE__ */ jsx30(KjunSpinner, { size: "sm", text: m.searching }) })
5528
+ /* @__PURE__ */ jsx30(View24, { style: { padding: tokens29.dimension.value12, alignItems: "center" }, children: /* @__PURE__ */ jsx30(KjunSpinner, { size: "sm", text: m.searching }) })
5401
5529
  ) : failed ? /* @__PURE__ */ jsx30(
5402
5530
  KText,
5403
5531
  {
5404
5532
  accessibilityRole: "alert",
5405
5533
  style: {
5406
- padding: tokens28.dimension.value12,
5534
+ padding: tokens29.dimension.value12,
5407
5535
  textAlign: "center",
5408
5536
  color: colors.danger
5409
5537
  },
@@ -5426,7 +5554,7 @@ function SearchField({
5426
5554
  KText,
5427
5555
  {
5428
5556
  style: {
5429
- padding: tokens28.dimension.value12,
5557
+ padding: tokens29.dimension.value12,
5430
5558
  textAlign: "center",
5431
5559
  color: colors.textTertiary
5432
5560
  },
@@ -5440,8 +5568,8 @@ function SearchField({
5440
5568
  }
5441
5569
 
5442
5570
  // packages/native/src/date-picker.tsx
5443
- import { tokens as tokens29 } from "@kjun-ui/tokens";
5444
- import { useRef as useRef21, useState as useState21 } from "react";
5571
+ import { tokens as tokens30 } from "@kjun-ui/tokens";
5572
+ import { useRef as useRef23, useState as useState21 } from "react";
5445
5573
  import { Platform as Platform19, View as View25 } from "react-native";
5446
5574
  import { Fragment as Fragment10, jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
5447
5575
  function displayMonth(value) {
@@ -5464,7 +5592,7 @@ function KjunDatePicker({
5464
5592
  const scope = useKjunMessageScope();
5465
5593
  placeholder != null ? placeholder : placeholder = scope.messages.datePlaceholder;
5466
5594
  const clear = clearable && !!value && !disabled;
5467
- const { colors } = useKjunStyles(), field = useKjunField(), [open, setOpen] = useState21(false), [month, setMonth] = useState21(() => displayMonth(value)), ref = useRef21(null), spec = tokens29.input[size];
5595
+ const { colors } = useKjunStyles(), field = useKjunField(), [open, setOpen] = useState21(false), [month, setMonth] = useState21(() => displayMonth(value)), ref = useRef23(null), spec = tokens30.input[size];
5468
5596
  const surface = useFieldSurface(size, { disabled, invalid: error || !!(field == null ? void 0 : field.error), open });
5469
5597
  const year = month.getFullYear(), m = month.getMonth(), first = new Date(year, m, 1).getDay(), count = new Date(year, m + 1, 0).getDate();
5470
5598
  const date = (day) => `${year}-${String(m + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
@@ -5472,7 +5600,7 @@ function KjunDatePicker({
5472
5600
  /* @__PURE__ */ jsxs20(View25, { ref, collapsable: false, ...fieldTarget(() => {
5473
5601
  setMonth(displayMonth(value));
5474
5602
  setOpen(true);
5475
- }, disabled), style: { minHeight: tokens29.native.minimumTouchTarget, justifyContent: "center" }, children: [
5603
+ }, disabled), style: { minHeight: tokens30.native.minimumTouchTarget, justifyContent: "center" }, children: [
5476
5604
  /* @__PURE__ */ jsxs20(
5477
5605
  FieldPressable,
5478
5606
  {
@@ -5498,7 +5626,7 @@ function KjunDatePicker({
5498
5626
  },
5499
5627
  style: {
5500
5628
  ...surface.style,
5501
- paddingHorizontal: spec.padding - tokens29.border.controlWidth,
5629
+ paddingHorizontal: spec.padding - tokens30.border.controlWidth,
5502
5630
  flexDirection: "row",
5503
5631
  alignItems: "center",
5504
5632
  justifyContent: "space-between"
@@ -5541,9 +5669,9 @@ function KjunDatePicker({
5541
5669
  triggerRef: ref,
5542
5670
  placement: "bottom-start",
5543
5671
  matchTriggerWidth: true,
5544
- minimumWidth: tokens29.extensions.calendar.minimumWidth,
5672
+ minimumWidth: tokens30.extensions.calendar.minimumWidth,
5545
5673
  ariaLabel: scope.messages.datePlaceholder,
5546
- children: /* @__PURE__ */ jsxs20(View25, { style: { padding: tokens29.dimension.value8 }, children: [
5674
+ children: /* @__PURE__ */ jsxs20(View25, { style: { padding: tokens30.dimension.value8 }, children: [
5547
5675
  /* @__PURE__ */ jsxs20(
5548
5676
  View25,
5549
5677
  {
@@ -5584,7 +5712,7 @@ function KjunDatePicker({
5584
5712
  style: {
5585
5713
  width: "14.2857%",
5586
5714
  textAlign: "center",
5587
- paddingVertical: tokens29.dimension.value8,
5715
+ paddingVertical: tokens30.dimension.value8,
5588
5716
  color: colors.textTertiary
5589
5717
  },
5590
5718
  children: day
@@ -5611,12 +5739,12 @@ function KjunDatePicker({
5611
5739
  },
5612
5740
  style: {
5613
5741
  width: "14.2857%",
5614
- minHeight: tokens29.native.minimumTouchTarget,
5742
+ minHeight: tokens30.native.minimumTouchTarget,
5615
5743
  alignItems: "center",
5616
5744
  justifyContent: "center",
5617
- borderRadius: tokens29.radius.radius6,
5745
+ borderRadius: tokens30.radius.radius6,
5618
5746
  backgroundColor: v === value ? colors.brand : void 0,
5619
- opacity: blocked ? tokens29.states.opacity.disabledStrong : 1
5747
+ opacity: blocked ? tokens30.states.opacity.disabledStrong : 1
5620
5748
  },
5621
5749
  children: /* @__PURE__ */ jsx31(
5622
5750
  KText,
@@ -5642,7 +5770,7 @@ function KjunDatePicker({
5642
5770
  import { useState as useState23 } from "react";
5643
5771
 
5644
5772
  // shared/package-runtime/search-input.ts
5645
- import { useEffect as useEffect16, useLayoutEffect as useLayoutEffect12, useRef as useRef22, useState as useState22 } from "react";
5773
+ import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect12, useRef as useRef24, useState as useState22 } from "react";
5646
5774
  function useSearchInputModel({
5647
5775
  value,
5648
5776
  disabled = false,
@@ -5652,10 +5780,10 @@ function useSearchInputModel({
5652
5780
  onValueChange,
5653
5781
  onSearchError
5654
5782
  }, open) {
5655
- const [query, setQuery] = useState22(value), [options, setOptions] = useState22([]), [loading, setLoading] = useState22(false), [failed, setFailed] = useState22(false), version = useRef22(0), notify = useRef22(onSearchError);
5783
+ const [query, setQuery] = useState22(value), [options, setOptions] = useState22([]), [loading, setLoading] = useState22(false), [failed, setFailed] = useState22(false), version = useRef24(0), notify = useRef24(onSearchError);
5656
5784
  notify.current = onSearchError;
5657
- const timer = useRef22(void 0);
5658
- const notifyValue = useRef22(onValueChange);
5785
+ const timer = useRef24(void 0);
5786
+ const notifyValue = useRef24(onValueChange);
5659
5787
  notifyValue.current = onValueChange;
5660
5788
  useLayoutEffect12(() => {
5661
5789
  clearTimeout(timer.current);
@@ -5665,7 +5793,7 @@ function useSearchInputModel({
5665
5793
  clearTimeout(timer.current);
5666
5794
  return () => clearTimeout(timer.current);
5667
5795
  }, [disabled, debounce, !!loadOptions]);
5668
- useEffect16(() => {
5796
+ useEffect17(() => {
5669
5797
  const current = ++version.current, abort = new AbortController();
5670
5798
  setFailed(false);
5671
5799
  if (!loadOptions || !open || disabled || query.length < minChars) {
@@ -5817,22 +5945,22 @@ function KjunSearchInput({
5817
5945
  }
5818
5946
 
5819
5947
  // packages/native/src/select-control.tsx
5820
- import { tokens as tokens31 } from "@kjun-ui/tokens";
5821
- import { useContext as useContext14, useEffect as useEffect18, useRef as useRef24 } from "react";
5948
+ import { tokens as tokens32 } from "@kjun-ui/tokens";
5949
+ import { useContext as useContext14, useEffect as useEffect19, useRef as useRef26 } from "react";
5822
5950
 
5823
5951
  // packages/native/src/compound-control.tsx
5824
5952
  import { createContext as createContext18 } from "react";
5825
5953
  import { View as View26 } from "react-native";
5826
- import { tokens as tokens30 } from "@kjun-ui/tokens";
5954
+ import { tokens as tokens31 } from "@kjun-ui/tokens";
5827
5955
  import { jsx as jsx33 } from "react/jsx-runtime";
5828
5956
  var CompoundControlContext = createContext18(null);
5829
5957
  function CompoundTarget({ children, square = false }) {
5830
- const touch = finePointer() ? void 0 : tokens30.native.minimumTouchTarget;
5958
+ const touch = finePointer() ? void 0 : tokens31.native.minimumTouchTarget;
5831
5959
  return /* @__PURE__ */ jsx33(View26, { style: { minHeight: touch, minWidth: square ? touch : void 0, alignItems: "center", justifyContent: "center" }, children });
5832
5960
  }
5833
5961
 
5834
5962
  // shared/package-runtime/select.ts
5835
- import { useEffect as useEffect17, useRef as useRef23, useState as useState24 } from "react";
5963
+ import { useEffect as useEffect18, useRef as useRef25, useState as useState24 } from "react";
5836
5964
  function useSelectState(controlled, disabled, pageSize, onOpenChange) {
5837
5965
  const [internal, setInternal] = useState24(false);
5838
5966
  const [query, setQuery] = useState24("");
@@ -5840,8 +5968,8 @@ function useSelectState(controlled, disabled, pageSize, onOpenChange) {
5840
5968
  const [session, setSession] = useState24(0);
5841
5969
  const isControlled = typeof controlled === "boolean";
5842
5970
  const open = !disabled && (isControlled ? controlled : internal);
5843
- const previousOpen = useRef23(open);
5844
- useEffect17(() => {
5971
+ const previousOpen = useRef25(open);
5972
+ useEffect18(() => {
5845
5973
  if (disabled && !isControlled) setInternal(false);
5846
5974
  if (previousOpen.current && !open) {
5847
5975
  setQuery("");
@@ -5850,7 +5978,7 @@ function useSelectState(controlled, disabled, pageSize, onOpenChange) {
5850
5978
  }
5851
5979
  previousOpen.current = open;
5852
5980
  }, [open, disabled, isControlled, pageSize]);
5853
- useEffect17(() => {
5981
+ useEffect18(() => {
5854
5982
  setLimit(pageSize);
5855
5983
  }, [pageSize]);
5856
5984
  const changeOpen = (next) => {
@@ -5900,14 +6028,14 @@ function KjunSelect({
5900
6028
  placeholder != null ? placeholder : placeholder = m.select;
5901
6029
  searchPlaceholder != null ? searchPlaceholder : searchPlaceholder = m.search;
5902
6030
  const { open, query, limit, changeOpen, search, showMore } = useSelectState(controlled, disabled, optionPageSize, onOpenChange);
5903
- const { colors } = useKjunStyles(), field = useKjunField(), ref = useRef24(null), spec = tokens31.input[size];
5904
- const trigger = useRef24(null);
6031
+ const { colors } = useKjunStyles(), field = useKjunField(), ref = useRef26(null), spec = tokens32.input[size];
6032
+ const trigger = useRef26(null);
5905
6033
  const compound = useContext14(CompoundControlContext);
5906
- useEffect18(() => {
6034
+ useEffect19(() => {
5907
6035
  if (compound == null ? void 0 : compound.focusRef) compound.focusRef.current = trigger.current;
5908
6036
  }, [compound == null ? void 0 : compound.focusRef]);
5909
6037
  const expanded = usePopupExpanded(open, ref);
5910
- const selectedRow = useRef24(null);
6038
+ const selectedRow = useRef26(null);
5911
6039
  const surface = useFieldSurface(size, { disabled, invalid: error || !!(field == null ? void 0 : field.error), open: expanded });
5912
6040
  const change = (v) => {
5913
6041
  onValueChange == null ? void 0 : onValueChange(v);
@@ -5932,10 +6060,10 @@ function KjunSelect({
5932
6060
  return /* @__PURE__ */ jsxs21(Fragment11, { children: [
5933
6061
  /* @__PURE__ */ jsxs21(View27, { ref, collapsable: false, ...fieldTarget(() => changeOpen(!open), disabled), style: {
5934
6062
  position: "relative",
5935
- minHeight: tokens31.native.minimumTouchTarget,
6063
+ minHeight: tokens32.native.minimumTouchTarget,
5936
6064
  justifyContent: "center",
5937
6065
  // Inside a compound field the touch target overflows so the shared surface keeps its size height.
5938
- ...compound ? { marginVertical: Math.min(0, (spec.height - tokens31.native.minimumTouchTarget) / 2) } : {}
6066
+ ...compound ? { marginVertical: Math.min(0, (spec.height - tokens32.native.minimumTouchTarget) / 2) } : {}
5939
6067
  }, children: [
5940
6068
  /* @__PURE__ */ jsxs21(
5941
6069
  FieldPressable,
@@ -5971,14 +6099,14 @@ function KjunSelect({
5971
6099
  flexDirection: "row",
5972
6100
  alignItems: "center",
5973
6101
  justifyContent: "space-between",
5974
- gap: tokens31.dimension.value8,
6102
+ gap: tokens32.dimension.value8,
5975
6103
  ...surface.style,
5976
- paddingHorizontal: spec.padding - tokens31.border.controlWidth,
5977
- paddingRight: spec.padding - tokens31.border.controlWidth,
5978
- ...compound ? { paddingHorizontal: tokens31.extensions.timePicker.segmentPadding, paddingRight: tokens31.extensions.timePicker.segmentPadding, paddingLeft: compound.leading ? spec.padding - tokens31.border.controlWidth : tokens31.extensions.timePicker.segmentPadding, gap: tokens31.extensions.timePicker.segmentPadding, backgroundColor: !disabled && (surface.active || surface.hovered) ? colors.hover : "transparent", borderColor: "transparent", outlineWidth: 0 } : {}
6104
+ paddingHorizontal: spec.padding - tokens32.border.controlWidth,
6105
+ paddingRight: spec.padding - tokens32.border.controlWidth,
6106
+ ...compound ? { paddingHorizontal: tokens32.extensions.timePicker.segmentPadding, paddingRight: tokens32.extensions.timePicker.segmentPadding, paddingLeft: compound.leading ? spec.padding - tokens32.border.controlWidth : tokens32.extensions.timePicker.segmentPadding, gap: tokens32.extensions.timePicker.segmentPadding, backgroundColor: !disabled && (surface.active || surface.hovered) ? colors.hover : "transparent", borderColor: "transparent", outlineWidth: 0 } : {}
5979
6107
  },
5980
6108
  children: [
5981
- /* @__PURE__ */ jsxs21(View27, { style: { ...compound ? { flexGrow: 1, flexShrink: 0 } : { flex: 1, minWidth: 0 }, paddingRight: clearable && label ? tokens31.native.minimumTouchTarget + spec.affixGap : 0 }, children: [
6109
+ /* @__PURE__ */ jsxs21(View27, { style: { ...compound ? { flexGrow: 1, flexShrink: 0 } : { flex: 1, minWidth: 0 }, paddingRight: clearable && label ? tokens32.native.minimumTouchTarget + spec.affixGap : 0 }, children: [
5982
6110
  compound && /* @__PURE__ */ jsx34(KText, { "aria-hidden": true, importantForAccessibility: "no-hide-descendants", style: { ...inputTypeStyle(size), fontVariant: ["tabular-nums"], opacity: 0 }, children: "00" }),
5983
6111
  (renderSelected == null ? void 0 : renderSelected(selectedOption)) || /* @__PURE__ */ jsx34(KText, { numberOfLines: 1, style: {
5984
6112
  ...inputTypeStyle(size),
@@ -5990,7 +6118,7 @@ function KjunSelect({
5990
6118
  KjunIcon,
5991
6119
  {
5992
6120
  name: "chevron-down",
5993
- size: compound ? tokens31.extensions.timePicker.iconSize : spec.iconSize,
6121
+ size: compound ? tokens32.extensions.timePicker.iconSize : spec.iconSize,
5994
6122
  color: surface.icon
5995
6123
  }
5996
6124
  ) })
@@ -6034,8 +6162,8 @@ function KjunSelect({
6034
6162
  View27,
6035
6163
  {
6036
6164
  style: {
6037
- padding: tokens31.dimension.value8,
6038
- borderBottomWidth: tokens31.border.defaultWidth,
6165
+ padding: tokens32.dimension.value8,
6166
+ borderBottomWidth: tokens32.border.defaultWidth,
6039
6167
  borderBottomColor: colors.border
6040
6168
  },
6041
6169
  children: /* @__PURE__ */ jsx34(
@@ -6055,7 +6183,7 @@ function KjunSelect({
6055
6183
  )
6056
6184
  }
6057
6185
  ),
6058
- loading ? /* @__PURE__ */ jsx34(View27, { style: { padding: tokens31.dimension.value12 }, children: /* @__PURE__ */ jsx34(KjunSpinner, { size: "sm", text: m.searching }) }) : visible.map(({ option: o, key }, index) => /* @__PURE__ */ jsx34(
6186
+ loading ? /* @__PURE__ */ jsx34(View27, { style: { padding: tokens32.dimension.value12 }, children: /* @__PURE__ */ jsx34(KjunSpinner, { size: "sm", text: m.searching }) }) : visible.map(({ option: o, key }, index) => /* @__PURE__ */ jsx34(
6059
6187
  OptionRow,
6060
6188
  {
6061
6189
  selected: selected(o),
@@ -6077,7 +6205,7 @@ function KjunSelect({
6077
6205
  KText,
6078
6206
  {
6079
6207
  style: {
6080
- padding: tokens31.dimension.value12,
6208
+ padding: tokens32.dimension.value12,
6081
6209
  textAlign: "center",
6082
6210
  color: colors.textTertiary
6083
6211
  },
@@ -6101,19 +6229,20 @@ function KjunSelect({
6101
6229
  }
6102
6230
 
6103
6231
  // packages/native/src/navigation.tsx
6104
- import { tokens as tokens34 } from "@kjun-ui/tokens";
6232
+ import { tokens as tokens35 } from "@kjun-ui/tokens";
6105
6233
 
6106
6234
  // packages/native/src/collapse.tsx
6107
- import { tokens as tokens32 } from "@kjun-ui/tokens";
6108
- import { useLayoutEffect as useLayoutEffect13, useRef as useRef25, useState as useState25 } from "react";
6235
+ import { tokens as tokens33 } from "@kjun-ui/tokens";
6236
+ import { useLayoutEffect as useLayoutEffect13, useRef as useRef27, useState as useState25 } from "react";
6109
6237
  import { Animated as Animated14, View as View28 } from "react-native";
6110
6238
  import { jsx as jsx35 } from "react/jsx-runtime";
6111
- function Collapse({ open, children }) {
6239
+ function Collapse({ open, keepMounted = false, children }) {
6112
6240
  const reduced = useReducedMotion();
6113
6241
  const [retained, setRetained] = useState25(open), [height, setHeight] = useState25(null);
6114
- const value = useRef25(new Animated14.Value(0)).current;
6242
+ const value = useRef27(new Animated14.Value(0)).current;
6115
6243
  const [settled, setSettled] = useState25(open);
6116
- const version = useRef25(0), first = useRef25(open);
6244
+ const version = useRef27(0), first = useRef27(open), opened = useRef27(open);
6245
+ if (open) opened.current = true;
6117
6246
  useLayoutEffect13(() => {
6118
6247
  const revision = ++version.current;
6119
6248
  if (open) setRetained(true);
@@ -6131,7 +6260,7 @@ function Collapse({ open, children }) {
6131
6260
  finish();
6132
6261
  } else {
6133
6262
  setSettled(false);
6134
- Animated14.timing(value, { toValue: target, duration: tokens32.motion.collapse, easing: motionOut, useNativeDriver: false }).start(({ finished }) => {
6263
+ Animated14.timing(value, { toValue: target, duration: tokens33.motion.collapse, easing: motionOut, useNativeDriver: false }).start(({ finished }) => {
6135
6264
  if (finished) finish();
6136
6265
  });
6137
6266
  }
@@ -6141,13 +6270,13 @@ function Collapse({ open, children }) {
6141
6270
  value.stopAnimation();
6142
6271
  };
6143
6272
  }, [open, height, reduced, value]);
6144
- return open || retained ? /* @__PURE__ */ jsx35(
6273
+ return open || retained || keepMounted && opened.current ? /* @__PURE__ */ jsx35(
6145
6274
  Animated14.View,
6146
6275
  {
6147
6276
  pointerEvents: open ? "auto" : "none",
6148
6277
  accessibilityElementsHidden: !open,
6149
6278
  importantForAccessibility: open ? "auto" : "no-hide-descendants",
6150
- ...!open ? { inert: true } : {},
6279
+ ...!open ? { inert: true, "aria-hidden": true } : {},
6151
6280
  style: { height: settled && open ? void 0 : value, overflow: "hidden" },
6152
6281
  children: /* @__PURE__ */ jsx35(View28, { onLayout: (event) => setHeight(event.nativeEvent.layout.height), children })
6153
6282
  }
@@ -6155,10 +6284,10 @@ function Collapse({ open, children }) {
6155
6284
  }
6156
6285
 
6157
6286
  // shared/package-runtime/navigation.ts
6158
- import { useEffect as useEffect19, useRef as useRef26, useState as useState26 } from "react";
6287
+ import { useEffect as useEffect20, useRef as useRef28, useState as useState26 } from "react";
6159
6288
  function useInitialTab(value, candidate, change) {
6160
- const requested = useRef26(/* @__PURE__ */ new Set());
6161
- useEffect19(() => {
6289
+ const requested = useRef28(/* @__PURE__ */ new Set());
6290
+ useEffect20(() => {
6162
6291
  if (value !== "") {
6163
6292
  requested.current.clear();
6164
6293
  return;
@@ -6170,7 +6299,7 @@ function useInitialTab(value, candidate, change) {
6170
6299
  }
6171
6300
  function useAccordionState(multiple) {
6172
6301
  const [opened, setOpened] = useState26(/* @__PURE__ */ new Set());
6173
- useEffect19(() => {
6302
+ useEffect20(() => {
6174
6303
  if (!multiple) setOpened((previous) => previous.size > 1 ? new Set([...previous].slice(-1)) : previous);
6175
6304
  }, [multiple]);
6176
6305
  return {
@@ -6198,19 +6327,20 @@ import {
6198
6327
  Fragment as Fragment12,
6199
6328
  createContext as createContext20,
6200
6329
  useContext as useContext16,
6201
- useEffect as useEffect20,
6330
+ useEffect as useEffect21,
6202
6331
  useId as useId7,
6332
+ useRef as useRef31,
6203
6333
  useState as useState28
6204
6334
  } from "react";
6205
6335
  import { Animated as Animated16, View as View30, useWindowDimensions as useWindowDimensions5, Platform as Platform22 } from "react-native";
6206
6336
 
6207
6337
  // packages/native/src/tabs.tsx
6208
- import { tokens as tokens33 } from "@kjun-ui/tokens";
6209
- import { Children as Children4, createContext as createContext19, isValidElement as isValidElement7, useContext as useContext15, useCallback as useCallback5, useLayoutEffect as useLayoutEffect15, useRef as useRef28, useId as useId6, useState as useState27 } from "react";
6338
+ import { tokens as tokens34 } from "@kjun-ui/tokens";
6339
+ import { Children as Children4, createContext as createContext19, isValidElement as isValidElement7, useContext as useContext15, useCallback as useCallback6, useLayoutEffect as useLayoutEffect15, useRef as useRef30, useId as useId6, useState as useState27 } from "react";
6210
6340
  import { Animated as Animated15, Platform as Platform21, ScrollView as ScrollView5, View as View29 } from "react-native";
6211
6341
 
6212
6342
  // packages/native/src/tabs-accessibility.web.ts
6213
- import { useLayoutEffect as useLayoutEffect14, useRef as useRef27 } from "react";
6343
+ import { useLayoutEffect as useLayoutEffect14, useRef as useRef29 } from "react";
6214
6344
 
6215
6345
  // shared/package-runtime/tab-keyboard.ts
6216
6346
  function manageTabList(list, select, keyboard = true) {
@@ -6293,7 +6423,7 @@ function panelNeedsFocus(panel) {
6293
6423
 
6294
6424
  // packages/native/src/tabs-accessibility.web.ts
6295
6425
  function useTabKeyboard(root, select) {
6296
- const callback = useRef27(select);
6426
+ const callback = useRef29(select);
6297
6427
  callback.current = select;
6298
6428
  useLayoutEffect14(() => {
6299
6429
  var _a;
@@ -6330,29 +6460,29 @@ function KjunTabs({
6330
6460
  isValidElement7
6331
6461
  );
6332
6462
  const tabs = items2.length ? items2 : panes.filter((child) => child.type === KjunTabPane).map((child) => child.props);
6333
- const id = "kjun-" + useId6(), root = useRef28(null);
6334
- const menuState = useRef28({ tabs, onTabMenu });
6463
+ const id = "kjun-" + useId6(), root = useRef30(null);
6464
+ const menuState = useRef30({ tabs, onTabMenu });
6335
6465
  menuState.current = { tabs, onTabMenu };
6336
- const pressedMenu = useRef28(null);
6466
+ const pressedMenu = useRef30(null);
6337
6467
  useLayoutEffect15(() => {
6338
6468
  if (!onTabMenu || !tabs.some((tab) => tab.name === pressedMenu.current && !tab.disabled)) pressedMenu.current = null;
6339
6469
  }, [tabs, onTabMenu]);
6340
6470
  const panelNames = panes.filter((child) => child.type === KjunTabPane).map((child) => child.props.name);
6341
- const geometry2 = tokens33.extensions.tabs;
6471
+ const geometry2 = tokens34.extensions.tabs;
6342
6472
  const underline = variant === "underline";
6343
6473
  const [hoveredTab, setHoveredTab] = useState27(null);
6344
6474
  const singleLine = Platform21.OS === "web" ? { whiteSpace: "nowrap" } : {};
6345
6475
  const paddingX = !underline ? geometry2.pillsPaddingX : density === "compact" ? geometry2.compactPaddingX : geometry2.paddingX;
6346
6476
  const height = density === "compact" ? geometry2.compactHeight : geometry2.height;
6347
- const ringRoom = tokens33.states.focus.width + tokens33.states.focus.offset;
6348
- const slop = Math.max(0, (tokens33.native.minimumTouchTarget - height) / 2);
6477
+ const ringRoom = tokens34.states.focus.width + tokens34.states.focus.offset;
6478
+ const slop = Math.max(0, (tokens34.native.minimumTouchTarget - height) / 2);
6349
6479
  const roomX = underline ? ringRoom : 0, roomY = Math.max(underline ? ringRoom : 0, slop);
6350
6480
  const selectedTab = tabs.find((tab) => tab.name === value);
6351
6481
  const selection = useButtonGroupMotion(selectedTab ? { ...selectedTab, value: selectedTab.name } : void 0);
6352
- const tabRefs = useRef28(/* @__PURE__ */ new Map());
6482
+ const tabRefs = useRef30(/* @__PURE__ */ new Map());
6353
6483
  const { updateLayout } = selection;
6354
6484
  const firstName = (_a = tabs[0]) == null ? void 0 : _a.name;
6355
- const measureIndicator = useCallback5((name, box) => {
6485
+ const measureIndicator = useCallback6((name, box) => {
6356
6486
  const left = underline && name === firstName ? 0 : paddingX;
6357
6487
  updateLayout(name, underline ? {
6358
6488
  x: box.x + left,
@@ -6404,7 +6534,7 @@ function KjunTabs({
6404
6534
  transform: [{ translateX: selection.x }],
6405
6535
  borderRadius: underline ? geometry2.indicatorHeight / 2 : geometry2.radius,
6406
6536
  backgroundColor: variant === "underline" ? colors.brand : colors.active,
6407
- opacity: (selectedTab == null ? void 0 : selectedTab.disabled) ? tokens33.states.opacity.disabled : 1
6537
+ opacity: (selectedTab == null ? void 0 : selectedTab.disabled) ? tokens34.states.opacity.disabled : 1
6408
6538
  }
6409
6539
  }
6410
6540
  ),
@@ -6464,7 +6594,7 @@ function KjunTabs({
6464
6594
  borderRadius: geometry2.radius,
6465
6595
  // Pills answer hover with the hover surface, like ButtonGroup and Web.
6466
6596
  backgroundColor: !underline && !active && !tab.disabled && hoveredTab === tab.name ? colors.hover : void 0,
6467
- opacity: tab.disabled ? tokens33.states.opacity.disabled : 1
6597
+ opacity: tab.disabled ? tokens34.states.opacity.disabled : 1
6468
6598
  },
6469
6599
  children: [
6470
6600
  !!tab.icon && /* @__PURE__ */ jsx36(
@@ -6521,7 +6651,7 @@ function KjunTabs({
6521
6651
  }
6522
6652
  function KjunTabPane({ name, children }) {
6523
6653
  const { value, id, names } = useContext15(TabContext);
6524
- const root = useRef28(null);
6654
+ const root = useRef30(null);
6525
6655
  usePanelFocus(root);
6526
6656
  const hidden = value !== name;
6527
6657
  return /* @__PURE__ */ jsx36(
@@ -6559,7 +6689,7 @@ function KjunAccordion({
6559
6689
  View30,
6560
6690
  {
6561
6691
  style: {
6562
- borderRadius: tokens34.extensions.accordion.radius,
6692
+ borderRadius: tokens35.extensions.accordion.radius,
6563
6693
  overflow: "hidden",
6564
6694
  backgroundColor: tone === "muted" ? colors.secondary : colors.surface
6565
6695
  },
@@ -6574,14 +6704,32 @@ function KjunAccordionItem({
6574
6704
  defaultOpen = false,
6575
6705
  disabled = false,
6576
6706
  header,
6707
+ open: openProp,
6708
+ onOpenChange,
6709
+ keepMounted = false,
6577
6710
  children
6578
6711
  }) {
6579
- const { colors } = useKjunStyles(), group = useContext16(AccordionContext), id = "kjun-" + useId7(), [own, setOwn] = useState28(defaultOpen), open = group ? group.opened.has(id) : own;
6580
- const rotation = useMotionValue(open ? 1 : 0, tokens34.motion.collapse, void 0, void 0, true);
6581
- const geometry2 = tokens34.extensions.accordion;
6712
+ const controlled = openProp !== void 0, context = useContext16(AccordionContext), { colors } = useKjunStyles(), group = controlled ? null : context, id = "kjun-" + useId7(), [own, setOwn] = useState28(defaultOpen), open = controlled ? openProp : group ? group.opened.has(id) : own;
6713
+ const reported = useRef31(open), notify = useRef31(onOpenChange), registering = useRef31(!!group && defaultOpen);
6714
+ notify.current = onOpenChange;
6715
+ useEffect21(() => {
6716
+ var _a;
6717
+ if (registering.current) {
6718
+ if (open) {
6719
+ registering.current = false;
6720
+ reported.current = open;
6721
+ }
6722
+ return;
6723
+ }
6724
+ if (controlled || reported.current === open) return;
6725
+ reported.current = open;
6726
+ (_a = notify.current) == null ? void 0 : _a.call(notify, open);
6727
+ }, [open, controlled]);
6728
+ const rotation = useMotionValue(open ? 1 : 0, tokens35.motion.collapse, void 0, void 0, true);
6729
+ const geometry2 = tokens35.extensions.accordion;
6582
6730
  const [hovered, setHovered] = useState28(false);
6583
6731
  const wrapping = Platform22.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
6584
- useEffect20(() => {
6732
+ useEffect21(() => {
6585
6733
  return group == null ? void 0 : group.register(id, defaultOpen);
6586
6734
  }, []);
6587
6735
  return /* @__PURE__ */ jsxs23(View30, { children: [
@@ -6591,11 +6739,14 @@ function KjunAccordionItem({
6591
6739
  nativeID: id + "-heading",
6592
6740
  accessibilityRole: "button",
6593
6741
  focusRingInset: true,
6594
- focusRingRadius: tokens34.extensions.accordion.radius,
6742
+ focusRingRadius: tokens35.extensions.accordion.radius,
6595
6743
  accessibilityLabel: title,
6596
6744
  accessibilityState: { expanded: open, disabled },
6597
6745
  disabled,
6598
- onPress: () => group ? group.toggle(id) : setOwn(!own),
6746
+ onPress: () => {
6747
+ registering.current = false;
6748
+ controlled ? onOpenChange == null ? void 0 : onOpenChange(!open) : group ? group.toggle(id) : setOwn(!own);
6749
+ },
6599
6750
  onHoverIn: () => setHovered(true),
6600
6751
  onHoverOut: () => setHovered(false),
6601
6752
  style: ({ pressed }) => ({
@@ -6607,7 +6758,7 @@ function KjunAccordionItem({
6607
6758
  paddingVertical: geometry2.headerPaddingY,
6608
6759
  paddingHorizontal: geometry2.paddingX,
6609
6760
  backgroundColor: !disabled && (pressed || hovered) ? colors.hover : void 0,
6610
- opacity: disabled ? tokens34.states.opacity.disabled : 1
6761
+ opacity: disabled ? tokens35.states.opacity.disabled : 1
6611
6762
  }),
6612
6763
  children: [
6613
6764
  /* @__PURE__ */ jsx37(View30, { style: { flex: 1, minWidth: 0 }, children: content(header || title, { ...typeStyle("control"), ...wrapping }) }),
@@ -6615,7 +6766,7 @@ function KjunAccordionItem({
6615
6766
  ]
6616
6767
  }
6617
6768
  ),
6618
- /* @__PURE__ */ jsx37(Collapse, { open, children: /* @__PURE__ */ jsx37(
6769
+ /* @__PURE__ */ jsx37(Collapse, { open, keepMounted, children: /* @__PURE__ */ jsx37(
6619
6770
  View30,
6620
6771
  {
6621
6772
  nativeID: id + "-panel",
@@ -6642,11 +6793,11 @@ function KjunBreadcrumb({
6642
6793
  flexDirection: "row",
6643
6794
  alignItems: "center",
6644
6795
  flexWrap: "wrap",
6645
- gap: tokens34.dimension.value8
6796
+ gap: tokens35.dimension.value8
6646
6797
  },
6647
6798
  children: items2.map((item, i) => {
6648
- const label = /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: tokens34.dimension.value4 }, children: [
6649
- !!item.icon && /* @__PURE__ */ jsx37(KjunIcon, { name: item.icon, size: tokens34.extensions.breadcrumb.iconSize, color: colors.textSecondary }),
6799
+ const label = /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: tokens35.dimension.value4 }, children: [
6800
+ !!item.icon && /* @__PURE__ */ jsx37(KjunIcon, { name: item.icon, size: tokens35.extensions.breadcrumb.iconSize, color: colors.textSecondary }),
6650
6801
  /* @__PURE__ */ jsx37(
6651
6802
  KText,
6652
6803
  {
@@ -6663,7 +6814,7 @@ function KjunBreadcrumb({
6663
6814
  KjunIcon,
6664
6815
  {
6665
6816
  name: "chevron-right",
6666
- size: tokens34.extensions.breadcrumb.separatorSize,
6817
+ size: tokens35.extensions.breadcrumb.separatorSize,
6667
6818
  color: colors.textTertiary
6668
6819
  }
6669
6820
  ),
@@ -6673,7 +6824,7 @@ function KjunBreadcrumb({
6673
6824
  {
6674
6825
  accessibilityRole: "link",
6675
6826
  onPress: () => onNavigate == null ? void 0 : onNavigate(item),
6676
- style: { minHeight: tokens34.native.minimumTouchTarget, justifyContent: "center" },
6827
+ style: { minHeight: tokens35.native.minimumTouchTarget, justifyContent: "center" },
6677
6828
  children: label
6678
6829
  }
6679
6830
  ) : label
@@ -6702,7 +6853,7 @@ function KjunPagination({
6702
6853
  const m = useKjunMessages();
6703
6854
  const { colors } = useKjunStyles(), window2 = useWindowDimensions5(), current = Math.max(1, Math.min(totalPages, (_a = currentPage != null ? currentPage : page) != null ? _a : 1));
6704
6855
  if (totalPages <= 1 && !showSizeSelector && !(showInfo && totalRows > 0)) return null;
6705
- const compact = window2.width < tokens34.responsive.pagination;
6856
+ const compact = window2.width < tokens35.responsive.pagination;
6706
6857
  const change = (v) => {
6707
6858
  if (v < 1 || v > totalPages || v === current) return;
6708
6859
  onPageChange == null ? void 0 : onPageChange(v);
@@ -6718,12 +6869,12 @@ function KjunPagination({
6718
6869
  ]);
6719
6870
  const pages = [...visible].sort((a, b) => a - b).flatMap((v, i, all) => i && v - all[i - 1] > 1 ? ["...", v] : [v]);
6720
6871
  const pageButtonStyle = {
6721
- width: Math.max(tokens34.extensions.pagination.itemSize, tokens34.native.minimumTouchTarget),
6722
- height: Math.max(tokens34.extensions.pagination.itemSize, tokens34.native.minimumTouchTarget),
6723
- borderRadius: tokens34.extensions.pagination.radius,
6872
+ width: Math.max(tokens35.extensions.pagination.itemSize, tokens35.native.minimumTouchTarget),
6873
+ height: Math.max(tokens35.extensions.pagination.itemSize, tokens35.native.minimumTouchTarget),
6874
+ borderRadius: tokens35.extensions.pagination.radius,
6724
6875
  paddingHorizontal: 0
6725
6876
  };
6726
- const arrowSize = (_b = Object.keys(tokens34.button.iconSizes).find((size) => tokens34.button.iconSizes[size] === tokens34.extensions.pagination.iconSize)) != null ? _b : "sm";
6877
+ const arrowSize = (_b = Object.keys(tokens35.button.iconSizes).find((size) => tokens35.button.iconSizes[size] === tokens35.extensions.pagination.iconSize)) != null ? _b : "sm";
6727
6878
  const button = (target, label, icon) => /* @__PURE__ */ jsx37(
6728
6879
  KjunButton,
6729
6880
  {
@@ -6744,9 +6895,9 @@ function KjunPagination({
6744
6895
  flexDirection: compact ? "column" : "row",
6745
6896
  alignItems: compact ? "stretch" : "center",
6746
6897
  justifyContent: "space-between",
6747
- gap: tokens34.extensions.pagination.gap,
6748
- padding: tokens34.extensions.pagination.padding,
6749
- borderTopWidth: tokens34.border.defaultWidth,
6898
+ gap: tokens35.extensions.pagination.gap,
6899
+ padding: tokens35.extensions.pagination.padding,
6900
+ borderTopWidth: tokens35.border.defaultWidth,
6750
6901
  borderTopColor: colors.border
6751
6902
  },
6752
6903
  children: [
@@ -6757,11 +6908,11 @@ function KjunPagination({
6757
6908
  style: {
6758
6909
  flexDirection: "row",
6759
6910
  alignItems: "center",
6760
- gap: tokens34.extensions.pagination.itemGap,
6911
+ gap: tokens35.extensions.pagination.itemGap,
6761
6912
  flexWrap: "wrap"
6762
6913
  },
6763
6914
  children: [
6764
- showSizeSelector && /* @__PURE__ */ jsx37(View30, { style: { minWidth: tokens34.extensions.pagination.selectorMinimumWidth }, children: /* @__PURE__ */ jsx37(
6915
+ showSizeSelector && /* @__PURE__ */ jsx37(View30, { style: { minWidth: tokens35.extensions.pagination.selectorMinimumWidth }, children: /* @__PURE__ */ jsx37(
6765
6916
  KjunSelect,
6766
6917
  {
6767
6918
  size: "sm",
@@ -6778,10 +6929,10 @@ function KjunPagination({
6778
6929
  }
6779
6930
  }
6780
6931
  ) }),
6781
- totalPages > 1 && /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: tokens34.extensions.pagination.itemGap, marginLeft: compact ? "auto" : void 0 }, children: [
6932
+ totalPages > 1 && /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: tokens35.extensions.pagination.itemGap, marginLeft: compact ? "auto" : void 0 }, children: [
6782
6933
  !compact && showFirstLast && button(1, m.firstPage, "chevrons-left"),
6783
6934
  button(current - 1, m.previousPage, "chevron-left"),
6784
- compact ? /* @__PURE__ */ jsxs23(KText, { style: { paddingHorizontal: tokens34.extensions.pagination.labelPaddingX, color: colors.text, fontVariant: ["tabular-nums"] }, children: [
6935
+ compact ? /* @__PURE__ */ jsxs23(KText, { style: { paddingHorizontal: tokens35.extensions.pagination.labelPaddingX, color: colors.text, fontVariant: ["tabular-nums"] }, children: [
6785
6936
  /* @__PURE__ */ jsx37(KText, { style: { fontWeight: typeStyle("control").fontWeight }, children: current }),
6786
6937
  " / ",
6787
6938
  totalPages
@@ -6811,8 +6962,8 @@ function KjunPagination({
6811
6962
  }
6812
6963
 
6813
6964
  // packages/native/src/actions.tsx
6814
- import { tokens as tokens35 } from "@kjun-ui/tokens";
6815
- import { useContext as useContext17, useEffect as useEffect21, useRef as useRef29, useState as useState29 } from "react";
6965
+ import { tokens as tokens36 } from "@kjun-ui/tokens";
6966
+ import { useContext as useContext17, useEffect as useEffect22, useRef as useRef32, useState as useState29 } from "react";
6816
6967
  import { Platform as Platform23, ScrollView as ScrollView7, View as View31 } from "react-native";
6817
6968
  import { jsx as jsx38, jsxs as jsxs24 } from "react/jsx-runtime";
6818
6969
  function KjunIconToggle({
@@ -6832,7 +6983,7 @@ function KjunIconToggle({
6832
6983
  }) {
6833
6984
  const { colors } = useKjunStyles();
6834
6985
  const navigation = useContext17(TopNavigationContext);
6835
- const box = navigation ? navigation.controlSize : size === "xs" ? tokens35.extensions.iconToggle.compactSize : tokens35.extensions.iconToggle.sizes[size];
6986
+ const box = navigation ? navigation.controlSize : size === "xs" ? tokens36.extensions.iconToggle.compactSize : tokens36.extensions.iconToggle.sizes[size];
6836
6987
  return /* @__PURE__ */ jsx38(KjunTooltip, { content: disabled || loading ? "" : tooltip != null ? tooltip : ariaLabel, placement: tooltipPlacement, delay: tooltipDelay, children: /* @__PURE__ */ jsx38(
6837
6988
  AccessiblePressable,
6838
6989
  {
@@ -6858,24 +7009,24 @@ function KjunIconToggle({
6858
7009
  ...Platform23.OS === "web" ? { pointerEvents: "auto" } : {},
6859
7010
  // The touch target stays 44pt; the visible square follows the icon-toggle scale.
6860
7011
  alignSelf: "flex-start",
6861
- minWidth: Math.max(tokens35.native.minimumTouchTarget, box),
6862
- minHeight: Math.max(tokens35.native.minimumTouchTarget, box),
7012
+ minWidth: Math.max(tokens36.native.minimumTouchTarget, box),
7013
+ minHeight: Math.max(tokens36.native.minimumTouchTarget, box),
6863
7014
  alignItems: "center",
6864
7015
  justifyContent: "center",
6865
7016
  ...navigation ? { width: navigation.controlSize, height: navigation.controlSize, flexShrink: 0 } : {},
6866
- borderRadius: tokens35.extensions.iconToggle.radii[size],
7017
+ borderRadius: tokens36.extensions.iconToggle.radii[size],
6867
7018
  // Loading blocks presses but stays legible; only disabled dims.
6868
- opacity: disabled ? tokens35.states.opacity.disabled : 1,
7019
+ opacity: disabled ? tokens36.states.opacity.disabled : 1,
6869
7020
  transform: [{ scale: pressed ? 0.94 : 1 }]
6870
7021
  }),
6871
7022
  children: ({ pressed, hovered }) => {
6872
7023
  var _a;
6873
- return /* @__PURE__ */ jsx38(View31, { style: { width: box, height: box, alignItems: "center", justifyContent: "center", borderRadius: tokens35.extensions.iconToggle.radii[size], backgroundColor: !disabled && !loading && (pressed || hovered) ? colors.hover : "transparent" }, children: loading ? navigation ? /* @__PURE__ */ jsx38(KjunIcon, { name: "loader-2", spin: true, size: navigation.iconSize }) : /* @__PURE__ */ jsx38(KjunSpinner, { size: "sm" }) : /* @__PURE__ */ jsx38(
7024
+ return /* @__PURE__ */ jsx38(View31, { style: { width: box, height: box, alignItems: "center", justifyContent: "center", borderRadius: tokens36.extensions.iconToggle.radii[size], backgroundColor: !disabled && !loading && (pressed || hovered) ? colors.hover : "transparent" }, children: loading ? navigation ? /* @__PURE__ */ jsx38(KjunIcon, { name: "loader-2", spin: true, size: navigation.iconSize }) : /* @__PURE__ */ jsx38(KjunSpinner, { size: "sm" }) : /* @__PURE__ */ jsx38(
6874
7025
  KjunIcon,
6875
7026
  {
6876
7027
  name: active ? activeIcon : inactiveIcon || activeIcon,
6877
7028
  filled: active,
6878
- size: (_a = navigation == null ? void 0 : navigation.iconSize) != null ? _a : tokens35.button.iconSizes[size],
7029
+ size: (_a = navigation == null ? void 0 : navigation.iconSize) != null ? _a : tokens36.button.iconSizes[size],
6879
7030
  color: active ? activeColor != null ? activeColor : colors.brand : hovered && !disabled && !loading ? colors.textSecondary : inactiveColor != null ? inactiveColor : colors.textTertiary
6880
7031
  }
6881
7032
  ) });
@@ -6897,8 +7048,8 @@ function KjunCopyButton({
6897
7048
  }) {
6898
7049
  const m = useKjunMessages();
6899
7050
  successText != null ? successText : successText = m.copied;
6900
- const feedback = useOptionalKjunFeedback(), { colors } = useKjunStyles(), [copied, setCopied] = useState29(false), [failed, setFailed] = useState29(false), busy = useRef29(false), timer = useRef29(void 0), mounted = useRef29(true);
6901
- useEffect21(() => {
7051
+ const feedback = useOptionalKjunFeedback(), { colors } = useKjunStyles(), [copied, setCopied] = useState29(false), [failed, setFailed] = useState29(false), busy = useRef32(false), timer = useRef32(void 0), mounted = useRef32(true);
7052
+ useEffect22(() => {
6902
7053
  mounted.current = true;
6903
7054
  return () => {
6904
7055
  mounted.current = false;
@@ -6936,24 +7087,24 @@ function KjunCopyButton({
6936
7087
  },
6937
7088
  style: ({ pressed }) => ({
6938
7089
  alignSelf: "flex-start",
6939
- minWidth: tokens35.native.minimumTouchTarget,
6940
- minHeight: tokens35.native.minimumTouchTarget,
7090
+ minWidth: tokens36.native.minimumTouchTarget,
7091
+ minHeight: tokens36.native.minimumTouchTarget,
6941
7092
  alignItems: "center",
6942
7093
  justifyContent: "center",
6943
7094
  flexDirection: "row",
6944
- gap: tokens35.dimension.value6,
6945
- paddingHorizontal: { xs: tokens35.dimension.value2, sm: tokens35.dimension.value8, md: tokens35.dimension.value12 }[size],
6946
- paddingVertical: { xs: tokens35.dimension.value2, sm: tokens35.dimension.value4, md: tokens35.dimension.value6 }[size],
6947
- borderRadius: tokens35.radius.radius6,
7095
+ gap: tokens36.dimension.value6,
7096
+ paddingHorizontal: { xs: tokens36.dimension.value2, sm: tokens36.dimension.value8, md: tokens36.dimension.value12 }[size],
7097
+ paddingVertical: { xs: tokens36.dimension.value2, sm: tokens36.dimension.value4, md: tokens36.dimension.value6 }[size],
7098
+ borderRadius: tokens36.radius.radius6,
6948
7099
  backgroundColor: pressed && !inline ? colors.hover : void 0,
6949
- opacity: disabled ? tokens35.states.opacity.disabled : 1
7100
+ opacity: disabled ? tokens36.states.opacity.disabled : 1
6950
7101
  }),
6951
7102
  children: [
6952
7103
  /* @__PURE__ */ jsx38(
6953
7104
  KjunIcon,
6954
7105
  {
6955
7106
  name: copied ? "check" : "copy",
6956
- size: tokens35.button.iconSizes[size],
7107
+ size: tokens36.button.iconSizes[size],
6957
7108
  color: copied ? colors.success : colors.textSecondary
6958
7109
  }
6959
7110
  ),
@@ -7028,12 +7179,12 @@ function KjunExternalLink({
7028
7179
  accessibilityRole: "link",
7029
7180
  accessibilityLabel: name ? name + m.newWindow : void 0,
7030
7181
  onPress: () => openUrl(url),
7031
- style: { alignSelf: "flex-start", minHeight: tokens35.native.minimumTouchTarget, justifyContent: "center" },
7182
+ style: { alignSelf: "flex-start", minHeight: tokens36.native.minimumTouchTarget, justifyContent: "center" },
7032
7183
  children: mode === "text" ? (
7033
7184
  // Like Web, text links show the new-window cue after the text.
7034
- /* @__PURE__ */ jsxs24(View31, { style: { flexDirection: "row", alignItems: "center", gap: tokens35.dimension.value4 }, children: [
7185
+ /* @__PURE__ */ jsxs24(View31, { style: { flexDirection: "row", alignItems: "center", gap: tokens36.dimension.value4 }, children: [
7035
7186
  body,
7036
- /* @__PURE__ */ jsx38(KjunIcon, { name: "external-link", size: tokens35.iconSizes.small, color: colors.text })
7187
+ /* @__PURE__ */ jsx38(KjunIcon, { name: "external-link", size: tokens36.iconSizes.small, color: colors.text })
7037
7188
  ] })
7038
7189
  ) : body
7039
7190
  }
@@ -7053,7 +7204,7 @@ function KjunScrollFade({ children }) {
7053
7204
 
7054
7205
  // packages/native/src/data-state.tsx
7055
7206
  import {
7056
- tokens as tokens36,
7207
+ tokens as tokens37,
7057
7208
  advanceQueryDisplay,
7058
7209
  initialQueryDisplay,
7059
7210
  queryDisplayStatus
@@ -7062,10 +7213,10 @@ import { Component, useState as useState31 } from "react";
7062
7213
  import { Platform as Platform24, View as View32 } from "react-native";
7063
7214
 
7064
7215
  // shared/package-runtime/use-loading-reveal.ts
7065
- import { useEffect as useEffect22, useState as useState30 } from "react";
7216
+ import { useEffect as useEffect23, useState as useState30 } from "react";
7066
7217
  function useLoadingReveal(active, delay = 0) {
7067
7218
  const [revealed, setRevealed] = useState30(false);
7068
- useEffect22(() => {
7219
+ useEffect23(() => {
7069
7220
  setRevealed(false);
7070
7221
  if (!active || delay <= 0) return;
7071
7222
  const timer = setTimeout(() => setRevealed(true), delay);
@@ -7116,7 +7267,7 @@ function KjunDataState({
7116
7267
  emptyText != null ? emptyText : emptyText = m.noData;
7117
7268
  loadingText != null ? loadingText : loadingText = m.loadingEllipsis;
7118
7269
  retryText != null ? retryText : retryText = m.retry;
7119
- const state = useQueryDisplay(query), blockingError = query.error && !(state.usesQueryState && state.hasCurrentResult), visibleRefreshError = refreshError || (state.usesQueryState && state.hasCurrentResult ? query.error : null), concealed = state.initialLoading || !!blockingError || empty, padding = tokens36.extensions.state.padding[size], revealed = useLoadingReveal(state.initialLoading, loadingDelay);
7270
+ const state = useQueryDisplay(query), blockingError = query.error && !(state.usesQueryState && state.hasCurrentResult), visibleRefreshError = refreshError || (state.usesQueryState && state.hasCurrentResult ? query.error : null), concealed = state.initialLoading || !!blockingError || empty, padding = tokens37.extensions.state.padding[size], revealed = useLoadingReveal(state.initialLoading, loadingDelay);
7120
7271
  const { colors } = useKjunStyles();
7121
7272
  return /* @__PURE__ */ jsxs25(
7122
7273
  View32,
@@ -7131,13 +7282,13 @@ function KjunDataState({
7131
7282
  style: {
7132
7283
  alignSelf: "flex-end",
7133
7284
  maxWidth: "100%",
7134
- marginBottom: tokens36.dimension.value12,
7285
+ marginBottom: tokens37.dimension.value12,
7135
7286
  flexDirection: "row",
7136
7287
  alignItems: "center",
7137
- gap: tokens36.dimension.value6,
7138
- paddingVertical: tokens36.dimension.value4,
7139
- paddingHorizontal: tokens36.dimension.value8,
7140
- borderRadius: tokens36.radius.radius12,
7288
+ gap: tokens37.dimension.value6,
7289
+ paddingVertical: tokens37.dimension.value4,
7290
+ paddingHorizontal: tokens37.dimension.value8,
7291
+ borderRadius: tokens37.radius.radius12,
7141
7292
  backgroundColor: colors.surface
7142
7293
  },
7143
7294
  children: [
@@ -7153,7 +7304,7 @@ function KjunDataState({
7153
7304
  "aria-hidden": revealed ? void 0 : true,
7154
7305
  importantForAccessibility: revealed ? void 0 : "no-hide-descendants",
7155
7306
  style: { paddingVertical: loadingPadding === "none" ? 0 : padding, opacity: revealed ? void 0 : 0 },
7156
- children: loadingContent || (skeleton ? /* @__PURE__ */ jsx39(View32, { style: { gap: tokens36.dimension.value12 }, children: Array.from({ length: skeletonCount }, (_, i) => /* @__PURE__ */ jsx39(KjunSkeleton, { type: skeletonType }, i)) }) : /* @__PURE__ */ jsxs25(View32, { style: { alignItems: "center", gap: tokens36.dimension.value12 }, children: [
7307
+ children: loadingContent || (skeleton ? /* @__PURE__ */ jsx39(View32, { style: { gap: tokens37.dimension.value12 }, children: Array.from({ length: skeletonCount }, (_, i) => /* @__PURE__ */ jsx39(KjunSkeleton, { type: skeletonType }, i)) }) : /* @__PURE__ */ jsxs25(View32, { style: { alignItems: "center", gap: tokens37.dimension.value12 }, children: [
7157
7308
  /* @__PURE__ */ jsx39(KjunSpinner, { size: "md" }),
7158
7309
  /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle("body"), color: colors.textSecondary, textAlign: "center", maxWidth: "100%" }, children: loadingText })
7159
7310
  ] }))
@@ -7172,12 +7323,12 @@ function KjunDataState({
7172
7323
  right: 0,
7173
7324
  opacity: 0,
7174
7325
  ...Platform24.OS === "web" ? { visibility: "hidden" } : {}
7175
- } : { opacity: query.loading && !state.usesQueryState ? tokens36.states.opacity.pending : 1 },
7326
+ } : { opacity: query.loading && !state.usesQueryState ? tokens37.states.opacity.pending : 1 },
7176
7327
  children: content(children)
7177
7328
  },
7178
7329
  "content"
7179
7330
  ),
7180
- visibleRefreshError && !state.initialLoading && /* @__PURE__ */ jsx39(DataStateContentContext.Provider, { value: "message", children: /* @__PURE__ */ jsx39(View32, { style: { marginTop: tokens36.dimension.value12 }, children: /* @__PURE__ */ jsx39(KjunAlert, { type: "warning", size: "sm", actions: onRetry && /* @__PURE__ */ jsx39(KjunButton, { variant: "secondary", onPress: onRetry, children: retryText }), children: m.refreshError(String(visibleRefreshError)) }) }) })
7331
+ visibleRefreshError && !state.initialLoading && /* @__PURE__ */ jsx39(DataStateContentContext.Provider, { value: "message", children: /* @__PURE__ */ jsx39(View32, { style: { marginTop: tokens37.dimension.value12 }, children: /* @__PURE__ */ jsx39(KjunAlert, { type: "warning", size: "sm", actions: onRetry && /* @__PURE__ */ jsx39(KjunButton, { variant: "secondary", onPress: onRetry, children: retryText }), children: m.refreshError(String(visibleRefreshError)) }) }) })
7181
7332
  ]
7182
7333
  }
7183
7334
  );
@@ -7185,7 +7336,7 @@ function KjunDataState({
7185
7336
  function BoundaryDescription() {
7186
7337
  const m = useKjunMessages();
7187
7338
  const { colors } = useKjunStyles();
7188
- return /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle({ ...tokens36.typography.caption, fontSizePx: tokens36.extensions.state.descriptionSize }), color: colors.textSecondary, textAlign: "center" }, children: m.retryHint });
7339
+ return /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle({ ...tokens37.typography.caption, fontSizePx: tokens37.extensions.state.descriptionSize }), color: colors.textSecondary, textAlign: "center" }, children: m.retryHint });
7189
7340
  }
7190
7341
  var KjunErrorBoundary = class extends Component {
7191
7342
  constructor() {
@@ -7205,13 +7356,13 @@ var KjunErrorBoundary = class extends Component {
7205
7356
  {
7206
7357
  style: {
7207
7358
  alignItems: "center",
7208
- paddingVertical: tokens36.dimension.value64,
7209
- paddingHorizontal: tokens36.dimension.value24,
7210
- gap: tokens36.dimension.value16
7359
+ paddingVertical: tokens37.dimension.value64,
7360
+ paddingHorizontal: tokens37.dimension.value24,
7361
+ gap: tokens37.dimension.value16
7211
7362
  },
7212
7363
  children: [
7213
- /* @__PURE__ */ jsxs25(View32, { style: { gap: tokens36.dimension.value8, alignItems: "center" }, children: [
7214
- /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle({ ...tokens36.typography.sectionTitle, fontSizePx: tokens36.extensions.state.titleSize }), textAlign: "center" }, children: this.props.fallbackMessage || this.context.messages.somethingWentWrong }),
7364
+ /* @__PURE__ */ jsxs25(View32, { style: { gap: tokens37.dimension.value8, alignItems: "center" }, children: [
7365
+ /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle({ ...tokens37.typography.sectionTitle, fontSizePx: tokens37.extensions.state.titleSize }), textAlign: "center" }, children: this.props.fallbackMessage || this.context.messages.somethingWentWrong }),
7215
7366
  /* @__PURE__ */ jsx39(BoundaryDescription, {})
7216
7367
  ] }),
7217
7368
  /* @__PURE__ */ jsx39(
@@ -7234,8 +7385,8 @@ var KjunErrorBoundary = class extends Component {
7234
7385
  KjunErrorBoundary.contextType = KjunMessageContext;
7235
7386
 
7236
7387
  // packages/native/src/skeletons.tsx
7237
- import { tokens as tokens40 } from "@kjun-ui/tokens";
7238
- import { useEffect as useEffect23, useRef as useRef30, useState as useState33 } from "react";
7388
+ import { tokens as tokens41 } from "@kjun-ui/tokens";
7389
+ import { useEffect as useEffect24, useRef as useRef33, useState as useState33 } from "react";
7239
7390
  import { Animated as Animated17, Platform as Platform25, View as View34, useWindowDimensions as useWindowDimensions6 } from "react-native";
7240
7391
  import Svg5, { Path as Path4 } from "react-native-svg";
7241
7392
 
@@ -7258,12 +7409,12 @@ function chartSkeletonKind(kind) {
7258
7409
  }
7259
7410
 
7260
7411
  // packages/native/src/market-skeleton.tsx
7261
- import { tokens as tokens39 } from "@kjun-ui/tokens";
7412
+ import { tokens as tokens40 } from "@kjun-ui/tokens";
7262
7413
  import { ScrollView as ScrollView8, View as View33 } from "react-native";
7263
7414
 
7264
7415
  // shared/package-runtime/market-layout.ts
7265
- import { tokens as tokens37 } from "@kjun-ui/tokens";
7266
- var marketGeometry = tokens37.extensions.marketTable;
7416
+ import { tokens as tokens38 } from "@kjun-ui/tokens";
7417
+ var marketGeometry = tokens38.extensions.marketTable;
7267
7418
  var isMarketIdentity = (key) => ["stock_name", "name", "symbol"].includes(key || "");
7268
7419
  var normalizeMarketColumns = (columns) => columns.map((column) => typeof column === "string" ? { key: column, label: column } : column);
7269
7420
  var defaultWidth = (column) => isMarketIdentity(column.key) ? marketGeometry.identityWidth : marketGeometry.columnWidth;
@@ -7281,33 +7432,33 @@ function nativeMarketLayout(columns, showActions, containerWidth) {
7281
7432
  }
7282
7433
 
7283
7434
  // packages/native/src/market-layout.ts
7284
- import { tokens as tokens38 } from "@kjun-ui/tokens";
7435
+ import { tokens as tokens39 } from "@kjun-ui/tokens";
7285
7436
  import { useState as useState32 } from "react";
7286
7437
  function useMarketLayout(columns, showActions) {
7287
7438
  const [containerWidth, setContainerWidth] = useState32(0);
7288
7439
  const onLayout = (event) => setContainerWidth(event.nativeEvent.layout.width);
7289
7440
  return { ...nativeMarketLayout(columns, showActions, containerWidth), onLayout };
7290
7441
  }
7291
- var marketHeaderStyle = { minHeight: marketGeometry.headerHeight, flexDirection: "row", borderBottomWidth: tokens38.border.defaultWidth };
7292
- var marketRowStyle = { minHeight: marketGeometry.rowHeight, flexDirection: "row", borderBottomWidth: tokens38.border.defaultWidth };
7442
+ var marketHeaderStyle = { minHeight: marketGeometry.headerHeight, flexDirection: "row", borderBottomWidth: tokens39.border.defaultWidth };
7443
+ var marketRowStyle = { minHeight: marketGeometry.rowHeight, flexDirection: "row", borderBottomWidth: tokens39.border.defaultWidth };
7293
7444
 
7294
7445
  // packages/native/src/market-skeleton.tsx
7295
7446
  import { jsx as jsx40, jsxs as jsxs26 } from "react/jsx-runtime";
7296
7447
  function KjunMarketTableSkeleton({ columns = [], rows = 8, showActions = false }) {
7297
7448
  const { colors } = useKjunStyles();
7298
7449
  const cols = normalizeMarketColumns(columns), layout = useMarketLayout(cols, showActions);
7299
- const actions = { width: marketGeometry.actionsWidth, paddingVertical: tokens39.dimension.value12, paddingHorizontal: tokens39.dimension.value4, justifyContent: "center", alignItems: "center" };
7450
+ const actions = { width: marketGeometry.actionsWidth, paddingVertical: tokens40.dimension.value12, paddingHorizontal: tokens40.dimension.value4, justifyContent: "center", alignItems: "center" };
7300
7451
  return /* @__PURE__ */ jsx40(ScrollView8, { horizontal: true, onLayout: layout.onLayout, accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: /* @__PURE__ */ jsxs26(View33, { style: { width: layout.width }, children: [
7301
7452
  /* @__PURE__ */ jsxs26(View33, { style: { ...marketHeaderStyle, borderBottomColor: colors.border }, children: [
7302
- showActions && /* @__PURE__ */ jsx40(View33, { style: actions, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: tokens39.extensions.marketTable.actionSkeletonWidth, height: tokens39.extensions.marketTable.headerSkeletonHeight }) }),
7303
- cols.map((col, i) => /* @__PURE__ */ jsx40(View33, { style: { width: layout.widths[i], padding: tokens39.dimension.value12, justifyContent: "center" }, children: /* @__PURE__ */ jsx40(KText, { style: { ...typeStyle("meta"), color: colors.textTertiary, textAlign: col.align }, children: col.label }) }, col.key || i))
7453
+ showActions && /* @__PURE__ */ jsx40(View33, { style: actions, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: tokens40.extensions.marketTable.actionSkeletonWidth, height: tokens40.extensions.marketTable.headerSkeletonHeight }) }),
7454
+ cols.map((col, i) => /* @__PURE__ */ jsx40(View33, { style: { width: layout.widths[i], padding: tokens40.dimension.value12, justifyContent: "center" }, children: /* @__PURE__ */ jsx40(KText, { style: { ...typeStyle("meta"), color: colors.textTertiary, textAlign: col.align }, children: col.label }) }, col.key || i))
7304
7455
  ] }),
7305
7456
  Array.from({ length: Math.max(0, rows) }, (_, row) => /* @__PURE__ */ jsxs26(View33, { style: { ...marketRowStyle, borderBottomColor: colors.border }, children: [
7306
- showActions && /* @__PURE__ */ jsx40(View33, { style: actions, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: tokens39.extensions.marketTable.actionSkeletonWidth, height: tokens39.extensions.financial.priceSkeletonHeight }) }),
7307
- cols.map((col, i) => /* @__PURE__ */ jsx40(View33, { style: { width: layout.widths[i], paddingVertical: tokens39.dimension.value14, paddingHorizontal: tokens39.dimension.value12, justifyContent: "center", alignItems: isMarketIdentity(col.key) ? void 0 : col.align === "right" ? "flex-end" : col.align === "center" ? "center" : "flex-start" }, children: isMarketIdentity(col.key) ? /* @__PURE__ */ jsxs26(View33, { style: { gap: tokens39.dimension.value2 }, children: [
7308
- /* @__PURE__ */ jsx40(View33, { style: { height: tokens39.typography.body.lineHeightPx, justifyContent: "center" }, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: "80%", height: tokens39.extensions.skeleton.lineHeights.md }) }),
7309
- /* @__PURE__ */ jsx40(View33, { style: { height: tokens39.typography.caption.lineHeightPx, justifyContent: "center" }, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: "60%", height: tokens39.extensions.skeleton.lineHeights.sm }) })
7310
- ] }) : /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: tokens39.extensions.financial.priceSkeletonWidth, height: tokens39.extensions.financial.priceSkeletonHeight }) }, col.key || i))
7457
+ showActions && /* @__PURE__ */ jsx40(View33, { style: actions, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: tokens40.extensions.marketTable.actionSkeletonWidth, height: tokens40.extensions.financial.priceSkeletonHeight }) }),
7458
+ cols.map((col, i) => /* @__PURE__ */ jsx40(View33, { style: { width: layout.widths[i], paddingVertical: tokens40.dimension.value14, paddingHorizontal: tokens40.dimension.value12, justifyContent: "center", alignItems: isMarketIdentity(col.key) ? void 0 : col.align === "right" ? "flex-end" : col.align === "center" ? "center" : "flex-start" }, children: isMarketIdentity(col.key) ? /* @__PURE__ */ jsxs26(View33, { style: { gap: tokens40.dimension.value2 }, children: [
7459
+ /* @__PURE__ */ jsx40(View33, { style: { height: tokens40.typography.body.lineHeightPx, justifyContent: "center" }, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: "80%", height: tokens40.extensions.skeleton.lineHeights.md }) }),
7460
+ /* @__PURE__ */ jsx40(View33, { style: { height: tokens40.typography.caption.lineHeightPx, justifyContent: "center" }, children: /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: "60%", height: tokens40.extensions.skeleton.lineHeights.sm }) })
7461
+ ] }) : /* @__PURE__ */ jsx40(KjunSkeleton, { type: "block", width: tokens40.extensions.financial.priceSkeletonWidth, height: tokens40.extensions.financial.priceSkeletonHeight }) }, col.key || i))
7311
7462
  ] }, row))
7312
7463
  ] }) });
7313
7464
  }
@@ -7318,11 +7469,11 @@ function KjunListSkeleton({
7318
7469
  rows = 8,
7319
7470
  variant = "market",
7320
7471
  avatar = true,
7321
- avatarSize = tokens40.extensions.skeleton.listAvatarSize,
7472
+ avatarSize = tokens41.extensions.skeleton.listAvatarSize,
7322
7473
  quote = true
7323
7474
  }) {
7324
7475
  const { colors } = useKjunStyles();
7325
- const market = variant === "market", narrow = useWindowDimensions6().width < tokens40.responsive.market;
7476
+ const market = variant === "market", narrow = useWindowDimensions6().width < tokens41.responsive.market;
7326
7477
  const slots = market ? [typeStyle(narrow ? "input" : "label").lineHeight, typeStyle(narrow ? "body" : "caption").lineHeight] : null;
7327
7478
  const slot = (index, child) => slots ? /* @__PURE__ */ jsx41(View34, { style: { height: slots[index], justifyContent: "center" }, children: child }) : child;
7328
7479
  return /* @__PURE__ */ jsx41(
@@ -7336,29 +7487,29 @@ function KjunListSkeleton({
7336
7487
  style: {
7337
7488
  flexDirection: "row",
7338
7489
  alignItems: "center",
7339
- gap: tokens40.extensions.skeleton.gap,
7340
- minHeight: market ? narrow ? tokens40.extensions.marketList.minimumHeight : void 0 : tokens40.extensions.skeleton.listHeights[variant],
7341
- paddingVertical: market ? narrow ? tokens40.dimension.value14 : tokens40.dimension.value16 : tokens40.extensions.skeleton.list[variant].paddingY,
7342
- paddingHorizontal: market ? narrow ? tokens40.dimension.value20 : tokens40.dimension.value16 : tokens40.extensions.skeleton.list[variant].paddingX,
7343
- borderBottomWidth: tokens40.border.defaultWidth,
7490
+ gap: tokens41.extensions.skeleton.gap,
7491
+ minHeight: market ? narrow ? tokens41.extensions.marketList.minimumHeight : void 0 : tokens41.extensions.skeleton.listHeights[variant],
7492
+ paddingVertical: market ? narrow ? tokens41.dimension.value14 : tokens41.dimension.value16 : tokens41.extensions.skeleton.list[variant].paddingY,
7493
+ paddingHorizontal: market ? narrow ? tokens41.dimension.value20 : tokens41.dimension.value16 : tokens41.extensions.skeleton.list[variant].paddingX,
7494
+ borderBottomWidth: tokens41.border.defaultWidth,
7344
7495
  borderBottomColor: colors.border
7345
7496
  },
7346
7497
  children: [
7347
7498
  avatar && /* @__PURE__ */ jsx41(KjunSkeleton, { type: "avatar", width: avatarSize, height: avatarSize }),
7348
- /* @__PURE__ */ jsxs27(View34, { style: { flex: 1, minWidth: 0, gap: market ? tokens40.dimension.value2 : tokens40.extensions.skeleton.detailGap }, children: [
7499
+ /* @__PURE__ */ jsxs27(View34, { style: { flex: 1, minWidth: 0, gap: market ? tokens41.dimension.value2 : tokens41.extensions.skeleton.detailGap }, children: [
7349
7500
  slot(0, /* @__PURE__ */ jsx41(
7350
7501
  KjunSkeleton,
7351
7502
  {
7352
7503
  type: "block",
7353
- height: tokens40.extensions.skeleton.lineHeights.md,
7504
+ height: tokens41.extensions.skeleton.lineHeights.md,
7354
7505
  width: i % 2 ? "80%" : "65%"
7355
7506
  }
7356
7507
  )),
7357
- slot(1, /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens40.extensions.skeleton.lineHeights.sm, width: "50%" }))
7508
+ slot(1, /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens41.extensions.skeleton.lineHeights.sm, width: "50%" }))
7358
7509
  ] }),
7359
- quote && /* @__PURE__ */ jsxs27(View34, { style: { alignItems: "flex-end", gap: market ? tokens40.dimension.value2 : tokens40.extensions.skeleton.detailGap }, children: [
7360
- slot(0, /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens40.extensions.skeleton.quoteHeight, width: tokens40.extensions.skeleton.quoteWidth })),
7361
- slot(1, /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens40.extensions.skeleton.lineHeights.sm, width: tokens40.extensions.skeleton.detailWidth }))
7510
+ quote && /* @__PURE__ */ jsxs27(View34, { style: { alignItems: "flex-end", gap: market ? tokens41.dimension.value2 : tokens41.extensions.skeleton.detailGap }, children: [
7511
+ slot(0, /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens41.extensions.skeleton.quoteHeight, width: tokens41.extensions.skeleton.quoteWidth })),
7512
+ slot(1, /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens41.extensions.skeleton.lineHeights.sm, width: tokens41.extensions.skeleton.detailWidth }))
7362
7513
  ] })
7363
7514
  ]
7364
7515
  },
@@ -7375,7 +7526,7 @@ function KjunFormSkeleton({
7375
7526
  }) {
7376
7527
  const { colors } = useKjunStyles();
7377
7528
  const window2 = useWindowDimensions6();
7378
- const twoColumns = columns === 2 && window2.width >= tokens40.responsive.formColumns;
7529
+ const twoColumns = columns === 2 && window2.width >= tokens41.responsive.formColumns;
7379
7530
  return /* @__PURE__ */ jsx41(
7380
7531
  View34,
7381
7532
  {
@@ -7384,13 +7535,13 @@ function KjunFormSkeleton({
7384
7535
  style: {
7385
7536
  flexDirection: twoColumns ? "row" : "column",
7386
7537
  flexWrap: twoColumns ? "wrap" : "nowrap",
7387
- gap: tokens40.extensions.skeleton.formGap
7538
+ gap: tokens41.extensions.skeleton.formGap
7388
7539
  },
7389
7540
  children: fields.map((field, i) => /* @__PURE__ */ jsxs27(
7390
7541
  View34,
7391
7542
  {
7392
7543
  style: {
7393
- gap: tokens40.extensions.skeleton.fieldGap,
7544
+ gap: tokens41.extensions.skeleton.fieldGap,
7394
7545
  minWidth: 0,
7395
7546
  flexBasis: twoColumns ? "45%" : void 0,
7396
7547
  flexGrow: 1
@@ -7398,13 +7549,13 @@ function KjunFormSkeleton({
7398
7549
  children: [
7399
7550
  field ? /* @__PURE__ */ jsx41(KText, { style: { color: colors.text, ...typeStyle("label") }, children: typeof field === "string" ? field : field.label }) : (
7400
7551
  // The bar sits in a label-line slot so the field starts where the real input will.
7401
- /* @__PURE__ */ jsx41(View34, { style: { height: typeStyle("label").lineHeight, justifyContent: "center" }, children: /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens40.extensions.skeleton.formLabelHeight, width: tokens40.extensions.skeleton.formLabelWidth }) })
7552
+ /* @__PURE__ */ jsx41(View34, { style: { height: typeStyle("label").lineHeight, justifyContent: "center" }, children: /* @__PURE__ */ jsx41(KjunSkeleton, { type: "block", height: tokens41.extensions.skeleton.formLabelHeight, width: tokens41.extensions.skeleton.formLabelWidth }) })
7402
7553
  ),
7403
- /* @__PURE__ */ jsx41(View34, { style: { borderRadius: tokens40.input[size].radius, overflow: "hidden" }, children: /* @__PURE__ */ jsx41(
7554
+ /* @__PURE__ */ jsx41(View34, { style: { borderRadius: tokens41.input[size].radius, overflow: "hidden" }, children: /* @__PURE__ */ jsx41(
7404
7555
  KjunSkeleton,
7405
7556
  {
7406
7557
  type: "block",
7407
- height: typeof field === "object" && field.height != null ? field.height : multiline ? tokens40.input[size].lineHeight * 3 + tokens40.input[size].textareaPaddingY * 2 + 2 * tokens40.border.controlWidth : tokens40.input[size].height
7558
+ height: typeof field === "object" && field.height != null ? field.height : multiline ? tokens41.input[size].lineHeight * 3 + tokens41.input[size].textareaPaddingY * 2 + 2 * tokens41.border.controlWidth : tokens41.input[size].height
7408
7559
  }
7409
7560
  ) })
7410
7561
  ]
@@ -7417,7 +7568,7 @@ function KjunFormSkeleton({
7417
7568
  var chartPart = (name) => Platform25.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
7418
7569
  function KjunChartSkeleton({
7419
7570
  kind: requestedKind = "frame",
7420
- height = tokens40.extensions.chartSkeleton.height,
7571
+ height = tokens41.extensions.chartSkeleton.height,
7421
7572
  loadingText,
7422
7573
  skeleton = true,
7423
7574
  loadingDelay = 0,
@@ -7426,13 +7577,13 @@ function KjunChartSkeleton({
7426
7577
  }) {
7427
7578
  const m = useKjunMessages();
7428
7579
  loadingText != null ? loadingText : loadingText = m.chartLoading;
7429
- const kind = chartSkeletonKind(requestedKind), { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef30(new Animated17.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = useState33(0), thickness = tokens40.extensions.chartSkeleton.donutThickness, boxHeight = typeof height === "number" ? height : measured, hole = boxHeight > 0 ? chartDonutHole(boxHeight, thickness) : void 0, rowCount = chartSkeletonCount(rows), columnCount = chartSkeletonCount(columns), status = revealed && loadingText ? "status" : void 0, hidden = { "aria-hidden": true, importantForAccessibility: "no-hide-descendants" };
7430
- useEffect23(() => {
7580
+ const kind = chartSkeletonKind(requestedKind), { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef33(new Animated17.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = useState33(0), thickness = tokens41.extensions.chartSkeleton.donutThickness, boxHeight = typeof height === "number" ? height : measured, hole = boxHeight > 0 ? chartDonutHole(boxHeight, thickness) : void 0, rowCount = chartSkeletonCount(rows), columnCount = chartSkeletonCount(columns), status = revealed && loadingText ? "status" : void 0, hidden = { "aria-hidden": true, importantForAccessibility: "no-hide-descendants" };
7581
+ useEffect24(() => {
7431
7582
  if (reduced || !skeleton) return;
7432
7583
  const loop = Animated17.loop(
7433
7584
  Animated17.sequence([
7434
- Animated17.timing(opacity, { toValue: 0.55, duration: tokens40.motion.shimmer / 2, useNativeDriver: true }),
7435
- Animated17.timing(opacity, { toValue: 1, duration: tokens40.motion.shimmer / 2, useNativeDriver: true })
7585
+ Animated17.timing(opacity, { toValue: 0.55, duration: tokens41.motion.shimmer / 2, useNativeDriver: true }),
7586
+ Animated17.timing(opacity, { toValue: 1, duration: tokens41.motion.shimmer / 2, useNativeDriver: true })
7436
7587
  ])
7437
7588
  );
7438
7589
  loop.start();
@@ -7449,7 +7600,7 @@ function KjunChartSkeleton({
7449
7600
  "aria-hidden": revealed ? void 0 : true,
7450
7601
  importantForAccessibility: revealed ? void 0 : "no-hide-descendants",
7451
7602
  ...Platform25.OS === "web" ? { dataSet: { kjunChartKind: kind, skeleton: skeleton ? void 0 : "false" } } : {},
7452
- children: !skeleton ? /* @__PURE__ */ jsxs27(View34, { ...chartPart("loading"), role: status, style: { alignItems: "center", gap: tokens40.dimension.value12 }, children: [
7603
+ children: !skeleton ? /* @__PURE__ */ jsxs27(View34, { ...chartPart("loading"), role: status, style: { alignItems: "center", gap: tokens41.dimension.value12 }, children: [
7453
7604
  /* @__PURE__ */ jsx41(View34, { ...hidden, children: /* @__PURE__ */ jsx41(KjunSpinner, { size: "md" }) }),
7454
7605
  !!loadingText && /* @__PURE__ */ jsx41(KText, { style: { ...typeStyle("body"), color: colors.textSecondary, textAlign: "center", maxWidth: "100%" }, children: loadingText })
7455
7606
  ] }) : /* @__PURE__ */ jsxs27(Fragment13, { children: [
@@ -7458,21 +7609,21 @@ function KjunChartSkeleton({
7458
7609
  {
7459
7610
  ...chartPart("donut"),
7460
7611
  ...hidden,
7461
- style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: tokens40.radius.radius9999 }
7612
+ style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: tokens41.radius.radius9999 }
7462
7613
  }
7463
- ) : kind === "matrix" ? /* @__PURE__ */ jsx41(View34, { ...chartPart("matrix"), ...hidden, style: { alignSelf: "stretch", flex: 1, gap: tokens40.dimension.value4 }, children: Array.from({ length: rowCount }, (_, row) => /* @__PURE__ */ jsx41(View34, { style: { flex: 1, flexDirection: "row", gap: tokens40.dimension.value4 }, children: Array.from({ length: columnCount }, (_2, column) => /* @__PURE__ */ jsx41(
7614
+ ) : kind === "matrix" ? /* @__PURE__ */ jsx41(View34, { ...chartPart("matrix"), ...hidden, style: { alignSelf: "stretch", flex: 1, gap: tokens41.dimension.value4 }, children: Array.from({ length: rowCount }, (_, row) => /* @__PURE__ */ jsx41(View34, { style: { flex: 1, flexDirection: "row", gap: tokens41.dimension.value4 }, children: Array.from({ length: columnCount }, (_2, column) => /* @__PURE__ */ jsx41(
7464
7615
  View34,
7465
7616
  {
7466
7617
  ...chartPart("cell"),
7467
7618
  style: {
7468
7619
  flex: 1,
7469
- borderRadius: tokens40.extensions.skeleton.lineRadius,
7620
+ borderRadius: tokens41.extensions.skeleton.lineRadius,
7470
7621
  backgroundColor: colors.skeleton,
7471
- opacity: chartMatrixMuted(row, column) ? tokens40.states.opacity.pending : 1
7622
+ opacity: chartMatrixMuted(row, column) ? tokens41.states.opacity.pending : 1
7472
7623
  }
7473
7624
  },
7474
7625
  column
7475
- )) }, row)) }) : /* @__PURE__ */ jsx41(View34, { ...chartPart("plot"), ...hidden, style: { alignSelf: "stretch", flex: 1 }, children: /* @__PURE__ */ jsx41(Svg5, { viewBox: chartFrameViewBox, preserveAspectRatio: "none", width: "100%", height: "100%", children: /* @__PURE__ */ jsx41(Path4, { d: chartFramePath, fill: "none", stroke: colors.chartGrid, strokeWidth: tokens40.border.defaultWidth, vectorEffect: "non-scaling-stroke" }) }) }),
7626
+ )) }, row)) }) : /* @__PURE__ */ jsx41(View34, { ...chartPart("plot"), ...hidden, style: { alignSelf: "stretch", flex: 1 }, children: /* @__PURE__ */ jsx41(Svg5, { viewBox: chartFrameViewBox, preserveAspectRatio: "none", width: "100%", height: "100%", children: /* @__PURE__ */ jsx41(Path4, { d: chartFramePath, fill: "none", stroke: colors.chartGrid, strokeWidth: tokens41.border.defaultWidth, vectorEffect: "non-scaling-stroke" }) }) }),
7476
7627
  !!loadingText && /* @__PURE__ */ jsx41(
7477
7628
  View34,
7478
7629
  {
@@ -7486,10 +7637,10 @@ function KjunChartSkeleton({
7486
7637
  {
7487
7638
  style: {
7488
7639
  ...typeStyle("body"),
7489
- paddingHorizontal: tokens40.dimension.value12,
7490
- paddingVertical: tokens40.dimension.value4,
7491
- borderRadius: tokens40.radius.radius6,
7492
- borderWidth: kind === "donut" ? 0 : tokens40.border.defaultWidth,
7640
+ paddingHorizontal: tokens41.dimension.value12,
7641
+ paddingVertical: tokens41.dimension.value4,
7642
+ borderRadius: tokens41.radius.radius6,
7643
+ borderWidth: kind === "donut" ? 0 : tokens41.border.defaultWidth,
7493
7644
  borderColor: colors.chartGrid,
7494
7645
  backgroundColor: colors.surface,
7495
7646
  color: colors.textSecondary,
@@ -7507,7 +7658,7 @@ function KjunChartSkeleton({
7507
7658
  }
7508
7659
 
7509
7660
  // packages/native/src/financial-display.tsx
7510
- import { deviationLevel, tokens as tokens43 } from "@kjun-ui/tokens";
7661
+ import { deviationLevel, tokens as tokens44 } from "@kjun-ui/tokens";
7511
7662
  import { useId as useId8 } from "react";
7512
7663
  import {
7513
7664
  View as View36
@@ -7522,13 +7673,13 @@ import Svg6, {
7522
7673
  } from "react-native-svg";
7523
7674
 
7524
7675
  // packages/native/src/number-display.tsx
7525
- import { tokens as tokens42 } from "@kjun-ui/tokens";
7676
+ import { tokens as tokens43 } from "@kjun-ui/tokens";
7526
7677
 
7527
7678
  // shared/package-runtime/use-number-motion.ts
7528
- import { useLayoutEffect as useLayoutEffect16, useRef as useRef31, useState as useState34 } from "react";
7679
+ import { useLayoutEffect as useLayoutEffect16, useRef as useRef34, useState as useState34 } from "react";
7529
7680
 
7530
7681
  // shared/package-runtime/number-motion.ts
7531
- import { tokens as tokens41 } from "@kjun-ui/tokens";
7682
+ import { tokens as tokens42 } from "@kjun-ui/tokens";
7532
7683
  function createNumberMotion(apply) {
7533
7684
  let frame = 0, revision = 0, current = 0;
7534
7685
  let previous;
@@ -7559,7 +7710,7 @@ function createNumberMotion(apply) {
7559
7710
  if (from === target) return;
7560
7711
  const tick = (now) => {
7561
7712
  if (version !== revision) return;
7562
- const progress = Math.min(1, Math.max(0, (now - started) / tokens41.motion.number));
7713
+ const progress = Math.min(1, Math.max(0, (now - started) / tokens42.motion.number));
7563
7714
  show(progress === 1 ? target : from + (target - from) * (1 - Math.pow(1 - progress, 3)));
7564
7715
  if (progress < 1) frame = requestAnimationFrame(tick);
7565
7716
  };
@@ -7572,7 +7723,7 @@ function createNumberMotion(apply) {
7572
7723
  // shared/package-runtime/use-number-motion.ts
7573
7724
  function useNumberMotion(value, animated, fromPrevious, reduced) {
7574
7725
  const [display, setDisplay] = useState34(typeof value === "string" || fromPrevious || !animated || reduced ? value : 0);
7575
- const motion = useRef31(null);
7726
+ const motion = useRef34(null);
7576
7727
  if (!motion.current) motion.current = createNumberMotion(setDisplay);
7577
7728
  useLayoutEffect16(() => {
7578
7729
  if (!motion.current) motion.current = createNumberMotion(setDisplay);
@@ -7648,7 +7799,7 @@ function KjunFreshness({
7648
7799
  KjunTooltip,
7649
7800
  {
7650
7801
  content: (source === "close" ? scope.messages.noRealtimeQuote : scope.messages.realtimeDelayed) + (fetchedAt ? " \xB7 " + ((formatter == null ? void 0 : formatter(fetchedAt)) || formatRelativeTime(fetchedAt, void 0, scope)) : ""),
7651
- children: /* @__PURE__ */ jsx42(AccessiblePressable, { accessibilityLabel: label, focusRingRadius: tokens42.extensions.badge.radius, children: /* @__PURE__ */ jsx42(KjunBadge, { variant: "warning", size: "xs", children: label }) })
7802
+ children: /* @__PURE__ */ jsx42(AccessiblePressable, { accessibilityLabel: label, focusRingRadius: tokens43.extensions.badge.radius, children: /* @__PURE__ */ jsx42(KjunBadge, { variant: "warning", size: "xs", children: label }) })
7652
7803
  }
7653
7804
  ) : null;
7654
7805
  }
@@ -7662,11 +7813,11 @@ function KjunPriceCell({
7662
7813
  fromPrevious = true
7663
7814
  }) {
7664
7815
  const { colors } = useKjunStyles(), quoteType = useContext18(MarketQuoteTypeContext);
7665
- return value == null ? /* @__PURE__ */ jsx42(KjunSkeleton, { type: "block", height: tokens42.extensions.financial.priceSkeletonHeight, width: tokens42.extensions.financial.priceSkeletonWidth }) : /* @__PURE__ */ jsxs28(View35, { style: { flexDirection: "row", alignItems: "center", gap: tokens42.extensions.financial.affixGap }, children: [
7816
+ return value == null ? /* @__PURE__ */ jsx42(KjunSkeleton, { type: "block", height: tokens43.extensions.financial.priceSkeletonHeight, width: tokens43.extensions.financial.priceSkeletonWidth }) : /* @__PURE__ */ jsxs28(View35, { style: { flexDirection: "row", alignItems: "center", gap: tokens43.extensions.financial.affixGap }, children: [
7666
7817
  /* @__PURE__ */ jsx42(
7667
7818
  View35,
7668
7819
  {
7669
- style: quoteType ? void 0 : { paddingVertical: tokens42.extensions.financial.pillPaddingY, paddingHorizontal: tokens42.extensions.financial.pillPaddingX, borderRadius: tokens42.radius.radius9999 },
7820
+ style: quoteType ? void 0 : { paddingVertical: tokens43.extensions.financial.pillPaddingY, paddingHorizontal: tokens43.extensions.financial.pillPaddingX, borderRadius: tokens43.radius.radius9999 },
7670
7821
  children: /* @__PURE__ */ jsx42(
7671
7822
  KjunAnimatedNumber,
7672
7823
  {
@@ -7705,14 +7856,14 @@ function KjunSignedValue({
7705
7856
  flexDirection: "row",
7706
7857
  alignItems: "center",
7707
7858
  alignSelf: "flex-start",
7708
- gap: tokens42.extensions.financial.affixGap,
7709
- paddingVertical: tone === "pill" ? tokens42.extensions.financial.pillPaddingY : 0,
7710
- paddingHorizontal: tone === "pill" ? tokens42.extensions.financial.pillPaddingX : 0,
7711
- borderRadius: tokens42.extensions.financial.pillRadius,
7859
+ gap: tokens43.extensions.financial.affixGap,
7860
+ paddingVertical: tone === "pill" ? tokens43.extensions.financial.pillPaddingY : 0,
7861
+ paddingHorizontal: tone === "pill" ? tokens43.extensions.financial.pillPaddingX : 0,
7862
+ borderRadius: tokens43.extensions.financial.pillRadius,
7712
7863
  backgroundColor: tone === "pill" && !stale && !loading && n !== null ? domainColor(domainColors, role + "Bg") : void 0
7713
7864
  },
7714
7865
  children: [
7715
- loading ? /* @__PURE__ */ jsx42(KjunSkeleton, { type: "block", width: tokens42.extensions.financial.signedSkeletonWidth, height: tokens42.extensions.financial.signedSkeletonHeight }) : /* @__PURE__ */ jsx42(
7866
+ loading ? /* @__PURE__ */ jsx42(KjunSkeleton, { type: "block", width: tokens43.extensions.financial.signedSkeletonWidth, height: tokens43.extensions.financial.signedSkeletonHeight }) : /* @__PURE__ */ jsx42(
7716
7867
  KText,
7717
7868
  {
7718
7869
  style: {
@@ -7734,7 +7885,7 @@ function KjunSignedValue({
7734
7885
 
7735
7886
  // packages/native/src/financial-display.tsx
7736
7887
  import { Fragment as Fragment14, jsx as jsx43, jsxs as jsxs29 } from "react/jsx-runtime";
7737
- var deviationFill = { neutral: 1, low: tokens43.states.opacity.deviationLow, medium: tokens43.states.opacity.deviationMedium, strong: tokens43.states.opacity.deviationStrong };
7888
+ var deviationFill = { neutral: 1, low: tokens44.states.opacity.deviationLow, medium: tokens44.states.opacity.deviationMedium, strong: tokens44.states.opacity.deviationStrong };
7738
7889
  function KjunDeviation({
7739
7890
  value,
7740
7891
  variant = "pill",
@@ -7755,7 +7906,7 @@ function KjunDeviation({
7755
7906
  flexDirection: "row",
7756
7907
  alignItems: "center",
7757
7908
  justifyContent: "flex-end",
7758
- gap: tokens43.extensions.financial.badgeGap
7909
+ gap: tokens44.extensions.financial.badgeGap
7759
7910
  },
7760
7911
  children: [
7761
7912
  /* @__PURE__ */ jsx43(
@@ -7774,22 +7925,22 @@ function KjunDeviation({
7774
7925
  }, children: label })
7775
7926
  }
7776
7927
  ),
7777
- !signal && /* @__PURE__ */ jsx43(View36, { style: { width: tokens43.extensions.financial.warningIconSize, flexShrink: 0 } }),
7928
+ !signal && /* @__PURE__ */ jsx43(View36, { style: { width: tokens44.extensions.financial.warningIconSize, flexShrink: 0 } }),
7778
7929
  signal && /* @__PURE__ */ jsx43(Fragment14, { children: /* @__PURE__ */ jsx43(View36, { style: { alignSelf: "center" }, children: /* @__PURE__ */ jsx43(KjunTooltip, { content: m.deviationWarning(signalThreshold), children: /* @__PURE__ */ jsx43(
7779
7930
  AccessiblePressable,
7780
7931
  {
7781
7932
  accessibilityRole: "image",
7782
7933
  accessibilityLabel: m.arbitrage,
7783
7934
  focusRingInset: true,
7784
- focusRingRadius: tokens43.radius.radius4,
7935
+ focusRingRadius: tokens44.radius.radius4,
7785
7936
  style: {
7786
- width: tokens43.extensions.financial.warningTargetSize,
7787
- height: tokens43.extensions.financial.warningTargetSize,
7788
- margin: (tokens43.extensions.financial.warningIconSize - tokens43.extensions.financial.warningTargetSize) / 2,
7937
+ width: tokens44.extensions.financial.warningTargetSize,
7938
+ height: tokens44.extensions.financial.warningTargetSize,
7939
+ margin: (tokens44.extensions.financial.warningIconSize - tokens44.extensions.financial.warningTargetSize) / 2,
7789
7940
  alignItems: "center",
7790
7941
  justifyContent: "center"
7791
7942
  },
7792
- children: /* @__PURE__ */ jsx43(KjunIcon, { name: "alert-triangle", size: tokens43.extensions.financial.warningIconSize, color: colors.warning })
7943
+ children: /* @__PURE__ */ jsx43(KjunIcon, { name: "alert-triangle", size: tokens44.extensions.financial.warningIconSize, color: colors.warning })
7793
7944
  }
7794
7945
  ) }) }) })
7795
7946
  ]
@@ -7801,9 +7952,9 @@ function KjunDeviation({
7801
7952
  style: {
7802
7953
  alignSelf: "flex-start",
7803
7954
  position: "relative",
7804
- borderRadius: tokens43.extensions.financial.cellRadius,
7805
- paddingVertical: variant === "pill" ? tokens43.extensions.financial.pillPaddingY : 0,
7806
- paddingHorizontal: variant === "pill" ? tokens43.extensions.financial.pillPaddingX : 0
7955
+ borderRadius: tokens44.extensions.financial.cellRadius,
7956
+ paddingVertical: variant === "pill" ? tokens44.extensions.financial.pillPaddingY : 0,
7957
+ paddingHorizontal: variant === "pill" ? tokens44.extensions.financial.pillPaddingX : 0
7807
7958
  },
7808
7959
  children: [
7809
7960
  variant === "pill" && /* @__PURE__ */ jsx43(
@@ -7813,7 +7964,7 @@ function KjunDeviation({
7813
7964
  style: {
7814
7965
  position: "absolute",
7815
7966
  inset: 0,
7816
- borderRadius: tokens43.extensions.financial.cellRadius,
7967
+ borderRadius: tokens44.extensions.financial.cellRadius,
7817
7968
  backgroundColor: neutral ? colors.secondary : color,
7818
7969
  opacity: deviationFill[level]
7819
7970
  }
@@ -7854,9 +8005,9 @@ function KjunHeatmapCell({
7854
8005
  style: {
7855
8006
  position: "relative",
7856
8007
  alignSelf: "flex-start",
7857
- paddingVertical: tokens43.extensions.financial.pillPaddingY,
7858
- paddingHorizontal: tokens43.extensions.financial.pillPaddingX,
7859
- borderRadius: tokens43.extensions.financial.cellRadius
8008
+ paddingVertical: tokens44.extensions.financial.pillPaddingY,
8009
+ paddingHorizontal: tokens44.extensions.financial.pillPaddingX,
8010
+ borderRadius: tokens44.extensions.financial.cellRadius
7860
8011
  },
7861
8012
  children: [
7862
8013
  /* @__PURE__ */ jsx43(
@@ -7866,10 +8017,10 @@ function KjunHeatmapCell({
7866
8017
  style: {
7867
8018
  position: "absolute",
7868
8019
  inset: 0,
7869
- borderRadius: tokens43.extensions.financial.cellRadius,
8020
+ borderRadius: tokens44.extensions.financial.cellRadius,
7870
8021
  // A zero cell keeps its shape on the neutral fill; any other value starts from a visible minimum.
7871
8022
  backgroundColor: magnitude ? background : colors.secondary,
7872
- opacity: magnitude ? tokens43.states.opacity.heatMinimum + (tokens43.states.opacity.heatMaximum - tokens43.states.opacity.heatMinimum) * magnitude : 1
8023
+ opacity: magnitude ? tokens44.states.opacity.heatMinimum + (tokens44.states.opacity.heatMaximum - tokens44.states.opacity.heatMinimum) * magnitude : 1
7873
8024
  }
7874
8025
  }
7875
8026
  ),
@@ -7887,7 +8038,7 @@ function KjunProgressCell({
7887
8038
  showLabel = true,
7888
8039
  color = "auto",
7889
8040
  customColor,
7890
- height = tokens43.extensions.financial.progressHeight
8041
+ height = tokens44.extensions.financial.progressHeight
7891
8042
  }) {
7892
8043
  const { colors, numericFontFamily, fontFamily } = useKjunStyles(), percent = max > 0 && Number.isFinite(value) ? Math.min(100, Math.max(0, value / max * 100)) : 0, role = color === "auto" ? percent < 30 ? "danger" : percent < 70 ? "warning" : "success" : color;
7893
8044
  return /* @__PURE__ */ jsxs29(
@@ -7896,8 +8047,8 @@ function KjunProgressCell({
7896
8047
  style: {
7897
8048
  flexDirection: "row",
7898
8049
  alignItems: "center",
7899
- gap: tokens43.extensions.financial.progressGap,
7900
- minWidth: tokens43.extensions.financial.progressMinimumWidth
8050
+ gap: tokens44.extensions.financial.progressGap,
8051
+ minWidth: tokens44.extensions.financial.progressMinimumWidth
7901
8052
  },
7902
8053
  children: [
7903
8054
  /* @__PURE__ */ jsx43(
@@ -7907,7 +8058,7 @@ function KjunProgressCell({
7907
8058
  height,
7908
8059
  flex: 1,
7909
8060
  backgroundColor: colors.tertiary,
7910
- borderRadius: tokens43.extensions.financial.progressRadius,
8061
+ borderRadius: tokens44.extensions.financial.progressRadius,
7911
8062
  overflow: "hidden"
7912
8063
  },
7913
8064
  children: /* @__PURE__ */ jsx43(
@@ -7916,7 +8067,7 @@ function KjunProgressCell({
7916
8067
  style: {
7917
8068
  width: `${percent}%`,
7918
8069
  height: "100%",
7919
- borderRadius: tokens43.extensions.financial.progressRadius,
8070
+ borderRadius: tokens44.extensions.financial.progressRadius,
7920
8071
  backgroundColor: color === "custom" ? customColor : colors[role]
7921
8072
  }
7922
8073
  }
@@ -7929,7 +8080,7 @@ function KjunProgressCell({
7929
8080
  style: {
7930
8081
  ...typeStyle("caption"),
7931
8082
  color: colors.textSecondary,
7932
- minWidth: tokens43.extensions.financial.progressLabelWidth,
8083
+ minWidth: tokens44.extensions.financial.progressLabelWidth,
7933
8084
  textAlign: "right",
7934
8085
  fontFamily: numericFontFamily || fontFamily,
7935
8086
  fontVariant: ["tabular-nums"]
@@ -7950,7 +8101,7 @@ function KjunCollectionMark({
7950
8101
  size = "md"
7951
8102
  }) {
7952
8103
  const { colors, domainColors } = useKjunStyles();
7953
- const box = tokens43.extensions.financial.markSizes[size], glyph = kind === "interest" ? tokens43.extensions.financial.heartMarkSizes[size] : box;
8104
+ const box = tokens44.extensions.financial.markSizes[size], glyph = kind === "interest" ? tokens44.extensions.financial.heartMarkSizes[size] : box;
7954
8105
  return /* @__PURE__ */ jsx43(View36, { style: { width: box, height: box, alignItems: "center", justifyContent: "center", overflow: "visible" }, children: /* @__PURE__ */ jsx43(
7955
8106
  KjunIcon,
7956
8107
  {
@@ -7982,8 +8133,8 @@ function KjunExecutionStatusBadge({
7982
8133
  }
7983
8134
  function KjunSparkline({
7984
8135
  data = [],
7985
- width = tokens43.extensions.financial.sparklineWidth,
7986
- height = tokens43.extensions.financial.sparklineHeight,
8136
+ width = tokens44.extensions.financial.sparklineWidth,
8137
+ height = tokens44.extensions.financial.sparklineHeight,
7987
8138
  color,
7988
8139
  semantic = "price",
7989
8140
  fill = true,
@@ -8037,7 +8188,7 @@ function KjunSparkline({
8037
8188
 
8038
8189
  // shared/package-runtime/table.ts
8039
8190
  import { nextTableSort } from "@kjun-ui/tokens";
8040
- import { useEffect as useEffect25, useRef as useRef33, useState as useState36 } from "react";
8191
+ import { useEffect as useEffect26, useRef as useRef36, useState as useState36 } from "react";
8041
8192
 
8042
8193
  // shared/package-runtime/table-model.ts
8043
8194
  function getValue(row, key) {
@@ -8084,8 +8235,8 @@ function useTableModel(props) {
8084
8235
  const [internalSort, setSort] = useState36({
8085
8236
  key: "",
8086
8237
  order: "asc"
8087
- }), [internalExpanded, setExpanded] = useState36([]), [search, setSearch] = useState36(""), timer = useRef33(void 0);
8088
- useEffect25(() => () => clearTimeout(timer.current), []);
8238
+ }), [internalExpanded, setExpanded] = useState36([]), [search, setSearch] = useState36(""), timer = useRef36(void 0);
8239
+ useEffect26(() => () => clearTimeout(timer.current), []);
8089
8240
  const sort = props.sort === void 0 ? internalSort : (_a = props.sort) != null ? _a : { key: "", order: "asc" };
8090
8241
  const rows = sortTableRows(data, sort, { sortable, sortMode });
8091
8242
  const key = (row, index = 0) => tableRowKey(row, rowKey, index);
@@ -8174,7 +8325,7 @@ function tableCellValue(props, column, row, index) {
8174
8325
  }
8175
8326
 
8176
8327
  // packages/native/src/table-toolbar.tsx
8177
- import { tokens as tokens44 } from "@kjun-ui/tokens";
8328
+ import { tokens as tokens45 } from "@kjun-ui/tokens";
8178
8329
  import { View as View37 } from "react-native";
8179
8330
  import { Fragment as Fragment15, jsx as jsx44, jsxs as jsxs30 } from "react/jsx-runtime";
8180
8331
  function TableToolbar({
@@ -8194,12 +8345,12 @@ function TableToolbar({
8194
8345
  const toolbarStyle = {
8195
8346
  flexDirection: "row",
8196
8347
  alignItems: "center",
8197
- gap: tokens44.dimension.value8,
8348
+ gap: tokens45.dimension.value8,
8198
8349
  flexWrap: "wrap",
8199
- paddingVertical: tokens44.dimension.value8,
8200
- paddingHorizontal: tokens44.dimension.value12,
8350
+ paddingVertical: tokens45.dimension.value8,
8351
+ paddingHorizontal: tokens45.dimension.value12,
8201
8352
  backgroundColor: colors.secondary,
8202
- borderBottomWidth: tokens44.border.defaultWidth,
8353
+ borderBottomWidth: tokens45.border.defaultWidth,
8203
8354
  borderBottomColor: colors.border
8204
8355
  };
8205
8356
  return /* @__PURE__ */ jsxs30(Fragment15, { children: [
@@ -8227,7 +8378,7 @@ function TableToolbar({
8227
8378
  ),
8228
8379
  (searchable || toolbar) && // Like Web: the search toolbar sits on the surface so the filled search field stands out from it.
8229
8380
  /* @__PURE__ */ jsxs30(View37, { style: { ...toolbarStyle, backgroundColor: colors.surface }, children: [
8230
- searchable && /* @__PURE__ */ jsx44(View37, { style: { width: tokens44.table.searchWidth, maxWidth: "100%" }, children: /* @__PURE__ */ jsx44(
8381
+ searchable && /* @__PURE__ */ jsx44(View37, { style: { width: tokens45.table.searchWidth, maxWidth: "100%" }, children: /* @__PURE__ */ jsx44(
8231
8382
  KjunInput,
8232
8383
  {
8233
8384
  size: "sm",
@@ -8245,7 +8396,7 @@ function TableToolbar({
8245
8396
  }
8246
8397
 
8247
8398
  // packages/native/src/table-grid.tsx
8248
- import { tokens as tokens45 } from "@kjun-ui/tokens";
8399
+ import { tokens as tokens46 } from "@kjun-ui/tokens";
8249
8400
  import { Fragment as Fragment16, useId as useId9, useState as useState37 } from "react";
8250
8401
  import Svg7, { Defs as Defs3, LinearGradient as LinearGradient3, Rect as Rect3, Stop as Stop3 } from "react-native-svg";
8251
8402
  import { ScrollView as ScrollView9, View as View38 } from "react-native";
@@ -8253,7 +8404,7 @@ import { jsx as jsx45, jsxs as jsxs31 } from "react/jsx-runtime";
8253
8404
  function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowClick, selectable, checkbox, cell, expandable, expand, renderExpand, emptyContent, emptyText, visible, maxHeight, stickyHeader, sortable, compact, striped, hoverable }) {
8254
8405
  const m = useKjunMessages();
8255
8406
  const { colors } = useKjunStyles();
8256
- const geometry2 = tokens45.table;
8407
+ const geometry2 = tokens46.table;
8257
8408
  const [scroll, setScroll] = useState37({ viewport: 0, x: 0 }), fadeId = "kjun-table-fade-" + useId9().replace(/[^a-z0-9]/gi, "");
8258
8409
  const cellPadding = geometry2.cellPadding[compact ? "compact" : "regular"];
8259
8410
  const width = (col) => typeof col.width === "number" ? col.width : typeof col.width === "string" && /^\d+(px)?$/.test(col.width) ? parseFloat(col.width) : geometry2.columnWidth;
@@ -8286,7 +8437,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8286
8437
  style: {
8287
8438
  flexDirection: "row",
8288
8439
  backgroundColor: colors.tableHeaderBg,
8289
- borderBottomWidth: tokens45.border.defaultWidth,
8440
+ borderBottomWidth: tokens46.border.defaultWidth,
8290
8441
  borderBottomColor: colors.border
8291
8442
  },
8292
8443
  children: [
@@ -8310,13 +8461,13 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8310
8461
  onPress: () => state.sortColumn(col),
8311
8462
  style: {
8312
8463
  width: width(col),
8313
- minHeight: tokens45.native.minimumTouchTarget,
8464
+ minHeight: tokens46.native.minimumTouchTarget,
8314
8465
  paddingVertical: geometry2.headerPadding.y,
8315
8466
  paddingHorizontal: geometry2.headerPadding.x,
8316
8467
  flexDirection: "row",
8317
8468
  alignItems: "center",
8318
8469
  justifyContent: col.align === "right" ? "flex-end" : col.align === "center" ? "center" : "flex-start",
8319
- gap: tokens45.dimension.value4
8470
+ gap: tokens46.dimension.value4
8320
8471
  },
8321
8472
  children: [
8322
8473
  /* @__PURE__ */ jsx45(
@@ -8333,7 +8484,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8333
8484
  KjunIcon,
8334
8485
  {
8335
8486
  name: state.sort.order === "asc" ? "sort-ascending" : "sort-descending",
8336
- size: tokens45.table.sortIconSize,
8487
+ size: tokens46.table.sortIconSize,
8337
8488
  color: colors.text
8338
8489
  }
8339
8490
  )
@@ -8360,7 +8511,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8360
8511
  {
8361
8512
  type: "block",
8362
8513
  height: geometry2.skeletonHeight,
8363
- width: col.key === "actions" ? tokens45.table.actionColumnWidth : "75%"
8514
+ width: col.key === "actions" ? tokens46.table.actionColumnWidth : "75%"
8364
8515
  }
8365
8516
  )
8366
8517
  },
@@ -8376,7 +8527,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8376
8527
  onPress: () => onRowClick == null ? void 0 : onRowClick(row, i),
8377
8528
  style: ({ pressed }) => ({
8378
8529
  flexDirection: "row",
8379
- borderBottomWidth: tokens45.border.defaultWidth,
8530
+ borderBottomWidth: tokens46.border.defaultWidth,
8380
8531
  borderBottomColor: colors.border,
8381
8532
  backgroundColor: pressed && hoverable ? colors.tableRowHover : striped && i % 2 ? colors.secondary : void 0
8382
8533
  }),
@@ -8436,7 +8587,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8436
8587
  )
8437
8588
  }
8438
8589
  ),
8439
- fade && /* @__PURE__ */ jsx45(View38, { pointerEvents: "none", style: { position: "absolute", top: 0, right: 0, bottom: 0, width: tokens45.extensions.scrollFade.width }, children: /* @__PURE__ */ jsxs31(Svg7, { width: "100%", height: "100%", children: [
8590
+ fade && /* @__PURE__ */ jsx45(View38, { pointerEvents: "none", style: { position: "absolute", top: 0, right: 0, bottom: 0, width: tokens46.extensions.scrollFade.width }, children: /* @__PURE__ */ jsxs31(Svg7, { width: "100%", height: "100%", children: [
8440
8591
  /* @__PURE__ */ jsx45(Defs3, { children: /* @__PURE__ */ jsxs31(LinearGradient3, { id: fadeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
8441
8592
  /* @__PURE__ */ jsx45(Stop3, { offset: "0", stopColor: colors.surface, stopOpacity: 0 }),
8442
8593
  /* @__PURE__ */ jsx45(Stop3, { offset: "1", stopColor: colors.surface, stopOpacity: 1 })
@@ -8447,14 +8598,14 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
8447
8598
  }
8448
8599
 
8449
8600
  // packages/native/src/table-view.tsx
8450
- import { tokens as tokens47 } from "@kjun-ui/tokens";
8601
+ import { tokens as tokens48 } from "@kjun-ui/tokens";
8451
8602
  import {
8452
8603
  View as View40,
8453
8604
  useWindowDimensions as useWindowDimensions7
8454
8605
  } from "react-native";
8455
8606
 
8456
8607
  // packages/native/src/table-cards.tsx
8457
- import { tokens as tokens46 } from "@kjun-ui/tokens";
8608
+ import { tokens as tokens47 } from "@kjun-ui/tokens";
8458
8609
  import {
8459
8610
  View as View39
8460
8611
  } from "react-native";
@@ -8480,7 +8631,7 @@ function TableCards({
8480
8631
  return /* @__PURE__ */ jsxs32(
8481
8632
  View39,
8482
8633
  {
8483
- style: { gap: tokens46.extensions.tableCard.gap, padding: tokens46.extensions.tableCard.listPadding, opacity: skeletonHidden ? 0 : void 0 },
8634
+ style: { gap: tokens47.extensions.tableCard.gap, padding: tokens47.extensions.tableCard.listPadding, opacity: skeletonHidden ? 0 : void 0 },
8484
8635
  "aria-hidden": skeletonHidden || void 0,
8485
8636
  children: [
8486
8637
  initialLoading ? Array.from({ length: skeletonRows }, (_, i) => /* @__PURE__ */ jsx46(KjunSkeleton, { type: "card" }, i)) : state.rows.map((row, i) => /* @__PURE__ */ jsxs32(
@@ -8489,10 +8640,10 @@ function TableCards({
8489
8640
  accessible: false,
8490
8641
  onPress: () => onRowClick == null ? void 0 : onRowClick(row, i),
8491
8642
  style: ({ pressed }) => ({
8492
- padding: tokens46.extensions.tableCard.padding,
8493
- borderWidth: tokens46.border.defaultWidth,
8643
+ padding: tokens47.extensions.tableCard.padding,
8644
+ borderWidth: tokens47.border.defaultWidth,
8494
8645
  borderColor: colors.border,
8495
- borderRadius: tokens46.extensions.tableCard.radius,
8646
+ borderRadius: tokens47.extensions.tableCard.radius,
8496
8647
  backgroundColor: pressed ? colors.hover : colors.background
8497
8648
  }),
8498
8649
  children: [
@@ -8502,8 +8653,8 @@ function TableCards({
8502
8653
  style: {
8503
8654
  flexDirection: "row",
8504
8655
  alignItems: "center",
8505
- gap: tokens46.extensions.tableCard.gap,
8506
- marginBottom: tokens46.dimension.value8
8656
+ gap: tokens47.extensions.tableCard.gap,
8657
+ marginBottom: tokens47.dimension.value8
8507
8658
  },
8508
8659
  children: [
8509
8660
  /* @__PURE__ */ jsxs32(
@@ -8513,7 +8664,7 @@ function TableCards({
8513
8664
  flexDirection: "row",
8514
8665
  flex: 1,
8515
8666
  alignItems: "center",
8516
- gap: tokens46.extensions.tableCard.gap,
8667
+ gap: tokens47.extensions.tableCard.gap,
8517
8668
  minWidth: 0
8518
8669
  },
8519
8670
  children: [
@@ -8522,8 +8673,8 @@ function TableCards({
8522
8673
  ]
8523
8674
  }
8524
8675
  ),
8525
- badges.length ? /* @__PURE__ */ jsx46(View39, { style: { flexDirection: "row", gap: tokens46.extensions.tableCard.fieldGap }, children: badges.map((col) => /* @__PURE__ */ jsx46(View39, { children: cell(col, row, i) }, col.key)) }) : subtitle ? cell(subtitle, row, i) : null,
8526
- inline.length > 0 && /* @__PURE__ */ jsx46(View39, { style: { flexDirection: "row", gap: tokens46.extensions.tableCard.fieldGap }, children: inline.map((col) => /* @__PURE__ */ jsx46(View39, { children: cell(col, row, i) }, col.key)) })
8676
+ badges.length ? /* @__PURE__ */ jsx46(View39, { style: { flexDirection: "row", gap: tokens47.extensions.tableCard.fieldGap }, children: badges.map((col) => /* @__PURE__ */ jsx46(View39, { children: cell(col, row, i) }, col.key)) }) : subtitle ? cell(subtitle, row, i) : null,
8677
+ inline.length > 0 && /* @__PURE__ */ jsx46(View39, { style: { flexDirection: "row", gap: tokens47.extensions.tableCard.fieldGap }, children: inline.map((col) => /* @__PURE__ */ jsx46(View39, { children: cell(col, row, i) }, col.key)) })
8527
8678
  ]
8528
8679
  }
8529
8680
  ),
@@ -8533,10 +8684,10 @@ function TableCards({
8533
8684
  View39,
8534
8685
  {
8535
8686
  style: {
8536
- borderTopWidth: index ? tokens46.border.defaultWidth : 0,
8687
+ borderTopWidth: index ? tokens47.border.defaultWidth : 0,
8537
8688
  borderTopColor: colors.border,
8538
- paddingTop: index ? tokens46.dimension.value12 : 0,
8539
- marginTop: index ? tokens46.dimension.value12 : 0
8689
+ paddingTop: index ? tokens47.dimension.value12 : 0,
8690
+ marginTop: index ? tokens47.dimension.value12 : 0
8540
8691
  },
8541
8692
  children: [
8542
8693
  !!section.label && /* @__PURE__ */ jsx46(
@@ -8545,7 +8696,7 @@ function TableCards({
8545
8696
  style: {
8546
8697
  ...typeStyle("controlSmall"),
8547
8698
  color: colors.textTertiary,
8548
- marginBottom: tokens46.dimension.value6
8699
+ marginBottom: tokens47.dimension.value6
8549
8700
  },
8550
8701
  children: section.label
8551
8702
  }
@@ -8556,7 +8707,7 @@ function TableCards({
8556
8707
  style: {
8557
8708
  flexDirection: "row",
8558
8709
  flexWrap: "wrap",
8559
- gap: section.layout === "metrics" ? tokens46.extensions.tableCard.gap : tokens46.extensions.tableCard.metricGap
8710
+ gap: section.layout === "metrics" ? tokens47.extensions.tableCard.gap : tokens47.extensions.tableCard.metricGap
8560
8711
  },
8561
8712
  children: cols.map((col) => /* @__PURE__ */ jsxs32(
8562
8713
  View39,
@@ -8565,7 +8716,7 @@ function TableCards({
8565
8716
  flexBasis: col.fullWidthInCard || section.layout === "stack" ? "100%" : section.layout === "metrics" ? "30%" : "47%",
8566
8717
  flexGrow: 1,
8567
8718
  minWidth: 0,
8568
- gap: tokens46.extensions.tableCard.valueGap
8719
+ gap: tokens47.extensions.tableCard.valueGap
8569
8720
  },
8570
8721
  children: [
8571
8722
  /* @__PURE__ */ jsx46(
@@ -8596,10 +8747,10 @@ function TableCards({
8596
8747
  View39,
8597
8748
  {
8598
8749
  style: {
8599
- borderTopWidth: tokens46.border.defaultWidth,
8750
+ borderTopWidth: tokens47.border.defaultWidth,
8600
8751
  borderTopColor: colors.border,
8601
- paddingTop: tokens46.dimension.value8,
8602
- marginTop: tokens46.dimension.value4
8752
+ paddingTop: tokens47.dimension.value8,
8753
+ marginTop: tokens47.dimension.value4
8603
8754
  },
8604
8755
  children: content(renderExpand == null ? void 0 : renderExpand(row, i))
8605
8756
  }
@@ -8608,10 +8759,10 @@ function TableCards({
8608
8759
  View39,
8609
8760
  {
8610
8761
  style: {
8611
- borderTopWidth: tokens46.border.defaultWidth,
8762
+ borderTopWidth: tokens47.border.defaultWidth,
8612
8763
  borderTopColor: colors.border,
8613
- paddingTop: tokens46.dimension.value8,
8614
- marginTop: tokens46.dimension.value8,
8764
+ paddingTop: tokens47.dimension.value8,
8765
+ marginTop: tokens47.dimension.value8,
8615
8766
  alignItems: "flex-end"
8616
8767
  },
8617
8768
  children: /* @__PURE__ */ jsx46(View39, { style: { alignSelf: "flex-end" }, children: cell(actions, row, i) })
@@ -8621,7 +8772,7 @@ function TableCards({
8621
8772
  },
8622
8773
  state.key(row, i)
8623
8774
  )),
8624
- !initialLoading && !state.rows.length && /* @__PURE__ */ jsx46(View39, { style: { padding: tokens46.extensions.tableCard.emptyPadding, alignItems: "center" }, children: content(emptyContent || emptyText, {
8775
+ !initialLoading && !state.rows.length && /* @__PURE__ */ jsx46(View39, { style: { padding: tokens47.extensions.tableCard.emptyPadding, alignItems: "center" }, children: content(emptyContent || emptyText, {
8625
8776
  color: colors.textTertiary
8626
8777
  }) })
8627
8778
  ]
@@ -8658,7 +8809,7 @@ function KjunTable(props) {
8658
8809
  onRowClick,
8659
8810
  onRetry
8660
8811
  } = props;
8661
- const { colors, domainColors } = useKjunStyles(), state = useTableModel2(props), query = useQueryDisplay(props), revealed = useLoadingReveal(query.initialLoading, skeleton ? loadingDelay : 0), mobile = useWindowDimensions7().width < tokens47.table.mobileBreakpoint;
8812
+ const { colors, domainColors } = useKjunStyles(), state = useTableModel2(props), query = useQueryDisplay(props), revealed = useLoadingReveal(query.initialLoading, skeleton ? loadingDelay : 0), mobile = useWindowDimensions7().width < tokens48.table.mobileBreakpoint;
8662
8813
  const layout = tablePresentation(props, mobile);
8663
8814
  const { card, visible } = layout;
8664
8815
  const cell = (col, row, index, role) => {
@@ -8670,9 +8821,9 @@ function KjunTable(props) {
8670
8821
  {
8671
8822
  style: {
8672
8823
  alignSelf: "flex-start",
8673
- paddingVertical: tokens47.dimension.value2,
8674
- paddingHorizontal: tokens47.dimension.value8,
8675
- borderRadius: tokens47.radius.radius4,
8824
+ paddingVertical: tokens48.dimension.value2,
8825
+ paddingHorizontal: tokens48.dimension.value8,
8826
+ borderRadius: tokens48.radius.radius4,
8676
8827
  backgroundColor: role2 ? domainColor(domainColors, role2 + "Bg") : void 0
8677
8828
  },
8678
8829
  children: content(body, {
@@ -8775,7 +8926,7 @@ function KpiNumberLine({ prefix, suffix, prefixGap, suffixGap, style, unitStyle,
8775
8926
  }
8776
8927
 
8777
8928
  // packages/native/src/kpi-hero.tsx
8778
- import { tokens as tokens48 } from "@kjun-ui/tokens";
8929
+ import { tokens as tokens49 } from "@kjun-ui/tokens";
8779
8930
  import {
8780
8931
  View as View42,
8781
8932
  useWindowDimensions as useWindowDimensions8
@@ -8808,8 +8959,8 @@ function KjunKpiHero(props) {
8808
8959
  deltaFormatter,
8809
8960
  renderSecondary
8810
8961
  } = props;
8811
- const { colors, domainColors, numericFontFamily, fontFamily } = useKjunStyles(), windowWidth = useWindowDimensions8().width, mobile = windowWidth <= tokens48.responsive.kpiHero, small = size === "sm", numberRole = small ? "displaySm" : mobile ? "displayMd" : "displayLg", font = typeStyle(numberRole).fontSize, unitStyle = typeStyle(small ? "numberSm" : mobile ? "numberMd" : "numberLg");
8812
- const geometry2 = tokens48.extensions.kpiHero;
8962
+ const { colors, domainColors, numericFontFamily, fontFamily } = useKjunStyles(), windowWidth = useWindowDimensions8().width, mobile = windowWidth <= tokens49.responsive.kpiHero, small = size === "sm", numberRole = small ? "displaySm" : mobile ? "displayMd" : "displayLg", font = typeStyle(numberRole).fontSize, unitStyle = typeStyle(small ? "numberSm" : mobile ? "numberMd" : "numberLg");
8963
+ const geometry2 = tokens49.extensions.kpiHero;
8813
8964
  const spec = small ? geometry2.sm : mobile ? geometry2.mobile : geometry2.md;
8814
8965
  const numeric2 = {
8815
8966
  fontFamily: numericFontFamily || fontFamily,
@@ -8821,7 +8972,7 @@ function KjunKpiHero(props) {
8821
8972
  );
8822
8973
  const delta = (v, kind, style) => {
8823
8974
  if (deltaFormatter) return /* @__PURE__ */ jsx49(KText, { style, children: deltaFormatter(v, kind) });
8824
- const sign = v > 0 ? "+" : v < 0 ? "\u2212" : "", gap = tokens48.extensions.financial.affixGap, number = new Intl.NumberFormat(void 0, {
8975
+ const sign = v > 0 ? "+" : v < 0 ? "\u2212" : "", gap = tokens49.extensions.financial.affixGap, number = new Intl.NumberFormat(void 0, {
8825
8976
  minimumFractionDigits: kind === "absolute" ? decimals : 1,
8826
8977
  maximumFractionDigits: kind === "absolute" ? decimals : 1
8827
8978
  }).format(Math.abs(v));
@@ -8924,11 +9075,11 @@ function KjunKpiHero(props) {
8924
9075
  gap: small && mobile ? geometry2.smallMobileGap : spec.secondaryGap,
8925
9076
  marginTop: spec.secondaryMargin,
8926
9077
  paddingTop: spec.secondaryPadding,
8927
- borderTopWidth: tokens48.border.defaultWidth,
9078
+ borderTopWidth: tokens49.border.defaultWidth,
8928
9079
  borderTopColor: colors.border
8929
9080
  },
8930
9081
  children: secondary.map((item, i) => {
8931
- const columns = mobile && !small && windowWidth <= tokens48.responsive.kpiHeroSecondary && secondary.length >= 3 ? 2 : 0;
9082
+ const columns = mobile && !small && windowWidth <= tokens49.responsive.kpiHeroSecondary && secondary.length >= 3 ? 2 : 0;
8932
9083
  const first = columns ? i % columns === 0 : i === 0;
8933
9084
  const last = columns ? i % columns === columns - 1 || i === secondary.length - 1 : i === secondary.length - 1;
8934
9085
  return /* @__PURE__ */ jsxs35(
@@ -8939,7 +9090,7 @@ function KjunKpiHero(props) {
8939
9090
  minWidth: 0,
8940
9091
  paddingLeft: first ? 0 : geometry2.itemPadding,
8941
9092
  paddingRight: last ? 0 : geometry2.itemPadding,
8942
- borderLeftWidth: first ? 0 : tokens48.border.defaultWidth,
9093
+ borderLeftWidth: first ? 0 : tokens49.border.defaultWidth,
8943
9094
  borderLeftColor: colors.border
8944
9095
  } : { minWidth: 0, maxWidth: "100%", flexShrink: 1 },
8945
9096
  children: [
@@ -9004,7 +9155,7 @@ function KjunKpiHero(props) {
9004
9155
  }
9005
9156
 
9006
9157
  // packages/native/src/kpi-row.tsx
9007
- import { tokens as tokens49 } from "@kjun-ui/tokens";
9158
+ import { tokens as tokens50 } from "@kjun-ui/tokens";
9008
9159
  import { useState as useState38 } from "react";
9009
9160
  import {
9010
9161
  View as View43,
@@ -9020,8 +9171,8 @@ function KjunKpiRow({
9020
9171
  onItemClick,
9021
9172
  renderValue
9022
9173
  }) {
9023
- const { colors, domainColors, numericFontFamily, fontFamily } = useKjunStyles(), mobile = useWindowDimensions9().width <= tokens49.responsive.kpiRow, small = size === "sm", summary = mobileSummary && mobile && !small;
9024
- const geometry2 = tokens49.extensions.kpiRow;
9174
+ const { colors, domainColors, numericFontFamily, fontFamily } = useKjunStyles(), mobile = useWindowDimensions9().width <= tokens50.responsive.kpiRow, small = size === "sm", summary = mobileSummary && mobile && !small;
9175
+ const geometry2 = tokens50.extensions.kpiRow;
9025
9176
  const spec = small ? geometry2.sm : mobile ? geometry2.mobile : geometry2.md;
9026
9177
  const [width, setWidth] = useState38(0);
9027
9178
  const paddingX = summary ? geometry2.summary.paddingX : spec.paddingX;
@@ -9100,8 +9251,8 @@ function KjunKpiRow({
9100
9251
  minWidth: 0,
9101
9252
  paddingVertical: summary ? 0 : small && mobile ? geometry2.smallMobile.itemPaddingY : spec.itemPaddingY,
9102
9253
  paddingHorizontal: summary ? 0 : small && mobile ? geometry2.smallMobile.itemPaddingX : spec.itemPaddingX,
9103
- borderLeftWidth: summary ? 0 : mobile && !small ? i % 2 && !full ? tokens49.border.defaultWidth : 0 : i ? tokens49.border.defaultWidth : 0,
9104
- borderTopWidth: mobile && !small && !summary && i >= 2 ? tokens49.border.defaultWidth : 0,
9254
+ borderLeftWidth: summary ? 0 : mobile && !small ? i % 2 && !full ? tokens50.border.defaultWidth : 0 : i ? tokens50.border.defaultWidth : 0,
9255
+ borderTopWidth: mobile && !small && !summary && i >= 2 ? tokens50.border.defaultWidth : 0,
9105
9256
  borderColor: colors.border,
9106
9257
  borderRadius: item.clickable ? geometry2.itemRadius : 0,
9107
9258
  flexDirection: sub ? "row" : "column",
@@ -9144,7 +9295,7 @@ function KjunKpiRow({
9144
9295
  summary && seg.label && /* @__PURE__ */ jsx50(
9145
9296
  KText,
9146
9297
  {
9147
- style: { ...typeStyle("caption"), marginRight: sub ? tokens49.dimension.value4 : 0, color: colors.textTertiary },
9298
+ style: { ...typeStyle("caption"), marginRight: sub ? tokens50.dimension.value4 : 0, color: colors.textTertiary },
9148
9299
  children: seg.label
9149
9300
  }
9150
9301
  ),
@@ -9238,11 +9389,11 @@ function KjunKpiRow({
9238
9389
  }
9239
9390
 
9240
9391
  // packages/native/src/market-cards.tsx
9241
- import { tokens as tokens51 } from "@kjun-ui/tokens";
9392
+ import { tokens as tokens52 } from "@kjun-ui/tokens";
9242
9393
  import { ScrollView as ScrollView10, View as View45 } from "react-native";
9243
9394
 
9244
9395
  // shared/package-runtime/market-cards.ts
9245
- import { useEffect as useEffect26, useRef as useRef34, useState as useState39 } from "react";
9396
+ import { useEffect as useEffect27, useRef as useRef37, useState as useState39 } from "react";
9246
9397
  function useMarketCardsModel(props, persistence) {
9247
9398
  const {
9248
9399
  columns,
@@ -9259,7 +9410,7 @@ function useMarketCardsModel(props, persistence) {
9259
9410
  isDefaultSort: c.defaultSort
9260
9411
  }));
9261
9412
  const [key, setKey] = useState39(""), restoreSignature = JSON.stringify([storageNamespace, pills]);
9262
- const mounted = useRef34("");
9413
+ const mounted = useRef37("");
9263
9414
  const save = (key2) => {
9264
9415
  var _a;
9265
9416
  try {
@@ -9267,7 +9418,7 @@ function useMarketCardsModel(props, persistence) {
9267
9418
  } catch (e) {
9268
9419
  }
9269
9420
  };
9270
- useEffect26(() => {
9421
+ useEffect27(() => {
9271
9422
  var _a, _b;
9272
9423
  if (mounted.current === restoreSignature) return;
9273
9424
  mounted.current = restoreSignature;
@@ -9304,7 +9455,7 @@ function useMarketCards(props) {
9304
9455
  }
9305
9456
 
9306
9457
  // packages/native/src/market-parts.tsx
9307
- import { tokens as tokens50 } from "@kjun-ui/tokens";
9458
+ import { tokens as tokens51 } from "@kjun-ui/tokens";
9308
9459
  import { View as View44, useWindowDimensions as useWindowDimensions10 } from "react-native";
9309
9460
  import { Fragment as Fragment18, jsx as jsx51, jsxs as jsxs37 } from "react/jsx-runtime";
9310
9461
  function MarketIdentity({
@@ -9314,7 +9465,7 @@ function MarketIdentity({
9314
9465
  compact = false
9315
9466
  }) {
9316
9467
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
9317
- const { colors } = useKjunStyles(), mobile = useWindowDimensions10().width < tokens50.responsive.market && !table && !compact, label = (_c = (_a = props.primaryLabel) == null ? void 0 : _a.call(props, row)) != null ? _c : String((_b = getValue(row, "name")) != null ? _b : ""), meta = ((_d = props.subMeta) == null ? void 0 : _d.call(props, row)) || "", id = getValue(row, props.rowKey || "id");
9468
+ const { colors } = useKjunStyles(), mobile = useWindowDimensions10().width < tokens51.responsive.market && !table && !compact, label = (_c = (_a = props.primaryLabel) == null ? void 0 : _a.call(props, row)) != null ? _c : String((_b = getValue(row, "name")) != null ? _b : ""), meta = ((_d = props.subMeta) == null ? void 0 : _d.call(props, row)) || "", id = getValue(row, props.rowKey || "id");
9318
9469
  const body = /* @__PURE__ */ jsxs37(Fragment18, { children: [
9319
9470
  (_e = props.renderNamePrefix) == null ? void 0 : _e.call(props, row),
9320
9471
  /* @__PURE__ */ jsxs37(View44, { style: { flex: 1, minWidth: 0 }, children: [
@@ -9324,7 +9475,7 @@ function MarketIdentity({
9324
9475
  style: {
9325
9476
  flexDirection: "row",
9326
9477
  alignItems: "center",
9327
- gap: tokens50.dimension.value4,
9478
+ gap: tokens51.dimension.value4,
9328
9479
  minWidth: 0
9329
9480
  },
9330
9481
  children: [
@@ -9346,7 +9497,7 @@ function MarketIdentity({
9346
9497
  ]
9347
9498
  }
9348
9499
  ),
9349
- (meta || props.renderSubMeta) && /* @__PURE__ */ jsx51(View44, { style: { marginTop: tokens50.dimension.value2 }, children: ((_i = props.renderSubMeta) == null ? void 0 : _i.call(props, row)) || /* @__PURE__ */ jsx51(
9500
+ (meta || props.renderSubMeta) && /* @__PURE__ */ jsx51(View44, { style: { marginTop: tokens51.dimension.value2 }, children: ((_i = props.renderSubMeta) == null ? void 0 : _i.call(props, row)) || /* @__PURE__ */ jsx51(
9350
9501
  KText,
9351
9502
  {
9352
9503
  numberOfLines: 1,
@@ -9408,9 +9559,9 @@ function MarketFooter({
9408
9559
  flexWrap: "wrap",
9409
9560
  alignItems: "center",
9410
9561
  justifyContent: "space-between",
9411
- gap: tokens50.dimension.value8,
9412
- paddingVertical: tokens50.dimension.value12,
9413
- paddingHorizontal: tokens50.dimension.value16
9562
+ gap: tokens51.dimension.value8,
9563
+ paddingVertical: tokens51.dimension.value12,
9564
+ paddingHorizontal: tokens51.dimension.value16
9414
9565
  },
9415
9566
  children: [
9416
9567
  /* @__PURE__ */ jsx51(KText, { style: { ...typeStyle("caption"), color: colors.textTertiary }, children: calculatedAt ? m.lastUpdated + (((_a = props.formatDate) == null ? void 0 : _a.call(props, calculatedAt)) || calculatedAt) : footerNote }),
@@ -9456,9 +9607,9 @@ function KjunMarketCards(props) {
9456
9607
  showsHorizontalScrollIndicator: false,
9457
9608
  contentContainerStyle: {
9458
9609
  flexDirection: "row",
9459
- gap: tokens51.dimension.value8,
9460
- paddingVertical: tokens51.dimension.value10,
9461
- paddingHorizontal: tokens51.dimension.value16
9610
+ gap: tokens52.dimension.value8,
9611
+ paddingVertical: tokens52.dimension.value10,
9612
+ paddingHorizontal: tokens52.dimension.value16
9462
9613
  },
9463
9614
  children: state.pills.map((pill) => /* @__PURE__ */ jsxs38(
9464
9615
  AccessiblePressable,
@@ -9467,14 +9618,14 @@ function KjunMarketCards(props) {
9467
9618
  accessibilityLabel: pill.label,
9468
9619
  accessibilityState: { selected: state.key === pill.key },
9469
9620
  onPress: () => state.select(pill.key),
9470
- hitSlop: { top: (tokens51.native.minimumTouchTarget - typeStyle("label").lineHeight - 2 * tokens51.dimension.value8) / 2, bottom: (tokens51.native.minimumTouchTarget - typeStyle("label").lineHeight - 2 * tokens51.dimension.value8) / 2 },
9621
+ hitSlop: { top: (tokens52.native.minimumTouchTarget - typeStyle("label").lineHeight - 2 * tokens52.dimension.value8) / 2, bottom: (tokens52.native.minimumTouchTarget - typeStyle("label").lineHeight - 2 * tokens52.dimension.value8) / 2 },
9471
9622
  style: {
9472
9623
  flexDirection: "row",
9473
9624
  alignItems: "center",
9474
- gap: tokens51.dimension.value4,
9475
- paddingVertical: tokens51.dimension.value8,
9476
- paddingHorizontal: tokens51.dimension.value16,
9477
- borderRadius: tokens51.radius.radius9999,
9625
+ gap: tokens52.dimension.value4,
9626
+ paddingVertical: tokens52.dimension.value8,
9627
+ paddingHorizontal: tokens52.dimension.value16,
9628
+ borderRadius: tokens52.radius.radius9999,
9478
9629
  backgroundColor: state.key === pill.key ? colors.brand : colors.secondary
9479
9630
  },
9480
9631
  children: [
@@ -9510,7 +9661,7 @@ function KjunMarketCards(props) {
9510
9661
  loadingContent: props.skeleton === false ? void 0 : /* @__PURE__ */ jsx52(KjunListSkeleton, { variant: "compact" }),
9511
9662
  emptyContent: /* @__PURE__ */ jsx52(KjunEmpty, { text: emptyMessage, description: emptySubMessage }),
9512
9663
  children: /* @__PURE__ */ jsxs38(View45, { children: [
9513
- state.pill && /* @__PURE__ */ jsx52(KText, { style: { textAlign: "right", paddingHorizontal: tokens51.dimension.value16, paddingVertical: tokens51.dimension.value8, ...typeStyle("caption"), color: colors.textSecondary }, children: state.pill.label }),
9664
+ state.pill && /* @__PURE__ */ jsx52(KText, { style: { textAlign: "right", paddingHorizontal: tokens52.dimension.value16, paddingVertical: tokens52.dimension.value8, ...typeStyle("caption"), color: colors.textSecondary }, children: state.pill.label }),
9514
9665
  rows.map((row, i) => {
9515
9666
  var _a, _b, _c;
9516
9667
  return /* @__PURE__ */ jsxs38(
@@ -9525,22 +9676,22 @@ function KjunMarketCards(props) {
9525
9676
  flexDirection: "row",
9526
9677
  alignItems: "center",
9527
9678
  justifyContent: "space-between",
9528
- paddingVertical: tokens51.dimension.value10,
9529
- paddingHorizontal: tokens51.dimension.value16,
9530
- borderBottomWidth: tokens51.border.defaultWidth,
9679
+ paddingVertical: tokens52.dimension.value10,
9680
+ paddingHorizontal: tokens52.dimension.value16,
9681
+ borderBottomWidth: tokens52.border.defaultWidth,
9531
9682
  borderBottomColor: colors.border,
9532
9683
  backgroundColor: pressed ? colors.hover : void 0
9533
9684
  }),
9534
9685
  children: [
9535
9686
  /* @__PURE__ */ jsx52(MarketIdentity, { row, props, compact: true }),
9536
- /* @__PURE__ */ jsx52(View45, { style: { marginLeft: tokens51.dimension.value12, alignItems: "flex-end" }, children: ((_b = state.pill) == null ? void 0 : _b.format) === "sparkline" ? /* @__PURE__ */ jsx52(
9687
+ /* @__PURE__ */ jsx52(View45, { style: { marginLeft: tokens52.dimension.value12, alignItems: "flex-end" }, children: ((_b = state.pill) == null ? void 0 : _b.format) === "sparkline" ? /* @__PURE__ */ jsx52(
9537
9688
  KjunSparkline,
9538
9689
  {
9539
9690
  data: getValue(row, state.key) || [],
9540
- width: tokens51.extensions.marketTable.sparklineWidth,
9541
- height: tokens51.extensions.marketTable.sparklineHeight
9691
+ width: tokens52.extensions.marketTable.sparklineWidth,
9692
+ height: tokens52.extensions.marketTable.sparklineHeight
9542
9693
  }
9543
- ) : state.pill ? /* @__PURE__ */ jsx52(Fragment19, { children: metricLoading(row, state.key) ? /* @__PURE__ */ jsx52(KjunSkeleton, { type: "block", height: tokens51.extensions.marketTable.valueSkeletonHeight, width: tokens51.extensions.marketTable.valueSkeletonWidth }) : isChange && getValue(row, state.key) != null ? /* @__PURE__ */ jsx52(
9694
+ ) : state.pill ? /* @__PURE__ */ jsx52(Fragment19, { children: metricLoading(row, state.key) ? /* @__PURE__ */ jsx52(KjunSkeleton, { type: "block", height: tokens52.extensions.marketTable.valueSkeletonHeight, width: tokens52.extensions.marketTable.valueSkeletonWidth }) : isChange && getValue(row, state.key) != null ? /* @__PURE__ */ jsx52(
9544
9695
  KjunSignedValue,
9545
9696
  {
9546
9697
  value: finiteNumber(getValue(row, state.key)),
@@ -9548,14 +9699,14 @@ function KjunMarketCards(props) {
9548
9699
  stale: !!getValue(row, "stale"),
9549
9700
  tone: "pill"
9550
9701
  }
9551
- ) : isPrice && getValue(row, state.key) == null ? /* @__PURE__ */ jsx52(KjunSkeleton, { type: "block", height: tokens51.extensions.financial.priceSkeletonHeight, width: tokens51.extensions.financial.priceSkeletonWidth }) : /* @__PURE__ */ jsxs38(
9702
+ ) : isPrice && getValue(row, state.key) == null ? /* @__PURE__ */ jsx52(KjunSkeleton, { type: "block", height: tokens52.extensions.financial.priceSkeletonHeight, width: tokens52.extensions.financial.priceSkeletonWidth }) : /* @__PURE__ */ jsxs38(
9552
9703
  View45,
9553
9704
  {
9554
9705
  style: {
9555
9706
  flexDirection: "row",
9556
9707
  alignItems: "center",
9557
9708
  justifyContent: "flex-end",
9558
- gap: tokens51.dimension.value4
9709
+ gap: tokens52.dimension.value4
9559
9710
  },
9560
9711
  children: [
9561
9712
  (_c = props.renderMetricPrefix) == null ? void 0 : _c.call(
@@ -9592,7 +9743,7 @@ function KjunMarketCards(props) {
9592
9743
  }
9593
9744
 
9594
9745
  // packages/native/src/market-list.tsx
9595
- import { tokens as tokens52 } from "@kjun-ui/tokens";
9746
+ import { tokens as tokens53 } from "@kjun-ui/tokens";
9596
9747
  import { View as View46, useWindowDimensions as useWindowDimensions11 } from "react-native";
9597
9748
  import { jsx as jsx53, jsxs as jsxs39 } from "react/jsx-runtime";
9598
9749
  var changeWeight = { fontWeight: typeStyle("label").fontWeight };
@@ -9610,7 +9761,7 @@ function KjunMarketSimpleList(props) {
9610
9761
  closingPrice = false,
9611
9762
  emptyMessage = m.noItems,
9612
9763
  emptySubMessage = ""
9613
- } = props, { colors } = useKjunStyles(), mobile = useWindowDimensions11().width < tokens52.responsive.market;
9764
+ } = props, { colors } = useKjunStyles(), mobile = useWindowDimensions11().width < tokens53.responsive.market;
9614
9765
  return /* @__PURE__ */ jsxs39(View46, { children: [
9615
9766
  /* @__PURE__ */ jsx53(
9616
9767
  KjunDataState,
@@ -9636,11 +9787,11 @@ function KjunMarketSimpleList(props) {
9636
9787
  flexDirection: "row",
9637
9788
  alignItems: "center",
9638
9789
  justifyContent: "space-between",
9639
- paddingVertical: mobile ? tokens52.dimension.value14 : tokens52.dimension.value16,
9640
- paddingHorizontal: mobile ? tokens52.dimension.value20 : tokens52.dimension.value16,
9790
+ paddingVertical: mobile ? tokens53.dimension.value14 : tokens53.dimension.value16,
9791
+ paddingHorizontal: mobile ? tokens53.dimension.value20 : tokens53.dimension.value16,
9641
9792
  // Like Web, the minimum height belongs to the narrow layout only.
9642
- minHeight: mobile ? tokens52.extensions.marketList.minimumHeight : void 0,
9643
- borderBottomWidth: tokens52.border.defaultWidth,
9793
+ minHeight: mobile ? tokens53.extensions.marketList.minimumHeight : void 0,
9794
+ borderBottomWidth: tokens53.border.defaultWidth,
9644
9795
  borderBottomColor: colors.border,
9645
9796
  backgroundColor: pressed ? colors.hover : void 0
9646
9797
  }),
@@ -9650,8 +9801,8 @@ function KjunMarketSimpleList(props) {
9650
9801
  View46,
9651
9802
  {
9652
9803
  style: {
9653
- marginLeft: tokens52.dimension.value12,
9654
- minWidth: mobile ? tokens52.extensions.marketList.mobileQuoteMinimumWidth : void 0,
9804
+ marginLeft: tokens53.dimension.value12,
9805
+ minWidth: mobile ? tokens53.extensions.marketList.mobileQuoteMinimumWidth : void 0,
9655
9806
  maxWidth: "50%",
9656
9807
  alignItems: "flex-end"
9657
9808
  },
@@ -9673,8 +9824,8 @@ function KjunMarketSimpleList(props) {
9673
9824
  flexWrap: "wrap",
9674
9825
  alignItems: "center",
9675
9826
  justifyContent: "flex-end",
9676
- gap: tokens52.dimension.value6,
9677
- marginTop: tokens52.dimension.value2
9827
+ gap: tokens53.dimension.value6,
9828
+ marginTop: tokens53.dimension.value2
9678
9829
  },
9679
9830
  children: [
9680
9831
  price !== null && ((_b = props.renderPricePrefix) == null ? void 0 : _b.call(props, row)),
@@ -9686,7 +9837,7 @@ function KjunMarketSimpleList(props) {
9686
9837
  fetchedAt
9687
9838
  }
9688
9839
  )),
9689
- changeLoading(row) ? /* @__PURE__ */ jsx53(KjunSkeleton, { type: "block", height: tokens52.extensions.marketList.changeSkeletonHeight, width: tokens52.extensions.marketList.changeSkeletonWidth }) : change !== null ? /* @__PURE__ */ jsx53(
9840
+ changeLoading(row) ? /* @__PURE__ */ jsx53(KjunSkeleton, { type: "block", height: tokens53.extensions.marketList.changeSkeletonHeight, width: tokens53.extensions.marketList.changeSkeletonWidth }) : change !== null ? /* @__PURE__ */ jsx53(
9690
9841
  KjunSignedValue,
9691
9842
  {
9692
9843
  value: change,
@@ -9720,7 +9871,7 @@ function KjunMarketSimpleList(props) {
9720
9871
  }
9721
9872
 
9722
9873
  // packages/native/src/market-panel.tsx
9723
- import { tokens as tokens53 } from "@kjun-ui/tokens";
9874
+ import { tokens as tokens54 } from "@kjun-ui/tokens";
9724
9875
  import { View as View47 } from "react-native";
9725
9876
  import { jsx as jsx54, jsxs as jsxs40 } from "react/jsx-runtime";
9726
9877
  function KjunMarketListPanel({
@@ -9734,8 +9885,8 @@ function KjunMarketListPanel({
9734
9885
  View47,
9735
9886
  {
9736
9887
  style: {
9737
- marginTop: tokens53.dimension.value16,
9738
- borderTopWidth: tokens53.border.defaultWidth,
9888
+ marginTop: tokens54.dimension.value16,
9889
+ borderTopWidth: tokens54.border.defaultWidth,
9739
9890
  borderTopColor: colors.border
9740
9891
  },
9741
9892
  children
@@ -9745,7 +9896,7 @@ function KjunMarketListPanel({
9745
9896
  }
9746
9897
 
9747
9898
  // packages/native/src/market-table.tsx
9748
- import { tokens as tokens54 } from "@kjun-ui/tokens";
9899
+ import { tokens as tokens55 } from "@kjun-ui/tokens";
9749
9900
  import { useId as useId10, useState as useState40 } from "react";
9750
9901
  import { ScrollView as ScrollView11, View as View48 } from "react-native";
9751
9902
  import Svg8, { Defs as Defs4, LinearGradient as LinearGradient4, Rect as Rect4, Stop as Stop4 } from "react-native-svg";
@@ -9773,7 +9924,7 @@ function KjunMarketTable(props) {
9773
9924
  const render = (row, col) => {
9774
9925
  const value = getValue(row, col.key), stale = !!getValue(row, "stale");
9775
9926
  if (cellLoading(row, col))
9776
- return /* @__PURE__ */ jsx55(KjunSkeleton, { type: "block", height: tokens54.extensions.marketTable.valueSkeletonHeight, width: tokens54.extensions.marketTable.valueSkeletonWidth });
9927
+ return /* @__PURE__ */ jsx55(KjunSkeleton, { type: "block", height: tokens55.extensions.marketTable.valueSkeletonHeight, width: tokens55.extensions.marketTable.valueSkeletonWidth });
9777
9928
  if (renderCell) return content(renderCell(row, col));
9778
9929
  if (["stock_name", "name", "symbol"].includes(col.key))
9779
9930
  return /* @__PURE__ */ jsx55(MarketIdentity, { row, props, table: true });
@@ -9782,8 +9933,8 @@ function KjunMarketTable(props) {
9782
9933
  KjunSparkline,
9783
9934
  {
9784
9935
  data: Array.isArray(value) ? value : [],
9785
- width: tokens54.extensions.marketTable.sparklineWidth,
9786
- height: tokens54.extensions.marketTable.sparklineHeight
9936
+ width: tokens55.extensions.marketTable.sparklineWidth,
9937
+ height: tokens55.extensions.marketTable.sparklineHeight
9787
9938
  }
9788
9939
  );
9789
9940
  if (col.type === "price")
@@ -9841,7 +9992,7 @@ function KjunMarketTable(props) {
9841
9992
  onLayout: layout.onLayout,
9842
9993
  style: {
9843
9994
  backgroundColor: embedded ? void 0 : colors.surface,
9844
- borderRadius: embedded ? 0 : tokens54.radius.radius12
9995
+ borderRadius: embedded ? 0 : tokens55.radius.radius12
9845
9996
  },
9846
9997
  children: [
9847
9998
  /* @__PURE__ */ jsx55(
@@ -9881,13 +10032,13 @@ function KjunMarketTable(props) {
9881
10032
  {
9882
10033
  style: {
9883
10034
  width: marketGeometry.actionsWidth,
9884
- paddingVertical: tokens54.dimension.value12,
9885
- paddingHorizontal: tokens54.dimension.value4,
10035
+ paddingVertical: tokens55.dimension.value12,
10036
+ paddingHorizontal: tokens55.dimension.value4,
9886
10037
  flexDirection: "row",
9887
10038
  alignItems: "center",
9888
10039
  justifyContent: "center"
9889
10040
  },
9890
- children: ["interest", "favorite"].map((kind) => /* @__PURE__ */ jsx55(View48, { style: { width: Math.max(tokens54.native.minimumTouchTarget, tokens54.extensions.iconToggle.sizes.xs), alignItems: "center" }, children: /* @__PURE__ */ jsx55(KjunCollectionMark, { kind, size: "md" }) }, kind))
10041
+ children: ["interest", "favorite"].map((kind) => /* @__PURE__ */ jsx55(View48, { style: { width: Math.max(tokens55.native.minimumTouchTarget, tokens55.extensions.iconToggle.sizes.xs), alignItems: "center" }, children: /* @__PURE__ */ jsx55(KjunCollectionMark, { kind, size: "md" }) }, kind))
9891
10042
  }
9892
10043
  ),
9893
10044
  columns.map((col, columnIndex) => /* @__PURE__ */ jsxs41(
@@ -9902,11 +10053,11 @@ function KjunMarketTable(props) {
9902
10053
  },
9903
10054
  style: {
9904
10055
  width: layout.widths[columnIndex],
9905
- padding: tokens54.dimension.value12,
10056
+ padding: tokens55.dimension.value12,
9906
10057
  flexDirection: "row",
9907
10058
  alignItems: "center",
9908
10059
  justifyContent: col.align === "right" ? "flex-end" : col.align === "center" ? "center" : "flex-start",
9909
- gap: tokens54.dimension.value4
10060
+ gap: tokens55.dimension.value4
9910
10061
  },
9911
10062
  children: [
9912
10063
  /* @__PURE__ */ jsx55(
@@ -9923,7 +10074,7 @@ function KjunMarketTable(props) {
9923
10074
  KjunIcon,
9924
10075
  {
9925
10076
  name: sortKey === col.key ? sortOrder === "asc" ? "sort-ascending" : "sort-descending" : "arrows-sort",
9926
- size: tokens54.extensions.marketTable.sortIconSize,
10077
+ size: tokens55.extensions.marketTable.sortIconSize,
9927
10078
  color: sortKey === col.key ? colors.brand : colors.textTertiary
9928
10079
  }
9929
10080
  )
@@ -9958,8 +10109,8 @@ function KjunMarketTable(props) {
9958
10109
  {
9959
10110
  style: {
9960
10111
  width: marketGeometry.actionsWidth,
9961
- paddingVertical: tokens54.dimension.value12,
9962
- paddingHorizontal: tokens54.dimension.value4,
10112
+ paddingVertical: tokens55.dimension.value12,
10113
+ paddingHorizontal: tokens55.dimension.value4,
9963
10114
  flexDirection: "row",
9964
10115
  alignItems: "center",
9965
10116
  justifyContent: "center"
@@ -10003,8 +10154,8 @@ function KjunMarketTable(props) {
10003
10154
  {
10004
10155
  style: {
10005
10156
  width: layout.widths[columnIndex],
10006
- paddingVertical: tokens54.dimension.value14,
10007
- paddingHorizontal: tokens54.dimension.value12,
10157
+ paddingVertical: tokens55.dimension.value14,
10158
+ paddingHorizontal: tokens55.dimension.value12,
10008
10159
  justifyContent: "center",
10009
10160
  alignItems: col.align === "right" ? "flex-end" : col.align === "center" ? "center" : void 0
10010
10161
  },
@@ -10030,7 +10181,7 @@ function KjunMarketTable(props) {
10030
10181
  ] })
10031
10182
  }
10032
10183
  ),
10033
- layout.width - scroll.viewport - scroll.x > 1 && /* @__PURE__ */ jsx55(View48, { pointerEvents: "none", style: { position: "absolute", top: 0, right: 0, bottom: 0, width: tokens54.extensions.scrollFade.width }, children: /* @__PURE__ */ jsxs41(Svg8, { width: "100%", height: "100%", children: [
10184
+ layout.width - scroll.viewport - scroll.x > 1 && /* @__PURE__ */ jsx55(View48, { pointerEvents: "none", style: { position: "absolute", top: 0, right: 0, bottom: 0, width: tokens55.extensions.scrollFade.width }, children: /* @__PURE__ */ jsxs41(Svg8, { width: "100%", height: "100%", children: [
10034
10185
  /* @__PURE__ */ jsx55(Defs4, { children: /* @__PURE__ */ jsxs41(LinearGradient4, { id: fadeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
10035
10186
  /* @__PURE__ */ jsx55(Stop4, { offset: "0", stopColor: colors.surface, stopOpacity: 0 }),
10036
10187
  /* @__PURE__ */ jsx55(Stop4, { offset: "1", stopColor: colors.surface, stopOpacity: 1 })
@@ -10047,50 +10198,62 @@ function KjunMarketTable(props) {
10047
10198
  }
10048
10199
 
10049
10200
  // packages/native/src/list.tsx
10050
- import { tokens as tokens55 } from "@kjun-ui/tokens";
10201
+ import { tokens as tokens56 } from "@kjun-ui/tokens";
10051
10202
  import { Children as Children5, createContext as createContext22, useContext as useContext19 } from "react";
10052
10203
  import { View as View49, Platform as Platform26 } from "react-native";
10053
10204
  import { Fragment as Fragment20, jsx as jsx56, jsxs as jsxs42 } from "react/jsx-runtime";
10054
10205
  var ListRowContext = createContext22({ divider: true, compact: false });
10055
- function KjunListRow({ title, description, leading, trailing, actions, href, disabled = false, onPress }) {
10206
+ function KjunListRow({ title, description, leading, trailing, actions, href, disabled = false, destructive = false, chevron = false, onPress, ariaLabel, children }) {
10056
10207
  const { colors } = useKjunStyles(), { divider, compact } = useContext19(ListRowContext);
10057
10208
  const parts = /* @__PURE__ */ jsxs42(Fragment20, { children: [
10058
10209
  hasContent(leading) && /* @__PURE__ */ jsx56(View49, { children: content(leading) }),
10059
10210
  /* @__PURE__ */ jsxs42(View49, { style: { flex: 1, minWidth: 0 }, children: [
10060
- /* @__PURE__ */ jsx56(KText, { style: { ...typeStyle("label") }, children: title }),
10061
- !!description && /* @__PURE__ */ jsx56(KText, { style: { marginTop: tokens55.extensions.list.descriptionGap, color: colors.textSecondary, ...typeStyle("caption") }, children: description })
10211
+ /* @__PURE__ */ jsx56(KText, { style: { ...typeStyle("label"), ...destructive ? { color: colors.danger } : {} }, children: title }),
10212
+ !!description && /* @__PURE__ */ jsx56(KText, { style: { marginTop: tokens56.extensions.list.descriptionGap, color: colors.textSecondary, ...typeStyle("caption") }, children: description }),
10213
+ hasContent(children) && /* @__PURE__ */ jsx56(View49, { style: { marginTop: tokens56.extensions.list.descriptionGap }, children: content(children) })
10062
10214
  ] }),
10063
- hasContent(trailing) && /* @__PURE__ */ jsx56(View49, { style: { maxWidth: "35%" }, children: content(trailing) })
10215
+ hasContent(trailing) && /* @__PURE__ */ jsx56(View49, { style: { maxWidth: "35%" }, children: content(trailing) }),
10216
+ chevron && /* @__PURE__ */ jsx56(View49, { accessible: false, importantForAccessibility: "no-hide-descendants", accessibilityElementsHidden: true, children: /* @__PURE__ */ jsx56(KjunIcon, { name: "chevron-right", size: tokens56.iconSizes.default, color: colors.textTertiary }) })
10064
10217
  ] });
10065
- const style = { flex: 1, minWidth: 0, minHeight: compact ? tokens55.extensions.list.compactMinimumHeight : tokens55.extensions.list.minimumHeight, flexDirection: "row", alignItems: "center", gap: tokens55.extensions.list.gap, padding: tokens55.extensions.list.padding, ...compact ? { paddingVertical: tokens55.extensions.list.compactPaddingY } : {} };
10066
- return /* @__PURE__ */ jsxs42(View49, { role: "listitem", style: { flexDirection: "row", alignItems: "center", gap: tokens55.extensions.list.gap, borderBottomWidth: divider ? tokens55.border.defaultWidth : 0, borderBottomColor: colors.divider }, children: [
10067
- onPress || href ? /* @__PURE__ */ jsx56(AccessiblePressable, { ...Platform26.OS === "web" && href && !disabled ? { href } : {}, accessibilityRole: href ? "link" : "button", accessibilityLabel: title + (description ? ", " + description : ""), disabled, accessibilityState: { disabled }, onPress, style: ({ pressed }) => ({ ...style, opacity: disabled ? tokens55.states.opacity.disabled : 1, backgroundColor: pressed ? colors.hover : "transparent" }), children: parts }) : /* @__PURE__ */ jsx56(View49, { style, children: parts }),
10068
- hasContent(actions) && /* @__PURE__ */ jsx56(View49, { pointerEvents: disabled ? "none" : "auto", ...disabled && Platform26.OS === "web" ? { inert: true } : {}, style: { maxWidth: "45%", flexDirection: "row", flexWrap: "wrap", gap: tokens55.extensions.list.actionsGap, paddingRight: tokens55.extensions.list.actionsPadding, opacity: disabled ? tokens55.states.opacity.disabled : 1 }, children: content(actions) })
10218
+ const style = { flex: 1, minWidth: 0, minHeight: compact ? tokens56.extensions.list.compactMinimumHeight : tokens56.extensions.list.minimumHeight, flexDirection: "row", alignItems: "center", gap: tokens56.extensions.list.gap, padding: tokens56.extensions.list.padding, ...compact ? { paddingVertical: tokens56.extensions.list.compactPaddingY } : {} };
10219
+ return /* @__PURE__ */ jsxs42(View49, { role: "listitem", style: { flexDirection: "row", alignItems: "center", gap: tokens56.extensions.list.gap, borderBottomWidth: divider ? tokens56.border.defaultWidth : 0, borderBottomColor: colors.divider }, children: [
10220
+ onPress || href ? /* @__PURE__ */ jsx56(AccessiblePressable, { ...Platform26.OS === "web" && href && !disabled ? { href } : {}, accessibilityRole: href ? "link" : "button", accessibilityLabel: ariaLabel != null ? ariaLabel : title + (description ? ", " + description : ""), disabled, accessibilityState: { disabled }, onPress, style: ({ pressed }) => ({ ...style, opacity: disabled ? tokens56.states.opacity.disabled : 1, backgroundColor: pressed ? colors.hover : "transparent" }), children: parts }) : /* @__PURE__ */ jsx56(View49, { style, children: parts }),
10221
+ hasContent(actions) && /* @__PURE__ */ jsx56(View49, { pointerEvents: disabled ? "none" : "auto", ...disabled && Platform26.OS === "web" ? { inert: true } : {}, style: { maxWidth: "45%", flexDirection: "row", flexWrap: "wrap", gap: tokens56.extensions.list.actionsGap, paddingRight: tokens56.extensions.list.actionsPadding, opacity: disabled ? tokens56.states.opacity.disabled : 1 }, children: content(actions) })
10069
10222
  ] });
10070
10223
  }
10071
- function KjunListSection({ title, description, actions, children, ariaLabel, divider = true, density = "default" }) {
10224
+ function KjunListSection({ title, description, actions, children, ariaLabel, surface = true, divider = true, density = "default" }) {
10072
10225
  const { colors } = useKjunStyles();
10073
- return /* @__PURE__ */ jsxs42(View49, { style: { minWidth: 0, backgroundColor: colors.surface }, children: [
10074
- !!(title || description || actions) && /* @__PURE__ */ jsxs42(View49, { style: { flexDirection: "row", alignItems: "center", gap: tokens55.extensions.list.gap, padding: tokens55.extensions.list.padding }, children: [
10226
+ return /* @__PURE__ */ jsxs42(View49, { style: { minWidth: 0, backgroundColor: surface ? colors.surface : "transparent" }, children: [
10227
+ !!(title || description || actions) && /* @__PURE__ */ jsxs42(View49, { style: { flexDirection: "row", alignItems: "center", gap: tokens56.extensions.list.gap, padding: tokens56.extensions.list.padding }, children: [
10075
10228
  /* @__PURE__ */ jsxs42(View49, { style: { flex: 1 }, children: [
10076
10229
  !!title && /* @__PURE__ */ jsx56(KText, { accessibilityRole: "header", style: { ...typeStyle("cardTitle") }, children: title }),
10077
- !!description && /* @__PURE__ */ jsx56(KText, { style: { marginTop: tokens55.extensions.list.descriptionGap, color: colors.textSecondary, ...typeStyle("caption") }, children: description })
10230
+ !!description && /* @__PURE__ */ jsx56(KText, { style: { marginTop: tokens56.extensions.list.descriptionGap, color: colors.textSecondary, ...typeStyle("caption") }, children: description })
10078
10231
  ] }),
10079
10232
  content(actions)
10080
10233
  ] }),
10081
10234
  /* @__PURE__ */ jsx56(View49, { role: "list", accessibilityLabel: ariaLabel || title, children: Children5.toArray(children).map((row, i, rows) => /* @__PURE__ */ jsx56(ListRowContext.Provider, { value: { divider: divider && i < rows.length - 1, compact: density === "compact" }, children: row }, i)) })
10082
10235
  ] });
10083
10236
  }
10237
+ function KjunListItem({ children }) {
10238
+ const { colors } = useKjunStyles(), { divider, compact } = useContext19(ListRowContext);
10239
+ return /* @__PURE__ */ jsx56(View49, { role: "listitem", style: {
10240
+ padding: tokens56.extensions.list.padding,
10241
+ ...compact ? { paddingVertical: tokens56.extensions.list.compactPaddingY } : {},
10242
+ borderBottomWidth: divider ? tokens56.border.defaultWidth : 0,
10243
+ borderBottomColor: colors.divider,
10244
+ minWidth: 0
10245
+ }, children: content(children) });
10246
+ }
10084
10247
 
10085
10248
  // packages/native/src/app-navigation.tsx
10086
- import { tokens as tokens56 } from "@kjun-ui/tokens";
10249
+ import { tokens as tokens57 } from "@kjun-ui/tokens";
10087
10250
  import { Children as Children6, Fragment as Fragment21, isValidElement as isValidElement8, useState as useState41 } from "react";
10088
10251
  import { View as View50, Platform as Platform27 } from "react-native";
10089
10252
  import { jsx as jsx57, jsxs as jsxs43 } from "react/jsx-runtime";
10090
10253
  function KjunTopNavigation({ title, description, leading, actions, safeAreaTop = 0 }) {
10091
10254
  const { colors } = useKjunStyles();
10092
- const geometry2 = tokens56.extensions.topNavigation;
10093
- const titleInset = Math.max(0, (geometry2.controlSize - tokens56.typography.sectionTitle.lineHeightPx) / 2);
10255
+ const geometry2 = tokens57.extensions.topNavigation;
10256
+ const titleInset = Math.max(0, (geometry2.controlSize - tokens57.typography.sectionTitle.lineHeightPx) / 2);
10094
10257
  const wrapping = Platform27.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
10095
10258
  const edgeInset = (geometry2.controlSize - geometry2.iconSize) / 2;
10096
10259
  const [iconEdges, setIconEdges] = useState41({ leading: false, trailing: false });
@@ -10114,13 +10277,13 @@ function KjunBottomNavigation({ items: items2, value, ariaLabel, safeAreaBottom
10114
10277
  const m = useKjunMessages();
10115
10278
  ariaLabel != null ? ariaLabel : ariaLabel = m.mainNavigation;
10116
10279
  const { colors } = useKjunStyles();
10117
- const geometry2 = tokens56.extensions.bottomNavigation;
10280
+ const geometry2 = tokens57.extensions.bottomNavigation;
10118
10281
  const hasIcons = items2.some((item) => item.icon);
10119
10282
  if (keyboardVisible && hideOnKeyboard) return null;
10120
10283
  return /* @__PURE__ */ jsx57(View50, { role: "navigation", accessibilityLabel: ariaLabel, style: { flexShrink: 0, flexDirection: "row", backgroundColor: colors.surface, paddingBottom: Math.max(0, safeAreaBottom) }, children: items2.map((item) => {
10121
10284
  const selected = item.key === value;
10122
10285
  const ink = selected ? colors.brand : colors.textSecondary;
10123
- const ring = tokens56.border.controlWidth;
10286
+ const ring = tokens57.border.controlWidth;
10124
10287
  const badge = item.badge != null && /* @__PURE__ */ jsx57(View50, { pointerEvents: "none", "aria-hidden": true, style: {
10125
10288
  position: "absolute",
10126
10289
  top: -geometry2.badgeOffset - ring,
@@ -10155,7 +10318,7 @@ function KjunBottomNavigation({ items: items2, value, ariaLabel, safeAreaBottom
10155
10318
  gap: geometry2.itemGap,
10156
10319
  paddingHorizontal: geometry2.itemPaddingX,
10157
10320
  paddingVertical: geometry2.itemPaddingY,
10158
- opacity: item.disabled ? tokens56.states.opacity.disabled : 1
10321
+ opacity: item.disabled ? tokens57.states.opacity.disabled : 1
10159
10322
  },
10160
10323
  children: [
10161
10324
  hasIcons && /* @__PURE__ */ jsxs43(View50, { style: { width: geometry2.iconSize, height: geometry2.iconSize, flexShrink: 0 }, children: [
@@ -10176,8 +10339,8 @@ function KjunBottomNavigation({ items: items2, value, ariaLabel, safeAreaBottom
10176
10339
  function KjunBottomActionBar({ description, children, safeAreaBottom = 0, keyboardVisible = false, hideOnKeyboard = false }) {
10177
10340
  const { colors } = useKjunStyles();
10178
10341
  const [width, setWidth] = useState41(0);
10179
- const geometry2 = tokens56.extensions.navigation;
10180
- const wide = width >= tokens56.responsive.bottomAction + geometry2.padding * 2;
10342
+ const geometry2 = tokens57.extensions.navigation;
10343
+ const wide = width >= tokens57.responsive.bottomAction + geometry2.padding * 2;
10181
10344
  const wrapping = Platform27.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
10182
10345
  if (keyboardVisible && hideOnKeyboard) return null;
10183
10346
  return /* @__PURE__ */ jsx57(BottomActionBarContext.Provider, { value: !wide, children: /* @__PURE__ */ jsxs43(View50, { onLayout: (event) => setWidth(event.nativeEvent.layout.width), style: {
@@ -10197,52 +10360,53 @@ function KjunBottomActionBar({ description, children, safeAreaBottom = 0, keyboa
10197
10360
  }
10198
10361
 
10199
10362
  // packages/native/src/media.tsx
10200
- import { useRef as useRef35, useState as useState42 } from "react";
10363
+ import { createContext as createContext23, useContext as useContext20, useRef as useRef38, useState as useState42 } from "react";
10201
10364
  import { Image, View as View51 } from "react-native";
10202
- import { tokens as tokens57 } from "@kjun-ui/tokens";
10365
+ import { tokens as tokens58 } from "@kjun-ui/tokens";
10203
10366
  import { jsx as jsx58 } from "react/jsx-runtime";
10367
+ var ImageBackgroundContext = createContext23(void 0);
10204
10368
  function KjunImage({ src, source, alt, decorative = false, aspectRatio = 1, fit = "cover", fallback: fallback2, onLoad, onError }) {
10205
- const { colors } = useKjunStyles();
10206
- const request = JSON.stringify(source != null ? source : src), current = useRef35({ request, version: 0 });
10369
+ const { colors } = useKjunStyles(), background = useContext20(ImageBackgroundContext);
10370
+ const request = JSON.stringify(source != null ? source : src), current = useRef38({ request, version: 0 });
10207
10371
  if (current.current.request !== request) current.current = { request, version: current.current.version + 1 };
10208
10372
  const version = current.current.version;
10209
10373
  const [failed, setFailed] = useState42(null);
10210
10374
  const missing = !source && !src;
10211
- return /* @__PURE__ */ jsx58(View51, { accessibilityElementsHidden: decorative, importantForAccessibility: decorative ? "no-hide-descendants" : "auto", "aria-hidden": decorative || void 0, style: { width: "100%", aspectRatio: aspectRatio > 0 ? aspectRatio : 1, overflow: "hidden", backgroundColor: colors.secondary }, children: !missing && failed !== version ? /* @__PURE__ */ jsx58(Image, { source: source != null ? source : { uri: src }, accessible: !decorative, accessibilityLabel: decorative ? void 0 : alt, resizeMode: fit, style: { position: "absolute", inset: 0, width: "100%", height: "100%" }, onLoad: () => {
10375
+ return /* @__PURE__ */ jsx58(View51, { accessibilityElementsHidden: decorative, importantForAccessibility: decorative ? "no-hide-descendants" : "auto", "aria-hidden": decorative || void 0, style: { width: "100%", aspectRatio: aspectRatio > 0 ? aspectRatio : 1, overflow: "hidden", backgroundColor: background != null ? background : colors.secondary }, children: !missing && failed !== version ? /* @__PURE__ */ jsx58(Image, { source: source != null ? source : { uri: src }, accessible: !decorative, accessibilityLabel: decorative ? void 0 : alt, resizeMode: fit, style: { position: "absolute", inset: 0, width: "100%", height: "100%" }, onLoad: () => {
10212
10376
  if (version === current.current.version) onLoad == null ? void 0 : onLoad();
10213
10377
  }, onError: () => {
10214
10378
  if (version === current.current.version) {
10215
10379
  setFailed(version);
10216
10380
  onError == null ? void 0 : onError();
10217
10381
  }
10218
- } }, version) : /* @__PURE__ */ jsx58(View51, { accessible: !decorative, accessibilityRole: "image", accessibilityLabel: decorative ? void 0 : alt, "aria-hidden": decorative || void 0, style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: content(fallback2 != null ? fallback2 : /* @__PURE__ */ jsx58(KjunIcon, { name: "image", size: tokens57.extensions.image.fallbackIconSize, color: colors.textSecondary }), { color: colors.textSecondary, fontWeight: typeStyle("control").fontWeight, textAlign: "center" }) }) });
10382
+ } }, version) : /* @__PURE__ */ jsx58(View51, { accessible: !decorative, accessibilityRole: "image", accessibilityLabel: decorative ? void 0 : alt, "aria-hidden": decorative || void 0, style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: content(fallback2 != null ? fallback2 : /* @__PURE__ */ jsx58(KjunIcon, { name: "image", size: tokens58.extensions.image.fallbackIconSize, color: colors.textSecondary }), { color: colors.textSecondary, fontWeight: typeStyle("control").fontWeight, textAlign: "center" }) }) });
10219
10383
  }
10220
- function KjunAvatar({ src, source, name = "", alt, decorative = false, size = "md", shape = "circle", fallback: fallback2, onLoad, onError }) {
10384
+ function KjunAvatar({ src, source, name = "", alt, decorative = false, size = "md", shape = "circle", color, textColor, fallback: fallback2, onLoad, onError }) {
10221
10385
  const m = useKjunMessages();
10222
10386
  const { colors } = useKjunStyles(), initial = Array.from(name.trim())[0];
10223
- return /* @__PURE__ */ jsx58(View51, { style: { width: tokens57.extensions.avatar[size], height: tokens57.extensions.avatar[size], borderRadius: shape === "circle" ? tokens57.radius.radius9999 : tokens57.radius.radius8, overflow: "hidden", flexShrink: 0 }, children: /* @__PURE__ */ jsx58(KjunImage, { src, source, alt: alt || name || m.user, decorative, fallback: fallback2 != null ? fallback2 : initial ? /* @__PURE__ */ jsx58(KText, { style: { ...typeStyle(size === "sm" ? "control" : size === "lg" ? "sectionTitle" : "input"), fontWeight: typeStyle("control").fontWeight, color: colors.textSecondary }, children: initial.toLocaleUpperCase() }) : /* @__PURE__ */ jsx58(KjunIcon, { name: "user", size: tokens57.extensions.avatar.fallbackIconSizes[size] }), onLoad, onError }) });
10387
+ return /* @__PURE__ */ jsx58(View51, { style: { width: tokens58.extensions.avatar[size], height: tokens58.extensions.avatar[size], borderRadius: shape === "circle" ? tokens58.radius.radius9999 : tokens58.radius.radius8, overflow: "hidden", flexShrink: 0 }, children: /* @__PURE__ */ jsx58(ImageBackgroundContext.Provider, { value: color, children: /* @__PURE__ */ jsx58(KjunImage, { src, source, alt: alt || name || m.user, decorative, fallback: fallback2 != null ? fallback2 : initial ? /* @__PURE__ */ jsx58(KText, { style: { ...typeStyle(size === "sm" ? "control" : size === "lg" ? "sectionTitle" : "input"), fontWeight: typeStyle("control").fontWeight, color: textColor != null ? textColor : colors.textSecondary }, children: initial.toLocaleUpperCase() }) : /* @__PURE__ */ jsx58(KjunIcon, { name: "user", size: tokens58.extensions.avatar.fallbackIconSizes[size], color: textColor }), onLoad, onError }) }) });
10224
10388
  }
10225
10389
 
10226
10390
  // packages/native/src/chip.tsx
10227
10391
  import { View as View52 } from "react-native";
10228
- import { tokens as tokens58 } from "@kjun-ui/tokens";
10392
+ import { tokens as tokens59 } from "@kjun-ui/tokens";
10229
10393
  import { jsx as jsx59, jsxs as jsxs44 } from "react/jsx-runtime";
10230
10394
  function KjunChip({ label, icon, removable = false, disabled = false, size = "md", removeLabel, onRemove }) {
10231
10395
  const m = useKjunMessages();
10232
10396
  const { colors } = useKjunStyles();
10233
- return /* @__PURE__ */ jsxs44(View52, { style: { alignSelf: "flex-start", maxWidth: "100%", minWidth: 0, flexShrink: 1, flexDirection: "row", alignItems: "center", gap: tokens58.extensions.chip.gap, minHeight: removable ? tokens58.extensions.chip.nativeRemoveSize : tokens58.extensions.chip[size], paddingVertical: removable ? 0 : tokens58.extensions.chip.paddingY, paddingLeft: tokens58.extensions.chip.paddingX, paddingRight: removable ? 0 : tokens58.extensions.chip.paddingX, borderRadius: tokens58.extensions.chip.radius, backgroundColor: colors.secondary, opacity: disabled ? tokens58.states.opacity.disabled : 1 }, children: [
10234
- !!icon && /* @__PURE__ */ jsx59(KjunIcon, { name: icon, size: tokens58.extensions.chip.iconSizes[size] }),
10235
- /* @__PURE__ */ jsx59(KText, { style: { ...typeStyle(tokens58.extensions.chip.typography[size]), flexShrink: 1, minWidth: 0 }, children: label }),
10236
- removable && /* @__PURE__ */ jsx59(AccessiblePressable, { accessibilityRole: "button", accessibilityLabel: removeLabel || m.remove(label), disabled, accessibilityState: { disabled }, onPress: onRemove, style: { width: tokens58.extensions.chip.nativeRemoveSize, height: tokens58.extensions.chip.nativeRemoveSize, borderRadius: tokens58.extensions.chip.radius, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx59(KjunIcon, { name: "x", size: tokens58.extensions.chip.removeIconSizes[size] }) })
10397
+ return /* @__PURE__ */ jsxs44(View52, { style: { alignSelf: "flex-start", maxWidth: "100%", minWidth: 0, flexShrink: 1, flexDirection: "row", alignItems: "center", gap: tokens59.extensions.chip.gap, minHeight: removable ? tokens59.extensions.chip.nativeRemoveSize : tokens59.extensions.chip[size], paddingVertical: removable ? 0 : tokens59.extensions.chip.paddingY, paddingLeft: tokens59.extensions.chip.paddingX, paddingRight: removable ? 0 : tokens59.extensions.chip.paddingX, borderRadius: tokens59.extensions.chip.radius, backgroundColor: colors.secondary, opacity: disabled ? tokens59.states.opacity.disabled : 1 }, children: [
10398
+ !!icon && /* @__PURE__ */ jsx59(KjunIcon, { name: icon, size: tokens59.extensions.chip.iconSizes[size] }),
10399
+ /* @__PURE__ */ jsx59(KText, { style: { ...typeStyle(tokens59.extensions.chip.typography[size]), flexShrink: 1, minWidth: 0 }, children: label }),
10400
+ removable && /* @__PURE__ */ jsx59(AccessiblePressable, { accessibilityRole: "button", accessibilityLabel: removeLabel || m.remove(label), disabled, accessibilityState: { disabled }, onPress: onRemove, style: { width: tokens59.extensions.chip.nativeRemoveSize, height: tokens59.extensions.chip.nativeRemoveSize, borderRadius: tokens59.extensions.chip.radius, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx59(KjunIcon, { name: "x", size: tokens59.extensions.chip.removeIconSizes[size] }) })
10237
10401
  ] });
10238
10402
  }
10239
10403
 
10240
10404
  // packages/native/src/fab.tsx
10241
- import { tokens as tokens59 } from "@kjun-ui/tokens";
10405
+ import { tokens as tokens60 } from "@kjun-ui/tokens";
10242
10406
  import { jsx as jsx60 } from "react/jsx-runtime";
10243
10407
  function KjunFab({ icon, ariaLabel, disabled = false, safeAreaBottom = 0, offsetBottom = 0, onPress }) {
10244
10408
  const { colors } = useKjunStyles();
10245
- const { size, inset, iconSize } = tokens59.extensions.fab;
10409
+ const { size, inset, iconSize } = tokens60.extensions.fab;
10246
10410
  return /* @__PURE__ */ jsx60(
10247
10411
  AccessiblePressable,
10248
10412
  {
@@ -10255,15 +10419,15 @@ function KjunFab({ icon, ariaLabel, disabled = false, safeAreaBottom = 0, offset
10255
10419
  position: "absolute",
10256
10420
  right: inset,
10257
10421
  bottom: inset + Math.max(0, safeAreaBottom) + Math.max(0, offsetBottom),
10258
- zIndex: tokens59.layers.page.navigation,
10422
+ zIndex: tokens60.layers.page.navigation,
10259
10423
  width: size,
10260
10424
  height: size,
10261
10425
  borderRadius: size / 2,
10262
10426
  alignItems: "center",
10263
10427
  justifyContent: "center",
10264
10428
  backgroundColor: pressed ? colors.brandActive : colors.brand,
10265
- opacity: disabled ? tokens59.states.opacity.disabled : 1,
10266
- boxShadow: shadowLayers(tokens59.elevation.floating, colors)
10429
+ opacity: disabled ? tokens60.states.opacity.disabled : 1,
10430
+ boxShadow: shadowLayers(tokens60.elevation.floating, colors)
10267
10431
  }),
10268
10432
  children: /* @__PURE__ */ jsx60(KjunIcon, { name: icon, size: iconSize, color: colors.onBrand })
10269
10433
  }
@@ -10271,12 +10435,12 @@ function KjunFab({ icon, ariaLabel, disabled = false, safeAreaBottom = 0, offset
10271
10435
  }
10272
10436
 
10273
10437
  // packages/native/src/range-input.tsx
10274
- import { useEffect as useEffect27, useMemo as useMemo3, useRef as useRef36, useState as useState43 } from "react";
10438
+ import { useEffect as useEffect28, useMemo as useMemo3, useRef as useRef39, useState as useState43 } from "react";
10275
10439
  import { PanResponder, Platform as Platform28, Pressable as Pressable3, View as View53 } from "react-native";
10276
- import { tokens as tokens60, createSliderDomain, sliderKey } from "@kjun-ui/tokens";
10440
+ import { tokens as tokens61, createSliderDomain, sliderKey } from "@kjun-ui/tokens";
10277
10441
  import { jsx as jsx61, jsxs as jsxs45 } from "react/jsx-runtime";
10278
- var geometry = tokens60.extensions.slider;
10279
- var targetSize = tokens60.native.minimumTouchTarget;
10442
+ var geometry = tokens61.extensions.slider;
10443
+ var targetSize = tokens61.native.minimumTouchTarget;
10280
10444
  var trackFocus = { tabIndex: -1 };
10281
10445
  function RangeInput({
10282
10446
  value,
@@ -10299,15 +10463,15 @@ function RangeInput({
10299
10463
  const [hovered, setHovered] = useState43(null);
10300
10464
  const [dragging, setDragging] = useState43(null);
10301
10465
  const [focused, setFocused] = useState43(null);
10302
- const track = useRef36(null), measured = useRef36({ x: 0, width: 1 }), selected = useRef36(0), dirty = useRef36(false);
10303
- const latest = useRef36(values);
10466
+ const track = useRef39(null), measured = useRef39({ x: 0, width: 1 }), selected = useRef39(0), dirty = useRef39(false);
10467
+ const latest = useRef39(values);
10304
10468
  latest.current = values;
10305
- const callbacks = useRef36({ onValueChange, onChangeCommit });
10469
+ const callbacks = useRef39({ onValueChange, onChangeCommit });
10306
10470
  callbacks.current = { onValueChange, onChangeCommit };
10307
- useEffect27(() => {
10471
+ useEffect28(() => {
10308
10472
  if (!valid) console.warn("KJUN Slider: \uBC94\uC704\xB7step\xB7\uAC12\uC744 \uD655\uC778\uD558\uC138\uC694.");
10309
10473
  }, [valid]);
10310
- useEffect27(() => {
10474
+ useEffect28(() => {
10311
10475
  if (blocked) {
10312
10476
  setDragging(null);
10313
10477
  setHovered(null);
@@ -10376,10 +10540,10 @@ function RangeInput({
10376
10540
  View53,
10377
10541
  {
10378
10542
  style: {
10379
- minWidth: tokens60.extensions.slider.minimumWidth,
10543
+ minWidth: tokens61.extensions.slider.minimumWidth,
10380
10544
  width: "100%",
10381
- gap: tokens60.dimension.value4,
10382
- opacity: blocked ? tokens60.states.opacity.disabled : 1
10545
+ gap: tokens61.dimension.value4,
10546
+ opacity: blocked ? tokens61.states.opacity.disabled : 1
10383
10547
  },
10384
10548
  children: [
10385
10549
  /* @__PURE__ */ jsxs45(
@@ -10389,7 +10553,7 @@ function RangeInput({
10389
10553
  flexDirection: "row",
10390
10554
  alignItems: "baseline",
10391
10555
  justifyContent: "space-between",
10392
- gap: tokens60.dimension.value12,
10556
+ gap: tokens61.dimension.value12,
10393
10557
  minWidth: 0
10394
10558
  },
10395
10559
  children: [
@@ -10450,7 +10614,7 @@ function RangeInput({
10450
10614
  {
10451
10615
  style: {
10452
10616
  height: geometry.track,
10453
- borderRadius: tokens60.radius.radius9999,
10617
+ borderRadius: tokens61.radius.radius9999,
10454
10618
  backgroundColor: colors.border
10455
10619
  }
10456
10620
  }
@@ -10465,7 +10629,7 @@ function RangeInput({
10465
10629
  position: "absolute",
10466
10630
  top: (targetSize - geometry.track) / 2,
10467
10631
  height: geometry.track,
10468
- borderRadius: tokens60.radius.radius9999,
10632
+ borderRadius: tokens61.radius.radius9999,
10469
10633
  left: pct(values.length === 2 ? percent(values[0]) : 0),
10470
10634
  width: pct(
10471
10635
  percent(values[values.length - 1]) - (values.length === 2 ? percent(values[0]) : 0)
@@ -10541,14 +10705,14 @@ function RangeInput({
10541
10705
  style: {
10542
10706
  width: geometry.thumb,
10543
10707
  height: geometry.thumb,
10544
- borderRadius: tokens60.radius.radius9999,
10545
- borderWidth: tokens60.border.controlWidth,
10708
+ borderRadius: tokens61.radius.radius9999,
10709
+ borderWidth: tokens61.border.controlWidth,
10546
10710
  borderColor: !blocked && dragging === index ? colors.brandActive : !blocked && hovered === index ? colors.brandHover : colors.brand,
10547
10711
  backgroundColor: colors.surface,
10548
10712
  ...Platform28.OS === "web" && !blocked && focused === index ? {
10549
10713
  outlineStyle: "solid",
10550
- outlineWidth: tokens60.states.focus.width,
10551
- outlineOffset: tokens60.states.focus.choiceOffset,
10714
+ outlineWidth: tokens61.states.focus.width,
10715
+ outlineOffset: tokens61.states.focus.choiceOffset,
10552
10716
  outlineColor: colors.focusRing
10553
10717
  } : {}
10554
10718
  }
@@ -10572,9 +10736,9 @@ function KjunRangeSlider(props) {
10572
10736
  }
10573
10737
 
10574
10738
  // packages/native/src/quantity-stepper.tsx
10575
- import { useEffect as useEffect28, useRef as useRef37, useState as useState44 } from "react";
10739
+ import { useEffect as useEffect29, useRef as useRef40, useState as useState44 } from "react";
10576
10740
  import { Platform as Platform29, View as View54 } from "react-native";
10577
- import { createNumberDomain, quantityKeyAction, tokens as tokens61 } from "@kjun-ui/tokens";
10741
+ import { createNumberDomain, quantityKeyAction, tokens as tokens62 } from "@kjun-ui/tokens";
10578
10742
 
10579
10743
  // shared/package-runtime/component-icons.ts
10580
10744
  import minus from "@kjun-ui/icons/icons/minus";
@@ -10588,23 +10752,23 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
10588
10752
  const field = useKjunField();
10589
10753
  const invalid = error || !!(field == null ? void 0 : field.error);
10590
10754
  const labelledBy = !ariaLabel && (field == null ? void 0 : field.label) && !field.labelHidden ? field.id + "-label" : void 0;
10591
- const geometry2 = tokens61.extensions.compound;
10592
- const buttonStyle = { width: tokens61.input[size].height, paddingHorizontal: 0 };
10593
- const outer = tokens61.input[size].radius;
10755
+ const geometry2 = tokens62.extensions.compound;
10756
+ const buttonStyle = { width: tokens62.input[size].height, paddingHorizontal: 0 };
10757
+ const outer = tokens62.input[size].radius;
10594
10758
  const decreaseStyle = { ...buttonStyle, borderRadius: 0, borderTopLeftRadius: outer, borderBottomLeftRadius: outer };
10595
10759
  const increaseStyle = { ...buttonStyle, borderRadius: 0, borderTopRightRadius: outer, borderBottomRightRadius: outer };
10596
10760
  const domain = createNumberDomain({ min, max, step, precision }), valid = domain.valid && domain.accepts(value), blocked = disabled || !valid;
10597
10761
  const surface = useFieldSurface(size, { disabled: blocked, invalid });
10598
10762
  const [draft, setDraft] = useState44(String(value));
10599
- const inputRef = useRef37(null);
10600
- const composing = useRef37(false), dirty = useRef37(false), accepted = useRef37(value);
10601
- const cancelledEscape = useRef37(false);
10602
- useEffect28(() => {
10763
+ const inputRef = useRef40(null);
10764
+ const composing = useRef40(false), dirty = useRef40(false), accepted = useRef40(value);
10765
+ const cancelledEscape = useRef40(false);
10766
+ useEffect29(() => {
10603
10767
  setDraft(String(value));
10604
10768
  accepted.current = value;
10605
10769
  dirty.current = false;
10606
10770
  }, [value, precision, min, max, step]);
10607
- useEffect28(() => {
10771
+ useEffect29(() => {
10608
10772
  if (!valid) console.warn("KJUN QuantityStepper: \uBC94\uC704\xB7step\xB7\uC815\uBC00\uB3C4\xB7\uAC12\uC744 \uD655\uC778\uD558\uC138\uC694.");
10609
10773
  }, [valid]);
10610
10774
  const emit = (next) => {
@@ -10641,7 +10805,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
10641
10805
  } else if (action === "commit") commit();
10642
10806
  else move(action === "increment" ? 1 : -1);
10643
10807
  };
10644
- const handlers = useRef37({ key, edit: (text) => {
10808
+ const handlers = useRef40({ key, edit: (text) => {
10645
10809
  dirty.current = true;
10646
10810
  setDraft(text);
10647
10811
  } });
@@ -10649,7 +10813,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
10649
10813
  dirty.current = true;
10650
10814
  setDraft(text);
10651
10815
  } };
10652
- useEffect28(() => {
10816
+ useEffect29(() => {
10653
10817
  if (Platform29.OS !== "web") return;
10654
10818
  const input = inputRef.current;
10655
10819
  const keydown = (event) => handlers.current.key(event);
@@ -10678,12 +10842,12 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
10678
10842
  input.removeEventListener("compositionend", end);
10679
10843
  };
10680
10844
  }, []);
10681
- const surfaceBox = { position: "absolute", left: 0, right: 0, top: "50%", height: tokens61.input[size].height, marginTop: -tokens61.input[size].height / 2, borderRadius: surface.spec.radius };
10845
+ const surfaceBox = { position: "absolute", left: 0, right: 0, top: "50%", height: tokens62.input[size].height, marginTop: -tokens62.input[size].height / 2, borderRadius: surface.spec.radius };
10682
10846
  const hug = Platform29.OS === "web" && !block ? { width: "fit-content" } : {};
10683
10847
  return /* @__PURE__ */ jsx62(IconFallbacks, { icons: componentIcons, children: /* @__PURE__ */ jsxs46(View54, { style: { flexDirection: "row", alignItems: "center", alignSelf: block ? "stretch" : "flex-start", maxWidth: "100%", borderRadius: surface.spec.radius, ...hug }, children: [
10684
10848
  /* @__PURE__ */ jsx62(View54, { pointerEvents: "none", "aria-hidden": true, style: { ...surfaceBox, backgroundColor: colors.inputBg } }),
10685
10849
  /* @__PURE__ */ jsx62(CompoundTarget, { square: true, children: /* @__PURE__ */ jsx62(KjunButton, { size, style: decreaseStyle, variant: "ghost", ariaLabel: m.decreaseQuantity, disabled: blocked || value <= min, onPress: () => move(-1), prefixIcon: "minus" }) }),
10686
- /* @__PURE__ */ jsx62(View54, { style: { flex: block ? 1 : void 0, width: block ? void 0 : geometry2.valueWidth, minWidth: 0, minHeight: finePointer() ? void 0 : tokens61.native.minimumTouchTarget, justifyContent: "center" }, ...fieldTarget(() => {
10850
+ /* @__PURE__ */ jsx62(View54, { style: { flex: block ? 1 : void 0, width: block ? void 0 : geometry2.valueWidth, minWidth: 0, minHeight: finePointer() ? void 0 : tokens62.native.minimumTouchTarget, justifyContent: "center" }, ...fieldTarget(() => {
10687
10851
  var _a;
10688
10852
  return (_a = inputRef.current) == null ? void 0 : _a.focus();
10689
10853
  }, blocked), children: /* @__PURE__ */ jsx62(
@@ -10712,30 +10876,30 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
10712
10876
  },
10713
10877
  onSubmitEditing: Platform29.OS === "web" ? void 0 : commit,
10714
10878
  ...Platform29.OS === "web" ? { "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": value, "aria-labelledby": labelledBy, "aria-describedby": field == null ? void 0 : field.describedBy, "aria-invalid": invalid || void 0, "aria-required": (field == null ? void 0 : field.required) || void 0 } : { onKeyPress: key },
10715
- style: { width: "100%", minWidth: 0, ...surface.style, borderRadius: 0, borderTopColor: "transparent", borderBottomColor: "transparent", borderLeftColor: "transparent", borderRightColor: "transparent", backgroundColor: !blocked && (surface.active || surface.hovered) ? colors.hover : "transparent", outlineWidth: 0, color: surface.ink, fontFamily, ...inputTypeStyle(size), textAlign: "center", paddingHorizontal: surface.spec.padding - tokens61.border.controlWidth, paddingVertical: 0 }
10879
+ style: { width: "100%", minWidth: 0, ...surface.style, borderRadius: 0, borderTopColor: "transparent", borderBottomColor: "transparent", borderLeftColor: "transparent", borderRightColor: "transparent", backgroundColor: !blocked && (surface.active || surface.hovered) ? colors.hover : "transparent", outlineWidth: 0, color: surface.ink, fontFamily, ...inputTypeStyle(size), textAlign: "center", paddingHorizontal: surface.spec.padding - tokens62.border.controlWidth, paddingVertical: 0 }
10716
10880
  }
10717
10881
  ) }),
10718
10882
  /* @__PURE__ */ jsx62(CompoundTarget, { square: true, children: /* @__PURE__ */ jsx62(KjunButton, { size, style: increaseStyle, variant: "ghost", ariaLabel: m.increaseQuantity, disabled: blocked || max !== void 0 && value >= max, onPress: () => move(1), prefixIcon: "plus" }) }),
10719
- (invalid || surface.active) && /* @__PURE__ */ jsx62(View54, { pointerEvents: "none", "aria-hidden": true, style: { ...surfaceBox, borderWidth: invalid ? tokens61.border.controlWidth : tokens61.states.focus.width, borderColor: invalid ? colors.danger : colors.focusRing } })
10883
+ (invalid || surface.active) && /* @__PURE__ */ jsx62(View54, { pointerEvents: "none", "aria-hidden": true, style: { ...surfaceBox, borderWidth: invalid ? tokens62.border.controlWidth : tokens62.states.focus.width, borderColor: invalid ? colors.danger : colors.focusRing } })
10720
10884
  ] }) });
10721
10885
  }
10722
10886
 
10723
10887
  // packages/native/src/time-picker.tsx
10724
- import { Fragment as Fragment22, useEffect as useEffect29, useId as useId11, useMemo as useMemo4, useRef as useRef38, useState as useState45 } from "react";
10888
+ import { Fragment as Fragment22, useEffect as useEffect30, useId as useId11, useMemo as useMemo4, useRef as useRef41, useState as useState45 } from "react";
10725
10889
  import { View as View55 } from "react-native";
10726
- import { createTimeDomain, tokens as tokens62 } from "@kjun-ui/tokens";
10890
+ import { createTimeDomain, tokens as tokens63 } from "@kjun-ui/tokens";
10727
10891
  import { jsx as jsx63, jsxs as jsxs47 } from "react/jsx-runtime";
10728
10892
  function KjunTimePicker({ value, precision = "minute", min, max, minuteStep = 1, secondStep = 1, disabled = false, error = false, clearable = true, size = "md", ariaLabel, onValueChange, onChangeCommit }) {
10729
10893
  const m = useKjunMessages();
10730
10894
  ariaLabel != null ? ariaLabel : ariaLabel = m.time;
10731
- const geometry2 = tokens62.extensions.timePicker, spec = tokens62.input[size];
10895
+ const geometry2 = tokens63.extensions.timePicker, spec = tokens63.input[size];
10732
10896
  const { colors } = useKjunStyles();
10733
- const first = useRef38(null);
10897
+ const first = useRef41(null);
10734
10898
  const [focused, setFocused] = useState45(false), [opened, setOpened] = useState45(null);
10735
10899
  const field = useKjunField(), uid = useId11();
10736
10900
  const fieldId = (field == null ? void 0 : field.id) || `kjun-time-${uid}`;
10737
10901
  const domain = useMemo4(() => createTimeDomain({ precision, min, max, minuteStep, secondStep }), [precision, min, max, minuteStep, secondStep]), valid = domain.valid && domain.accepts(value);
10738
- useEffect29(() => {
10902
+ useEffect30(() => {
10739
10903
  if (!valid) console.warn("KJUN TimePicker: \uC2DC\uAC01 \uBC94\uC704\xB7\uAC04\uACA9\xB7\uAC12\uC744 \uD655\uC778\uD558\uC138\uC694.");
10740
10904
  }, [valid]);
10741
10905
  const change = (next) => {
@@ -10752,12 +10916,12 @@ function KjunTimePicker({ value, precision = "minute", min, max, minuteStep = 1,
10752
10916
  if (typeof next === "number") change(domain.select(value, index, next));
10753
10917
  }, onOpenChange: (open) => setOpened(open ? index : null), ariaLabel: ((field == null ? void 0 : field.label) || ariaLabel) + " " + label, placeholder: label, disabled: disabled || !valid, error, size, clearable: false, searchable: false }) }) }) })
10754
10918
  ] }, label)) }),
10755
- clearable && value !== null && /* @__PURE__ */ jsx63(View55, { style: { marginVertical: Math.min(0, (spec.height - tokens62.native.minimumTouchTarget) / 2) }, children: /* @__PURE__ */ jsx63(FieldClear, { size, label: m.clearValue(ariaLabel), disabled: disabled || !valid, onPress: () => {
10919
+ clearable && value !== null && /* @__PURE__ */ jsx63(View55, { style: { marginVertical: Math.min(0, (spec.height - tokens63.native.minimumTouchTarget) / 2) }, children: /* @__PURE__ */ jsx63(FieldClear, { size, label: m.clearValue(ariaLabel), disabled: disabled || !valid, onPress: () => {
10756
10920
  var _a;
10757
10921
  change(null);
10758
10922
  (_a = first.current) == null ? void 0 : _a.focus();
10759
10923
  } }) }),
10760
- !!(error || !!(field == null ? void 0 : field.error) || focused || opened !== null) && /* @__PURE__ */ jsx63(View55, { pointerEvents: "none", "aria-hidden": true, style: { position: "absolute", inset: 0, borderRadius: spec.radius, borderWidth: error || !!(field == null ? void 0 : field.error) ? tokens62.border.controlWidth : tokens62.states.focus.width, borderColor: error || (field == null ? void 0 : field.error) ? colors.danger : colors.focusRing } })
10924
+ !!(error || !!(field == null ? void 0 : field.error) || focused || opened !== null) && /* @__PURE__ */ jsx63(View55, { pointerEvents: "none", "aria-hidden": true, style: { position: "absolute", inset: 0, borderRadius: spec.radius, borderWidth: error || !!(field == null ? void 0 : field.error) ? tokens63.border.controlWidth : tokens63.states.focus.width, borderColor: error || (field == null ? void 0 : field.error) ? colors.danger : colors.focusRing } })
10761
10925
  ] });
10762
10926
  }
10763
10927
  export {
@@ -10806,6 +10970,7 @@ export {
10806
10970
  KjunInput,
10807
10971
  KjunKpiHero,
10808
10972
  KjunKpiRow,
10973
+ KjunListItem,
10809
10974
  KjunListRow,
10810
10975
  KjunListSection,
10811
10976
  KjunListSkeleton,
@@ -10845,6 +11010,7 @@ export {
10845
11010
  KjunTimePicker,
10846
11011
  KjunTooltip,
10847
11012
  KjunTopNavigation,
11013
+ createKjunFeedback,
10848
11014
  kjunMessagesEn,
10849
11015
  kjunMessagesKo,
10850
11016
  useKjunFeedback,