-
Notifications
You must be signed in to change notification settings - Fork 526
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Component that renders a text input with tokens (#1489)
* adds token components * adds component that renders a text input with tokens * Format token files with Prettier * Update docs/content/Token.mdx Co-authored-by: Cole Bemis <colebemis@github.com> * Update src/Token/TokenBase.tsx Co-authored-by: Cole Bemis <colebemis@github.com> * addresses first batch of changes requested in code review * Update src/stories/TextInputWithTokens.stories.tsx Co-authored-by: Cole Bemis <colebemis@github.com> * fixes issue label remove button in Storybook * refactors TokenBase to do less inside the 'styled' function * renames LabelToken to IssueLabelToken * renames TokenProfile to ProfileToken * allows link tokens to have clickable 'x', fixes keyboard nav for IssueLabelTokens, fixes IssueLabelToken import typo * renames token size keys from abbreviated sizes to full word * Update src/TextInputWithTokens.tsx Co-authored-by: Cole Bemis <colebemis@github.com> * Update src/TextInputWithTokens.tsx Co-authored-by: Cole Bemis <colebemis@github.com> * Update docs/content/TextInputWithTokens.mdx Co-authored-by: Cole Bemis <colebemis@github.com> * pulls in updates to Token components, changes 'tokenSizeVariant' prop to 'size' * define type of 'tokens' prop based on the type of 'tokenComponent' prop * runs lint:fix * runs lint:fix * updates comments in TextInputWithTokens * changes IssueLabelToken's implementation of color transform to match Memex and dotcom * updates package-lock * rms tinycolor2 types * improves Storybook stories * improves Storybook stories, fixes maxHeight and preventTokenWrapping style bugs * adds missing dependency to IssueLabelToken style object * configure Storybook controls for token stories * rms storybook-addon/knobs * improve IssueLabelToken isSelected+focus style, fix lineHeight * adds tests * fixes ESLint errors * Update src/Token/Token.tsx Co-authored-by: Cole Bemis <colebemis@github.com> * adds tests * adds more tests, fixes ESLint errors * removes Knobs tab from Storybook * improve click target area for interactive tokens * updates token size keys, renames Token test file * updates docs * updates snapshots * updates default 'size' prop, updates docs * fixes lint errors in docs mdx file * reverts changes to TextInput * Update docs/content/Token.mdx Co-authored-by: Cole Bemis <colebemis@github.com> * addresses more code review feedback * Update docs/content/TextInputTokens.mdx Co-authored-by: Cole Bemis <colebemis@github.com> * Update src/index.ts Co-authored-by: Cole Bemis <colebemis@github.com> * updates snapshots for AvatarToken name change * adds TextInputWithTokens to React docs sidebar * updates textinputwithtokens snapshots * renders prop tables in Token docs * adds props table to TextInputWithTokens docs * fixes bundlesize issue, improves cursor UX for non-interactive tokens * updates snapshots * Rename TextInputWithTokens markdown file * Create thin-humans-tell.md * Update thin-humans-tell.md * Update src/Token/TokenBase.tsx Co-authored-by: Cole Bemis <colebemis@github.com> * updates token snapshots * adds prop table to TextInputWithTokens docs page * updates snapshots * rm Token changeset * adds TextInputWithTokens changeset Co-authored-by: Cole Bemis <colebemis@github.com>
- Loading branch information
Showing
11 changed files
with
6,225 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@primer/components': minor | ||
--- | ||
|
||
Add alpha `TextInputWithTokens` component |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
--- | ||
title: TextInputWithTokens | ||
status: Alpha | ||
source: https://github.com/primer/react/tree/main/src/TextInputWithTokens.tsx | ||
--- | ||
|
||
import {Props} from '../src/props' | ||
import {TextInputWithTokens} from '@primer/components' | ||
|
||
A `TextInputWithTokens` component is used to show multiple values in one field. | ||
|
||
It supports all of the features of a [TextInput](/TextInput) component, but it can render a list of [Tokens](/Token) next to the area a user types in. | ||
|
||
## Basic Example | ||
|
||
```javascript live noinline | ||
const BasicExample = () => { | ||
const [tokens, setTokens] = React.useState([ | ||
{text: 'zero', id: 0}, | ||
{text: 'one', id: 1}, | ||
{text: 'two', id: 2} | ||
]) | ||
const onTokenRemove = tokenId => { | ||
setTokens(tokens.filter(token => token.id !== tokenId)) | ||
} | ||
|
||
return ( | ||
<> | ||
<Box as="label" display="block" htmlFor="inputWithTokens-basic"> | ||
Basic example tokens | ||
</Box> | ||
<TextInputWithTokens tokens={tokens} onTokenRemove={onTokenRemove} id="inputWithTokens-basic" /> | ||
</> | ||
) | ||
} | ||
|
||
render(BasicExample) | ||
``` | ||
|
||
## Component Props | ||
|
||
| Name | Type | Default | Description | | ||
| :--------------------- | :------------------------------------ | :----------: | :------------------------------------------------------------------------------------------------------------------------ | | ||
| tokens | `TokenProps[]` | `undefined` | Required. The array of tokens to render | | ||
| onTokenRemove | `(tokenId: string \| number) => void` | `undefined` | Required. The function that gets called when a token is removed | | ||
| tokenComponent | `React.ComponentType<any>` | `Token` | Optional. The component used to render each token | | ||
| maxHeight | `React.CSSProperties['maxHeight']` | `undefined` | Optional. The maximum height of the component. If the content in the input exceeds this height, it will scroll vertically | | ||
| preventTokenWrapping | `boolean` | `false` | Optional. Whether tokens should render inline horizontally. By default, tokens wrap to new lines. | | ||
| size | `TokenSizeKeys` | `extralarge` | Optional. The size of the tokens | | ||
| hideTokenRemoveButtons | `boolean` | `false` | Optional. Whether the remove buttons should be rendered in the tokens | | ||
|
||
## Adding and removing tokens | ||
|
||
The array passed to the `tokens` prop needs to be manually updated to add and remove tokens. | ||
|
||
The function passed to the `onRemoveToken` prop is called when: | ||
|
||
- Clicking the remove button in the token | ||
- Pressing the `Backspace` key when the input is empty | ||
- Selecting a token using the arrow keys or by clicking on a token and then pressing the `Backspace` key | ||
|
||
There is no function that gets called to "add" a token, so the user needs to be provided with a UI to select tokens. | ||
|
||
## Custom token rendering | ||
|
||
By default, the `Token` component is used to render the tokens in the input. If this component does not make sense for the kinds of tokens you're rendering, you can pass a component to the `tokenComponent` prop | ||
|
||
Example: a `TextInputWithTokens` that renders tokens as `IssueLabelToken`: | ||
|
||
```javascript live noinline | ||
const UsingIssueLabelTokens = () => { | ||
const [tokens, setTokens] = React.useState([ | ||
{text: 'enhancement', id: 1, fillColor: '#a2eeef'}, | ||
{text: 'bug', id: 2, fillColor: '#d73a4a'}, | ||
{text: 'good first issue', id: 3, fillColor: '#0cf478'} | ||
]) | ||
const onTokenRemove = tokenId => { | ||
setTokens(tokens.filter(token => token.id !== tokenId)) | ||
} | ||
|
||
return ( | ||
<> | ||
<Box as="label" display="block" htmlFor="inputWithTokens-issueLabels"> | ||
Issue labels | ||
</Box> | ||
<TextInputWithTokens | ||
tokenComponent={IssueLabelToken} | ||
tokens={tokens} | ||
onTokenRemove={onTokenRemove} | ||
id="inputWithTokens-issueLabels" | ||
/> | ||
</> | ||
) | ||
} | ||
|
||
render(<UsingIssueLabelTokens />) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.