@lumx/react 3.7.2-alpha.0 → 3.7.3

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/package.json CHANGED
@@ -7,8 +7,8 @@
7
7
  },
8
8
  "dependencies": {
9
9
  "@juggle/resize-observer": "^3.2.0",
10
- "@lumx/core": "^3.7.2-alpha.0",
11
- "@lumx/icons": "^3.7.2-alpha.0",
10
+ "@lumx/core": "^3.7.3",
11
+ "@lumx/icons": "^3.7.3",
12
12
  "@popperjs/core": "^2.5.4",
13
13
  "body-scroll-lock": "^3.1.5",
14
14
  "classnames": "^2.3.2",
@@ -112,5 +112,5 @@
112
112
  "build:storybook": "storybook build"
113
113
  },
114
114
  "sideEffects": false,
115
- "version": "3.7.2-alpha.0"
115
+ "version": "3.7.3"
116
116
  }
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  import { Theme } from '@lumx/react';
4
4
  import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
5
- import { render, screen } from '@testing-library/react';
5
+ import { fireEvent, render, screen } from '@testing-library/react';
6
6
  import { getByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
7
7
  import userEvent from '@testing-library/user-event';
8
8
  import { Chip, ChipProps } from './Chip';
@@ -160,6 +160,14 @@ describe('<Chip />', () => {
160
160
  await userEvent.click(after as any);
161
161
  expect(onClick).toHaveBeenCalled();
162
162
  });
163
+
164
+ it('should forward key down event', async () => {
165
+ const onKeyDown = jest.fn();
166
+ const { chip } = setup({ onClick, onKeyDown });
167
+
168
+ fireEvent.keyDown(chip, { key: 'A', code: 'KeyA' });
169
+ expect(onKeyDown).toHaveBeenCalled();
170
+ });
163
171
  });
164
172
 
165
173
  commonTestsSuiteRTL(setup, { baseClassName: CLASSNAME, forwardClassName: 'chip', forwardAttributes: 'chip' });
@@ -84,6 +84,7 @@ export const Chip: Comp<ChipProps, HTMLAnchorElement> = forwardRef((props, ref)
84
84
  size,
85
85
  theme,
86
86
  href,
87
+ onKeyDown,
87
88
  ...forwardedProps
88
89
  } = props;
89
90
  const hasAfterClick = isFunction(onAfterClick);
@@ -97,6 +98,12 @@ export const Chip: Comp<ChipProps, HTMLAnchorElement> = forwardRef((props, ref)
97
98
 
98
99
  const handleOnBeforeClick = useStopPropagation(onBeforeClick);
99
100
  const handleOnAfterClick = useStopPropagation(onAfterClick);
101
+ const handleKeyDown = (evt: React.KeyboardEvent) => {
102
+ onKeyDown?.(evt);
103
+ if (hasOnClick) {
104
+ onEnterPressed(onClick);
105
+ }
106
+ };
100
107
 
101
108
  return (
102
109
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
@@ -123,7 +130,7 @@ export const Chip: Comp<ChipProps, HTMLAnchorElement> = forwardRef((props, ref)
123
130
  )}
124
131
  aria-disabled={(isClickable && isDisabled) || undefined}
125
132
  onClick={hasOnClick ? onClick : undefined}
126
- onKeyDown={hasOnClick ? onEnterPressed(onClick) : undefined}
133
+ onKeyDown={handleKeyDown}
127
134
  >
128
135
  {before && (
129
136
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
@@ -13,6 +13,7 @@ import { InputLabel } from '@lumx/react/components/input-label/InputLabel';
13
13
 
14
14
  import { Comp } from '@lumx/react/utils/type';
15
15
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
16
+ import { mergeRefs } from '@lumx/react/utils/mergeRefs';
16
17
 
17
18
  import { WithSelectContext } from './WithSelectContext';
18
19
  import { CoreSelectProps, SelectVariant } from './constants';
@@ -61,6 +62,7 @@ const SelectField: React.FC<SelectProps> = ({
61
62
  theme,
62
63
  value,
63
64
  variant,
65
+ selectElementRef,
64
66
  ...forwardedProps
65
67
  }) => {
66
68
  return (
@@ -82,7 +84,7 @@ const SelectField: React.FC<SelectProps> = ({
82
84
 
83
85
  {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
84
86
  <div
85
- ref={anchorRef as RefObject<HTMLDivElement>}
87
+ ref={mergeRefs(anchorRef as RefObject<HTMLDivElement>, selectElementRef)}
86
88
  id={id}
87
89
  className={`${CLASSNAME}__wrapper`}
88
90
  onClick={onInputClick}
@@ -145,7 +147,7 @@ const SelectField: React.FC<SelectProps> = ({
145
147
  after={<Icon icon={isEmpty ? mdiMenuDown : mdiCloseCircle} />}
146
148
  onAfterClick={isEmpty ? onInputClick : onClear}
147
149
  onClick={onInputClick}
148
- ref={anchorRef as RefObject<HTMLAnchorElement>}
150
+ ref={mergeRefs(anchorRef as RefObject<HTMLAnchorElement>, selectElementRef)}
149
151
  theme={theme}
150
152
  {...forwardedProps}
151
153
  >
@@ -11,6 +11,7 @@ import { InputLabel } from '@lumx/react/components/input-label/InputLabel';
11
11
 
12
12
  import { Comp } from '@lumx/react/utils/type';
13
13
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
14
+ import { mergeRefs } from '@lumx/react/utils/mergeRefs';
14
15
 
15
16
  import { WithSelectContext } from './WithSelectContext';
16
17
  import { CoreSelectProps, SelectVariant } from './constants';
@@ -75,6 +76,7 @@ export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
75
76
  theme,
76
77
  value,
77
78
  variant,
79
+ selectElementRef,
78
80
  ...forwardedProps
79
81
  }) => (
80
82
  <>
@@ -95,7 +97,7 @@ export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
95
97
 
96
98
  {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
97
99
  <div
98
- ref={anchorRef as RefObject<HTMLDivElement>}
100
+ ref={mergeRefs(anchorRef as RefObject<HTMLDivElement>, selectElementRef)}
99
101
  id={id}
100
102
  className={`${CLASSNAME}__wrapper`}
101
103
  onClick={onInputClick}
@@ -150,7 +152,7 @@ export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
150
152
  after={<Icon icon={isEmpty ? mdiMenuDown : mdiCloseCircle} />}
151
153
  onAfterClick={isEmpty ? onInputClick : onClear}
152
154
  onClick={onInputClick}
153
- ref={anchorRef as RefObject<HTMLAnchorElement>}
155
+ ref={mergeRefs(anchorRef as RefObject<HTMLAnchorElement>, selectElementRef)}
154
156
  theme={theme}
155
157
  {...forwardedProps}
156
158
  >
@@ -124,7 +124,7 @@ describe(`<${TextField.displayName}>`, () => {
124
124
  });
125
125
 
126
126
  expect(helper).toHaveTextContent('helper');
127
- expect(inputNative).toHaveAttribute('aria-describedby');
127
+ expect(inputNative).toHaveAccessibleDescription('helper');
128
128
  });
129
129
 
130
130
  it('should have error text', () => {
@@ -137,7 +137,7 @@ describe(`<${TextField.displayName}>`, () => {
137
137
 
138
138
  expect(error).toHaveTextContent('error');
139
139
  expect(inputNative).toHaveAttribute('aria-invalid', 'true');
140
- expect(inputNative).toHaveAttribute('aria-describedby');
140
+ expect(inputNative).toHaveAccessibleDescription('error');
141
141
  });
142
142
 
143
143
  it('should not have error text', () => {
@@ -151,7 +151,7 @@ describe(`<${TextField.displayName}>`, () => {
151
151
  });
152
152
 
153
153
  it('should have error and helper text', () => {
154
- const { error, helper } = setup({
154
+ const { error, helper, inputNative } = setup({
155
155
  error: 'error',
156
156
  hasError: true,
157
157
  helper: 'helper',
@@ -160,6 +160,21 @@ describe(`<${TextField.displayName}>`, () => {
160
160
  });
161
161
  expect(error).toHaveTextContent('error');
162
162
  expect(helper).toHaveTextContent('helper');
163
+ expect(inputNative).toHaveAccessibleDescription('error helper');
164
+ });
165
+
166
+ it('should have error and helper text and custom aria describedby', () => {
167
+ const { error, helper, inputNative } = setup({
168
+ error: 'error',
169
+ hasError: true,
170
+ helper: 'helper',
171
+ label: 'test',
172
+ placeholder: 'test',
173
+ 'aria-describedby': 'aria-description',
174
+ });
175
+ expect(error).toHaveTextContent('error');
176
+ expect(helper).toHaveTextContent('helper');
177
+ expect(inputNative).toHaveAttribute('aria-describedby', expect.stringContaining('aria-description'));
163
178
  });
164
179
  });
165
180
 
@@ -309,7 +309,7 @@ export const TextField: Comp<TextFieldProps, HTMLDivElement> = forwardRef((props
309
309
  */
310
310
  const helperId = helper ? `text-field-helper-${uid()}` : undefined;
311
311
  const errorId = error ? `text-field-error-${uid()}` : undefined;
312
- const describedByIds = [errorId, helperId].filter(Boolean);
312
+ const describedByIds = [errorId, helperId, forwardedProps['aria-describedby']].filter(Boolean);
313
313
  const describedById = describedByIds.length === 0 ? undefined : describedByIds.join(' ');
314
314
 
315
315
  const [isFocus, setFocus] = useState(false);