@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.js CHANGED
@@ -2271,36 +2271,6 @@ function KjunSkeleton({
2271
2271
  ))
2272
2272
  }
2273
2273
  ),
2274
- type === "chart" && /* @__PURE__ */ jsxs7(View10, { style: [frame, { height: height || tokens11.extensions.skeleton.chartHeight }], children: [
2275
- /* @__PURE__ */ jsx15(
2276
- View10,
2277
- {
2278
- style: {
2279
- flex: 1,
2280
- flexDirection: "row",
2281
- alignItems: "flex-end",
2282
- justifyContent: "space-around",
2283
- gap: tokens11.extensions.skeleton.gap
2284
- // Bars stand on the axis line, like ChartSkeleton.
2285
- },
2286
- children: [40, 65, 50, 80, 60, 90, 75].map((h, i) => /* @__PURE__ */ jsx15(
2287
- Animated6.View,
2288
- {
2289
- style: {
2290
- flex: 1,
2291
- maxWidth: tokens11.extensions.skeleton.chartBarMaxWidth,
2292
- height: `${h}%`,
2293
- backgroundColor: shimmer,
2294
- borderTopLeftRadius: tokens11.radius.radius4,
2295
- borderTopRightRadius: tokens11.radius.radius4
2296
- }
2297
- },
2298
- i
2299
- ))
2300
- }
2301
- ),
2302
- block("100%", tokens11.extensions.skeleton.chartAxisHeight, { backgroundColor: colors.border })
2303
- ] }),
2304
2274
  type === "stat" && /* @__PURE__ */ jsxs7(
2305
2275
  View10,
2306
2276
  {
@@ -6279,9 +6249,27 @@ var KjunErrorBoundary = class extends Component {
6279
6249
 
6280
6250
  // packages/native/src/skeletons.tsx
6281
6251
  import { tokens as tokens37 } from "@kjun-ui/tokens";
6282
- import { Fragment as Fragment11, useEffect as useEffect22, useRef as useRef28 } from "react";
6283
- import { Animated as Animated17, View as View32, useWindowDimensions as useWindowDimensions6 } from "react-native";
6284
- import Svg5, { G as G2, Path as Path4, Rect as Rect3 } from "react-native-svg";
6252
+ import { useEffect as useEffect22, useRef as useRef28, useState as useState32 } from "react";
6253
+ import { Animated as Animated17, Platform as Platform24, View as View32, useWindowDimensions as useWindowDimensions6 } from "react-native";
6254
+ import Svg5, { Path as Path4 } from "react-native-svg";
6255
+
6256
+ // shared/package-runtime/chart-skeleton.ts
6257
+ var chartFrameViewBox = "0 0 600 240";
6258
+ var chartFramePath = "M20 10V220H590 M20 65H590 M20 120H590 M20 175H590";
6259
+ var chartSkeletonMaxCount = 100;
6260
+ function chartSkeletonCount(value) {
6261
+ return Number.isFinite(value) ? Math.min(chartSkeletonMaxCount, Math.max(1, Math.floor(value))) : 1;
6262
+ }
6263
+ function chartMatrixMuted(row, column) {
6264
+ return (row + column + 2) % 3 === 0;
6265
+ }
6266
+ var chartDonutRatio = 0.8;
6267
+ function chartDonutHole(height, thickness) {
6268
+ return Math.max(0, height * chartDonutRatio - 2 * thickness);
6269
+ }
6270
+ function chartSkeletonKind(kind) {
6271
+ return kind === "donut" || kind === "matrix" ? kind : "frame";
6272
+ }
6285
6273
 
6286
6274
  // packages/native/src/market-skeleton.tsx
6287
6275
  import { tokens as tokens36 } from "@kjun-ui/tokens";
@@ -6339,7 +6327,7 @@ function KjunMarketTableSkeleton({ columns = [], rows = 8, showActions = false }
6339
6327
  }
6340
6328
 
6341
6329
  // packages/native/src/skeletons.tsx
6342
- import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
6330
+ import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
6343
6331
  function KjunListSkeleton({
6344
6332
  rows = 8,
6345
6333
  variant = "market",
@@ -6440,26 +6428,23 @@ function KjunFormSkeleton({
6440
6428
  }
6441
6429
  );
6442
6430
  }
6431
+ var chartPart = (name) => Platform24.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
6443
6432
  function KjunChartSkeleton({
6433
+ kind: requestedKind = "frame",
6434
+ height = tokens37.extensions.chartSkeleton.height,
6444
6435
  loadingText = "\uCC28\uD2B8\uB97C \uBD88\uB7EC\uC624\uB294 \uC911",
6445
- kind = "line",
6446
- height = tokens37.extensions.chartSkeleton.height
6436
+ skeleton = true,
6437
+ loadingDelay = 0,
6438
+ rows = 8,
6439
+ columns = 14
6447
6440
  }) {
6448
- const { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef28(new Animated17.Value(1)).current;
6441
+ const kind = chartSkeletonKind(requestedKind), { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = useRef28(new Animated17.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = useState32(0), thickness = tokens37.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" };
6449
6442
  useEffect22(() => {
6450
- if (reduced) return;
6443
+ if (reduced || !skeleton) return;
6451
6444
  const loop = Animated17.loop(
6452
6445
  Animated17.sequence([
6453
- Animated17.timing(opacity, {
6454
- toValue: 0.55,
6455
- duration: tokens37.motion.shimmer / 2,
6456
- useNativeDriver: true
6457
- }),
6458
- Animated17.timing(opacity, {
6459
- toValue: 1,
6460
- duration: tokens37.motion.shimmer / 2,
6461
- useNativeDriver: true
6462
- })
6446
+ Animated17.timing(opacity, { toValue: 0.55, duration: tokens37.motion.shimmer / 2, useNativeDriver: true }),
6447
+ Animated17.timing(opacity, { toValue: 1, duration: tokens37.motion.shimmer / 2, useNativeDriver: true })
6463
6448
  ])
6464
6449
  );
6465
6450
  loop.start();
@@ -6467,92 +6452,68 @@ function KjunChartSkeleton({
6467
6452
  loop.stop();
6468
6453
  opacity.setValue(1);
6469
6454
  };
6470
- }, [opacity, reduced]);
6471
- return /* @__PURE__ */ jsxs26(
6455
+ }, [opacity, reduced, skeleton]);
6456
+ return /* @__PURE__ */ jsx39(
6472
6457
  Animated17.View,
6473
6458
  {
6474
- style: {
6475
- height,
6476
- alignItems: "center",
6477
- justifyContent: "center",
6478
- width: "100%",
6479
- minWidth: 0,
6480
- opacity
6481
- },
6482
- accessibilityElementsHidden: true,
6483
- importantForAccessibility: "no-hide-descendants",
6484
- children: [
6459
+ onLayout: typeof height === "number" ? void 0 : (event) => setMeasured(event.nativeEvent.layout.height),
6460
+ style: { height, alignItems: "center", justifyContent: "center", width: "100%", minWidth: 0, opacity: revealed ? opacity : 0 },
6461
+ "aria-hidden": revealed ? void 0 : true,
6462
+ importantForAccessibility: revealed ? void 0 : "no-hide-descendants",
6463
+ ...Platform24.OS === "web" ? { dataSet: { kjunChartKind: kind, skeleton: skeleton ? void 0 : "false" } } : {},
6464
+ children: !skeleton ? /* @__PURE__ */ jsxs26(View32, { ...chartPart("loading"), role: status, style: { alignItems: "center", gap: tokens37.dimension.value12 }, children: [
6465
+ /* @__PURE__ */ jsx39(View32, { ...hidden, children: /* @__PURE__ */ jsx39(KjunSpinner, { size: "md" }) }),
6466
+ !!loadingText && /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle("body"), color: colors.textSecondary, textAlign: "center", maxWidth: "100%" }, children: loadingText })
6467
+ ] }) : /* @__PURE__ */ jsxs26(Fragment11, { children: [
6485
6468
  kind === "donut" ? /* @__PURE__ */ jsx39(
6486
6469
  View32,
6487
6470
  {
6488
- style: {
6489
- height: "80%",
6490
- aspectRatio: 1,
6491
- borderWidth: tokens37.extensions.chartSkeleton.donutThickness,
6492
- borderColor: colors.skeleton,
6493
- borderRadius: tokens37.radius.radius9999,
6494
- alignItems: "center",
6495
- justifyContent: "center"
6496
- },
6497
- children: /* @__PURE__ */ jsx39(KjunSkeleton, { type: "block", width: tokens37.extensions.chartSkeleton.donutLabelWidth, height: tokens37.extensions.chartSkeleton.donutLabelHeight })
6471
+ ...chartPart("donut"),
6472
+ ...hidden,
6473
+ style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: tokens37.radius.radius9999 }
6498
6474
  }
6499
- ) : /* @__PURE__ */ jsxs26(
6500
- Svg5,
6475
+ ) : kind === "matrix" ? /* @__PURE__ */ jsx39(View32, { ...chartPart("matrix"), ...hidden, style: { alignSelf: "stretch", flex: 1, gap: tokens37.dimension.value4 }, children: Array.from({ length: rowCount }, (_, row) => /* @__PURE__ */ jsx39(View32, { style: { flex: 1, flexDirection: "row", gap: tokens37.dimension.value4 }, children: Array.from({ length: columnCount }, (_2, column) => /* @__PURE__ */ jsx39(
6476
+ View32,
6501
6477
  {
6502
- viewBox: "0 0 600 240",
6503
- preserveAspectRatio: "none",
6504
- width: "100%",
6505
- height: "100%",
6506
- children: [
6507
- /* @__PURE__ */ jsx39(
6508
- Path4,
6509
- {
6510
- d: "M20 10V220H590 M20 65H590 M20 120H590 M20 175H590",
6511
- fill: "none",
6512
- stroke: colors.border,
6513
- strokeWidth: 1
6514
- }
6515
- ),
6516
- 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" }),
6517
- kind === "matrix" ? Array.from({ length: 8 }, (_, row) => /* @__PURE__ */ jsx39(G2, { children: Array.from({ length: 14 }, (_2, col) => /* @__PURE__ */ jsx39(
6518
- Rect3,
6519
- {
6520
- x: 24 + col * 40,
6521
- y: 12 + row * 26,
6522
- width: 36,
6523
- height: 22,
6524
- rx: 2,
6525
- fill: colors.skeleton,
6526
- opacity: (row + col + 2) % 3 === 0 ? 0.55 : 1
6478
+ ...chartPart("cell"),
6479
+ style: {
6480
+ flex: 1,
6481
+ borderRadius: tokens37.extensions.skeleton.lineRadius,
6482
+ backgroundColor: colors.skeleton,
6483
+ opacity: chartMatrixMuted(row, column) ? tokens37.states.opacity.pending : 1
6484
+ }
6485
+ },
6486
+ column
6487
+ )) }, row)) }) : /* @__PURE__ */ jsx39(View32, { ...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: tokens37.border.defaultWidth, vectorEffect: "non-scaling-stroke" }) }) }),
6488
+ !!loadingText && /* @__PURE__ */ jsx39(
6489
+ View32,
6490
+ {
6491
+ ...chartPart("status"),
6492
+ role: status,
6493
+ accessibilityLiveRegion: status ? "polite" : void 0,
6494
+ pointerEvents: "none",
6495
+ style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center" },
6496
+ children: /* @__PURE__ */ jsx39(
6497
+ KText,
6498
+ {
6499
+ style: {
6500
+ ...typeStyle("body"),
6501
+ paddingHorizontal: tokens37.dimension.value12,
6502
+ paddingVertical: tokens37.dimension.value4,
6503
+ borderRadius: tokens37.radius.radius6,
6504
+ borderWidth: kind === "donut" ? 0 : tokens37.border.defaultWidth,
6505
+ borderColor: colors.chartGrid,
6506
+ backgroundColor: colors.surface,
6507
+ color: colors.textSecondary,
6508
+ maxWidth: kind === "donut" && hole != null ? hole : "90%",
6509
+ textAlign: "center"
6527
6510
  },
6528
- col
6529
- )) }, row)) : (kind === "bar" || kind === "candle") && [60, 100, 85, 140, 110, 165, 180].map((h, i) => /* @__PURE__ */ jsxs26(Fragment11, { children: [
6530
- kind === "candle" && /* @__PURE__ */ jsx39(
6531
- Path4,
6532
- {
6533
- d: `M${55 + i * 75} ${195 - h}V${225 - h / 2}`,
6534
- fill: "none",
6535
- stroke: colors.skeleton,
6536
- strokeWidth: 4
6537
- }
6538
- ),
6539
- /* @__PURE__ */ jsx39(
6540
- Rect3,
6541
- {
6542
- x: 35 + i * 75,
6543
- y: kind === "candle" ? 210 - h : 220 - h,
6544
- width: kind === "candle" ? 28 : 42,
6545
- height: kind === "candle" ? h / 2 : h,
6546
- rx: 3,
6547
- fill: colors.skeleton
6548
- }
6549
- )
6550
- ] }, i))
6551
- ]
6511
+ children: loadingText
6512
+ }
6513
+ )
6552
6514
  }
6553
- ),
6554
- /* @__PURE__ */ jsx39(View32, { pointerEvents: "none", style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center", gap: tokens37.dimension.value12 }, children: !!loadingText && /* @__PURE__ */ jsx39(KText, { style: { ...typeStyle("body"), paddingHorizontal: tokens37.dimension.value12, paddingVertical: tokens37.dimension.value4, borderRadius: tokens37.radius.radius6, backgroundColor: colors.surface, color: colors.textSecondary, maxWidth: "90%", textAlign: "center" }, children: loadingText }) })
6555
- ]
6515
+ )
6516
+ ] })
6556
6517
  }
6557
6518
  );
6558
6519
  }
@@ -6576,7 +6537,7 @@ import Svg6, {
6576
6537
  import { tokens as tokens39 } from "@kjun-ui/tokens";
6577
6538
 
6578
6539
  // shared/package-runtime/use-number-motion.ts
6579
- import { useLayoutEffect as useLayoutEffect12, useRef as useRef29, useState as useState32 } from "react";
6540
+ import { useLayoutEffect as useLayoutEffect12, useRef as useRef29, useState as useState33 } from "react";
6580
6541
 
6581
6542
  // shared/package-runtime/number-motion.ts
6582
6543
  import { tokens as tokens38 } from "@kjun-ui/tokens";
@@ -6622,7 +6583,7 @@ function createNumberMotion(apply) {
6622
6583
 
6623
6584
  // shared/package-runtime/use-number-motion.ts
6624
6585
  function useNumberMotion(value, animated, fromPrevious, reduced) {
6625
- const [display, setDisplay] = useState32(typeof value === "string" || fromPrevious || !animated || reduced ? value : 0);
6586
+ const [display, setDisplay] = useState33(typeof value === "string" || fromPrevious || !animated || reduced ? value : 0);
6626
6587
  const motion = useRef29(null);
6627
6588
  if (!motion.current) motion.current = createNumberMotion(setDisplay);
6628
6589
  useLayoutEffect12(() => {
@@ -7109,7 +7070,7 @@ function KjunSparkline({
7109
7070
 
7110
7071
  // shared/package-runtime/table.ts
7111
7072
  import { nextTableSort } from "@kjun-ui/tokens";
7112
- import { useEffect as useEffect24, useRef as useRef31, useState as useState34 } from "react";
7073
+ import { useEffect as useEffect24, useRef as useRef31, useState as useState35 } from "react";
7113
7074
 
7114
7075
  // shared/package-runtime/table-model.ts
7115
7076
  function getValue(row, key) {
@@ -7153,10 +7114,10 @@ function useTableModel(props) {
7153
7114
  expandSingle = false,
7154
7115
  onExpandedRowsChange
7155
7116
  } = props;
7156
- const [internalSort, setSort] = useState34({
7117
+ const [internalSort, setSort] = useState35({
7157
7118
  key: "",
7158
7119
  order: "asc"
7159
- }), [internalExpanded, setExpanded] = useState34([]), [search, setSearch] = useState34(""), timer = useRef31(void 0);
7120
+ }), [internalExpanded, setExpanded] = useState35([]), [search, setSearch] = useState35(""), timer = useRef31(void 0);
7160
7121
  useEffect24(() => () => clearTimeout(timer.current), []);
7161
7122
  const sort = props.sort === void 0 ? internalSort : (_a = props.sort) != null ? _a : { key: "", order: "asc" };
7162
7123
  const rows = sortTableRows(data, sort, { sortable, sortMode });
@@ -7311,14 +7272,14 @@ function TableToolbar({
7311
7272
 
7312
7273
  // packages/native/src/table-grid.tsx
7313
7274
  import { tokens as tokens42 } from "@kjun-ui/tokens";
7314
- import { Fragment as Fragment14, useId as useId9, useState as useState35 } from "react";
7315
- import Svg7, { Defs as Defs3, LinearGradient as LinearGradient3, Rect as Rect4, Stop as Stop3 } from "react-native-svg";
7275
+ import { Fragment as Fragment14, useId as useId9, useState as useState36 } from "react";
7276
+ import Svg7, { Defs as Defs3, LinearGradient as LinearGradient3, Rect as Rect3, Stop as Stop3 } from "react-native-svg";
7316
7277
  import { ScrollView as ScrollView9, View as View36 } from "react-native";
7317
7278
  import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
7318
7279
  function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowClick, selectable, checkbox, cell, expandable, expand, renderExpand, emptyContent, emptyText, visible, maxHeight, stickyHeader, sortable, compact, striped, hoverable }) {
7319
7280
  const { colors } = useKjunStyles();
7320
7281
  const geometry2 = tokens42.table;
7321
- const [scroll, setScroll] = useState35({ viewport: 0, x: 0 }), fadeId = "kjun-table-fade-" + useId9().replace(/[^a-z0-9]/gi, "");
7282
+ const [scroll, setScroll] = useState36({ viewport: 0, x: 0 }), fadeId = "kjun-table-fade-" + useId9().replace(/[^a-z0-9]/gi, "");
7322
7283
  const cellPadding = geometry2.cellPadding[compact ? "compact" : "regular"];
7323
7284
  const width = (col) => typeof col.width === "number" ? col.width : typeof col.width === "string" && /^\d+(px)?$/.test(col.width) ? parseFloat(col.width) : geometry2.columnWidth;
7324
7285
  const totalWidth = visible.reduce((sum, col) => sum + width(col), 0) + (selectable ? geometry2.actionColumnWidth : 0) + (expandable ? geometry2.actionColumnWidth : 0);
@@ -7505,7 +7466,7 @@ function TableGrid({ initialLoading, skeletonRows, skeletonHidden, state, onRowC
7505
7466
  /* @__PURE__ */ jsx43(Stop3, { offset: "0", stopColor: colors.surface, stopOpacity: 0 }),
7506
7467
  /* @__PURE__ */ jsx43(Stop3, { offset: "1", stopColor: colors.surface, stopOpacity: 1 })
7507
7468
  ] }) }),
7508
- /* @__PURE__ */ jsx43(Rect4, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
7469
+ /* @__PURE__ */ jsx43(Rect3, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
7509
7470
  ] }) })
7510
7471
  ] });
7511
7472
  }
@@ -8068,7 +8029,7 @@ function KjunKpiHero(props) {
8068
8029
 
8069
8030
  // packages/native/src/kpi-row.tsx
8070
8031
  import { tokens as tokens46 } from "@kjun-ui/tokens";
8071
- import { useState as useState36 } from "react";
8032
+ import { useState as useState37 } from "react";
8072
8033
  import {
8073
8034
  Text as Text6,
8074
8035
  View as View41,
@@ -8087,7 +8048,7 @@ function KjunKpiRow({
8087
8048
  const { colors, domainColors, numericFontFamily, fontFamily } = useKjunStyles(), mobile = useWindowDimensions9().width <= tokens46.responsive.kpiRow, small = size === "sm", summary = mobileSummary && mobile && !small;
8088
8049
  const geometry2 = tokens46.extensions.kpiRow;
8089
8050
  const spec = small ? geometry2.sm : mobile ? geometry2.mobile : geometry2.md;
8090
- const [width, setWidth] = useState36(0);
8051
+ const [width, setWidth] = useState37(0);
8091
8052
  const paddingX = summary ? geometry2.summary.paddingX : spec.paddingX;
8092
8053
  const gapX = summary ? geometry2.summary.gapX : 0;
8093
8054
  const explicit = items.some(
@@ -8306,7 +8267,7 @@ import { tokens as tokens48 } from "@kjun-ui/tokens";
8306
8267
  import { ScrollView as ScrollView10, View as View43 } from "react-native";
8307
8268
 
8308
8269
  // shared/package-runtime/market-cards.ts
8309
- import { useEffect as useEffect25, useRef as useRef32, useState as useState37 } from "react";
8270
+ import { useEffect as useEffect25, useRef as useRef32, useState as useState38 } from "react";
8310
8271
  function useMarketCardsModel(props, persistence) {
8311
8272
  const {
8312
8273
  columns,
@@ -8322,7 +8283,7 @@ function useMarketCardsModel(props, persistence) {
8322
8283
  sortKey: c.sortable ? metricConfig[c.key].sortKey : null,
8323
8284
  isDefaultSort: c.defaultSort
8324
8285
  }));
8325
- const [key, setKey] = useState37(""), restoreSignature = JSON.stringify([storageNamespace, pills]);
8286
+ const [key, setKey] = useState38(""), restoreSignature = JSON.stringify([storageNamespace, pills]);
8326
8287
  const mounted = useRef32("");
8327
8288
  const save = (key2) => {
8328
8289
  var _a;
@@ -8811,9 +8772,9 @@ function KjunMarketListPanel({
8811
8772
 
8812
8773
  // packages/native/src/market-table.tsx
8813
8774
  import { tokens as tokens51 } from "@kjun-ui/tokens";
8814
- import { useId as useId10, useState as useState38 } from "react";
8775
+ import { useId as useId10, useState as useState39 } from "react";
8815
8776
  import { ScrollView as ScrollView11, View as View46 } from "react-native";
8816
- import Svg8, { Defs as Defs4, LinearGradient as LinearGradient4, Rect as Rect5, Stop as Stop4 } from "react-native-svg";
8777
+ import Svg8, { Defs as Defs4, LinearGradient as LinearGradient4, Rect as Rect4, Stop as Stop4 } from "react-native-svg";
8817
8778
  import { jsx as jsx53, jsxs as jsxs40 } from "react/jsx-runtime";
8818
8779
  function KjunMarketTable(props) {
8819
8780
  const {
@@ -8897,7 +8858,7 @@ function KjunMarketTable(props) {
8897
8858
  );
8898
8859
  };
8899
8860
  const layout = useMarketLayout(columns, showActions);
8900
- const [scroll, setScroll] = useState38({ viewport: 0, x: 0 }), fadeId = "kjun-market-fade-" + useId10().replace(/[^a-z0-9]/gi, "");
8861
+ const [scroll, setScroll] = useState39({ viewport: 0, x: 0 }), fadeId = "kjun-market-fade-" + useId10().replace(/[^a-z0-9]/gi, "");
8901
8862
  const tableQuote = { price: {}, change: { fontWeight: typeStyle("body").fontWeight } };
8902
8863
  return /* @__PURE__ */ jsxs40(
8903
8864
  View46,
@@ -9107,7 +9068,7 @@ function KjunMarketTable(props) {
9107
9068
  /* @__PURE__ */ jsx53(Stop4, { offset: "0", stopColor: colors.surface, stopOpacity: 0 }),
9108
9069
  /* @__PURE__ */ jsx53(Stop4, { offset: "1", stopColor: colors.surface, stopOpacity: 1 })
9109
9070
  ] }) }),
9110
- /* @__PURE__ */ jsx53(Rect5, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
9071
+ /* @__PURE__ */ jsx53(Rect4, { width: "100%", height: "100%", fill: `url(#${fadeId})` })
9111
9072
  ] }) })
9112
9073
  ] }) })
9113
9074
  }
@@ -9121,7 +9082,7 @@ function KjunMarketTable(props) {
9121
9082
  // packages/native/src/list.tsx
9122
9083
  import { tokens as tokens52 } from "@kjun-ui/tokens";
9123
9084
  import { Children as Children4, createContext as createContext20, useContext as useContext17 } from "react";
9124
- import { View as View47, Platform as Platform24 } from "react-native";
9085
+ import { View as View47, Platform as Platform25 } from "react-native";
9125
9086
  import { Fragment as Fragment18, jsx as jsx54, jsxs as jsxs41 } from "react/jsx-runtime";
9126
9087
  var LastListRow = createContext20(false);
9127
9088
  function KjunListRow({ title, description, leading, trailing, actions, href, disabled = false, onPress }) {
@@ -9136,8 +9097,8 @@ function KjunListRow({ title, description, leading, trailing, actions, href, dis
9136
9097
  ] });
9137
9098
  const style = { flex: 1, minWidth: 0, minHeight: tokens52.extensions.list.minimumHeight, flexDirection: "row", alignItems: "center", gap: tokens52.extensions.list.gap, padding: tokens52.extensions.list.padding };
9138
9099
  return /* @__PURE__ */ jsxs41(View47, { role: "listitem", style: { flexDirection: "row", alignItems: "center", gap: tokens52.extensions.list.gap, borderBottomWidth: last ? 0 : tokens52.border.defaultWidth, borderBottomColor: colors.divider }, children: [
9139
- 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 ? tokens52.states.opacity.disabled : 1, backgroundColor: pressed ? colors.hover : "transparent" }), children: parts }) : /* @__PURE__ */ jsx54(View47, { style, children: parts }),
9140
- actions && /* @__PURE__ */ jsx54(View47, { pointerEvents: disabled ? "none" : "auto", ...disabled && Platform24.OS === "web" ? { inert: true } : {}, style: { maxWidth: "45%", flexDirection: "row", flexWrap: "wrap", gap: tokens52.extensions.list.actionsGap, paddingRight: tokens52.extensions.list.actionsPadding, opacity: disabled ? tokens52.states.opacity.disabled : 1 }, children: content(actions) })
9100
+ 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 ? tokens52.states.opacity.disabled : 1, backgroundColor: pressed ? colors.hover : "transparent" }), children: parts }) : /* @__PURE__ */ jsx54(View47, { style, children: parts }),
9101
+ actions && /* @__PURE__ */ jsx54(View47, { pointerEvents: disabled ? "none" : "auto", ...disabled && Platform25.OS === "web" ? { inert: true } : {}, style: { maxWidth: "45%", flexDirection: "row", flexWrap: "wrap", gap: tokens52.extensions.list.actionsGap, paddingRight: tokens52.extensions.list.actionsPadding, opacity: disabled ? tokens52.states.opacity.disabled : 1 }, children: content(actions) })
9141
9102
  ] });
9142
9103
  }
9143
9104
  function KjunListSection({ title, description, actions, children, ariaLabel }) {
@@ -9156,16 +9117,16 @@ function KjunListSection({ title, description, actions, children, ariaLabel }) {
9156
9117
 
9157
9118
  // packages/native/src/app-navigation.tsx
9158
9119
  import { tokens as tokens53 } from "@kjun-ui/tokens";
9159
- import { Children as Children5, Fragment as Fragment19, isValidElement as isValidElement7, useState as useState39 } from "react";
9160
- import { View as View48, Platform as Platform25 } from "react-native";
9120
+ import { Children as Children5, Fragment as Fragment19, isValidElement as isValidElement7, useState as useState40 } from "react";
9121
+ import { View as View48, Platform as Platform26 } from "react-native";
9161
9122
  import { jsx as jsx55, jsxs as jsxs42 } from "react/jsx-runtime";
9162
9123
  function KjunTopNavigation({ title, description, leading, actions, safeAreaTop = 0 }) {
9163
9124
  const { colors } = useKjunStyles();
9164
9125
  const geometry2 = tokens53.extensions.topNavigation;
9165
9126
  const titleInset = Math.max(0, (geometry2.controlSize - tokens53.typography.sectionTitle.lineHeightPx) / 2);
9166
- const wrapping = Platform25.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9127
+ const wrapping = Platform26.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9167
9128
  const edgeInset = (geometry2.controlSize - geometry2.iconSize) / 2;
9168
- const [iconEdges, setIconEdges] = useState39({ leading: false, trailing: false });
9129
+ const [iconEdges, setIconEdges] = useState40({ leading: false, trailing: false });
9169
9130
  const square = (key) => (event) => {
9170
9131
  const { width, height } = event.nativeEvent.layout;
9171
9132
  const next = Math.abs(width - height) < 1 && Math.abs(height - geometry2.controlSize) < 1;
@@ -9210,8 +9171,8 @@ function KjunBottomNavigation({ items, value, ariaLabel = "\uC8FC\uC694 \uD0D0\u
9210
9171
  AccessiblePressable,
9211
9172
  {
9212
9173
  focusRingInset: true,
9213
- ...Platform25.OS === "web" ? { href: item.disabled ? void 0 : item.href, "aria-current": selected ? "page" : void 0 } : {},
9214
- accessibilityRole: Platform25.OS === "web" && item.href ? "link" : "button",
9174
+ ...Platform26.OS === "web" ? { href: item.disabled ? void 0 : item.href, "aria-current": selected ? "page" : void 0 } : {},
9175
+ accessibilityRole: Platform26.OS === "web" && item.href ? "link" : "button",
9215
9176
  accessibilityLabel: item.label + (item.badge != null ? ", " + item.badge : ""),
9216
9177
  accessibilityState: { selected, disabled: !!item.disabled },
9217
9178
  disabled: item.disabled,
@@ -9245,10 +9206,10 @@ function KjunBottomNavigation({ items, value, ariaLabel = "\uC8FC\uC694 \uD0D0\u
9245
9206
  }
9246
9207
  function KjunBottomActionBar({ description, children, safeAreaBottom = 0, keyboardVisible = false, hideOnKeyboard = false }) {
9247
9208
  const { colors } = useKjunStyles();
9248
- const [width, setWidth] = useState39(0);
9209
+ const [width, setWidth] = useState40(0);
9249
9210
  const geometry2 = tokens53.extensions.navigation;
9250
9211
  const wide = width >= tokens53.responsive.bottomAction + geometry2.padding * 2;
9251
- const wrapping = Platform25.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9212
+ const wrapping = Platform26.OS === "web" ? { wordBreak: "keep-all", overflowWrap: "anywhere" } : {};
9252
9213
  if (keyboardVisible && hideOnKeyboard) return null;
9253
9214
  return /* @__PURE__ */ jsx55(BottomActionBarContext.Provider, { value: !wide, children: /* @__PURE__ */ jsxs42(View48, { onLayout: (event) => setWidth(event.nativeEvent.layout.width), style: {
9254
9215
  flexShrink: 0,
@@ -9267,7 +9228,7 @@ function KjunBottomActionBar({ description, children, safeAreaBottom = 0, keyboa
9267
9228
  }
9268
9229
 
9269
9230
  // packages/native/src/media.tsx
9270
- import { useRef as useRef33, useState as useState40 } from "react";
9231
+ import { useRef as useRef33, useState as useState41 } from "react";
9271
9232
  import { Image, View as View49 } from "react-native";
9272
9233
  import { tokens as tokens54 } from "@kjun-ui/tokens";
9273
9234
  import { jsx as jsx56 } from "react/jsx-runtime";
@@ -9276,7 +9237,7 @@ function KjunImage({ src, source, alt, decorative = false, aspectRatio = 1, fit
9276
9237
  const request = JSON.stringify(source != null ? source : src), current = useRef33({ request, version: 0 });
9277
9238
  if (current.current.request !== request) current.current = { request, version: current.current.version + 1 };
9278
9239
  const version = current.current.version;
9279
- const [failed, setFailed] = useState40(null);
9240
+ const [failed, setFailed] = useState41(null);
9280
9241
  const missing = !source && !src;
9281
9242
  return /* @__PURE__ */ jsx56(View49, { 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: () => {
9282
9243
  if (version === current.current.version) onLoad == null ? void 0 : onLoad();
@@ -9306,8 +9267,8 @@ function KjunChip({ label, icon, removable = false, disabled = false, size = "md
9306
9267
  }
9307
9268
 
9308
9269
  // packages/native/src/range-input.tsx
9309
- import { useEffect as useEffect26, useMemo as useMemo2, useRef as useRef34, useState as useState41 } from "react";
9310
- import { PanResponder, Platform as Platform26, Pressable as Pressable3, View as View51 } from "react-native";
9270
+ import { useEffect as useEffect26, useMemo as useMemo2, useRef as useRef34, useState as useState42 } from "react";
9271
+ import { PanResponder, Platform as Platform27, Pressable as Pressable3, View as View51 } from "react-native";
9311
9272
  import { tokens as tokens56, createSliderDomain, sliderKey } from "@kjun-ui/tokens";
9312
9273
  import { jsx as jsx58, jsxs as jsxs44 } from "react/jsx-runtime";
9313
9274
  var geometry = tokens56.extensions.slider;
@@ -9330,9 +9291,9 @@ function RangeInput({
9330
9291
  const valid = domain.valid && (!Array.isArray(value) || value.length === 2) && values.every(domain.accepts) && (values.length === 1 || values[0] <= values[1]);
9331
9292
  const blocked = disabled || !valid;
9332
9293
  const effectiveMax = valid ? domain.snap(max) : min;
9333
- const [hovered, setHovered] = useState41(null);
9334
- const [dragging, setDragging] = useState41(null);
9335
- const [focused, setFocused] = useState41(null);
9294
+ const [hovered, setHovered] = useState42(null);
9295
+ const [dragging, setDragging] = useState42(null);
9296
+ const [focused, setFocused] = useState42(null);
9336
9297
  const track = useRef34(null), measured = useRef34({ x: 0, width: 1 }), selected = useRef34(0), dirty = useRef34(false);
9337
9298
  const latest = useRef34(values);
9338
9299
  latest.current = values;
@@ -9538,7 +9499,7 @@ function RangeInput({
9538
9499
  setFocused(null);
9539
9500
  commit();
9540
9501
  },
9541
- ...Platform26.OS === "web" ? {
9502
+ ...Platform27.OS === "web" ? {
9542
9503
  "aria-valuenow": number,
9543
9504
  "aria-valuemin": index === 1 ? values[0] : min,
9544
9505
  "aria-valuemax": values.length === 2 && index === 0 ? values[1] : domain.snap(max),
@@ -9562,7 +9523,7 @@ function RangeInput({
9562
9523
  alignItems: "center",
9563
9524
  justifyContent: "center",
9564
9525
  zIndex: focused === index || dragging === index ? 1 : 0,
9565
- ...Platform26.OS === "web" ? {
9526
+ ...Platform27.OS === "web" ? {
9566
9527
  outlineStyle: "solid",
9567
9528
  outlineWidth: 0,
9568
9529
  cursor: blocked ? "default" : dragging === index ? "grabbing" : "grab"
@@ -9579,7 +9540,7 @@ function RangeInput({
9579
9540
  borderWidth: tokens56.border.controlWidth,
9580
9541
  borderColor: !blocked && dragging === index ? colors.brandActive : !blocked && hovered === index ? colors.brandHover : colors.brand,
9581
9542
  backgroundColor: colors.surface,
9582
- ...Platform26.OS === "web" && !blocked && focused === index ? {
9543
+ ...Platform27.OS === "web" && !blocked && focused === index ? {
9583
9544
  outlineStyle: "solid",
9584
9545
  outlineWidth: tokens56.states.focus.width,
9585
9546
  outlineOffset: tokens56.states.focus.choiceOffset,
@@ -9606,8 +9567,8 @@ function KjunRangeSlider(props) {
9606
9567
  }
9607
9568
 
9608
9569
  // packages/native/src/quantity-stepper.tsx
9609
- import { useEffect as useEffect27, useRef as useRef35, useState as useState42 } from "react";
9610
- import { Platform as Platform27, View as View52 } from "react-native";
9570
+ import { useEffect as useEffect27, useRef as useRef35, useState as useState43 } from "react";
9571
+ import { Platform as Platform28, View as View52 } from "react-native";
9611
9572
  import { createNumberDomain, quantityKeyAction, tokens as tokens57 } from "@kjun-ui/tokens";
9612
9573
 
9613
9574
  // shared/package-runtime/component-icons.ts
@@ -9628,7 +9589,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9628
9589
  const increaseStyle = { ...buttonStyle, borderRadius: 0, borderTopRightRadius: outer, borderBottomRightRadius: outer };
9629
9590
  const domain = createNumberDomain({ min, max, step, precision }), valid = domain.valid && domain.accepts(value), blocked = disabled || !valid;
9630
9591
  const surface = useFieldSurface(size, { disabled: blocked, invalid });
9631
- const [draft, setDraft] = useState42(String(value));
9592
+ const [draft, setDraft] = useState43(String(value));
9632
9593
  const inputRef = useRef35(null);
9633
9594
  const composing = useRef35(false), dirty = useRef35(false), accepted = useRef35(value);
9634
9595
  const cancelledEscape = useRef35(false);
@@ -9683,7 +9644,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9683
9644
  setDraft(text);
9684
9645
  } };
9685
9646
  useEffect27(() => {
9686
- if (Platform27.OS !== "web") return;
9647
+ if (Platform28.OS !== "web") return;
9687
9648
  const input = inputRef.current;
9688
9649
  const keydown = (event) => handlers.current.key(event);
9689
9650
  const keyup = (event) => {
@@ -9712,7 +9673,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9712
9673
  };
9713
9674
  }, []);
9714
9675
  const surfaceBox = { position: "absolute", left: 0, right: 0, top: "50%", height: tokens57.input[size].height, marginTop: -tokens57.input[size].height / 2, borderRadius: surface.spec.radius };
9715
- const hug = Platform27.OS === "web" && !block ? { width: "fit-content" } : {};
9676
+ const hug = Platform28.OS === "web" && !block ? { width: "fit-content" } : {};
9716
9677
  return /* @__PURE__ */ jsx59(IconFallbacks, { icons: componentIcons, children: /* @__PURE__ */ jsxs45(View52, { style: { flexDirection: "row", alignItems: "center", alignSelf: block ? "stretch" : "flex-start", maxWidth: "100%", borderRadius: surface.spec.radius, ...hug }, children: [
9717
9678
  /* @__PURE__ */ jsx59(View52, { pointerEvents: "none", "aria-hidden": true, style: { ...surfaceBox, backgroundColor: colors.inputBg } }),
9718
9679
  /* @__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" }) }),
@@ -9743,8 +9704,8 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9743
9704
  surface.setFocused(false);
9744
9705
  commit();
9745
9706
  },
9746
- onSubmitEditing: Platform27.OS === "web" ? void 0 : commit,
9747
- ...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 },
9707
+ onSubmitEditing: Platform28.OS === "web" ? void 0 : commit,
9708
+ ...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 },
9748
9709
  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 - tokens57.border.controlWidth, paddingVertical: 0 }
9749
9710
  }
9750
9711
  ) }),
@@ -9754,7 +9715,7 @@ function KjunQuantityStepper({ value, min = 0, max, step = 1, precision = 0, dis
9754
9715
  }
9755
9716
 
9756
9717
  // packages/native/src/time-picker.tsx
9757
- import { Fragment as Fragment20, useEffect as useEffect28, useId as useId11, useMemo as useMemo3, useRef as useRef36, useState as useState43 } from "react";
9718
+ import { Fragment as Fragment20, useEffect as useEffect28, useId as useId11, useMemo as useMemo3, useRef as useRef36, useState as useState44 } from "react";
9758
9719
  import { View as View53 } from "react-native";
9759
9720
  import { createTimeDomain, tokens as tokens58 } from "@kjun-ui/tokens";
9760
9721
  import { jsx as jsx60, jsxs as jsxs46 } from "react/jsx-runtime";
@@ -9762,7 +9723,7 @@ function KjunTimePicker({ value, precision = "minute", min, max, minuteStep = 1,
9762
9723
  const geometry2 = tokens58.extensions.timePicker, spec = tokens58.input[size];
9763
9724
  const { colors } = useKjunStyles();
9764
9725
  const first = useRef36(null);
9765
- const [focused, setFocused] = useState43(false), [opened, setOpened] = useState43(null);
9726
+ const [focused, setFocused] = useState44(false), [opened, setOpened] = useState44(null);
9766
9727
  const field = useKjunField(), uid = useId11();
9767
9728
  const fieldId = (field == null ? void 0 : field.id) || `kjun-time-${uid}`;
9768
9729
  const domain = useMemo3(() => createTimeDomain({ precision, min, max, minuteStep, secondStep }), [precision, min, max, minuteStep, secondStep]), valid = domain.valid && domain.accepts(value);