@stn-uiux/pub-ui 0.1.56 → 0.1.58

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 (95) hide show
  1. package/dist/{chunk-L7DYM4V7.js → chunk-2FHXIAM3.js} +10 -28
  2. package/dist/{chunk-L7DYM4V7.js.map → chunk-2FHXIAM3.js.map} +1 -1
  3. package/dist/chunk-2WKT7X65.js +407 -0
  4. package/dist/chunk-2WKT7X65.js.map +1 -0
  5. package/dist/{chunk-THCCTVUM.js → chunk-5F63CMM7.js} +11 -1
  6. package/dist/chunk-5F63CMM7.js.map +1 -0
  7. package/dist/{chunk-Q3W7QA7N.js → chunk-75GHU6VI.js} +24 -43
  8. package/dist/chunk-75GHU6VI.js.map +1 -0
  9. package/dist/{chunk-4C7ABT2K.js → chunk-AE4CKAEK.js} +3 -3
  10. package/dist/chunk-AE4CKAEK.js.map +1 -0
  11. package/dist/{chunk-P5V6SFR7.js → chunk-EDXSK54U.js} +2 -2
  12. package/dist/{chunk-GR76L7M7.js → chunk-EQVFEZEQ.js} +2 -2
  13. package/dist/{chunk-OMCBVK57.js → chunk-J46EPVSY.js} +2 -2
  14. package/dist/{chunk-WRGBYWRV.js → chunk-LKVTW54X.js} +1 -1
  15. package/dist/chunk-LKVTW54X.js.map +1 -0
  16. package/dist/{chunk-V7HD6SBG.js → chunk-PVF77NHZ.js} +5 -3
  17. package/dist/{chunk-V7HD6SBG.js.map → chunk-PVF77NHZ.js.map} +1 -1
  18. package/dist/{chunk-XZ3JOUX2.js → chunk-TDLGKV4C.js} +2 -1
  19. package/dist/{chunk-XZ3JOUX2.js.map → chunk-TDLGKV4C.js.map} +1 -1
  20. package/dist/{chunk-ERPXTTTO.js → chunk-XBFXX3D6.js} +17 -15
  21. package/dist/chunk-XBFXX3D6.js.map +1 -0
  22. package/dist/chunk-XPARWRVD.js +9 -0
  23. package/dist/chunk-XPARWRVD.js.map +1 -0
  24. package/dist/{chunk-S4YA4H2S.js → chunk-YBNEQ5LB.js} +2 -2
  25. package/dist/cli.js +10 -10
  26. package/dist/data/index.d.ts +2 -2
  27. package/dist/data/index.js +16 -14
  28. package/dist/data/stnAlertCenter.d.ts +4 -3
  29. package/dist/data/stnAlertCenter.js +1 -1
  30. package/dist/data/stnBreadcrumb.js +3 -3
  31. package/dist/data/stnDatePicker.js +2 -2
  32. package/dist/data/stnDateRangeField.d.ts +1 -1
  33. package/dist/data/stnDateRangeField.js +1 -1
  34. package/dist/data/stnDropdown.d.ts +1 -1
  35. package/dist/data/stnDropdown.js +1 -1
  36. package/dist/data/stnHeader.js +3 -3
  37. package/dist/data/stnLayer0Background.js +1 -1
  38. package/dist/data/stnLayer0BackgroundAssets.d.ts +17 -16
  39. package/dist/data/stnLayer0BackgroundAssets.js +3 -1
  40. package/dist/data/stnPackageVersion.d.ts +2 -2
  41. package/dist/data/stnPackageVersion.js +1 -1
  42. package/dist/data/stnPopup.d.ts +19 -41
  43. package/dist/data/stnPopup.js +1 -1
  44. package/dist/data/stnSearchRequirement.d.ts +4 -4
  45. package/dist/data/stnSearchRequirement.js +1 -1
  46. package/dist/data/stnSideNavItem.js +3 -3
  47. package/dist/data/stnSizeSemantic.js +1 -1
  48. package/dist/data/stnSystemIcons.js +2 -2
  49. package/dist/data/stnSystemIconsData.generated.js +1 -1
  50. package/dist/index.d.ts +2 -2
  51. package/dist/index.js +16 -14
  52. package/package.json +2 -1
  53. package/styles/@assets/svg/system/line/eye-off.svg +5 -0
  54. package/styles/components/stn-btn.css +1 -1
  55. package/styles/components/stn-date-picker.css +13 -5
  56. package/styles/components/stn-date-range-field.css +153 -16
  57. package/styles/components/stn-dropdown.css +150 -38
  58. package/styles/components/stn-label-prefix.css +319 -0
  59. package/styles/components/stn-popup.css +78 -132
  60. package/styles/components/stn-search-requirement.css +27 -20
  61. package/styles/components/stn-text-field.css +401 -374
  62. package/styles/components/stn-toast.css +17 -0
  63. package/styles/components/stn-toggle-button.css +37 -0
  64. package/styles/patterns/stn-alert-center.css +85 -0
  65. package/styles/patterns/stn-tree.css +157 -0
  66. package/styles/style-pub.css +1 -0
  67. package/styles/tokens/stn-colors-semantic.css +7 -1
  68. package/styles/tokens/stn-radius-semantic.css +3 -2
  69. package/styles/tokens/stn-size-semantic.css +19 -6
  70. package/styles/tokens/stn-size.css +2 -0
  71. package/styles/tokens/stn-spacing-semantic.css +12 -0
  72. package/styles/tokens/stn-typography.css +1 -0
  73. package/dist/chunk-2EMXBNFK.js +0 -9
  74. package/dist/chunk-2EMXBNFK.js.map +0 -1
  75. package/dist/chunk-4C7ABT2K.js.map +0 -1
  76. package/dist/chunk-ERPXTTTO.js.map +0 -1
  77. package/dist/chunk-Q3W7QA7N.js.map +0 -1
  78. package/dist/chunk-THCCTVUM.js.map +0 -1
  79. package/dist/chunk-WRGBYWRV.js.map +0 -1
  80. package/dist/chunk-ZI6EF4XD.js +0 -209
  81. package/dist/chunk-ZI6EF4XD.js.map +0 -1
  82. package/styles/@assets/images/layer0/dashboard-dark.png +0 -0
  83. package/styles/@assets/images/layer0/dashboard-light.png +0 -0
  84. package/styles/@assets/images/layer0/login-dark.png +0 -0
  85. package/styles/@assets/images/layer0/login-light.png +0 -0
  86. package/styles/@assets/images/layer0/map-dark.png +0 -0
  87. package/styles/@assets/images/layer0/map-light.png +0 -0
  88. package/styles/@assets/images/layer0/showroom-a-dark.png +0 -0
  89. package/styles/@assets/images/layer0/showroom-a-light.png +0 -0
  90. package/styles/@assets/images/layer0/showroom-b-dark.png +0 -0
  91. package/styles/@assets/images/layer0/showroom-b-light.png +0 -0
  92. /package/dist/{chunk-P5V6SFR7.js.map → chunk-EDXSK54U.js.map} +0 -0
  93. /package/dist/{chunk-GR76L7M7.js.map → chunk-EQVFEZEQ.js.map} +0 -0
  94. /package/dist/{chunk-OMCBVK57.js.map → chunk-J46EPVSY.js.map} +0 -0
  95. /package/dist/{chunk-S4YA4H2S.js.map → chunk-YBNEQ5LB.js.map} +0 -0
@@ -34,19 +34,19 @@
34
34
  .stn-dropdown>.selected {
35
35
  position: relative;
36
36
  z-index: 2;
37
- display: block !important;
37
+ display: block;
38
38
  width: 100%;
39
39
  box-sizing: border-box;
40
40
  padding-right: 36px;
41
- border: 1px solid var(--stn-input-border);
41
+ border: var(--stn-size-1, 1px) solid var(--stn-input-border);
42
42
  background-color: var(--stn-input-bg);
43
43
  color: var(--stn-input-fg, var(--stn-text-primary));
44
44
  font-weight: var(--stn-font-weight-medium);
45
45
  overflow: hidden;
46
46
  text-overflow: ellipsis;
47
47
  white-space: nowrap;
48
- -webkit-line-clamp: unset !important;
49
- -webkit-box-orient: unset !important;
48
+ -webkit-line-clamp: unset;
49
+ -webkit-box-orient: unset;
50
50
  transition: border-color var(--stn-motion-duration-fast, 150ms) ease,
51
51
  background-color var(--stn-motion-duration-fast, 150ms) ease;
52
52
  }
@@ -57,13 +57,15 @@
57
57
 
58
58
  /* ==========================================================================
59
59
  2. Prop: size (sm · md · lg · xl)
60
+ 표준 통일 스케일: sm(24px) · md(32px, 기본값) · lg(40px) · xl(56px)
61
+ 8px 그리드 — TextField / Button / ToggleButton과 완벽 정렬
60
62
  ========================================================================== */
61
63
 
62
64
  /* 2-1. Size sm (24px) */
63
65
  .stn-dropdown.sm>.selected {
64
- height: var(--stn-dropdown-height-sm) !important;
66
+ height: var(--stn-dropdown-height-sm);
65
67
  line-height: var(--stn-line-height-px-22);
66
- padding: 0 28px 0 10px;
68
+ padding: 0 24px 0 10px;
67
69
  border-radius: var(--stn-radius-dropdown-sm);
68
70
  font-size: var(--stn-text-body-small-size);
69
71
  }
@@ -84,9 +86,9 @@
84
86
 
85
87
  /* 2-2. Size md (32px — 기본값) */
86
88
  .stn-dropdown.md>.selected {
87
- height: var(--stn-dropdown-height-md) !important;
89
+ height: var(--stn-dropdown-height-md);
88
90
  line-height: var(--stn-line-height-px-30);
89
- padding: 0 36px 0 12px;
91
+ padding: 0 28px 0 12px;
90
92
  border-radius: var(--stn-radius-dropdown-md);
91
93
  font-size: var(--stn-text-body-small-size);
92
94
  }
@@ -107,7 +109,7 @@
107
109
 
108
110
  /* 2-3. Size lg (40px) */
109
111
  .stn-dropdown.lg>.selected {
110
- height: var(--stn-dropdown-height-lg) !important;
112
+ height: var(--stn-dropdown-height-lg);
111
113
  line-height: var(--stn-line-height-px-38);
112
114
  padding: 0 36px 0 12px;
113
115
  border-radius: var(--stn-radius-dropdown-lg);
@@ -128,30 +130,30 @@
128
130
  font-size: var(--stn-text-body-medium-size);
129
131
  }
130
132
 
131
- /* 2-4. Size xl (52px — Prominent) */
133
+ /* 2-4. Size xl (56px) */
132
134
  .stn-dropdown.xl:not(.w80):not(.w100):not(.w120):not(.w140):not(.w160):not(.w180):not(.w200):not(.full) {
133
135
  width: 200px;
134
136
  }
135
137
 
136
138
  .stn-dropdown.xl>.selected {
137
- height: var(--stn-dropdown-height-prominent, 52px) !important;
138
- line-height: var(--stn-line-height-px-50, 50px);
139
+ height: var(--stn-dropdown-height-xl);
140
+ line-height: var(--stn-line-height-px-54);
139
141
  padding: 0 36px 0 14px;
140
- border-radius: var(--stn-radius-dropdown-prominent, 8px);
142
+ border-radius: var(--stn-radius-dropdown-lg);
141
143
  font-size: var(--stn-text-body-large-size, 15px);
142
144
  }
143
145
 
144
146
  .stn-dropdown.xl.on>.selected {
145
- border-radius: var(--stn-radius-dropdown-prominent) var(--stn-radius-dropdown-prominent) 0 0;
147
+ border-radius: var(--stn-radius-dropdown-lg) var(--stn-radius-dropdown-lg) 0 0;
146
148
  }
147
149
 
148
150
  .stn-dropdown.xl>.select_option {
149
- border-radius: 0 0 var(--stn-radius-dropdown-prominent) var(--stn-radius-dropdown-prominent);
151
+ border-radius: 0 0 var(--stn-radius-dropdown-lg) var(--stn-radius-dropdown-lg);
150
152
  }
151
153
 
152
154
  .stn-dropdown.xl>.select_option>li {
153
- height: var(--stn-dropdown-height-prominent);
154
- line-height: var(--stn-line-height-px-50);
155
+ height: var(--stn-dropdown-height-xl);
156
+ line-height: var(--stn-line-height-px-54);
155
157
  font-size: var(--stn-text-body-large-size);
156
158
  }
157
159
 
@@ -161,14 +163,14 @@
161
163
 
162
164
  /* 3-1. Outline (기본값 — 전체 테두리 박스) */
163
165
  .stn-dropdown.outline>.selected {
164
- border: 1px solid var(--stn-input-border);
166
+ border: var(--stn-size-1, 1px) solid var(--stn-input-border);
165
167
  background-color: var(--stn-input-bg);
166
168
  }
167
169
 
168
170
  /* 3-2. Standard (하단 밑줄 라인만 하나) */
169
171
  .stn-dropdown.standard>.selected {
170
172
  border: none;
171
- border-bottom: 1px solid var(--stn-input-border);
173
+ border-bottom: var(--stn-size-1, 1px) solid var(--stn-input-border);
172
174
  border-radius: 0;
173
175
  background-color: transparent;
174
176
  padding-left: 2px;
@@ -180,11 +182,29 @@
180
182
 
181
183
  /* 3-3. Filled (라인 없이 배경 채움 — 토큰 연동: 다크 gray-750 / 라이트 gray-50) */
182
184
  .stn-dropdown.filled>.selected {
183
- border: 1px solid var(--stn-input-filled-border, transparent);
185
+ border: var(--stn-size-1, 1px) solid var(--stn-input-filled-border, transparent);
184
186
  background-color: var(--stn-input-filled-bg, var(--stn-input-bg));
185
187
  color: var(--stn-input-fg, var(--stn-text-primary));
186
188
  }
187
189
 
190
+ /* 3-4. Transparent (테두리·배경 없음 — StnLabelPrefix 등 래퍼 내부 조합용) */
191
+ .stn-dropdown.transparent>.selected {
192
+ border: none;
193
+ background-color: transparent;
194
+ border-radius: 0;
195
+ }
196
+
197
+ .stn-dropdown.transparent.on>.selected,
198
+ .stn-dropdown.transparent:focus-within>.selected {
199
+ border: none;
200
+ background: transparent;
201
+ }
202
+
203
+ .stn-dropdown.transparent.is-error>.selected,
204
+ .stn-dropdown.transparent[aria-invalid='true']>.selected {
205
+ border-bottom: var(--stn-size-1, 1px) solid var(--stn-feedback-error);
206
+ }
207
+
188
208
  /* ==========================================================================
189
209
  4. Prop: state (Normal · Focus/Open · Disabled · Error · ReadOnly)
190
210
  ========================================================================== */
@@ -214,7 +234,7 @@
214
234
 
215
235
  .stn-dropdown.filled.on>.selected,
216
236
  .stn-dropdown.filled:focus-within>.selected {
217
- border: 1px solid var(--stn-input-focus-fg);
237
+ border: var(--stn-size-1, 1px) solid var(--stn-input-focus-fg);
218
238
  }
219
239
 
220
240
  /* 4-2. Disabled State (.is-disabled, [aria-disabled='true']) */
@@ -244,7 +264,7 @@
244
264
  /* 4-4. ReadOnly State (.is-readonly, [aria-readonly='true']) */
245
265
  .stn-dropdown.is-readonly>.selected,
246
266
  .stn-dropdown[aria-readonly='true']>.selected {
247
- cursor: default !important;
267
+ cursor: default;
248
268
  pointer-events: none;
249
269
  background-color: var(--stn-dropdown-readonly-bg);
250
270
  opacity: 0.85;
@@ -282,7 +302,7 @@
282
302
  }
283
303
 
284
304
  .stn-dropdown.full {
285
- width: 100% !important;
305
+ width: 100%;
286
306
  display: block;
287
307
  }
288
308
 
@@ -297,12 +317,110 @@
297
317
  box-sizing: border-box;
298
318
  }
299
319
 
300
- .stn-dropdown-field--full,
301
- .stn-dropdown-wrap--full {
302
- display: flex;
320
+ /* Width Presets (GEMINI.md 표준: w80~w200, full) */
321
+ :is(.stn-dropdown, .stn-dropdown-wrap).w80 {
322
+ width: var(--stn-size-80, 80px);
323
+ }
324
+ :is(.stn-dropdown, .stn-dropdown-wrap).w100 {
325
+ width: var(--stn-size-100, 100px);
326
+ }
327
+ :is(.stn-dropdown, .stn-dropdown-wrap).w120 {
328
+ width: var(--stn-size-120, 120px);
329
+ }
330
+ :is(.stn-dropdown, .stn-dropdown-wrap).w140 {
331
+ width: var(--stn-size-140, 140px);
332
+ }
333
+ :is(.stn-dropdown, .stn-dropdown-wrap).w160 {
334
+ width: var(--stn-size-160, 160px);
335
+ }
336
+ :is(.stn-dropdown, .stn-dropdown-wrap).w180 {
337
+ width: var(--stn-size-180, 180px);
338
+ }
339
+ :is(.stn-dropdown, .stn-dropdown-wrap).w200 {
340
+ width: var(--stn-size-200, 200px);
341
+ }
342
+ :is(.stn-dropdown, .stn-dropdown-wrap):is(.full, .stn-dropdown-wrap--full, .stn-dropdown-field--full, .w100p) {
303
343
  width: 100%;
304
344
  }
305
345
 
346
+ /* Label & Wrap Container Layout */
347
+ .stn-dropdown-wrap {
348
+ box-sizing: border-box;
349
+ display: inline-flex;
350
+ flex-direction: column;
351
+ align-items: stretch;
352
+ flex-shrink: 0;
353
+ max-width: 100%;
354
+ vertical-align: top;
355
+ }
356
+
357
+ .stn-dropdown-wrap .stn-dropdown {
358
+ width: 100%;
359
+ min-width: 0;
360
+ max-width: 100%;
361
+ }
362
+
363
+ .stn-dropdown-wrap__body {
364
+ display: inline-flex;
365
+ flex-direction: column;
366
+ flex: 1 1 auto;
367
+ min-width: 0;
368
+ }
369
+
370
+ /* Row Layout (Left/Right Label) */
371
+ .stn-dropdown-wrap--row {
372
+ flex-direction: row;
373
+ align-items: center;
374
+ gap: var(--stn-space-8, 8px);
375
+ }
376
+
377
+ .stn-dropdown-wrap--row .stn-dropdown-wrap__body {
378
+ width: auto;
379
+ flex: 1 1 auto;
380
+ }
381
+
382
+ /* Column Layout (Top Label) */
383
+ .stn-dropdown-wrap--col {
384
+ flex-direction: column;
385
+ gap: var(--stn-space-6, 6px);
386
+ }
387
+
388
+ .stn-dropdown-wrap--col .stn-dropdown-wrap__body {
389
+ width: 100%;
390
+ }
391
+
392
+ /* Label Styles */
393
+ .stn-dropdown__label {
394
+ box-sizing: border-box;
395
+ display: inline-flex;
396
+ align-items: center;
397
+ gap: var(--stn-space-4, 4px);
398
+ font-family: var(--stn-font-body, inherit);
399
+ font-size: var(--stn-text-body-small-size, 12px);
400
+ font-weight: var(--stn-font-weight-medium, 500);
401
+ color: var(--stn-text-primary);
402
+ line-height: 1;
403
+ white-space: nowrap;
404
+ user-select: none;
405
+ cursor: pointer;
406
+ flex-shrink: 0;
407
+ }
408
+
409
+ .stn-dropdown__label-icon {
410
+ display: inline-flex;
411
+ align-items: center;
412
+ justify-content: center;
413
+ color: var(--stn-text-secondary);
414
+ }
415
+
416
+ .stn-dropdown__required {
417
+ color: var(--stn-feedback-error);
418
+ font-weight: var(--stn-font-weight-bold);
419
+ line-height: 1;
420
+ margin-inline-start: var(--stn-space-2, 2px);
421
+ }
422
+
423
+ /* Legacy helper field backward compatibility */
306
424
  .stn-dropdown-field--pos-bottom,
307
425
  .stn-dropdown-wrap--bottom {
308
426
  flex-direction: column;
@@ -317,13 +435,6 @@
317
435
  gap: var(--stn-space-4, 4px);
318
436
  }
319
437
 
320
- .stn-dropdown-field--pos-bottom>.stn-dropdown,
321
- .stn-dropdown-wrap--bottom>.stn-dropdown,
322
- .stn-dropdown-field--pos-top>.stn-dropdown,
323
- .stn-dropdown-wrap--top>.stn-dropdown {
324
- width: 100%;
325
- }
326
-
327
438
  .stn-dropdown-field--pos-left,
328
439
  .stn-dropdown-wrap--left {
329
440
  flex-direction: row-reverse;
@@ -345,13 +456,14 @@
345
456
  color: var(--stn-dropdown-helper);
346
457
  word-break: break-word;
347
458
  white-space: nowrap;
459
+ margin-top: var(--stn-space-4, 4px);
348
460
  }
349
461
 
350
462
  .stn-dropdown-field.is-error .stn-dropdown-field__helper,
351
463
  .stn-dropdown-field__helper--error,
352
464
  .stn-dropdown-wrap.is-error .stn-dropdown__helper,
353
465
  .stn-dropdown__helper--error {
354
- color: var(--stn-feedback-error) !important;
466
+ color: var(--stn-feedback-error);
355
467
  }
356
468
 
357
469
  /* ==========================================================================
@@ -398,7 +510,7 @@
398
510
  list-style: none;
399
511
  box-sizing: border-box;
400
512
  background-color: var(--stn-dropdown-menu-bg, var(--stn-input-bg));
401
- border: 1px solid var(--stn-input-border);
513
+ border: var(--stn-size-1, 1px) solid var(--stn-input-border);
402
514
  z-index: var(--stn-dropdown-menu-z, 150);
403
515
  box-shadow: var(--stn-dropdown-menu-shadow);
404
516
  max-height: 220px;
@@ -453,7 +565,7 @@
453
565
  .stn-table .stn-table__footer .stn-dropdown>.select_option {
454
566
  top: auto;
455
567
  bottom: 100%;
456
- border-top: 1px solid var(--stn-input-border);
568
+ border-top: var(--stn-size-1, 1px) solid var(--stn-input-border);
457
569
  border-bottom: none;
458
570
  box-shadow: var(--stn-dropdown-menu-shadow-flip);
459
571
  }
@@ -461,8 +573,8 @@
461
573
  .stn-dropdown.up.on>.selected,
462
574
  .stn-dropdown.stn-table__page-size.on>.selected,
463
575
  .stn-table .stn-table__footer .stn-dropdown.on>.selected {
464
- border-top: none !important;
465
- border-bottom: 1px solid var(--stn-input-border) !important;
576
+ border-top: none;
577
+ border-bottom: var(--stn-size-1, 1px) solid var(--stn-input-border);
466
578
  }
467
579
 
468
580
  .stn-dropdown.up.sm>.select_option,
@@ -0,0 +1,319 @@
1
+ /**
2
+ * StnLabelPrefix — 아이콘+레이블이 내장된 입력 래퍼 컴포넌트
3
+ *
4
+ * 구조:
5
+ * div.stn-label-prefix
6
+ * ├── .stn-label-prefix__label (아이콘 + 텍스트 + 구분선)
7
+ * └── .stn-label-prefix__control (children slot — StnDropdown·StnTextField·StnDateRangeField 등)
8
+ *
9
+ * Props:
10
+ * variant : outline(기본) · filled · standard · transparent
11
+ * size : sm(24px) · md(32px, 기본) · lg(40px)
12
+ * radius : none · sm · md · lg · xl (기본은 size에 따름)
13
+ * position : prefix(왼쪽, 기본) · suffix(오른쪽)
14
+ *
15
+ * ==========================================================================
16
+ * 1. Base Layout
17
+ * 2. Label Area (.stn-label-prefix__label)
18
+ * 3. Divider (.stn-label-prefix__divider)
19
+ * 4. Control Slot (.stn-label-prefix__control)
20
+ * 5. Size (sm · md · lg)
21
+ * 6. Variant (outline · filled · standard · transparent)
22
+ * 7. Focus-within State
23
+ * 8. Suffix Position
24
+ * 9. Radius Override
25
+ * 10. Width Presets
26
+ * 11. Disabled State
27
+ * ==========================================================================
28
+ */
29
+
30
+ /* ==========================================================================
31
+ 1. Base Layout
32
+ ========================================================================== */
33
+ .stn-label-prefix {
34
+ display: inline-flex;
35
+ align-items: stretch;
36
+ box-sizing: border-box;
37
+ max-width: 100%;
38
+ overflow: hidden;
39
+ vertical-align: middle;
40
+ transition: border-color var(--stn-motion-duration-fast, 150ms) ease;
41
+ }
42
+
43
+ /* ==========================================================================
44
+ 2. Label Area
45
+ ========================================================================== */
46
+ .stn-label-prefix__label {
47
+ display: inline-flex;
48
+ align-items: center;
49
+ flex-shrink: 0;
50
+ gap: var(--stn-space-16);
51
+ padding-inline-start: var(--stn-space-16);
52
+ padding-inline-end: 0;
53
+ white-space: nowrap;
54
+ color: var(--stn-label-prefix-label-color, var(--stn-text-secondary));
55
+ background-color: transparent;
56
+ font-weight: var(--stn-font-weight-medium);
57
+ user-select: none;
58
+ }
59
+
60
+ .stn-label-prefix__icon {
61
+ display: inline-flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ flex-shrink: 0;
65
+ }
66
+
67
+ .stn-label-prefix__text {
68
+ display: inline-flex;
69
+ align-items: center;
70
+ }
71
+
72
+ .stn-label-prefix__required {
73
+ color: var(--stn-feedback-error);
74
+ font-weight: var(--stn-font-weight-bold);
75
+ line-height: var(--stn-line-height-tight);
76
+ margin-inline-start: var(--stn-space-2, 2px);
77
+ }
78
+
79
+ /* ==========================================================================
80
+ 3. Divider
81
+ ========================================================================== */
82
+ .stn-label-prefix__divider {
83
+ flex-shrink: 0;
84
+ width: var(--stn-size-1, 1px);
85
+ align-self: stretch;
86
+ background-color: var(--stn-label-prefix-divider, var(--stn-input-border));
87
+ margin: var(--stn-space-8) 0;
88
+ }
89
+
90
+ /* ==========================================================================
91
+ 4. Control Slot
92
+ ========================================================================== */
93
+ .stn-label-prefix__control {
94
+ flex: 1 1 auto;
95
+ min-width: 0;
96
+ display: flex;
97
+ align-items: center;
98
+ }
99
+
100
+ /* children(Dropdown 등)이 full height를 차지하도록 */
101
+ .stn-label-prefix__control > * {
102
+ width: 100%;
103
+ }
104
+
105
+ /* ==========================================================================
106
+ 5. Size (sm · md · lg)
107
+ ========================================================================== */
108
+
109
+ /* sm — 32px */
110
+ .stn-label-prefix.sm {
111
+ height: var(--stn-dropdown-height-sm, 32px);
112
+ border-radius: var(--stn-radius-input-sm, 4px);
113
+ font-size: var(--stn-text-body-small-size);
114
+ }
115
+
116
+ .stn-label-prefix.sm > .stn-label-prefix__control {
117
+ padding: 0 var(--stn-space-8);
118
+ }
119
+
120
+ /* md — 40px (기본값) */
121
+ .stn-label-prefix.md {
122
+ height: var(--stn-dropdown-height-md, 40px);
123
+ border-radius: var(--stn-radius-input-md, 4px);
124
+ font-size: var(--stn-text-body-small-size);
125
+ }
126
+
127
+ .stn-label-prefix.md > .stn-label-prefix__control {
128
+ padding: 0 var(--stn-space-10);
129
+ }
130
+
131
+ /* lg — 56px */
132
+ .stn-label-prefix.lg {
133
+ height: var(--stn-dropdown-height-lg, 56px);
134
+ border-radius: var(--stn-radius-input-lg, 8px);
135
+ font-size: var(--stn-text-body-medium-size);
136
+ }
137
+
138
+ .stn-label-prefix.lg > .stn-label-prefix__control {
139
+ padding: 0 var(--stn-space-12);
140
+ }
141
+
142
+ /* ==========================================================================
143
+ 6. Variant (outline · filled · standard · transparent)
144
+ ========================================================================== */
145
+
146
+ /* 6-1. Outline (기본값 — 전체 테두리 박스) */
147
+ .stn-label-prefix.outline {
148
+ border: var(--stn-size-1, 1px) solid var(--stn-input-border);
149
+ background-color: var(--stn-input-bg);
150
+ }
151
+
152
+ /* 6-2. Filled (배경 채움) */
153
+ .stn-label-prefix.filled {
154
+ border: var(--stn-size-1, 1px) solid var(--stn-input-filled-border, transparent);
155
+ background-color: var(--stn-input-filled-bg, var(--stn-input-bg));
156
+ }
157
+
158
+ .stn-label-prefix.filled > .stn-label-prefix__label {
159
+ background-color: var(--stn-label-prefix-label-bg, transparent);
160
+ }
161
+
162
+ /* 6-3. Standard (하단 밑줄만) */
163
+ .stn-label-prefix.standard {
164
+ border: none;
165
+ border-bottom: var(--stn-size-1, 1px) solid var(--stn-input-border);
166
+ border-radius: var(--stn-radius-0, 0px);
167
+ background-color: transparent;
168
+ }
169
+
170
+ /* 6-4. Transparent (테두리·배경 없음 — 외부 래퍼 조합용) */
171
+ .stn-label-prefix.transparent {
172
+ border: none;
173
+ background-color: transparent;
174
+ }
175
+
176
+ /* ==========================================================================
177
+ 7. Focus-within State
178
+ ========================================================================== */
179
+ .stn-label-prefix.outline:focus-within,
180
+ .stn-label-prefix.filled:focus-within {
181
+ border-color: var(--stn-input-focus-fg, var(--stn-primary));
182
+ }
183
+
184
+ .stn-label-prefix.standard:focus-within {
185
+ border-bottom: var(--stn-input-focus);
186
+ }
187
+
188
+ /* ==========================================================================
189
+ 8. Suffix Position (label이 오른쪽에)
190
+ ========================================================================== */
191
+ .stn-label-prefix--suffix {
192
+ flex-direction: row-reverse;
193
+ }
194
+
195
+ /* suffix일 때 레이블 패딩 방향 전환 (오른쪽이 바깥쪽이므로 우측 16, 좌측 0) */
196
+ .stn-label-prefix--suffix > .stn-label-prefix__label {
197
+ padding-inline-start: 0;
198
+ padding-inline-end: var(--stn-space-16);
199
+ }
200
+
201
+ /* suffix일 때 divider를 label 내부의 가장 왼쪽(control과의 경계)에 배치 */
202
+ .stn-label-prefix--suffix .stn-label-prefix__divider {
203
+ order: -1;
204
+ }
205
+
206
+ /* ==========================================================================
207
+ 9. Radius Override
208
+ ========================================================================== */
209
+ .stn-label-prefix.radius-none {
210
+ border-radius: var(--stn-radius-0, 0px);
211
+ }
212
+
213
+ .stn-label-prefix.radius-sm {
214
+ border-radius: var(--stn-radius-input-sm, 4px);
215
+ }
216
+
217
+ .stn-label-prefix.radius-md {
218
+ border-radius: var(--stn-radius-input-md, 4px);
219
+ }
220
+
221
+ .stn-label-prefix.radius-lg {
222
+ border-radius: var(--stn-radius-input-lg, 8px);
223
+ }
224
+
225
+ .stn-label-prefix.radius-xl {
226
+ border-radius: var(--stn-radius-input-xl, 16px);
227
+ }
228
+
229
+ /* ==========================================================================
230
+ 10. Width Presets (.w80 ~ .w200 / .full)
231
+ 기본 고정 너비로 작동하며, 레이블이나 내부 컨트롤의 내용이 지정 너비보다
232
+ 길어질 경우 내용물에 맞춰 자연스럽게 늘어납니다(Hug content).
233
+ ========================================================================== */
234
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w80 { min-width: var(--stn-size-80, 80px); width: max-content; }
235
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w100 { min-width: var(--stn-size-100, 100px); width: max-content; }
236
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w120 { min-width: var(--stn-size-120, 120px); width: max-content; }
237
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w140 { min-width: var(--stn-size-140, 140px); width: max-content; }
238
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w160 { min-width: var(--stn-size-160, 160px); width: max-content; }
239
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w180 { min-width: var(--stn-size-180, 180px); width: max-content; }
240
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).w200 { min-width: var(--stn-size-200, 200px); width: max-content; }
241
+ :is(.stn-label-prefix, .stn-label-prefix-wrap).full {
242
+ width: 100%;
243
+ min-width: 0;
244
+ display: flex;
245
+ }
246
+
247
+ /* ==========================================================================
248
+ 11. Disabled State
249
+ ========================================================================== */
250
+ .stn-label-prefix.is-disabled {
251
+ opacity: var(--stn-input-disabled-opacity, 0.55);
252
+ cursor: not-allowed;
253
+ pointer-events: none;
254
+ }
255
+
256
+ /* ==========================================================================
257
+ 12. Feedback / Status Colors & Error State
258
+ ========================================================================== */
259
+ .stn-label-prefix.is-error,
260
+ .stn-label-prefix.error,
261
+ .stn-label-prefix[aria-invalid='true'] {
262
+ border-color: var(--stn-feedback-error);
263
+ }
264
+
265
+ .stn-label-prefix.standard.is-error,
266
+ .stn-label-prefix.standard.error,
267
+ .stn-label-prefix.standard[aria-invalid='true'] {
268
+ border-bottom-color: var(--stn-feedback-error);
269
+ }
270
+
271
+ .stn-label-prefix.outline.is-error:focus-within,
272
+ .stn-label-prefix.filled.is-error:focus-within,
273
+ .stn-label-prefix.outline.error:focus-within,
274
+ .stn-label-prefix.filled.error:focus-within {
275
+ border-color: var(--stn-feedback-error);
276
+ }
277
+
278
+ .stn-label-prefix.standard.is-error:focus-within,
279
+ .stn-label-prefix.standard.error:focus-within {
280
+ border-bottom-color: var(--stn-feedback-error);
281
+ }
282
+
283
+ .stn-label-prefix.success {
284
+ border-color: var(--stn-feedback-success);
285
+ }
286
+
287
+ .stn-label-prefix.warning {
288
+ border-color: var(--stn-feedback-warning);
289
+ }
290
+
291
+ .stn-label-prefix.info {
292
+ border-color: var(--stn-feedback-info);
293
+ }
294
+
295
+ /* ==========================================================================
296
+ 13. Helper Text & Wrapper
297
+ ========================================================================== */
298
+ .stn-label-prefix-wrap {
299
+ display: inline-flex;
300
+ flex-direction: column;
301
+ box-sizing: border-box;
302
+ vertical-align: middle;
303
+ }
304
+
305
+ .stn-label-prefix-wrap > .stn-label-prefix {
306
+ width: 100%;
307
+ }
308
+
309
+ .stn-label-prefix__helper {
310
+ margin: var(--stn-space-4) 0 0 0;
311
+ font-size: var(--stn-text-caption-size, 12px);
312
+ line-height: var(--stn-line-height-tight, 1.3);
313
+ color: var(--stn-text-muted);
314
+ }
315
+
316
+ .stn-label-prefix-wrap.is-error .stn-label-prefix__helper,
317
+ .stn-label-prefix__helper--error {
318
+ color: var(--stn-feedback-error);
319
+ }