@workday/canvas-kit-docs 6.0.0-beta.0-next.15 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/commonjs/lib/specs.js +263 -33
- package/dist/es6/lib/specs.js +263 -33
- package/dist/mdx/4.0-MIGRATION-GUIDE.mdx +1 -1
- package/dist/mdx/6.0-MIGRATION-GUIDE.mdx +554 -0
- package/dist/mdx/COMPOUND_COMPONENTS.mdx +31 -30
- package/dist/mdx/CONTRIBUTING.mdx +90 -63
- package/dist/mdx/labs-react/search-form/SearchForm.mdx +64 -0
- package/dist/mdx/labs-react/search-form/examples/Basic.tsx +61 -0
- package/dist/mdx/labs-react/search-form/examples/CustomTheme.tsx +72 -0
- package/dist/mdx/labs-react/search-form/examples/Grow.tsx +62 -0
- package/dist/mdx/labs-react/search-form/examples/PropTables.splitProps.tsx +4 -0
- package/dist/mdx/labs-react/search-form/examples/RTL.tsx +70 -0
- package/dist/mdx/labs-react/search-form/examples/Theming.tsx +64 -0
- package/dist/mdx/labs-react/text-input/TextInput.mdx +123 -0
- package/dist/mdx/labs-react/text-input/examples/Alert.tsx +46 -0
- package/dist/mdx/labs-react/text-input/examples/Basic.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/Disabled.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/Error.tsx +43 -0
- package/dist/mdx/labs-react/text-input/examples/Grow.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/HiddenLabel.tsx +17 -0
- package/dist/mdx/labs-react/text-input/examples/LabelPosition.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/LoginForm.tsx +100 -0
- package/dist/mdx/labs-react/text-input/examples/Password.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/Placeholder.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/RefForwarding.tsx +27 -0
- package/dist/mdx/labs-react/text-input/examples/Required.tsx +20 -0
- package/dist/mdx/labs-react/text-input/examples/ThemedAlert.tsx +51 -0
- package/dist/mdx/labs-react/text-input/examples/ThemedError.tsx +40 -0
- package/dist/mdx/preview-react/breadcrumbs/Breadcrumbs.mdx +1 -1
- package/dist/mdx/preview-react/menu/Menu.mdx +17 -9
- package/dist/mdx/preview-react/menu/examples/Basic.tsx +65 -10
- package/dist/mdx/preview-react/menu/examples/ContextMenu.tsx +45 -29
- package/dist/mdx/preview-react/menu/examples/CustomMenuItem.tsx +2 -2
- package/dist/mdx/preview-react/menu/examples/Icons.tsx +1 -1
- package/dist/mdx/preview-react/menu/examples/ManyItems.tsx +2 -2
- package/dist/mdx/preview-react/side-panel/SidePanel.mdx +1 -1
- package/dist/mdx/react/action-bar/ActionBar.mdx +1 -1
- package/dist/mdx/react/button/button/Button.mdx +34 -9
- package/dist/mdx/react/button/button/examples/Primary.tsx +10 -1
- package/dist/mdx/react/button/button/examples/PrimaryInverse.tsx +14 -0
- package/dist/mdx/react/button/button/examples/Secondary.tsx +10 -1
- package/dist/mdx/react/button/button/examples/SecondaryInverse.tsx +14 -0
- package/dist/mdx/react/button/button/examples/Tertiary.tsx +10 -1
- package/dist/mdx/react/button/button/examples/TertiaryInverse.tsx +14 -0
- package/dist/mdx/react/button/icon-button/IconButton.mdx +1 -1
- package/dist/mdx/react/card/card.mdx +1 -1
- package/dist/mdx/react/pagination/PropTables.splitprops.tsx +47 -0
- package/dist/mdx/react/pagination/examples/{StepControls.tsx → Basic.tsx} +1 -1
- package/dist/mdx/react/pagination/examples/GoToForm.tsx +1 -1
- package/dist/mdx/react/pagination/examples/HoistedModel.tsx +36 -22
- package/dist/mdx/react/pagination/examples/RTL.tsx +1 -1
- package/dist/mdx/react/pagination/pagination.mdx +225 -474
- package/dist/mdx/react/popup/Popup.mdx +34 -36
- package/dist/mdx/react/radio/examples/Alert.tsx +3 -3
- package/dist/mdx/react/radio/examples/Basic.tsx +3 -3
- package/dist/mdx/react/radio/examples/Disabled.tsx +3 -3
- package/dist/mdx/react/radio/examples/Error.tsx +3 -3
- package/dist/mdx/react/radio/examples/LabelPosition.tsx +3 -3
- package/dist/mdx/react/radio/examples/NoValue.tsx +3 -3
- package/dist/mdx/react/radio/examples/RefForwarding.tsx +3 -3
- package/dist/mdx/react/radio/examples/Required.tsx +3 -3
- package/dist/mdx/react/segmented-control/SegmentedControl.mdx +1 -1
- package/dist/mdx/react/tabs/Tabs.mdx +160 -88
- package/dist/mdx/react/tabs/TabsModel.splitprops.tsx +5 -0
- package/dist/mdx/react/tabs/examples/{Simple.tsx → Basic.tsx} +0 -0
- package/dist/mdx/react/tabs/examples/DisabledTab.tsx +1 -1
- package/dist/mdx/react/tabs/examples/DynamicTabs.tsx +41 -13
- package/dist/mdx/react/tabs/examples/HoistedModel.tsx +4 -4
- package/dist/mdx/react/tabs/examples/Icons.tsx +36 -0
- package/dist/mdx/react/tabs/examples/{NamedKeys.tsx → NamedTabs.tsx} +0 -0
- package/dist/mdx/react/tabs/examples/OverflowTabs.tsx +58 -0
- package/dist/mdx/react/tabs/examples/SinglePanel.tsx +1 -1
- package/dist/mdx/react/text-area/TextArea.mdx +1 -1
- package/dist/mdx/react/toast/toast.mdx +1 -17
- package/dist/mdx/react/tooltip/Tooltip.mdx +1 -1
- package/dist/mdx/react/tooltip/examples/Ellipsis.tsx +6 -0
- package/package.json +3 -3
- package/dist/mdx/CODE_OF_CONDUCT.md +0 -68
- package/dist/mdx/preview-react/menu/examples/ContextMenuTarget.tsx +0 -33
- package/dist/mdx/preview-react/menu/examples/ControlButton.tsx +0 -84
- package/dist/mdx/react/pagination/examples/ShowAdditionalDetails.tsx +0 -52
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {MenuItem} from '@workday/canvas-kit-preview-react/menu';
|
|
3
|
+
import {SearchForm} from '@workday/canvas-kit-labs-react/search-form';
|
|
4
|
+
import {Flex} from '@workday/canvas-kit-labs-react/layout';
|
|
5
|
+
import {CanvasProvider, ContentDirection} from '@workday/canvas-kit-react/common';
|
|
6
|
+
|
|
7
|
+
const initialWineList = [
|
|
8
|
+
'Beaujolais',
|
|
9
|
+
'Bordeaux',
|
|
10
|
+
'Cabernet Sauvignon',
|
|
11
|
+
'Champagne',
|
|
12
|
+
'Chardonnay',
|
|
13
|
+
'Chianti',
|
|
14
|
+
'Malbec',
|
|
15
|
+
'Merlot',
|
|
16
|
+
'Pinot Grigio',
|
|
17
|
+
'Pinot Gris',
|
|
18
|
+
'Pinot Noir',
|
|
19
|
+
'Primitivo',
|
|
20
|
+
'Prosecco',
|
|
21
|
+
'Riesling',
|
|
22
|
+
'Rioja',
|
|
23
|
+
'Rosé',
|
|
24
|
+
'Sauvignon Blanc',
|
|
25
|
+
'Syrah',
|
|
26
|
+
'Zinfandel',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export default () => {
|
|
30
|
+
const [wineList, setWineList] = React.useState(initialWineList);
|
|
31
|
+
// Tracking the input value for onSubmit
|
|
32
|
+
const [searchInput, setSearchInput] = React.useState('');
|
|
33
|
+
const menuItems = wineList.map(wine => <MenuItem key={wine}>{wine}</MenuItem>);
|
|
34
|
+
|
|
35
|
+
const filterMenuItems = e => {
|
|
36
|
+
setSearchInput(e.target.value);
|
|
37
|
+
const formattedValue = e.target.value.toLowerCase();
|
|
38
|
+
|
|
39
|
+
// Reset the list if the input is cleared
|
|
40
|
+
if (!formattedValue.length) {
|
|
41
|
+
setWineList(initialWineList);
|
|
42
|
+
} else {
|
|
43
|
+
const filteredItems = wineList.filter(wine => wine.toLowerCase().startsWith(formattedValue));
|
|
44
|
+
setWineList(filteredItems);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const handleSubmit = () => {
|
|
49
|
+
// We don't need to prevent the default event because SearchForm handles that internally
|
|
50
|
+
console.log(`Searching for: ${searchInput}`);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const theme = {
|
|
54
|
+
canvas: {
|
|
55
|
+
direction: ContentDirection.RTL,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<CanvasProvider theme={theme}>
|
|
61
|
+
<Flex minHeight={200} alignItems="flex-start" padding="xs">
|
|
62
|
+
<SearchForm
|
|
63
|
+
autocompleteItems={menuItems}
|
|
64
|
+
onInputChange={filterMenuItems}
|
|
65
|
+
onSubmit={handleSubmit}
|
|
66
|
+
/>
|
|
67
|
+
</Flex>
|
|
68
|
+
</CanvasProvider>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {MenuItem} from '@workday/canvas-kit-preview-react/menu';
|
|
3
|
+
import {SearchForm, SearchTheme} from '@workday/canvas-kit-labs-react/search-form';
|
|
4
|
+
import {Flex} from '@workday/canvas-kit-labs-react/layout';
|
|
5
|
+
|
|
6
|
+
const initialWineList = [
|
|
7
|
+
'Beaujolais',
|
|
8
|
+
'Bordeaux',
|
|
9
|
+
'Cabernet Sauvignon',
|
|
10
|
+
'Champagne',
|
|
11
|
+
'Chardonnay',
|
|
12
|
+
'Chianti',
|
|
13
|
+
'Malbec',
|
|
14
|
+
'Merlot',
|
|
15
|
+
'Pinot Grigio',
|
|
16
|
+
'Pinot Gris',
|
|
17
|
+
'Pinot Noir',
|
|
18
|
+
'Primitivo',
|
|
19
|
+
'Prosecco',
|
|
20
|
+
'Riesling',
|
|
21
|
+
'Rioja',
|
|
22
|
+
'Rosé',
|
|
23
|
+
'Sauvignon Blanc',
|
|
24
|
+
'Syrah',
|
|
25
|
+
'Zinfandel',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export default () => {
|
|
29
|
+
const [wineList, setWineList] = React.useState(initialWineList);
|
|
30
|
+
// Tracking the input value for onSubmit
|
|
31
|
+
const [searchInput, setSearchInput] = React.useState('');
|
|
32
|
+
const menuItems = wineList.map(wine => <MenuItem key={wine}>{wine}</MenuItem>);
|
|
33
|
+
|
|
34
|
+
const filterMenuItems = e => {
|
|
35
|
+
setSearchInput(e.target.value);
|
|
36
|
+
const formattedValue = e.target.value.toLowerCase();
|
|
37
|
+
|
|
38
|
+
// Reset the list if the input is cleared
|
|
39
|
+
if (!formattedValue.length) {
|
|
40
|
+
setWineList(initialWineList);
|
|
41
|
+
} else {
|
|
42
|
+
const filteredItems = wineList.filter(wine => wine.toLowerCase().startsWith(formattedValue));
|
|
43
|
+
setWineList(filteredItems);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleSubmit = () => {
|
|
48
|
+
// We don't need to prevent the default event because SearchForm handles that internally
|
|
49
|
+
console.log(`Searching for: ${searchInput}`);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<Flex minHeight={200} alignItems="flex-start">
|
|
54
|
+
<Flex padding="xs" backgroundColor="blueberry500" flex={1} flexBasis="auto">
|
|
55
|
+
<SearchForm
|
|
56
|
+
searchTheme={SearchTheme.Dark}
|
|
57
|
+
autocompleteItems={menuItems}
|
|
58
|
+
onInputChange={filterMenuItems}
|
|
59
|
+
onSubmit={handleSubmit}
|
|
60
|
+
/>
|
|
61
|
+
</Flex>
|
|
62
|
+
</Flex>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {Specifications} from '@workday/canvas-kit-docs';
|
|
2
|
+
|
|
3
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
4
|
+
|
|
5
|
+
import Basic from './examples/Basic';
|
|
6
|
+
import Disabled from './examples/Disabled';
|
|
7
|
+
import Grow from './examples/Grow';
|
|
8
|
+
import LabelPosition from './examples/LabelPosition';
|
|
9
|
+
import Placeholder from './examples/Placeholder';
|
|
10
|
+
import RefForwarding from './examples/RefForwarding';
|
|
11
|
+
import Required from './examples/Required';
|
|
12
|
+
import Password from './examples/Password';
|
|
13
|
+
import HiddenLabel from './examples/HiddenLabel';
|
|
14
|
+
import ThemedAlert from './examples/ThemedAlert';
|
|
15
|
+
import ThemedError from './examples/ThemedError';
|
|
16
|
+
import Error from './examples/Error';
|
|
17
|
+
import Alert from './examples/Alert';
|
|
18
|
+
import LoginForm from './examples/LoginForm';
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Canvas Kit Text Input
|
|
22
|
+
|
|
23
|
+
Text Inputs allow users to enter words or characters without styling.
|
|
24
|
+
|
|
25
|
+
[> Workday Design Reference](https://design.workday.com/components/inputs/text-input)
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
yarn add @workday/canvas-kit-react
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### Basic Example
|
|
36
|
+
|
|
37
|
+
<ExampleCodeBlock code={Basic} />
|
|
38
|
+
|
|
39
|
+
### Disabled
|
|
40
|
+
|
|
41
|
+
Set the `disabled` prop of the TextInput.Field to prevent users from interacting with it.
|
|
42
|
+
|
|
43
|
+
<ExampleCodeBlock code={Disabled} />
|
|
44
|
+
|
|
45
|
+
### Placeholder
|
|
46
|
+
|
|
47
|
+
Set the `placeholder` prop of the TextInput.Field to display a sample of its expected format or
|
|
48
|
+
value before a value has been provided.
|
|
49
|
+
|
|
50
|
+
<ExampleCodeBlock code={Placeholder} />
|
|
51
|
+
|
|
52
|
+
### Required
|
|
53
|
+
|
|
54
|
+
Set the `isRequired` property property from useTextInputModel to indicate that the field is
|
|
55
|
+
required. This will also add an red asterisk next to your TextInput.Label.
|
|
56
|
+
|
|
57
|
+
<ExampleCodeBlock code={Required} />
|
|
58
|
+
|
|
59
|
+
### Ref Forwarding
|
|
60
|
+
|
|
61
|
+
All the TextInput subcomponents support
|
|
62
|
+
[ref forwarding](https://reactjs.org/docs/forwarding-refs.html). e.g. TextInput.Field will forward
|
|
63
|
+
`ref` to its underlying `<input type="text">` element.
|
|
64
|
+
|
|
65
|
+
<ExampleCodeBlock code={RefForwarding} />
|
|
66
|
+
|
|
67
|
+
### Grow
|
|
68
|
+
|
|
69
|
+
There are lots of ways to accomplish this. The TextInput.Field extends from Box so it is easy to
|
|
70
|
+
extend full width, e.g. setting width prop to 100%, or you can wrap the whole TextInput in it a Flex
|
|
71
|
+
and set the growth that way, etc.
|
|
72
|
+
|
|
73
|
+
<ExampleCodeBlock code={Grow} />
|
|
74
|
+
|
|
75
|
+
### Label Position
|
|
76
|
+
|
|
77
|
+
Setting the Label position can be done using HStack or VStack
|
|
78
|
+
|
|
79
|
+
<ExampleCodeBlock code={LabelPosition} />
|
|
80
|
+
|
|
81
|
+
### Visually Hiding The Label
|
|
82
|
+
|
|
83
|
+
If your label is just for screen reader users you can add the isVisuallyHidden to TextInput.Label
|
|
84
|
+
|
|
85
|
+
<ExampleCodeBlock code={HiddenLabel} />
|
|
86
|
+
|
|
87
|
+
### Type
|
|
88
|
+
|
|
89
|
+
Set the `type` prop TextInput.Field to any allowed string, e.g. password to change the input field
|
|
90
|
+
type.
|
|
91
|
+
|
|
92
|
+
<ExampleCodeBlock code={Password} />
|
|
93
|
+
|
|
94
|
+
### Error States
|
|
95
|
+
|
|
96
|
+
Use the `hasError` property from useTextInputModel to set the TextInput to the Error state. If you
|
|
97
|
+
have an accompanying hint you can use the TextInput.Hint subcomponent.
|
|
98
|
+
|
|
99
|
+
#### Errors
|
|
100
|
+
|
|
101
|
+
<ExampleCodeBlock code={Error} />
|
|
102
|
+
|
|
103
|
+
#### Themed Errors
|
|
104
|
+
|
|
105
|
+
<ExampleCodeBlock code={ThemedError} />
|
|
106
|
+
|
|
107
|
+
### Other Visual States
|
|
108
|
+
|
|
109
|
+
Use the `useThemedRing` hook to change the visual state of the input field.
|
|
110
|
+
|
|
111
|
+
#### Alerts
|
|
112
|
+
|
|
113
|
+
<ExampleCodeBlock code={Alert} />
|
|
114
|
+
|
|
115
|
+
#### Themed Alerts
|
|
116
|
+
|
|
117
|
+
<ExampleCodeBlock code={ThemedAlert} />
|
|
118
|
+
|
|
119
|
+
#### Full example
|
|
120
|
+
|
|
121
|
+
Login Form using Formik
|
|
122
|
+
|
|
123
|
+
<ExampleCodeBlock code={LoginForm} />
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
import {styled} from '@workday/canvas-kit-react/common';
|
|
5
|
+
import {useThemedRing} from '@workday/canvas-kit-labs-react/common';
|
|
6
|
+
import {CSSProperties, space} from '@workday/canvas-kit-react/tokens';
|
|
7
|
+
|
|
8
|
+
const StyledField = styled(TextInput.Field)<{alertStyles?: CSSProperties}>(
|
|
9
|
+
({alertStyles}) => alertStyles
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export default () => {
|
|
13
|
+
const [value, setValue] = React.useState('foo');
|
|
14
|
+
|
|
15
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
16
|
+
setValue(event.target.value);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const alertStyles = useThemedRing(
|
|
20
|
+
value.length < 3 ? 'error' : value.length < 5 ? 'alert' : 'success'
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
25
|
+
<TextInput>
|
|
26
|
+
<TextInput.Label>Password</TextInput.Label>
|
|
27
|
+
<StyledField
|
|
28
|
+
alertStyles={alertStyles}
|
|
29
|
+
onChange={handleChange}
|
|
30
|
+
value={value}
|
|
31
|
+
type="password"
|
|
32
|
+
/>
|
|
33
|
+
<TextInput.Hint paddingTop={space.xxs}>
|
|
34
|
+
<strong>Password Strength: </strong>
|
|
35
|
+
{value.length < 3 ? (
|
|
36
|
+
<span>Weak</span>
|
|
37
|
+
) : value.length < 5 ? (
|
|
38
|
+
<span>Average</span>
|
|
39
|
+
) : (
|
|
40
|
+
<span>Strong</span>
|
|
41
|
+
)}
|
|
42
|
+
</TextInput.Hint>
|
|
43
|
+
</TextInput>
|
|
44
|
+
</VStack>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
14
|
+
<TextInput>
|
|
15
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</VStack>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
14
|
+
<TextInput>
|
|
15
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} disabled />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</VStack>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
import {space} from '@workday/canvas-kit-react/tokens';
|
|
5
|
+
|
|
6
|
+
export default () => {
|
|
7
|
+
const [value, setValue] = React.useState('four');
|
|
8
|
+
const [hint, setHint] = React.useState('');
|
|
9
|
+
const [hasError, setHasError] = React.useState(false);
|
|
10
|
+
|
|
11
|
+
const validateInput = (value: string) => {
|
|
12
|
+
const stringLength = value.length;
|
|
13
|
+
if (stringLength !== 3) {
|
|
14
|
+
setHasError(true);
|
|
15
|
+
const hintStart = 'Word length must be';
|
|
16
|
+
setHint(stringLength < 3 ? `${hintStart} greater than 2` : `${hintStart} less than 4`);
|
|
17
|
+
} else {
|
|
18
|
+
setHasError(false);
|
|
19
|
+
setHint('');
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
React.useEffect(() => {
|
|
24
|
+
validateInput(value);
|
|
25
|
+
// Only run on load
|
|
26
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
30
|
+
validateInput(event.target.value);
|
|
31
|
+
setValue(event.target.value);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
36
|
+
<TextInput hasError={hasError}>
|
|
37
|
+
<TextInput.Label>A three letter word</TextInput.Label>
|
|
38
|
+
<TextInput.Field onChange={handleChange} value={value} />
|
|
39
|
+
<TextInput.Hint paddingTop={space.xxs}>{hint}</TextInput.Hint>
|
|
40
|
+
</TextInput>
|
|
41
|
+
</VStack>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<VStack spacing="xxxs">
|
|
14
|
+
<TextInput>
|
|
15
|
+
<TextInput.Label>Street Address</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</VStack>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
|
|
4
|
+
export default () => {
|
|
5
|
+
const [value, setValue] = React.useState('');
|
|
6
|
+
|
|
7
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
8
|
+
setValue(event.target.value);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<TextInput>
|
|
13
|
+
<TextInput.Label isVisuallyHidden={true}>Email</TextInput.Label>
|
|
14
|
+
<TextInput.Field onChange={handleChange} value={value} />
|
|
15
|
+
</TextInput>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {HStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<HStack spacing="l" alignItems="center">
|
|
14
|
+
<TextInput>
|
|
15
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</HStack>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {useFormik} from 'formik';
|
|
4
|
+
import * as yup from 'yup';
|
|
5
|
+
|
|
6
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
7
|
+
import {HStack, VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
8
|
+
import {IconButton, PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
9
|
+
import {visibleIcon, invisibleIcon} from '@workday/canvas-system-icons-web';
|
|
10
|
+
import {useUniqueId} from '@workday/canvas-kit-react/common';
|
|
11
|
+
|
|
12
|
+
export default () => {
|
|
13
|
+
const passwordMinimum = 8;
|
|
14
|
+
const passwordHint = `Password should be of minimum ${passwordMinimum} characters length`;
|
|
15
|
+
const emailRequired = 'Email is required';
|
|
16
|
+
const passwordRequired = 'Password is required';
|
|
17
|
+
|
|
18
|
+
const validationSchema = yup.object({
|
|
19
|
+
email: yup
|
|
20
|
+
.string()
|
|
21
|
+
.email('Enter a valid email')
|
|
22
|
+
.required(emailRequired),
|
|
23
|
+
password: yup
|
|
24
|
+
.string()
|
|
25
|
+
.min(passwordMinimum, passwordHint)
|
|
26
|
+
.required(passwordRequired),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const passwordRef = React.useRef<HTMLInputElement>(null);
|
|
30
|
+
const [showPassword, setShowPassword] = React.useState(false);
|
|
31
|
+
const passwordId = useUniqueId();
|
|
32
|
+
|
|
33
|
+
const formik = useFormik({
|
|
34
|
+
initialValues: {
|
|
35
|
+
email: 'example@baz.com',
|
|
36
|
+
password: 'foobarbaz',
|
|
37
|
+
},
|
|
38
|
+
validationSchema: validationSchema,
|
|
39
|
+
onSubmit: values => {
|
|
40
|
+
passwordRef.current.type = 'password';
|
|
41
|
+
|
|
42
|
+
// Send data to server
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
alert(JSON.stringify(values, null, 2));
|
|
45
|
+
}, 0);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<form onSubmit={formik.handleSubmit} action=".">
|
|
51
|
+
<VStack spacing="xs" alignItems="flex-start">
|
|
52
|
+
<TextInput isRequired={true} hasError={formik.touched.email && !!formik.errors.email}>
|
|
53
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
54
|
+
<TextInput.Field
|
|
55
|
+
name="email"
|
|
56
|
+
autoComplete="username"
|
|
57
|
+
placeholder="yourName@example.com"
|
|
58
|
+
onChange={formik.handleChange}
|
|
59
|
+
onBlur={formik.handleBlur}
|
|
60
|
+
value={formik.values.email}
|
|
61
|
+
/>
|
|
62
|
+
<TextInput.Hint>{formik.touched.email && formik.errors.email}</TextInput.Hint>
|
|
63
|
+
</TextInput>
|
|
64
|
+
<TextInput
|
|
65
|
+
inputId={passwordId}
|
|
66
|
+
hasError={formik.touched.password && !!formik.errors.password}
|
|
67
|
+
isRequired={true}
|
|
68
|
+
>
|
|
69
|
+
<TextInput.Label>Password</TextInput.Label>
|
|
70
|
+
<HStack spacing="xxs">
|
|
71
|
+
<TextInput.Field
|
|
72
|
+
type={showPassword ? 'text' : 'password'}
|
|
73
|
+
name="password"
|
|
74
|
+
autoComplete="current-password"
|
|
75
|
+
ref={passwordRef}
|
|
76
|
+
onChange={formik.handleChange}
|
|
77
|
+
onBlur={formik.handleBlur}
|
|
78
|
+
value={formik.values.password}
|
|
79
|
+
/>
|
|
80
|
+
<IconButton
|
|
81
|
+
type="button"
|
|
82
|
+
icon={showPassword ? invisibleIcon : visibleIcon}
|
|
83
|
+
aria-label={showPassword ? 'Hide Password' : 'Show Password'}
|
|
84
|
+
aria-controls={passwordId}
|
|
85
|
+
onClick={() => {
|
|
86
|
+
setShowPassword(state => !state);
|
|
87
|
+
passwordRef.current.focus();
|
|
88
|
+
}}
|
|
89
|
+
/>
|
|
90
|
+
</HStack>
|
|
91
|
+
<TextInput.Hint>
|
|
92
|
+
{(formik.touched.password && formik.errors.password) || passwordHint}
|
|
93
|
+
</TextInput.Hint>
|
|
94
|
+
</TextInput>
|
|
95
|
+
|
|
96
|
+
<PrimaryButton type="submit">Submit</PrimaryButton>
|
|
97
|
+
</VStack>
|
|
98
|
+
</form>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('SuperSecret1');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
14
|
+
<TextInput>
|
|
15
|
+
<TextInput.Label>Password</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} type="password" />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</VStack>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
14
|
+
<TextInput>
|
|
15
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} placeholder="user@email.com" />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</VStack>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
import {PrimaryButton} from '@workday/canvas-kit-react/button';
|
|
5
|
+
|
|
6
|
+
export default () => {
|
|
7
|
+
const [value, setValue] = React.useState('');
|
|
8
|
+
const ref = React.useRef(null);
|
|
9
|
+
|
|
10
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
11
|
+
setValue(event.target.value);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const handleClick = () => {
|
|
15
|
+
ref.current.focus();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
20
|
+
<TextInput>
|
|
21
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
22
|
+
<TextInput.Field onChange={handleChange} value={value} ref={ref} />
|
|
23
|
+
</TextInput>
|
|
24
|
+
<PrimaryButton onClick={handleClick}>Focus Text Input</PrimaryButton>
|
|
25
|
+
</VStack>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {TextInput} from '@workday/canvas-kit-labs-react/text-input';
|
|
3
|
+
import {VStack} from '@workday/canvas-kit-labs-react/layout';
|
|
4
|
+
|
|
5
|
+
export default () => {
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
setValue(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<VStack spacing="xxxs" alignItems="flex-start">
|
|
14
|
+
<TextInput isRequired={true}>
|
|
15
|
+
<TextInput.Label>Email</TextInput.Label>
|
|
16
|
+
<TextInput.Field onChange={handleChange} value={value} />
|
|
17
|
+
</TextInput>
|
|
18
|
+
</VStack>
|
|
19
|
+
);
|
|
20
|
+
};
|