@@ -10,18 +10,14 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
1010
1111 // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1212 class WoltlabCoreListBoxElement extends HTMLParsedElement {
13- #input: HTMLInputElement | undefined = undefined ;
1413 #selected = "" ;
15- #shadow: ShadowRoot | undefined = undefined ;
14+ readonly #formInput: HTMLInputElement ;
1615 readonly #items: Set < WoltlabCoreListItemElement > = new Set ( ) ;
16+ readonly #shadow: ShadowRoot ;
17+ readonly #slot: HTMLSlotElement ;
1718
18- connectedCallback ( ) {
19- this . role = "listbox" ;
20- this . setAttribute ( "aria-multiselectable" , "false" ) ;
21- this . setAttribute ( "aria-orientation" , "vertical" ) ;
22-
23- const shadow = this . #getShadow( ) ;
24- shadow . innerHTML = "" ;
19+ constructor ( ) {
20+ super ( ) ;
2521
2622 const style = document . createElement ( "style" ) ;
2723 style . textContent = `
@@ -41,57 +37,56 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
4137}
4238 ` ;
4339
44- const elements = document . createElement ( "slot" ) ;
45- elements . addEventListener ( "slotchange" , ( ) => {
46- for ( const element of elements . assignedElements ( ) ) {
47- if ( element instanceof WoltlabCoreListItemElement ) {
48- if ( element . selected ) {
49- if ( this . #selected === "" ) {
50- this . #selected = element . value ;
51- this . setAttribute ( "selected" , this . #selected) ;
52-
53- if ( this . #input !== undefined ) {
54- this . #input. value = element . value ;
55- }
56- } else {
57- element . selected = false ;
58- }
59- }
40+ this . #slot = document . createElement ( "slot" ) ;
6041
61- if ( ! this . #items . has ( element ) ) {
62- this . #items . add ( element ) ;
42+ this . #shadow = this . attachShadow ( { mode : "open" } ) ;
43+ this . #shadow . append ( style , this . #slot ) ;
6344
64- element . addEventListener ( "change" , ( event ) => {
65- if ( event . detail . selected ) {
66- this . #changeSelection( element . value ) ;
67- } else {
68- throw new Error ( "TODO: not implemented" ) ;
69- }
70- } ) ;
71- }
72- }
45+ this . #formInput = document . createElement ( "input" ) ;
46+ this . #formInput. type = "hidden" ;
47+ }
48+
49+ parsedCallback ( ) {
50+ this . role = "listbox" ;
51+ this . setAttribute ( "aria-multiselectable" , "false" ) ;
52+ this . setAttribute ( "aria-orientation" , "vertical" ) ;
53+
54+ const selected = this . getAttribute ( "selected" ) || this . #selected;
55+ this . removeAttribute ( "selected" ) ;
56+
57+ let foundValue = false ;
58+ for ( const element of this . #slot. assignedElements ( ) ) {
59+ if ( ! ( element instanceof WoltlabCoreListItemElement ) ) {
60+ continue ;
7361 }
74- } ) ;
7562
76- shadow . append ( style , elements ) ;
63+ if ( element . value === selected ) {
64+ element . selected = true ;
7765
78- const name = this . getAttribute ( "name" ) || "" ;
79- if ( name !== "" ) {
80- this . #input = document . createElement ( "input" ) ;
81- this . #input. type = "hidden" ;
82- this . #input. name = name ;
83- this . #input. value = this . #selected;
66+ if ( this . #formInput !== undefined ) {
67+ this . #formInput. value = this . #selected;
68+ }
8469
85- this . removeAttribute ( "name" ) ;
86- }
70+ foundValue = true ;
71+ } else {
72+ element . selected = false ;
73+ }
8774
88- if ( this . #input !== undefined ) {
89- this . append ( this . #input) ;
75+ if ( ! this . #items. has ( element ) ) {
76+ this . #items. add ( element ) ;
77+
78+ element . addEventListener ( "change" , ( event ) => {
79+ if ( event . detail . selected ) {
80+ this . #changeSelection( element . value ) ;
81+ } else {
82+ throw new Error ( "TODO: not implemented" ) ;
83+ }
84+ } ) ;
85+ }
9086 }
91- }
9287
93- parsedCallback ( ) : void {
94- console . log ( "parsedCallback()" ) ;
88+ this . #selected = foundValue ? selected : "" ;
89+ this . #updateFormInput ( this . name ) ;
9590 }
9691
9792 #changeSelection( value : string ) : void {
@@ -108,8 +103,8 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
108103 }
109104 }
110105
111- if ( this . #input !== undefined ) {
112- this . #input . value = value ;
106+ if ( this . #formInput !== undefined ) {
107+ this . #formInput . value = value ;
113108 }
114109
115110 const event = new CustomEvent < ChangePayload > ( "change" , {
@@ -120,17 +115,29 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
120115 this . dispatchEvent ( event ) ;
121116 }
122117
123- #getShadow( ) : ShadowRoot {
124- if ( this . #shadow === undefined ) {
125- this . #shadow = this . attachShadow ( { mode : "open" } ) ;
126- }
118+ #updateFormInput( name : string ) : void {
119+ if ( name === "" ) {
120+ this . removeAttribute ( "name" ) ;
121+ this . #formInput. remove ( ) ;
122+ } else {
123+ this . #formInput. name = name ;
124+ this . #formInput. value = this . #selected;
127125
128- return this . #shadow;
126+ this . #shadow. append ( this . #formInput) ;
127+ }
129128 }
130129
131130 get selected ( ) : string {
132131 return this . #selected;
133132 }
133+
134+ get name ( ) : string {
135+ return this . getAttribute ( "name" ) || "" ;
136+ }
137+
138+ set name ( name : string ) {
139+ this . #updateFormInput( name ) ;
140+ }
134141 }
135142
136143 // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
0 commit comments