Skip to content

Commit 3e2b1ec

Browse files
authored
Merge pull request #13 from kubit-ui/feature/updates-and-improvements
Feature/updates and improvements
2 parents b4c1acd + 4d44273 commit 3e2b1ec

File tree

97 files changed

+1458
-370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1458
-370
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kubit-ui-web/react-components",
3-
"version": "1.4.0",
3+
"version": "1.5.0",
44
"description": "Kubit React Components is a customizable, accessible library of React web components, designed to enhance your application's user experience",
55
"author": {
66
"name": "Kubit",
@@ -152,8 +152,8 @@
152152
"dependencies": {
153153
"@emotion/is-prop-valid": "^1.2.1",
154154
"lottie-web": "^5.12.2",
155-
"react": "^18.2.0",
156-
"react-dom": "^18.2.0",
155+
"react": "^18.3.1",
156+
"react-dom": "^18.3.1",
157157
"react-transition-group": "^4.4.5",
158158
"styled-components": "^6.1.8"
159159
},

src/components/carousel/__tests__/carousel.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,24 @@ describe('Carousel component', () => {
7676
expect(results).toHaveNoViolations();
7777
});
7878

79+
it('Carousel with no elements should not break', async () => {
80+
const { container, getByTestId } = renderProvider(
81+
<CarouselUnControlled {...mockProps} elements={[]} />
82+
);
83+
84+
const carousel = getByTestId('dataTestIdCarouselWrapper');
85+
expect(carousel).toBeInTheDocument();
86+
87+
const results = await axe(container);
88+
// Disable style in line
89+
expect(container).toHTMLValidate({
90+
rules: {
91+
'no-inline-style': 'off',
92+
},
93+
});
94+
expect(results).toHaveNoViolations();
95+
});
96+
7997
it('Carousel with numPages 1', async () => {
8098
const elements = [
8199
<div key="0" aria-label="1 of 10" aria-roledescription="slide" role="group">

src/components/carousel/hooks/useCarousel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ export const useCarousel = ({
551551
!carouselContainer ||
552552
!carouselContent ||
553553
!allowShift.current ||
554-
!numElementsPerPage.current
554+
!numElementsPerPage.current ||
555+
!elements.length
555556
) {
556557
return;
557558
}

src/components/dropdownSelected/__tests__/dropdownSelected.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,26 @@ describe('DropdownSelected component', () => {
182182
expect(handleMouseEnter).toHaveBeenCalledTimes(1);
183183
expect(handleMouseLeave).toHaveBeenCalledTimes(1);
184184
});
185+
186+
it('closes the dropdown when the visibility changes', async () => {
187+
// Mock the document.hidden property
188+
Object.defineProperty(document, 'hidden', {
189+
configurable: true,
190+
get: () => true,
191+
});
192+
193+
const { getAllByRole } = renderProvider(<DropdownSelected {...mockProps} defaultOpen={true} />);
194+
195+
const option1 = getAllByRole('option')[0];
196+
option1.focus();
197+
198+
expect(option1).toBeInTheDocument();
199+
200+
await act(async () => {
201+
// Simulate the visibilitychange event
202+
fireEvent(document, new Event('visibilitychange'));
203+
});
204+
205+
expect(option1).not.toBeInTheDocument();
206+
});
185207
});

src/components/dropdownSelected/dropdownSelectedStandAlone.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ const DropdownSelectedStandAloneComponent = (
7171
ref={ref}
7272
data-testid={props.dataTestIdComponent}
7373
styles={props.styles}
74-
onBlur={event => props.onFocus?.(event)}
74+
onBlur={props.onBlur}
7575
onFocus={props.onFocus}
76-
onKeyDown={event => props.onKeyDown?.(event)}
76+
onKeyDown={props.onKeyDown}
7777
onMouseEnter={props.onMouseEnter}
7878
onMouseLeave={props.onMouseLeave}
7979
>

src/components/dropdownSelected/dropdownSelectedUncontrolled.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ const DropdownSelectedUnControlledComponent = (
2626

2727
const buttonOrLinkRef = React.useRef<HTMLButtonElement>(null);
2828

29+
// Close dropdown when the document hides
30+
React.useEffect(() => {
31+
const handleVisibilityChange = e => {
32+
if (document.hidden) {
33+
setOpen(false);
34+
}
35+
};
36+
document.addEventListener('visibilitychange', handleVisibilityChange);
37+
return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
38+
}, []);
39+
2940
const handleOnClickButton: React.MouseEventHandler<HTMLButtonElement | HTMLLinkElement> = () => {
3041
props.onButtonClick?.(!open);
3142
setOpen(!open);

src/components/dropdownSelected/stories/dropdownSelected.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const commonArgs: IDropdownSelectedUncontrolled = {
4949
value: 'option2',
5050
},
5151
],
52+
type: ListOptionsType.SELECTION,
5253
},
5354
closePopoverOnScroll: true,
5455
};

src/components/input/__tests__/input.test.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ function backspace(element) {
5454
fireEvent.keyUp(element, sharedEventConfig);
5555
}
5656

57-
global.structuredClone = jest.fn(val => {
58-
return JSON.parse(JSON.stringify(val));
59-
});
60-
6157
const writeText = jest.fn();
6258

6359
Object.assign(navigator, {
@@ -295,7 +291,7 @@ describe('New Input Component', () => {
295291
informationAssociatedValue: undefined,
296292
informationAssociatedIcon: undefined,
297293
};
298-
const { container, getByText, getByAltText } = renderProvider(
294+
const { container, getByText, getByLabelText } = renderProvider(
299295
<Input
300296
{...commonProps}
301297
{...informationAssociatedConfig}
@@ -308,7 +304,7 @@ describe('New Input Component', () => {
308304
const errorMessage = getByText('ERROR');
309305
expect(errorMessage).toBeInTheDocument();
310306

311-
const errorIcon = getByAltText('Error alt text');
307+
const errorIcon = getByLabelText('Error alt text');
312308
expect(errorIcon).toBeInTheDocument();
313309
// A11Y and w3c validator
314310
const results = await axe(container);

src/components/input/components/errorMessage.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,20 @@ export const ErrorMessageStandAlone = (props: IErrorMessage): JSX.Element => {
1515
id={props.errorMessageId}
1616
styles={props.styles}
1717
>
18-
{props.errorMessage?.content && hasError(props.state) ? (
19-
<Text
20-
customTypography={props.styles?.errorMessage}
21-
dataTestId={`${props.dataTestId}ErrorMessage`}
22-
{...props.errorMessage}
23-
>
24-
{props.errorIcon?.icon && (
25-
<ErrorIconWrapperStyled styles={props.styles}>
26-
<ElementOrIcon
27-
customIconStyles={props.styles?.errorMessageIcon}
28-
{...props.errorIcon}
29-
/>
30-
</ErrorIconWrapperStyled>
31-
)}
32-
{props.errorMessage.content}
33-
</Text>
34-
) : null}
18+
{hasError(props.state) && (
19+
<>
20+
<ErrorIconWrapperStyled styles={props.styles}>
21+
<ElementOrIcon customIconStyles={props.styles?.errorMessageIcon} {...props.errorIcon} />
22+
</ErrorIconWrapperStyled>
23+
<Text
24+
customTypography={props.styles?.errorMessage}
25+
dataTestId={`${props.dataTestId}ErrorMessage`}
26+
{...props.errorMessage}
27+
>
28+
{props.errorMessage?.content}
29+
</Text>
30+
</>
31+
)}
3532
</InputErrorStyled>
3633
);
3734
};

src/components/input/components/informationAssociated.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ export const InformationAssociatedStandAlone = (
4444
/>
4545
) : (
4646
<ElementOrIcon
47-
color={props.styles?.informationAssociatedIcon?.color}
48-
height={props.styles?.informationAssociatedIcon?.height}
49-
width={props.styles?.informationAssociatedIcon?.width}
47+
customIconStyles={props.styles?.informationAssociatedIcon}
5048
{...props.informationAssociatedIcon}
5149
/>
5250
);

0 commit comments

Comments
 (0)