diff --git a/.changeset/chatty-jokes-walk.md b/.changeset/chatty-jokes-walk.md new file mode 100644 index 0000000000..87155d980e --- /dev/null +++ b/.changeset/chatty-jokes-walk.md @@ -0,0 +1,5 @@ +--- +'@primer/view-components': minor +--- + +Include value in event metadata when SelectPanel items are activated diff --git a/app/components/primer/alpha/select_panel_element.ts b/app/components/primer/alpha/select_panel_element.ts index 81dcdeecc3..3cb044976a 100644 --- a/app/components/primer/alpha/select_panel_element.ts +++ b/app/components/primer/alpha/select_panel_element.ts @@ -867,8 +867,12 @@ export class SelectPanelElement extends HTMLElement { const activationSuccess = this.dispatchEvent( new CustomEvent('beforeItemActivated', { bubbles: true, - detail: {item, checked}, cancelable: true, + detail: { + item, + checked, + value: this.#getItemContent(item)?.getAttribute('data-value'), + }, }), ) @@ -909,7 +913,11 @@ export class SelectPanelElement extends HTMLElement { this.dispatchEvent( new CustomEvent('itemActivated', { bubbles: true, - detail: {item, checked}, + detail: { + item, + checked, + value: this.#getItemContent(item)?.getAttribute('data-value'), + }, }), ) } diff --git a/app/components/primer/shared_events.ts b/app/components/primer/shared_events.ts index 2fc70ad154..e9f0150885 100644 --- a/app/components/primer/shared_events.ts +++ b/app/components/primer/shared_events.ts @@ -1,10 +1,12 @@ export type ItemActivatedEvent = { item: Element checked: boolean + value: string | null } declare global { interface HTMLElementEventMap { itemActivated: CustomEvent + beforeItemActivated: CustomEvent } } diff --git a/test/system/alpha/select_panel_test.rb b/test/system/alpha/select_panel_test.rb index 3357b5ee3c..793639f9fb 100644 --- a/test/system/alpha/select_panel_test.rb +++ b/test/system/alpha/select_panel_test.rb @@ -718,16 +718,41 @@ def test_uncheck_item_via_js_api refute_selector "li[data-item-id=item1] [aria-selected=true]" end + def test_fires_event_before_activation + visit_preview(:single_select) + + evaluate_multiline_script(<<~JS) + window.activatedItemText = null + window.activatedItemChecked = false + window.activatedItemValue = null + + document.querySelector('select-panel').addEventListener('beforeItemActivated', (event) => { + window.activatedItemText = event.detail.item.innerText + window.activatedItemChecked = event.detail.checked + window.activatedItemValue = event.detail.value + }) + JS + + click_on_invoker_button + click_on_first_item + + assert page.evaluate_script("window.activatedItemChecked") + assert_equal "Item 1", page.evaluate_script("window.activatedItemText") + assert_equal "1", page.evaluate_script("window.activatedItemValue") + end + def test_fires_event_on_activation visit_preview(:single_select) evaluate_multiline_script(<<~JS) window.activatedItemText = null window.activatedItemChecked = false + window.activatedItemValue = null document.querySelector('select-panel').addEventListener('itemActivated', (event) => { window.activatedItemText = event.detail.item.innerText window.activatedItemChecked = event.detail.checked + window.activatedItemValue = event.detail.value }) JS @@ -736,6 +761,7 @@ def test_fires_event_on_activation assert page.evaluate_script("window.activatedItemChecked") assert_equal "Item 1", page.evaluate_script("window.activatedItemText") + assert_equal "1", page.evaluate_script("window.activatedItemValue") end def test_cancelling_before_item_activated_event_prevents_selection