);
}
```
Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать. Для такой реализации имеется пропс `portal` , который принимает либо `ref` либо `id` html-тега. Также нужно прокинуть проп `listWidth` , чтобы явно задать ширину списку. Если этого не сделать, то будет взята ширина 100% от блока, на который ведет ссылка портала.
```tsx
import React, { useRef } from 'react';
import { Select } 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 (
);
}
```
В режиме `textfield` доступны только следующие варианты `view` : `default` , `warning` , `positive` и `negative` . ```tsx
import React from 'react';
import { Select } from '@salutejs/plasma-web';
export function App() {
const [singleValue, setSingleValue] = useState('');
const [multipleValue, setMultipleValue] = useState([]);
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 { Select } 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 { Select } 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 (
);
}
```
В режиме `textfield` доступны только следующие варианты `view` : `default` , `warning` , `positive` и `negative` . ```tsx
import React from 'react';
import { Select } from '@salutejs/plasma-web';
export function App() {
const [singleValue, setSingleValue] = useState('');
const [multipleValue, setMultipleValue] = useState([]);
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 { Select } 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 { Select } 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 (
);
}
```
Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` .
Работает только в одноуровневых списках.
```tsx
import React, { useState } from 'react';
import { Select } from '@salutejs/plasma-web';
export function App() {
const items = Array(5000).fill(1).map((_, i) => ({ value: i.toString(), label: i.toString() }));
return (
);
}
```
В режиме `textfield` доступны только следующие варианты `view` : `default` , `warning` , `positive` и `negative` . ```tsx
import React from 'react';
import { Select } from '@salutejs/plasma-web';
export function App() {
const [singleValue, setSingleValue] = useState('');
const [multipleValue, setMultipleValue] = useState([]);
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 { Select } 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 { Select } 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 (
);
}
```
Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` .
Работает только в одноуровневых списках. ```tsx
import React, { useState } from 'react';
import { Select } 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 { Select } 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 (
);
}
```
В режиме `textfield` доступны только следующие варианты `view` : `default` , `warning` , `positive` и `negative` . ```tsx
import React from 'react';
import { Select } from '@salutejs/plasma-web';
export function App() {
const [singleValue, setSingleValue] = useState('');
const [multipleValue, setMultipleValue] = useState([]);
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 { Select } 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 { Select } 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 (
);
}
```
Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` .
Работает только в одноуровневых списках. ```tsx
import React, { useState } from 'react';
import { Select } 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 { Select } 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 (
);
}
```
Работа с кнопкой "Выбрать всё" осуществляется через свойство `selectAllOptions` только в режиме `multiselect` :
```tsx
type SelectAllProps = {
checked?: boolean;
indeterminate?: boolean;
label?: string;
onClick?: () => void;
sticky?: boolean;
};
```
В режиме `textfield` доступны только следующие варианты `view` : `default` , `warning` , `positive` и `negative` . ```tsx
import React from 'react';
import { Select } from '@salutejs/plasma-web';
export function App() {
const [singleValue, setSingleValue] = useState('');
const [multipleValue, setMultipleValue] = useState([]);
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 { Select } 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 { Select } 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 (
);
}
```
Свойство `virtual` позволяет виртуализировать выпадающий список. Для настройки высоты списка можно использовать свойство `listMaxHeight` .
Работает только в одноуровневых списках. ```tsx
import React, { useState } from 'react';
import { Select } 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 { Select } 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 (
);
}
```
Работа с кнопкой "Выбрать всё" осуществляется через свойство `selectAllOptions` только в режиме `multiselect` : ```tsx
type SelectAllProps = {
checked?: boolean;
indeterminate?: boolean;
label?: string;
onClick?: () => void;
sticky?: boolean;
};
```
Вся логика выбора элементов и взаимодействия с компонентом лежит на стороне пользователя.
```tsx
import React, { useState } from 'react';
import { Select } 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));
}
};
React.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 (
);
}
```
## Взаимодействие с disabled-элементами Изнутри компонента взаимодействие с disabled-элементами невозможно . Ниже представлены примеры с `selected` и `unselected` disabled-элементом.
```tsx
import React, { useState } from 'react';
import { Select } 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 { Select, Button } from '@salutejs/plasma-web';
export function App() {
type Inputs = {
Select: string,
SelectMulti: string[]
}
const { register, handleSubmit } = useForm({
defaultValues: {
Select: 'north_america',
SelectMulti: ['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 { Select, Button } from '@salutejs/plasma-web';
export function App() {
type Inputs = {
Select: string,
SelectMulti: string[]
}
const { register, handleSubmit } = useForm({
defaultValues: {
Select: 'north_america',
SelectMulti: ['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 (