Skip to content

Commit

Permalink
Text input loading state (#1920)
Browse files Browse the repository at this point in the history
* adds loading indicator to text inputs

* removes style debugging div

* updates stories and docs

* updates tests

* fixes silly test mistakes

* revert default textinput story

* adds changeset

* Update src/TextInput.tsx

Co-authored-by: Pavithra Kodmad <pksjce@github.com>

* updates component API

* addresses PR feedback

* fixes linting error

* indicate a busy status to assistive technology

* updates snaps

* renames 'isLoading' prop to 'loading'

* Update docs/content/TextInput.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update docs/content/TextInput.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update docs/content/TextInput.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update docs/content/TextInput.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* Update docs/content/TextInput.mdx

Co-authored-by: Cole Bemis <colebemis@github.com>

* updates snapshots

* nests examples under an 'Examples' heading

* export TextInput non-pass-through props

* fix undefined type usage

* fixes story types

Co-authored-by: Pavithra Kodmad <pksjce@github.com>
Co-authored-by: Cole Bemis <colebemis@github.com>
  • Loading branch information
3 people authored Mar 21, 2022
1 parent da44635 commit 40ed423
Show file tree
Hide file tree
Showing 13 changed files with 12,982 additions and 50 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-lemons-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Adds a loadings state to our text input components
107 changes: 88 additions & 19 deletions docs/content/TextInput.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ TextInput is a form component to add default styling to the native text input.

**Note:** Don't forget to set `aria-label` to make the TextInput accessible to screen reader users.

## Default example
## Examples

### Basic

```jsx live
<TextInput aria-label="Zipcode" name="zipcode" placeholder="Zipcode" autoComplete="postal-code" />
```

## Text Input with icons
### With icons

```jsx live
<>
Expand All @@ -37,7 +39,7 @@ TextInput is a form component to add default styling to the native text input.
</>
```

## Text Input with text visuals
### With text visuals

```jsx live
<>
Expand All @@ -47,7 +49,66 @@ TextInput is a form component to add default styling to the native text input.
</>
```

## Text Input with error and warning states
### With visuals and loading indicators

```javascript live noinline
const WithIconAndLoadingIndicator = () => {
const [loading, setLoading] = React.useState(true)

const toggleLoadingState = () => {
setLoading(!loading)
}

return (
<>
<Box mb={6}>
<button type="button" onClick={toggleLoadingState}>
Toggle loading state {loading ? 'off' : 'on'}
</button>
</Box>

<Text fontSize={3} mb={1} display="block">
No visual
</Text>
<Box mb={3}>
<TextInput loading={loading} />
</Box>

<Text fontSize={3} mb={1} display="block">
Leading visual
</Text>
<Box mb={3}>
<TextInput leadingVisual={SearchIcon} loading={loading} />
</Box>

<Text fontSize={3} mb={1} display="block">
Trailing visual
</Text>
<Box mb={3}>
<TextInput trailingVisual={SearchIcon} loading={loading} />
</Box>

<Text fontSize={3} mb={1} display="block">
Both visuals
</Text>
<Box mb={3}>
<TextInput leadingVisual={SearchIcon} trailingVisual={SearchIcon} loading={loading} />
</Box>

<Text fontSize={3} mb={2} display="block">
Both visuals, position overriden
</Text>
<Box mb={3}>
<TextInput loaderPosition="trailing" leadingVisual={SearchIcon} trailingVisual={SearchIcon} loading={loading} />
</Box>
</>
)
}

render(<WithIconAndLoadingIndicator />)
```

### With error and warning states

```jsx live
<>
Expand All @@ -69,19 +130,19 @@ TextInput is a form component to add default styling to the native text input.
</>
```

## Block text input
### Block text input

```jsx live
<TextInput block aria-label="Zipcode" name="zipcode" placeholder="560076" autoComplete="postal-code" />
```

## Contrast text input
### Contrast text input

```jsx live
<TextInput contrast aria-label="Zipcode" name="zipcode" placeholder="Find user" autoComplete="postal-code" />
```

## Monospace text input
### Monospace text input

```jsx live
<TextInput
Expand All @@ -103,31 +164,40 @@ TextInput is a form component to add default styling to the native text input.
name="block"
type="boolean"
defaultValue="false"
description={
<>
Creates a full width input element
</>
}
description="Creates a full-width input element"
/>
<PropsTableRow
name="contrast"
type="boolean"
defaultValue="false"
description="Changes background color to a higher contrast color"
/>
<PropsTableRow
name="monospace"
type="boolean"
defaultValue="false"
description="Shows input in monospace font"
/>
<PropsTableRow name='size' type="'small' | 'medium' | 'large'" description="Creates a smaller or larger input than the default." />

<PropsTableRow name="loading" type="boolean" description="Whether to show a loading indicator in the input" />
<PropsTableRow
name="loaderPosition"
type="'auto' | 'leading' | 'trailing'"
description={
<>
<div>Which position to render the loading indicator</div>
<ul>
<li>
'auto' (default): at the end of the input, unless a `leadingVisual` is passed. Then, it will render at the
beginning
</li>
<li>'leading': at the beginning of the input</li>
<li>'trailing': at the end of the input</li>
</ul>
</>
}
/>
<PropsTableRow
name="leadingVisual"
type={<>string | React.ComponentType</>}
description="Visual positioned on the left edge inside the input"
/>
<PropsTableRow name="monospace" type="boolean" defaultValue="false" description="Shows input in monospace font" />
<PropsTableRow
name="trailingVisual"
type={<>string | React.ComponentType</>}
Expand All @@ -138,7 +208,6 @@ TextInput is a form component to add default styling to the native text input.
type="'error' | 'success' | 'warning'"
description="Style the input to match the status"
/>

<PropsTableRow
name="variant"
type="'small' | 'medium' | 'large'"
Expand Down
153 changes: 153 additions & 0 deletions docs/content/TextInputWithTokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,159 @@ const LeadingVisualExample = () => {
render(LeadingVisualExample)
```

## With visuals and loading indicators

```javascript live noinline
const WithIconAndLoadingIndicator = () => {
const [dates, setDates] = React.useState([
{text: '01 Jan', id: 0},
{text: '01 Feb', id: 1},
{text: '01 Mar', id: 2}
])
const onDateRemove = tokenId => {
setDates(dates.filter(token => token.id !== tokenId))
}

const [loading, setLoading] = React.useState(true)
const toggleLoadingState = () => {
setLoading(!loading)
}

return (
<>
<Box mb={5} display="flex" justifyContent="flex-end">
<button type="button" onClick={toggleLoadingState}>
Toggle loading state {loading ? 'off' : 'on'}
</button>
</Box>

<h3>No visual</h3>
<Box mb={2}>
<TextInputWithTokens tokens={dates} onTokenRemove={onDateRemove} value="auto" loading={loading} />
</Box>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
value="leading"
loading={loading}
loaderPosition="leading"
/>
</Box>
<Box mb={5}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
value="trailing"
loading={loading}
loaderPosition="trailing"
/>
</Box>

<h3>Leading visual</h3>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
leadingVisual={CalendarIcon}
loading={loading}
value="auto"
/>
</Box>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
leadingVisual={CalendarIcon}
loading={loading}
loaderPosition="leading"
value="leading"
/>
</Box>
<Box mb={5}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
leadingVisual={CalendarIcon}
loading={loading}
loaderPosition="trailing"
value="trailing"
/>
</Box>

<h3>Trailing visual</h3>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
trailingVisual={CalendarIcon}
loading={loading}
value="auto"
/>
</Box>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
trailingVisual={CalendarIcon}
loading={loading}
loaderPosition="leading"
value="leading"
/>
</Box>
<Box mb={5}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
trailingVisual={CalendarIcon}
loading={loading}
loaderPosition="trailing"
value="trailing"
/>
</Box>

<h3>Both visuals</h3>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
size="small"
leadingVisual={CalendarIcon}
trailingVisual={CalendarIcon}
loading={loading}
value="auto"
/>
</Box>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
leadingVisual={CalendarIcon}
trailingVisual={CalendarIcon}
loading={loading}
loaderPosition="leading"
value="leading"
/>
</Box>
<Box mb={2}>
<TextInputWithTokens
tokens={dates}
onTokenRemove={onDateRemove}
size="large"
leadingVisual={CalendarIcon}
trailingVisual={CalendarIcon}
loading={loading}
loaderPosition="trailing"
value="trailing"
/>
</Box>
</>
)
}

render(<WithIconAndLoadingIndicator />)
```

## Props

<PropsTable>
Expand Down
Loading

0 comments on commit 40ed423

Please sign in to comment.