@wipco/sdui 0.17.1 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-WVBU3SZM.js → chunk-J532YYGP.js} +79 -89
- package/dist/{chunk-J6OHRAPS.js → chunk-WXBOQRD6.js} +65 -75
- package/dist/chunk-XQPTSEJC.js +135 -0
- package/dist/{chunk-Q2EUB5UV.js → chunk-YJSOC5KM.js} +2 -5
- package/dist/index.d.ts +36 -1
- package/dist/index.js +5 -23
- package/dist/rich.js +3 -2
- package/dist/styles.css +10 -0
- package/dist/widgets/SearchableMultiPicker.js +2 -1
- package/dist/widgets/TreePicker.js +2 -1
- package/dist/widgets/index.js +5 -4
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveTreeNodes, TreeView } from './chunk-PYSTET2C.js';
|
|
2
|
+
import { OverlayLayer } from './chunk-XQPTSEJC.js';
|
|
2
3
|
import { Field, Dialog, Icon, Button, Input } from './chunk-WIDDHR7L.js';
|
|
3
4
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
4
5
|
import { useState, useMemo, useEffect } from 'react';
|
|
@@ -99,98 +100,87 @@ function TreePickerImpl({
|
|
|
99
100
|
return /* @__PURE__ */ jsxs("div", { className: "erp-treepicker", style: { minWidth: 0 }, children: [
|
|
100
101
|
/* @__PURE__ */ jsx("style", { children: PICKER_CSS }),
|
|
101
102
|
label ? /* @__PURE__ */ jsx(Field, { label, children: trigger }) : trigger,
|
|
102
|
-
open ? /* @__PURE__ */ jsx(
|
|
103
|
-
|
|
103
|
+
open ? /* @__PURE__ */ jsx(OverlayLayer, { onClose: closeDialog, children: /* @__PURE__ */ jsx(
|
|
104
|
+
Dialog,
|
|
104
105
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
borderRadius: "var(--wp-radius-sm)",
|
|
148
|
-
cursor: "pointer",
|
|
149
|
-
userSelect: "none"
|
|
150
|
-
},
|
|
151
|
-
onClick: () => setPendingId(null),
|
|
152
|
-
onKeyDown: (event) => {
|
|
153
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
154
|
-
event.preventDefault();
|
|
155
|
-
setPendingId(null);
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
children: [
|
|
159
|
-
/* @__PURE__ */ jsx(
|
|
160
|
-
Icon,
|
|
161
|
-
{
|
|
162
|
-
name: noneSelected ? "circle-dot" : "circle-x",
|
|
163
|
-
size: 16,
|
|
164
|
-
style: { flexShrink: 0, color: noneSelected ? "var(--wp-text-brand)" : "var(--wp-text-muted)" }
|
|
165
|
-
}
|
|
166
|
-
),
|
|
167
|
-
/* @__PURE__ */ jsx(
|
|
168
|
-
"span",
|
|
169
|
-
{
|
|
170
|
-
className: "wp-body-sm",
|
|
171
|
-
style: { color: noneSelected ? "var(--wp-text-strong)" : "var(--wp-text-muted)" },
|
|
172
|
-
children: "(\uC5C6\uC74C)"
|
|
173
|
-
}
|
|
174
|
-
)
|
|
175
|
-
]
|
|
176
|
-
}
|
|
177
|
-
) : null,
|
|
178
|
-
/* @__PURE__ */ jsx(
|
|
179
|
-
TreeView,
|
|
180
|
-
{
|
|
181
|
-
nodes: sourceNodes,
|
|
182
|
-
selectedId: pendingId,
|
|
183
|
-
onSelect: (id) => setPendingId(id),
|
|
184
|
-
searchable: true,
|
|
185
|
-
excludeIds,
|
|
186
|
-
maxHeight: "320px"
|
|
106
|
+
title: label ?? "\uD56D\uBAA9 \uC120\uD0DD",
|
|
107
|
+
subtitle: "\uD2B8\uB9AC\uC5D0\uC11C \uD56D\uBAA9\uC744 \uC120\uD0DD\uD55C \uB4A4 [\uC120\uD0DD]\uC744 \uB204\uB974\uC138\uC694.",
|
|
108
|
+
icon: "git-branch",
|
|
109
|
+
size: "md",
|
|
110
|
+
onClose: closeDialog,
|
|
111
|
+
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
112
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: closeDialog, children: "\uCDE8\uC18C" }),
|
|
113
|
+
/* @__PURE__ */ jsx(
|
|
114
|
+
Button,
|
|
115
|
+
{
|
|
116
|
+
variant: "primary",
|
|
117
|
+
onClick: commit,
|
|
118
|
+
disabled: commitDisabled,
|
|
119
|
+
title: commitDisabled ? "\uC120\uD0DD\uD560 \uD56D\uBAA9\uC744 \uC9C0\uC815\uD558\uC138\uC694" : void 0,
|
|
120
|
+
children: "\uC120\uD0DD"
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] }),
|
|
124
|
+
children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--wp-space-2)", minWidth: 0 }, children: [
|
|
125
|
+
allowEmpty ? /* @__PURE__ */ jsxs(
|
|
126
|
+
"div",
|
|
127
|
+
{
|
|
128
|
+
role: "radio",
|
|
129
|
+
"aria-checked": noneSelected,
|
|
130
|
+
"aria-current": noneSelected ? "true" : void 0,
|
|
131
|
+
tabIndex: 0,
|
|
132
|
+
className: "erp-treepicker__none",
|
|
133
|
+
style: {
|
|
134
|
+
display: "flex",
|
|
135
|
+
alignItems: "center",
|
|
136
|
+
gap: "var(--wp-space-2)",
|
|
137
|
+
minHeight: "var(--wp-row-h-dense)",
|
|
138
|
+
padding: "0 var(--wp-space-2)",
|
|
139
|
+
borderRadius: "var(--wp-radius-sm)",
|
|
140
|
+
cursor: "pointer",
|
|
141
|
+
userSelect: "none"
|
|
142
|
+
},
|
|
143
|
+
onClick: () => setPendingId(null),
|
|
144
|
+
onKeyDown: (event) => {
|
|
145
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
146
|
+
event.preventDefault();
|
|
147
|
+
setPendingId(null);
|
|
187
148
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
149
|
+
},
|
|
150
|
+
children: [
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
Icon,
|
|
153
|
+
{
|
|
154
|
+
name: noneSelected ? "circle-dot" : "circle-x",
|
|
155
|
+
size: 16,
|
|
156
|
+
style: { flexShrink: 0, color: noneSelected ? "var(--wp-text-brand)" : "var(--wp-text-muted)" }
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
/* @__PURE__ */ jsx(
|
|
160
|
+
"span",
|
|
161
|
+
{
|
|
162
|
+
className: "wp-body-sm",
|
|
163
|
+
style: { color: noneSelected ? "var(--wp-text-strong)" : "var(--wp-text-muted)" },
|
|
164
|
+
children: "(\uC5C6\uC74C)"
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
) : null,
|
|
170
|
+
/* @__PURE__ */ jsx(
|
|
171
|
+
TreeView,
|
|
172
|
+
{
|
|
173
|
+
nodes: sourceNodes,
|
|
174
|
+
selectedId: pendingId,
|
|
175
|
+
onSelect: (id) => setPendingId(id),
|
|
176
|
+
searchable: true,
|
|
177
|
+
excludeIds,
|
|
178
|
+
maxHeight: "320px"
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
] })
|
|
192
182
|
}
|
|
193
|
-
) : null
|
|
183
|
+
) }) : null
|
|
194
184
|
] });
|
|
195
185
|
}
|
|
196
186
|
var TreePicker = boxed(TreePickerImpl, "TreePicker");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OverlayLayer } from './chunk-XQPTSEJC.js';
|
|
1
2
|
import { includesLooseSearch } from './chunk-GZB6YLUI.js';
|
|
2
3
|
import { Button, Dialog, Input, Tag, Checkbox } from './chunk-WIDDHR7L.js';
|
|
3
4
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
@@ -102,85 +103,74 @@ function SearchableMultiPickerImpl({
|
|
|
102
103
|
}
|
|
103
104
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
104
105
|
triggerNode,
|
|
105
|
-
open ? /* @__PURE__ */ jsx(
|
|
106
|
-
|
|
106
|
+
open ? /* @__PURE__ */ jsx(OverlayLayer, { onClose: closeDialog, children: /* @__PURE__ */ jsx(
|
|
107
|
+
Dialog,
|
|
107
108
|
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
109
|
+
title: title ?? "\uD56D\uBAA9 \uC120\uD0DD",
|
|
110
|
+
subtitle: `\uC804\uCCB4 ${safeOptions.length}\uAC1C \uC911\uC5D0\uC11C \uC120\uD0DD`,
|
|
111
|
+
icon: "list-filter",
|
|
112
|
+
size: "md",
|
|
113
|
+
onClose: closeDialog,
|
|
114
|
+
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
115
|
+
/* @__PURE__ */ jsx("div", { style: { marginRight: "auto" }, children: /* @__PURE__ */ jsx(
|
|
116
|
+
Button,
|
|
117
|
+
{
|
|
118
|
+
type: "button",
|
|
119
|
+
variant: "ghost",
|
|
120
|
+
size: "sm",
|
|
121
|
+
icon: "rotate-ccw",
|
|
122
|
+
disabled: draft.length === 0,
|
|
123
|
+
onClick: () => setDraft([]),
|
|
124
|
+
children: "\uC804\uCCB4 \uD574\uC81C"
|
|
125
|
+
}
|
|
126
|
+
) }),
|
|
127
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: commit, children: "\uC644\uB8CC" })
|
|
128
|
+
] }),
|
|
129
|
+
children: /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-3)" }, children: [
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
Input,
|
|
132
|
+
{
|
|
133
|
+
icon: "search",
|
|
134
|
+
placeholder: "\uC774\uB984\xB7\uC124\uBA85\uC73C\uB85C \uAC80\uC0C9",
|
|
135
|
+
autoFocus: true,
|
|
136
|
+
value: query,
|
|
137
|
+
onChange: (event) => setQuery(event.target.value)
|
|
138
|
+
}
|
|
139
|
+
),
|
|
140
|
+
/* @__PURE__ */ jsxs("div", { className: "wp-row", style: { flexWrap: "wrap", gap: "var(--wp-space-1)" }, children: [
|
|
141
|
+
/* @__PURE__ */ jsxs("span", { className: "wp-caption", style: { flex: "none" }, children: [
|
|
142
|
+
"\uC120\uD0DD ",
|
|
143
|
+
draft.length,
|
|
144
|
+
"\uAC1C"
|
|
136
145
|
] }),
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
146
|
+
draftChips.map((chip) => /* @__PURE__ */ jsx(Tag, { onRemove: () => toggle(chip.value, false), children: chip.label }, chip.value))
|
|
147
|
+
] }),
|
|
148
|
+
/* @__PURE__ */ jsx(
|
|
149
|
+
"div",
|
|
150
|
+
{
|
|
151
|
+
className: "wp-col",
|
|
152
|
+
style: {
|
|
153
|
+
maxHeight: 320,
|
|
154
|
+
overflowY: "auto",
|
|
155
|
+
gap: "var(--wp-space-1)",
|
|
156
|
+
borderTop: "var(--wp-border-w) solid var(--wp-divider)",
|
|
157
|
+
paddingTop: "var(--wp-space-2)"
|
|
158
|
+
},
|
|
159
|
+
children: visibleOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "wp-caption", style: { padding: "var(--wp-space-2) 0" }, children: "\uACB0\uACFC \uC5C6\uC74C" }) : visibleOptions.map((option) => /* @__PURE__ */ jsx(
|
|
160
|
+
Checkbox,
|
|
140
161
|
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
draft.length,
|
|
152
|
-
"\uAC1C"
|
|
153
|
-
] }),
|
|
154
|
-
draftChips.map((chip) => /* @__PURE__ */ jsx(Tag, { onRemove: () => toggle(chip.value, false), children: chip.label }, chip.value))
|
|
155
|
-
] }),
|
|
156
|
-
/* @__PURE__ */ jsx(
|
|
157
|
-
"div",
|
|
158
|
-
{
|
|
159
|
-
className: "wp-col",
|
|
160
|
-
style: {
|
|
161
|
-
maxHeight: 320,
|
|
162
|
-
overflowY: "auto",
|
|
163
|
-
gap: "var(--wp-space-1)",
|
|
164
|
-
borderTop: "var(--wp-border-w) solid var(--wp-divider)",
|
|
165
|
-
paddingTop: "var(--wp-space-2)"
|
|
166
|
-
},
|
|
167
|
-
children: visibleOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "wp-caption", style: { padding: "var(--wp-space-2) 0" }, children: "\uACB0\uACFC \uC5C6\uC74C" }) : visibleOptions.map((option) => /* @__PURE__ */ jsx(
|
|
168
|
-
Checkbox,
|
|
169
|
-
{
|
|
170
|
-
label: option.label,
|
|
171
|
-
description: option.sub,
|
|
172
|
-
checked: draft.includes(option.value),
|
|
173
|
-
onChange: (event) => toggle(option.value, event.target.checked)
|
|
174
|
-
},
|
|
175
|
-
option.value
|
|
176
|
-
))
|
|
177
|
-
}
|
|
178
|
-
)
|
|
179
|
-
] })
|
|
180
|
-
}
|
|
181
|
-
)
|
|
162
|
+
label: option.label,
|
|
163
|
+
description: option.sub,
|
|
164
|
+
checked: draft.includes(option.value),
|
|
165
|
+
onChange: (event) => toggle(option.value, event.target.checked)
|
|
166
|
+
},
|
|
167
|
+
option.value
|
|
168
|
+
))
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] })
|
|
182
172
|
}
|
|
183
|
-
) : null
|
|
173
|
+
) }) : null
|
|
184
174
|
] });
|
|
185
175
|
}
|
|
186
176
|
var SearchableMultiPicker = boxed(SearchableMultiPickerImpl, "SearchableMultiPicker");
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import React, { useRef, useEffect, useSyncExternalStore } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/overlay.tsx
|
|
6
|
+
var OVERLAY_ROOT_ID = "wp-overlay-root";
|
|
7
|
+
var DOCUMENT_POSITION_FOLLOWING = 4;
|
|
8
|
+
function getOverlayRoot() {
|
|
9
|
+
if (typeof document === "undefined") return null;
|
|
10
|
+
const existing = document.getElementById(OVERLAY_ROOT_ID);
|
|
11
|
+
if (existing) return existing;
|
|
12
|
+
const created = document.createElement("div");
|
|
13
|
+
created.id = OVERLAY_ROOT_ID;
|
|
14
|
+
document.body.appendChild(created);
|
|
15
|
+
return created;
|
|
16
|
+
}
|
|
17
|
+
var layers = [];
|
|
18
|
+
var nextId = 0;
|
|
19
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
20
|
+
var keyListenerBound = false;
|
|
21
|
+
function emit() {
|
|
22
|
+
layers = layers.slice();
|
|
23
|
+
subscribers.forEach((fn) => fn());
|
|
24
|
+
}
|
|
25
|
+
function topLayer(list) {
|
|
26
|
+
let best;
|
|
27
|
+
let bestNode = null;
|
|
28
|
+
for (const layer of list) {
|
|
29
|
+
const node = layer.node();
|
|
30
|
+
if (!best) {
|
|
31
|
+
best = layer;
|
|
32
|
+
bestNode = node;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (!node) continue;
|
|
36
|
+
if (!bestNode) {
|
|
37
|
+
best = layer;
|
|
38
|
+
bestNode = node;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (bestNode.compareDocumentPosition(node) & DOCUMENT_POSITION_FOLLOWING) {
|
|
42
|
+
best = layer;
|
|
43
|
+
bestNode = node;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return best;
|
|
47
|
+
}
|
|
48
|
+
function layerHoldsTop(list, id) {
|
|
49
|
+
const top = topLayer(list);
|
|
50
|
+
if (!top) return false;
|
|
51
|
+
if (top.id === id) return true;
|
|
52
|
+
const mine = list.find((l) => l.id === id)?.node();
|
|
53
|
+
const topNode = top.node();
|
|
54
|
+
return !!mine && !!topNode && mine.contains(topNode);
|
|
55
|
+
}
|
|
56
|
+
function escapeTopmost() {
|
|
57
|
+
topLayer(layers)?.onEscape();
|
|
58
|
+
}
|
|
59
|
+
function handleKeyDown(event) {
|
|
60
|
+
if (event.key !== "Escape") return;
|
|
61
|
+
escapeTopmost();
|
|
62
|
+
}
|
|
63
|
+
function push(layer) {
|
|
64
|
+
layers.push(layer);
|
|
65
|
+
if (!keyListenerBound && typeof document !== "undefined") {
|
|
66
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
67
|
+
keyListenerBound = true;
|
|
68
|
+
}
|
|
69
|
+
emit();
|
|
70
|
+
}
|
|
71
|
+
function remove(id) {
|
|
72
|
+
layers = layers.filter((l) => l.id !== id);
|
|
73
|
+
emit();
|
|
74
|
+
}
|
|
75
|
+
function subscribe(fn) {
|
|
76
|
+
subscribers.add(fn);
|
|
77
|
+
return () => {
|
|
78
|
+
subscribers.delete(fn);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
var snapshot = () => layers;
|
|
82
|
+
var serverSnapshot = () => [];
|
|
83
|
+
function useOverlayLayer(active, onEscape, nodeRef) {
|
|
84
|
+
const idRef = useRef(0);
|
|
85
|
+
if (idRef.current === 0) idRef.current = ++nextId;
|
|
86
|
+
const escapeRef = useRef(onEscape);
|
|
87
|
+
escapeRef.current = onEscape;
|
|
88
|
+
const nodeRefRef = useRef(nodeRef);
|
|
89
|
+
nodeRefRef.current = nodeRef;
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (!active) return;
|
|
92
|
+
const id2 = idRef.current;
|
|
93
|
+
push({
|
|
94
|
+
id: id2,
|
|
95
|
+
onEscape: () => escapeRef.current?.(),
|
|
96
|
+
node: () => nodeRefRef.current?.current ?? null
|
|
97
|
+
});
|
|
98
|
+
return () => remove(id2);
|
|
99
|
+
}, [active]);
|
|
100
|
+
const current = useSyncExternalStore(subscribe, snapshot, serverSnapshot);
|
|
101
|
+
const id = idRef.current;
|
|
102
|
+
return {
|
|
103
|
+
isTop: active && topLayer(current)?.id === id,
|
|
104
|
+
holdsTop: active && layerHoldsTop(current, id)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
var OverlayContainerContext = React.createContext(null);
|
|
108
|
+
function OverlayLayer({
|
|
109
|
+
onClose,
|
|
110
|
+
children
|
|
111
|
+
}) {
|
|
112
|
+
const ref = useRef(null);
|
|
113
|
+
const container = React.useContext(OverlayContainerContext);
|
|
114
|
+
const { holdsTop } = useOverlayLayer(true, onClose, ref);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
ref.current?.toggleAttribute("inert", !holdsTop);
|
|
117
|
+
}, [holdsTop]);
|
|
118
|
+
const layer = /* @__PURE__ */ jsx(
|
|
119
|
+
"div",
|
|
120
|
+
{
|
|
121
|
+
ref,
|
|
122
|
+
className: "wp-overlay-layer",
|
|
123
|
+
onClick: (event) => {
|
|
124
|
+
if (onClose && event.target instanceof HTMLElement && event.target.classList.contains("wp-overlay")) {
|
|
125
|
+
onClose();
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
children
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
const root = container ?? getOverlayRoot();
|
|
132
|
+
return root ? createPortal(layer, root) : layer;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { OverlayContainerContext, OverlayLayer, getOverlayRoot, useOverlayLayer };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useOverlayLayer } from './chunk-XQPTSEJC.js';
|
|
1
2
|
import { Icon } from './chunk-WIDDHR7L.js';
|
|
2
3
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
4
|
import { createContext, useState, useRef, useMemo, useCallback, useEffect, useLayoutEffect, useContext } from 'react';
|
|
@@ -281,16 +282,12 @@ function useDismiss(open, hostRef, onDismiss) {
|
|
|
281
282
|
if (event.target instanceof Node && hostRef.current?.contains(event.target)) return;
|
|
282
283
|
onDismiss("outside");
|
|
283
284
|
};
|
|
284
|
-
const handleKeyDown = (event) => {
|
|
285
|
-
if (event.key === "Escape") onDismiss("escape");
|
|
286
|
-
};
|
|
287
285
|
document.addEventListener("pointerdown", handlePointerDown);
|
|
288
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
289
286
|
return () => {
|
|
290
287
|
document.removeEventListener("pointerdown", handlePointerDown);
|
|
291
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
292
288
|
};
|
|
293
289
|
}, [open, hostRef, onDismiss]);
|
|
290
|
+
useOverlayLayer(open, () => onDismiss("escape"), hostRef);
|
|
294
291
|
}
|
|
295
292
|
function triggerClassName(size, invalid) {
|
|
296
293
|
const classes = ["wp-input", "wp-dp-trigger"];
|
package/dist/index.d.ts
CHANGED
|
@@ -1361,6 +1361,9 @@ declare function Divider({ style, className }: SduiBoxProps): React__default.JSX
|
|
|
1361
1361
|
|
|
1362
1362
|
/**
|
|
1363
1363
|
* Dialog + 표준 닫기 UX(Escape·배경 클릭). 레지스트리의 "Dialog"는 이 래퍼다.
|
|
1364
|
+
*
|
|
1365
|
+
* 겹침 처리는 전부 OverlayLayer가 맡는다 — 단일 오버레이 루트로 포털해 조상
|
|
1366
|
+
* CSS에 휘둘리지 않고, Escape는 맨 위 한 겹만 닫는다(overlay.tsx 주석 참고).
|
|
1364
1367
|
*/
|
|
1365
1368
|
declare function SduiDialog(props: DialogProps): React.JSX.Element;
|
|
1366
1369
|
|
|
@@ -1746,6 +1749,38 @@ declare function useSduiRuntime(): SduiRuntime;
|
|
|
1746
1749
|
|
|
1747
1750
|
declare function boxed<P extends object>(Inner: React__default.ComponentType<P>, displayName?: string): React__default.FC<P & SduiBoxProps>;
|
|
1748
1751
|
|
|
1752
|
+
/** 모달이 사는 단일 컨테이너. 없으면 만든다(비어 있으면 CSS가 display:none). */
|
|
1753
|
+
declare function getOverlayRoot(): HTMLElement | null;
|
|
1754
|
+
/**
|
|
1755
|
+
* 이 겹이 스택에 있는 동안 Escape를 받을 자격을 관리한다.
|
|
1756
|
+
* `active`가 참인 동안만 스택에 오르고, **맨 위일 때만** `onEscape`가 불린다.
|
|
1757
|
+
*
|
|
1758
|
+
* 포털을 쓰지 않는 팝오버(DatePicker)도 이 훅만 쓰면 순서가 맞는다.
|
|
1759
|
+
* `nodeRef`를 주면 문서 순서 판정에 쓰고, 없으면 등록 순서로 떨어진다.
|
|
1760
|
+
*/
|
|
1761
|
+
declare function useOverlayLayer(active: boolean, onEscape?: () => void, nodeRef?: React__default.RefObject<HTMLElement | null>): {
|
|
1762
|
+
isTop: boolean;
|
|
1763
|
+
holdsTop: boolean;
|
|
1764
|
+
};
|
|
1765
|
+
/**
|
|
1766
|
+
* 겹을 담을 곳을 바꾼다. 기본은 body 밑 단일 루트지만, **화면 일부에 페이지를
|
|
1767
|
+
* 그려 보이는 곳**(편집기 미리보기·뷰어)은 자기 상자를 지정해야 한다 — 안 그러면
|
|
1768
|
+
* 미리본 다이얼로그의 오버레이가 편집기 전체를 덮는다(0.17.1에서 겪은 그 문제).
|
|
1769
|
+
* 그 상자에 `contain: paint`가 걸려 있으면 오버레이는 상자 안에 갇힌다.
|
|
1770
|
+
*/
|
|
1771
|
+
declare const OverlayContainerContext: React__default.Context<HTMLElement | null>;
|
|
1772
|
+
/**
|
|
1773
|
+
* 모달 한 겹. 자식(보통 `<Dialog>`)을 단일 오버레이 루트로 포털한다.
|
|
1774
|
+
*
|
|
1775
|
+
* - 배경(.wp-overlay) 클릭 시 닫기 — 내용 클릭은 무시한다
|
|
1776
|
+
* - Escape는 맨 위 겹에서만 먹는다
|
|
1777
|
+
* - 아래 겹은 `inert`로 잠근다 — 탭·클릭이 가려진 창으로 새지 않게
|
|
1778
|
+
*/
|
|
1779
|
+
declare function OverlayLayer({ onClose, children, }: {
|
|
1780
|
+
onClose?: () => void;
|
|
1781
|
+
children: React__default.ReactNode;
|
|
1782
|
+
}): React__default.ReactElement | null;
|
|
1783
|
+
|
|
1749
1784
|
interface Props {
|
|
1750
1785
|
name: string;
|
|
1751
1786
|
children: React__default.ReactNode;
|
|
@@ -1795,4 +1830,4 @@ interface ImageViewerProps {
|
|
|
1795
1830
|
*/
|
|
1796
1831
|
declare function ImageViewer({ src, alt, open, onClose }: ImageViewerProps): React__default.ReactPortal | null;
|
|
1797
1832
|
|
|
1798
|
-
export { Actions, type ActionsProps, Alert, type AlertProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeTone, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Can, type CanProps, Card, type CardProps, type CascadingSearchOption, Checkbox, type CheckboxProps, Col, type ColProps, type CustomActionHandler, type CustomValidator, DatePickerProps, DateRangePickerProps, Dialog, type DialogProps, Divider, EmptyState, type EmptyStateProps, Field, type FieldProps, Grid, type GridCardConfig, type GridCardRow, type GridProps, Icon, IconButton, type IconButtonProps, type IconProps, ImageViewer, type ImageViewerProps, Input, type InputProps, type Justify, type KeyValueItem, KeyValueList, type KeyValueListProps, type MeterTone, NodeErrorBoundary, PageHead, type PageHeadProps, Pagination, type PaginationProps, ProgressBar, type ProgressBarProps, Radio, type RadioProps, RemoteSearchResults, type RemoteSearchResultsProps, ResultTable, type ResultTableColumn, type ResultTableProps, Row, type RowProps, SduiAction, type SduiAdapter, type SduiAssetContext, type SduiAssetResolver, type SduiBadgeCell, SduiBoxProps, type SduiCanFn, type SduiCanQuery, type SduiCanSetting, type SduiCell, SduiColumnsScale, SduiContainerLayoutProps, type SduiDateCell, SduiDialog, type SduiDispatch, SduiForm, type SduiFormConfig, type SduiFormProps, SduiGapScale, type SduiGridCard, type SduiGridCardAction, type SduiGridCardRow, type SduiIconCell, type SduiImageCell, type SduiLinkCell, type SduiNumberCell, SduiPage, SduiPermissionProvider, type SduiProgressCell, SduiPropValue, type SduiRegistry, SduiRenderer, type SduiRendererProps, type SduiRowCondition, SduiRule, type SduiRuntime, type SduiSearchAction, type SduiSearchColumn, SduiSearchDataProvider, SduiSearchResults, type SduiSearchResultsProps, type SduiTagCell, SduiTextAlignScale, type SduiTextCell, type SduiUseSpec, SduiWeightScale, type SearchAction, type SearchColumn, type SearchFetcher, type SearchField, type SearchFilter, type SearchOption, type SearchPage, SearchResults, type SearchResultsProps, type SearchRow, SearchToolbar, type SearchValues, type SearchViewItem, Section, type SectionProps, SegmentedControl, type SegmentedControlProps, type SegmentedItem, Select, type SelectOption, type SelectOptionRecord, type SelectProps, Show, type ShowProps, SidebarNav, type SidebarNavItem, type SidebarNavProps, type SidebarNavSection, type SortDir, SortHandle, type SortHandleProps, SortableList, type SortableListProps, Spacer, type SpacerProps, type SpecIssue, Spinner, type SpinnerProps, StatCard, type StatCardProps, Switch, type SwitchProps, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Tag, type TagProps, Text, type TextPreset, type TextProps, Textarea, type TextareaProps, Toast, type ToastProps, Tooltip, type TooltipProps, boxed, cascadingValuePaths, cellRenderer, cleanSearchValues, createRegistry, defaultAdapter, defaultRegistry, imageRenderer, includesLooseSearch, joinMultiValue, normalizePageSizes, normalizeSearchText, searchFieldKeys, searchValuesFromParams, sortableDropIndex, sortableMove, splitMultiValue, useRemoteSearchPage, useSduiAssetResolver, useSduiCan, useSduiDispatch, useSduiRuntime, useSduiSandbox, useSearchFetcher, validateSpec };
|
|
1833
|
+
export { Actions, type ActionsProps, Alert, type AlertProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeTone, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Can, type CanProps, Card, type CardProps, type CascadingSearchOption, Checkbox, type CheckboxProps, Col, type ColProps, type CustomActionHandler, type CustomValidator, DatePickerProps, DateRangePickerProps, Dialog, type DialogProps, Divider, EmptyState, type EmptyStateProps, Field, type FieldProps, Grid, type GridCardConfig, type GridCardRow, type GridProps, Icon, IconButton, type IconButtonProps, type IconProps, ImageViewer, type ImageViewerProps, Input, type InputProps, type Justify, type KeyValueItem, KeyValueList, type KeyValueListProps, type MeterTone, NodeErrorBoundary, OverlayContainerContext, OverlayLayer, PageHead, type PageHeadProps, Pagination, type PaginationProps, ProgressBar, type ProgressBarProps, Radio, type RadioProps, RemoteSearchResults, type RemoteSearchResultsProps, ResultTable, type ResultTableColumn, type ResultTableProps, Row, type RowProps, SduiAction, type SduiAdapter, type SduiAssetContext, type SduiAssetResolver, type SduiBadgeCell, SduiBoxProps, type SduiCanFn, type SduiCanQuery, type SduiCanSetting, type SduiCell, SduiColumnsScale, SduiContainerLayoutProps, type SduiDateCell, SduiDialog, type SduiDispatch, SduiForm, type SduiFormConfig, type SduiFormProps, SduiGapScale, type SduiGridCard, type SduiGridCardAction, type SduiGridCardRow, type SduiIconCell, type SduiImageCell, type SduiLinkCell, type SduiNumberCell, SduiPage, SduiPermissionProvider, type SduiProgressCell, SduiPropValue, type SduiRegistry, SduiRenderer, type SduiRendererProps, type SduiRowCondition, SduiRule, type SduiRuntime, type SduiSearchAction, type SduiSearchColumn, SduiSearchDataProvider, SduiSearchResults, type SduiSearchResultsProps, type SduiTagCell, SduiTextAlignScale, type SduiTextCell, type SduiUseSpec, SduiWeightScale, type SearchAction, type SearchColumn, type SearchFetcher, type SearchField, type SearchFilter, type SearchOption, type SearchPage, SearchResults, type SearchResultsProps, type SearchRow, SearchToolbar, type SearchValues, type SearchViewItem, Section, type SectionProps, SegmentedControl, type SegmentedControlProps, type SegmentedItem, Select, type SelectOption, type SelectOptionRecord, type SelectProps, Show, type ShowProps, SidebarNav, type SidebarNavItem, type SidebarNavProps, type SidebarNavSection, type SortDir, SortHandle, type SortHandleProps, SortableList, type SortableListProps, Spacer, type SpacerProps, type SpecIssue, Spinner, type SpinnerProps, StatCard, type StatCardProps, Switch, type SwitchProps, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Tag, type TagProps, Text, type TextPreset, type TextProps, Textarea, type TextareaProps, Toast, type ToastProps, Tooltip, type TooltipProps, boxed, cascadingValuePaths, cellRenderer, cleanSearchValues, createRegistry, defaultAdapter, defaultRegistry, getOverlayRoot, imageRenderer, includesLooseSearch, joinMultiValue, normalizePageSizes, normalizeSearchText, searchFieldKeys, searchValuesFromParams, sortableDropIndex, sortableMove, splitMultiValue, useOverlayLayer, useRemoteSearchPage, useSduiAssetResolver, useSduiCan, useSduiDispatch, useSduiRuntime, useSduiSandbox, useSearchFetcher, validateSpec };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { DEV, HoistedStyle, isSafeNavigationTarget, useSduiAdapter, hostFetchOf, DateRangePicker, DatePicker, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-
|
|
2
|
-
export { DatePicker, DateRangePicker, defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-
|
|
1
|
+
import { DEV, HoistedStyle, isSafeNavigationTarget, useSduiAdapter, hostFetchOf, DateRangePicker, DatePicker, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-YJSOC5KM.js';
|
|
2
|
+
export { DatePicker, DateRangePicker, defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-YJSOC5KM.js';
|
|
3
3
|
import { ImageViewer } from './chunk-THEP3VWY.js';
|
|
4
4
|
export { ImageViewer } from './chunk-THEP3VWY.js';
|
|
5
|
+
import { OverlayLayer } from './chunk-XQPTSEJC.js';
|
|
6
|
+
export { OverlayContainerContext, OverlayLayer, getOverlayRoot, useOverlayLayer } from './chunk-XQPTSEJC.js';
|
|
5
7
|
import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-GZB6YLUI.js';
|
|
6
8
|
export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-GZB6YLUI.js';
|
|
7
9
|
import { EmptyState, Button, Checkbox, SegmentedControl, Spinner, Select, Pagination, Icon, Card, Badge, ProgressBar, Tag, Toast, Textarea, Tabs, Table, Switch, StatCard, Input, IconButton, Field, Alert, warnOnce, Dialog } from './chunk-WIDDHR7L.js';
|
|
@@ -1356,27 +1358,7 @@ function RemoteSearchResultsImpl({
|
|
|
1356
1358
|
var SduiSearchResults = boxed(SduiSearchResultsImpl, "SduiSearchResults");
|
|
1357
1359
|
var RemoteSearchResults = boxed(RemoteSearchResultsImpl, "RemoteSearchResults");
|
|
1358
1360
|
function SduiDialog(props) {
|
|
1359
|
-
|
|
1360
|
-
useEffect(() => {
|
|
1361
|
-
if (!onClose) return;
|
|
1362
|
-
const onKeyDown = (event) => {
|
|
1363
|
-
if (event.key === "Escape") onClose();
|
|
1364
|
-
};
|
|
1365
|
-
document.addEventListener("keydown", onKeyDown);
|
|
1366
|
-
return () => document.removeEventListener("keydown", onKeyDown);
|
|
1367
|
-
}, [onClose]);
|
|
1368
|
-
return /* @__PURE__ */ jsx(
|
|
1369
|
-
"div",
|
|
1370
|
-
{
|
|
1371
|
-
style: { position: "fixed", inset: 0, zIndex: "var(--wp-z-dialog)" },
|
|
1372
|
-
onClick: (event) => {
|
|
1373
|
-
if (onClose && event.target instanceof HTMLElement && event.target.classList.contains("wp-overlay")) {
|
|
1374
|
-
onClose();
|
|
1375
|
-
}
|
|
1376
|
-
},
|
|
1377
|
-
children: /* @__PURE__ */ jsx(Dialog, { ...props })
|
|
1378
|
-
}
|
|
1379
|
-
);
|
|
1361
|
+
return /* @__PURE__ */ jsx(OverlayLayer, { onClose: props.onClose, children: /* @__PURE__ */ jsx(Dialog, { ...props }) });
|
|
1380
1362
|
}
|
|
1381
1363
|
var SduiRuntimeContext = createContext(null);
|
|
1382
1364
|
function useSduiRuntime() {
|
package/dist/rich.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useSduiAssetResolver, HoistedStyle } from './chunk-
|
|
2
|
-
export { DatePicker, DateRangePicker } from './chunk-
|
|
1
|
+
import { useSduiAssetResolver, HoistedStyle } from './chunk-YJSOC5KM.js';
|
|
2
|
+
export { DatePicker, DateRangePicker } from './chunk-YJSOC5KM.js';
|
|
3
|
+
import './chunk-XQPTSEJC.js';
|
|
3
4
|
import { Spinner, EmptyState } from './chunk-WIDDHR7L.js';
|
|
4
5
|
import './chunk-SAN4IX6N.js';
|
|
5
6
|
import { useRef, useCallback, useMemo, useState, useEffect, useLayoutEffect } from 'react';
|
package/dist/styles.css
CHANGED
|
@@ -794,6 +794,16 @@
|
|
|
794
794
|
.wp-pager__gap { color: var(--wp-text-subtle); padding: 0 4px; }
|
|
795
795
|
|
|
796
796
|
/* ---------- 다이얼로그 ---------- */
|
|
797
|
+
/* 겹쳐 뜨는 것들이 모이는 단일 컨테이너(overlay.tsx가 body에 만든다).
|
|
798
|
+
비어 있으면 아예 없는 것처럼 굴어야 페이지가 평소대로 보인다 — :empty로 끄고,
|
|
799
|
+
떠 있을 때도 pointer-events는 겹(.wp-overlay-layer)에서만 살린다.
|
|
800
|
+
z-index는 여기 한 번만 건다. 겹끼리는 문서 순서대로 쌓인다(나중 것이 위). */
|
|
801
|
+
#wp-overlay-root {
|
|
802
|
+
position: fixed; inset: 0; z-index: var(--wp-z-dialog); pointer-events: none;
|
|
803
|
+
}
|
|
804
|
+
#wp-overlay-root:empty { display: none; }
|
|
805
|
+
.wp-overlay-layer { position: fixed; inset: 0; pointer-events: auto; }
|
|
806
|
+
|
|
797
807
|
.wp-overlay {
|
|
798
808
|
position: absolute; inset: 0; background: var(--wp-surface-overlay);
|
|
799
809
|
display: flex; align-items: flex-start; justify-content: center;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { TreePicker } from '../chunk-
|
|
1
|
+
export { TreePicker } from '../chunk-J532YYGP.js';
|
|
2
2
|
import '../chunk-PYSTET2C.js';
|
|
3
|
+
import '../chunk-XQPTSEJC.js';
|
|
3
4
|
import '../chunk-GZB6YLUI.js';
|
|
4
5
|
import '../chunk-WIDDHR7L.js';
|
|
5
6
|
import '../chunk-SAN4IX6N.js';
|
package/dist/widgets/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SearchableMultiPicker } from '../chunk-
|
|
2
|
-
export { SearchableMultiPicker } from '../chunk-
|
|
1
|
+
import { SearchableMultiPicker } from '../chunk-WXBOQRD6.js';
|
|
2
|
+
export { SearchableMultiPicker } from '../chunk-WXBOQRD6.js';
|
|
3
3
|
import { SecureScreen } from '../chunk-IIRENCDS.js';
|
|
4
4
|
export { SecureScreen } from '../chunk-IIRENCDS.js';
|
|
5
5
|
import { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
@@ -12,8 +12,8 @@ import { TagMultiSelect } from '../chunk-QDEZXA34.js';
|
|
|
12
12
|
export { TagMultiSelect } from '../chunk-QDEZXA34.js';
|
|
13
13
|
import { Timeline } from '../chunk-EFYEOT47.js';
|
|
14
14
|
export { Timeline } from '../chunk-EFYEOT47.js';
|
|
15
|
-
import { TreePicker } from '../chunk-
|
|
16
|
-
export { TreePicker } from '../chunk-
|
|
15
|
+
import { TreePicker } from '../chunk-J532YYGP.js';
|
|
16
|
+
export { TreePicker } from '../chunk-J532YYGP.js';
|
|
17
17
|
import { TreeView } from '../chunk-PYSTET2C.js';
|
|
18
18
|
export { TreeView, buildTreeNodes } from '../chunk-PYSTET2C.js';
|
|
19
19
|
import { EventCalendar } from '../chunk-C3JY6GA3.js';
|
|
@@ -33,6 +33,7 @@ export { PeriodFilter } from '../chunk-M3TDEPD2.js';
|
|
|
33
33
|
import { PrintSheet } from '../chunk-MYJ2KEIP.js';
|
|
34
34
|
export { PrintSheet } from '../chunk-MYJ2KEIP.js';
|
|
35
35
|
import '../chunk-THEP3VWY.js';
|
|
36
|
+
import '../chunk-XQPTSEJC.js';
|
|
36
37
|
export { AutocompleteField, toAutocompleteOptions } from '../chunk-3MS4UWWZ.js';
|
|
37
38
|
import '../chunk-GZB6YLUI.js';
|
|
38
39
|
import { ColumnBoard } from '../chunk-C4JRSZGS.js';
|