@neo4j-ndl/react
Version:
React implementation of Neo4j Design System
531 lines (445 loc) • 14.4 kB
Markdown
Import: `import { Select } from '@neo4j-ndl/react'`
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `ariaLabel` | `string` | | | Aria label of the select component |
| `as` | `ElementType<any, keyof IntrinsicElements>` | | | An override of the default HTML tag of the root of the component. Can also be another React component. |
| `errorText` | `ReactNode` | | | Error message, if it exists the select will be in error state |
| `helpText` | `ReactNode` | | | Help text of the select component |
| `isClean` | `boolean` | | `false` | Whether the select component is clean. If true, the select component will have a transparent background, no border and be hug the width of the content. |
| `isDisabled` | `boolean` | | | Whether the select component is disabled |
| `isFluid` | `boolean` | | `true` | Whether the select component is fluid |
| `label` | `ReactNode` | | | Label of the select component. If not provided, please provide an ariaLabel. |
| `ref` | `any` | | | A ref to apply to the root element. |
| `selectProps` | `StateManagerProps<OptionType, IsMulti, GroupType> \| CreatableProps<OptionType, IsMulti, GroupType> \| AsyncProps<...>` | | `{}` | Props of the select component, based of React Select props |
| `size` | `'large' \| 'medium' \| 'small'` | | `medium` | Size of the component |
| `type` | `'async' \| 'creatable' \| 'select'` | | `select` | Type of the select component |
The `type` prop is used to specify the type of select component to render, which will be passed to the underlying React Select component.
The `selectProps` prop is dynamically typed based on the `type` prop and can be one of the following: `StateManagerProps`, `CreatableProps`, `AsyncProps`. All select variants will have the `SelectProps` base type from React Select. For more information on the available props, see the [React Select documentation](https://react-select.com/props).
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{
label: 'Really long label that does not fit on one row',
value: 'long-label',
},
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Select an option"
helpText="Help text"
type="select"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const loadOptions = (inputValue: string) => {
return new Promise<typeof EXAMPLE_OPTIONS>((resolve) => {
setTimeout(() => {
const filteredOptions = EXAMPLE_OPTIONS.filter((option) =>
option.label.toLowerCase().includes(inputValue.toLowerCase()),
);
resolve(filteredOptions);
}, 1000);
});
};
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
helpText="Start typing to load options dynamically"
type="async"
selectProps={{
cacheOptions: true,
defaultOptions: true,
isClearable: true,
loadOptions,
menuIsOpen: props.selectProps?.menuIsOpen,
placeholder: 'Type to search...',
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
type="select"
isClean={true}
isFluid={false}
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import { Select, Typography } from '@neo4j-ndl/react';
import { useState } from 'react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
const [value, setValue] = useState<(typeof EXAMPLE_OPTIONS)[number]>(
EXAMPLE_OPTIONS[0],
);
return (
<div className="n-flex n-flex-col n-gap-token-8">
<Select
label="Label"
type="select"
selectProps={{
isMulti: false,
menuIsOpen: props.selectProps?.menuIsOpen,
menuPortalTarget: document.querySelector('body'),
onChange: (newValue) => newValue && setValue(newValue),
options: EXAMPLE_OPTIONS,
value: value,
}}
/>
<Typography variant="body-small">
Value Selected: {JSON.stringify(value)}
</Typography>
</div>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
helpText="You can create values even if they don't exist as options"
type="creatable"
selectProps={{
isClearable: true,
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
import { QuestionMarkCircleIconOutline } from '@neo4j-ndl/react/icons';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label={
<div className="n-flex n-flex-row n-gap-token-4 n-h-7 n-items-center">
Custom JSX element
<QuestionMarkCircleIconOutline className="n-h-token-16" />
</div>
}
helpText="You can have a custom label with JSX code 😱"
type="select"
selectProps={{
defaultValue: EXAMPLE_OPTIONS[1],
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
type="select"
selectProps={{
isDisabled: true,
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
helpText="Help text"
type="select"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: [],
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
errorText="Validate that your selection is correct"
type="select"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Dialog, FilledButton, Select, Typography } from '@neo4j-ndl/react';
import { useRef, useState } from 'react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
const ref = useRef<HTMLDivElement | null>(null);
const [isOpen, setIsOpen] = useState<boolean>(false);
return (
<div
ref={ref}
className="n-flex n-flex-col n-items-center n-justify-center n-relative n-h-[500px]"
>
<FilledButton size="medium" onClick={() => setIsOpen(true)}>
Open Dialog
</FilledButton>
<Dialog
container={ref?.current || undefined}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
aria-label="Dialog"
>
<Dialog.Header>Using Select inside a dialog</Dialog.Header>
<Dialog.Description className="n-flex n-flex-col n-gap-token-32">
<Typography variant="body-medium">
To use select inside a dialog and avoid the cut-off, you need to use
the property <code>menuPosition: "fixed"</code> inside the{' '}
<code>selectProps</code>. This is done automatically if used in a
Needle Dialog, but can always be overridden manually.
</Typography>
<Select
label="Inside a dialog"
type="select"
selectProps={{
defaultValue: EXAMPLE_OPTIONS[1],
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
</Dialog.Description>
</Dialog>
</div>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<div className="n-flex n-gap-token-16 n-pt-token-64">
<Select
label="Automatic menu placement"
type="select"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
menuPlacement: 'auto',
options: EXAMPLE_OPTIONS,
}}
/>
<Select
label="Bottom menu placement"
type="select"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
menuPlacement: 'bottom',
options: EXAMPLE_OPTIONS,
}}
/>
<Select
label="Top menu placement"
type="select"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
menuPlacement: 'top',
options: EXAMPLE_OPTIONS,
}}
/>
</div>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<Select
label="Label"
type="select"
selectProps={{
defaultValue: EXAMPLE_OPTIONS[1],
isClearable: true,
isMulti: true,
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
);
};
export default Component;
```
```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
import { Select } from '@neo4j-ndl/react';
const EXAMPLE_OPTIONS = [
{ label: 'Neo4j', value: 'neo4j' },
{ label: 'Needle 🪡', value: 'needle' },
{ label: 'Graph Databases', value: 'graph-database' },
{ isDisabled: true, label: 'Disabled database option', value: 'disabled' },
];
const Component = (props: React.ComponentProps<typeof Select>) => {
return (
<div className="n-flex n-gap-token-16">
<Select
label="Small"
type="select"
size="small"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
<Select
label="Medium"
type="select"
size="medium"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
<Select
label="Large"
type="select"
size="large"
selectProps={{
menuIsOpen: props.selectProps?.menuIsOpen,
options: EXAMPLE_OPTIONS,
}}
/>
</div>
);
};
export default Component;
```