@wipco/sdui 0.4.2 → 0.6.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/meta.js CHANGED
@@ -62,6 +62,149 @@ var classNameProp = {
62
62
  group: "layout",
63
63
  advanced: true
64
64
  };
65
+ var gapProp = {
66
+ name: "gap",
67
+ kind: "enum",
68
+ label: "\uC774 \uC548\uC758 \uAC04\uACA9",
69
+ default: "8",
70
+ description: "DS \uAC04\uACA9 \uCC99\uB3C4(px). \uCC99\uB3C4 \uBC16 \uAC12\uC740 style\uC5D0 \uB0A8\uAE34\uB2E4.",
71
+ options: [
72
+ { value: "2", label: "2px" },
73
+ { value: "4", label: "4px" },
74
+ { value: "8", label: "8px" },
75
+ { value: "12", label: "12px" },
76
+ { value: "16", label: "16px" },
77
+ { value: "20", label: "20px" },
78
+ { value: "24", label: "24px" },
79
+ { value: "32", label: "32px" }
80
+ ],
81
+ group: "layout"
82
+ };
83
+ var gridGapProp = {
84
+ name: "gap",
85
+ kind: "enum",
86
+ label: "\uC774 \uC548\uC758 \uAC04\uACA9",
87
+ default: "20",
88
+ description: "DS \uAC04\uACA9 \uCC99\uB3C4(px). \uADF8\uB9AC\uB4DC \uAE30\uBCF8\uC740 20px(--wp-gutter)\uC774\uB2E4.",
89
+ options: [
90
+ { value: "2", label: "2px" },
91
+ { value: "4", label: "4px" },
92
+ { value: "8", label: "8px" },
93
+ { value: "12", label: "12px" },
94
+ { value: "16", label: "16px" },
95
+ { value: "20", label: "20px" },
96
+ { value: "24", label: "24px" },
97
+ { value: "32", label: "32px" }
98
+ ],
99
+ group: "layout"
100
+ };
101
+ var rowAlignProp = {
102
+ name: "align",
103
+ kind: "enum",
104
+ label: "\uC774 \uC548\uC758 \uAD50\uCC28\uCD95 \uC815\uB82C",
105
+ default: "center",
106
+ description: "\uC790\uC2DD\uB4E4\uC744 \uC138\uB85C\uB85C \uC5B4\uB514\uC5D0 \uB9DE\uCD9C\uC9C0(align-items). \uC790\uC2DD\uC774 selfAlign\uC73C\uB85C \uC790\uAE30 \uAC83\uB9CC \uB4A4\uC9D1\uC744 \uC218 \uC788\uB2E4.",
107
+ options: [
108
+ { value: "start", label: "\uC704" },
109
+ { value: "center", label: "\uAC00\uC6B4\uB370" },
110
+ { value: "end", label: "\uC544\uB798" },
111
+ { value: "baseline", label: "\uAE00\uC790 \uAE30\uC900\uC120" },
112
+ { value: "stretch", label: "\uB298\uB9AC\uAE30" }
113
+ ],
114
+ group: "layout"
115
+ };
116
+ var stretchAlignProp = {
117
+ name: "align",
118
+ kind: "enum",
119
+ label: "\uC774 \uC548\uC758 \uAD50\uCC28\uCD95 \uC815\uB82C",
120
+ default: "stretch",
121
+ description: "\uC790\uC2DD\uB4E4\uC744 \uAC00\uB85C\uB85C \uC5B4\uB514\uC5D0 \uB9DE\uCD9C\uC9C0(align-items). \uC790\uC2DD\uC774 selfAlign\uC73C\uB85C \uC790\uAE30 \uAC83\uB9CC \uB4A4\uC9D1\uC744 \uC218 \uC788\uB2E4.",
122
+ options: [
123
+ { value: "start", label: "\uC67C\uCABD" },
124
+ { value: "center", label: "\uAC00\uC6B4\uB370" },
125
+ { value: "end", label: "\uC624\uB978\uCABD" },
126
+ { value: "baseline", label: "\uAE00\uC790 \uAE30\uC900\uC120" },
127
+ { value: "stretch", label: "\uB298\uB9AC\uAE30" }
128
+ ],
129
+ group: "layout"
130
+ };
131
+ var wrapProp = {
132
+ name: "wrap",
133
+ kind: "boolean",
134
+ label: "\uB118\uCE58\uBA74 \uC904\uBC14\uAFC8",
135
+ default: false,
136
+ description: "flex-wrap. \uB044\uBA74 \uD55C \uC904\uC5D0 \uBC00\uC5B4 \uB123\uB294\uB2E4.",
137
+ group: "layout"
138
+ };
139
+ var columnJustifyProp = {
140
+ name: "justify",
141
+ kind: "enum",
142
+ label: "\uC774 \uC548\uC758 \uC8FC\uCD95 \uC815\uB82C",
143
+ description: "justify-content. \uC138\uB85C \uBB36\uC74C\uC774\uB77C \uC138\uB85C \uBC29\uD5A5\uC774\uACE0, \uB192\uC774\uAC00 \uC815\uD574\uC9C4 \uC790\uB9AC\uC5D0\uC11C\uB9CC \uD45C\uAC00 \uB09C\uB2E4.",
144
+ options: [
145
+ { value: "start", label: "\uC704" },
146
+ { value: "center", label: "\uAC00\uC6B4\uB370" },
147
+ { value: "end", label: "\uC544\uB798" },
148
+ { value: "between", label: "\uC591\uB05D" }
149
+ ],
150
+ group: "layout",
151
+ advanced: true
152
+ };
153
+ var growProp = {
154
+ name: "grow",
155
+ kind: "boolean",
156
+ label: "\uC790\uAE30: \uB0A8\uB294 \uACF5\uAC04 \uCC28\uC9C0",
157
+ description: "flex-grow. \uBD80\uBAA8\uC758 \uB0A8\uB294 \uD3ED(\uC138\uB85C \uBB36\uC74C\uC774\uBA74 \uB192\uC774)\uC744 \uC774 \uB178\uB4DC\uAC00 \uBA39\uB294\uB2E4.",
158
+ group: "layout",
159
+ advanced: true
160
+ };
161
+ var shrinkProp = {
162
+ name: "shrink",
163
+ kind: "boolean",
164
+ label: "\uC790\uAE30: \uC881\uC544\uC9C0\uBA74 \uC904\uC5B4\uB4E6",
165
+ description: "flex-shrink. \uB044\uBA74 \uC881\uC544\uC838\uB3C4 \uC6D0\uB798 \uD06C\uAE30\uB97C \uC9C0\uD0A8\uB2E4(\uBC84\uD2BC\xB7\uBC30\uC9C0\uCC98\uB7FC \uCC0C\uADF8\uB7EC\uC9C0\uBA74 \uC548 \uB418\uB294 \uAC83).",
166
+ group: "layout",
167
+ advanced: true
168
+ };
169
+ var spanProp = {
170
+ name: "span",
171
+ kind: "enum",
172
+ label: "\uC790\uAE30: \uC5F4 \uBCD1\uD569",
173
+ description: "grid-column: span N. \uBD80\uBAA8\uAC00 Grid\uC77C \uB54C\uB9CC \uB73B\uC774 \uC788\uB2E4.",
174
+ options: [
175
+ { value: 1, label: "1\uCE78" },
176
+ { value: 2, label: "2\uCE78" },
177
+ { value: 3, label: "3\uCE78" },
178
+ { value: 4, label: "4\uCE78" },
179
+ { value: 5, label: "5\uCE78" },
180
+ { value: 6, label: "6\uCE78" }
181
+ ],
182
+ group: "layout",
183
+ advanced: true
184
+ };
185
+ var selfAlignProp = {
186
+ name: "selfAlign",
187
+ kind: "enum",
188
+ label: "\uC790\uAE30: \uAD50\uCC28\uCD95 \uC815\uB82C",
189
+ description: "align-self. \uBD80\uBAA8\uC758 align\uC744 \uC774 \uB178\uB4DC\uC5D0\uC11C\uB9CC \uB4A4\uC9D1\uB294\uB2E4.",
190
+ options: [
191
+ { value: "start", label: "\uC2DC\uC791" },
192
+ { value: "center", label: "\uAC00\uC6B4\uB370" },
193
+ { value: "end", label: "\uB05D" },
194
+ { value: "baseline", label: "\uAE00\uC790 \uAE30\uC900\uC120" },
195
+ { value: "stretch", label: "\uB298\uB9AC\uAE30" }
196
+ ],
197
+ group: "layout",
198
+ advanced: true
199
+ };
200
+ var truncateProp = {
201
+ name: "truncate",
202
+ kind: "boolean",
203
+ label: "\uC790\uAE30: \uD55C \uC904 \uB9D0\uC904\uC784",
204
+ description: "\uB118\uCE58\uB294 \uAE00\uC790\uB97C \u2026\uB85C \uC790\uB978\uB2E4. \uC790\uAE30 min-width\uB97C 0\uC73C\uB85C \uD480\uC5B4 \uBB36\uC74C \uC548\uC5D0\uC11C\uB3C4 \uB3D9\uC791\uD55C\uB2E4.",
205
+ group: "layout",
206
+ advanced: true
207
+ };
65
208
  var ActionsMeta = {
66
209
  name: "Actions",
67
210
  label: "\uC561\uC158 \uBB36\uC74C",
@@ -83,8 +226,15 @@ var ActionsMeta = {
83
226
  ],
84
227
  group: "layout"
85
228
  },
229
+ gapProp,
230
+ rowAlignProp,
231
+ wrapProp,
86
232
  styleProp,
87
- classNameProp
233
+ classNameProp,
234
+ growProp,
235
+ shrinkProp,
236
+ spanProp,
237
+ selfAlignProp
88
238
  ],
89
239
  children: { accepts: true, text: false, label: "\uC815\uB82C\uD560 \uBC84\uD2BC\uB4E4" },
90
240
  dom: { element: "div" },
@@ -137,7 +287,12 @@ var CardMeta = {
137
287
  { name: "selected", kind: "boolean", label: "\uC120\uD0DD\uB428", default: false, bindable: true, group: "appearance" },
138
288
  { name: "onClick", kind: "action", label: "\uD074\uB9AD", group: "behavior" },
139
289
  styleProp,
140
- classNameProp
290
+ classNameProp,
291
+ growProp,
292
+ shrinkProp,
293
+ spanProp,
294
+ selfAlignProp,
295
+ truncateProp
141
296
  ],
142
297
  slots: [
143
298
  { name: "actions", label: "\uD5E4\uB354 \uC6B0\uCE21 \uC561\uC158", description: "\uBC84\uD2BC\xB7Select \uB4F1", allow: ["Actions", "Button", "IconButton", "Select", "Badge", "Tag", "Row", "Show", "Can"] },
@@ -158,12 +313,28 @@ var ColMeta = {
158
313
  category: "layout",
159
314
  icon: "chevrons-up-down",
160
315
  description: "\uC790\uC2DD\uC744 \uC138\uB85C\uB85C \uC313\uB294\uB2E4(.wp-col).",
161
- props: [styleProp, classNameProp],
316
+ props: [
317
+ gapProp,
318
+ stretchAlignProp,
319
+ columnJustifyProp,
320
+ wrapProp,
321
+ styleProp,
322
+ classNameProp,
323
+ growProp,
324
+ shrinkProp,
325
+ spanProp,
326
+ selfAlignProp
327
+ ],
162
328
  children: { accepts: true, text: true },
163
329
  dom: { element: "div" },
330
+ // 자식이 둘이다 — gap·align은 자식이 하나면 값을 바꿔도 화면이 그대로라
331
+ // 사용자가 프롭이 고장 났다고 판단한다. 레이아웃 컨테이너 preset의 규칙으로 잡는다.
164
332
  preset: {
165
333
  component: "Col",
166
- children: [{ component: "Text", props: { preset: "body" }, children: ["\uCCAB \uC904"] }]
334
+ children: [
335
+ { component: "Text", props: { preset: "body" }, children: ["\uCCAB \uC904"] },
336
+ { component: "Text", props: { preset: "body" }, children: ["\uB458\uC9F8 \uC904"] }
337
+ ]
167
338
  },
168
339
  resize: { kind: "style", axis: "both" }
169
340
  };
@@ -192,10 +363,15 @@ var GridMeta = {
192
363
  label: "\uC5F4 \uC218",
193
364
  default: 3,
194
365
  description: "wp-grid--N \uD504\uB9AC\uC14B. \uC2A4\uD399\uC5D0\uB294 \uBB38\uC790\uC5F4\uC774 \uC544\uB2C8\uB77C \uC22B\uC790\uB85C \uB4E4\uC5B4\uAC04\uB2E4.",
366
+ // 1·5·6은 새로 열었다 — v2 원본 88화면이 22회 쓴다(1열 11 · 5열 5 · 6열 3).
367
+ // 규칙은 어휘가 들고 다니는 시트(LAYOUT_CSS)에 있다. 2·3·4는 기존 시트 그대로.
195
368
  options: [
369
+ { value: 1, label: "1\uC5F4" },
196
370
  { value: 2, label: "2\uC5F4" },
197
371
  { value: 3, label: "3\uC5F4" },
198
- { value: 4, label: "4\uC5F4" }
372
+ { value: 4, label: "4\uC5F4" },
373
+ { value: 5, label: "5\uC5F4" },
374
+ { value: 6, label: "6\uC5F4" }
199
375
  ],
200
376
  group: "layout"
201
377
  },
@@ -206,8 +382,15 @@ var GridMeta = {
206
382
  description: 'grid-template-columns \uAC12. \uC608: "minmax(0,1.6fr) minmax(0,1fr)". columns\uB97C \uBB34\uC2DC\uD55C\uB2E4.',
207
383
  group: "layout"
208
384
  },
385
+ gridGapProp,
386
+ stretchAlignProp,
387
+ wrapProp,
209
388
  styleProp,
210
- classNameProp
389
+ classNameProp,
390
+ growProp,
391
+ shrinkProp,
392
+ spanProp,
393
+ selfAlignProp
211
394
  ],
212
395
  children: { accepts: true, text: false, label: "\uADF8\uB9AC\uB4DC \uCE78" },
213
396
  dom: { element: "div" },
@@ -219,7 +402,7 @@ var GridMeta = {
219
402
  { component: "Card", props: { title: "\uC624\uB978\uCABD" }, children: [] }
220
403
  ]
221
404
  },
222
- resize: { kind: "enum", prop: "columns", values: ["2", "3", "4"], axis: "x" }
405
+ resize: { kind: "enum", prop: "columns", values: ["1", "2", "3", "4", "5", "6"], axis: "x" }
223
406
  };
224
407
  var PageHeadMeta = {
225
408
  name: "PageHead",
@@ -260,8 +443,15 @@ var RowMeta = {
260
443
  ],
261
444
  group: "layout"
262
445
  },
446
+ gapProp,
447
+ rowAlignProp,
448
+ wrapProp,
263
449
  styleProp,
264
- classNameProp
450
+ classNameProp,
451
+ growProp,
452
+ shrinkProp,
453
+ spanProp,
454
+ selfAlignProp
265
455
  ],
266
456
  children: { accepts: true, text: true },
267
457
  dom: { element: "div" },
@@ -283,15 +473,26 @@ var SectionMeta = {
283
473
  description: "\uC81C\uBAA9(h4)\uC774 \uBD99\uC740 \uC138\uB85C \uAD6C\uD68D.",
284
474
  props: [
285
475
  { name: "title", kind: "node", label: "\uC81C\uBAA9", slot: true, group: "content" },
476
+ gapProp,
477
+ stretchAlignProp,
478
+ columnJustifyProp,
479
+ wrapProp,
286
480
  styleProp,
287
- classNameProp
481
+ classNameProp,
482
+ growProp,
483
+ shrinkProp,
484
+ spanProp,
485
+ selfAlignProp
288
486
  ],
289
487
  children: { accepts: true, text: true },
290
488
  dom: { element: "section", slotElement: { title: "h2" } },
291
489
  preset: {
292
490
  component: "Section",
293
491
  props: { title: "\uC139\uC158 \uC81C\uBAA9" },
294
- children: [{ component: "Text", props: { preset: "body" }, children: ["\uB0B4\uC6A9"] }]
492
+ children: [
493
+ { component: "Text", props: { preset: "body" }, children: ["\uB0B4\uC6A9"] },
494
+ { component: "Text", props: { preset: "body" }, children: ["\uB458\uC9F8 \uC904"] }
495
+ ]
295
496
  },
296
497
  resize: { kind: "style", axis: "both" }
297
498
  };
@@ -478,7 +679,12 @@ var ButtonMeta = {
478
679
  },
479
680
  { name: "onClick", kind: "action", label: "\uD074\uB9AD", group: "behavior" },
480
681
  styleProp,
481
- classNameProp
682
+ classNameProp,
683
+ growProp,
684
+ shrinkProp,
685
+ spanProp,
686
+ selfAlignProp,
687
+ truncateProp
482
688
  ],
483
689
  children: { accepts: true, text: true, label: "\uBC84\uD2BC \uB77C\uBCA8" },
484
690
  dom: { element: "button", elementProp: "as" },
@@ -877,7 +1083,12 @@ var InputMeta = {
877
1083
  group: "content"
878
1084
  },
879
1085
  styleProp,
880
- classNameProp
1086
+ classNameProp,
1087
+ growProp,
1088
+ shrinkProp,
1089
+ spanProp,
1090
+ selfAlignProp,
1091
+ truncateProp
881
1092
  ],
882
1093
  children: { accepts: false },
883
1094
  dom: { element: "input" },
@@ -930,7 +1141,12 @@ var SelectMeta = {
930
1141
  { name: "disabled", kind: "boolean", label: "\uBE44\uD65C\uC131", default: false, bindable: true, group: "behavior" },
931
1142
  { name: "aria-label", kind: "string", label: "\uC811\uADFC\uC131 \uB77C\uBCA8", description: "Field \uB77C\uBCA8\uC774 \uC5C6\uC744 \uB54C \uC4F4\uB2E4.", group: "content", advanced: true },
932
1143
  styleProp,
933
- classNameProp
1144
+ classNameProp,
1145
+ growProp,
1146
+ shrinkProp,
1147
+ spanProp,
1148
+ selfAlignProp,
1149
+ truncateProp
934
1150
  ],
935
1151
  children: { accepts: false },
936
1152
  dom: { element: "div" },
@@ -1242,6 +1458,39 @@ var TextMeta = {
1242
1458
  ],
1243
1459
  group: "appearance"
1244
1460
  },
1461
+ /*
1462
+ * weight·textAlign은 `preset`이 묶어 놓은 축을 푸는 자리다.
1463
+ * 프리셋 19종이 크기·굵기·정렬을 한 덩어리로 갖고 있어서 "본문 크기인데 굵게"
1464
+ * (v2 원본의 font-medium 282회)를 만들 수단이 없었다.
1465
+ *
1466
+ * `default`를 적지 않은 것은 의도다 — 기본 굵기가 preset마다 다르다(.wp-body 400,
1467
+ * .wp-label 600, .wp-h1 700). 하나를 적으면 편집기가 다른 preset에서 값을 잘못 지운다.
1468
+ */
1469
+ {
1470
+ name: "weight",
1471
+ kind: "enum",
1472
+ label: "\uAE00\uC790 \uAD75\uAE30",
1473
+ description: "preset\uC774 \uC815\uD55C \uAD75\uAE30\uB97C \uC774 \uC790\uB9AC\uC5D0\uC11C\uB9CC \uB4A4\uC9D1\uB294\uB2E4. \uC0DD\uB7B5\uD558\uBA74 preset\uC758 \uAD75\uAE30.",
1474
+ options: [
1475
+ { value: "regular", label: "\uBCF4\uD1B5(400)" },
1476
+ { value: "medium", label: "\uC911\uAC04(500)" },
1477
+ { value: "semibold", label: "\uC57D\uAC04 \uAD75\uAC8C(600)" },
1478
+ { value: "bold", label: "\uAD75\uAC8C(700)" }
1479
+ ],
1480
+ group: "appearance"
1481
+ },
1482
+ {
1483
+ name: "textAlign",
1484
+ kind: "enum",
1485
+ label: "\uAE00\uC790 \uC815\uB82C",
1486
+ description: "\uC0DD\uB7B5\uD558\uBA74 \uC0C1\uC18D\uBC1B\uC740 \uC815\uB82C\uC744 \uADF8\uB300\uB85C \uC4F4\uB2E4.",
1487
+ options: [
1488
+ { value: "left", label: "\uC67C\uCABD" },
1489
+ { value: "center", label: "\uAC00\uC6B4\uB370" },
1490
+ { value: "right", label: "\uC624\uB978\uCABD" }
1491
+ ],
1492
+ group: "appearance"
1493
+ },
1245
1494
  {
1246
1495
  name: "value",
1247
1496
  kind: "node",
@@ -1251,7 +1500,14 @@ var TextMeta = {
1251
1500
  group: "content"
1252
1501
  },
1253
1502
  styleProp,
1254
- classNameProp
1503
+ classNameProp,
1504
+ growProp,
1505
+ shrinkProp,
1506
+ spanProp,
1507
+ selfAlignProp,
1508
+ // Text는 truncate의 주 대상이다 — v2 원본이 truncate 45회 + whitespace-nowrap 15회를
1509
+ // 거의 전부 글자에 걸었다. 폭이 좁아지는 자리(표 셀·목록 행)에서 줄바꿈 대신 …로 자른다.
1510
+ truncateProp
1255
1511
  ],
1256
1512
  children: { accepts: true, text: true, label: "\uD14D\uC2A4\uD2B8" },
1257
1513
  dom: { element: "p", elementProp: "as" },
@@ -1731,6 +1987,107 @@ var RemoteSearchResultsMeta = {
1731
1987
  },
1732
1988
  resize: { kind: "none" }
1733
1989
  };
1990
+ var SortableListMeta = {
1991
+ name: "SortableList",
1992
+ label: "\uC21C\uC11C \uBCC0\uACBD \uBAA9\uB85D",
1993
+ category: "data",
1994
+ icon: "list",
1995
+ description: '\uC790\uC2DD ForEach\uAC00 \uADF8\uB9B0 \uD589\uC744 \uC190\uC7A1\uC774\uB85C \uB04C\uC5B4 \uC21C\uC11C\uB97C \uBC14\uAFBC\uB2E4. \uD45C\uC758 "\uC815\uB82C \uAC00\uB2A5"(\uAC12 \uAE30\uC900 \uC815\uB82C)\uACFC \uB2E4\uB974\uB2E4. \uD3B8\uC9D1\uAE30 \uCE94\uBC84\uC2A4\uC5D0\uC11C\uB294 \uD45C\uC2DD\uB9CC \uBCF4\uC774\uACE0 \uB3D9\uC791\uD558\uC9C0 \uC54A\uB294\uB2E4.',
1996
+ props: [
1997
+ {
1998
+ name: "stateKey",
1999
+ kind: "string",
2000
+ label: "\uC21C\uC11C\uB97C \uBC14\uAFC0 \uBC30\uC5F4\uC758 \uC0C1\uD0DC \uD0A4",
2001
+ required: true,
2002
+ bindable: true,
2003
+ description: "arrayMove\uAC00 \uC4F8 \uD0A4. \uCD5C\uC0C1\uC704 \uD0A4\uC5EC\uC57C \uD55C\uB2E4 \u2014 \uC911\uCCA9 \uACBD\uB85C(a.0.b)\uB294 \uBB34\uB3D9\uC791\uC774\uB2E4. \uD589\uB9C8\uB2E4 \uB2E4\uB978 \uBC30\uC5F4\uC774 \uD544\uC694\uD558\uBA74 $calc concat\uC73C\uB85C \uD0A4\uB97C \uB9CC\uB4E0\uB2E4.",
2004
+ group: "data"
2005
+ },
2006
+ {
2007
+ name: "disabled",
2008
+ kind: "boolean",
2009
+ label: "\uC21C\uC11C \uBCC0\uACBD \uC7A0\uAE08",
2010
+ default: false,
2011
+ bindable: true,
2012
+ description: "\uC190\uC7A1\uC774\uB294 \uADF8\uB300\uB85C \uBCF4\uC774\uACE0 \uC7A0\uAE34 \uC0AC\uC720\uAC00 \uD234\uD301\uC73C\uB85C \uBD99\uB294\uB2E4.",
2013
+ group: "behavior"
2014
+ },
2015
+ classNameProp,
2016
+ styleProp
2017
+ ],
2018
+ // 자식은 보통 ForEach 하나다. `allow`는 금지가 아니라 "흔히 넣는 게 아니다"라는 약한
2019
+ // 경고로 걸린다(canDrop) — 정적 목록에 손잡이를 다는 쓰임까지 막지는 않으려는 것이다.
2020
+ children: { accepts: true, text: false, label: "\uD589 \uBAA9\uB85D(\uBCF4\uD1B5 ForEach \uD558\uB098)", allow: ["ForEach"] },
2021
+ dom: { element: "div" },
2022
+ /*
2023
+ * 프리셋의 배열이 `default`로만 있는 것은 **알고 고른 것**이다. `$state`만 두면 드롭한
2024
+ * 직후 캔버스에도 화면에도 아무것도 안 나온다("드롭했는데 사라졌다"). default를 두면
2025
+ * 행이 보이고, 실제로 끌면 손잡이가 "아직 배열 상태가 아니다"를 툴팁으로 말해 준다 —
2026
+ * 무엇을 더 해야 하는지가 화면에 남는 쪽을 골랐다.
2027
+ */
2028
+ preset: {
2029
+ component: "SortableList",
2030
+ props: { stateKey: "sortRows" },
2031
+ children: [
2032
+ {
2033
+ component: "ForEach",
2034
+ props: {
2035
+ source: {
2036
+ $state: "sortRows",
2037
+ default: [
2038
+ { id: "r1", name: "\uCCAB \uBC88\uC9F8 \uD56D\uBAA9" },
2039
+ { id: "r2", name: "\uB450 \uBC88\uC9F8 \uD56D\uBAA9" },
2040
+ { id: "r3", name: "\uC138 \uBC88\uC9F8 \uD56D\uBAA9" }
2041
+ ]
2042
+ }
2043
+ },
2044
+ children: [
2045
+ {
2046
+ component: "Row",
2047
+ children: [
2048
+ { component: "SortHandle", props: { index: { $index: true }, label: { $item: "name" } } },
2049
+ { component: "Text", props: { preset: "body", value: { $item: "name" } } }
2050
+ ]
2051
+ }
2052
+ ]
2053
+ }
2054
+ ]
2055
+ },
2056
+ resize: { kind: "none" }
2057
+ };
2058
+ var SortHandleMeta = {
2059
+ name: "SortHandle",
2060
+ label: "\uC21C\uC11C \uC190\uC7A1\uC774",
2061
+ category: "input",
2062
+ icon: "move",
2063
+ description: 'ForEach \uD589 \uC548\uC5D0 \uB450\uB294 \uADF8\uB9BD. \uB04C\uBA74 \uC21C\uC11C\uAC00 \uBC14\uB00C\uACE0, \uD0A4\uBCF4\uB4DC\uB294 Space\uB85C \uC9D1\uC5B4 \uC704\xB7\uC544\uB798 \uD654\uC0B4\uD45C\uB85C \uC62E\uAE34\uB2E4. index\uC5D0 {"$index": true}\uB97C \uB123\uC5B4\uC57C \uD55C\uB2E4.',
2064
+ props: [
2065
+ {
2066
+ name: "index",
2067
+ kind: "binding",
2068
+ label: "\uD589 \uBC88\uD638",
2069
+ required: true,
2070
+ bindable: true,
2071
+ description: '\uAC70\uC758 \uD56D\uC0C1 {"$index": true}. \uC774 \uAC12\uC774 \uACE7 arrayMove\uC758 from\uC774\uB2E4.',
2072
+ group: "data"
2073
+ },
2074
+ {
2075
+ name: "label",
2076
+ kind: "string",
2077
+ label: "\uBCF4\uC870\uAE30\uC220\uC6A9 \uC774\uB984",
2078
+ bindable: true,
2079
+ description: '"\u25CB\u25CB \uC21C\uC11C \uC190\uC7A1\uC774"\uB85C \uC77D\uD78C\uB2E4. \uBCF4\uD1B5 {"$item":"title"}. \uC5C6\uC73C\uBA74 "N\uBC88\uC9F8 \uD56D\uBAA9".',
2080
+ group: "content"
2081
+ },
2082
+ classNameProp,
2083
+ styleProp
2084
+ ],
2085
+ children: { accepts: false },
2086
+ dom: { element: "button" },
2087
+ preset: { component: "SortHandle", props: { index: { $index: true } } },
2088
+ // 그립은 24×24가 최소다(WCAG SC 2.5.8). 크기 손잡이를 달면 그 최소치를 깰 수 있다.
2089
+ resize: { kind: "none" }
2090
+ };
1734
2091
  var AlertMeta = {
1735
2092
  name: "Alert",
1736
2093
  label: "\uC54C\uB9BC \uBC15\uC2A4",
@@ -2082,6 +2439,8 @@ var coreComponentMeta = {
2082
2439
  Section: SectionMeta,
2083
2440
  Select: SelectMeta,
2084
2441
  Show: ShowMeta,
2442
+ SortableList: SortableListMeta,
2443
+ SortHandle: SortHandleMeta,
2085
2444
  Spacer: SpacerMeta,
2086
2445
  Spinner: SpinnerMeta,
2087
2446
  StatCard: StatCardMeta,
@@ -3796,12 +4155,33 @@ var StripMeta = {
3796
4155
  icon: "arrow-right",
3797
4156
  description: "\uC790\uC2DD\uC744 \uC904\uBC14\uAFC8 \uC5C6\uC774 \uD55C \uC904\uB85C \uB298\uC5B4\uB193\uACE0 \uAC00\uB85C\uB85C \uC2A4\uD06C\uB864\uD55C\uB2E4. \uCE74\uB4DC \uCE90\uB7EC\uC140 \uAC19\uC740 \uC790\uB9AC\uC5D0 \uC4F4\uB2E4.",
3798
4157
  props: [
4158
+ /*
4159
+ * 자유 CSS 길이에서 DS 간격 척도로 좁혔다.
4160
+ *
4161
+ * `gap`이 공통 어휘로 올라오면서 한 이름이 두 타입을 갖게 됐다 — 다른 컨테이너는
4162
+ * px 척도 문자열("12")인데 여기만 자유 길이("var(--wp-space-3)")라, 속성 패널에서
4163
+ * 같은 이름이 자리마다 다른 입력을 그리게 된다.
4164
+ *
4165
+ * 실사용 4건이 전부 `"var(--wp-space-3)"`(=12px)이고 새 기본값도 12px이라
4166
+ * 값이 무시돼도 화면이 그대로다. 그래도 편집기가 옛 값을 지우지 않도록 legacy 후보로 남긴다.
4167
+ */
3799
4168
  {
3800
4169
  name: "gap",
3801
- kind: "string",
4170
+ kind: "enum",
3802
4171
  label: "\uD56D\uBAA9 \uAC04\uACA9",
3803
- default: "var(--wp-space-3)",
3804
- description: "CSS \uAE38\uC774. \uAC04\uACA9 \uD1A0\uD070(var(--wp-space-N))\uC744 \uC4F0\uB294 \uD3B8\uC774 \uB0AB\uB2E4.",
4172
+ default: "12",
4173
+ description: "DS \uAC04\uACA9 \uCC99\uB3C4(px).",
4174
+ options: [
4175
+ { value: "2", label: "2px" },
4176
+ { value: "4", label: "4px" },
4177
+ { value: "8", label: "8px" },
4178
+ { value: "12", label: "12px" },
4179
+ { value: "16", label: "16px" },
4180
+ { value: "20", label: "20px" },
4181
+ { value: "24", label: "24px" },
4182
+ { value: "32", label: "32px" },
4183
+ { value: "var(--wp-space-3)", label: "12px (\uC61B \uD45C\uAE30)", legacy: true }
4184
+ ],
3805
4185
  group: "layout"
3806
4186
  },
3807
4187
  {
@@ -3817,7 +4197,7 @@ var StripMeta = {
3817
4197
  dom: { element: "div" },
3818
4198
  preset: {
3819
4199
  component: "Strip",
3820
- props: { gap: "var(--wp-space-3)" },
4200
+ props: { gap: "12" },
3821
4201
  children: [
3822
4202
  { component: "Card", props: { title: "\uCE74\uB4DC 1" } },
3823
4203
  { component: "Card", props: { title: "\uCE74\uB4DC 2" } },
@@ -3883,4 +4263,4 @@ function paletteGroups(catalog = allComponentMeta) {
3883
4263
  })).filter((group) => group.items.length > 0);
3884
4264
  }
3885
4265
 
3886
- export { ActionsMeta, AlertMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, FieldMeta, ForEachMeta, FormMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PrintSheetMeta, ProgressBarMeta, RadioMeta, RemoteSearchResultsMeta, RowMeta, SDUI_CATEGORIES, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta };
4266
+ export { ActionsMeta, AlertMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, FieldMeta, ForEachMeta, FormMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PrintSheetMeta, ProgressBarMeta, RadioMeta, RemoteSearchResultsMeta, RowMeta, SDUI_CATEGORIES, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta };
package/dist/styles.css CHANGED
@@ -306,10 +306,20 @@
306
306
  .wp-num { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--wp-text-muted); }
307
307
 
308
308
  /* ---------- 레이아웃 프리미티브 ---------- */
309
- .wp-col { display: flex; flex-direction: column; gap: var(--wp-space-4); min-width: 0; }
309
+ /*
310
+ * gap 기본값은 **ERP의 styles/css/layout.css를 정본으로 삼아** 맞춘 값이다.
311
+ * 실측상 두 시트가 같은 클래스에 다른 값을 갖고 있었다 — .wp-col은 여기 16px / ERP 8px,
312
+ * .wp-grid는 여기 16px / ERP 20px(--wp-gutter). ERP가 이 시트를 로드하지 않아서
313
+ * (main.tsx가 자기 styles/index.css만 import한다) 지금까지 사고가 나지 않았을 뿐이다.
314
+ *
315
+ * 어긋난 채로는 메타데이터의 `default`를 적을 수가 없다. 편집기는 프롭 값이 default와
316
+ * 같으면 스펙에서 지우는데, 두 소비자의 실제 기본이 다르면 지운 순간 한쪽 화면이 바뀐다.
317
+ * 화면 85개가 이미 ERP 값으로 그려져 있으므로 그쪽을 정본으로 잡고 이 시트를 옮겼다.
318
+ */
319
+ .wp-col { display: flex; flex-direction: column; gap: var(--wp-space-2); min-width: 0; }
310
320
  .wp-row { display: flex; align-items: center; gap: var(--wp-space-2); min-width: 0; }
311
321
  .wp-row--between { justify-content: space-between; }
312
- .wp-grid { display: grid; gap: var(--wp-space-4); min-width: 0; }
322
+ .wp-grid { display: grid; gap: var(--wp-space-5); min-width: 0; }
313
323
  .wp-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
314
324
  .wp-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
315
325
  .wp-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@@ -1,4 +1,5 @@
1
1
  import React__default from 'react';
2
+ import { f as SduiGapScale } from '../layout-BnYUuWC2.js';
2
3
 
3
4
  /**
4
5
  * Strip — 가로 스크롤 스트립.
@@ -10,8 +11,14 @@ import React__default from 'react';
10
11
 
11
12
  interface StripProps {
12
13
  children: React__default.ReactNode;
13
- /** 항목 간격(CSS 길이). 기본 var(--wp-space-3) */
14
- gap?: string;
14
+ /**
15
+ * 항목 간격 — 간격 척도(px 문자열). 기본 12px.
16
+ *
17
+ * 예전에는 자유 CSS 길이(`'var(--wp-space-3)'`)를 받았다. `gap`이 공통 어휘로 올라오면서
18
+ * 한 이름이 두 타입을 갖게 되어 좁혔다 — 실사용 4건이 전부 `"var(--wp-space-3)"`라
19
+ * `"12"`로 무손실 이관된다. 척도 밖 값은 무시되고 기본값이 남는다.
20
+ */
21
+ gap?: SduiGapScale;
15
22
  /** 항목 시작점에 스크롤 스냅 */
16
23
  snap?: boolean;
17
24
  }
@@ -1 +1,2 @@
1
- export { Strip } from '../chunk-IL2KS4WS.js';
1
+ export { Strip } from '../chunk-PJRXPMI3.js';
2
+ import '../chunk-QBIVW7E6.js';
@@ -40,6 +40,7 @@ export { TreePickerProps } from './TreePicker.js';
40
40
  import { TreeView } from './TreeView.js';
41
41
  export { TreeNode, TreeViewProps } from './TreeView.js';
42
42
  export { AutocompleteField, AutocompleteFieldProps, AutocompleteOption, AutocompleteSearchFn, AutocompleteSearchResult, toAutocompleteOptions } from './AutocompleteField.js';
43
+ import '../layout-BnYUuWC2.js';
43
44
 
44
45
  /**
45
46
  * `createRegistry(widgetComponents)`로 어휘에 얹는 묶음.
@@ -4,8 +4,8 @@ import { SecureScreen } from '../chunk-APCXOCAO.js';
4
4
  export { SecureScreen } from '../chunk-APCXOCAO.js';
5
5
  import { StackedMeter } from '../chunk-7Y4J7EOK.js';
6
6
  export { StackedMeter } from '../chunk-7Y4J7EOK.js';
7
- import { Strip } from '../chunk-IL2KS4WS.js';
8
- export { Strip } from '../chunk-IL2KS4WS.js';
7
+ import { Strip } from '../chunk-PJRXPMI3.js';
8
+ export { Strip } from '../chunk-PJRXPMI3.js';
9
9
  import { SummaryTable } from '../chunk-USKRM22W.js';
10
10
  export { SummaryTable } from '../chunk-USKRM22W.js';
11
11
  import { TagMultiSelect } from '../chunk-4SU2KYPU.js';
@@ -32,6 +32,7 @@ import { PeriodFilter } from '../chunk-DGPRX4MU.js';
32
32
  export { PeriodFilter } from '../chunk-DGPRX4MU.js';
33
33
  import { PrintSheet } from '../chunk-KBHI3IUR.js';
34
34
  export { PrintSheet } from '../chunk-KBHI3IUR.js';
35
+ import '../chunk-QBIVW7E6.js';
35
36
  export { AutocompleteField, toAutocompleteOptions } from '../chunk-MOIU7MUA.js';
36
37
  import '../chunk-KADFN76X.js';
37
38
  import { ColumnBoard } from '../chunk-Q6SBH63R.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipco/sdui",
3
- "version": "0.4.2",
3
+ "version": "0.6.0",
4
4
  "description": "WIPCO 서버 주도 UI(SDUI) 렌더러 — JSON 페이지 스펙을 React 컴포넌트로 렌더링",
5
5
  "keywords": [
6
6
  "sdui",
@@ -144,6 +144,7 @@
144
144
  "dev": "tsup --watch",
145
145
  "typecheck": "tsc --noEmit",
146
146
  "check:meta": "node scripts/check-meta.mjs",
147
+ "test": "tsx --test test/*.test.ts",
147
148
  "prepack": "pnpm run build"
148
149
  },
149
150
  "peerDependencies": {
@@ -164,6 +165,7 @@
164
165
  "@types/react": "^19.0.0",
165
166
  "@types/react-dom": "^19.0.0",
166
167
  "tsup": "^8.5.0",
168
+ "tsx": "^4.20.0",
167
169
  "typescript": "^5.7.0"
168
170
  }
169
171
  }