Обзор
CountrySelect предоставляет полный выбор страны с триггером с подписью, декоративными флагами, поиском и вариантом без выбора страны. CountrySelect.Root, CountrySelect.Trigger и CountrySelect.Options предоставляют одну и ту же реализацию для композиции с Dropdown. Ваше приложение предоставляет данные о странах и переведённый текст, а также определяет, как выбранные идентификаторы сопоставляются с сохраняемыми значениями.
Использование
Предоставьте подготовленные варианты с уникальными стабильными строковыми идентификаторами и отображаемыми подписями. Средство выбора передаёт идентификаторы без изменений, независимо от отображаемого языка. Флаги — необязательные декоративные React-узлы. Для варианта можно задатьdisabled: true, чтобы он оставался видимым без возможности выбора.
defaultValue инициализирует неконтролируемый выбор. Используйте value и onValueChange для контролируемого выбора. Внешнее обновление value обновляет и триггер, и выбранный вариант, в том числе когда всплывающее окно открыто.
Общие части
Root управляет подготовленными вариантами и выбранным идентификатором. Он не добавляет элемент DOM. Trigger считывает этот выбор и отображает его метку и флаг. Options считывает те же данные и отображает строки с поиском внутри Dropdown.SelectionGroup. Dropdown управляет открытием, размещением всплывающего окна, страницами, навигацией и фокусом.
closeOnSelect по умолчанию — true. Задайте для него false в сокращённой форме или в Options, если после выбора всплывающее окно должно оставаться открытым.
Очистка и отмена
null означает отсутствие страны. При выборе строки без страны передаётся null; передача value={null} очищает контролируемый селектор. Пустая строка ('') — допустимый предоставленный идентификатор варианта, отличный от null.
onValueChange получает следующий идентификатор или null, а также сведения о событии выбора Dropdown: event, reason, trigger, cancel и isCanceled. Вызовите details.cancel() перед обновлением контролируемого состояния, чтобы сохранить текущий выбор и оставить всплывающее окно открытым. Повторный выбор текущего идентификатора не вызывает ещё одного изменения значения.
Для идентификатора, отсутствующего в countries, отображаются noCountryLabel и значок отсутствия страны. Его отображение не вызывает изменения и не перезаписывает значение хоста. Приложение само решает, как обрабатывать сохранённые значения, отсутствующие среди текущих вариантов.
Поиск и взаимодействие
Поиск сопоставляет подготовленные отображаемые метки. Он игнорирует регистр букв, необязательные диакритические знаки в латинском, греческом, арабском и еврейском тексте, а также знаки ударения в кириллице, считает кириллическуюё буквой е и преобразует такие буквы, как ø, æ и ß, в o, ae и ss. Он также игнорирует отдельные символы диакритических знаков, такие как ^, `, ´, ¨ и ˇ, поэтому ожидающая мертвая клавиша не скрывает совпадения. Знаки, образующие отдельные буквы, остаются значимыми, например японские знаки озвончения, индийские знаки гласных и кириллическая й. Частично введенный корейский слог, например ㅎ или 하, соответствует слогам, которые начинаются с него, например 한. noCountryLabel участвует в том же поиске. Запрос без соответствующих вариантов отображает noResultsLabel.
Клавиши со стрелками, Home и End перемещают фокус, не изменяя выбранный идентификатор. Enter или Space на доступном варианте подтверждает выбор через его группу выбора. Escape и взаимодействие вне элемента используют механизмы закрытия и обработки фокуса Dropdown. У каждого селектора независимые состояние выбора и всплывающего окна.
Активация поиска Dropdown и защита IME по-прежнему требуют интеграционной работы, как и сеансы ленивой загрузки страниц и поведение неактивных страниц. Обе формы селектора при повторном открытии сбрасывают собственный поиск, в том числе во всплывающих окнах, которые остаются смонтированными. Их общая реализация ещё не завершает жизненный цикл страниц и просмотра Dropdown.
disabled на Root или в сокращённой форме предотвращает открытие и выбор. Средство выбора без предоставленных стран также отключено. Если любое из этих условий возникает, когда всплывающее окно открыто, селектор запрашивает закрытие. При закрытии фокус возвращается триггеру. Контролируемые хосты должны принять этот запрос на закрытие через onOpenChange; сокращённая форма также скрывает всплывающее окно, пока оно отключено. После принятия запроса на закрытие повторное включение селектора не открывает его автоматически. Триггер остаётся доступным для фокуса и предоставляет aria-disabled. Отключённые триггеры пропускают обработчики активации потребителя. Функциональные формы className, style и render получают disabled: true в состоянии триггера.
Метки и настройка
Укажите видимыйlabel или используйте aria-label либо aria-labelledby на триггере. Метки по ссылке имеют приоритет над непустым aria-label, который имеет приоритет над видимой меткой. При наличии одного из этих имён выбранная страна описывает триггер. В противном случае его именует выбранная страна. Всплывающее окно наследует имя триггера, если метки всплывающего окна, заданные вызывающим кодом, или заголовок Dropdown не задают ему имя. Сокращённая форма также именует свой список вариантов на основе этих меток триггера, если только optionsProps не задаёт собственное доступное имя. При составном использовании задайте для Options aria-label или aria-labelledby, чтобы явно указать имя списка вариантов. В противном случае он ссылается на зарегистрированный заголовок Dropdown или содержимое триггера. Подсказка показывает полную выбранную метку, если она обрезана.
searchLabel задает заполнитель и доступное имя поля поиска, noCountryLabel — текст отсутствия страны, а noResultsLabel — текст пустого результата. По умолчанию используются Search, No country и No results. Передавайте переведенные строки, когда ваше приложение локализовано. Пользовательские дочерние элементы Trigger заменяют отображение выбранной страны; вызывающий код управляет этим содержимым и его доступным представлением.
Нативные атрибуты триггера, обработчики событий, className, style, ref и render применяются к кнопке триггера. wrapperProps применяется к окружающему div, который также содержит видимую метку. Нативные свойства Options, ref и render применяются к его div группы выбора. Его функция render получает { value, multiple: false }, где value — общедоступный идентификатор страны или null, а не внутренний идентификатор варианта. searchProps применяется к полю ввода поиска; значение поиска и обработка изменений остаются в управлении селектора. Сокращённая форма принимает те же свойства поиска напрямую, а атрибуты группы — через optionsProps. Передавайте предоставленные свойства и ссылки при замене элемента через render.
Интеграция с хостом и хранение
Сокращённая форма принимаетopen, defaultOpen, onOpenChange, onEscapeKeyDown, onInteractOutside и defaultPage из Dropdown. При составном использовании задавайте их в Dropdown.Root. Сейчас onOpenChange передаёт только логическое значение в соответствии с публичным контрактом Dropdown. Сведения о событии открытия и общая отмена открытия по-прежнему недоступны на верхнем уровне. Колбэки закрытия по Escape и при взаимодействии вне элемента могут вызвать event.preventDefault(), чтобы оставить всплывающее окно открытым.
popupProps принимает все свойства Dropdown.Content, кроме children, включая нативные атрибуты всплывающего окна, ref, render, позиционирование, место назначения портала, доступные имена и keepMounted. При составном использовании передавайте их непосредственно в Dropdown.Content.
Храните идентификаторы выпадающего списка, стеки фокуса, метаданные полей, сохранение и жизненный цикл редактирования в адаптере хоста. Фронтенд-адаптер Twenty использует стабильные коды стран для идентификаторов селектора и преобразует явные выборы обратно в существующие значения названий стран исходного источника. Сохранённая пустая строка сопоставляется с null селектора; несовпадающие устаревшие значения остаются сохранёнными, пока явный выбор не изменит их. Переведённые отображаемые метки не становятся сохранёнными названиями стран. Приложения с другим форматом хранения также должны выполнять преобразование в своём адаптере.
Отправка нативной формы, сброс, required, readOnly и интеграция Field для этого пользовательского селектора пока отложены.
Средство рендеринга компонента Front
Фикстуры фронтенд-компонентов React и Preact проверяют открытие указателем, фильтрацию и выбор через сокращённый и составной API, включая контролируемые и неконтролируемые значения, очистку и повторный выбор null, отменённые изменения, внешние контролируемые обновления, отключённое взаимодействие, переведённые метки и декоративные флаги. Они также проверяют нативные свойства и ссылки триггера и поля ввода поиска, а также цели рендеринга и ссылки триггера и группы вариантов. Активация поиска с клавиатуры и обработка IME, время жизни сеанса страниц, а также полное принятие портала, геометрии, прокрутки, закрытия по взаимодействию вне элемента и восстановления фокуса средством рендеринга остаются открытыми вопросами.Миграция
Замените прежний маркер отсутствия страны в виде пустой строки наnull в контролируемых значениях и состоянии выбора. Пустая строка ('') теперь является допустимым идентификатором варианта, поэтому value="" больше не означает отсутствие страны. Сохраняйте неизменным каждое значение CountryChoice.value; существующие строковые идентификаторы могут остаться без изменений, а отображаемые метки можно переводить независимо.
Обновите обработчики onValueChange, чтобы они принимали string | null. Теперь колбэк также получает eventDetails вторым аргументом, включая cancel() для отклонения выбора. Обработчики, которым не нужны сведения о событии, могут продолжать использовать только первый аргумент.
Если ваше хранилище использует '' для отсутствия страны, преобразуйте его в null перед передачей в селектор и преобразуйте полученный null обратно в '' при сохранении. Сохраняйте это преобразование совместимости в адаптере приложения и не применяйте его, когда '' является преднамеренным идентификатором варианта.
Свойства
ReactNode
Custom trigger content. Replaces the selected country presentation while retaining shared trigger behavior.
string | ((state: PopoverTriggerState) => string | undefined)
Class applied to the trigger.
number
по умолчанию:"0"
How long to wait before closing the popover that was opened on hover.
Specified in milliseconds.Requires the
openOnHover prop.boolean
Closes the popup after a selection. Defaults to true. Cancelled selection keeps it open.
readonly CountryChoice[]
обязательно
Prepared country choices with unique stable string values, caller-owned labels, and optional decorative flags and disabled states. An empty string is a valid choice value.
boolean
Whether the uncontrolled popup is initially open.
string
Dropdown page shown when the popup opens. Defaults to root.
string | null
Initial uncontrolled selected identifier. Defaults to null.
number
по умолчанию:"300"
How long to wait before the popover may be opened on hover. Specified in milliseconds.Requires the
openOnHover prop.boolean
Prevents opening and selection while the trigger stays focusable. An empty country list is also disabled.
string
ID of the trigger. Generated when omitted.
string
Optional visible label that names the trigger.
boolean
по умолчанию:"true"
Whether the component renders a native
<button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (e.g. <div>).string
Text of the no-country choice, also displayed when no country is selected.
string
Text displayed when no choice matches the search.
((event: DropdownDismissEvent) => void)
Called before Escape dismisses the popup. Call event.preventDefault() to keep it open.
((event: DropdownDismissEvent) => void)
Called before outside interaction or Tab dismisses the popup. Call event.preventDefault() to keep it open.
((open: boolean) => void)
Reports popup opening and closing with the next boolean state, matching Dropdown.Root.
((value: string | null, eventDetails: DropdownSelectionGroupChangeEventDetails) => void)
Reports the selected identifier or null with cancellable event details. Call details.cancel() to preserve selection and keep the popup open.
boolean
Controls whether the country popup is open.
boolean
по умолчанию:"false"
Whether the popover should also open when the trigger is hovered.
Omit<CountrySelectOptionsProps, "closeOnSelect" | "searchLabel" | "noResultsLabel" | "searchProps">
Native props, ref, and render for the selection group div rendered by CountrySelect.Options.
Omit<DropdownContentProps, "children">
Dropdown.Content props, including native popup attributes, ref, render, positioning, portal destination, and keepMounted. Explicit popup accessible names override the trigger name. Children are owned by the picker.
Ref<HTMLButtonElement>
Ref to the trigger element.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverTriggerState>
Replaces the trigger element while preserving its behavior and props.
string
Placeholder and accessible name of the search input.
Omit<DropdownSearchProps, "defaultValue" | "value" | "onValueChange">
Native search input props, ref, and render. Search value and change handling are owned by the picker.
CSSProperties | ((state: PopoverTriggerState) => CSSProperties | undefined)
Style applied to the element, or a function that
returns a style object based on the component’s state.
string | null
Controlled selected identifier. Null selects no country; undefined leaves selection uncontrolled.
Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "children">
Native props and ref for the div around the trigger and its visible label. Children are owned by the picker.
CountrySelect.Root
ReactNode
обязательно
Picker composition containing Dropdown.Root, CountrySelect.Trigger, and CountrySelect.Options. Root adds no DOM element.
readonly CountryChoice[]
обязательно
Prepared country choices with unique stable string values, caller-owned labels, and optional decorative flags and disabled states. An empty string is a valid choice value.
string | null
по умолчанию:"null"
Initial uncontrolled selected identifier. Defaults to null.
boolean
по умолчанию:"false"
Prevents opening and selection. An empty country list is also disabled. The trigger stays focusable with aria-disabled.
string
по умолчанию:"No country"
Text for the null selection and its option. Defaults to No country.
((value: string | null, eventDetails: DropdownSelectionGroupChangeEventDetails) => void)
Reports the selected identifier or null with event, reason, trigger, cancel and isCanceled details. Call cancel() to preserve selection and keep the popup open.
string | null
Controlled selected identifier. Null selects no country; undefined leaves selection uncontrolled.
CountrySelect.Trigger
ReactNode
Custom trigger content. Replaces the selected country presentation while retaining shared trigger behavior.
string | ((state: PopoverTriggerState) => string | undefined)
Class applied to the trigger button.
number
по умолчанию:"0"
How long to wait before closing the popover that was opened on hover.
Specified in milliseconds.Requires the
openOnHover prop.number
по умолчанию:"300"
How long to wait before the popover may be opened on hover. Specified in milliseconds.Requires the
openOnHover prop.string
ID of the trigger. In addition to being forwarded to the rendered element,
it is also used to specify the active trigger for the popover in controlled mode (with the PopoverRoot
triggerId prop).string
Optional visible label that names the trigger.
boolean
по умолчанию:"true"
Whether the component renders a native
<button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (e.g. <div>).boolean
по умолчанию:"false"
Whether the popover should also open when the trigger is hovered.
Ref<HTMLButtonElement>
Ref to the trigger element.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverTriggerState>
Replaces the trigger element. Custom components must forward the supplied props and ref.
CSSProperties | ((state: PopoverTriggerState) => CSSProperties | undefined)
Style applied to the element, or a function that
returns a style object based on the component’s state.
Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "children">
Native props and ref for the div around the trigger and its visible label. Children are owned by the picker.
CountrySelect.Options
string
Accessible name for the selection listbox. Overrides its default name.
string
Accessible name references for the selection listbox. Defaults to the registered Dropdown title or trigger element.
string
Class applied to the selection group div.
boolean
Closes the popup after a selection. Defaults to true. Cancelled selection keeps it open.
string
Text displayed when no choice matches the search. Defaults to No results.
Ref<HTMLDivElement>
Ref to the selection group element.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, CountrySelectOptionsState>
Replaces the selection group div. Functions receive supplied props and { value, multiple: false } state, with the public string or null selection. Custom components must forward the supplied props and ref.
string
Search placeholder and accessible name. Defaults to Search.
Omit<DropdownSearchProps, "defaultValue" | "value" | "onValueChange">
Native search input props, ref, and render. Search value and change handling are owned by the picker.