Skip to content

Commit 5f61563

Browse files
authored
Merge pull request #25 from kubit-ui/feature/improvements-and-fix-bugs
Feature/improvements and fix bugs
2 parents 400ca99 + ab8a3c5 commit 5f61563

Some content is hidden

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

50 files changed

+2035
-344
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kubit-ui-web/react-components",
3-
"version": "1.9.0",
3+
"version": "1.10.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",
@@ -111,8 +111,8 @@
111111
"@types/react-dom": "^18.3.0",
112112
"@types/styled-components": "^5.1.34",
113113
"@types/ungap__structured-clone": "^1.2.0",
114-
"@typescript-eslint/eslint-plugin": "^8.0.0",
115-
"@typescript-eslint/parser": "^8.0.0",
114+
"@typescript-eslint/eslint-plugin": "^8.0.1",
115+
"@typescript-eslint/parser": "^8.0.1",
116116
"@ungap/structured-clone": "^1.2.0",
117117
"@vitejs/plugin-react": "^4.3.1",
118118
"babel-jest": "^29.7.0",
@@ -127,7 +127,7 @@
127127
"eslint-plugin-n": "^17.10.2",
128128
"eslint-plugin-node": "^11.1.0",
129129
"eslint-plugin-prettier": "5.2.1",
130-
"eslint-plugin-promise": "^7.0.0",
130+
"eslint-plugin-promise": "^7.1.0",
131131
"eslint-plugin-react": "^7.35.0",
132132
"eslint-plugin-react-hooks": "^4.6.2",
133133
"eslint-plugin-react-refresh": "^0.4.9",

src/components/accordion/accordion.styled.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ export const AccordionHeaderMainContainerStyled = styled.div<IAccordionStyles>`
3232
${props => getStyles(props.styles)}
3333
`;
3434

35-
export const AccordionHeaderTitleHeadlineStyled = styled.span`
35+
export const AccordionHeaderTitleHeadlineStyled = styled.span<IAccordionStyles>`
3636
display: flex;
3737
width: 100%;
38+
${props => getStyles(props.styles)}
3839
`;
3940

4041
export const AccordionTitleStyled = styled.span<IAccordionStyles>`

src/components/accordion/accordionStandAlone.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ const AccordionStandAloneComponent = (
5858
styles={props.styles.headerInternalContainer}
5959
>
6060
<AccordionHeaderMainContainerStyled styles={props.styles.headerMainContainer}>
61-
<AccordionHeaderTitleHeadlineStyled as={props.triggerComponent}>
61+
<AccordionHeaderTitleHeadlineStyled
62+
as={props.triggerComponent}
63+
styles={props.styles.titleHeaderMainContainer}
64+
>
6265
<AccordionTriggerStyled
6366
aria-controls={PANEL_ID}
6467
aria-expanded={open}

src/components/accordion/types/accordionTheme.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type AccordionPropsStylesType = {
1414
headerExternalContainer?: CommonStyleType;
1515
headerInternalContainer?: CommonStyleType;
1616
headerMainContainer?: CommonStyleType;
17+
titleHeaderMainContainer?: CommonStyleType;
1718
trigger?: CommonStyleType;
1819
/**
1920
* @deprecated currently link styles is used instead of trigger when tittle is not type of string. In the next major only trigger styles will be used

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export * from './message';
3636
export * from './modal';
3737
export * from './oliveMenu';
3838
export * from './pillSelector';
39+
export * from './pillSelectorV2';
3940
export * from './tabs';
4041
export * from './snackbar';
4142
export * from './stepperNumber';

src/components/pillSelector/pillSelectorControlled.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,7 @@ const PillSelectorControlled = React.forwardRef(PillSelectorBoundary) as <
9292
}
9393
) => ReturnType<typeof PillSelectorBoundary>;
9494

95+
/**
96+
* @deprecated Try the new PillSelectorV2 component
97+
*/
9598
export { PillSelectorControlled };

src/components/pillSelector/pillSelectorUnControlled.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,7 @@ const PillSelectorUnControlled = React.forwardRef(PillSelectorUnControlledCompon
4545
}
4646
) => ReturnType<typeof PillSelectorUnControlledComponent>;
4747

48+
/**
49+
* @deprecated Try the new PillSelectorV2 component
50+
*/
4851
export { PillSelectorUnControlled };
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import { screen } from '@testing-library/react';
2+
import * as React from 'react';
3+
4+
import { axe } from 'jest-axe';
5+
6+
import { ICONS } from '@/assets';
7+
import {
8+
PillSelectorSizeTypeV2,
9+
PillSelectorVariantTypeV2,
10+
} from '@/designSystem/kubit/components/variants';
11+
import { renderProvider } from '@/tests/renderProvider/renderProvider.utility';
12+
import { ROLES } from '@/types';
13+
14+
import { PillSelectorControlled } from '../pillSelectorControlled';
15+
import { PillSelectorUnControlled } from '../pillSelectorUnControlled';
16+
import { IPillSelectorControlled, IPillSelectorUnControlled, PillSelectorType } from '../types';
17+
18+
const mockProps: IPillSelectorUnControlled = {
19+
variant: PillSelectorVariantTypeV2.DEFAULT,
20+
size: PillSelectorSizeTypeV2.LARGE,
21+
pills: [
22+
{ label: { content: 'Pill 1' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 1' },
23+
{ label: { content: 'Pill 2 ' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 2' },
24+
{ label: { content: 'Pill 3' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 3' },
25+
{ label: { content: 'Pill 4' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 4' },
26+
],
27+
};
28+
29+
describe('PillSelectorUncontrolled', () => {
30+
it('Should render a set of pills, by default pill type is input checkbox (PillSelectorType.SELECTOR_MULTIPLE)', async () => {
31+
const { container } = renderProvider(<PillSelectorUnControlled {...mockProps} />);
32+
33+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
34+
expect(pills).toHaveLength(mockProps.pills?.length as number);
35+
36+
const results = await axe(container);
37+
expect(container).toHTMLValidate();
38+
expect(results).toHaveNoViolations();
39+
});
40+
41+
it('When SELECTOR_SIMPLE, pills are render as checkbox', async () => {
42+
const { container } = renderProvider(
43+
<PillSelectorUnControlled {...mockProps} type={PillSelectorType.SELECTOR_SIMPLE} />
44+
);
45+
46+
const pills = screen.getAllByRole(ROLES.RADIO);
47+
expect(pills).toHaveLength(mockProps.pills?.length as number);
48+
49+
const results = await axe(container);
50+
expect(container).toHTMLValidate();
51+
expect(results).toHaveNoViolations();
52+
});
53+
54+
it('Size prop is optional', () => {
55+
const { size, ...restMockProps } = mockProps;
56+
renderProvider(<PillSelectorUnControlled {...restMockProps} />);
57+
58+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
59+
expect(pills).toHaveLength(mockProps.pills?.length as number);
60+
});
61+
62+
it('When SELECTOR_MULTIPLE, value should be an array of the value of the selected options', () => {
63+
const value = [mockProps.pills?.[0].value as string];
64+
renderProvider(<PillSelectorUnControlled {...mockProps} defaultValue={value} />);
65+
66+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
67+
expect(pills[0]).toBeChecked();
68+
});
69+
70+
it('When SELECTOR_SIMPLE, value should be a value from the values of the selected options', () => {
71+
const value = mockProps.pills?.[0].value as string;
72+
renderProvider(
73+
<PillSelectorUnControlled
74+
{...mockProps}
75+
defaultValue={value}
76+
type={PillSelectorType.SELECTOR_SIMPLE}
77+
/>
78+
);
79+
80+
const pills = screen.getAllByRole(ROLES.RADIO);
81+
expect(pills[0]).toBeChecked();
82+
});
83+
84+
it('When SELECTOR_MULTIPLE, onChange should return an array of the value of the selected options', () => {
85+
const value = [mockProps.pills?.[0].value as string];
86+
const handleChange = jest.fn();
87+
renderProvider(<PillSelectorUnControlled {...mockProps} onChange={handleChange} />);
88+
89+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
90+
pills[0].click();
91+
expect(handleChange).toHaveBeenCalledWith(value);
92+
});
93+
94+
it('When SELECTOR_MULTIPLE, onChange should return an array of the value of the selected options, if it is already selected it should be removed', () => {
95+
const value = [mockProps.pills?.[0].value as string];
96+
const handleChange = jest.fn();
97+
renderProvider(
98+
<PillSelectorUnControlled {...mockProps} defaultValue={value} onChange={handleChange} />
99+
);
100+
101+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
102+
pills[0].click();
103+
expect(handleChange).toHaveBeenCalledWith([]);
104+
});
105+
106+
it('When SELECTOR_MULTIPLE, onChange should return an array of the value of the selected options, if it not is already selected it should be added', () => {
107+
const value = [mockProps.pills?.[0].value as string];
108+
const handleChange = jest.fn();
109+
renderProvider(
110+
<PillSelectorUnControlled {...mockProps} defaultValue={value} onChange={handleChange} />
111+
);
112+
113+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
114+
pills[1].click();
115+
expect(handleChange).toHaveBeenCalledWith([
116+
mockProps.pills?.[0].value as string,
117+
mockProps.pills?.[1].value as string,
118+
]);
119+
});
120+
121+
it('When SELECTOR_SIMPLE, onChange should return a value from the values of the selected options', () => {
122+
const value = mockProps.pills?.[0].value as string;
123+
const handleChange = jest.fn();
124+
renderProvider(
125+
<PillSelectorUnControlled
126+
{...mockProps}
127+
type={PillSelectorType.SELECTOR_SIMPLE}
128+
onChange={handleChange}
129+
/>
130+
);
131+
132+
const pills = screen.getAllByRole(ROLES.RADIO);
133+
pills[0].click();
134+
expect(handleChange).toHaveBeenCalledWith(value);
135+
});
136+
});
137+
138+
const mockPropsControlled: IPillSelectorControlled = {
139+
variant: PillSelectorVariantTypeV2.DEFAULT,
140+
size: PillSelectorSizeTypeV2.LARGE,
141+
pills: [
142+
{ label: { content: 'Pill 1' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 1' },
143+
{ label: { content: 'Pill 2 ' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 2' },
144+
{ label: { content: 'Pill 3' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 3' },
145+
{ label: { content: 'Pill 4' }, icon: { icon: ICONS.ICON_PLACEHOLDER }, value: 'value 4' },
146+
],
147+
};
148+
149+
describe('PillSelectorcontrolled', () => {
150+
it('Should render a set of pills, by default pill type is input checkbox (PillSelectorType.SELECTOR_MULTIPLE)', () => {
151+
renderProvider(<PillSelectorControlled {...mockPropsControlled} />);
152+
153+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
154+
expect(pills).toHaveLength(mockProps.pills?.length as number);
155+
});
156+
157+
it('If onChange is not passed, when pressing over a pill it will not trigger any action', () => {
158+
renderProvider(<PillSelectorControlled {...mockPropsControlled} />);
159+
160+
const pills = screen.getAllByRole(ROLES.CHECKBOX);
161+
pills[0].click();
162+
163+
expect(pills[0]).not.toBeChecked();
164+
});
165+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export type {
2+
PillSelectorPillType as PillSelectorPillTypeV2,
3+
PillSelectorValueType as PillSelectorValueTypeV2,
4+
IPillSelectorUnControlled as IPillSelectorV2,
5+
IPillSelectorControlled as IPillSelectorControlledV2,
6+
PillSelectorPropsStylesType as PillSelectorPropsStylesTypeV2,
7+
PillSelectorStylesType as PillSelectorStylesTypeV2,
8+
} from './types';
9+
10+
export { PillSelectorType as PillSelectorTypeV2 } from './types/pillSelectorType';
11+
12+
export { PillSelectorUnControlled as PillSelectorV2 } from './pillSelectorUnControlled';
13+
export { PillSelectorControlled as PillSelectorControlledV2 } from './pillSelectorControlled';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import styled from 'styled-components';
2+
3+
import { getStyles } from '@/utils';
4+
5+
import { PillSelectorPropsStylesType } from './types';
6+
7+
export const RootContainerStyled = styled.div<{
8+
styles?: PillSelectorPropsStylesType;
9+
}>`
10+
${({ styles }) => getStyles(styles?.rootContainer)};
11+
`;

0 commit comments

Comments
 (0)