@operato/input 10.29.39 → 10.29.40

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/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ### [10.29.40](https://github.com/hatiolab/operato/compare/v10.29.39...v10.29.40) (2026-10-17)
7
+
8
+
9
+ ### :bug: Bug Fix
10
+
11
+ * **input:** a select shows the chosen label when its options arrive late ([b581c0c](https://github.com/hatiolab/operato/commit/b581c0c76fffe3f8566c74f614a58745742daa81))
12
+
13
+
14
+
6
15
  ### [10.29.39](https://github.com/hatiolab/operato/compare/v10.29.38...v10.29.39) (2026-10-17)
7
16
 
8
17
 
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">74.6% </span>
26
+ <span class="strong">74.58% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>30168/40437</span>
28
+ <span class='fraction'>30168/40450</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">71.92% </span>
33
+ <span class="strong">71.99% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>812/1129</span>
35
+ <span class='fraction'>815/1132</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">33.01% </span>
40
+ <span class="strong">33.14% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>342/1036</span>
42
+ <span class='fraction'>344/1038</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">74.6% </span>
47
+ <span class="strong">74.58% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>30168/40437</span>
49
+ <span class='fraction'>30168/40450</span>
50
50
  </div>
51
51
 
52
52
 
@@ -110,17 +110,17 @@
110
110
 
111
111
  <tr>
112
112
  <td class="file low" data-value="Users/super/Documents/GitHub/.worktrees/v10-rel-op-addr/webcomponents/input/__wds-outside-root__/1/popup/src"><a href="Users/super/Documents/GitHub/.worktrees/v10-rel-op-addr/webcomponents/input/__wds-outside-root__/1/popup/src/index.html">Users/super/Documents/GitHub/.worktrees/v10-rel-op-addr/webcomponents/input/__wds-outside-root__/1/popup/src</a></td>
113
- <td data-value="28.61" class="pic low">
113
+ <td data-value="28.51" class="pic low">
114
114
  <div class="chart"><div class="cover-fill" style="width: 28%"></div><div class="cover-empty" style="width: 72%"></div></div>
115
115
  </td>
116
- <td data-value="28.61" class="pct low">28.61%</td>
117
- <td data-value="3582" class="abs low">1025/3582</td>
116
+ <td data-value="28.51" class="pct low">28.51%</td>
117
+ <td data-value="3595" class="abs low">1025/3595</td>
118
118
  <td data-value="100" class="pct high">100%</td>
119
119
  <td data-value="6" class="abs high">6/6</td>
120
- <td data-value="7.22" class="pct low">7.22%</td>
121
- <td data-value="83" class="abs low">6/83</td>
122
- <td data-value="28.61" class="pct low">28.61%</td>
123
- <td data-value="3582" class="abs low">1025/3582</td>
120
+ <td data-value="7.05" class="pct low">7.05%</td>
121
+ <td data-value="85" class="abs low">6/85</td>
122
+ <td data-value="28.51" class="pct low">28.51%</td>
123
+ <td data-value="3595" class="abs low">1025/3595</td>
124
124
  </tr>
125
125
 
126
126
  <tr>
@@ -640,10 +640,10 @@
640
640
  </td>
641
641
  <td data-value="100" class="pct high">100%</td>
642
642
  <td data-value="2712" class="abs high">2712/2712</td>
643
- <td data-value="66.27" class="pct medium">66.27%</td>
644
- <td data-value="86" class="abs medium">57/86</td>
645
- <td data-value="43.39" class="pct low">43.39%</td>
646
- <td data-value="53" class="abs low">23/53</td>
643
+ <td data-value="67.41" class="pct medium">67.41%</td>
644
+ <td data-value="89" class="abs medium">60/89</td>
645
+ <td data-value="47.16" class="pct low">47.16%</td>
646
+ <td data-value="53" class="abs low">25/53</td>
647
647
  <td data-value="100" class="pct high">100%</td>
648
648
  <td data-value="2712" class="abs high">2712/2712</td>
649
649
  </tr>
@@ -761,7 +761,7 @@
761
761
  <div class='footer quiet pad2 space-top1 center small'>
762
762
  Code coverage generated by
763
763
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
764
- at 2026-10-17T11:52:32.606Z
764
+ at 2026-10-17T14:45:54.872Z
765
765
  </div>
766
766
  <script src="prettify.js"></script>
767
767
  <script>
@@ -103,7 +103,7 @@ Error: Unable to lookup source: /webpack/bootstrap (ENOENT: no such file or dire
103
103
  <div class='footer quiet pad2 space-top1 center small'>
104
104
  Code coverage generated by
105
105
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
106
- at 2026-10-17T11:52:32.606Z
106
+ at 2026-10-17T14:45:54.872Z
107
107
  </div>
108
108
  <script src="../prettify.js"></script>
109
109
  <script>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2026-10-17T11:52:32.606Z
104
+ at 2026-10-17T14:45:54.872Z
105
105
  </div>
106
106
  <script src="../prettify.js"></script>
107
107
  <script>
@@ -103,7 +103,7 @@ Error: Unable to lookup source: /webpack/runtime/define property getters (ENOENT
103
103
  <div class='footer quiet pad2 space-top1 center small'>
104
104
  Code coverage generated by
105
105
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
106
- at 2026-10-17T11:52:32.606Z
106
+ at 2026-10-17T14:45:54.872Z
107
107
  </div>
108
108
  <script src="../../prettify.js"></script>
109
109
  <script>
@@ -103,7 +103,7 @@ Error: Unable to lookup source: /webpack/runtime/global (ENOENT: no such file or
103
103
  <div class='footer quiet pad2 space-top1 center small'>
104
104
  Code coverage generated by
105
105
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
106
- at 2026-10-17T11:52:32.606Z
106
+ at 2026-10-17T14:45:54.872Z
107
107
  </div>
108
108
  <script src="../../prettify.js"></script>
109
109
  <script>
@@ -103,7 +103,7 @@ Error: Unable to lookup source: /webpack/runtime/hasOwnProperty shorthand (ENOEN
103
103
  <div class='footer quiet pad2 space-top1 center small'>
104
104
  Code coverage generated by
105
105
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
106
- at 2026-10-17T11:52:32.606Z
106
+ at 2026-10-17T14:45:54.872Z
107
107
  </div>
108
108
  <script src="../../prettify.js"></script>
109
109
  <script>
@@ -146,7 +146,7 @@
146
146
  <div class='footer quiet pad2 space-top1 center small'>
147
147
  Code coverage generated by
148
148
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
149
- at 2026-10-17T11:52:32.606Z
149
+ at 2026-10-17T14:45:54.872Z
150
150
  </div>
151
151
  <script src="../../prettify.js"></script>
152
152
  <script>
@@ -103,7 +103,7 @@ Error: Unable to lookup source: /webpack/runtime/make namespace object (ENOENT:
103
103
  <div class='footer quiet pad2 space-top1 center small'>
104
104
  Code coverage generated by
105
105
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
106
- at 2026-10-17T11:52:32.606Z
106
+ at 2026-10-17T14:45:54.872Z
107
107
  </div>
108
108
  <script src="../../prettify.js"></script>
109
109
  <script>
@@ -2033,17 +2033,19 @@ FN:11,guaranteeFocus
2033
2033
  FN:32,OxPopupList
2034
2034
  FN:33,<static_initializer>
2035
2035
  FN:190,render
2036
- FN:230,_oninputsearch
2037
- FN:237,_onchangesearch
2038
- FN:242,_onkeydownsearch
2039
- FN:306,updated
2040
- FN:376,getSelectedLabels
2041
- FN:391,select
2042
- FN:421,setActive
2043
- FN:461,open
2044
- FN:486,close
2045
- FN:508,open
2046
- FNF:14
2036
+ FN:231,_oninputsearch
2037
+ FN:238,_onchangesearch
2038
+ FN:243,_onkeydownsearch
2039
+ FN:307,updated
2040
+ FN:358,markSelected
2041
+ FN:379,optionsChanged
2042
+ FN:389,getSelectedLabels
2043
+ FN:404,select
2044
+ FN:434,setActive
2045
+ FN:474,open
2046
+ FN:499,close
2047
+ FN:521,open
2048
+ FNF:16
2047
2049
  FNH:1
2048
2050
  FNDA:0,guaranteeFocus
2049
2051
  FNDA:0,OxPopupList
@@ -2053,6 +2055,8 @@ FNDA:0,_oninputsearch
2053
2055
  FNDA:0,_onchangesearch
2054
2056
  FNDA:0,_onkeydownsearch
2055
2057
  FNDA:0,updated
2058
+ FNDA:0,markSelected
2059
+ FNDA:0,optionsChanged
2056
2060
  FNDA:0,getSelectedLabels
2057
2061
  FNDA:0,select
2058
2062
  FNDA:0,setActive
@@ -2636,7 +2640,20 @@ DA:574,0
2636
2640
  DA:575,0
2637
2641
  DA:576,0
2638
2642
  DA:577,0
2639
- LF:577
2643
+ DA:578,0
2644
+ DA:579,0
2645
+ DA:580,0
2646
+ DA:581,0
2647
+ DA:582,0
2648
+ DA:583,0
2649
+ DA:584,0
2650
+ DA:585,0
2651
+ DA:586,0
2652
+ DA:587,0
2653
+ DA:588,0
2654
+ DA:589,0
2655
+ DA:590,0
2656
+ LF:590
2640
2657
  LH:128
2641
2658
  BRDA:33,0,0,1
2642
2659
  BRF:1
@@ -38812,7 +38829,7 @@ FN:3,E
38812
38829
  FN:9,P
38813
38830
  FN:9,l
38814
38831
  FNF:53
38815
- FNH:23
38832
+ FNH:25
38816
38833
  FNDA:1,t.exports
38817
38834
  FNDA:0,t.exports
38818
38835
  FNDA:0,t.exports
@@ -38858,13 +38875,13 @@ FNDA:0,trim
38858
38875
  FNDA:3,u
38859
38876
  FNDA:1,Y
38860
38877
  FNDA:280,i
38861
- FNDA:64,_
38862
- FNDA:56,o
38863
- FNDA:0,A
38878
+ FNDA:66,_
38879
+ FNDA:62,o
38880
+ FNDA:10,A
38864
38881
  FNDA:12,O
38865
38882
  FNDA:0,onchange
38866
38883
  FNDA:4,E
38867
- FNDA:0,P
38884
+ FNDA:4,P
38868
38885
  FNDA:48,l
38869
38886
  DA:1,1
38870
38887
  DA:2,280
@@ -38874,7 +38891,7 @@ DA:5,4
38874
38891
  DA:6,4
38875
38892
  DA:7,4
38876
38893
  DA:8,4
38877
- DA:9,4
38894
+ DA:9,1
38878
38895
  DA:10,1
38879
38896
  DA:11,1
38880
38897
  LF:11
@@ -38956,17 +38973,20 @@ BRDA:7,73,0,0
38956
38973
  BRDA:7,74,0,0
38957
38974
  BRDA:7,75,0,0
38958
38975
  BRDA:8,76,0,1
38959
- BRDA:9,77,0,56
38960
- BRDA:5,78,0,12
38961
- BRDA:3,79,0,4
38962
- BRDA:3,80,0,0
38963
- BRDA:9,81,0,1
38976
+ BRDA:9,77,0,62
38977
+ BRDA:3,78,0,10
38978
+ BRDA:5,79,0,12
38979
+ BRDA:3,80,0,4
38980
+ BRDA:3,81,0,10
38964
38981
  BRDA:8,82,0,0
38965
- BRDA:8,83,0,1
38966
- BRDA:8,84,0,1
38967
- BRDA:9,85,0,2
38968
- BRF:86
38969
- BRH:57
38982
+ BRDA:9,83,0,4
38983
+ BRDA:9,84,0,1
38984
+ BRDA:8,85,0,0
38985
+ BRDA:8,86,0,1
38986
+ BRDA:8,87,0,1
38987
+ BRDA:9,88,0,2
38988
+ BRF:89
38989
+ BRH:60
38970
38990
  end_of_record
38971
38991
  TN:
38972
38992
  SF:../../../../../../../../node_modules/core-js/internals/a-constructor.js
@@ -18,6 +18,8 @@ export declare class OxSelect extends OxFormField {
18
18
  connectedCallback(): void;
19
19
  disconnectedCallback(): void;
20
20
  handleKeyDown(e: KeyboardEvent): void;
21
+ /** Its list's options arrived or changed: show the label of the value they now hold. */
22
+ private optionsChanged;
21
23
  updated(changes: PropertyValues<this>): Promise<void>;
22
24
  setOptions(options: string[] | {
23
25
  display: string;
@@ -19,6 +19,12 @@ let OxSelect = class OxSelect extends OxFormField {
19
19
  this.popupContainer = null;
20
20
  this.observer = null;
21
21
  this.hasLabelSlot = false;
22
+ /** Its list's options arrived or changed: show the label of the value they now hold. */
23
+ this.optionsChanged = (e) => {
24
+ e.stopPropagation();
25
+ const popupList = e.target;
26
+ this.label = popupList.getSelectedLabels();
27
+ };
22
28
  }
23
29
  static { this.styles = [
24
30
  InputStyles,
@@ -97,11 +103,13 @@ let OxSelect = class OxSelect extends OxFormField {
97
103
  this.setAttribute('tabindex', '0');
98
104
  this.addEventListener('keydown', this.handleKeyDown);
99
105
  this.addEventListener('click', this.expand);
106
+ this.addEventListener('options-change', this.optionsChanged);
100
107
  }
101
108
  disconnectedCallback() {
102
109
  super.disconnectedCallback();
103
110
  this.removeEventListener('keydown', this.handleKeyDown);
104
111
  this.removeEventListener('click', this.expand);
112
+ this.removeEventListener('options-change', this.optionsChanged);
105
113
  }
106
114
  handleKeyDown(e) {
107
115
  e.preventDefault();
@@ -1 +1 @@
1
- {"version":3,"file":"ox-select.js","sourceRoot":"","sources":["../../src/ox-select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\nimport '@operato/popup/ox-popup-list.js'\nimport './ox-checkbox.js'\n\nimport { css, html, render, PropertyValues } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { OxPopupList } from '@operato/popup'\n\nimport { OxFormField } from './ox-form-field.js'\nimport { InputStyles } from './input-styles.js'\n\n@customElement('ox-select')\nexport class OxSelect extends OxFormField {\n static styles = [\n InputStyles,\n css`\n /* 컴포넌트 조정 지점(L3) — 모두 L2 계약(--ox-input-*)으로 폴백하므로\n 앱은 전역(L2) 또는 이 컴포넌트만(L3) 어느 쪽으로도 통제할 수 있다.\n 고정 리터럴을 남기지 않는다. */\n :host {\n display: block;\n position: relative;\n border-bottom: var(--ox-select-border-bottom, var(--ox-input-underline));\n\n --ox-select-padding: var(--ox-input-padding);\n --ox-select-font: var(--ox-input-font);\n --ox-select-color: var(--ox-input-color);\n --ox-select-icon-color: var(--ox-input-placeholder-color);\n --ox-select-icon-hover-color: var(--ox-input-focus-color);\n --ox-select-icon-size: var(--ox-input-font-size);\n --ox-select-icon-opacity: 0.7;\n }\n\n div {\n width: 100%;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n padding: var(--ox-select-padding);\n font: var(--ox-select-font);\n color: var(--ox-select-color);\n transition: var(--ox-input-transition);\n }\n\n span {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n gap: var(--ox-input-gap);\n }\n\n md-icon {\n --md-icon-size: var(--ox-select-icon-size);\n display: block;\n text-align: right;\n color: var(--ox-select-icon-color);\n opacity: var(--ox-select-icon-opacity);\n transition: var(--ox-input-transition);\n }\n\n div:hover md-icon {\n color: var(--ox-select-icon-hover-color);\n opacity: 1;\n }\n `\n ]\n\n @property({ type: String }) name: string = ''\n @property({ type: String }) placeholder: string = ''\n\n @state() label: string | string[] = ''\n @state() popupContainer: HTMLElement | null = null\n @state() observer: MutationObserver | null = null\n @state() hasLabelSlot: boolean = false\n\n render() {\n // value/label 은 문자열이 아닐 수 있다 (예: select option value 가 숫자 0/1).\n // `(0)?.trim()` 은 0 이 nullish 가 아니라 단락되지 않아 TypeError 가 난다 →\n // 비-문자열 스칼라는 String() 으로 강제, nullish 만 '' 처리.\n const asText = (v: unknown): string =>\n v instanceof Array ? v.join(', ') : typeof v === 'string' ? v.trim() : v == null ? '' : String(v)\n\n const label = asText(this.label) || asText(this.value) || this.placeholder || ''\n\n return html`\n <div @click=${this.expand}>\n <span data-reactive-tooltip> <slot name=\"label\">${label}</slot> </span>\n <md-icon>expand_more</md-icon>\n </div>\n\n <slot></slot>\n `\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n this.setAttribute('tabindex', '0')\n this.addEventListener('keydown', this.handleKeyDown)\n this.addEventListener('click', this.expand)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.removeEventListener('keydown', this.handleKeyDown)\n this.removeEventListener('click', this.expand)\n }\n\n handleKeyDown(e: KeyboardEvent) {\n e.preventDefault()\n if (e.key === ' ' || e.key === 'Spacebar' || e.key === 'ArrowDown') {\n this.expand()\n }\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('value')) {\n const popupList = (this.popupContainer?.querySelector('ox-popup-list') ||\n this.querySelector('ox-popup-list')) as OxPopupList\n\n if (popupList) {\n popupList.value = this.value\n await this.requestUpdate()\n this.label = popupList.getSelectedLabels()\n }\n }\n }\n\n setOptions(\n options: string[] | { display: string; value: string }[],\n opt: { multiple?: boolean; withSearch?: boolean } = {}\n ) {\n const objOptions = options.map(option => {\n return typeof option == 'string' ? { display: option, value: option } : option\n })\n\n const { multiple, withSearch } = opt || {}\n\n const template = html`\n <ox-popup-list\n align-left\n nowrap\n ?multiple=${multiple}\n attr-selected=${multiple ? 'checked' : ''}\n ?with-search=${withSearch}\n >\n ${multiple\n ? html`<ox-checkbox\n @change=${(e: Event) => {\n const target = e.target as HTMLInputElement\n const options = Array.from(target.parentElement!.querySelectorAll('[option]')).filter(\n option => !option.hasAttribute('hidden')\n )\n options.forEach(option => ((option as HTMLInputElement).checked = target.checked))\n\n this.value = options\n .map(option =>\n (option as HTMLInputElement).checked ? (option as HTMLInputElement).value : undefined\n )\n .filter(Boolean)\n }}\n >set all</ox-checkbox\n >\n ${objOptions.map(\n option => html` <ox-checkbox option value=${option.value}>${option.display}</ox-checkbox> `\n )}`\n : html`${objOptions.map(option => html` <div option value=${option.value}>${option.display}</div> `)}`}\n </ox-popup-list>\n `\n\n render(template, this)\n }\n\n expand() {\n if (this.disabled) {\n return\n }\n\n const slotContent = (this.renderRoot.querySelector('slot:not([name])') as HTMLSlotElement)?.assignedNodes() || []\n\n if (slotContent.length > 0) {\n const popupList = slotContent.find(content => content instanceof OxPopupList) as OxPopupList\n\n if (popupList) {\n const { left, bottom } = this.getBoundingClientRect()\n\n popupList.value = this.value\n popupList.style.width = `${this.offsetWidth}px`\n popupList.style.textWrap = 'nowrap'\n\n const selectHandler = async (e: Event) => {\n this.value = (e as CustomEvent).detail\n\n if (popupList) {\n await this.requestUpdate()\n this.label = popupList.getSelectedLabels()\n }\n }\n popupList.addEventListener('select', selectHandler)\n\n const closeHandler = (e: Event) => {\n /* popup이 close될 때 change 이벤트를 발생시킨다. */\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n popupList.removeEventListener('select', selectHandler)\n popupList.removeEventListener('close', closeHandler)\n\n this.appendChild(popupList)\n }\n popupList.addEventListener('close', closeHandler, { once: true })\n\n document.body.appendChild(popupList)\n\n popupList.open({\n left,\n top: bottom\n })\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ox-select.js","sourceRoot":"","sources":["../../src/ox-select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\nimport '@operato/popup/ox-popup-list.js'\nimport './ox-checkbox.js'\n\nimport { css, html, render, PropertyValues } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { OxPopupList } from '@operato/popup'\n\nimport { OxFormField } from './ox-form-field.js'\nimport { InputStyles } from './input-styles.js'\n\n@customElement('ox-select')\nexport class OxSelect extends OxFormField {\n static styles = [\n InputStyles,\n css`\n /* 컴포넌트 조정 지점(L3) — 모두 L2 계약(--ox-input-*)으로 폴백하므로\n 앱은 전역(L2) 또는 이 컴포넌트만(L3) 어느 쪽으로도 통제할 수 있다.\n 고정 리터럴을 남기지 않는다. */\n :host {\n display: block;\n position: relative;\n border-bottom: var(--ox-select-border-bottom, var(--ox-input-underline));\n\n --ox-select-padding: var(--ox-input-padding);\n --ox-select-font: var(--ox-input-font);\n --ox-select-color: var(--ox-input-color);\n --ox-select-icon-color: var(--ox-input-placeholder-color);\n --ox-select-icon-hover-color: var(--ox-input-focus-color);\n --ox-select-icon-size: var(--ox-input-font-size);\n --ox-select-icon-opacity: 0.7;\n }\n\n div {\n width: 100%;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n padding: var(--ox-select-padding);\n font: var(--ox-select-font);\n color: var(--ox-select-color);\n transition: var(--ox-input-transition);\n }\n\n span {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n gap: var(--ox-input-gap);\n }\n\n md-icon {\n --md-icon-size: var(--ox-select-icon-size);\n display: block;\n text-align: right;\n color: var(--ox-select-icon-color);\n opacity: var(--ox-select-icon-opacity);\n transition: var(--ox-input-transition);\n }\n\n div:hover md-icon {\n color: var(--ox-select-icon-hover-color);\n opacity: 1;\n }\n `\n ]\n\n @property({ type: String }) name: string = ''\n @property({ type: String }) placeholder: string = ''\n\n @state() label: string | string[] = ''\n @state() popupContainer: HTMLElement | null = null\n @state() observer: MutationObserver | null = null\n @state() hasLabelSlot: boolean = false\n\n render() {\n // value/label 은 문자열이 아닐 수 있다 (예: select option value 가 숫자 0/1).\n // `(0)?.trim()` 은 0 이 nullish 가 아니라 단락되지 않아 TypeError 가 난다 →\n // 비-문자열 스칼라는 String() 으로 강제, nullish 만 '' 처리.\n const asText = (v: unknown): string =>\n v instanceof Array ? v.join(', ') : typeof v === 'string' ? v.trim() : v == null ? '' : String(v)\n\n const label = asText(this.label) || asText(this.value) || this.placeholder || ''\n\n return html`\n <div @click=${this.expand}>\n <span data-reactive-tooltip> <slot name=\"label\">${label}</slot> </span>\n <md-icon>expand_more</md-icon>\n </div>\n\n <slot></slot>\n `\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n this.setAttribute('tabindex', '0')\n this.addEventListener('keydown', this.handleKeyDown)\n this.addEventListener('click', this.expand)\n this.addEventListener('options-change', this.optionsChanged)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.removeEventListener('keydown', this.handleKeyDown)\n this.removeEventListener('click', this.expand)\n this.removeEventListener('options-change', this.optionsChanged)\n }\n\n handleKeyDown(e: KeyboardEvent) {\n e.preventDefault()\n if (e.key === ' ' || e.key === 'Spacebar' || e.key === 'ArrowDown') {\n this.expand()\n }\n }\n\n /** Its list's options arrived or changed: show the label of the value they now hold. */\n private optionsChanged = (e: Event) => {\n e.stopPropagation()\n const popupList = e.target as OxPopupList\n this.label = popupList.getSelectedLabels()\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('value')) {\n const popupList = (this.popupContainer?.querySelector('ox-popup-list') ||\n this.querySelector('ox-popup-list')) as OxPopupList\n\n if (popupList) {\n popupList.value = this.value\n await this.requestUpdate()\n this.label = popupList.getSelectedLabels()\n }\n }\n }\n\n setOptions(\n options: string[] | { display: string; value: string }[],\n opt: { multiple?: boolean; withSearch?: boolean } = {}\n ) {\n const objOptions = options.map(option => {\n return typeof option == 'string' ? { display: option, value: option } : option\n })\n\n const { multiple, withSearch } = opt || {}\n\n const template = html`\n <ox-popup-list\n align-left\n nowrap\n ?multiple=${multiple}\n attr-selected=${multiple ? 'checked' : ''}\n ?with-search=${withSearch}\n >\n ${multiple\n ? html`<ox-checkbox\n @change=${(e: Event) => {\n const target = e.target as HTMLInputElement\n const options = Array.from(target.parentElement!.querySelectorAll('[option]')).filter(\n option => !option.hasAttribute('hidden')\n )\n options.forEach(option => ((option as HTMLInputElement).checked = target.checked))\n\n this.value = options\n .map(option =>\n (option as HTMLInputElement).checked ? (option as HTMLInputElement).value : undefined\n )\n .filter(Boolean)\n }}\n >set all</ox-checkbox\n >\n ${objOptions.map(\n option => html` <ox-checkbox option value=${option.value}>${option.display}</ox-checkbox> `\n )}`\n : html`${objOptions.map(option => html` <div option value=${option.value}>${option.display}</div> `)}`}\n </ox-popup-list>\n `\n\n render(template, this)\n }\n\n expand() {\n if (this.disabled) {\n return\n }\n\n const slotContent = (this.renderRoot.querySelector('slot:not([name])') as HTMLSlotElement)?.assignedNodes() || []\n\n if (slotContent.length > 0) {\n const popupList = slotContent.find(content => content instanceof OxPopupList) as OxPopupList\n\n if (popupList) {\n const { left, bottom } = this.getBoundingClientRect()\n\n popupList.value = this.value\n popupList.style.width = `${this.offsetWidth}px`\n popupList.style.textWrap = 'nowrap'\n\n const selectHandler = async (e: Event) => {\n this.value = (e as CustomEvent).detail\n\n if (popupList) {\n await this.requestUpdate()\n this.label = popupList.getSelectedLabels()\n }\n }\n popupList.addEventListener('select', selectHandler)\n\n const closeHandler = (e: Event) => {\n /* popup이 close될 때 change 이벤트를 발생시킨다. */\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n popupList.removeEventListener('select', selectHandler)\n popupList.removeEventListener('close', closeHandler)\n\n this.appendChild(popupList)\n }\n popupList.addEventListener('close', closeHandler, { once: true })\n\n document.body.appendChild(popupList)\n\n popupList.open({\n left,\n top: bottom\n })\n }\n }\n }\n}\n"]}