@wipco/sdui-editor 0.6.0 → 0.8.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.
Files changed (2) hide show
  1. package/dist/index.js +94 -17
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2991,17 +2991,48 @@ var CSS = `
2991
2991
  * \uBAA8\uB2EC\uC744 \uD750\uB984 \uC548\uC73C\uB85C \uB418\uB3CC\uB9B0\uB2E4.
2992
2992
  * \uCE94\uBC84\uC2A4 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB294 SduiDialog(\uC778\uB77C\uC778 position:fixed) \uB300\uC2E0 \uC54C\uB9F9\uC774 Dialog\uB97C \uC4F0\uBBC0\uB85C
2993
2993
  * \uB0A8\uB294 \uAC83\uC740 \uD074\uB798\uC2A4\uBFD0\uC774\uACE0, \uADF8\uB7EC\uBA74 \uC5EC\uAE30\uC11C \uB36E\uC744 \uC218 \uC788\uB2E4.
2994
+ *
2995
+ * ## z-index: auto \uAC00 \uC774 \uADDC\uCE59\uC758 \uB098\uBA38\uC9C0 \uC808\uBC18\uC774\uB2E4
2996
+ *
2997
+ * "position: static\uC774\uBA74 z-index\uB294 \uBB34\uC2DC\uB41C\uB2E4"\uC5D0\uB294 \uC608\uC678\uAC00 \uC788\uB2E4 \u2014 **\uD50C\uB809\uC2A4\xB7\uADF8\uB9AC\uB4DC \uC544\uC774\uD15C\uC740
2998
+ * static\uC774\uC5B4\uB3C4 z-index\uAC00 \uBA39\uACE0, \uADF8 \uAC12\uC73C\uB85C \uC313\uC784 \uB9E5\uB77D\uC744 \uB9CC\uB4E0\uB2E4.** \uADF8\uB9AC\uACE0 \uCE94\uBC84\uC2A4\uC5D0\uC11C
2999
+ * \uB418\uB3CC\uB824\uC9C4 .wp-overlay \uB294 \uAC70\uC758 \uC5B8\uC81C\uB098 \uD50C\uB809\uC2A4 \uC544\uC774\uD15C\uC774\uB2E4: \uB17C\uB9AC \uB798\uD37C
3000
+ * .sdui-editor-cv-chrome \uB3C4, \uC2A4\uD399 \uB8E8\uD2B8 .sdui-editor-canvas__page .sdui-root \uB3C4
3001
+ * display: flex \uB77C\uC11C\uB2E4(\uB458 \uB2E4 \uC774 \uD30C\uC77C\uC774 \uADF8\uB807\uAC8C \uB9CC\uB4E0\uB2E4).
3002
+ *
3003
+ * \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC2DC\uD2B8\uC758 .wp-overlay \uC5D0\uB294 z-index\uAC00 \uC5C6\uC5B4 \uC5EC\uAE30\uAE4C\uC9C0\uB294 \uB4DC\uB7EC\uB098\uC9C0 \uC54A\uB294\uB2E4.
3004
+ * \uB4DC\uB7EC\uB098\uB294 \uAC74 **\uC18C\uBE44 \uD504\uB85C\uC81D\uD2B8\uAC00 \uC790\uAE30 \uC2DC\uD2B8\uB85C \uAC19\uC740 \uD074\uB798\uC2A4\uC5D0 z-index\uB97C \uC5B9\uC5C8\uC744 \uB54C**\uB2E4
3005
+ * (ERP\uB294 --wp-z-dialog). \uADF8\uB7EC\uBA74 \uC704\uCE58\uB9CC \uBE8F\uAE30\uACE0 \uC313\uC784 \uC21C\uC11C\uB294 \uADF8\uB300\uB85C\uB77C, \uD3B8\uC9D1 \uB808\uC774\uC5B4
3006
+ * (--wp-z-sticky)\uAC00 \uADF8 \uC544\uB798\uB85C \uAE54\uB9B0\uB2E4. \uACB0\uACFC\uB294 "\uD14C\uB450\uB9AC\uAC00 \uB2E4\uC774\uC5BC\uB85C\uADF8\uB97C \uAC00\uB9B0\uB2E4"\uAC00 \uC544\uB2C8\uB77C
3007
+ * \uADF8 \uBC18\uB300 \u2014 **\uB2E4\uC774\uC5BC\uB85C\uADF8 \uC548 \uB178\uB4DC\uC758 \uC120\uD0DD \uD14C\uB450\uB9AC\uAC00 \uD1B5\uC9F8\uB85C \uC0AC\uB77C\uC9C4\uB2E4.**
3008
+ * \uC2E4\uCE21(ERP fi/products, KeyValueList): \uD14C\uB450\uB9AC 4\uBCC0 \uC911 **0\uBCC0**\uB9CC \uCE60\uD588\uACE0, \uC774 \uC120\uC5B8\uC744
3009
+ * \uB123\uC740 \uB4A4 **4\uBCC0** \uC804\uBD80 \uCE60\uD588\uB2E4. \uC704\uCE58\uB97C \uBE8F\uC5C8\uC73C\uBA74 \uC313\uC784 \uC21C\uC11C\uB3C4 \uAC19\uC774 \uBE8F\uC5B4\uC57C \uD55C\uB2E4.
3010
+ *
3011
+ * \uBC84\uB9B0 \uB300\uC548(\uC804\uBD80 \uC9C4\uC9DC \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uC7AC \uBD24\uB2E4):
3012
+ * - *\uCE94\uBC84\uC2A4 Dialog\uC5D0 position: relative* \u2014 z-index\uB97C \uB418\uC0B4\uB9AC\uB294 \uBC29\uD5A5\uC774\uB77C \uB354 \uB098\uBE60\uC9C4\uB2E4(0/4).
3013
+ * - *\uD3B8\uC9D1 \uB808\uC774\uC5B4\uC758 z-index\uB97C \uB0AE\uCD98\uB2E4* \u2014 \uAC00\uB9AC\uB294 \uCABD\uC744 \uBC14\uAFB8\uB294 \uAC83\uC77C \uBFD0, \uC548\uCABD \uD14C\uB450\uB9AC\uB294 \uACC4\uC18D
3014
+ * \uC548 \uBCF4\uC778\uB2E4(0/4).
3015
+ * - *\uCE94\uBC84\uC2A4\uC5D0 isolation: isolate* \u2014 \uB2E4\uC774\uC5BC\uB85C\uADF8\uC640 \uD3B8\uC9D1 \uB808\uC774\uC5B4\uAC00 **\uAC19\uC740** \uB9E5\uB77D \uC548\uC5D0 \uC788\uC5B4
3016
+ * \uB458\uC758 \uC0C1\uB300 \uC21C\uC11C\uB294 \uADF8\uB300\uB85C\uB2E4(0/4). \uCE94\uBC84\uC2A4 \uBC16\uC73C\uB85C z-index\uAC00 \uC0C8\uB294 \uAC83\uC744 \uB9C9\uC744 \uBFD0\uC774\uB2E4.
3017
+ * - *\uD3B8\uC9D1 \uB808\uC774\uC5B4\uB97C \uD1A0\uD070 \uCC99\uB3C4 \uC704\uB85C \uC62C\uB9B0\uB2E4* \u2014 4/4\uB85C \uACE0\uCCD0\uC9C0\uAE34 \uD558\uB098 \uC6D0\uC778\uC744 \uB0A8\uAE34 \uCC44
3018
+ * \uC22B\uC790 \uACBD\uC7C1\uC744 \uC2DC\uC791\uD558\uB294 \uAC83\uC774\uB77C, \uC18C\uBE44 \uD504\uB85C\uC81D\uD2B8\uAC00 \uCC99\uB3C4\uB97C \uC62C\uB9AC\uBA74 \uB2E4\uC2DC \uAE68\uC9C4\uB2E4.
2994
3019
  */
2995
3020
  .sdui-editor-canvas .wp-overlay {
2996
3021
  position: static; inset: auto; background: none;
2997
3022
  display: block; padding: 0; overflow: visible;
3023
+ z-index: auto;
2998
3024
  }
2999
3025
  .sdui-editor-canvas .wp-dialog {
3000
3026
  max-height: none; animation: none; margin: 0 auto;
3001
3027
  box-shadow: var(--wp-shadow-sm);
3002
3028
  }
3003
- /* \uD1A0\uC2A4\uD2B8\uB3C4 \uBDF0\uD3EC\uD2B8 \uACE0\uC815\uC744 \uD480\uC5B4 \uCE94\uBC84\uC2A4 \uC548\uC5D0 \uBA38\uBB3C\uAC8C \uD55C\uB2E4. */
3004
- .sdui-editor-canvas .wp-toast-region { position: static; }
3029
+ /*
3030
+ * \uD1A0\uC2A4\uD2B8\uB3C4 \uBDF0\uD3EC\uD2B8 \uACE0\uC815\uC744 \uD480\uC5B4 \uCE94\uBC84\uC2A4 \uC548\uC5D0 \uBA38\uBB3C\uAC8C \uD55C\uB2E4.
3031
+ * z-index\uB97C \uD568\uAED8 \uB0B4\uB9AC\uB294 \uADFC\uAC70\uB294 \uC704\uC640 \uAC19\uB2E4(--wp-z-toast \uB294 \uCC99\uB3C4\uC758 \uAC70\uC758 \uAF2D\uB300\uAE30\uB2E4).
3032
+ * \uC9C0\uAE08 \uCE94\uBC84\uC2A4\uC5D0\uC11C \uD1A0\uC2A4\uD2B8\uAC00 \uB728\uB294 \uACBD\uB85C\uB294 \uC5C6\uC5B4\uC11C(\uBD80\uC791\uC6A9\uC774 \uB9C9\uD600 \uC788\uB2E4) \uB208\uC73C\uB85C \uC7AC\uD604\uD558\uC9C0\uB294
3033
+ * \uBABB\uD588\uB2E4 \u2014 \uAC19\uC740 \uD568\uC815\uC744 \uD55C \uC904 \uC544\uB798 \uB0A8\uACA8 \uB450\uC9C0 \uC54A\uC73C\uB824\uB294 \uC608\uBC29\uC774\uB2E4.
3034
+ */
3035
+ .sdui-editor-canvas .wp-toast-region { position: static; z-index: auto; }
3005
3036
 
3006
3037
  /* \u2550\u2550 \uD3B8\uC9D1 \uB808\uC774\uC5B4 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */
3007
3038
 
@@ -3703,6 +3734,18 @@ var GROUP_LABELS = {
3703
3734
  validation: "\uAC80\uC99D",
3704
3735
  other: "\uAE30\uD0C0"
3705
3736
  };
3737
+ function slotTextTarget(node, name) {
3738
+ const list = node.slots[name];
3739
+ if (!list || list.length !== 1) return null;
3740
+ const only = list[0];
3741
+ if (!only || only.kind !== "text") return null;
3742
+ return { id: only.id, text: only.text };
3743
+ }
3744
+ function canBind(entry, kind) {
3745
+ if (entry.binding) return false;
3746
+ if (entry.slotted) return false;
3747
+ return kind !== "action";
3748
+ }
3706
3749
  function groupKeyOf(meta) {
3707
3750
  return meta?.group ?? "other";
3708
3751
  }
@@ -3716,6 +3759,11 @@ function entryOf(node, name, meta) {
3716
3759
  value,
3717
3760
  present,
3718
3761
  slotted,
3762
+ // 프롭에 이미 값이 있으면 슬롯 텍스트 입력을 주지 않는다. 그 자리는 프롭 편집기가
3763
+ // 이미 그려지고 있어서(둘 다 찬 자리는 원문을 고칠 수 있어야 한다) 입력이 두 칸이
3764
+ // 되는데, 어느 칸이 화면을 정하는지는 컴포넌트마다 달라 답을 줄 수 없다.
3765
+ // 실측 0건이지만 스펙은 편집기 밖에서도 만들어진다.
3766
+ slotText: present ? null : slotTextTarget(node, name),
3719
3767
  binding: bindingOf(value),
3720
3768
  filled: present || slotted
3721
3769
  };
@@ -3756,7 +3804,9 @@ function inspectNode(node, catalog) {
3756
3804
  }
3757
3805
  function initialOpenGroups(inspection) {
3758
3806
  const open = /* @__PURE__ */ new Set();
3759
- for (const group of inspection.groups) if (group.filled > 0) open.add(group.key);
3807
+ for (const group of inspection.groups) {
3808
+ if (group.entries.length > 0 || group.filled > 0) open.add(group.key);
3809
+ }
3760
3810
  if (open.size === 0 && inspection.groups[0]) open.add(inspection.groups[0].key);
3761
3811
  return open;
3762
3812
  }
@@ -5134,23 +5184,38 @@ function NodePanel({
5134
5184
  select: "keep"
5135
5185
  });
5136
5186
  };
5187
+ const applySlotText = (entry, target, text) => {
5188
+ onApply({
5189
+ result: setText(doc, target.id, text),
5190
+ label: changeLabel(entry.meta, entry.name),
5191
+ // 합치기 키를 프롭이 아니라 **텍스트 노드** 기준으로 잡는다. 고치는 대상이 그
5192
+ // 노드이고, 트리에서 같은 노드를 골라 고치는 `TextChildPanel`과 키가 같아야
5193
+ // 패널을 오가며 친 글자가 되돌리기 한 칸으로 이어진다.
5194
+ coalesce: coalesceKey(target.id, "$text"),
5195
+ select: "keep"
5196
+ });
5197
+ };
5137
5198
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5138
5199
  inspection.groups.map((group) => /* @__PURE__ */ jsx(
5139
5200
  GroupSection,
5140
5201
  {
5141
5202
  group,
5142
5203
  defaultOpen: open.has(group.key),
5143
- children: (entry) => /* @__PURE__ */ jsx(
5144
- PropRow,
5145
- {
5146
- entry,
5147
- ctx,
5148
- slotCount: node.slots[entry.name]?.length ?? 0,
5149
- onChange: (next) => apply(entry.name, next, entry.meta),
5150
- onBind: onRequestBinding ? () => onRequestBinding(entry.name) : void 0
5151
- },
5152
- entry.name
5153
- )
5204
+ children: (entry) => {
5205
+ const slotText = entry.slotText;
5206
+ return /* @__PURE__ */ jsx(
5207
+ PropRow,
5208
+ {
5209
+ entry,
5210
+ ctx,
5211
+ slotCount: node.slots[entry.name]?.length ?? 0,
5212
+ onChange: (next) => apply(entry.name, next, entry.meta),
5213
+ onSlotText: slotText ? (text) => applySlotText(entry, slotText, text) : void 0,
5214
+ onBind: onRequestBinding ? () => onRequestBinding(entry.name) : void 0
5215
+ },
5216
+ entry.name
5217
+ );
5218
+ }
5154
5219
  },
5155
5220
  `${node.id}:${group.key}`
5156
5221
  )),
@@ -5199,11 +5264,13 @@ function PropRow({
5199
5264
  ctx,
5200
5265
  slotCount,
5201
5266
  onChange,
5267
+ onSlotText,
5202
5268
  onBind
5203
5269
  }) {
5204
5270
  const meta = entry.meta;
5205
5271
  const label = meta?.label ?? entry.name;
5206
5272
  const missing = meta?.required === true && !entry.filled;
5273
+ const slotText = onSlotText ? entry.slotText : null;
5207
5274
  return /* @__PURE__ */ jsxs("div", { className: `sdui-insp-row${meta?.legacy ? " sdui-insp-row--legacy" : ""}`, children: [
5208
5275
  /* @__PURE__ */ jsxs("div", { className: "sdui-insp-row__head", children: [
5209
5276
  /* @__PURE__ */ jsx("span", { className: "sdui-insp-row__label", children: label }),
@@ -5211,7 +5278,7 @@ function PropRow({
5211
5278
  missing ? /* @__PURE__ */ jsx("span", { className: "sdui-insp-flag sdui-insp-flag--req", children: "\uD544\uC218" }) : null,
5212
5279
  meta?.legacy ? /* @__PURE__ */ jsx("span", { className: "sdui-insp-flag sdui-insp-flag--legacy", children: "\uC61B \uD504\uB86D" }) : null,
5213
5280
  /* @__PURE__ */ jsxs("span", { className: "sdui-insp-row__tools", children: [
5214
- onBind && !entry.binding && meta?.kind !== "action" ? /* @__PURE__ */ jsx(
5281
+ onBind && canBind(entry, meta?.kind) ? /* @__PURE__ */ jsx(
5215
5282
  ToolButton,
5216
5283
  {
5217
5284
  icon: "link",
@@ -5231,10 +5298,11 @@ function PropRow({
5231
5298
  )
5232
5299
  ] })
5233
5300
  ] }),
5234
- entry.slotted ? /* @__PURE__ */ jsxs("p", { className: "sdui-insp-row__warn", children: [
5301
+ entry.slotted && !slotText ? /* @__PURE__ */ jsxs("p", { className: "sdui-insp-row__warn", children: [
5235
5302
  `\uC2AC\uB86F\uC5D0 \uB178\uB4DC ${slotCount}\uAC1C\uAC00 \uB4E4\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uB0B4\uC6A9\uC740 \uD2B8\uB9AC\uC5D0\uC11C \uD3B8\uC9D1\uD558\uC138\uC694.`,
5236
- entry.present ? " \uD504\uB86D \uAC12\uB3C4 \uD568\uAED8 \uC788\uC5B4 \uCEF4\uD3EC\uB10C\uD2B8\uC5D0 \uB530\uB77C \uD55C\uCABD\uC774 \uBB34\uC2DC\uB429\uB2C8\uB2E4." : ""
5303
+ entry.present ? " \uD504\uB86D \uAC12\uB3C4 \uD568\uAED8 \uC788\uC9C0\uB9CC \uD654\uBA74\uC5D0\uB294 \uC2AC\uB86F\uC774 \uC774\uAE41\uB2C8\uB2E4 \u2014 \uD504\uB86D\uC740 \uBB34\uC2DC\uB429\uB2C8\uB2E4." : ""
5237
5304
  ] }) : null,
5305
+ slotText && onSlotText ? /* @__PURE__ */ jsx(SlotTextField, { target: slotText, onChange: onSlotText }) : null,
5238
5306
  !entry.slotted || entry.present ? /* @__PURE__ */ jsx(
5239
5307
  ValueEditor,
5240
5308
  {
@@ -5250,6 +5318,15 @@ function PropRow({
5250
5318
  meta?.legacy ? /* @__PURE__ */ jsx("p", { className: "sdui-insp-row__warn", children: "\uB354 \uC774\uC0C1 \uC4F0\uC774\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uAC12\uC740 \uADF8\uB300\uB85C \uB450\uACE0 \uC800\uC7A5\uB429\uB2C8\uB2E4." }) : null
5251
5319
  ] });
5252
5320
  }
5321
+ function SlotTextField({
5322
+ target,
5323
+ onChange
5324
+ }) {
5325
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5326
+ /* @__PURE__ */ jsx(Input, { size: "sm", value: target.text, onChange: (e) => onChange(e.target.value) }),
5327
+ /* @__PURE__ */ jsx("p", { className: "sdui-insp-row__desc", children: "\uC2AC\uB86F\uC5D0 \uB4E0 \uD14D\uC2A4\uD2B8 \uB178\uB4DC\uC785\uB2C8\uB2E4. \uD2B8\uB9AC\uC5D0\uC11C \uADF8 \uB178\uB4DC\uB97C \uACE8\uB77C \uACE0\uCE58\uB294 \uAC83\uACFC \uAC19\uC2B5\uB2C8\uB2E4." })
5328
+ ] });
5329
+ }
5253
5330
  function fallbackMeta(entry) {
5254
5331
  const action = looksLikeAction(entry.name) || isActionShaped(entry.value);
5255
5332
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipco/sdui-editor",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "SDUI 페이지 스펙 편집기 — 소비 프로젝트가 자기 라우트에 마운트하는 React 컴포넌트",
5
5
  "keywords": [
6
6
  "sdui",
@@ -58,14 +58,14 @@
58
58
  "codemirror": "^6.0.1"
59
59
  },
60
60
  "peerDependencies": {
61
- "@wipco/sdui": "^0.6.0",
61
+ "@wipco/sdui": "^0.8.0",
62
62
  "react": ">=18",
63
63
  "react-dom": ">=18"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/react": "^19.0.0",
67
67
  "@types/react-dom": "^19.0.0",
68
- "@wipco/sdui": "^0.6.0",
68
+ "@wipco/sdui": "^0.8.0",
69
69
  "tsup": "^8.5.0",
70
70
  "tsx": "^4.20.0",
71
71
  "typescript": "^5.7.0"