```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство alwaysOpened позволяет отображать Combobox всегда открытым. При этом closeAfterSelect игнорируется. ```tsx import React, { useState } from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [alwaysOpened, setAlwaysOpened] = useState(false); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство alwaysOpened позволяет отображать Combobox всегда открытым. При этом closeAfterSelect игнорируется. ```tsx import React, { useState } from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [alwaysOpened, setAlwaysOpened] = useState(false); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` . Работает только в одноуровневых списках. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = Array(5000).fill(1).map((_, i) => ({ value: i.toString(), label: i.toString() })); return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство alwaysOpened позволяет отображать Combobox всегда открытым. При этом closeAfterSelect игнорируется. ```tsx import React, { useState } from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [alwaysOpened, setAlwaysOpened] = useState(false); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` . Работает только в одноуровневых списках. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = Array(5000).fill(1).map((_, i) => ({ value: i.toString(), label: i.toString() })); return (
); } ``` Пример с бесконечной загрузкой элементов в списке. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { function getRandomData() { return Array(10) .fill(1) .map(() => { const n = Math.floor(Math.random() * 90000000) + 10000000; return { value: n.toString(), label: n.toString() }; }); }; const [items, setItems] = useState(getRandomData()); const [isInfiniteLoading, setIsInfiniteLoading] = useState(false); const getData = async () => { return new Promise((resolve) => { setTimeout(() => { resolve(getRandomData()); }, 1500); }); }; const handleScroll = async (e) => { if (isInfiniteLoading) return; if (e.target.scrollTop + e.target.offsetHeight + 10 > e.target.scrollHeight) { setIsInfiniteLoading(true); const res = await getData(); setItems([...items, ...res]); setIsInfiniteLoading(false); } }; return (
Загружаю... : undefined} />
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство alwaysOpened позволяет отображать Combobox всегда открытым. При этом closeAfterSelect игнорируется. ```tsx import React, { useState } from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [alwaysOpened, setAlwaysOpened] = useState(false); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` . Работает только в одноуровневых списках. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = Array(5000).fill(1).map((_, i) => ({ value: i.toString(), label: i.toString() })); return (
); } ``` Пример с бесконечной загрузкой элементов в списке. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { function getRandomData() { return Array(10) .fill(1) .map(() => { const n = Math.floor(Math.random() * 90000000) + 10000000; return { value: n.toString(), label: n.toString() }; }); }; const [items, setItems] = useState(getRandomData()); const [isInfiniteLoading, setIsInfiniteLoading] = useState(false); const getData = async () => { return new Promise((resolve) => { setTimeout(() => { resolve(getRandomData()); }, 1500); }); }; const handleScroll = async (e) => { if (isInfiniteLoading) return; if (e.target.scrollTop + e.target.offsetHeight + 10 > e.target.scrollHeight) { setIsInfiniteLoading(true); const res = await getData(); setItems([...items, ...res]); setIsInfiniteLoading(false); } }; return (
Загружаю... : undefined} />
); } ``` Работа с кнопкой "Выбрать всё" осуществляется через свойство `selectAllOptions` только в режиме `multiple` : ```tsx type SelectAllProps = { checked?: boolean; indeterminate?: boolean; label?: string; onClick?: () => void; sticky?: boolean; }; ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство alwaysOpened позволяет отображать Combobox всегда открытым. При этом closeAfterSelect игнорируется. ```tsx import React, { useState } from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [alwaysOpened, setAlwaysOpened] = useState(false); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` . Работает только в одноуровневых списках. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = Array(5000).fill(1).map((_, i) => ({ value: i.toString(), label: i.toString() })); return (
); } ``` Пример с бесконечной загрузкой элементов в списке. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { function getRandomData() { return Array(10) .fill(1) .map(() => { const n = Math.floor(Math.random() * 90000000) + 10000000; return { value: n.toString(), label: n.toString() }; }); }; const [items, setItems] = useState(getRandomData()); const [isInfiniteLoading, setIsInfiniteLoading] = useState(false); const getData = async () => { return new Promise((resolve) => { setTimeout(() => { resolve(getRandomData()); }, 1500); }); }; const handleScroll = async (e) => { if (isInfiniteLoading) return; if (e.target.scrollTop + e.target.offsetHeight + 10 > e.target.scrollHeight) { setIsInfiniteLoading(true); const res = await getData(); setItems([...items, ...res]); setIsInfiniteLoading(false); } }; return (
Загружаю... : undefined} />
); } ``` Работа с кнопкой "Выбрать всё" осуществляется через свойство `selectAllOptions` только в режиме `multiple` : ```tsx type SelectAllProps = { checked?: boolean; indeterminate?: boolean; label?: string; onClick?: () => void; sticky?: boolean; }; ``` Вся логика выбора элементов и взаимодействия с компонентом лежит на стороне пользователя. ```tsx import React, { useState, useEffect } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const flatItems = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'rio_de_janeiro', label: 'Рио-де-Жанейро', }, { value: 'sao_paulo', label: 'Сан-Паулу', }, { value: 'buenos_aires', label: 'Буэнос-Айрес', }, { value: 'cordoba', label: 'Кордова', }, { value: 'bogota', label: 'Богота', }, { value: 'medellin', label: 'Медельин', }, ]; const [value, setValue] = useState([]); const [checked, setChecked] = useState(false); const [indeterminate, setIndeterminate] = useState(false); const handleClick = () => { if (checked && !indeterminate) { setValue([]); } else { setValue(flatItems.map((item) => item.value)); } }; useEffect(() => { if (value.length === 0) { setChecked(false); setIndeterminate(false); } else if (value.length === flatItems.length) { setChecked(true); setIndeterminate(false); } else { setChecked(true); setIndeterminate(true); } }, [value]); return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState([]); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Есть возможность задать значения по дефолту (главное, чтобы они находились в `items` ). Также можно управлять состоянием снаружи селекта. ```tsx import React from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [multipleValue, setMultipleValue] = useState(['brazil', 'north_america']); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала. ```tsx import React, { useRef } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const [value, setValue] = useState(''); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const ref = useRef(null) return (
); } ``` `value` и `onChange` - опциональные параметры. Если вы хотите `uncontrolled` вариант компонента - их пробрасывать необязательно. ```tsx import React from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство alwaysOpened позволяет отображать Combobox всегда открытым. При этом closeAfterSelect игнорируется. ```tsx import React, { useState } from 'react'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const [alwaysOpened, setAlwaysOpened] = useState(false); const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` . Работает только в одноуровневых списках. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = Array(5000).fill(1).map((_, i) => ({ value: i.toString(), label: i.toString() })); return (
); } ``` Пример с бесконечной загрузкой элементов в списке. ```tsx import React, { useState } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { function getRandomData() { return Array(10) .fill(1) .map(() => { const n = Math.floor(Math.random() * 90000000) + 10000000; return { value: n.toString(), label: n.toString() }; }); }; const [items, setItems] = useState(getRandomData()); const [isInfiniteLoading, setIsInfiniteLoading] = useState(false); const getData = async () => { return new Promise((resolve) => { setTimeout(() => { resolve(getRandomData()); }, 1500); }); }; const handleScroll = async (e) => { if (isInfiniteLoading) return; if (e.target.scrollTop + e.target.offsetHeight + 10 > e.target.scrollHeight) { setIsInfiniteLoading(true); const res = await getData(); setItems([...items, ...res]); setIsInfiniteLoading(false); } }; return (
Загружаю... : undefined} />
); } ``` Работа с кнопкой "Выбрать всё" осуществляется через свойство `selectAllOptions` только в режиме `multiple` : ```tsx type SelectAllProps = { checked?: boolean; indeterminate?: boolean; label?: string; onClick?: () => void; sticky?: boolean; }; ``` Вся логика выбора элементов и взаимодействия с компонентом лежит на стороне пользователя. ```tsx import React, { useState, useEffect } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const flatItems = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'rio_de_janeiro', label: 'Рио-де-Жанейро', }, { value: 'sao_paulo', label: 'Сан-Паулу', }, { value: 'buenos_aires', label: 'Буэнос-Айрес', }, { value: 'cordoba', label: 'Кордова', }, { value: 'bogota', label: 'Богота', }, { value: 'medellin', label: 'Медельин', }, ]; const [value, setValue] = useState([]); const [checked, setChecked] = useState(false); const [indeterminate, setIndeterminate] = useState(false); const handleClick = () => { if (checked && !indeterminate) { setValue([]); } else { setValue(flatItems.map((item) => item.value)); } }; useEffect(() => { if (value.length === 0) { setChecked(false); setIndeterminate(false); } else if (value.length === flatItems.length) { setChecked(true); setIndeterminate(false); } else { setChecked(true); setIndeterminate(true); } }, [value]); return (
); } ``` Пример с добавлением нового элемента в список. ```tsx import React, { useState, useEffect } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const shortListItems = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'rio_de_janeiro', label: 'Рио-де-Жанейро', }, { value: 'sao_paulo', label: 'Сан-Паулу', }, ]; const [items, setItems] = useState(shortListItems); const [value, setValue] = useState([]); const [textValue, setTextValue] = useState(''); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { setItems([...items, { value: textValue, label: textValue }]); setValue([...value, textValue]); setTextValue(''); } }; return (
); } ``` ## Взаимодействие с disabled-элементами Изнутри компонента взаимодействие с disabled-элементами невозможно . Ниже представлены примеры с `selected` и `unselected` disabled-элементом. ```tsx import React, { useState, useEffect } from 'react'; import { Combobox } from '@salutejs/plasma-web'; export function App() { const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', disabled: true, }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; const [value, setValue] = useState(['brazil']); return (
); } ``` ## Использование с React Hook Form и нативной формой :::caution Использование атрибута `name` Используйте свойство `name` только когда это необходимо. Оно влияет на выходной тип в `onChange` . ::: Работа с `react-hook-form` через `register` . ```tsx import React from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { type Inputs = { combobox: string, comboboxMulti: string[] } const { register, handleSubmit } = useForm({ defaultValues: { combobox: 'north_america', comboboxMulti: ['brazil'] } }); const onSubmit: SubmitHandler = (data) => { console.log(data); }; const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` ## Использование с React Hook Form и нативной формой :::caution Использование атрибута `name` Используйте свойство `name` только когда это необходимо. Оно влияет на выходной тип в `onChange` . ::: Работа с `react-hook-form` через `register` . ```tsx import React from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { type Inputs = { combobox: string, comboboxMulti: string[] } const { register, handleSubmit } = useForm({ defaultValues: { combobox: 'north_america', comboboxMulti: ['brazil'] } }); const onSubmit: SubmitHandler = (data) => { console.log(data); }; const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Работа с `react-hook-form` через `controller` . ```tsx import React from 'react'; import { useForm, Controller, SubmitHandler } from 'react-hook-form'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { type Inputs = { combobox: string, comboboxMulti: string[] } const { control, handleSubmit } = useForm({ defaultValues: { combobox: 'north_america', comboboxMulti: ['brazil'] } }); const onSubmit: SubmitHandler = (data) => { console.log(data); }; const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
( )} /> ( )} />
); } ``` ## Использование с React Hook Form и нативной формой :::caution Использование атрибута `name` Используйте свойство `name` только когда это необходимо. Оно влияет на выходной тип в `onChange` . ::: Работа с `react-hook-form` через `register` . ```tsx import React from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { type Inputs = { combobox: string, comboboxMulti: string[] } const { register, handleSubmit } = useForm({ defaultValues: { combobox: 'north_america', comboboxMulti: ['brazil'] } }); const onSubmit: SubmitHandler = (data) => { console.log(data); }; const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ``` Работа с `react-hook-form` через `controller` . ```tsx import React from 'react'; import { useForm, Controller, SubmitHandler } from 'react-hook-form'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { type Inputs = { combobox: string, comboboxMulti: string[] } const { control, handleSubmit } = useForm({ defaultValues: { combobox: 'north_america', comboboxMulti: ['brazil'] } }); const onSubmit: SubmitHandler = (data) => { console.log(data); }; const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
( )} /> ( )} />
); } ``` Работа с нативной формой. ```tsx import React from 'react'; import { useForm, Controller, SubmitHandler } from 'react-hook-form'; import { Combobox, Button } from '@salutejs/plasma-web'; export function App() { const onSubmit = (event: React.FormEvent) => { event.preventDefault(); const formData = new FormData(event.currentTarget); for (const [name, value] of formData) { console.log(name, value); } }; const items = [ { value: 'north_america', label: 'Северная Америка', }, { value: 'south_america', label: 'Южная Америка', items: [ { value: 'brazil', label: 'Бразилия', }, { value: 'argentina', label: 'Аргентина', }, ], }, ]; return (
); } ```