uikit-react-public 0.49.2 → 0.49.4

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.
@@ -24,6 +24,7 @@ const ConfidentialDisplayField = forwardRef<Ref, ConfidentialDisplayFieldProps>(
24
24
  value,
25
25
  numeric,
26
26
  maskFormat,
27
+ format,
27
28
  showable = false,
28
29
  testId = NAME,
29
30
  className,
@@ -45,7 +46,9 @@ const ConfidentialDisplayField = forwardRef<Ref, ConfidentialDisplayFieldProps>(
45
46
  const valueIsShown = showable && isShown;
46
47
  const displayedValue = valueIsShown
47
48
  ? stringValue
48
- : formatConfidentialValue(stringValue, maskFormat);
49
+ : formatConfidentialValue(stringValue, maskFormat, {
50
+ includeTemplateLiterals: !format,
51
+ });
49
52
 
50
53
  useEffect(() => {
51
54
  if (!showable) setIsShown(false);
@@ -68,6 +71,7 @@ const ConfidentialDisplayField = forwardRef<Ref, ConfidentialDisplayFieldProps>(
68
71
  {...props}
69
72
  ref={ref}
70
73
  value={displayedValue}
74
+ format={format}
71
75
  numeric={numeric ?? typeof value === 'number'}
72
76
  testId={testId}
73
77
  noMargins
@@ -14,7 +14,7 @@ import {
14
14
 
15
15
  `ConfidentialDisplayField` extends `DisplayField` with the same simple mask
16
16
  format used by `ConfidentialInput`. `#` reveals a value character, `*` masks it
17
- with a `•`, and other characters are displayed as separators.
17
+ with a `●`, and other characters are displayed as separators.
18
18
 
19
19
  <Source
20
20
  code={`<ConfidentialDisplayField
@@ -23,7 +23,7 @@ describe('ConfidentialDisplayField', () => {
23
23
 
24
24
  expect(
25
25
  screen.getByTestId('ucl-uikit-confidential-display-field')
26
- ).toHaveTextContent('••••••78');
26
+ ).toHaveTextContent('●●●●●●78');
27
27
  });
28
28
 
29
29
  test('applies a function mask', () => {
@@ -34,7 +34,7 @@ describe('ConfidentialDisplayField', () => {
34
34
 
35
35
  expect(
36
36
  screen.getByTestId('ucl-uikit-confidential-display-field')
37
- ).toHaveTextContent('•••• ending in 78');
37
+ ).toHaveTextContent('●●●● ending in 78');
38
38
  });
39
39
 
40
40
  test('does not add a visibility control by default', () => {
@@ -69,20 +69,20 @@ describe('ConfidentialDisplayField', () => {
69
69
  await user.click(
70
70
  screen.getByRole('button', { name: 'Hide confidential value' })
71
71
  );
72
- expect(output).toHaveTextContent('••••••78');
72
+ expect(output).toHaveTextContent('●●●●●●78');
73
73
  });
74
74
 
75
75
  test('formats both masked and visible values', async () => {
76
76
  const user = userEvent.setup();
77
77
  renderDisplayField({
78
78
  value: '123472',
79
- maskFormat: '****##',
79
+ maskFormat: '**-**-##',
80
80
  format: '##-##-##',
81
81
  showable: true,
82
82
  });
83
83
 
84
84
  const output = screen.getByTestId('ucl-uikit-confidential-display-field');
85
- expect(output).toHaveTextContent('••-••-72');
85
+ expect(output).toHaveTextContent('●●-●●-72');
86
86
 
87
87
  await user.click(
88
88
  screen.getByRole('button', { name: 'Show confidential value' })
@@ -139,6 +139,6 @@ describe('ConfidentialDisplayField', () => {
139
139
 
140
140
  expect(
141
141
  screen.getByTestId('ucl-uikit-confidential-display-field')
142
- ).toHaveTextContent('••••••78');
142
+ ).toHaveTextContent('●●●●●●78');
143
143
  });
144
144
  });
@@ -125,7 +125,8 @@ const ConfidentialInput = forwardRef<Ref, ConfidentialInputProps>(
125
125
  value === undefined ? uncontrolledValue : getStringValue(value);
126
126
  const displayedMaskedValue = formatConfidentialValue(
127
127
  stringValue,
128
- maskFormat
128
+ maskFormat,
129
+ { includeTemplateLiterals: !format }
129
130
  );
130
131
  const configuredValueIsVisible =
131
132
  !isFocused &&
@@ -20,7 +20,7 @@ change events, and form submission while displaying a masked value.
20
20
  ## Usage
21
21
 
22
22
  The string mask is a simple template. `#` reveals the corresponding value
23
- character, `*` masks it with a `•`, and all other characters are displayed as
23
+ character, `*` masks it with a `●`, and all other characters are displayed as
24
24
  separators. Asterisks returned by a formatter function are also displayed as
25
25
  bullets. Focusing the input temporarily reveals the original value for editing,
26
26
  and blurring restores the configured mask. When `showable` is `true`, the Eye
@@ -27,7 +27,7 @@ describe('ConfidentialInput', () => {
27
27
  );
28
28
  expect(
29
29
  screen.getByTestId('ucl-uikit-confidential-input-mask')
30
- ).toHaveTextContent('1234••••');
30
+ ).toHaveTextContent('1234●●●●');
31
31
  });
32
32
 
33
33
  test('supports separators and masks characters beyond the template', () => {
@@ -39,7 +39,7 @@ describe('ConfidentialInput', () => {
39
39
 
40
40
  expect(
41
41
  screen.getByTestId('ucl-uikit-confidential-input-mask')
42
- ).toHaveTextContent('••-••-72');
42
+ ).toHaveTextContent('●●-●●-72');
43
43
  });
44
44
 
45
45
  test('applies a function mask', () => {
@@ -51,7 +51,7 @@ describe('ConfidentialInput', () => {
51
51
 
52
52
  expect(
53
53
  screen.getByTestId('ucl-uikit-confidential-input-mask')
54
- ).toHaveTextContent('•••• ending in 78');
54
+ ).toHaveTextContent('●●●● ending in 78');
55
55
  });
56
56
 
57
57
  test('does not add a visibility control by default', () => {
@@ -120,7 +120,7 @@ describe('ConfidentialInput', () => {
120
120
 
121
121
  expect(
122
122
  screen.getByTestId('ucl-uikit-confidential-input-mask')
123
- ).toHaveTextContent('••••');
123
+ ).toHaveTextContent('●●●●');
124
124
  expect(onChange).toHaveBeenLastCalledWith(expect.objectContaining({}));
125
125
  expect(onChange.mock.lastCall?.[0].target.value).toBe('1234');
126
126
  });
@@ -189,7 +189,7 @@ describe('ConfidentialInput', () => {
189
189
  ) as HTMLInputElement;
190
190
  expect(
191
191
  screen.getByTestId('ucl-uikit-confidential-input-mask')
192
- ).toHaveTextContent('••-••-72');
192
+ ).toHaveTextContent('●●-●●-72');
193
193
 
194
194
  await user.click(input);
195
195
 
@@ -203,7 +203,7 @@ describe('ConfidentialInput', () => {
203
203
 
204
204
  expect(
205
205
  screen.getByTestId('ucl-uikit-confidential-input-mask')
206
- ).toHaveTextContent('••-••-72');
206
+ ).toHaveTextContent('●●-●●-72');
207
207
  });
208
208
 
209
209
  test('uses native password masking when visibleWhenFocused is false', async () => {
@@ -219,7 +219,7 @@ describe('ConfidentialInput', () => {
219
219
  ) as HTMLInputElement;
220
220
  expect(
221
221
  screen.getByTestId('ucl-uikit-confidential-input-mask')
222
- ).toHaveTextContent('••-••-72');
222
+ ).toHaveTextContent('●●-●●-72');
223
223
 
224
224
  await user.click(input);
225
225
 
@@ -234,7 +234,7 @@ describe('ConfidentialInput', () => {
234
234
 
235
235
  expect(
236
236
  screen.getByTestId('ucl-uikit-confidential-input-mask')
237
- ).toHaveTextContent('••-••-72');
237
+ ).toHaveTextContent('●●-●●-72');
238
238
  });
239
239
 
240
240
  test('shows the raw value while editing a showable value', async () => {
@@ -250,7 +250,7 @@ describe('ConfidentialInput', () => {
250
250
  ) as HTMLInputElement;
251
251
  expect(
252
252
  screen.getByTestId('ucl-uikit-confidential-input-mask')
253
- ).toHaveTextContent('••-••-72');
253
+ ).toHaveTextContent('●●-●●-72');
254
254
 
255
255
  await user.click(input);
256
256
 
@@ -268,7 +268,7 @@ describe('ConfidentialInput', () => {
268
268
 
269
269
  expect(
270
270
  screen.getByTestId('ucl-uikit-confidential-input-mask')
271
- ).toHaveTextContent('••-••-72');
271
+ ).toHaveTextContent('●●-●●-72');
272
272
  });
273
273
 
274
274
  test('supports a right icon alongside the visibility control', () => {
@@ -293,7 +293,7 @@ describe('ConfidentialInput', () => {
293
293
  const user = userEvent.setup();
294
294
  renderInput({
295
295
  value: '123472',
296
- maskFormat: '****##',
296
+ maskFormat: '**-**-##',
297
297
  format: '##-##-##',
298
298
  showable: true,
299
299
  onChange: () => {},
@@ -301,7 +301,7 @@ describe('ConfidentialInput', () => {
301
301
 
302
302
  expect(
303
303
  screen.getByTestId('ucl-uikit-confidential-input-mask')
304
- ).toHaveTextContent('••-••-72');
304
+ ).toHaveTextContent('●●-●●-72');
305
305
 
306
306
  await user.click(
307
307
  screen.getByRole('button', { name: 'Show confidential value' })
@@ -1,6 +1,14 @@
1
1
  export type MaskFormat = string | ((value: string) => string);
2
2
 
3
- const applyMaskTemplate = (value: string, template: string) => {
3
+ interface FormatConfidentialValueOptions {
4
+ includeTemplateLiterals?: boolean;
5
+ }
6
+
7
+ const applyMaskTemplate = (
8
+ value: string,
9
+ template: string,
10
+ includeTemplateLiterals: boolean
11
+ ) => {
4
12
  const valueCharacters = Array.from(value);
5
13
  let valueIndex = 0;
6
14
  let maskedValue = '';
@@ -14,7 +22,7 @@ const applyMaskTemplate = (value: string, template: string) => {
14
22
  } else if (templateCharacter === '*') {
15
23
  maskedValue += '*';
16
24
  valueIndex += 1;
17
- } else {
25
+ } else if (includeTemplateLiterals) {
18
26
  maskedValue += templateCharacter;
19
27
  }
20
28
  }
@@ -24,13 +32,17 @@ const applyMaskTemplate = (value: string, template: string) => {
24
32
  );
25
33
  };
26
34
 
27
- const formatConfidentialValue = (value: string, maskFormat: MaskFormat) => {
35
+ const formatConfidentialValue = (
36
+ value: string,
37
+ maskFormat: MaskFormat,
38
+ { includeTemplateLiterals = true }: FormatConfidentialValueOptions = {}
39
+ ) => {
28
40
  const maskedValue =
29
41
  typeof maskFormat === 'function'
30
42
  ? maskFormat(value)
31
- : applyMaskTemplate(value, maskFormat);
43
+ : applyMaskTemplate(value, maskFormat, includeTemplateLiterals);
32
44
 
33
- return maskedValue.split('*').join('');
45
+ return maskedValue.split('*').join('');
34
46
  };
35
47
 
36
48
  export default formatConfidentialValue;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "uikit-react-public",
3
3
  "private": false,
4
4
  "license": "UNLICENSED",
5
- "version": "0.49.2",
5
+ "version": "0.49.4",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",