Skip to content

Commit

Permalink
docs(form): Add simple examples for Select/NativeSelect
Browse files Browse the repository at this point in the history
Relates to #1396
  • Loading branch information
mlaursen committed Apr 19, 2022
1 parent ec7de5d commit 05358f5
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
The `NativeSelect` component is a simple wrapper for the `<select>` element with
`TextField` styles. Just like native `<select>` elements, this wrapper **does
not support**:

- placeholder text
- enabling `readOnly` (it can almost manually be done by disabiling each option
yourself, but it'll make it impossible to close on mobile devices if it there
are so many options that it covers the entire viewport)

That being said, the demo below will show you some patterns you can use to fake
placeholder text using the floating label and an empty `<option>` element as
well as a read-only view by disabling all `<option>`s.
This demo below will show you some patterns you can use to fake placeholder text
using the floating label and an empty `<option>` element as well as a read-only
view by disabling all `<option>`s.
Original file line number Diff line number Diff line change
@@ -1,35 +1,2 @@
The `Select` component is a custom widget that allows you to have additional
styling controls for a native `<select>` element while still being accessible.
This component inherits all the `TextField` styles just like the `NativeSelect`,
but also allows each `option` to be rendered like a `ListItem` from the #list
and #menu packages.

> Note: Even though the `Select` component supports the `inline` prop, it does
> not behave the same was as the `NativeSelect` or a native `<select>` component
> since it will not automatically update it's width to be the longest renderable
> option. The size will update whenever the value of the select changes.
This component is fully controlled, so you will need to provide the current
`value`, an `onChange` handler, and a list of `options`. An option can be:

- a number
- a string
- or an object of props to pass to a `ListItem` (see the next example for more
details here)

The `onChange` handler **will not be a native change event** since there are no
`<input>` or `<select>` elements being rendered. Instead, the `onChange` handler
will be provided the next value string as the first argument and the option as
the second: `onChange(nextValue: string, option: object | string | number)`.

Just like a native `<select>` component, the list of options can be shown by
clicking, pressing the space key, or using the up and down arrow keys. Once the
list of options are shown, the user can:

- type letters to find a match starting with the same letters
- use the up and down arrow keys to focus the previous and next items
- use the home and end keys to focus the first and last items
- press the escape key to close the listbox
- use the space or enter key to select and close the listbox

> Check out the next example for some better examples of the typeahead feature
This demo will showcase some of the of the theming options available for a
`Select` and some other built-in functionality.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { IconProvider } from "@react-md/icon";
import DemoPage from "components/Demos/DemoPage";
import type { DemoConfig } from "components/Demos/types";

import SimpleNativeSelect from "./SimpleNativeSelect";
import simpleNativeSelect from "./SimpleNativeSelect.md";

import NativeSelectExample from "./NativeSelectExample";
import nativeSelectExample from "./NativeSelectExample.md";

import SimpleSelectExample from "./SimpleSelectExample";
import simpleSelectExample from "./SimpleSelectExample.md";

import SelectExample from "./SelectExample";
import selectExample from "./SelectExample.md";

Expand All @@ -16,11 +22,21 @@ import {
} from "./CustomizingSelectOptions";

const demos: DemoConfig[] = [
{
name: "Simple Native Select",
description: simpleNativeSelect,
children: <SimpleNativeSelect />,
},
{
name: "Native Select Example",
description: nativeSelectExample,
children: <NativeSelectExample />,
},
{
name: "Simple Select Example",
description: simpleSelectExample,
children: <SimpleSelectExample />,
},
{
name: "Select Example",
description: selectExample,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
The `NativeSelect` component is a simple wrapper for the `<select>` element with
`TextField` styles. Just like native `<select>` elements, this wrapper **does
not support**:

- placeholder text
- enabling `readOnly` (it can almost manually be done by disabling each option
yourself, but it'll make it impossible to close on mobile devices if it there
are so many options that it covers the entire viewport)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ReactElement } from "react";
import { useState } from "react";
import { NativeSelect } from "@react-md/form";

import states from "constants/states";

export default function SimpleNativeSelect(): ReactElement {
const [value, setValue] = useState("");
return (
<NativeSelect
id="simple-native-select"
name="select"
label="A Label"
value={value}
onChange={(event) => setValue(event.currentTarget.value)}
>
<option value="" disabled hidden />
{states.map(({ name, abbreviation }) => (
<option key={abbreviation} value={abbreviation}>
{name}
</option>
))}
</NativeSelect>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
The `Select` component is a custom widget that allows you to have additional
styling controls for a native `<select>` element while still being accessible.
This component inherits all the `TextField` styles just like the `NativeSelect`,
but also allows each `option` to be rendered like a `ListItem` from the #list
and #menu packages.

> Note: Even though the `Select` component supports the `inline` prop, it does
> not behave the same was as the `NativeSelect` or a native `<select>` component
> since it will not automatically update it's width to be the longest renderable
> option. The size will update whenever the value of the select changes.
This component is fully controlled, so you will need to provide the current
`value`, an `onChange` handler, and a list of `options`. An option can be:

- a number
- a string
- or an object of props to pass to a `ListItem` (see the next example for more
details here)

The `onChange` handler **will not be a native change event** since there are no
`<input>` or `<select>` elements being rendered. Instead, the `onChange` handler
will be provided the next value string as the first argument and the option as
the second: `onChange(nextValue: string, option: object | string | number)`.

Just like a native `<select>` component, the list of options can be shown by
clicking, pressing the space key, or using the up and down arrow keys. Once the
list of options are shown, the user can:

- type letters to find a match starting with the same letters
- use the up and down arrow keys to focus the previous and next items
- use the home and end keys to focus the first and last items
- press the escape key to close the listbox
- use the space or enter key to select and close the listbox

> Check out the [Customizing Select Options](#customizing-select-options)
> example for some better examples of the typeahead feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { ReactElement } from "react";
import { useState } from "react";
import { Select } from "@react-md/form";

import states from "constants/states";

export default function SimpleSelectExample(): ReactElement {
const [value, setValue] = useState("");
return (
<Select
id="simple-select-example"
label="A Label"
placeholder="Choose..."
name="select"
options={states.map(({ abbreviation, name }) => ({
label: name,
value: abbreviation,
}))}
value={value}
onChange={(value) => setValue(value)}
/>
);
}

1 comment on commit 05358f5

@vercel
Copy link

@vercel vercel bot commented on 05358f5 Apr 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

react-md – ./

react-md-pi.vercel.app
react-md-mlaursen.vercel.app
react-md-git-main-mlaursen.vercel.app
react-md.dev

Please sign in to comment.