@kjun-ui/native 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.web.js CHANGED
@@ -2366,36 +2366,6 @@ function KjunSkeleton({
2366
2366
  ))
2367
2367
  }
2368
2368
  ),
2369
- type === "chart" && /* @__PURE__ */ jsxs8(View11, { style: [frame, { height: height || tokens11.extensions.skeleton.chartHeight }], children: [
2370
- /* @__PURE__ */ jsx15(
2371
- View11,
2372
- {
2373
- style: {
2374
- flex: 1,
2375
- flexDirection: "row",
2376
- alignItems: "flex-end",
2377
- justifyContent: "space-around",
2378
- gap: tokens11.extensions.skeleton.gap
2379
- // Bars stand on the axis line, like ChartSkeleton.
2380
- },
2381
- children: [40, 65, 50, 80, 60, 90, 75].map((h, i) => /* @__PURE__ */ jsx15(
2382
- Animated6.View,
2383
- {
2384
- style: {
2385
- flex: 1,
2386
- maxWidth: tokens11.extensions.skeleton.chartBarMaxWidth,
2387
- height: `${h}%`,
2388
- backgroundColor: shimmer,
2389
- borderTopLeftRadius: tokens11.radius.radius4,
2390
- borderTopRightRadius: tokens11.radius.radius4
2391
- }
2392
- },
2393
- i
2394
- ))
2395
- }
2396
- ),
2397
- block("100%", tokens11.extensions.skeleton.chartAxisHeight, { backgroundColor: colors.border })
2398
- ] }),
2399
2369
  type === "stat" && /* @__PURE__ */ jsxs8(
2400
2370
  View11,
2401
2371
  {
@@ -6534,9 +6504,27 @@ var KjunErrorBoundary = class extends Component {
6534
6504
 
6535
6505
  // packages/native/src/skeletons.tsx
6536
6506
  import { tokens as tokens38 } from "@kjun-ui/tokens";
6537
- import { Fragment as Fragment12, useEffect as useEffect22, useRef as useRef30 } from "react";
6538
- import { Animated as Animated17, View as View33, useWindowDimensions as useWindowDimensions6 } from "react-native";
6539
- import Svg5, { G as G2, Path as Path4, Rect as Rect3 } from "react-native-svg";
6507
+ import { useEffect as useEffect22, useRef as useRef30, useState as useState33 } from "react";
6508
+ import { Animated as Animated17, Platform as Platform24, View as View33, useWindowDimensions as useWindowDimensions6 } from "react-native";
6509
+ import Svg5, { Path as Path4 } from "react-native-svg";
6510
+
6511
+ // shared/package-runtime/chart-skeleton.ts
6512
+ var chartFrameViewBox = "0 0 600 240";
6513
+ var chartFramePath = "M20 10V220H590 M20 65H590 M20 120H590 M20 175H590";
6514
+ var chartSkeletonMaxCount = 100;
6515
+ function chartSkeletonCount(value) {
6516
+ return Number.isFinite(value) ? Math.min(chartSkeletonMaxCount, Math.max(1, Math.floor(value))) : 1;
6517
+ }
6518
+ function chartMatrixMuted(row, column) {
6519
+ return (row + column + 2) % 3 === 0;
6520
+ }
6521
+ var chartDonutRatio = 0.8;
6522
+ function chartDonutHole(height, thickness) {
6523
+ return Math.max(0, height * chartDonutRatio - 2 * thickness);
6524
+ }
6525
+ function chartSkeletonKind(kind) {
6526
+ return kind === "donut" || kind === "matrix" ? kind : "frame";
6527
+ }
6540
6528
 
6541
6529
  // packages/native/src/market-skeleton.tsx
6542
6530
  import { tokens as tokens37 } from "@kjun-ui/tokens";
@@ -6594,7 +6582,7 @@ function KjunMarketTableSkeleton({ columns = [], rows = 8, showActions = false }
6594
6582
  }
6595
6583
 
6596
6584
  // packages/native/src/skeletons.tsx
6597
- import { jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
6585
+ import { Fragment as Fragment12, jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
6598
6586
  function KjunListSkeleton({
6599
6587
  rows = 8,
6600
6588
  variant = "market",
@@ -6695,26 +6683,23 @@ function KjunFormSkeleton({
6695
6683
  }
6696
6684
  );
6697
6685
  }
6686
+ var chartPart = (name) => Platform24.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
6698
6687
  function KjunChartSkeleton({
6688
+ kind: requestedKind = "frame",
6689
+ height = tokens38.extensions.chartSkeleton.height,
6699
6690
  loadingText = "\uCC28\uD2B8\uB97C \uBD88\uB7EC\uC624\uB294 \uC911",
6700
- kind = "line",
6701
- height = tokens38.extensions.chartSkeleton.height
6691
+ skeleton = true,
6692
+ loadingDelay = 0,
6693
+ rows = 8,
6694
+ columns = 14
6702
6695
  }) {
6703
- const { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef30(new Animated17.Value(1)).current;
6696
+ const kind = chartSkeletonKind(requestedKind), { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef30(new Animated17.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = useState33(0), thickness = tokens38.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" };
6704
6697
  useEffect22(() => {
6705
- if (reduced) return;
6698
+ if (reduced || !skeleton) return;
6706
6699
  const loop = Animated17.loop(
6707
6700
  Animated17.sequence([
6708
- Animated17.timing(opacity, {
6709
- toValue: 0.55,
6710
- duration: tokens38.motion.shimmer / 2,
6711
- useNativeDriver: true
6712
- }),
6713
- Animated17.timing(opacity, {
6714
- toValue: 1,
6715
- duration: tokens38.motion.shimmer / 2,
6716
- useNativeDriver: true
6717
- })
6701
+ Animated17.timing(opacity, { toValue: 0.55, duration: tokens38.motion.shimmer / 2, useNativeDriver: true }),
6702
+ Animated17.timing(opacity, { toValue: 1, duration: tokens38.motion.shimmer / 2, useNativeDriver: true })
6718
6703
  ])
6719
6704
  );
6720
6705
  loop.start();
@@ -6722,92 +6707,68 @@ function KjunChartSkeleton({
6722
6707
  loop.stop();
6723
6708
  opacity.setValue(1);
6724
6709
  };
6725
- }, [opacity, reduced]);
6726
- return /* @__PURE__ */ jsxs27(
6710
+ }, [opacity, reduced, skeleton]);
6711
+ return /* @__PURE__ */ jsx39(
6727
6712
  Animated17.View,
6728
6713
  {
6729
- style: {
6730
- height,
6731
- alignItems: "center",
6732
- justifyContent: "center",
6733
- width: "100%",
6734
- minWidth: 0,
6735
- opacity
6736
- },
6737
- accessibilityElementsHidden: true,
6738
- importantForAccessibility: "no-hide-descendants",
6739
- children: [
6714
+ onLayout: typeof height === "number" ? void 0 : (event) => setMeasured(event.nativeEvent.layout.height),
6715
+ style: { height, alignItems: "center", justifyContent: "center", width: "100%", minWidth: 0, opacity: revealed ? opacity : 0 },
6716
+ "aria-hidden": revealed ? void 0 : true,
6717
+ importantForAccessibility: revealed ? void 0 : "no-hide-descendants",
6718
+ ...Platform24.OS === "web" ? { dataSet: { kjunChartKind: kind, skeleton: skeleton ? void 0 : "false" } } : {},
6719
+ children: !skeleton ? /* @__PURE__ */ jsxs27(View33, { ...chartPart("loading"), role: status, style: { alignItems: "center", gap: tokens38.dimension.value12 }, children: [
6720
+ /* @__PURE__ */ jsx39(View33, { ...hidden, children: /* @__PURE__ */ jsx39(KjunSpinner, { size: "md" }) }),
6721
+ !!loadingText && /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle("body"), color: colors.textSecondary, textAlign: "center", maxWidth: "100%" }, children: loadingText })
6722
+ ] }) : /* @__PURE__ */ jsxs27(Fragment12, { children: [
6740
6723
  kind === "donut" ? /* @__PURE__ */ jsx39(
6741
6724
  View33,
6742
6725
  {
6743
- style: {
6744
- height: "80%",
6745
- aspectRatio: 1,
6746
- borderWidth: tokens38.extensions.chartSkeleton.donutThickness,
6747
- borderColor: colors.skeleton,
6748
- borderRadius: tokens38.radius.radius9999,
6749
- alignItems: "center",
6750
- justifyContent: "center"
6751
- },
6752
- children: /* @__PURE__ */ jsx39(KjunSkeleton, { type: "block", width: tokens38.extensions.chartSkeleton.donutLabelWidth, height: tokens38.extensions.chartSkeleton.donutLabelHeight })
6726
+ ...chartPart("donut"),
6727
+ ...hidden,
6728
+ style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: tokens38.radius.radius9999 }
6753
6729
  }
6754
- ) : /* @__PURE__ */ jsxs27(
6755
- Svg5,
6730
+ ) : kind === "matrix" ? /* @__PURE__ */ jsx39(View33, { ...chartPart("matrix"), ...hidden, style: { alignSelf: "stretch", flex: 1, gap: tokens38.dimension.value4 }, children: Array.from({ length: rowCount }, (_, row) => /* @__PURE__ */ jsx39(View33, { style: { flex: 1, flexDirection: "row", gap: tokens38.dimension.value4 }, children: Array.from({ length: columnCount }, (_2, column) => /* @__PURE__ */ jsx39(
6731
+ View33,
6756
6732
  {
6757
- viewBox: "0 0 600 240",
6758
- preserveAspectRatio: "none",
6759
- width: "100%",
6760
- height: "100%",
6761
- children: [
6762
- /* @__PURE__ */ jsx39(
6763
- Path4,
6764
- {
6765
- d: "M20 10V220H590 M20 65H590 M20 120H590 M20 175H590",
6766
- fill: "none",
6767
- stroke: colors.border,
6768
- strokeWidth: 1
6769
- }
6770
- ),
6771
- kind === "line" && /* @__PURE__ */ jsx39(Path4, { d: "M20 190 L100 160 L180 172 L260 120 L340 140 L420 96 L500 110 L590 64", fill: "none", stroke: colors.skeleton, strokeWidth: 4, strokeLinecap: "round", strokeLinejoin: "round" }),
6772
- kind === "matrix" ? Array.from({ length: 8 }, (_, row) => /* @__PURE__ */ jsx39(G2, { children: Array.from({ length: 14 }, (_2, col) => /* @__PURE__ */ jsx39(
6773
- Rect3,
6774
- {
6775
- x: 24 + col * 40,
6776
- y: 12 + row * 26,
6777
- width: 36,
6778
- height: 22,
6779
- rx: 2,
6780
- fill: colors.skeleton,
6781
- opacity: (row + col + 2) % 3 === 0 ? 0.55 : 1
6733
+ ...chartPart("cell"),
6734
+ style: {
6735
+ flex: 1,
6736
+ borderRadius: tokens38.extensions.skeleton.lineRadius,
6737
+ backgroundColor: colors.skeleton,
6738
+ opacity: chartMatrixMuted(row, column) ? tokens38.states.opacity.pending : 1
6739
+ }
6740
+ },
6741
+ column
6742
+ )) }, row)) }) : /* @__PURE__ */ jsx39(View33, { ...chartPart("plot"), ...hidden, style: { alignSelf: "stretch", flex: 1 }, children: /* @__PURE__ */ jsx39(Svg5, { viewBox: chartFrameViewBox, preserveAspectRatio: "none", width: "100%", height: "100%", children: /* @__PURE__ */ jsx39(Path4, { d: chartFramePath, fill: "none", stroke: colors.chartGrid, strokeWidth: tokens38.border.defaultWidth, vectorEffect: "non-scaling-stroke" }) }) }),
6743
+ !!loadingText && /* @__PURE__ */ jsx39(
6744
+ View33,
6745
+ {
6746
+ ...chartPart("status"),
6747
+ role: status,
6748
+ accessibilityLiveRegion: status ? "polite" : void 0,
6749
+ pointerEvents: "none",
6750
+ style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center" },
6751
+ children: /* @__PURE__ */ jsx39(
6752
+ KText,
6753
+ {
6754
+ style: {
6755
+ ...typeStyle("body"),
6756
+ paddingHorizontal: tokens38.dimension.value12,
6757
+ paddingVertical: tokens38.dimension.value4,
6758
+ borderRadius: tokens38.radius.radius6,
6759
+ borderWidth: kind === "donut" ? 0 : tokens38.border.defaultWidth,
6760
+ borderColor: colors.chartGrid,
6761
+ backgroundColor: colors.surface,
6762
+ color: colors.textSecondary,
6763
+ maxWidth: kind === "donut" && hole != null ? hole : "90%",
6764
+ textAlign: "center"
6782
6765
  },
6783
- col
6784
- )) }, row)) : (kind === "bar" || kind === "candle") && [60, 100, 85, 140, 110, 165, 180].map((h, i) => /* @__PURE__ */ jsxs27(Fragment12, { children: [
6785
- kind === "candle" && /* @__PURE__ */ jsx39(
6786
- Path4,
6787
- {
6788
- d: `M${55 + i * 75} ${195 - h}V${225 - h / 2}`,
6789
- fill: "none",
6790
- stroke: colors.skeleton,
6791
- strokeWidth: 4
6792
- }
6793
- ),
6794
- /* @__PURE__ */ jsx39(
6795
- Rect3,
6796
- {
6797
- x: 35 + i * 75,
6798
- y: kind === "candle" ? 210 - h : 220 - h,
6799
- width: kind === "candle" ? 28 : 42,
6800
- height: kind === "candle" ? h / 2 : h,
6801
- rx: 3,
6802
- fill: colors.skeleton
6803
- }
6804
- )
6805
- ] }, i))
6806
- ]
6766
+ children: loadingText
6767
+ }
6768
+ )
6807
6769
  }
6808
- ),
6809
- /* @__PURE__ */ jsx39(View33, { pointerEvents: "none", style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center", gap: tokens38.dimension.value12 }, children: !!loadingText && /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle("body"), paddingHorizontal: tokens38.dimension.value12, paddingVertical: tokens38.dimension.value4, borderRadius: tokens38.radius.radius6, backgroundColor: colors.surface, color: colors.textSecondary, maxWidth: "90%", textAlign: "center" }, children: loadingText }) })
6810
- ]
6770
+ )
6771
+ ] })
6811
6772
  }
6812
6773
  );
6813
6774
  }
@@ -6831,7 +6792,7 @@ import Svg6, {
6831
6792
  import { tokens as tokens40 } from "@kjun-ui/tokens";
6832
6793
 
6833
6794
  // shared/package-runtime/use-number-motion.ts
6834
- import { useLayoutEffect as useLayoutEffect16, useRef as useRef31, useState as useState33 } from "react";
6795
+ import { useLayoutEffect as useLayoutEffect16, useRef as useRef31, useState as useState34 } from "react";
6835
6796
 
6836
6797
  // shared/package-runtime/number-motion.ts
6837
6798
  import { tokens as tokens39 } from "@kjun-ui/tokens";
@@ -6877,7 +6838,7 @@ function createNumberMotion(apply) {
6877
6838
 
6878
6839
  // shared/package-runtime/use-number-motion.ts
6879
6840
  function useNumberMotion(value, animated, fromPrevious, reduced) {
6880
- const [display, setDisplay] = useState33(typeof value === "string" || fromPrevious || !animated || reduced ? value : 0);
6841
+ const [display, setDisplay] = useState34(typeof value === "string" || fromPrevious || !animated || reduced ? value : 0);
6881
6842
  const motion = useRef31(null);
6882
6843
  if (!motion.current) motion.current = createNumberMotion(setDisplay);
6883
6844
  useLayoutEffect16(() => {
@@ -7364,7 +7325,7 @@ function KjunSparkline({
7364
7325
 
7365
7326
  // shared/package-runtime/table.ts
7366
7327
  import { nextTableSort } from "@kjun-ui/tokens";
7367
- import { useEffect as useEffect24, useRef as useRef33, useState as useState35 } from "react";
7328
+ import { useEffect as useEffect24, useRef as useRef33, useState as useState36 } from "react";
7368
7329
 
7369
7330
  // shared/package-runtime/table-model.ts
7370
7331
  function getValue(row, key) {
@@ -7408,10 +7369,10 @@ function useTableModel(props) {
7408
7369
  expandSingle = false,
7409
7370
  onExpandedRowsChange
7410
7371
  } = props;
7411
- const [internalSort, setSort] = useState35({
7372
+ const [internalSort, setSort] = useState36({
7412
7373
  key: "",
7413
7374
  order: "asc"
7414
- }), [internalExpanded, setExpanded] = useState35([]), [search, setSearch] = useState35(""), timer = useRef33(void 0);
7375
+ }), [internalExpanded, setExpanded] = useState36([]), [search, setSearch] = useState36(""), timer = useRef33(void 0);
7415
7376
  useEffect24(() => () => clearTimeout(timer.current), []);
7416
7377
  const sort = props.sort === void 0 ? internalSort : (_a = props.sort) != null ? _a : { key: "", order: "asc" };
7417
7378
  const rows = sortTableRows(data, sort, { sortable, sortMode });
@@ -7566,14 +7527,14 @@ function TableToolbar({
7566
7527
 
7567
7528
  // packages/native/src/table-grid.tsx
7568
7529
  import { tokens as tokens43 } from "@kjun-ui/tokens";
7569
- import { Fragment as Fragment15, useId as useId9, useState as useState36 } from "react";
7570
- import Svg7, { Defs as Defs3, LinearGradient as LinearGradient3, Rect as Rect4, Stop as Stop3 } from "react-native-svg";
7530
+ import { Fragment as Fragment15, useId as useId9, useState as useState37 } from "react";
7531
+ import Svg7, { Defs as Defs3, LinearGradient as LinearGradient3, Rect as Rect3, Stop as Stop3 } from "react-native-svg";
7571
7532
  import { ScrollView as ScrollView9, View as View37 } from "react-native";
7572
7533
  import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
7573
7534
  function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowClick, selectable, checkbox, cell, expandable, expand, renderExpand, emptyContent, emptyText, visible, maxHeight, stickyHeader, sortable, compact, striped, hoverable }) {
7574
7535
  const { colors } = useKjunStyles();
7575
7536
  const geometry2 = tokens43.table;
7576
- const [scroll, setScroll] = useState36({ viewport: 0, x: 0 }), fadeId = "kjun-table-fade-" + useId9().replace(/[^a-z0-9]/gi, "");
7537
+ const [scroll, setScroll] = useState37({ viewport: 0, x: 0 }), fadeId = "kjun-table-fade-" + useId9().replace(/[^a-z0-9]/gi, "");
7577
7538
  const cellPadding = geometry2.cellPadding[compact ? "compact" : "regular"];
7578
7539
  const width = (col) => typeof col.width === "number" ? col.width : typeof col.width === "string" && /^\d+(px)?$/.test(col.width) ? parseFloat(col.width) : geometry2.columnWidth;
7579
7540
  const totalWidth = visible.reduce((sum, col) => sum + width(col), 0) + (selectable ? geometry2.actionColumnWidth : 0) + (expandable ? geometry2.actionColumnWidth : 0);
@@ -7760,7 +7721,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
7760
7721
  /* @__PURE__ */ jsx43(Stop3, { offset: "0", stopColor: colors.surface, stopOpacity: 0 }),
7761
7722
  /* @__PURE__ */ jsx43(Stop3, { offset: "1", stopColor: colors.surface, stopOpacity: 1 })
7762
7723
  ] }) }),
7763
- /* @__PURE__ */ jsx43(Rect4, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
7724
+ /* @__PURE__ */ jsx43(Rect3, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
7764
7725
  ] }) })
7765
7726
  ] });
7766
7727
  }
@@ -8323,7 +8284,7 @@ function KjunKpiHero(props) {
8323
8284
 
8324
8285
  // packages/native/src/kpi-row.tsx
8325
8286
  import { tokens as tokens47 } from "@kjun-ui/tokens";
8326
- import { useState as useState37 } from "react";
8287
+ import { useState as useState38 } from "react";
8327
8288
  import {
8328
8289
  Text as Text6,
8329
8290
  View as View42,
@@ -8342,7 +8303,7 @@ function KjunKpiRow({
8342
8303
  const { colors, domainColors, numericFontFamily, fontFamily } = useKjunStyles(), mobile = useWindowDimensions9().width <= tokens47.responsive.kpiRow, small = size === "sm", summary = mobileSummary && mobile && !small;
8343
8304
  const geometry2 = tokens47.extensions.kpiRow;
8344
8305
  const spec = small ? geometry2.sm : mobile ? geometry2.mobile : geometry2.md;
8345
- const [width, setWidth] = useState37(0);
8306
+ const [width, setWidth] = useState38(0);
8346
8307
  const paddingX = summary ? geometry2.summary.paddingX : spec.paddingX;
8347
8308
  const gapX = summary ? geometry2.summary.gapX : 0;
8348
8309
  const explicit = items.some(
@@ -8561,7 +8522,7 @@ import { tokens as tokens49 } from "@kjun-ui/tokens";
8561
8522
  import { ScrollView as ScrollView10, View as View44 } from "react-native";
8562
8523
 
8563
8524
  // shared/package-runtime/market-cards.ts
8564
- import { useEffect as useEffect25, useRef as useRef34, useState as useState38 } from "react";
8525
+ import { useEffect as useEffect25, useRef as useRef34, useState as useState39 } from "react";
8565
8526
  function useMarketCardsModel(props, persistence) {
8566
8527
  const {
8567
8528
  columns,
@@ -8577,7 +8538,7 @@ function useMarketCardsModel(props, persistence) {
8577
8538
  sortKey: c.sortable ? metricConfig[c.key].sortKey : null,
8578
8539
  isDefaultSort: c.defaultSort
8579
8540
  }));
8580
- const [key, setKey] = useState38(""), restoreSignature = JSON.stringify([storageNamespace, pills]);
8541
+ const [key, setKey] = useState39(""), restoreSignature = JSON.stringify([storageNamespace, pills]);
8581
8542
  const mounted = useRef34("");
8582
8543
  const save = (key2) => {
8583
8544
  var _a;
@@ -9066,9 +9027,9 @@ function KjunMarketListPanel({
9066
9027
 
9067
9028
  // packages/native/src/market-table.tsx
9068
9029
  import { tokens as tokens52 } from "@kjun-ui/tokens";
9069
- import { useId as useId10, useState as useState39 } from "react";
9030
+ import { useId as useId10, useState as useState40 } from "react";
9070
9031
  import { ScrollView as ScrollView11, View as View47 } from "react-native";
9071
- import Svg8, { Defs as Defs4, LinearGradient as LinearGradient4, Rect as Rect5, Stop as Stop4 } from "react-native-svg";
9032
+ import Svg8, { Defs as Defs4, LinearGradient as LinearGradient4, Rect as Rect4, Stop as Stop4 } from "react-native-svg";
9072
9033
  import { jsx as jsx53, jsxs as jsxs41 } from "react/jsx-runtime";
9073
9034
  function KjunMarketTable(props) {
9074
9035
  const {
@@ -9152,7 +9113,7 @@ function KjunMarketTable(props) {
9152
9113
  );
9153
9114
  };
9154
9115
  const layout = useMarketLayout(columns, showActions);
9155
- const [scroll, setScroll] = useState39({ viewport: 0, x: 0 }), fadeId = "kjun-market-fade-" + useId10().replace(/[^a-z0-9]/gi, "");
9116
+ const [scroll, setScroll] = useState40({ viewport: 0, x: 0 }), fadeId = "kjun-market-fade-" + useId10().replace(/[^a-z0-9]/gi, "");
9156
9117
  const tableQuote = { price: {}, change: { fontWeight: typeStyle("body").fontWeight } };
9157
9118
  return /* @__PURE__ */ jsxs41(
9158
9119
  View47,
@@ -9362,7 +9323,7 @@ function KjunMarketTable(props) {
9362
9323
  /* @__PURE__ */ jsx53(Stop4, { offset: "0", stopColor: colors.surface, stopOpacity: 0 }),
9363
9324
  /* @__PURE__ */ jsx53(Stop4, { offset: "1", stopColor: colors.surface, stopOpacity: 1 })
9364
9325
  ] }) }),
9365
- /* @__PURE__ */ jsx53(Rect5, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
9326
+ /* @__PURE__ */ jsx53(Rect4, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
9366
9327
  ] }) })
9367
9328
  ] }) })
9368
9329
  }
@@ -9376,7 +9337,7 @@ function KjunMarketTable(props) {
9376
9337
  // packages/native/src/list.tsx
9377
9338
  import { tokens as tokens53 } from "@kjun-ui/tokens";
9378
9339
  import { Children as Children4, createContext as createContext20, useContext as useContext17 } from "react";
9379
- import { View as View48, Platform as Platform24 } from "react-native";
9340
+ import { View as View48, Platform as Platform25 } from "react-native";
9380
9341
  import { Fragment as Fragment19, jsx as jsx54, jsxs as jsxs42 } from "react/jsx-runtime";
9381
9342
  var LastListRow = createContext20(false);
9382
9343
  function KjunListRow({ title, description, leading, trailing, actions, href, disabled = false, onPress }) {
@@ -9391,8 +9352,8 @@ function KjunListRow({ title, description, leading, trailing, actions, href, dis
9391
9352
  ] });
9392
9353
  const style = { flex: 1, minWidth: 0, minHeight: tokens53.extensions.list.minimumHeight, flexDirection: "row", alignItems: "center", gap: tokens53.extensions.list.gap, padding: tokens53.extensions.list.padding };
9393
9354
  return /* @__PURE__ */ jsxs42(View48, { role: "listitem", style: { flexDirection: "row", alignItems: "center", gap: tokens53.extensions.list.gap, borderBottomWidth: last ? 0 : tokens53.border.defaultWidth, borderBottomColor: colors.divider }, children: [
9394
- onPress || href ? /* @__PURE__ */ jsx54(AccessiblePressable, { ...Platform24.OS === "web" && href && !disabled ? { href } : {}, accessibilityRole: href ? "link" : "button", accessibilityLabel: title + (description ? ", " + description : ""), disabled, accessibilityState: { disabled }, onPress, style: ({ pressed }) => ({ ...style, opacity: disabled ? tokens53.states.opacity.disabled : 1, backgroundColor: pressed ? colors.hover : "transparent" }), children: parts }) : /* @__PURE__ */ jsx54(View48, { style, children: parts }),
9395
- actions && /* @__PURE__ */ jsx54(View48, { pointerEvents: disabled ? "none" : "auto", ...disabled && Platform24.OS === "web" ? { inert: true } : {}, style: { maxWidth: "45%", flexDirection: "row", flexWrap: "wrap", gap: tokens53.extensions.list.actionsGap, paddingRight: tokens53.extensions.list.actionsPadding, opacity: disabled ? tokens53.states.opacity.disabled : 1 }, children: content(actions) })
9355
+ onPress || href ? /* @__PURE__ */ jsx54(AccessiblePressable, { ...Platform25.OS === "web" && href && !disabled ? { href } : {}, accessibilityRole: href ? "link" : "button", accessibilityLabel: title + (description ? ", " + description : ""), disabled, accessibilityState: { disabled }, onPress, style: ({ pressed }) => ({ ...style, opacity: disabled ? tokens53.states.opacity.disabled : 1, backgroundColor: pressed ? colors.hover : "transparent" }), children: parts }) : /* @__PURE__ */ jsx54(View48, { style, children: parts }),
9356
+ actions && /* @__PURE__ */ jsx54(View48, { pointerEvents: disabled ? "none" : "auto", ...disabled && Platform25.OS === "web" ? { inert: true } : {}, style: { maxWidth: "45%", flexDirection: "row", flexWrap: "wrap", gap: tokens53.extensions.list.actionsGap, paddingRight: tokens53.extensions.list.actionsPadding, opacity: disabled ? tokens53.states.opacity.disabled : 1 }, children: content(actions) })
9396
9357
  ] });
9397
9358
  }
9398
9359
  function KjunListSection({ title, description, actions, children, ariaLabel }) {
@@ -9411,16 +9372,16 @@ function KjunListSection({ title, description, actions, children, ariaLabel }) {
9411
9372
 
9412
9373
  // packages/native/src/app-navigation.tsx
9413
9374
  import { tokens as tokens54 } from "@kjun-ui/tokens";
9414
- import { Children as Children5, Fragment as Fragment20, isValidElement as isValidElement7, useState as useState40 } from "react";
9415
- import { View as View49, Platform as Platform25 } from "react-native";
9375
+ import { Children as Children5, Fragment as Fragment20, isValidElement as isValidElement7, useState as useState41 } from "react";
9376
+ import { View as View49, Platform as Platform26 } from "react-native";
9416
9377
  import { jsx as jsx55, jsxs as jsxs43 } from "react/jsx-runtime";
9417
9378
  function KjunTopNavigation({ title, description, leading, actions, safeAreaTop = 0 }) {
9418
9379
  const { colors } = useKjunStyles();
9419
9380
  const geometry2 = tokens54.extensions.topNavigation;
9420
9381
  const titleInset = Math.max(0, (geometry2.controlSize - tokens54.typography.sectionTitle.lineHeightPx) / 2);
9421
- const wrapping = Platform25.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9382
+ const wrapping = Platform26.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9422
9383
  const edgeInset = (geometry2.controlSize - geometry2.iconSize) / 2;
9423
- const [iconEdges, setIconEdges] = useState40({ leading: false, trailing: false });
9384
+ const [iconEdges, setIconEdges] = useState41({ leading: false, trailing: false });
9424
9385
  const square = (key) => (event) => {
9425
9386
  const { width, height } = event.nativeEvent.layout;
9426
9387
  const next = Math.abs(width - height) < 1 && Math.abs(height - geometry2.controlSize) < 1;
@@ -9465,8 +9426,8 @@ function KjunBottomNavigation({ items, value, ariaLabel = "\uC8FC\uC694 \uD0D0\u
9465
9426
  AccessiblePressable,
9466
9427
  {
9467
9428
  focusRingInset: true,
9468
- ...Platform25.OS === "web" ? { href: item.disabled ? void 0 : item.href, "aria-current": selected ? "page" : void 0 } : {},
9469
- accessibilityRole: Platform25.OS === "web" && item.href ? "link" : "button",
9429
+ ...Platform26.OS === "web" ? { href: item.disabled ? void 0 : item.href, "aria-current": selected ? "page" : void 0 } : {},
9430
+ accessibilityRole: Platform26.OS === "web" && item.href ? "link" : "button",
9470
9431
  accessibilityLabel: item.label + (item.badge != null ? ", " + item.badge : ""),
9471
9432
  accessibilityState: { selected, disabled: !!item.disabled },
9472
9433
  disabled: item.disabled,
@@ -9500,10 +9461,10 @@ function KjunBottomNavigation({ items, value, ariaLabel = "\uC8FC\uC694 \uD0D0\u
9500
9461
  }
9501
9462
  function KjunBottomActionBar({ description, children, safeAreaBottom = 0, keyboardVisible = false, hideOnKeyboard = false }) {
9502
9463
  const { colors } = useKjunStyles();
9503
- const [width, setWidth] = useState40(0);
9464
+ const [width, setWidth] = useState41(0);
9504
9465
  const geometry2 = tokens54.extensions.navigation;
9505
9466
  const wide = width >= tokens54.responsive.bottomAction + geometry2.padding * 2;
9506
- const wrapping = Platform25.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9467
+ const wrapping = Platform26.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9507
9468
  if (keyboardVisible && hideOnKeyboard) return null;
9508
9469
  return /* @__PURE__ */ jsx55(BottomActionBarContext.Provider, { value: !wide, children: /* @__PURE__ */ jsxs43(View49, { onLayout: (event) => setWidth(event.nativeEvent.layout.width), style: {
9509
9470
  flexShrink: 0,
@@ -9522,7 +9483,7 @@ function KjunBottomActionBar({ description, children, safeAreaBottom = 0, keyboa
9522
9483
  }
9523
9484
 
9524
9485
  // packages/native/src/media.tsx
9525
- import { useRef as useRef35, useState as useState41 } from "react";
9486
+ import { useRef as useRef35, useState as useState42 } from "react";
9526
9487
  import { Image, View as View50 } from "react-native";
9527
9488
  import { tokens as tokens55 } from "@kjun-ui/tokens";
9528
9489
  import { jsx as jsx56 } from "react/jsx-runtime";
@@ -9531,7 +9492,7 @@ function KjunImage({ src, source, alt, decorative = false, aspectRatio = 1, fit
9531
9492
  const request = JSON.stringify(source != null ? source : src), current = useRef35({ request, version: 0 });
9532
9493
  if (current.current.request !== request) current.current = { request, version: current.current.version + 1 };
9533
9494
  const version = current.current.version;
9534
- const [failed, setFailed] = useState41(null);
9495
+ const [failed, setFailed] = useState42(null);
9535
9496
  const missing = !source && !src;
9536
9497
  return /* @__PURE__ */ jsx56(View50, { 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__ */ jsx56(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: () => {
9537
9498
  if (version === current.current.version) onLoad == null ? void 0 : onLoad();
@@ -9561,8 +9522,8 @@ function KjunChip({ label, icon, removable = false, disabled = false, size = "md
9561
9522
  }
9562
9523
 
9563
9524
  // packages/native/src/range-input.tsx
9564
- import { useEffect as useEffect26, useMemo as useMemo2, useRef as useRef36, useState as useState42 } from "react";
9565
- import { PanResponder, Platform as Platform26, Pressable as Pressable3, View as View52 } from "react-native";
9525
+ import { useEffect as useEffect26, useMemo as useMemo2, useRef as useRef36, useState as useState43 } from "react";
9526
+ import { PanResponder, Platform as Platform27, Pressable as Pressable3, View as View52 } from "react-native";
9566
9527
  import { tokens as tokens57, createSliderDomain, sliderKey } from "@kjun-ui/tokens";
9567
9528
  import { jsx as jsx58, jsxs as jsxs45 } from "react/jsx-runtime";
9568
9529
  var geometry = tokens57.extensions.slider;
@@ -9585,9 +9546,9 @@ function RangeInput({
9585
9546
  const valid = domain.valid && (!Array.isArray(value) || value.length === 2) && values.every(domain.accepts) && (values.length === 1 || values[0] <= values[1]);
9586
9547
  const blocked = disabled || !valid;
9587
9548
  const effectiveMax = valid ? domain.snap(max) : min;
9588
- const [hovered, setHovered] = useState42(null);
9589
- const [dragging, setDragging] = useState42(null);
9590
- const [focused, setFocused] = useState42(null);
9549
+ const [hovered, setHovered] = useState43(null);
9550
+ const [dragging, setDragging] = useState43(null);
9551
+ const [focused, setFocused] = useState43(null);
9591
9552
  const track = useRef36(null), measured = useRef36({ x: 0, width: 1 }), selected = useRef36(0), dirty = useRef36(false);
9592
9553
  const latest = useRef36(values);
9593
9554
  latest.current = values;
@@ -9793,7 +9754,7 @@ function RangeInput({
9793
9754
  setFocused(null);
9794
9755
  commit();
9795
9756
  },
9796
- ...Platform26.OS === "web" ? {
9757
+ ...Platform27.OS === "web" ? {
9797
9758
  "aria-valuenow": number,
9798
9759
  "aria-valuemin": index === 1 ? values[0] : min,
9799
9760
  "aria-valuemax": values.length === 2 && index === 0 ? values[1] : domain.snap(max),
@@ -9817,7 +9778,7 @@ function RangeInput({
9817
9778
  alignItems: "center",
9818
9779
  justifyContent: "center",
9819
9780
  zIndex: focused === index || dragging === index ? 1 : 0,
9820
- ...Platform26.OS === "web" ? {
9781
+ ...Platform27.OS === "web" ? {
9821
9782
  outlineStyle: "solid",
9822
9783
  outlineWidth: 0,
9823
9784
  cursor: blocked ? "default" : dragging === index ? "grabbing" : "grab"
@@ -9834,7 +9795,7 @@ function RangeInput({
9834
9795
  borderWidth: tokens57.border.controlWidth,
9835
9796
  borderColor: !blocked && dragging === index ? colors.brandActive : !blocked && hovered === index ? colors.brandHover : colors.brand,
9836
9797
  backgroundColor: colors.surface,
9837
- ...Platform26.OS === "web" && !blocked && focused === index ? {
9798
+ ...Platform27.OS === "web" && !blocked && focused === index ? {
9838
9799
  outlineStyle: "solid",
9839
9800
  outlineWidth: tokens57.states.focus.width,
9840
9801
  outlineOffset: tokens57.states.focus.choiceOffset,
@@ -9861,8 +9822,8 @@ function KjunRangeSlider(props) {
9861
9822
  }
9862
9823
 
9863
9824
  // packages/native/src/quantity-stepper.tsx
9864
- import { useEffect as useEffect27, useRef as useRef37, useState as useState43 } from "react";
9865
- import { Platform as Platform27, View as View53 } from "react-native";
9825
+ import { useEffect as useEffect27, useRef as useRef37, useState as useState44 } from "react";
9826
+ import { Platform as Platform28, View as View53 } from "react-native";
9866
9827
  import { createNumberDomain, quantityKeyAction, tokens as tokens58 } from "@kjun-ui/tokens";
9867
9828
 
9868
9829
  // shared/package-runtime/component-icons.ts
@@ -9883,7 +9844,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9883
9844
  const increaseStyle = { ...buttonStyle, borderRadius: 0, borderTopRightRadius: outer, borderBottomRightRadius: outer };
9884
9845
  const domain = createNumberDomain({ min, max, step, precision }), valid = domain.valid && domain.accepts(value), blocked = disabled || !valid;
9885
9846
  const surface = useFieldSurface(size, { disabled: blocked, invalid });
9886
- const [draft, setDraft] = useState43(String(value));
9847
+ const [draft, setDraft] = useState44(String(value));
9887
9848
  const inputRef = useRef37(null);
9888
9849
  const composing = useRef37(false), dirty = useRef37(false), accepted = useRef37(value);
9889
9850
  const cancelledEscape = useRef37(false);
@@ -9938,7 +9899,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9938
9899
  setDraft(text);
9939
9900
  } };
9940
9901
  useEffect27(() => {
9941
- if (Platform27.OS !== "web") return;
9902
+ if (Platform28.OS !== "web") return;
9942
9903
  const input = inputRef.current;
9943
9904
  const keydown = (event) => handlers.current.key(event);
9944
9905
  const keyup = (event) => {
@@ -9967,7 +9928,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9967
9928
  };
9968
9929
  }, []);
9969
9930
  const surfaceBox = { position: "absolute", left: 0, right: 0, top: "50%", height: tokens58.input[size].height, marginTop: -tokens58.input[size].height / 2, borderRadius: surface.spec.radius };
9970
- const hug = Platform27.OS === "web" && !block ? { width: "fit-content" } : {};
9931
+ const hug = Platform28.OS === "web" && !block ? { width: "fit-content" } : {};
9971
9932
  return /* @__PURE__ */ jsx59(IconFallbacks, { icons: componentIcons, children: /* @__PURE__ */ jsxs46(View53, { style: { flexDirection: "row", alignItems: "center", alignSelf: block ? "stretch" : "flex-start", maxWidth: "100%", borderRadius: surface.spec.radius, ...hug }, children: [
9972
9933
  /* @__PURE__ */ jsx59(View53, { pointerEvents: "none", "aria-hidden": true, style: { ...surfaceBox, backgroundColor: colors.inputBg } }),
9973
9934
  /* @__PURE__ */ jsx59(CompoundTarget, { square: true, children: /* @__PURE__ */ jsx59(KjunButton, { size, style: decreaseStyle, variant: "ghost", ariaLabel: "\uC218\uB7C9 \uC904\uC774\uAE30", disabled: blocked || value <= min, onPress: () => move(-1), prefixIcon: "minus" }) }),
@@ -9998,8 +9959,8 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9998
9959
  surface.setFocused(false);
9999
9960
  commit();
10000
9961
  },
10001
- onSubmitEditing: Platform27.OS === "web" ? void 0 : commit,
10002
- ...Platform27.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 },
9962
+ onSubmitEditing: Platform28.OS === "web" ? void 0 : commit,
9963
+ ...Platform28.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 },
10003
9964
  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 - tokens58.border.controlWidth, paddingVertical: 0 }
10004
9965
  }
10005
9966
  ) }),
@@ -10009,7 +9970,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
10009
9970
  }
10010
9971
 
10011
9972
  // packages/native/src/time-picker.tsx
10012
- import { Fragment as Fragment21, useEffect as useEffect28, useId as useId11, useMemo as useMemo3, useRef as useRef38, useState as useState44 } from "react";
9973
+ import { Fragment as Fragment21, useEffect as useEffect28, useId as useId11, useMemo as useMemo3, useRef as useRef38, useState as useState45 } from "react";
10013
9974
  import { View as View54 } from "react-native";
10014
9975
  import { createTimeDomain, tokens as tokens59 } from "@kjun-ui/tokens";
10015
9976
  import { jsx as jsx60, jsxs as jsxs47 } from "react/jsx-runtime";
@@ -10017,7 +9978,7 @@ function KjunTimePicker({ value, precision = "minute", min, max, minuteStep = 1,
10017
9978
  const geometry2 = tokens59.extensions.timePicker, spec = tokens59.input[size];
10018
9979
  const { colors } = useKjunStyles();
10019
9980
  const first = useRef38(null);
10020
- const [focused, setFocused] = useState44(false), [opened, setOpened] = useState44(null);
9981
+ const [focused, setFocused] = useState45(false), [opened, setOpened] = useState45(null);
10021
9982
  const field = useKjunField(), uid = useId11();
10022
9983
  const fieldId = (field == null ? void 0 : field.id) || `kjun-time-${uid}`;
10023
9984
  const domain = useMemo3(() => createTimeDomain({ precision, min, max, minuteStep, secondStep }), [precision, min, max, minuteStep, secondStep]), valid = domain.valid && domain.accepts(value);