@kjun-ui/native 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +68 -20
- package/dist/index.js +68 -20
- package/dist/index.web.cjs +68 -20
- package/dist/index.web.js +68 -20
- package/dist/styles.css +3 -1
- package/dist/types/packages/native/src/select-control.d.cts +5 -1
- package/dist/types/packages/native/src/select-control.d.ts +5 -1
- package/dist/types/packages/native/src/skeletons.d.cts +1 -1
- package/dist/types/packages/native/src/skeletons.d.ts +1 -1
- package/dist/types/shared/package-runtime/chart-skeleton.d.cts +5 -1
- package/dist/types/shared/package-runtime/chart-skeleton.d.ts +5 -1
- package/dist/types/shared/package-runtime/layer-state.d.cts +3 -0
- package/dist/types/shared/package-runtime/layer-state.d.ts +3 -0
- package/dist/types/shared/package-runtime/options.d.cts +5 -1
- package/dist/types/shared/package-runtime/options.d.ts +5 -1
- package/dist/types/shared/package-runtime/table-presentation.d.cts +4 -0
- package/dist/types/shared/package-runtime/table-presentation.d.ts +4 -0
- package/dist/types/shared/package-runtime/use-layer.d.cts +3 -1
- package/dist/types/shared/package-runtime/use-layer.d.ts +3 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -234,6 +234,10 @@ function installLayerKeyboard(document2, state, keyupFallback = false) {
|
|
|
234
234
|
var import_react2 = require("react");
|
|
235
235
|
|
|
236
236
|
// shared/package-runtime/layer-state.ts
|
|
237
|
+
function chooseReturnTarget(chosen, fallback2) {
|
|
238
|
+
if (chosen === false) return void 0;
|
|
239
|
+
return chosen && chosen.isConnected !== false ? chosen : fallback2;
|
|
240
|
+
}
|
|
237
241
|
function createLayerState() {
|
|
238
242
|
const entries = /* @__PURE__ */ new Map(), listeners = /* @__PURE__ */ new Set();
|
|
239
243
|
const restoredFocus = /* @__PURE__ */ new WeakSet();
|
|
@@ -254,6 +258,7 @@ function createLayerState() {
|
|
|
254
258
|
return !layer.blocked && (layer.kind === "window" ? ((_a = topWindow()) == null ? void 0 : _a.id) === layer.id : ((_b = topWindow()) == null ? void 0 : _b.id) === layer.owner);
|
|
255
259
|
};
|
|
256
260
|
const top = () => [...entries.values()].filter(active).sort((a, b) => a.order - b.order).at(-1);
|
|
261
|
+
const topPopup = () => [...entries.values()].filter((layer) => layer.kind !== "tooltip" && active(layer)).sort((a, b) => a.order - b.order).at(-1);
|
|
257
262
|
function dismiss(layer) {
|
|
258
263
|
if (layer.closeRequested) return;
|
|
259
264
|
layer.closeRequested = true;
|
|
@@ -273,6 +278,7 @@ function createLayerState() {
|
|
|
273
278
|
entries,
|
|
274
279
|
topWindow,
|
|
275
280
|
top,
|
|
281
|
+
topPopup,
|
|
276
282
|
windowOf,
|
|
277
283
|
isRestoredFocus(target) {
|
|
278
284
|
return !!target && restoredFocus.has(target);
|
|
@@ -421,21 +427,31 @@ function focusTrigger(target) {
|
|
|
421
427
|
}
|
|
422
428
|
return target;
|
|
423
429
|
}
|
|
424
|
-
function restoreFocus(target, state, id) {
|
|
430
|
+
function restoreFocus(target, state, id, fallback2) {
|
|
431
|
+
const usable = (item) => (item == null ? void 0 : item.isConnected) !== false && !(typeof HTMLElement !== "undefined" && item instanceof HTMLElement && item.closest("[inert]"));
|
|
425
432
|
const restore = () => {
|
|
426
|
-
var _a, _b, _c, _d;
|
|
433
|
+
var _a, _b, _c, _d, _e;
|
|
427
434
|
if (state.entries.has(id)) return;
|
|
428
|
-
if ((target
|
|
429
|
-
else (
|
|
435
|
+
if (usable(target)) (_a = target == null ? void 0 : target.focus) == null ? void 0 : _a.call(target, { preventScroll: true });
|
|
436
|
+
else if (fallback2 && fallback2 !== target && usable(fallback2)) (_b = fallback2.focus) == null ? void 0 : _b.call(fallback2, { preventScroll: true });
|
|
437
|
+
else (_e = (_d = (_c = state.topWindow()) == null ? void 0 : _c.root) == null ? void 0 : _d.focus) == null ? void 0 : _e.call(_d, { preventScroll: true });
|
|
430
438
|
};
|
|
431
439
|
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(restore);
|
|
432
440
|
else queueMicrotask(restore);
|
|
433
441
|
}
|
|
434
|
-
function useLayer(open, present, kind, close, trigger) {
|
|
442
|
+
function useLayer(open, present, kind, close, trigger, returnFocus) {
|
|
435
443
|
var _a;
|
|
436
444
|
const state = useLayerState(), parent = (0, import_react2.useContext)(LayerScope), id = (0, import_react2.useId)();
|
|
437
445
|
const callback = (0, import_react2.useRef)(close);
|
|
438
446
|
callback.current = close;
|
|
447
|
+
const returnRef = (0, import_react2.useRef)(returnFocus);
|
|
448
|
+
returnRef.current = returnFocus;
|
|
449
|
+
const fallbackFocus = (0, import_react2.useRef)(null);
|
|
450
|
+
const removeLayer = () => {
|
|
451
|
+
const removed = state.remove(id, currentFocus());
|
|
452
|
+
if (removed) fallbackFocus.current = removed;
|
|
453
|
+
return removed && returnRef.current ? chooseReturnTarget(returnRef.current(), removed) : removed;
|
|
454
|
+
};
|
|
439
455
|
const openingFocus = (0, import_react2.useRef)(null);
|
|
440
456
|
const wasOpen = (0, import_react2.useRef)(false);
|
|
441
457
|
const pendingFocus = (0, import_react2.useRef)(null);
|
|
@@ -447,17 +463,17 @@ function useLayer(open, present, kind, close, trigger) {
|
|
|
447
463
|
state.open(id, kind, parent, () => callback.current(), focusTrigger(trigger == null ? void 0 : trigger.current) || openingFocus.current);
|
|
448
464
|
} else if (kind === "window" && present) state.markClosing(id);
|
|
449
465
|
else if (kind !== "window" || !present) {
|
|
450
|
-
const target =
|
|
466
|
+
const target = removeLayer();
|
|
451
467
|
if (target) pendingFocus.current = target;
|
|
452
468
|
if (!present && pendingFocus.current) {
|
|
453
|
-
restoreFocus(pendingFocus.current, state, id);
|
|
469
|
+
restoreFocus(pendingFocus.current, state, id, fallbackFocus.current);
|
|
454
470
|
pendingFocus.current = null;
|
|
455
471
|
}
|
|
456
472
|
}
|
|
457
473
|
}, [open, present, state, id, kind, parent, trigger]);
|
|
458
474
|
(0, import_react2.useLayoutEffect)(() => () => {
|
|
459
|
-
const target =
|
|
460
|
-
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id);
|
|
475
|
+
const target = removeLayer();
|
|
476
|
+
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id, fallbackFocus.current);
|
|
461
477
|
}, [state, id]);
|
|
462
478
|
const entry = state.entries.get(id);
|
|
463
479
|
return {
|
|
@@ -3065,7 +3081,7 @@ function KjunRadioGroup({
|
|
|
3065
3081
|
accessibilityLabel: ariaLabel,
|
|
3066
3082
|
style: {
|
|
3067
3083
|
flexDirection: direction === "vertical" ? "column" : "row",
|
|
3068
|
-
flexWrap: "wrap",
|
|
3084
|
+
flexWrap: direction === "vertical" ? "nowrap" : "wrap",
|
|
3069
3085
|
gap: direction === "vertical" ? import_tokens18.tokens.dimension.value8 : import_tokens18.tokens.dimension.value16
|
|
3070
3086
|
},
|
|
3071
3087
|
children: children || options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -4254,6 +4270,17 @@ function nextOptionValue(value, option, key, multiple) {
|
|
|
4254
4270
|
if (!multiple) return id;
|
|
4255
4271
|
return Array.isArray(value) && value.includes(id) ? value.filter((item) => item !== id) : [...Array.isArray(value) ? value : [], id];
|
|
4256
4272
|
}
|
|
4273
|
+
function optionMatchRank(option, query, labelKey, searchKeys = []) {
|
|
4274
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
4275
|
+
if (!needle) return 0;
|
|
4276
|
+
const label = optionLabel(option, labelKey).toLocaleLowerCase();
|
|
4277
|
+
if (label.startsWith(needle)) return 0;
|
|
4278
|
+
if (label.includes(needle)) return 1;
|
|
4279
|
+
return typeof option === "object" && searchKeys.some((key) => {
|
|
4280
|
+
var _a;
|
|
4281
|
+
return String((_a = option[key]) != null ? _a : "").toLocaleLowerCase().includes(needle);
|
|
4282
|
+
}) ? 2 : -1;
|
|
4283
|
+
}
|
|
4257
4284
|
function selectOptions({
|
|
4258
4285
|
options,
|
|
4259
4286
|
value,
|
|
@@ -4263,10 +4290,13 @@ function selectOptions({
|
|
|
4263
4290
|
pageSize,
|
|
4264
4291
|
limit,
|
|
4265
4292
|
loading,
|
|
4266
|
-
multiple
|
|
4293
|
+
multiple,
|
|
4294
|
+
filterFn,
|
|
4295
|
+
searchKeys = []
|
|
4267
4296
|
}) {
|
|
4268
4297
|
const selected = (option) => optionSelected(value, option, valueKey);
|
|
4269
|
-
const
|
|
4298
|
+
const indexed = options.map((option, index) => ({ option, key: optionKey(option, valueKey, index) }));
|
|
4299
|
+
const matching = filterFn ? indexed.filter(({ option }) => filterFn(option, query)) : indexed.map((item, index) => ({ item, index, rank: optionMatchRank(item.option, query, labelKey, searchKeys) })).filter(({ rank }) => rank >= 0).sort((a, b) => a.rank - b.rank || a.index - b.index).map(({ item }) => item);
|
|
4270
4300
|
const visible = loading ? [] : pageSize > 0 ? matching.slice(0, limit) : matching;
|
|
4271
4301
|
const selectedOption = options.find(selected);
|
|
4272
4302
|
const label = multiple && Array.isArray(value) && value.length > 1 ? `${value.length}\uAC1C \uC120\uD0DD\uB428` : selectedOption !== void 0 ? optionLabel(selectedOption, labelKey) : "";
|
|
@@ -5001,7 +5031,9 @@ function KjunSelect({
|
|
|
5001
5031
|
onChange,
|
|
5002
5032
|
onOpenChange,
|
|
5003
5033
|
onSearch,
|
|
5004
|
-
onClear
|
|
5034
|
+
onClear,
|
|
5035
|
+
filterFn,
|
|
5036
|
+
searchKeys
|
|
5005
5037
|
}) {
|
|
5006
5038
|
const { open, query, limit, changeOpen, search, showMore } = useSelectState(controlled, disabled, optionPageSize, onOpenChange);
|
|
5007
5039
|
const { colors } = useKjunStyles(), field = useKjunField(), ref = (0, import_react44.useRef)(null), spec = import_tokens30.tokens.input[size];
|
|
@@ -5026,7 +5058,9 @@ function KjunSelect({
|
|
|
5026
5058
|
pageSize: optionPageSize,
|
|
5027
5059
|
limit,
|
|
5028
5060
|
loading,
|
|
5029
|
-
multiple
|
|
5061
|
+
multiple,
|
|
5062
|
+
filterFn,
|
|
5063
|
+
searchKeys
|
|
5030
5064
|
});
|
|
5031
5065
|
const firstSelected = visible.findIndex(({ option }) => selected(option));
|
|
5032
5066
|
if (firstSelected < 0) selectedRow.current = null;
|
|
@@ -5988,7 +6022,7 @@ function KjunRefreshButton({
|
|
|
5988
6022
|
...props
|
|
5989
6023
|
}) {
|
|
5990
6024
|
const reduced = useReducedMotion();
|
|
5991
|
-
const label = ariaLabel || [targetName, "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6025
|
+
const label = ariaLabel || [targetName, mode === "text" ? text : "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
5992
6026
|
const hint = tooltip != null ? tooltip : mode === "icon" ? label : "";
|
|
5993
6027
|
const button = /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(KjunTooltip, { content: props.disabled || props.loading ? "" : hint, placement: tooltipPlacement, delay: tooltipDelay, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
5994
6028
|
KjunButton,
|
|
@@ -6236,8 +6270,12 @@ function chartSkeletonCount(value) {
|
|
|
6236
6270
|
function chartMatrixMuted(row, column) {
|
|
6237
6271
|
return (row + column + 2) % 3 === 0;
|
|
6238
6272
|
}
|
|
6273
|
+
var chartDonutRatio = 0.8;
|
|
6239
6274
|
function chartDonutHole(height, thickness) {
|
|
6240
|
-
return Math.max(0, height *
|
|
6275
|
+
return Math.max(0, height * chartDonutRatio - 2 * thickness);
|
|
6276
|
+
}
|
|
6277
|
+
function chartSkeletonKind(kind) {
|
|
6278
|
+
return kind === "donut" || kind === "matrix" ? kind : "frame";
|
|
6241
6279
|
}
|
|
6242
6280
|
|
|
6243
6281
|
// packages/native/src/market-skeleton.tsx
|
|
@@ -6399,7 +6437,7 @@ function KjunFormSkeleton({
|
|
|
6399
6437
|
}
|
|
6400
6438
|
var chartPart = (name) => import_react_native42.Platform.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
|
|
6401
6439
|
function KjunChartSkeleton({
|
|
6402
|
-
kind = "frame",
|
|
6440
|
+
kind: requestedKind = "frame",
|
|
6403
6441
|
height = import_tokens39.tokens.extensions.chartSkeleton.height,
|
|
6404
6442
|
loadingText = "\uCC28\uD2B8\uB97C \uBD88\uB7EC\uC624\uB294 \uC911",
|
|
6405
6443
|
skeleton = true,
|
|
@@ -6407,7 +6445,7 @@ function KjunChartSkeleton({
|
|
|
6407
6445
|
rows = 8,
|
|
6408
6446
|
columns = 14
|
|
6409
6447
|
}) {
|
|
6410
|
-
const { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = (0, import_react53.useRef)(new import_react_native42.Animated.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = (0, import_react53.useState)(0), thickness = import_tokens39.tokens.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" };
|
|
6448
|
+
const kind = chartSkeletonKind(requestedKind), { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = (0, import_react53.useRef)(new import_react_native42.Animated.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = (0, import_react53.useState)(0), thickness = import_tokens39.tokens.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" };
|
|
6411
6449
|
(0, import_react53.useEffect)(() => {
|
|
6412
6450
|
if (reduced || !skeleton) return;
|
|
6413
6451
|
const loop = import_react_native42.Animated.loop(
|
|
@@ -6439,7 +6477,7 @@ function KjunChartSkeleton({
|
|
|
6439
6477
|
{
|
|
6440
6478
|
...chartPart("donut"),
|
|
6441
6479
|
...hidden,
|
|
6442
|
-
style: { height:
|
|
6480
|
+
style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: import_tokens39.tokens.radius.radius9999 }
|
|
6443
6481
|
}
|
|
6444
6482
|
) : kind === "matrix" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native42.View, { ...chartPart("matrix"), ...hidden, style: { alignSelf: "stretch", flex: 1, gap: import_tokens39.tokens.dimension.value4 }, children: Array.from({ length: rowCount }, (_, row) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native42.View, { style: { flex: 1, flexDirection: "row", gap: import_tokens39.tokens.dimension.value4 }, children: Array.from({ length: columnCount }, (_2, column) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6445
6483
|
import_react_native42.View,
|
|
@@ -6459,6 +6497,7 @@ function KjunChartSkeleton({
|
|
|
6459
6497
|
{
|
|
6460
6498
|
...chartPart("status"),
|
|
6461
6499
|
role: status,
|
|
6500
|
+
accessibilityLiveRegion: status ? "polite" : void 0,
|
|
6462
6501
|
pointerEvents: "none",
|
|
6463
6502
|
style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center" },
|
|
6464
6503
|
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
@@ -7147,9 +7186,18 @@ function tablePresentation(props, mobile) {
|
|
|
7147
7186
|
}
|
|
7148
7187
|
};
|
|
7149
7188
|
}
|
|
7189
|
+
var warnedFormats = /* @__PURE__ */ new Set();
|
|
7190
|
+
function columnFormat(column) {
|
|
7191
|
+
if (typeof column.format === "function") return column.format;
|
|
7192
|
+
if (column.format != null && !warnedFormats.has(column.key)) {
|
|
7193
|
+
warnedFormats.add(column.key);
|
|
7194
|
+
console.warn(`KJUN Table: ${column.key} \uC5F4\uC758 format\uC740 \uD568\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.`);
|
|
7195
|
+
}
|
|
7196
|
+
return void 0;
|
|
7197
|
+
}
|
|
7150
7198
|
function tableCellValue(props, column, row, index) {
|
|
7151
7199
|
const value = getValue(row, column.key);
|
|
7152
|
-
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : column
|
|
7200
|
+
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : columnFormat(column) ? columnFormat(column)(value, row) : props.formatValue ? props.formatValue(value, column, row) : value == null ? "-" : typeof value === "number" && column.type === "number" ? new Intl.NumberFormat().format(value) : String(value);
|
|
7153
7201
|
return { value, body };
|
|
7154
7202
|
}
|
|
7155
7203
|
|
package/dist/index.js
CHANGED
|
@@ -119,6 +119,10 @@ function installLayerKeyboard(document2, state, keyupFallback = false) {
|
|
|
119
119
|
import { createContext as createContext2, useContext as useContext2, useId, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
120
120
|
|
|
121
121
|
// shared/package-runtime/layer-state.ts
|
|
122
|
+
function chooseReturnTarget(chosen, fallback2) {
|
|
123
|
+
if (chosen === false) return void 0;
|
|
124
|
+
return chosen && chosen.isConnected !== false ? chosen : fallback2;
|
|
125
|
+
}
|
|
122
126
|
function createLayerState() {
|
|
123
127
|
const entries = /* @__PURE__ */ new Map(), listeners = /* @__PURE__ */ new Set();
|
|
124
128
|
const restoredFocus = /* @__PURE__ */ new WeakSet();
|
|
@@ -139,6 +143,7 @@ function createLayerState() {
|
|
|
139
143
|
return !layer.blocked && (layer.kind === "window" ? ((_a = topWindow()) == null ? void 0 : _a.id) === layer.id : ((_b = topWindow()) == null ? void 0 : _b.id) === layer.owner);
|
|
140
144
|
};
|
|
141
145
|
const top = () => [...entries.values()].filter(active).sort((a, b) => a.order - b.order).at(-1);
|
|
146
|
+
const topPopup = () => [...entries.values()].filter((layer) => layer.kind !== "tooltip" && active(layer)).sort((a, b) => a.order - b.order).at(-1);
|
|
142
147
|
function dismiss(layer) {
|
|
143
148
|
if (layer.closeRequested) return;
|
|
144
149
|
layer.closeRequested = true;
|
|
@@ -158,6 +163,7 @@ function createLayerState() {
|
|
|
158
163
|
entries,
|
|
159
164
|
topWindow,
|
|
160
165
|
top,
|
|
166
|
+
topPopup,
|
|
161
167
|
windowOf,
|
|
162
168
|
isRestoredFocus(target) {
|
|
163
169
|
return !!target && restoredFocus.has(target);
|
|
@@ -306,21 +312,31 @@ function focusTrigger(target) {
|
|
|
306
312
|
}
|
|
307
313
|
return target;
|
|
308
314
|
}
|
|
309
|
-
function restoreFocus(target, state, id) {
|
|
315
|
+
function restoreFocus(target, state, id, fallback2) {
|
|
316
|
+
const usable = (item) => (item == null ? void 0 : item.isConnected) !== false && !(typeof HTMLElement !== "undefined" && item instanceof HTMLElement && item.closest("[inert]"));
|
|
310
317
|
const restore = () => {
|
|
311
|
-
var _a, _b, _c, _d;
|
|
318
|
+
var _a, _b, _c, _d, _e;
|
|
312
319
|
if (state.entries.has(id)) return;
|
|
313
|
-
if ((target
|
|
314
|
-
else (
|
|
320
|
+
if (usable(target)) (_a = target == null ? void 0 : target.focus) == null ? void 0 : _a.call(target, { preventScroll: true });
|
|
321
|
+
else if (fallback2 && fallback2 !== target && usable(fallback2)) (_b = fallback2.focus) == null ? void 0 : _b.call(fallback2, { preventScroll: true });
|
|
322
|
+
else (_e = (_d = (_c = state.topWindow()) == null ? void 0 : _c.root) == null ? void 0 : _d.focus) == null ? void 0 : _e.call(_d, { preventScroll: true });
|
|
315
323
|
};
|
|
316
324
|
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(restore);
|
|
317
325
|
else queueMicrotask(restore);
|
|
318
326
|
}
|
|
319
|
-
function useLayer(open, present, kind, close, trigger) {
|
|
327
|
+
function useLayer(open, present, kind, close, trigger, returnFocus) {
|
|
320
328
|
var _a;
|
|
321
329
|
const state = useLayerState(), parent = useContext2(LayerScope), id = useId();
|
|
322
330
|
const callback = useRef(close);
|
|
323
331
|
callback.current = close;
|
|
332
|
+
const returnRef = useRef(returnFocus);
|
|
333
|
+
returnRef.current = returnFocus;
|
|
334
|
+
const fallbackFocus = useRef(null);
|
|
335
|
+
const removeLayer = () => {
|
|
336
|
+
const removed = state.remove(id, currentFocus());
|
|
337
|
+
if (removed) fallbackFocus.current = removed;
|
|
338
|
+
return removed && returnRef.current ? chooseReturnTarget(returnRef.current(), removed) : removed;
|
|
339
|
+
};
|
|
324
340
|
const openingFocus = useRef(null);
|
|
325
341
|
const wasOpen = useRef(false);
|
|
326
342
|
const pendingFocus = useRef(null);
|
|
@@ -332,17 +348,17 @@ function useLayer(open, present, kind, close, trigger) {
|
|
|
332
348
|
state.open(id, kind, parent, () => callback.current(), focusTrigger(trigger == null ? void 0 : trigger.current) || openingFocus.current);
|
|
333
349
|
} else if (kind === "window" && present) state.markClosing(id);
|
|
334
350
|
else if (kind !== "window" || !present) {
|
|
335
|
-
const target =
|
|
351
|
+
const target = removeLayer();
|
|
336
352
|
if (target) pendingFocus.current = target;
|
|
337
353
|
if (!present && pendingFocus.current) {
|
|
338
|
-
restoreFocus(pendingFocus.current, state, id);
|
|
354
|
+
restoreFocus(pendingFocus.current, state, id, fallbackFocus.current);
|
|
339
355
|
pendingFocus.current = null;
|
|
340
356
|
}
|
|
341
357
|
}
|
|
342
358
|
}, [open, present, state, id, kind, parent, trigger]);
|
|
343
359
|
useLayoutEffect(() => () => {
|
|
344
|
-
const target =
|
|
345
|
-
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id);
|
|
360
|
+
const target = removeLayer();
|
|
361
|
+
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id, fallbackFocus.current);
|
|
346
362
|
}, [state, id]);
|
|
347
363
|
const entry = state.entries.get(id);
|
|
348
364
|
return {
|
|
@@ -3031,7 +3047,7 @@ function KjunRadioGroup({
|
|
|
3031
3047
|
accessibilityLabel: ariaLabel,
|
|
3032
3048
|
style: {
|
|
3033
3049
|
flexDirection: direction === "vertical" ? "column" : "row",
|
|
3034
|
-
flexWrap: "wrap",
|
|
3050
|
+
flexWrap: direction === "vertical" ? "nowrap" : "wrap",
|
|
3035
3051
|
gap: direction === "vertical" ? tokens16.dimension.value8 : tokens16.dimension.value16
|
|
3036
3052
|
},
|
|
3037
3053
|
children: children || options.map((option) => /* @__PURE__ */ jsx19(
|
|
@@ -4269,6 +4285,17 @@ function nextOptionValue(value, option, key, multiple) {
|
|
|
4269
4285
|
if (!multiple) return id;
|
|
4270
4286
|
return Array.isArray(value) && value.includes(id) ? value.filter((item) => item !== id) : [...Array.isArray(value) ? value : [], id];
|
|
4271
4287
|
}
|
|
4288
|
+
function optionMatchRank(option, query, labelKey, searchKeys = []) {
|
|
4289
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
4290
|
+
if (!needle) return 0;
|
|
4291
|
+
const label = optionLabel(option, labelKey).toLocaleLowerCase();
|
|
4292
|
+
if (label.startsWith(needle)) return 0;
|
|
4293
|
+
if (label.includes(needle)) return 1;
|
|
4294
|
+
return typeof option === "object" && searchKeys.some((key) => {
|
|
4295
|
+
var _a;
|
|
4296
|
+
return String((_a = option[key]) != null ? _a : "").toLocaleLowerCase().includes(needle);
|
|
4297
|
+
}) ? 2 : -1;
|
|
4298
|
+
}
|
|
4272
4299
|
function selectOptions({
|
|
4273
4300
|
options,
|
|
4274
4301
|
value,
|
|
@@ -4278,10 +4305,13 @@ function selectOptions({
|
|
|
4278
4305
|
pageSize,
|
|
4279
4306
|
limit,
|
|
4280
4307
|
loading,
|
|
4281
|
-
multiple
|
|
4308
|
+
multiple,
|
|
4309
|
+
filterFn,
|
|
4310
|
+
searchKeys = []
|
|
4282
4311
|
}) {
|
|
4283
4312
|
const selected = (option) => optionSelected(value, option, valueKey);
|
|
4284
|
-
const
|
|
4313
|
+
const indexed = options.map((option, index) => ({ option, key: optionKey(option, valueKey, index) }));
|
|
4314
|
+
const matching = filterFn ? indexed.filter(({ option }) => filterFn(option, query)) : indexed.map((item, index) => ({ item, index, rank: optionMatchRank(item.option, query, labelKey, searchKeys) })).filter(({ rank }) => rank >= 0).sort((a, b) => a.rank - b.rank || a.index - b.index).map(({ item }) => item);
|
|
4285
4315
|
const visible = loading ? [] : pageSize > 0 ? matching.slice(0, limit) : matching;
|
|
4286
4316
|
const selectedOption = options.find(selected);
|
|
4287
4317
|
const label = multiple && Array.isArray(value) && value.length > 1 ? `${value.length}\uAC1C \uC120\uD0DD\uB428` : selectedOption !== void 0 ? optionLabel(selectedOption, labelKey) : "";
|
|
@@ -5016,7 +5046,9 @@ function KjunSelect({
|
|
|
5016
5046
|
onChange,
|
|
5017
5047
|
onOpenChange,
|
|
5018
5048
|
onSearch,
|
|
5019
|
-
onClear
|
|
5049
|
+
onClear,
|
|
5050
|
+
filterFn,
|
|
5051
|
+
searchKeys
|
|
5020
5052
|
}) {
|
|
5021
5053
|
const { open, query, limit, changeOpen, search, showMore } = useSelectState(controlled, disabled, optionPageSize, onOpenChange);
|
|
5022
5054
|
const { colors } = useKjunStyles(), field = useKjunField(), ref = useRef23(null), spec = tokens28.input[size];
|
|
@@ -5041,7 +5073,9 @@ function KjunSelect({
|
|
|
5041
5073
|
pageSize: optionPageSize,
|
|
5042
5074
|
limit,
|
|
5043
5075
|
loading,
|
|
5044
|
-
multiple
|
|
5076
|
+
multiple,
|
|
5077
|
+
filterFn,
|
|
5078
|
+
searchKeys
|
|
5045
5079
|
});
|
|
5046
5080
|
const firstSelected = visible.findIndex(({ option }) => selected(option));
|
|
5047
5081
|
if (firstSelected < 0) selectedRow.current = null;
|
|
@@ -6010,7 +6044,7 @@ function KjunRefreshButton({
|
|
|
6010
6044
|
...props
|
|
6011
6045
|
}) {
|
|
6012
6046
|
const reduced = useReducedMotion();
|
|
6013
|
-
const label = ariaLabel || [targetName, "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6047
|
+
const label = ariaLabel || [targetName, mode === "text" ? text : "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6014
6048
|
const hint = tooltip != null ? tooltip : mode === "icon" ? label : "";
|
|
6015
6049
|
const button = /* @__PURE__ */ jsx36(KjunTooltip, { content: props.disabled || props.loading ? "" : hint, placement: tooltipPlacement, delay: tooltipDelay, children: /* @__PURE__ */ jsx36(
|
|
6016
6050
|
KjunButton,
|
|
@@ -6263,8 +6297,12 @@ function chartSkeletonCount(value) {
|
|
|
6263
6297
|
function chartMatrixMuted(row, column) {
|
|
6264
6298
|
return (row + column + 2) % 3 === 0;
|
|
6265
6299
|
}
|
|
6300
|
+
var chartDonutRatio = 0.8;
|
|
6266
6301
|
function chartDonutHole(height, thickness) {
|
|
6267
|
-
return Math.max(0, height *
|
|
6302
|
+
return Math.max(0, height * chartDonutRatio - 2 * thickness);
|
|
6303
|
+
}
|
|
6304
|
+
function chartSkeletonKind(kind) {
|
|
6305
|
+
return kind === "donut" || kind === "matrix" ? kind : "frame";
|
|
6268
6306
|
}
|
|
6269
6307
|
|
|
6270
6308
|
// packages/native/src/market-skeleton.tsx
|
|
@@ -6426,7 +6464,7 @@ function KjunFormSkeleton({
|
|
|
6426
6464
|
}
|
|
6427
6465
|
var chartPart = (name) => Platform24.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
|
|
6428
6466
|
function KjunChartSkeleton({
|
|
6429
|
-
kind = "frame",
|
|
6467
|
+
kind: requestedKind = "frame",
|
|
6430
6468
|
height = tokens37.extensions.chartSkeleton.height,
|
|
6431
6469
|
loadingText = "\uCC28\uD2B8\uB97C \uBD88\uB7EC\uC624\uB294 \uC911",
|
|
6432
6470
|
skeleton = true,
|
|
@@ -6434,7 +6472,7 @@ function KjunChartSkeleton({
|
|
|
6434
6472
|
rows = 8,
|
|
6435
6473
|
columns = 14
|
|
6436
6474
|
}) {
|
|
6437
|
-
const { 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" };
|
|
6475
|
+
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" };
|
|
6438
6476
|
useEffect22(() => {
|
|
6439
6477
|
if (reduced || !skeleton) return;
|
|
6440
6478
|
const loop = Animated17.loop(
|
|
@@ -6466,7 +6504,7 @@ function KjunChartSkeleton({
|
|
|
6466
6504
|
{
|
|
6467
6505
|
...chartPart("donut"),
|
|
6468
6506
|
...hidden,
|
|
6469
|
-
style: { height:
|
|
6507
|
+
style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: tokens37.radius.radius9999 }
|
|
6470
6508
|
}
|
|
6471
6509
|
) : 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(
|
|
6472
6510
|
View32,
|
|
@@ -6486,6 +6524,7 @@ function KjunChartSkeleton({
|
|
|
6486
6524
|
{
|
|
6487
6525
|
...chartPart("status"),
|
|
6488
6526
|
role: status,
|
|
6527
|
+
accessibilityLiveRegion: status ? "polite" : void 0,
|
|
6489
6528
|
pointerEvents: "none",
|
|
6490
6529
|
style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center" },
|
|
6491
6530
|
children: /* @__PURE__ */ jsx39(
|
|
@@ -7186,9 +7225,18 @@ function tablePresentation(props, mobile) {
|
|
|
7186
7225
|
}
|
|
7187
7226
|
};
|
|
7188
7227
|
}
|
|
7228
|
+
var warnedFormats = /* @__PURE__ */ new Set();
|
|
7229
|
+
function columnFormat(column) {
|
|
7230
|
+
if (typeof column.format === "function") return column.format;
|
|
7231
|
+
if (column.format != null && !warnedFormats.has(column.key)) {
|
|
7232
|
+
warnedFormats.add(column.key);
|
|
7233
|
+
console.warn(`KJUN Table: ${column.key} \uC5F4\uC758 format\uC740 \uD568\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.`);
|
|
7234
|
+
}
|
|
7235
|
+
return void 0;
|
|
7236
|
+
}
|
|
7189
7237
|
function tableCellValue(props, column, row, index) {
|
|
7190
7238
|
const value = getValue(row, column.key);
|
|
7191
|
-
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : column
|
|
7239
|
+
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : columnFormat(column) ? columnFormat(column)(value, row) : props.formatValue ? props.formatValue(value, column, row) : value == null ? "-" : typeof value === "number" && column.type === "number" ? new Intl.NumberFormat().format(value) : String(value);
|
|
7192
7240
|
return { value, body };
|
|
7193
7241
|
}
|
|
7194
7242
|
|
package/dist/index.web.cjs
CHANGED
|
@@ -234,6 +234,10 @@ function installLayerKeyboard(document2, state, keyupFallback = false) {
|
|
|
234
234
|
var import_react2 = require("react");
|
|
235
235
|
|
|
236
236
|
// shared/package-runtime/layer-state.ts
|
|
237
|
+
function chooseReturnTarget(chosen, fallback2) {
|
|
238
|
+
if (chosen === false) return void 0;
|
|
239
|
+
return chosen && chosen.isConnected !== false ? chosen : fallback2;
|
|
240
|
+
}
|
|
237
241
|
function createLayerState() {
|
|
238
242
|
const entries = /* @__PURE__ */ new Map(), listeners = /* @__PURE__ */ new Set();
|
|
239
243
|
const restoredFocus = /* @__PURE__ */ new WeakSet();
|
|
@@ -254,6 +258,7 @@ function createLayerState() {
|
|
|
254
258
|
return !layer.blocked && (layer.kind === "window" ? ((_a = topWindow()) == null ? void 0 : _a.id) === layer.id : ((_b = topWindow()) == null ? void 0 : _b.id) === layer.owner);
|
|
255
259
|
};
|
|
256
260
|
const top = () => [...entries.values()].filter(active).sort((a, b) => a.order - b.order).at(-1);
|
|
261
|
+
const topPopup = () => [...entries.values()].filter((layer) => layer.kind !== "tooltip" && active(layer)).sort((a, b) => a.order - b.order).at(-1);
|
|
257
262
|
function dismiss(layer) {
|
|
258
263
|
if (layer.closeRequested) return;
|
|
259
264
|
layer.closeRequested = true;
|
|
@@ -273,6 +278,7 @@ function createLayerState() {
|
|
|
273
278
|
entries,
|
|
274
279
|
topWindow,
|
|
275
280
|
top,
|
|
281
|
+
topPopup,
|
|
276
282
|
windowOf,
|
|
277
283
|
isRestoredFocus(target) {
|
|
278
284
|
return !!target && restoredFocus.has(target);
|
|
@@ -421,21 +427,31 @@ function focusTrigger(target) {
|
|
|
421
427
|
}
|
|
422
428
|
return target;
|
|
423
429
|
}
|
|
424
|
-
function restoreFocus(target, state, id) {
|
|
430
|
+
function restoreFocus(target, state, id, fallback2) {
|
|
431
|
+
const usable = (item) => (item == null ? void 0 : item.isConnected) !== false && !(typeof HTMLElement !== "undefined" && item instanceof HTMLElement && item.closest("[inert]"));
|
|
425
432
|
const restore = () => {
|
|
426
|
-
var _a, _b, _c, _d;
|
|
433
|
+
var _a, _b, _c, _d, _e;
|
|
427
434
|
if (state.entries.has(id)) return;
|
|
428
|
-
if ((target
|
|
429
|
-
else (
|
|
435
|
+
if (usable(target)) (_a = target == null ? void 0 : target.focus) == null ? void 0 : _a.call(target, { preventScroll: true });
|
|
436
|
+
else if (fallback2 && fallback2 !== target && usable(fallback2)) (_b = fallback2.focus) == null ? void 0 : _b.call(fallback2, { preventScroll: true });
|
|
437
|
+
else (_e = (_d = (_c = state.topWindow()) == null ? void 0 : _c.root) == null ? void 0 : _d.focus) == null ? void 0 : _e.call(_d, { preventScroll: true });
|
|
430
438
|
};
|
|
431
439
|
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(restore);
|
|
432
440
|
else queueMicrotask(restore);
|
|
433
441
|
}
|
|
434
|
-
function useLayer(open, present, kind, close, trigger) {
|
|
442
|
+
function useLayer(open, present, kind, close, trigger, returnFocus) {
|
|
435
443
|
var _a;
|
|
436
444
|
const state = useLayerState(), parent = (0, import_react2.useContext)(LayerScope), id = (0, import_react2.useId)();
|
|
437
445
|
const callback = (0, import_react2.useRef)(close);
|
|
438
446
|
callback.current = close;
|
|
447
|
+
const returnRef = (0, import_react2.useRef)(returnFocus);
|
|
448
|
+
returnRef.current = returnFocus;
|
|
449
|
+
const fallbackFocus = (0, import_react2.useRef)(null);
|
|
450
|
+
const removeLayer = () => {
|
|
451
|
+
const removed = state.remove(id, currentFocus());
|
|
452
|
+
if (removed) fallbackFocus.current = removed;
|
|
453
|
+
return removed && returnRef.current ? chooseReturnTarget(returnRef.current(), removed) : removed;
|
|
454
|
+
};
|
|
439
455
|
const openingFocus = (0, import_react2.useRef)(null);
|
|
440
456
|
const wasOpen = (0, import_react2.useRef)(false);
|
|
441
457
|
const pendingFocus = (0, import_react2.useRef)(null);
|
|
@@ -447,17 +463,17 @@ function useLayer(open, present, kind, close, trigger) {
|
|
|
447
463
|
state.open(id, kind, parent, () => callback.current(), focusTrigger(trigger == null ? void 0 : trigger.current) || openingFocus.current);
|
|
448
464
|
} else if (kind === "window" && present) state.markClosing(id);
|
|
449
465
|
else if (kind !== "window" || !present) {
|
|
450
|
-
const target =
|
|
466
|
+
const target = removeLayer();
|
|
451
467
|
if (target) pendingFocus.current = target;
|
|
452
468
|
if (!present && pendingFocus.current) {
|
|
453
|
-
restoreFocus(pendingFocus.current, state, id);
|
|
469
|
+
restoreFocus(pendingFocus.current, state, id, fallbackFocus.current);
|
|
454
470
|
pendingFocus.current = null;
|
|
455
471
|
}
|
|
456
472
|
}
|
|
457
473
|
}, [open, present, state, id, kind, parent, trigger]);
|
|
458
474
|
(0, import_react2.useLayoutEffect)(() => () => {
|
|
459
|
-
const target =
|
|
460
|
-
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id);
|
|
475
|
+
const target = removeLayer();
|
|
476
|
+
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id, fallbackFocus.current);
|
|
461
477
|
}, [state, id]);
|
|
462
478
|
const entry = state.entries.get(id);
|
|
463
479
|
return {
|
|
@@ -3227,7 +3243,7 @@ function KjunRadioGroup({
|
|
|
3227
3243
|
accessibilityLabel: ariaLabel,
|
|
3228
3244
|
style: {
|
|
3229
3245
|
flexDirection: direction === "vertical" ? "column" : "row",
|
|
3230
|
-
flexWrap: "wrap",
|
|
3246
|
+
flexWrap: direction === "vertical" ? "nowrap" : "wrap",
|
|
3231
3247
|
gap: direction === "vertical" ? import_tokens19.tokens.dimension.value8 : import_tokens19.tokens.dimension.value16
|
|
3232
3248
|
},
|
|
3233
3249
|
children: children || options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -4416,6 +4432,17 @@ function nextOptionValue(value, option, key, multiple) {
|
|
|
4416
4432
|
if (!multiple) return id;
|
|
4417
4433
|
return Array.isArray(value) && value.includes(id) ? value.filter((item) => item !== id) : [...Array.isArray(value) ? value : [], id];
|
|
4418
4434
|
}
|
|
4435
|
+
function optionMatchRank(option, query, labelKey, searchKeys = []) {
|
|
4436
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
4437
|
+
if (!needle) return 0;
|
|
4438
|
+
const label = optionLabel(option, labelKey).toLocaleLowerCase();
|
|
4439
|
+
if (label.startsWith(needle)) return 0;
|
|
4440
|
+
if (label.includes(needle)) return 1;
|
|
4441
|
+
return typeof option === "object" && searchKeys.some((key) => {
|
|
4442
|
+
var _a;
|
|
4443
|
+
return String((_a = option[key]) != null ? _a : "").toLocaleLowerCase().includes(needle);
|
|
4444
|
+
}) ? 2 : -1;
|
|
4445
|
+
}
|
|
4419
4446
|
function selectOptions({
|
|
4420
4447
|
options,
|
|
4421
4448
|
value,
|
|
@@ -4425,10 +4452,13 @@ function selectOptions({
|
|
|
4425
4452
|
pageSize,
|
|
4426
4453
|
limit,
|
|
4427
4454
|
loading,
|
|
4428
|
-
multiple
|
|
4455
|
+
multiple,
|
|
4456
|
+
filterFn,
|
|
4457
|
+
searchKeys = []
|
|
4429
4458
|
}) {
|
|
4430
4459
|
const selected = (option) => optionSelected(value, option, valueKey);
|
|
4431
|
-
const
|
|
4460
|
+
const indexed = options.map((option, index) => ({ option, key: optionKey(option, valueKey, index) }));
|
|
4461
|
+
const matching = filterFn ? indexed.filter(({ option }) => filterFn(option, query)) : indexed.map((item, index) => ({ item, index, rank: optionMatchRank(item.option, query, labelKey, searchKeys) })).filter(({ rank }) => rank >= 0).sort((a, b) => a.rank - b.rank || a.index - b.index).map(({ item }) => item);
|
|
4432
4462
|
const visible = loading ? [] : pageSize > 0 ? matching.slice(0, limit) : matching;
|
|
4433
4463
|
const selectedOption = options.find(selected);
|
|
4434
4464
|
const label = multiple && Array.isArray(value) && value.length > 1 ? `${value.length}\uAC1C \uC120\uD0DD\uB428` : selectedOption !== void 0 ? optionLabel(selectedOption, labelKey) : "";
|
|
@@ -5163,7 +5193,9 @@ function KjunSelect({
|
|
|
5163
5193
|
onChange,
|
|
5164
5194
|
onOpenChange,
|
|
5165
5195
|
onSearch,
|
|
5166
|
-
onClear
|
|
5196
|
+
onClear,
|
|
5197
|
+
filterFn,
|
|
5198
|
+
searchKeys
|
|
5167
5199
|
}) {
|
|
5168
5200
|
const { open, query, limit, changeOpen, search, showMore } = useSelectState(controlled, disabled, optionPageSize, onOpenChange);
|
|
5169
5201
|
const { colors } = useKjunStyles(), field = useKjunField(), ref = (0, import_react47.useRef)(null), spec = import_tokens31.tokens.input[size];
|
|
@@ -5188,7 +5220,9 @@ function KjunSelect({
|
|
|
5188
5220
|
pageSize: optionPageSize,
|
|
5189
5221
|
limit,
|
|
5190
5222
|
loading,
|
|
5191
|
-
multiple
|
|
5223
|
+
multiple,
|
|
5224
|
+
filterFn,
|
|
5225
|
+
searchKeys
|
|
5192
5226
|
});
|
|
5193
5227
|
const firstSelected = visible.findIndex(({ option }) => selected(option));
|
|
5194
5228
|
if (firstSelected < 0) selectedRow.current = null;
|
|
@@ -6243,7 +6277,7 @@ function KjunRefreshButton({
|
|
|
6243
6277
|
...props
|
|
6244
6278
|
}) {
|
|
6245
6279
|
const reduced = useReducedMotion();
|
|
6246
|
-
const label = ariaLabel || [targetName, "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6280
|
+
const label = ariaLabel || [targetName, mode === "text" ? text : "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6247
6281
|
const hint = tooltip != null ? tooltip : mode === "icon" ? label : "";
|
|
6248
6282
|
const button = /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(KjunTooltip, { content: props.disabled || props.loading ? "" : hint, placement: tooltipPlacement, delay: tooltipDelay, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6249
6283
|
KjunButton,
|
|
@@ -6491,8 +6525,12 @@ function chartSkeletonCount(value) {
|
|
|
6491
6525
|
function chartMatrixMuted(row, column) {
|
|
6492
6526
|
return (row + column + 2) % 3 === 0;
|
|
6493
6527
|
}
|
|
6528
|
+
var chartDonutRatio = 0.8;
|
|
6494
6529
|
function chartDonutHole(height, thickness) {
|
|
6495
|
-
return Math.max(0, height *
|
|
6530
|
+
return Math.max(0, height * chartDonutRatio - 2 * thickness);
|
|
6531
|
+
}
|
|
6532
|
+
function chartSkeletonKind(kind) {
|
|
6533
|
+
return kind === "donut" || kind === "matrix" ? kind : "frame";
|
|
6496
6534
|
}
|
|
6497
6535
|
|
|
6498
6536
|
// packages/native/src/market-skeleton.tsx
|
|
@@ -6654,7 +6692,7 @@ function KjunFormSkeleton({
|
|
|
6654
6692
|
}
|
|
6655
6693
|
var chartPart = (name) => import_react_native42.Platform.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
|
|
6656
6694
|
function KjunChartSkeleton({
|
|
6657
|
-
kind = "frame",
|
|
6695
|
+
kind: requestedKind = "frame",
|
|
6658
6696
|
height = import_tokens40.tokens.extensions.chartSkeleton.height,
|
|
6659
6697
|
loadingText = "\uCC28\uD2B8\uB97C \uBD88\uB7EC\uC624\uB294 \uC911",
|
|
6660
6698
|
skeleton = true,
|
|
@@ -6662,7 +6700,7 @@ function KjunChartSkeleton({
|
|
|
6662
6700
|
rows = 8,
|
|
6663
6701
|
columns = 14
|
|
6664
6702
|
}) {
|
|
6665
|
-
const { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = (0, import_react57.useRef)(new import_react_native42.Animated.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = (0, import_react57.useState)(0), thickness = import_tokens40.tokens.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" };
|
|
6703
|
+
const kind = chartSkeletonKind(requestedKind), { colors } = useKjunStyles(), reduced = useReducedMotion(), opacity = (0, import_react57.useRef)(new import_react_native42.Animated.Value(1)).current, revealed = useLoadingReveal(true, loadingDelay), [measured, setMeasured] = (0, import_react57.useState)(0), thickness = import_tokens40.tokens.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" };
|
|
6666
6704
|
(0, import_react57.useEffect)(() => {
|
|
6667
6705
|
if (reduced || !skeleton) return;
|
|
6668
6706
|
const loop = import_react_native42.Animated.loop(
|
|
@@ -6694,7 +6732,7 @@ function KjunChartSkeleton({
|
|
|
6694
6732
|
{
|
|
6695
6733
|
...chartPart("donut"),
|
|
6696
6734
|
...hidden,
|
|
6697
|
-
style: { height:
|
|
6735
|
+
style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: import_tokens40.tokens.radius.radius9999 }
|
|
6698
6736
|
}
|
|
6699
6737
|
) : kind === "matrix" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native42.View, { ...chartPart("matrix"), ...hidden, style: { alignSelf: "stretch", flex: 1, gap: import_tokens40.tokens.dimension.value4 }, children: Array.from({ length: rowCount }, (_, row) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native42.View, { style: { flex: 1, flexDirection: "row", gap: import_tokens40.tokens.dimension.value4 }, children: Array.from({ length: columnCount }, (_2, column) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6700
6738
|
import_react_native42.View,
|
|
@@ -6714,6 +6752,7 @@ function KjunChartSkeleton({
|
|
|
6714
6752
|
{
|
|
6715
6753
|
...chartPart("status"),
|
|
6716
6754
|
role: status,
|
|
6755
|
+
accessibilityLiveRegion: status ? "polite" : void 0,
|
|
6717
6756
|
pointerEvents: "none",
|
|
6718
6757
|
style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center" },
|
|
6719
6758
|
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
@@ -7402,9 +7441,18 @@ function tablePresentation(props, mobile) {
|
|
|
7402
7441
|
}
|
|
7403
7442
|
};
|
|
7404
7443
|
}
|
|
7444
|
+
var warnedFormats = /* @__PURE__ */ new Set();
|
|
7445
|
+
function columnFormat(column) {
|
|
7446
|
+
if (typeof column.format === "function") return column.format;
|
|
7447
|
+
if (column.format != null && !warnedFormats.has(column.key)) {
|
|
7448
|
+
warnedFormats.add(column.key);
|
|
7449
|
+
console.warn(`KJUN Table: ${column.key} \uC5F4\uC758 format\uC740 \uD568\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.`);
|
|
7450
|
+
}
|
|
7451
|
+
return void 0;
|
|
7452
|
+
}
|
|
7405
7453
|
function tableCellValue(props, column, row, index) {
|
|
7406
7454
|
const value = getValue(row, column.key);
|
|
7407
|
-
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : column
|
|
7455
|
+
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : columnFormat(column) ? columnFormat(column)(value, row) : props.formatValue ? props.formatValue(value, column, row) : value == null ? "-" : typeof value === "number" && column.type === "number" ? new Intl.NumberFormat().format(value) : String(value);
|
|
7408
7456
|
return { value, body };
|
|
7409
7457
|
}
|
|
7410
7458
|
|
package/dist/index.web.js
CHANGED
|
@@ -119,6 +119,10 @@ function installLayerKeyboard(document2, state, keyupFallback = false) {
|
|
|
119
119
|
import { createContext as createContext2, useContext as useContext2, useId, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
120
120
|
|
|
121
121
|
// shared/package-runtime/layer-state.ts
|
|
122
|
+
function chooseReturnTarget(chosen, fallback2) {
|
|
123
|
+
if (chosen === false) return void 0;
|
|
124
|
+
return chosen && chosen.isConnected !== false ? chosen : fallback2;
|
|
125
|
+
}
|
|
122
126
|
function createLayerState() {
|
|
123
127
|
const entries = /* @__PURE__ */ new Map(), listeners = /* @__PURE__ */ new Set();
|
|
124
128
|
const restoredFocus = /* @__PURE__ */ new WeakSet();
|
|
@@ -139,6 +143,7 @@ function createLayerState() {
|
|
|
139
143
|
return !layer.blocked && (layer.kind === "window" ? ((_a = topWindow()) == null ? void 0 : _a.id) === layer.id : ((_b = topWindow()) == null ? void 0 : _b.id) === layer.owner);
|
|
140
144
|
};
|
|
141
145
|
const top = () => [...entries.values()].filter(active).sort((a, b) => a.order - b.order).at(-1);
|
|
146
|
+
const topPopup = () => [...entries.values()].filter((layer) => layer.kind !== "tooltip" && active(layer)).sort((a, b) => a.order - b.order).at(-1);
|
|
142
147
|
function dismiss(layer) {
|
|
143
148
|
if (layer.closeRequested) return;
|
|
144
149
|
layer.closeRequested = true;
|
|
@@ -158,6 +163,7 @@ function createLayerState() {
|
|
|
158
163
|
entries,
|
|
159
164
|
topWindow,
|
|
160
165
|
top,
|
|
166
|
+
topPopup,
|
|
161
167
|
windowOf,
|
|
162
168
|
isRestoredFocus(target) {
|
|
163
169
|
return !!target && restoredFocus.has(target);
|
|
@@ -306,21 +312,31 @@ function focusTrigger(target) {
|
|
|
306
312
|
}
|
|
307
313
|
return target;
|
|
308
314
|
}
|
|
309
|
-
function restoreFocus(target, state, id) {
|
|
315
|
+
function restoreFocus(target, state, id, fallback2) {
|
|
316
|
+
const usable = (item) => (item == null ? void 0 : item.isConnected) !== false && !(typeof HTMLElement !== "undefined" && item instanceof HTMLElement && item.closest("[inert]"));
|
|
310
317
|
const restore = () => {
|
|
311
|
-
var _a, _b, _c, _d;
|
|
318
|
+
var _a, _b, _c, _d, _e;
|
|
312
319
|
if (state.entries.has(id)) return;
|
|
313
|
-
if ((target
|
|
314
|
-
else (
|
|
320
|
+
if (usable(target)) (_a = target == null ? void 0 : target.focus) == null ? void 0 : _a.call(target, { preventScroll: true });
|
|
321
|
+
else if (fallback2 && fallback2 !== target && usable(fallback2)) (_b = fallback2.focus) == null ? void 0 : _b.call(fallback2, { preventScroll: true });
|
|
322
|
+
else (_e = (_d = (_c = state.topWindow()) == null ? void 0 : _c.root) == null ? void 0 : _d.focus) == null ? void 0 : _e.call(_d, { preventScroll: true });
|
|
315
323
|
};
|
|
316
324
|
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(restore);
|
|
317
325
|
else queueMicrotask(restore);
|
|
318
326
|
}
|
|
319
|
-
function useLayer(open, present, kind, close, trigger) {
|
|
327
|
+
function useLayer(open, present, kind, close, trigger, returnFocus) {
|
|
320
328
|
var _a;
|
|
321
329
|
const state = useLayerState(), parent = useContext2(LayerScope), id = useId();
|
|
322
330
|
const callback = useRef(close);
|
|
323
331
|
callback.current = close;
|
|
332
|
+
const returnRef = useRef(returnFocus);
|
|
333
|
+
returnRef.current = returnFocus;
|
|
334
|
+
const fallbackFocus = useRef(null);
|
|
335
|
+
const removeLayer = () => {
|
|
336
|
+
const removed = state.remove(id, currentFocus());
|
|
337
|
+
if (removed) fallbackFocus.current = removed;
|
|
338
|
+
return removed && returnRef.current ? chooseReturnTarget(returnRef.current(), removed) : removed;
|
|
339
|
+
};
|
|
324
340
|
const openingFocus = useRef(null);
|
|
325
341
|
const wasOpen = useRef(false);
|
|
326
342
|
const pendingFocus = useRef(null);
|
|
@@ -332,17 +348,17 @@ function useLayer(open, present, kind, close, trigger) {
|
|
|
332
348
|
state.open(id, kind, parent, () => callback.current(), focusTrigger(trigger == null ? void 0 : trigger.current) || openingFocus.current);
|
|
333
349
|
} else if (kind === "window" && present) state.markClosing(id);
|
|
334
350
|
else if (kind !== "window" || !present) {
|
|
335
|
-
const target =
|
|
351
|
+
const target = removeLayer();
|
|
336
352
|
if (target) pendingFocus.current = target;
|
|
337
353
|
if (!present && pendingFocus.current) {
|
|
338
|
-
restoreFocus(pendingFocus.current, state, id);
|
|
354
|
+
restoreFocus(pendingFocus.current, state, id, fallbackFocus.current);
|
|
339
355
|
pendingFocus.current = null;
|
|
340
356
|
}
|
|
341
357
|
}
|
|
342
358
|
}, [open, present, state, id, kind, parent, trigger]);
|
|
343
359
|
useLayoutEffect(() => () => {
|
|
344
|
-
const target =
|
|
345
|
-
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id);
|
|
360
|
+
const target = removeLayer();
|
|
361
|
+
if (target || pendingFocus.current) restoreFocus(target || pendingFocus.current, state, id, fallbackFocus.current);
|
|
346
362
|
}, [state, id]);
|
|
347
363
|
const entry = state.entries.get(id);
|
|
348
364
|
return {
|
|
@@ -3193,7 +3209,7 @@ function KjunRadioGroup({
|
|
|
3193
3209
|
accessibilityLabel: ariaLabel,
|
|
3194
3210
|
style: {
|
|
3195
3211
|
flexDirection: direction === "vertical" ? "column" : "row",
|
|
3196
|
-
flexWrap: "wrap",
|
|
3212
|
+
flexWrap: direction === "vertical" ? "nowrap" : "wrap",
|
|
3197
3213
|
gap: direction === "vertical" ? tokens17.dimension.value8 : tokens17.dimension.value16
|
|
3198
3214
|
},
|
|
3199
3215
|
children: children || options.map((option) => /* @__PURE__ */ jsx19(
|
|
@@ -4431,6 +4447,17 @@ function nextOptionValue(value, option, key, multiple) {
|
|
|
4431
4447
|
if (!multiple) return id;
|
|
4432
4448
|
return Array.isArray(value) && value.includes(id) ? value.filter((item) => item !== id) : [...Array.isArray(value) ? value : [], id];
|
|
4433
4449
|
}
|
|
4450
|
+
function optionMatchRank(option, query, labelKey, searchKeys = []) {
|
|
4451
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
4452
|
+
if (!needle) return 0;
|
|
4453
|
+
const label = optionLabel(option, labelKey).toLocaleLowerCase();
|
|
4454
|
+
if (label.startsWith(needle)) return 0;
|
|
4455
|
+
if (label.includes(needle)) return 1;
|
|
4456
|
+
return typeof option === "object" && searchKeys.some((key) => {
|
|
4457
|
+
var _a;
|
|
4458
|
+
return String((_a = option[key]) != null ? _a : "").toLocaleLowerCase().includes(needle);
|
|
4459
|
+
}) ? 2 : -1;
|
|
4460
|
+
}
|
|
4434
4461
|
function selectOptions({
|
|
4435
4462
|
options,
|
|
4436
4463
|
value,
|
|
@@ -4440,10 +4467,13 @@ function selectOptions({
|
|
|
4440
4467
|
pageSize,
|
|
4441
4468
|
limit,
|
|
4442
4469
|
loading,
|
|
4443
|
-
multiple
|
|
4470
|
+
multiple,
|
|
4471
|
+
filterFn,
|
|
4472
|
+
searchKeys = []
|
|
4444
4473
|
}) {
|
|
4445
4474
|
const selected = (option) => optionSelected(value, option, valueKey);
|
|
4446
|
-
const
|
|
4475
|
+
const indexed = options.map((option, index) => ({ option, key: optionKey(option, valueKey, index) }));
|
|
4476
|
+
const matching = filterFn ? indexed.filter(({ option }) => filterFn(option, query)) : indexed.map((item, index) => ({ item, index, rank: optionMatchRank(item.option, query, labelKey, searchKeys) })).filter(({ rank }) => rank >= 0).sort((a, b) => a.rank - b.rank || a.index - b.index).map(({ item }) => item);
|
|
4447
4477
|
const visible = loading ? [] : pageSize > 0 ? matching.slice(0, limit) : matching;
|
|
4448
4478
|
const selectedOption = options.find(selected);
|
|
4449
4479
|
const label = multiple && Array.isArray(value) && value.length > 1 ? `${value.length}\uAC1C \uC120\uD0DD\uB428` : selectedOption !== void 0 ? optionLabel(selectedOption, labelKey) : "";
|
|
@@ -5178,7 +5208,9 @@ function KjunSelect({
|
|
|
5178
5208
|
onChange,
|
|
5179
5209
|
onOpenChange,
|
|
5180
5210
|
onSearch,
|
|
5181
|
-
onClear
|
|
5211
|
+
onClear,
|
|
5212
|
+
filterFn,
|
|
5213
|
+
searchKeys
|
|
5182
5214
|
}) {
|
|
5183
5215
|
const { open, query, limit, changeOpen, search, showMore } = useSelectState(controlled, disabled, optionPageSize, onOpenChange);
|
|
5184
5216
|
const { colors } = useKjunStyles(), field = useKjunField(), ref = useRef24(null), spec = tokens29.input[size];
|
|
@@ -5203,7 +5235,9 @@ function KjunSelect({
|
|
|
5203
5235
|
pageSize: optionPageSize,
|
|
5204
5236
|
limit,
|
|
5205
5237
|
loading,
|
|
5206
|
-
multiple
|
|
5238
|
+
multiple,
|
|
5239
|
+
filterFn,
|
|
5240
|
+
searchKeys
|
|
5207
5241
|
});
|
|
5208
5242
|
const firstSelected = visible.findIndex(({ option }) => selected(option));
|
|
5209
5243
|
if (firstSelected < 0) selectedRow.current = null;
|
|
@@ -6265,7 +6299,7 @@ function KjunRefreshButton({
|
|
|
6265
6299
|
...props
|
|
6266
6300
|
}) {
|
|
6267
6301
|
const reduced = useReducedMotion();
|
|
6268
|
-
const label = ariaLabel || [targetName, "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6302
|
+
const label = ariaLabel || [targetName, mode === "text" ? text : "\uC0C8\uB85C\uACE0\uCE68"].filter(Boolean).join(" ");
|
|
6269
6303
|
const hint = tooltip != null ? tooltip : mode === "icon" ? label : "";
|
|
6270
6304
|
const button = /* @__PURE__ */ jsx36(KjunTooltip, { content: props.disabled || props.loading ? "" : hint, placement: tooltipPlacement, delay: tooltipDelay, children: /* @__PURE__ */ jsx36(
|
|
6271
6305
|
KjunButton,
|
|
@@ -6518,8 +6552,12 @@ function chartSkeletonCount(value) {
|
|
|
6518
6552
|
function chartMatrixMuted(row, column) {
|
|
6519
6553
|
return (row + column + 2) % 3 === 0;
|
|
6520
6554
|
}
|
|
6555
|
+
var chartDonutRatio = 0.8;
|
|
6521
6556
|
function chartDonutHole(height, thickness) {
|
|
6522
|
-
return Math.max(0, height *
|
|
6557
|
+
return Math.max(0, height * chartDonutRatio - 2 * thickness);
|
|
6558
|
+
}
|
|
6559
|
+
function chartSkeletonKind(kind) {
|
|
6560
|
+
return kind === "donut" || kind === "matrix" ? kind : "frame";
|
|
6523
6561
|
}
|
|
6524
6562
|
|
|
6525
6563
|
// packages/native/src/market-skeleton.tsx
|
|
@@ -6681,7 +6719,7 @@ function KjunFormSkeleton({
|
|
|
6681
6719
|
}
|
|
6682
6720
|
var chartPart = (name) => Platform24.OS === "web" ? { dataSet: { kjunChartPart: name } } : {};
|
|
6683
6721
|
function KjunChartSkeleton({
|
|
6684
|
-
kind = "frame",
|
|
6722
|
+
kind: requestedKind = "frame",
|
|
6685
6723
|
height = tokens38.extensions.chartSkeleton.height,
|
|
6686
6724
|
loadingText = "\uCC28\uD2B8\uB97C \uBD88\uB7EC\uC624\uB294 \uC911",
|
|
6687
6725
|
skeleton = true,
|
|
@@ -6689,7 +6727,7 @@ function KjunChartSkeleton({
|
|
|
6689
6727
|
rows = 8,
|
|
6690
6728
|
columns = 14
|
|
6691
6729
|
}) {
|
|
6692
|
-
const { 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" };
|
|
6730
|
+
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" };
|
|
6693
6731
|
useEffect22(() => {
|
|
6694
6732
|
if (reduced || !skeleton) return;
|
|
6695
6733
|
const loop = Animated17.loop(
|
|
@@ -6721,7 +6759,7 @@ function KjunChartSkeleton({
|
|
|
6721
6759
|
{
|
|
6722
6760
|
...chartPart("donut"),
|
|
6723
6761
|
...hidden,
|
|
6724
|
-
style: { height:
|
|
6762
|
+
style: { height: `${chartDonutRatio * 100}%`, aspectRatio: 1, borderWidth: thickness, borderColor: colors.skeleton, borderRadius: tokens38.radius.radius9999 }
|
|
6725
6763
|
}
|
|
6726
6764
|
) : 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(
|
|
6727
6765
|
View33,
|
|
@@ -6741,6 +6779,7 @@ function KjunChartSkeleton({
|
|
|
6741
6779
|
{
|
|
6742
6780
|
...chartPart("status"),
|
|
6743
6781
|
role: status,
|
|
6782
|
+
accessibilityLiveRegion: status ? "polite" : void 0,
|
|
6744
6783
|
pointerEvents: "none",
|
|
6745
6784
|
style: { position: "absolute", inset: 0, alignItems: "center", justifyContent: "center" },
|
|
6746
6785
|
children: /* @__PURE__ */ jsx39(
|
|
@@ -7441,9 +7480,18 @@ function tablePresentation(props, mobile) {
|
|
|
7441
7480
|
}
|
|
7442
7481
|
};
|
|
7443
7482
|
}
|
|
7483
|
+
var warnedFormats = /* @__PURE__ */ new Set();
|
|
7484
|
+
function columnFormat(column) {
|
|
7485
|
+
if (typeof column.format === "function") return column.format;
|
|
7486
|
+
if (column.format != null && !warnedFormats.has(column.key)) {
|
|
7487
|
+
warnedFormats.add(column.key);
|
|
7488
|
+
console.warn(`KJUN Table: ${column.key} \uC5F4\uC758 format\uC740 \uD568\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.`);
|
|
7489
|
+
}
|
|
7490
|
+
return void 0;
|
|
7491
|
+
}
|
|
7444
7492
|
function tableCellValue(props, column, row, index) {
|
|
7445
7493
|
const value = getValue(row, column.key);
|
|
7446
|
-
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : column
|
|
7494
|
+
const body = props.renderCell ? props.renderCell(value, column, row, index) : column.render ? column.render(value, row, index) : columnFormat(column) ? columnFormat(column)(value, row) : props.formatValue ? props.formatValue(value, column, row) : value == null ? "-" : typeof value === "number" && column.type === "number" ? new Intl.NumberFormat().format(value) : String(value);
|
|
7447
7495
|
return { value, body };
|
|
7448
7496
|
}
|
|
7449
7497
|
|
package/dist/styles.css
CHANGED
|
@@ -3100,6 +3100,8 @@
|
|
|
3100
3100
|
height: 100%;
|
|
3101
3101
|
}
|
|
3102
3102
|
.kjun-chart-skeleton-donut {
|
|
3103
|
+
/* The hole is 80% − 2 × thickness only in border-box, whatever the app's reset. */
|
|
3104
|
+
box-sizing: border-box;
|
|
3103
3105
|
height: 80%;
|
|
3104
3106
|
aspect-ratio: 1;
|
|
3105
3107
|
border: var(--_kjun-extension-chart-skeleton-donut-thickness) solid var(--_kjun-color-skeleton);
|
|
@@ -3135,7 +3137,7 @@
|
|
|
3135
3137
|
|
|
3136
3138
|
.kjun-chart-skeleton-status { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--_kjun-extension-skeleton-gap); pointer-events:none; }
|
|
3137
3139
|
.kjun-chart-skeleton-status>span { max-width:90%; padding:var(--_kjun-geometry-dimension-value4) var(--_kjun-geometry-dimension-value12); border-radius:var(--_kjun-geometry-radius-radius6); font-size:var(--_kjun-type-body-size); text-align:center; overflow-wrap:anywhere; background:var(--_kjun-color-surface); color:var(--_kjun-color-text-secondary); line-height: var(--_kjun-type-body-line); font-weight: var(--_kjun-type-body-weight); letter-spacing: var(--_kjun-type-body-tracking); border:var(--_kjun-border-default-width) solid var(--_kjun-color-chart-grid); }
|
|
3138
|
-
.kjun-chart-skeleton[data-kjun-chart-kind="donut"] .kjun-chart-skeleton-status>span { border:0; max-width:calc(80cqh - 2 * var(--_kjun-extension-chart-skeleton-donut-thickness)); }
|
|
3140
|
+
.kjun-chart-skeleton[data-kjun-chart-kind="donut"] .kjun-chart-skeleton-status>span { box-sizing:border-box; border:0; max-width:calc(80cqh - 2 * var(--_kjun-extension-chart-skeleton-donut-thickness)); }
|
|
3139
3141
|
|
|
3140
3142
|
.kjun-data-status > .kjun-spinner { flex-shrink: 0; }
|
|
3141
3143
|
.kjun-data-status > span:last-child { min-width: 0; overflow-wrap: anywhere; }
|
|
@@ -25,6 +25,10 @@ export interface KjunSelectProps<T extends SelectOption = SelectOption> {
|
|
|
25
25
|
onChange?: (v: OptionValue | OptionValue[] | null) => void;
|
|
26
26
|
onOpenChange?: (v: boolean) => void;
|
|
27
27
|
onSearch?: (v: string) => void;
|
|
28
|
+
/** Replaces the default ranked label/searchKeys match; results keep the original order. */
|
|
29
|
+
filterFn?: (option: T, query: string) => boolean;
|
|
30
|
+
/** Extra option fields searched after the label. */
|
|
31
|
+
searchKeys?: string[];
|
|
28
32
|
onClear?: () => void;
|
|
29
33
|
}
|
|
30
|
-
export declare function KjunSelect<T extends SelectOption = SelectOption>({ value, options, placeholder, ariaLabel, labelKey, valueKey, size, disabled, searchable, open: controlled, loading, searchPlaceholder, optionPageSize, clearable, multiple, error, menuHeader, renderOption, renderSelected, onValueChange, onChange, onOpenChange, onSearch, onClear, }: KjunSelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function KjunSelect<T extends SelectOption = SelectOption>({ value, options, placeholder, ariaLabel, labelKey, valueKey, size, disabled, searchable, open: controlled, loading, searchPlaceholder, optionPageSize, clearable, multiple, error, menuHeader, renderOption, renderSelected, onValueChange, onChange, onOpenChange, onSearch, onClear, filterFn, searchKeys, }: KjunSelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -25,6 +25,10 @@ export interface KjunSelectProps<T extends SelectOption = SelectOption> {
|
|
|
25
25
|
onChange?: (v: OptionValue | OptionValue[] | null) => void;
|
|
26
26
|
onOpenChange?: (v: boolean) => void;
|
|
27
27
|
onSearch?: (v: string) => void;
|
|
28
|
+
/** Replaces the default ranked label/searchKeys match; results keep the original order. */
|
|
29
|
+
filterFn?: (option: T, query: string) => boolean;
|
|
30
|
+
/** Extra option fields searched after the label. */
|
|
31
|
+
searchKeys?: string[];
|
|
28
32
|
onClear?: () => void;
|
|
29
33
|
}
|
|
30
|
-
export declare function KjunSelect<T extends SelectOption = SelectOption>({ value, options, placeholder, ariaLabel, labelKey, valueKey, size, disabled, searchable, open: controlled, loading, searchPlaceholder, optionPageSize, clearable, multiple, error, menuHeader, renderOption, renderSelected, onValueChange, onChange, onOpenChange, onSearch, onClear, }: KjunSelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function KjunSelect<T extends SelectOption = SelectOption>({ value, options, placeholder, ariaLabel, labelKey, valueKey, size, disabled, searchable, open: controlled, loading, searchPlaceholder, optionPageSize, clearable, multiple, error, menuHeader, renderOption, renderSelected, onValueChange, onChange, onOpenChange, onSearch, onClear, filterFn, searchKeys, }: KjunSelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -28,6 +28,6 @@ export interface KjunChartSkeletonProps {
|
|
|
28
28
|
rows?: number;
|
|
29
29
|
columns?: number;
|
|
30
30
|
}
|
|
31
|
-
export declare function KjunChartSkeleton({ kind, height, loadingText, skeleton, loadingDelay, rows, columns, }: KjunChartSkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function KjunChartSkeleton({ kind: requestedKind, height, loadingText, skeleton, loadingDelay, rows, columns, }: KjunChartSkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
32
32
|
export { KjunMarketTableSkeleton } from "./market-skeleton.cjs";
|
|
33
33
|
export type { KjunMarketTableSkeletonProps } from "./market-skeleton.cjs";
|
|
@@ -28,6 +28,6 @@ export interface KjunChartSkeletonProps {
|
|
|
28
28
|
rows?: number;
|
|
29
29
|
columns?: number;
|
|
30
30
|
}
|
|
31
|
-
export declare function KjunChartSkeleton({ kind, height, loadingText, skeleton, loadingDelay, rows, columns, }: KjunChartSkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function KjunChartSkeleton({ kind: requestedKind, height, loadingText, skeleton, loadingDelay, rows, columns, }: KjunChartSkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
32
32
|
export { KjunMarketTableSkeleton } from "./market-skeleton.js";
|
|
33
33
|
export type { KjunMarketTableSkeletonProps } from "./market-skeleton.js";
|
|
@@ -8,5 +8,9 @@ export declare const chartSkeletonMaxCount = 100;
|
|
|
8
8
|
export declare function chartSkeletonCount(value: number): number;
|
|
9
9
|
/** Every third diagonal cell is drawn at the pending opacity so the matrix reads as a heatmap. */
|
|
10
10
|
export declare function chartMatrixMuted(row: number, column: number): boolean;
|
|
11
|
-
/**
|
|
11
|
+
/** Donut ring diameter as a share of the skeleton height; data-state.css repeats it as 80% and 80cqh. */
|
|
12
|
+
export declare const chartDonutRatio = 0.8;
|
|
13
|
+
/** Inner diameter of the donut ring. */
|
|
12
14
|
export declare function chartDonutHole(height: number, thickness: number): number;
|
|
15
|
+
/** Kinds removed in 0.8.0 (line, bar, candle, grid) or any other value draw, and are named, frame. */
|
|
16
|
+
export declare function chartSkeletonKind(kind: unknown): KjunChartSkeletonKind;
|
|
@@ -8,5 +8,9 @@ export declare const chartSkeletonMaxCount = 100;
|
|
|
8
8
|
export declare function chartSkeletonCount(value: number): number;
|
|
9
9
|
/** Every third diagonal cell is drawn at the pending opacity so the matrix reads as a heatmap. */
|
|
10
10
|
export declare function chartMatrixMuted(row: number, column: number): boolean;
|
|
11
|
-
/**
|
|
11
|
+
/** Donut ring diameter as a share of the skeleton height; data-state.css repeats it as 80% and 80cqh. */
|
|
12
|
+
export declare const chartDonutRatio = 0.8;
|
|
13
|
+
/** Inner diameter of the donut ring. */
|
|
12
14
|
export declare function chartDonutHole(height: number, thickness: number): number;
|
|
15
|
+
/** Kinds removed in 0.8.0 (line, bar, candle, grid) or any other value draw, and are named, frame. */
|
|
16
|
+
export declare function chartSkeletonKind(kind: unknown): KjunChartSkeletonKind;
|
|
@@ -6,6 +6,8 @@ export interface FocusTarget {
|
|
|
6
6
|
}) => void;
|
|
7
7
|
isConnected?: boolean;
|
|
8
8
|
}
|
|
9
|
+
/** A caller-chosen return target wins while it is still in the document; false means the caller moves focus itself. */
|
|
10
|
+
export declare function chooseReturnTarget(chosen: FocusTarget | null | false | undefined, fallback: FocusTarget | null | undefined): FocusTarget | null | undefined;
|
|
9
11
|
export interface LayerEntry {
|
|
10
12
|
id: string;
|
|
11
13
|
kind: LayerKind;
|
|
@@ -24,6 +26,7 @@ export declare function createLayerState(): {
|
|
|
24
26
|
entries: Map<string, LayerEntry>;
|
|
25
27
|
topWindow: () => LayerEntry | undefined;
|
|
26
28
|
top: () => LayerEntry | undefined;
|
|
29
|
+
topPopup: () => LayerEntry | undefined;
|
|
27
30
|
windowOf: (id?: string) => string | undefined;
|
|
28
31
|
isRestoredFocus(target?: FocusTarget | null): boolean;
|
|
29
32
|
clearRestoredFocus(target?: FocusTarget | null): void;
|
|
@@ -6,6 +6,8 @@ export interface FocusTarget {
|
|
|
6
6
|
}) => void;
|
|
7
7
|
isConnected?: boolean;
|
|
8
8
|
}
|
|
9
|
+
/** A caller-chosen return target wins while it is still in the document; false means the caller moves focus itself. */
|
|
10
|
+
export declare function chooseReturnTarget(chosen: FocusTarget | null | false | undefined, fallback: FocusTarget | null | undefined): FocusTarget | null | undefined;
|
|
9
11
|
export interface LayerEntry {
|
|
10
12
|
id: string;
|
|
11
13
|
kind: LayerKind;
|
|
@@ -24,6 +26,7 @@ export declare function createLayerState(): {
|
|
|
24
26
|
entries: Map<string, LayerEntry>;
|
|
25
27
|
topWindow: () => LayerEntry | undefined;
|
|
26
28
|
top: () => LayerEntry | undefined;
|
|
29
|
+
topPopup: () => LayerEntry | undefined;
|
|
27
30
|
windowOf: (id?: string) => string | undefined;
|
|
28
31
|
isRestoredFocus(target?: FocusTarget | null): boolean;
|
|
29
32
|
clearRestoredFocus(target?: FocusTarget | null): void;
|
|
@@ -8,7 +8,9 @@ export declare const optionDisabled: (option: SelectOption) => boolean;
|
|
|
8
8
|
export declare function optionKey(option: SelectOption, key: string, index: number): string;
|
|
9
9
|
export declare function optionSelected(value: OptionValue | OptionValue[] | null, option: SelectOption, key: string): boolean;
|
|
10
10
|
export declare function nextOptionValue(value: OptionValue | OptionValue[] | null, option: SelectOption, key: string, multiple: boolean): OptionValue | OptionValue[];
|
|
11
|
-
|
|
11
|
+
/** 0 label starts with the query, 1 label contains it, 2 a searchKeys field contains it, -1 no match; an empty query matches as 0. */
|
|
12
|
+
export declare function optionMatchRank(option: SelectOption, query: string, labelKey: string, searchKeys?: readonly string[]): 0 | 1 | -1 | 2;
|
|
13
|
+
export declare function selectOptions<T extends SelectOption>({ options, value, labelKey, valueKey, query, pageSize, limit, loading, multiple, filterFn, searchKeys, }: {
|
|
12
14
|
options: T[];
|
|
13
15
|
value: OptionValue | OptionValue[] | null;
|
|
14
16
|
labelKey: string;
|
|
@@ -18,6 +20,8 @@ export declare function selectOptions<T extends SelectOption>({ options, value,
|
|
|
18
20
|
limit: number;
|
|
19
21
|
loading: boolean;
|
|
20
22
|
multiple: boolean;
|
|
23
|
+
filterFn?: (option: T, query: string) => boolean;
|
|
24
|
+
searchKeys?: readonly string[];
|
|
21
25
|
}): {
|
|
22
26
|
selected: (option: T) => boolean;
|
|
23
27
|
matching: {
|
|
@@ -8,7 +8,9 @@ export declare const optionDisabled: (option: SelectOption) => boolean;
|
|
|
8
8
|
export declare function optionKey(option: SelectOption, key: string, index: number): string;
|
|
9
9
|
export declare function optionSelected(value: OptionValue | OptionValue[] | null, option: SelectOption, key: string): boolean;
|
|
10
10
|
export declare function nextOptionValue(value: OptionValue | OptionValue[] | null, option: SelectOption, key: string, multiple: boolean): OptionValue | OptionValue[];
|
|
11
|
-
|
|
11
|
+
/** 0 label starts with the query, 1 label contains it, 2 a searchKeys field contains it, -1 no match; an empty query matches as 0. */
|
|
12
|
+
export declare function optionMatchRank(option: SelectOption, query: string, labelKey: string, searchKeys?: readonly string[]): 0 | 1 | -1 | 2;
|
|
13
|
+
export declare function selectOptions<T extends SelectOption>({ options, value, labelKey, valueKey, query, pageSize, limit, loading, multiple, filterFn, searchKeys, }: {
|
|
12
14
|
options: T[];
|
|
13
15
|
value: OptionValue | OptionValue[] | null;
|
|
14
16
|
labelKey: string;
|
|
@@ -18,6 +20,8 @@ export declare function selectOptions<T extends SelectOption>({ options, value,
|
|
|
18
20
|
limit: number;
|
|
19
21
|
loading: boolean;
|
|
20
22
|
multiple: boolean;
|
|
23
|
+
filterFn?: (option: T, query: string) => boolean;
|
|
24
|
+
searchKeys?: readonly string[];
|
|
21
25
|
}): {
|
|
22
26
|
selected: (option: T) => boolean;
|
|
23
27
|
matching: {
|
|
@@ -11,6 +11,10 @@ export declare function tablePresentation<Row extends object>(props: TableProps<
|
|
|
11
11
|
sections: TableCardSection[];
|
|
12
12
|
columnsForSection(row: Row, section: TableCardSection): TableColumn<Row>[];
|
|
13
13
|
};
|
|
14
|
+
export declare function columnFormat<Format>(column: {
|
|
15
|
+
key: string;
|
|
16
|
+
format?: Format;
|
|
17
|
+
}): Format | undefined;
|
|
14
18
|
export declare function tableCellValue<Row extends object>(props: TableProps<Row, unknown>, column: TableColumn<Row>, row: Row, index: number): {
|
|
15
19
|
value: unknown;
|
|
16
20
|
body: ReactNode;
|
|
@@ -11,6 +11,10 @@ export declare function tablePresentation<Row extends object>(props: TableProps<
|
|
|
11
11
|
sections: TableCardSection[];
|
|
12
12
|
columnsForSection(row: Row, section: TableCardSection): TableColumn<Row>[];
|
|
13
13
|
};
|
|
14
|
+
export declare function columnFormat<Format>(column: {
|
|
15
|
+
key: string;
|
|
16
|
+
format?: Format;
|
|
17
|
+
}): Format | undefined;
|
|
14
18
|
export declare function tableCellValue<Row extends object>(props: TableProps<Row, unknown>, column: TableColumn<Row>, row: Row, index: number): {
|
|
15
19
|
value: unknown;
|
|
16
20
|
body: ReactNode;
|
|
@@ -9,6 +9,7 @@ export declare function useLayerState(): {
|
|
|
9
9
|
entries: Map<string, import("./layer-state.cjs").LayerEntry>;
|
|
10
10
|
topWindow: () => import("./layer-state.cjs").LayerEntry | undefined;
|
|
11
11
|
top: () => import("./layer-state.cjs").LayerEntry | undefined;
|
|
12
|
+
topPopup: () => import("./layer-state.cjs").LayerEntry | undefined;
|
|
12
13
|
windowOf: (id?: string) => string | undefined;
|
|
13
14
|
isRestoredFocus(target?: FocusTarget | null): boolean;
|
|
14
15
|
clearRestoredFocus(target?: FocusTarget | null): void;
|
|
@@ -36,12 +37,13 @@ export declare function useActiveLayerScope(): boolean;
|
|
|
36
37
|
export declare function focusTrigger(target: FocusTarget | null | undefined): FocusTarget | HTMLElement | null | undefined;
|
|
37
38
|
export declare function useLayer(open: boolean, present: boolean, kind: LayerKind, close: () => void, trigger?: {
|
|
38
39
|
current: FocusTarget | null;
|
|
39
|
-
}): {
|
|
40
|
+
}, returnFocus?: () => FocusTarget | null | false | undefined): {
|
|
40
41
|
id: string;
|
|
41
42
|
state: {
|
|
42
43
|
entries: Map<string, import("./layer-state.cjs").LayerEntry>;
|
|
43
44
|
topWindow: () => import("./layer-state.cjs").LayerEntry | undefined;
|
|
44
45
|
top: () => import("./layer-state.cjs").LayerEntry | undefined;
|
|
46
|
+
topPopup: () => import("./layer-state.cjs").LayerEntry | undefined;
|
|
45
47
|
windowOf: (id?: string) => string | undefined;
|
|
46
48
|
isRestoredFocus(target?: FocusTarget | null): boolean;
|
|
47
49
|
clearRestoredFocus(target?: FocusTarget | null): void;
|
|
@@ -9,6 +9,7 @@ export declare function useLayerState(): {
|
|
|
9
9
|
entries: Map<string, import("./layer-state.js").LayerEntry>;
|
|
10
10
|
topWindow: () => import("./layer-state.js").LayerEntry | undefined;
|
|
11
11
|
top: () => import("./layer-state.js").LayerEntry | undefined;
|
|
12
|
+
topPopup: () => import("./layer-state.js").LayerEntry | undefined;
|
|
12
13
|
windowOf: (id?: string) => string | undefined;
|
|
13
14
|
isRestoredFocus(target?: FocusTarget | null): boolean;
|
|
14
15
|
clearRestoredFocus(target?: FocusTarget | null): void;
|
|
@@ -36,12 +37,13 @@ export declare function useActiveLayerScope(): boolean;
|
|
|
36
37
|
export declare function focusTrigger(target: FocusTarget | null | undefined): FocusTarget | HTMLElement | null | undefined;
|
|
37
38
|
export declare function useLayer(open: boolean, present: boolean, kind: LayerKind, close: () => void, trigger?: {
|
|
38
39
|
current: FocusTarget | null;
|
|
39
|
-
}): {
|
|
40
|
+
}, returnFocus?: () => FocusTarget | null | false | undefined): {
|
|
40
41
|
id: string;
|
|
41
42
|
state: {
|
|
42
43
|
entries: Map<string, import("./layer-state.js").LayerEntry>;
|
|
43
44
|
topWindow: () => import("./layer-state.js").LayerEntry | undefined;
|
|
44
45
|
top: () => import("./layer-state.js").LayerEntry | undefined;
|
|
46
|
+
topPopup: () => import("./layer-state.js").LayerEntry | undefined;
|
|
45
47
|
windowOf: (id?: string) => string | undefined;
|
|
46
48
|
isRestoredFocus(target?: FocusTarget | null): boolean;
|
|
47
49
|
clearRestoredFocus(target?: FocusTarget | null): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kjun-ui/native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://ui.kjun.dev",
|
|
6
6
|
"repository": {
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"./package.json": "./package.json"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@kjun-ui/tokens": "0.
|
|
51
|
-
"@kjun-ui/icons": "0.
|
|
50
|
+
"@kjun-ui/tokens": "0.9.0",
|
|
51
|
+
"@kjun-ui/icons": "0.9.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"react": "^19.2.3",
|