Skip to content

Text input loading state #1920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c9f34f1
adds loading indicator to text inputs
mperrotti Mar 2, 2022
26976c7
removes style debugging div
mperrotti Mar 2, 2022
5157087
updates stories and docs
mperrotti Mar 2, 2022
258ed6c
updates tests
mperrotti Mar 2, 2022
245b568
fixes silly test mistakes
mperrotti Mar 2, 2022
6c1f358
revert default textinput story
mperrotti Mar 2, 2022
81a1022
adds changeset
mperrotti Mar 2, 2022
89b0e44
Merge branch 'main' into mp/text-input-loading-state
mperrotti Mar 2, 2022
e964c11
Merge branch 'main' of github.com:primer/react into mp/text-input-loa…
mperrotti Mar 8, 2022
5388500
Update src/TextInput.tsx
mperrotti Mar 8, 2022
0473333
Merge branch 'mp/text-input-loading-state' of github.com:primer/react…
mperrotti Mar 8, 2022
070612f
updates component API
mperrotti Mar 8, 2022
f2f52c7
Merge branch 'main' of github.com:primer/react into mp/text-input-loa…
mperrotti Mar 10, 2022
79fbe76
addresses PR feedback
mperrotti Mar 10, 2022
4a4fcc0
fixes linting error
mperrotti Mar 10, 2022
1bdf6d1
indicate a busy status to assistive technology
mperrotti Mar 10, 2022
5f14db8
Merge branch 'main' of github.com:primer/react into mp/text-input-loa…
mperrotti Mar 11, 2022
3464982
updates snaps
mperrotti Mar 11, 2022
d586a80
renames 'isLoading' prop to 'loading'
mperrotti Mar 15, 2022
ced3de3
Merge branch 'main' of github.com:primer/react into mp/text-input-loa…
mperrotti Mar 15, 2022
8bc639e
Update docs/content/TextInput.mdx
mperrotti Mar 21, 2022
eebc472
Update docs/content/TextInput.mdx
mperrotti Mar 21, 2022
2b18aee
Update docs/content/TextInput.mdx
mperrotti Mar 21, 2022
52d2e1a
Update docs/content/TextInput.mdx
mperrotti Mar 21, 2022
5cfc485
Update docs/content/TextInput.mdx
mperrotti Mar 21, 2022
fc0eeef
Merge branch 'main' of github.com:primer/react into mp/text-input-loa…
mperrotti Mar 21, 2022
8bf281d
updates snapshots
mperrotti Mar 21, 2022
e785ccd
nests examples under an 'Examples' heading
mperrotti Mar 21, 2022
a3dc21d
export TextInput non-pass-through props
mperrotti Mar 21, 2022
fffa764
fix undefined type usage
mperrotti Mar 21, 2022
f9ad318
fixes story types
mperrotti Mar 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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