@availity/mui-textfield 0.5.21 → 0.6.1

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 CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [0.6.1](https://github.com/Availity/element/compare/@availity/mui-textfield@0.6.0...@availity/mui-textfield@0.6.1) (2024-07-22)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `mui-form-utils` updated to version `0.6.0`
10
+ * `mui-icon` updated to version `0.6.0`
11
+ * `mui-button` updated to version `0.6.0`
12
+ * `mui-chip` updated to version `0.6.0`
13
+ * `mui-menu` updated to version `0.6.0`
14
+ ## [0.6.0](https://github.com/Availity/element/compare/@availity/mui-textfield@0.5.21...@availity/mui-textfield@0.6.0) (2024-07-19)
15
+
16
+ ### Dependency Updates
17
+
18
+ * `mui-form-utils` updated to version `0.5.21`
19
+
20
+ ### Features
21
+
22
+ * **mui-form-utils:** input masking ([243ca34](https://github.com/Availity/element/commit/243ca3447d9da7ac49de20b26f5cd9a595879f9b))
23
+
5
24
  ## [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
25
 
7
26
  ### Dependency Updates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@availity/mui-textfield",
3
- "version": "0.5.21",
3
+ "version": "0.6.1",
4
4
  "description": "Availity MUI Textfield Component - part of the @availity/element design system",
5
5
  "keywords": [
6
6
  "react",
@@ -32,8 +32,8 @@
32
32
  "publish:canary": "yarn npm publish --access public --tag canary"
33
33
  },
34
34
  "dependencies": {
35
- "@availity/mui-form-utils": "0.11.3",
36
- "@availity/mui-icon": "0.8.2"
35
+ "@availity/mui-form-utils": "0.12.1",
36
+ "@availity/mui-icon": "0.9.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@mui/material": "^5.15.15",
@@ -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 Box from '@mui/material/Box';
5
- import Chip from '@mui/material/Chip';
6
- import InputAdornment from '@mui/material/InputAdornment';
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('');