sellmate-design-system-react 9.0.0-beta.36 → 9.0.0-beta.38
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/components/SLoadingContainer/loading.d.ts +18 -2
- package/dist/index.cjs +121 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +121 -63
- package/dist/index.js.map +1 -1
- package/dist/styles.css +21 -0
- package/package.json +1 -1
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
/** 오버레이 뷰포트 — 스토어를 구독해 SLoadingContainer 를 렌더한다. 직접 배치도 가능. */
|
|
2
2
|
export declare function SLoadingViewport(): import("react").JSX.Element;
|
|
3
3
|
export declare const loading: {
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* 로딩 오버레이 표시. 겹쳐 부르면 그만큼 쌓이고 **마지막 하나가 걷힐 때** 닫힌다.
|
|
6
|
+
* 반환값은 이 호출 하나만 걷는 함수다(두 번 불러도 한 번만 걷힌다) — `hide()` 대신 이것을
|
|
7
|
+
* 쓰면 짝이 어긋나지 않는다.
|
|
8
|
+
*
|
|
9
|
+
* ⚠️ 메시지만 바꾸려면 `update()` 를 쓴다. `show()` 를 다시 부르면 하나 더 쌓여
|
|
10
|
+
* `hide()` 한 번으로는 닫히지 않는다.
|
|
11
|
+
*/
|
|
5
12
|
show(options?: {
|
|
6
13
|
message?: string;
|
|
14
|
+
}): () => void;
|
|
15
|
+
/** 표시 중인 메시지 갱신 — 쌓인 수는 그대로다 */
|
|
16
|
+
update(options: {
|
|
17
|
+
message?: string;
|
|
7
18
|
}): void;
|
|
8
|
-
/**
|
|
19
|
+
/** 가장 나중의 show 하나를 걷는다. 남은 것이 없을 때만 오버레이가 닫힌다 */
|
|
9
20
|
hide(): void;
|
|
21
|
+
/**
|
|
22
|
+
* 쌓인 것을 모두 걷고 즉시 닫는다. 화면 전환·에러 복구처럼 진행 중이던 작업의 짝을 더는
|
|
23
|
+
* 맞출 수 없을 때만 쓴다 — 평소에는 `hide()` 나 `show()` 가 준 함수로 하나씩 걷는다.
|
|
24
|
+
*/
|
|
25
|
+
hideAll(): void;
|
|
10
26
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -6491,10 +6491,19 @@ var SLoadingContainer = /* @__PURE__ */ react.forwardRef(
|
|
|
6491
6491
|
var state = { open: false, message: void 0 };
|
|
6492
6492
|
var listeners = /* @__PURE__ */ new Set();
|
|
6493
6493
|
var emit = () => listeners.forEach((l) => l());
|
|
6494
|
-
var
|
|
6495
|
-
|
|
6494
|
+
var entries = [];
|
|
6495
|
+
var seq = 0;
|
|
6496
|
+
var sync = () => {
|
|
6497
|
+
const top = entries[entries.length - 1];
|
|
6498
|
+
state = { open: entries.length > 0, message: top?.message };
|
|
6496
6499
|
emit();
|
|
6497
6500
|
};
|
|
6501
|
+
var release = (id) => {
|
|
6502
|
+
const next = entries.filter((e) => e.id !== id);
|
|
6503
|
+
if (next.length === entries.length) return;
|
|
6504
|
+
entries = next;
|
|
6505
|
+
sync();
|
|
6506
|
+
};
|
|
6498
6507
|
var subscribe = (cb) => {
|
|
6499
6508
|
listeners.add(cb);
|
|
6500
6509
|
return () => listeners.delete(cb);
|
|
@@ -6514,14 +6523,41 @@ function ensureMounted() {
|
|
|
6514
6523
|
client.createRoot(host).render(/* @__PURE__ */ jsxRuntime.jsx(SLoadingViewport, {}));
|
|
6515
6524
|
}
|
|
6516
6525
|
var loading = {
|
|
6517
|
-
/**
|
|
6526
|
+
/**
|
|
6527
|
+
* 로딩 오버레이 표시. 겹쳐 부르면 그만큼 쌓이고 **마지막 하나가 걷힐 때** 닫힌다.
|
|
6528
|
+
* 반환값은 이 호출 하나만 걷는 함수다(두 번 불러도 한 번만 걷힌다) — `hide()` 대신 이것을
|
|
6529
|
+
* 쓰면 짝이 어긋나지 않는다.
|
|
6530
|
+
*
|
|
6531
|
+
* ⚠️ 메시지만 바꾸려면 `update()` 를 쓴다. `show()` 를 다시 부르면 하나 더 쌓여
|
|
6532
|
+
* `hide()` 한 번으로는 닫히지 않는다.
|
|
6533
|
+
*/
|
|
6518
6534
|
show(options = {}) {
|
|
6519
6535
|
ensureMounted();
|
|
6520
|
-
|
|
6536
|
+
const id = ++seq;
|
|
6537
|
+
entries = [...entries, { id, message: options.message }];
|
|
6538
|
+
sync();
|
|
6539
|
+
return () => release(id);
|
|
6540
|
+
},
|
|
6541
|
+
/** 표시 중인 메시지 갱신 — 쌓인 수는 그대로다 */
|
|
6542
|
+
update(options) {
|
|
6543
|
+
const top = entries[entries.length - 1];
|
|
6544
|
+
if (!top) return;
|
|
6545
|
+
entries = [...entries.slice(0, -1), { ...top, message: options.message }];
|
|
6546
|
+
sync();
|
|
6521
6547
|
},
|
|
6522
|
-
/**
|
|
6548
|
+
/** 가장 나중의 show 하나를 걷는다. 남은 것이 없을 때만 오버레이가 닫힌다 */
|
|
6523
6549
|
hide() {
|
|
6524
|
-
|
|
6550
|
+
const top = entries[entries.length - 1];
|
|
6551
|
+
if (top) release(top.id);
|
|
6552
|
+
},
|
|
6553
|
+
/**
|
|
6554
|
+
* 쌓인 것을 모두 걷고 즉시 닫는다. 화면 전환·에러 복구처럼 진행 중이던 작업의 짝을 더는
|
|
6555
|
+
* 맞출 수 없을 때만 쓴다 — 평소에는 `hide()` 나 `show()` 가 준 함수로 하나씩 걷는다.
|
|
6556
|
+
*/
|
|
6557
|
+
hideAll() {
|
|
6558
|
+
if (entries.length === 0) return;
|
|
6559
|
+
entries = [];
|
|
6560
|
+
sync();
|
|
6525
6561
|
}
|
|
6526
6562
|
};
|
|
6527
6563
|
var SIZE_CONFIG = {
|
|
@@ -7940,7 +7976,7 @@ var MODAL_HOST_Z_INDEX = Z_INDEX.modalHost;
|
|
|
7940
7976
|
var MODAL_HOST_ATTRIBUTE = "data-s-modal-host";
|
|
7941
7977
|
var nextId = 0;
|
|
7942
7978
|
var nextLayerIndex = 0;
|
|
7943
|
-
var
|
|
7979
|
+
var entries2 = [];
|
|
7944
7980
|
function getModalHost() {
|
|
7945
7981
|
if (typeof document === "undefined" || !document.body) return void 0;
|
|
7946
7982
|
const existing = document.body.querySelector(`[${MODAL_HOST_ATTRIBUTE}]`);
|
|
@@ -7961,16 +7997,16 @@ function registerModalStackEntry() {
|
|
|
7961
7997
|
id: ++nextId,
|
|
7962
7998
|
layerIndex: nextLayerIndex++
|
|
7963
7999
|
};
|
|
7964
|
-
|
|
8000
|
+
entries2.push(entry);
|
|
7965
8001
|
let registered = true;
|
|
7966
8002
|
return {
|
|
7967
8003
|
layerIndex: entry.layerIndex,
|
|
7968
|
-
isTop: () =>
|
|
8004
|
+
isTop: () => entries2[entries2.length - 1] === entry,
|
|
7969
8005
|
unregister: () => {
|
|
7970
8006
|
if (!registered) return;
|
|
7971
8007
|
registered = false;
|
|
7972
|
-
const index =
|
|
7973
|
-
if (index !== -1)
|
|
8008
|
+
const index = entries2.indexOf(entry);
|
|
8009
|
+
if (index !== -1) entries2.splice(index, 1);
|
|
7974
8010
|
}
|
|
7975
8011
|
};
|
|
7976
8012
|
}
|
|
@@ -7994,8 +8030,10 @@ function SModalContainer({
|
|
|
7994
8030
|
const contentRef = react.useRef(null);
|
|
7995
8031
|
const stackRegistrationRef = react.useRef(null);
|
|
7996
8032
|
const [layerIndex, setLayerIndex] = react.useState(null);
|
|
8033
|
+
const closeRequested = react.useRef(false);
|
|
7997
8034
|
react.useEffect(() => {
|
|
7998
8035
|
if (open) {
|
|
8036
|
+
closeRequested.current = false;
|
|
7999
8037
|
setRendered(true);
|
|
8000
8038
|
return;
|
|
8001
8039
|
}
|
|
@@ -8051,7 +8089,7 @@ function SModalContainer({
|
|
|
8051
8089
|
{
|
|
8052
8090
|
forceMount: rendered ? true : void 0,
|
|
8053
8091
|
ref: contentRef,
|
|
8054
|
-
className: "pointer-events-auto outline-none data-[state=open]:animate-modal-in data-[state=closed]:animate-modal-out",
|
|
8092
|
+
className: "pointer-events-auto outline-none data-[state=open]:animate-modal-in data-[state=closed]:pointer-events-none data-[state=closed]:animate-modal-out",
|
|
8055
8093
|
style: { animationFillMode: "forwards" },
|
|
8056
8094
|
onOpenAutoFocus: (e) => {
|
|
8057
8095
|
e.preventDefault();
|
|
@@ -8082,6 +8120,8 @@ function SModalContainer({
|
|
|
8082
8120
|
icon: "close",
|
|
8083
8121
|
ariaLabel: "\uB2EB\uAE30",
|
|
8084
8122
|
onClick: () => {
|
|
8123
|
+
if (closeRequested.current) return;
|
|
8124
|
+
closeRequested.current = true;
|
|
8085
8125
|
onClose?.();
|
|
8086
8126
|
onOpenChange?.(false);
|
|
8087
8127
|
},
|
|
@@ -8155,6 +8195,16 @@ function SConfirmModal({
|
|
|
8155
8195
|
}) {
|
|
8156
8196
|
const iconName = TYPE_ICON[type];
|
|
8157
8197
|
const mainStyle = MAIN_BUTTON_STYLE[mainButtonName ?? DEFAULT_MAIN_BUTTON[type]];
|
|
8198
|
+
const [settled, setSettled] = react.useState(false);
|
|
8199
|
+
react.useEffect(() => {
|
|
8200
|
+
if (open) setSettled(false);
|
|
8201
|
+
}, [open]);
|
|
8202
|
+
const settle = (emit3) => {
|
|
8203
|
+
if (settled) return;
|
|
8204
|
+
setSettled(true);
|
|
8205
|
+
emit3?.();
|
|
8206
|
+
onOpenChange?.(false);
|
|
8207
|
+
};
|
|
8158
8208
|
const tagNode = tagSlot ?? (tagLabel ? /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }) : null);
|
|
8159
8209
|
const optionNode = optionSlot ?? (slotLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: slotLabel }) : null);
|
|
8160
8210
|
const hasContentBox = tagNode != null || optionNode != null;
|
|
@@ -8167,7 +8217,7 @@ function SConfirmModal({
|
|
|
8167
8217
|
persistent,
|
|
8168
8218
|
ariaTitle: modalTitle,
|
|
8169
8219
|
showClose: true,
|
|
8170
|
-
onClose,
|
|
8220
|
+
onClose: () => settle(onClose),
|
|
8171
8221
|
className: "w-fit min-w-[min(520px,calc(100dvw-48px))]",
|
|
8172
8222
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-auto flex-col items-center gap-[40px] px-[32px] py-[40px]", children: [
|
|
8173
8223
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full min-h-0 flex-col items-center gap-[20px] overflow-y-auto", children: [
|
|
@@ -8217,10 +8267,8 @@ function SConfirmModal({
|
|
|
8217
8267
|
color: "neutral",
|
|
8218
8268
|
outline: true,
|
|
8219
8269
|
size: "md",
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
onOpenChange?.(false);
|
|
8223
|
-
},
|
|
8270
|
+
disabled: settled,
|
|
8271
|
+
onClick: () => settle(onCancel),
|
|
8224
8272
|
label: subButtonLabel
|
|
8225
8273
|
}
|
|
8226
8274
|
),
|
|
@@ -8229,10 +8277,8 @@ function SConfirmModal({
|
|
|
8229
8277
|
{
|
|
8230
8278
|
...mainStyle,
|
|
8231
8279
|
size: "md",
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
onOpenChange?.(false);
|
|
8235
|
-
},
|
|
8280
|
+
disabled: settled,
|
|
8281
|
+
onClick: () => settle(onOk),
|
|
8236
8282
|
label: mainButtonLabel
|
|
8237
8283
|
}
|
|
8238
8284
|
)
|
|
@@ -8475,10 +8521,10 @@ function SDrawer({
|
|
|
8475
8521
|
}, []);
|
|
8476
8522
|
react.useEffect(() => {
|
|
8477
8523
|
if (!rendered) return;
|
|
8478
|
-
const
|
|
8479
|
-
|
|
8480
|
-
window.addEventListener("resize",
|
|
8481
|
-
return () => window.removeEventListener("resize",
|
|
8524
|
+
const sync2 = () => setViewportWidth(window.innerWidth);
|
|
8525
|
+
sync2();
|
|
8526
|
+
window.addEventListener("resize", sync2);
|
|
8527
|
+
return () => window.removeEventListener("resize", sync2);
|
|
8482
8528
|
}, [rendered]);
|
|
8483
8529
|
react.useEffect(() => {
|
|
8484
8530
|
const panel2 = panelRef.current;
|
|
@@ -8724,7 +8770,7 @@ function SDrawer({
|
|
|
8724
8770
|
|
|
8725
8771
|
// src/lib/modal-outlet.ts
|
|
8726
8772
|
var EMPTY = [];
|
|
8727
|
-
var
|
|
8773
|
+
var entries3 = EMPTY;
|
|
8728
8774
|
var listeners2 = /* @__PURE__ */ new Set();
|
|
8729
8775
|
var outletRendered = false;
|
|
8730
8776
|
var outletCount = 0;
|
|
@@ -8739,7 +8785,7 @@ function subscribeModalEntries(listener) {
|
|
|
8739
8785
|
};
|
|
8740
8786
|
}
|
|
8741
8787
|
function getModalEntries() {
|
|
8742
|
-
return
|
|
8788
|
+
return entries3;
|
|
8743
8789
|
}
|
|
8744
8790
|
function getServerModalEntries() {
|
|
8745
8791
|
return EMPTY;
|
|
@@ -8758,9 +8804,9 @@ function registerModalOutlet() {
|
|
|
8758
8804
|
function sweepOrphans() {
|
|
8759
8805
|
if (outletCount > 0) return;
|
|
8760
8806
|
outletRendered = false;
|
|
8761
|
-
if (
|
|
8762
|
-
const orphans =
|
|
8763
|
-
|
|
8807
|
+
if (entries3 === EMPTY) return;
|
|
8808
|
+
const orphans = entries3;
|
|
8809
|
+
entries3 = EMPTY;
|
|
8764
8810
|
emit2();
|
|
8765
8811
|
for (const entry of orphans) entry.onOrphan();
|
|
8766
8812
|
}
|
|
@@ -8772,14 +8818,14 @@ function isModalOutletMounted() {
|
|
|
8772
8818
|
}
|
|
8773
8819
|
function addModalEntry(host, node, onOrphan) {
|
|
8774
8820
|
const id = ++nextId2;
|
|
8775
|
-
|
|
8821
|
+
entries3 = [...entries3, { id, host, node, onOrphan }];
|
|
8776
8822
|
emit2();
|
|
8777
8823
|
return id;
|
|
8778
8824
|
}
|
|
8779
8825
|
function removeModalEntry(id) {
|
|
8780
|
-
const next =
|
|
8781
|
-
if (next.length ===
|
|
8782
|
-
|
|
8826
|
+
const next = entries3.filter((entry) => entry.id !== id);
|
|
8827
|
+
if (next.length === entries3.length) return;
|
|
8828
|
+
entries3 = next;
|
|
8783
8829
|
emit2();
|
|
8784
8830
|
}
|
|
8785
8831
|
var EXIT_DURATION = 300;
|
|
@@ -8820,11 +8866,22 @@ var SModalRefImpl = class {
|
|
|
8820
8866
|
else this.pendingPatches.push(patch);
|
|
8821
8867
|
return this;
|
|
8822
8868
|
}
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8869
|
+
/**
|
|
8870
|
+
* 확정 콜백 1회 발화 — 이미 닫힘이 시작됐으면 무시한다. 발화했으면 true.
|
|
8871
|
+
*
|
|
8872
|
+
* 한 번 띄운 모달의 결말은 하나다(ok 이거나 cancel 이거나 close 다). 닫힘은 시작만 하고
|
|
8873
|
+
* 퇴장 애니메이션 동안 카드가 남아 있으므로, 그동안의 재클릭·키 반복이 두 번째 결말을
|
|
8874
|
+
* 만들지 않도록 여기서 막는다.
|
|
8875
|
+
*/
|
|
8876
|
+
settleEmit(emit3) {
|
|
8877
|
+
if (this.dismissRequested) return false;
|
|
8826
8878
|
this.dismissRequested = true;
|
|
8827
8879
|
emit3();
|
|
8880
|
+
return true;
|
|
8881
|
+
}
|
|
8882
|
+
// 닫힘 트리거 — 이미 닫힘이 시작됐으면 무시(중복 콜백 방지)
|
|
8883
|
+
settle(emit3) {
|
|
8884
|
+
if (!this.settleEmit(emit3)) return;
|
|
8828
8885
|
if (this.closeBinding) this.closeBinding();
|
|
8829
8886
|
else this.pendingClose = true;
|
|
8830
8887
|
}
|
|
@@ -8877,17 +8934,18 @@ var SModalRefImpl = class {
|
|
|
8877
8934
|
_markDismissed() {
|
|
8878
8935
|
this.dismissRequested = true;
|
|
8879
8936
|
}
|
|
8880
|
-
|
|
8937
|
+
// 아래 세 경로는 컴포넌트가 스스로 닫으므로(onOpenChange(false)) 발화 가드만 태운다.
|
|
8938
|
+
/** @internal confirm 버튼 경로에서 onOk 발화 (닫히는 중의 재클릭·키 반복은 무시) */
|
|
8881
8939
|
_emitOk() {
|
|
8882
|
-
this.okFn?.();
|
|
8940
|
+
this.settleEmit(() => this.okFn?.());
|
|
8883
8941
|
}
|
|
8884
|
-
/** @internal confirm 버튼 경로에서 onCancel 발화 */
|
|
8942
|
+
/** @internal confirm 버튼 경로에서 onCancel 발화 (닫히는 중의 재클릭·키 반복은 무시) */
|
|
8885
8943
|
_emitCancel() {
|
|
8886
|
-
this.cancelFn?.();
|
|
8944
|
+
this.settleEmit(() => this.cancelFn?.());
|
|
8887
8945
|
}
|
|
8888
|
-
/** @internal 닫기(X) 경로에서 onClose 발화 */
|
|
8946
|
+
/** @internal 닫기(X) 경로에서 onClose 발화 (닫히는 중의 재클릭·키 반복은 무시) */
|
|
8889
8947
|
_emitClose() {
|
|
8890
|
-
this.closeFn?.();
|
|
8948
|
+
this.settleEmit(() => this.closeFn?.());
|
|
8891
8949
|
}
|
|
8892
8950
|
/** @internal loading 버튼 경로에서 onClick 발화 */
|
|
8893
8951
|
_emitClick() {
|
|
@@ -9083,7 +9141,7 @@ function SModalEntryPortal({ entry }) {
|
|
|
9083
9141
|
}
|
|
9084
9142
|
function SModalOutlet() {
|
|
9085
9143
|
markModalOutletRendered();
|
|
9086
|
-
const
|
|
9144
|
+
const entries4 = react.useSyncExternalStore(
|
|
9087
9145
|
subscribeModalEntries,
|
|
9088
9146
|
getModalEntries,
|
|
9089
9147
|
getServerModalEntries
|
|
@@ -9096,7 +9154,7 @@ function SModalOutlet() {
|
|
|
9096
9154
|
}
|
|
9097
9155
|
return registerModalOutlet();
|
|
9098
9156
|
}, []);
|
|
9099
|
-
return /* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: null, children: /* @__PURE__ */ jsxRuntime.jsx(InsideModalProvider, { value: false, children:
|
|
9157
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: null, children: /* @__PURE__ */ jsxRuntime.jsx(InsideModalProvider, { value: false, children: entries4.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(SModalEntryPortal, { entry }, entry.id)) }) });
|
|
9100
9158
|
}
|
|
9101
9159
|
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
9102
9160
|
var SPageColumnContext = /* @__PURE__ */ react.createContext(null);
|
|
@@ -17870,10 +17928,10 @@ var useIsMobile = () => {
|
|
|
17870
17928
|
react.useEffect(() => {
|
|
17871
17929
|
if (typeof window.matchMedia !== "function") return;
|
|
17872
17930
|
const query = window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH - 1}px)`);
|
|
17873
|
-
const
|
|
17874
|
-
|
|
17875
|
-
query.addEventListener("change",
|
|
17876
|
-
return () => query.removeEventListener("change",
|
|
17931
|
+
const sync2 = () => setIsMobile(query.matches);
|
|
17932
|
+
sync2();
|
|
17933
|
+
query.addEventListener("change", sync2);
|
|
17934
|
+
return () => query.removeEventListener("change", sync2);
|
|
17877
17935
|
}, []);
|
|
17878
17936
|
return isMobile;
|
|
17879
17937
|
};
|
|
@@ -19373,9 +19431,9 @@ var keywordEntries = (value) => {
|
|
|
19373
19431
|
return [];
|
|
19374
19432
|
};
|
|
19375
19433
|
var CSV_PASTE_SEPARATOR = /[,\r\n\t]+/;
|
|
19376
|
-
var newKeywordEntries = (
|
|
19434
|
+
var newKeywordEntries = (entries4, candidates) => candidates.reduce((acc, raw) => {
|
|
19377
19435
|
const next = raw.trim();
|
|
19378
|
-
if (next === "" ||
|
|
19436
|
+
if (next === "" || entries4.includes(next) || acc.includes(next)) return acc;
|
|
19379
19437
|
return [...acc, next];
|
|
19380
19438
|
}, []);
|
|
19381
19439
|
var withKeywordEntries = (field, current, nextEntries) => field.matchModes ? { keywords: nextEntries, mode: isKeywordValue(current) ? current.mode : "contains" } : nextEntries;
|
|
@@ -19639,13 +19697,13 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
19639
19697
|
const field = fields.find((f) => f.key === key);
|
|
19640
19698
|
if (field == null || field.type !== "keyword" || disabled || field.disabled) return null;
|
|
19641
19699
|
const current = valuesRef.current[key];
|
|
19642
|
-
const
|
|
19700
|
+
const entries4 = keywordEntries(current);
|
|
19643
19701
|
const added = newKeywordEntries(
|
|
19644
|
-
|
|
19702
|
+
entries4,
|
|
19645
19703
|
field.input === "csv" ? draft.text.split(CSV_PASTE_SEPARATOR) : [draft.text]
|
|
19646
19704
|
);
|
|
19647
19705
|
if (added.length === 0) return null;
|
|
19648
|
-
const nextValue = withKeywordEntries(field, current, [...
|
|
19706
|
+
const nextValue = withKeywordEntries(field, current, [...entries4, ...added]);
|
|
19649
19707
|
const next = { ...valuesRef.current, [key]: nextValue };
|
|
19650
19708
|
onValueChange?.(next);
|
|
19651
19709
|
onFilterChange?.({ key, value: nextValue, values: next });
|
|
@@ -20666,7 +20724,7 @@ function KeywordEditor({
|
|
|
20666
20724
|
onValueCommit,
|
|
20667
20725
|
onDraftChange
|
|
20668
20726
|
}) {
|
|
20669
|
-
const
|
|
20727
|
+
const entries4 = keywordEntries(value);
|
|
20670
20728
|
const [draftText, setDraftText] = react.useState("");
|
|
20671
20729
|
const [mode, setMode] = react.useState(
|
|
20672
20730
|
isKeywordValue(value) ? value.mode : "contains"
|
|
@@ -20688,16 +20746,16 @@ function KeywordEditor({
|
|
|
20688
20746
|
};
|
|
20689
20747
|
const changeMode = (next) => {
|
|
20690
20748
|
setMode(next);
|
|
20691
|
-
emit3(
|
|
20749
|
+
emit3(entries4, next);
|
|
20692
20750
|
};
|
|
20693
|
-
const newEntries = (candidates) => newKeywordEntries(
|
|
20751
|
+
const newEntries = (candidates) => newKeywordEntries(entries4, candidates);
|
|
20694
20752
|
const addEntry = (raw) => {
|
|
20695
20753
|
const added = newEntries([raw]);
|
|
20696
20754
|
if (added.length === 0) {
|
|
20697
20755
|
setDraft("");
|
|
20698
20756
|
return;
|
|
20699
20757
|
}
|
|
20700
|
-
commit([...
|
|
20758
|
+
commit([...entries4, ...added]);
|
|
20701
20759
|
setDraft("");
|
|
20702
20760
|
};
|
|
20703
20761
|
const changeDraft = (next) => {
|
|
@@ -20708,7 +20766,7 @@ function KeywordEditor({
|
|
|
20708
20766
|
const parts = next.split(",");
|
|
20709
20767
|
const tail = parts.pop() ?? "";
|
|
20710
20768
|
const added = newEntries(parts);
|
|
20711
|
-
if (added.length > 0) commit([...
|
|
20769
|
+
if (added.length > 0) commit([...entries4, ...added]);
|
|
20712
20770
|
setDraft(tail);
|
|
20713
20771
|
};
|
|
20714
20772
|
const onPaste = (event) => {
|
|
@@ -20717,11 +20775,11 @@ function KeywordEditor({
|
|
|
20717
20775
|
if (!CSV_PASTE_SEPARATOR.test(text)) return;
|
|
20718
20776
|
event.preventDefault();
|
|
20719
20777
|
const added = newEntries((draftText + text).split(CSV_PASTE_SEPARATOR));
|
|
20720
|
-
if (added.length > 0) commit([...
|
|
20778
|
+
if (added.length > 0) commit([...entries4, ...added]);
|
|
20721
20779
|
setDraft("");
|
|
20722
20780
|
};
|
|
20723
20781
|
const removeEntry = (entry) => {
|
|
20724
|
-
emit3(
|
|
20782
|
+
emit3(entries4.filter((e) => e !== entry));
|
|
20725
20783
|
};
|
|
20726
20784
|
const onKeyDown = (event) => {
|
|
20727
20785
|
if (event.key === "Enter") {
|
|
@@ -20770,12 +20828,12 @@ function KeywordEditor({
|
|
|
20770
20828
|
)
|
|
20771
20829
|
] })
|
|
20772
20830
|
] }),
|
|
20773
|
-
|
|
20831
|
+
entries4.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20774
20832
|
"div",
|
|
20775
20833
|
{
|
|
20776
20834
|
className: "min-h-0 flex-1 overflow-auto border-t border-solid py-[var(--cmp-chipFilter-listbox-list-paddingY)]",
|
|
20777
20835
|
style: { borderColor: CHIPFILTER.listboxBorder },
|
|
20778
|
-
children:
|
|
20836
|
+
children: entries4.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
20779
20837
|
KeywordEntryRow,
|
|
20780
20838
|
{
|
|
20781
20839
|
label: optionLabel(field, entry),
|