@availity/mui-textfield 0.5.21 → 0.6.0
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/CHANGELOG.md +10 -0
- package/package.json +2 -2
- package/src/lib/TextField.stories.tsx +205 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [0.6.0](https://github.com/Availity/element/compare/@availity/mui-textfield@0.5.21...@availity/mui-textfield@0.6.0) (2024-07-19)
|
|
6
|
+
|
|
7
|
+
### Dependency Updates
|
|
8
|
+
|
|
9
|
+
* `mui-form-utils` updated to version `0.5.21`
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **mui-form-utils:** input masking ([243ca34](https://github.com/Availity/element/commit/243ca3447d9da7ac49de20b26f5cd9a595879f9b))
|
|
14
|
+
|
|
5
15
|
## [0.5.21](https://github.com/Availity/element/compare/@availity/mui-textfield@0.5.20...@availity/mui-textfield@0.5.21) (2024-06-27)
|
|
6
16
|
|
|
7
17
|
### Dependency Updates
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@availity/mui-textfield",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Availity MUI Textfield Component - part of the @availity/element design system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"publish:canary": "yarn npm publish --access public --tag canary"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@availity/mui-form-utils": "0.
|
|
35
|
+
"@availity/mui-form-utils": "0.12.0",
|
|
36
36
|
"@availity/mui-icon": "0.8.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// Each exported component in the package should have its own stories file
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { forwardRef, useState } from 'react';
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import MenuItem from '@mui/material/MenuItem';
|
|
8
|
-
import { SelectChangeEvent } from '@mui/material/Select';
|
|
9
|
-
import Stack from '@mui/material/Stack';
|
|
10
|
-
import { EyeIcon, EyeSlashIcon, SearchIcon } from '@availity/mui-icon';
|
|
4
|
+
import { AsYouType } from 'libphonenumber-js';
|
|
5
|
+
import { IMaskInput } from 'react-imask';
|
|
6
|
+
import { NumericFormat, NumericFormatProps } from 'react-number-format';
|
|
11
7
|
import { IconButton } from '@availity/mui-button';
|
|
8
|
+
import { Chip } from '@availity/mui-chip';
|
|
9
|
+
import { FormControl, FormLabel, Input, InputAdornment, SelectChangeEvent } from '@availity/mui-form-utils';
|
|
10
|
+
import { EyeIcon, EyeSlashIcon, SearchIcon } from '@availity/mui-icon';
|
|
11
|
+
import { Box, Grid, Stack } from '@availity/mui-layout';
|
|
12
|
+
import { MenuItem } from '@availity/mui-menu';
|
|
12
13
|
|
|
13
14
|
import { TextField, TextFieldProps } from './TextField';
|
|
14
15
|
|
|
@@ -40,7 +41,7 @@ export const _TextField: StoryObj<typeof TextField> = {
|
|
|
40
41
|
|
|
41
42
|
export const _States: StoryObj<typeof TextField> = {
|
|
42
43
|
render: (args: TextFieldProps) => (
|
|
43
|
-
<Stack direction="row" spacing={1}>
|
|
44
|
+
<Stack direction="row" spacing={1} flexWrap="wrap">
|
|
44
45
|
<TextField label="Default" id="default" {...args} />
|
|
45
46
|
<TextField label="Focused" id="Focused" focused {...args} />
|
|
46
47
|
<TextField label="Error" id="error" error {...args} />
|
|
@@ -105,6 +106,201 @@ export const _PasswordField: StoryObj<typeof TextField> = {
|
|
|
105
106
|
},
|
|
106
107
|
};
|
|
107
108
|
|
|
109
|
+
/** Formatted value using `libphonenumber-js`. _Formatting occurs `onBlur` for accessibility._ */
|
|
110
|
+
export const _PhoneWithExt: StoryObj<typeof TextField> = {
|
|
111
|
+
render: () => {
|
|
112
|
+
const [phone, setPhone] = useState('')
|
|
113
|
+
|
|
114
|
+
const asYouFormat = (phoneString: string) => {
|
|
115
|
+
// partial parsePhoneNumber always return country code :(
|
|
116
|
+
const asYouType = new AsYouType('US');
|
|
117
|
+
|
|
118
|
+
return asYouType.input(phoneString);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const formatPhoneOnBlur = () => {
|
|
122
|
+
setPhone(asYouFormat(phone));
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
126
|
+
setPhone(event.target.value);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<Grid container rowSpacing={3} columnSpacing={2} maxWidth='360px'>
|
|
131
|
+
<Grid xs>
|
|
132
|
+
<TextField
|
|
133
|
+
type='tel'
|
|
134
|
+
label="Phone"
|
|
135
|
+
id="phone"
|
|
136
|
+
value={phone}
|
|
137
|
+
onBlur={formatPhoneOnBlur}
|
|
138
|
+
onChange={handleChange}
|
|
139
|
+
fullWidth={true}
|
|
140
|
+
/>
|
|
141
|
+
</Grid>
|
|
142
|
+
<Grid xs={2} minWidth='5rem'>
|
|
143
|
+
<TextField
|
|
144
|
+
type='tel'
|
|
145
|
+
label="Ext"
|
|
146
|
+
id="phoneextension"
|
|
147
|
+
fullWidth={true}
|
|
148
|
+
/>
|
|
149
|
+
</Grid>
|
|
150
|
+
</Grid>
|
|
151
|
+
);
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
interface CustomProps {
|
|
156
|
+
onChange: (event: { target: { name: string; value: string } }) => void;
|
|
157
|
+
name: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const TextMaskCustom = forwardRef<HTMLInputElement, CustomProps>(
|
|
161
|
+
function TextMaskCustom(props, ref) {
|
|
162
|
+
const { onChange, ...other } = props;
|
|
163
|
+
return (
|
|
164
|
+
<IMaskInput
|
|
165
|
+
{...other}
|
|
166
|
+
mask="(#00) 000-0000"
|
|
167
|
+
definitions={{
|
|
168
|
+
'#': /[1-9]/,
|
|
169
|
+
}}
|
|
170
|
+
inputRef={ref}
|
|
171
|
+
onAccept={(value: any) => onChange({ target: { name: props.name, value } })}
|
|
172
|
+
overwrite
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const NumericFormatCustom = forwardRef<NumericFormatProps, CustomProps>(
|
|
179
|
+
function NumericFormatCustom(props, ref) {
|
|
180
|
+
const { onChange, ...other } = props;
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<NumericFormat
|
|
184
|
+
{...other}
|
|
185
|
+
getInputRef={ref}
|
|
186
|
+
onValueChange={(values) => {
|
|
187
|
+
onChange({
|
|
188
|
+
target: {
|
|
189
|
+
name: props.name,
|
|
190
|
+
value: values.value,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
}}
|
|
194
|
+
thousandSeparator
|
|
195
|
+
valueIsNumericString
|
|
196
|
+
prefix="$"
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
199
|
+
},
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
/** _There are accessibility concerns with masking to consider as it is making live changes to values that may not be communicated via assistive technologies._
|
|
203
|
+
*
|
|
204
|
+
* > You can use third-party libraries to format an input. You have to provide a custom implementation of the `<input>` element with the `inputComponent` property.
|
|
205
|
+
* >
|
|
206
|
+
* > The following demo uses the `react-imask` and `react-number-format` libraries. The same concept could be applied to, for example `react-stripe-element`.
|
|
207
|
+
* >
|
|
208
|
+
* > -- <cite>[Integration with 3rd party input libraries](https://mui.com/material-ui/react-text-field/#integration-with-3rd-party-input-libraries)</cite>
|
|
209
|
+
*/
|
|
210
|
+
export const _InputMasking: StoryObj<typeof TextField> = {
|
|
211
|
+
render: () => {
|
|
212
|
+
// COMMENTED CODE IS OUTSIDE OF FUNCTION
|
|
213
|
+
|
|
214
|
+
// interface CustomProps {
|
|
215
|
+
// onChange: (event: { target: { name: string; value: string } }) => void;
|
|
216
|
+
// name: string;
|
|
217
|
+
// }
|
|
218
|
+
|
|
219
|
+
// const TextMaskCustom = forwardRef<HTMLInputElement, CustomProps>(
|
|
220
|
+
// function TextMaskCustom(props, ref) {
|
|
221
|
+
// const { onChange, ...other } = props;
|
|
222
|
+
// return (
|
|
223
|
+
// <IMaskInput
|
|
224
|
+
// {...other}
|
|
225
|
+
// mask="(#00) 000-0000"
|
|
226
|
+
// definitions={{
|
|
227
|
+
// '#': /[1-9]/,
|
|
228
|
+
// }}
|
|
229
|
+
// inputRef={ref}
|
|
230
|
+
// onAccept={(value: any) => onChange({ target: { name: props.name, value } })}
|
|
231
|
+
// overwrite
|
|
232
|
+
// />
|
|
233
|
+
// );
|
|
234
|
+
// },
|
|
235
|
+
// );
|
|
236
|
+
|
|
237
|
+
// const NumericFormatCustom = forwardRef<NumericFormatProps, CustomProps>(
|
|
238
|
+
// function NumericFormatCustom(props, ref) {
|
|
239
|
+
// const { onChange, ...other } = props;
|
|
240
|
+
|
|
241
|
+
// return (
|
|
242
|
+
// <NumericFormat
|
|
243
|
+
// {...other}
|
|
244
|
+
// getInputRef={ref}
|
|
245
|
+
// onValueChange={(values) => {
|
|
246
|
+
// onChange({
|
|
247
|
+
// target: {
|
|
248
|
+
// name: props.name,
|
|
249
|
+
// value: values.value,
|
|
250
|
+
// },
|
|
251
|
+
// });
|
|
252
|
+
// }}
|
|
253
|
+
// thousandSeparator
|
|
254
|
+
// valueIsNumericString
|
|
255
|
+
// prefix="$"
|
|
256
|
+
// />
|
|
257
|
+
// );
|
|
258
|
+
// },
|
|
259
|
+
// );
|
|
260
|
+
|
|
261
|
+
// ---------------------------------------
|
|
262
|
+
|
|
263
|
+
const [values, setValues] = useState({
|
|
264
|
+
textmask: '(100) 000-0000',
|
|
265
|
+
numberformat: '1320',
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
269
|
+
setValues({
|
|
270
|
+
...values,
|
|
271
|
+
[event.target.name]: event.target.value,
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
return (
|
|
276
|
+
<>
|
|
277
|
+
<FormControl variant="standard" margin="normal">
|
|
278
|
+
<FormLabel htmlFor="formatted-text-mask-input">react-imask</FormLabel>
|
|
279
|
+
<Input
|
|
280
|
+
value={values.textmask}
|
|
281
|
+
onChange={handleChange}
|
|
282
|
+
name="textmask"
|
|
283
|
+
id="formatted-text-mask-input"
|
|
284
|
+
inputComponent={TextMaskCustom as any}
|
|
285
|
+
/>
|
|
286
|
+
</FormControl>
|
|
287
|
+
<TextField
|
|
288
|
+
label="react-number-format"
|
|
289
|
+
value={values.numberformat}
|
|
290
|
+
onChange={handleChange}
|
|
291
|
+
name="numberformat"
|
|
292
|
+
id="formatted-numberformat-input"
|
|
293
|
+
InputProps={{
|
|
294
|
+
inputComponent: NumericFormatCustom as any,
|
|
295
|
+
}}
|
|
296
|
+
fullWidth={false}
|
|
297
|
+
margin="normal"
|
|
298
|
+
/>
|
|
299
|
+
</>
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
108
304
|
export const _Select: StoryObj<typeof TextField> = {
|
|
109
305
|
render: (args: TextFieldProps) => {
|
|
110
306
|
const [count, setCount] = useState('');
|