@api-client/ui 0.5.29 → 0.5.30

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.
@@ -73,6 +73,40 @@ describe('md', () => {
73
73
  return fixture(html`<ui-select label="Empty select"></ui-select>`)
74
74
  }
75
75
 
76
+ async function selectedAttributeFixture(): Promise<UiSelect> {
77
+ return fixture(html`
78
+ <ui-select label="Select with pre-selected option">
79
+ <ui-option value="apple">Apple</ui-option>
80
+ <ui-option value="banana" selected>Banana</ui-option>
81
+ <ui-option value="cherry">Cherry</ui-option>
82
+ </ui-select>
83
+ `)
84
+ }
85
+
86
+ async function multipleSelectedFixture(): Promise<UiSelect> {
87
+ return fixture(html`
88
+ <ui-select label="Select with multiple selected">
89
+ <ui-option value="apple" selected>Apple</ui-option>
90
+ <ui-option value="banana" selected>Banana</ui-option>
91
+ <ui-option value="cherry">Cherry</ui-option>
92
+ </ui-select>
93
+ `)
94
+ }
95
+
96
+ async function selectedWithValueFixture(): Promise<UiSelect> {
97
+ return fixture(html`
98
+ <ui-select label="Select with both value and selected" value="cherry">
99
+ <ui-option value="apple">Apple</ui-option>
100
+ <ui-option value="banana" selected>Banana</ui-option>
101
+ <ui-option value="cherry">Cherry</ui-option>
102
+ </ui-select>
103
+ `)
104
+ }
105
+
106
+ async function dynamicOptionsFixture(): Promise<UiSelect> {
107
+ return fixture(html` <ui-select label="Dynamic options"> </ui-select> `)
108
+ }
109
+
76
110
  describe('Basic functionality', () => {
77
111
  it('should create select element', async () => {
78
112
  const element = await basicFixture()
@@ -160,6 +194,61 @@ describe('md', () => {
160
194
  assert.isNull(element.selectedItem, 'selected item should be null')
161
195
  assert.equal(element.renderValue, '')
162
196
  })
197
+
198
+ it('should discover selected attribute on options', async () => {
199
+ const element = await selectedAttributeFixture()
200
+ await element.updateComplete
201
+
202
+ assert.equal(element.value, 'banana')
203
+ assert.isNotNull(element.selectedItem)
204
+ assert.equal(element.selectedItem!.value, 'banana')
205
+ assert.equal(element.renderValue, 'Banana')
206
+ })
207
+
208
+ it('should handle multiple selected options by selecting the first one', async () => {
209
+ const element = await multipleSelectedFixture()
210
+ await element.updateComplete
211
+ await nextFrame()
212
+
213
+ // When multiple options have selected attribute, only the first one should be selected
214
+ assert.equal(element.value, 'apple')
215
+ assert.isNotNull(element.selectedItem)
216
+ assert.equal(element.selectedItem!.value, 'apple') // First selected item
217
+ assert.equal(element.renderValue, 'Apple') // Display value should match the first selected item
218
+ })
219
+
220
+ it('should prioritize value over selected attribute', async () => {
221
+ const element = await selectedWithValueFixture()
222
+ await element.updateComplete
223
+
224
+ assert.equal(element.value, 'cherry')
225
+ assert.isNotNull(element.selectedItem)
226
+ assert.equal(element.selectedItem!.value, 'cherry')
227
+ assert.equal(element.renderValue, 'Cherry')
228
+ })
229
+
230
+ it('should update value when options change dynamically', async () => {
231
+ const element = await dynamicOptionsFixture()
232
+ await element.updateComplete
233
+
234
+ // Initially, there are no options, so value should be undefined
235
+ assert.isUndefined(element.value)
236
+
237
+ // Add options dynamically
238
+ element.innerHTML = `
239
+ <ui-option value="apple">Apple</ui-option>
240
+ <ui-option value="banana" selected>Banana</ui-option>
241
+ <ui-option value="cherry">Cherry</ui-option>
242
+ `
243
+ await element.updateComplete
244
+ await nextFrame()
245
+
246
+ // The value should now reflect the selected option
247
+ assert.equal(element.value, 'banana')
248
+ assert.isNotNull(element.selectedItem)
249
+ assert.equal(element.selectedItem!.value, 'banana')
250
+ assert.equal(element.renderValue, 'Banana')
251
+ })
163
252
  })
164
253
 
165
254
  describe('Form integration', () => {
@@ -663,5 +752,145 @@ describe('md', () => {
663
752
  assert.equal(options[2].value, 'cherry')
664
753
  })
665
754
  })
755
+
756
+ describe('Selected attribute discovery', () => {
757
+ it('should discover and set value from selected attribute on initialization', async () => {
758
+ const element = await selectedAttributeFixture()
759
+ await element.updateComplete
760
+ await nextFrame()
761
+
762
+ assert.equal(element.value, 'banana', 'value should be set from selected option')
763
+ assert.isNotNull(element.selectedItem, 'selected item should not be null')
764
+ assert.equal(element.selectedItem!.value, 'banana', 'selected item should be the banana option')
765
+ assert.equal(element.renderValue, 'Banana', 'render value should match selected option')
766
+ })
767
+
768
+ it('should handle case with no selected options', async () => {
769
+ const element = await basicFixture()
770
+ await element.updateComplete
771
+ await nextFrame()
772
+
773
+ assert.isUndefined(element.value, 'value should be undefined when no options are selected')
774
+ assert.isNull(element.selectedItem, 'selected item should be null when no options are selected')
775
+ assert.equal(element.renderValue, '', 'render value should be empty when no options are selected')
776
+ })
777
+
778
+ it('should select the first option when multiple options have selected attribute', async () => {
779
+ const element = await multipleSelectedFixture()
780
+ await element.updateComplete
781
+ await nextFrame()
782
+
783
+ assert.equal(element.value, 'apple', 'should select the first option with selected attribute')
784
+ assert.isNotNull(element.selectedItem, 'selected item should not be null')
785
+ assert.equal(element.selectedItem!.value, 'apple', 'selected item should be the first selected option')
786
+ assert.equal(element.renderValue, 'Apple', 'render value should match first selected option')
787
+ })
788
+
789
+ it('should prioritize explicit value property over selected attribute', async () => {
790
+ const element = await selectedWithValueFixture()
791
+ await element.updateComplete
792
+ await nextFrame()
793
+
794
+ assert.equal(element.value, 'cherry', 'value property should take precedence')
795
+ assert.isNotNull(element.selectedItem, 'selected item should not be null')
796
+ assert.equal(element.selectedItem!.value, 'cherry', 'selected item should match value property')
797
+ assert.equal(element.renderValue, 'Cherry', 'render value should match value property')
798
+ })
799
+
800
+ it('should rediscover selected options when value is cleared', async () => {
801
+ const element = await selectedAttributeFixture()
802
+ await element.updateComplete
803
+ await nextFrame()
804
+
805
+ // First, verify it's initialized correctly
806
+ assert.equal(element.value, 'banana')
807
+
808
+ // Now clear the value and it should fall back to selected attribute
809
+ element.value = undefined
810
+ await element.updateComplete
811
+ await nextFrame()
812
+
813
+ assert.equal(element.value, 'banana', 'should rediscover selected option when value is cleared')
814
+ assert.isNotNull(element.selectedItem, 'selected item should not be null')
815
+ assert.equal(element.selectedItem!.value, 'banana', 'selected item should be rediscovered')
816
+ })
817
+
818
+ it('should handle dynamically added options with selected attribute', async () => {
819
+ const element = await dynamicOptionsFixture()
820
+ await element.updateComplete
821
+ await nextFrame()
822
+
823
+ // Initially no options
824
+ assert.isUndefined(element.value)
825
+ assert.isNull(element.selectedItem)
826
+
827
+ // Add options dynamically
828
+ element.innerHTML = `
829
+ <ui-option value="apple">Apple</ui-option>
830
+ <ui-option value="banana" selected>Banana</ui-option>
831
+ <ui-option value="cherry">Cherry</ui-option>
832
+ `
833
+
834
+ await element.updateComplete
835
+ await nextFrame()
836
+
837
+ assert.equal(element.value, 'banana', 'should discover selected option from dynamically added content')
838
+ assert.isNotNull(element.selectedItem, 'selected item should not be null')
839
+ assert.equal(
840
+ (element.selectedItem as UiOption)!.value,
841
+ 'banana',
842
+ 'selected item should be the dynamically added selected option'
843
+ )
844
+ })
845
+
846
+ it('should update when selected attribute is added to existing option', async () => {
847
+ const element = await basicFixture()
848
+ await element.updateComplete
849
+ await nextFrame()
850
+
851
+ // Initially no selection
852
+ assert.isUndefined(element.value)
853
+ assert.isNull(element.selectedItem)
854
+
855
+ // Add selected attribute to an option
856
+ const bananaOption = element.querySelector('ui-option[value="banana"]') as UiOption
857
+ bananaOption.selected = true
858
+
859
+ // Trigger setCurrentOption manually since we changed the DOM
860
+ await (element as UiSelect & { setCurrentOption(): Promise<void> }).setCurrentOption()
861
+ await element.updateComplete
862
+ await nextFrame()
863
+
864
+ assert.equal(element.value, 'banana', 'should discover newly selected option')
865
+ assert.isNotNull(element.selectedItem, 'selected item should not be null')
866
+ assert.equal(
867
+ (element.selectedItem as UiOption)!.value,
868
+ 'banana',
869
+ 'selected item should be the newly selected option'
870
+ )
871
+ })
872
+
873
+ it('should clear selection when selected attribute is removed from all options', async () => {
874
+ const element = await selectedAttributeFixture()
875
+ await element.updateComplete
876
+ await nextFrame()
877
+
878
+ // Initially has selection
879
+ assert.equal(element.value, 'banana')
880
+
881
+ // Remove selected attribute
882
+ const bananaOption = element.querySelector('ui-option[value="banana"]') as UiOption
883
+ bananaOption.selected = false
884
+
885
+ // Clear the value to trigger rediscovery
886
+ element.value = undefined
887
+ await element.updateComplete
888
+ await nextFrame()
889
+
890
+ assert.isUndefined(element.value, 'value should be undefined when no options are selected')
891
+ assert.isNull(element.selectedItem, 'selected item should be null when no options are selected')
892
+ assert.equal(element.renderValue, '', 'render value should be empty when no options are selected')
893
+ })
894
+ })
666
895
  })
667
896
  })