tailwindlabs / headlessui

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
https://headlessui.com
MIT License
25.81k stars 1.07k forks source link

Display value not present in the DOM #3417

Open ruffjaxson opened 1 month ago

ruffjaxson commented 1 month ago

Discussed in https://github.com/tailwindlabs/headlessui/discussions/3416

Originally posted by **ruffjaxson** August 7, 2024 (using Headless 2.1) I'm trying to switch all of the drop-downs in our app over to the Combobox. We have extensive E2E tests using Cypress. These tests use the pickers, and then check the display values. From what I can tell, the combobox does not expose the selected item's display value in the DOM... yet it's somehow appearing inside the input element. Screenshot 2024-08-07 at 1 24 31 AM To be clear, even though there is a value selected, when I CMD+F in the dev console Elements tab for 'Hawaii', I only see the hidden input with the right value. I need to see the display value somewhere in the DOM for proper E2E testing. The cypress code: ``` cy.get('#dropdown-account-status').should('contain', 'Free Trial'); ``` Our combobox: ``` import React, { Dispatch, ReactElement, SetStateAction, useState, useEffect } from 'react'; import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Label } from '@headlessui/react' import classNames from '../../../utils/class-names'; import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/24/outline'; import { prepareStringForId, ripOutHtml } from '../../../utils/string-utility'; export interface HeadlessPickerItem { value: string; displayValue: string; } type HeadlessUiPickerProps = { formInputName: string; items: Array; selectedItem: HeadlessPickerItem; setSelectedItem: Dispatch>; label?: string; emWidth?: number; disabled?: boolean; }; const HeadlessUiPicker = ( { formInputName, items, selectedItem, setSelectedItem, label, emWidth = 14, disabled = false, }: HeadlessUiPickerProps, ): ReactElement => { const [query, setQuery] = useState('') const filteredItems = query === '' ? items : items.filter((item) => { return item.displayValue.toLowerCase().includes(query.toLowerCase()) }); return (
{ setSelectedItem(item)}} onClose={() => setQuery('')} by="value" > {label && ()}
setQuery(event.target.value)} style={{ height: '38px' }} displayValue={(item?: HeadlessPickerItem) => item?.displayValue} placeholder="Select One:" />
{filteredItems.map((item) => ( {ripOutHtml(item.displayValue)} ))}

); };

export default HeadlessUiPicker;



Any help greatly appreciated. Thank you 🙏🏼
</div>