Skip to content

Commit b4c1acd

Browse files
authored
Merge pull request #12 from kubit-ui/feature/new-update-and-improvements
Feature/new update and improvements
2 parents fd6737d + a3cac28 commit b4c1acd

File tree

90 files changed

+1223
-406
lines changed

Some content is hidden

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

90 files changed

+1223
-406
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kubit-ui-web/react-components",
3-
"version": "1.3.2",
3+
"version": "1.4.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",

src/components/calendar/selector/selector.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,15 @@ export const Selector = (props: ISelector): JSX.Element => {
126126
<SelectorStyled isDaySelector={isDaySelector} styles={props.styles}>
127127
<IconAndBackTextStyled styles={props.styles} onClick={handleOnClickBack}>
128128
<ElementOrIcon
129+
color={iconArrowDisabled(props.minDate) ? props.styles?.colorArrowDisabled : undefined}
130+
customIconStyles={props.styles?.leftArrow}
131+
disabled={iconArrowDisabled(props.minDate)}
132+
{...leftArrowIcon}
129133
aria-label={
130134
showCustomSelector
131135
? props.configAccesibility?.backToMonthAriaLabel
132136
: leftArrowIcon['aria-label']
133137
}
134-
color={iconArrowDisabled(props.minDate) ? props.styles?.colorArrowDisabled : undefined}
135-
customIconStyles={props.styles?.leftArrow}
136-
disabled={iconArrowDisabled(props.minDate)}
137-
{...leftArrowIcon}
138138
onClick={handleOnClickLeftIcon}
139139
/>
140140
{showCustomSelector && (

src/components/checkbox/__tests__/checkbox.test.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,10 @@ describe('Checkbox component', () => {
247247
const checkbox = screen.getByRole('checkbox');
248248

249249
expect(checkbox).toBeInTheDocument();
250-
expect(checkbox).toHaveAttribute('aria-describedby', `${checkboxId}ScreenReader`);
250+
expect(checkbox).toHaveAttribute(
251+
'aria-describedby',
252+
`${checkboxId}Label ${checkboxId}ScreenReader`
253+
);
251254

252255
const results = await axe(container);
253256
expect(container).toHTMLValidate();

src/components/checkbox/checkboxStandAlone.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const CheckboxStandAloneComponent = (
5151
const { isChecked, isDisabled, hasError } = checkboxState(state);
5252

5353
const checkBoxId = id ?? uniqueId;
54+
const checkBoxLabelId = `${checkBoxId}Label`;
5455
const checkBoxkHelpContentId = `${checkBoxId}HelpContent`;
5556
const checkBoxErrorId = `${checkBoxId}Error`;
5657
const screenReaderId = `${checkBoxId}ScreenReader`;
@@ -68,6 +69,7 @@ const CheckboxStandAloneComponent = (
6869
color={labelTypography?.color}
6970
cursor={isDisabled ? CURSOR_DEFAULT : CURSOR_POINTER}
7071
dataTestId={`${dataTestId}Label`}
72+
id={checkBoxLabelId}
7173
inputId={checkBoxId}
7274
required={required}
7375
textVariant={labelTypography?.font_variant}
@@ -126,6 +128,8 @@ const CheckboxStandAloneComponent = (
126128
ref={ref}
127129
aria-describedby={buildAriaDescribedBy({
128130
extraAriaDescribedBy,
131+
label: label?.content,
132+
checkBoxLabelId,
129133
helpContent: helperContent?.content,
130134
checkBoxkHelpContentId,
131135
hasError,

src/components/checkbox/utils/aria.utils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/**
22
* Build the aria-describedby attribute for the checkbox
33
* @param extraAriaDescribedBy
4+
* @param label
5+
* @param checkBoxLabelId
46
* @param helpContent
57
* @param checkBoxkHelpContentId
68
* @param textError
@@ -12,6 +14,8 @@
1214
*/
1315
export const buildAriaDescribedBy = ({
1416
extraAriaDescribedBy,
17+
label,
18+
checkBoxLabelId,
1519
helpContent,
1620
checkBoxkHelpContentId,
1721
errorText,
@@ -21,6 +25,8 @@ export const buildAriaDescribedBy = ({
2125
screenReaderId,
2226
}: {
2327
extraAriaDescribedBy: string;
28+
label?: JSX.Element | string;
29+
checkBoxLabelId: string;
2430
helpContent?: JSX.Element | string;
2531
checkBoxkHelpContentId: string;
2632
hasError: boolean;
@@ -30,6 +36,9 @@ export const buildAriaDescribedBy = ({
3036
screenReaderId: string;
3137
}): string => {
3238
let res = extraAriaDescribedBy;
39+
if (label) {
40+
res += ` ${checkBoxLabelId}`;
41+
}
3342
if (screenReaderText) {
3443
res += ` ${screenReaderId}`;
3544
}

src/components/footer/components/footerContent.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,24 @@ interface IFooterContent {
88
contentDirection?: ContentDirectionType;
99
forceVertical?: boolean;
1010
children: React.ReactNode[];
11+
margin?: boolean;
12+
marginLeft?: boolean;
13+
marginRight?: boolean;
1114
}
1215

1316
export const FooterContent = (props: IFooterContent): JSX.Element | null => {
1417
// always returned something, cause we need to put container to flex direction
1518
const flexDirectionDesktopTablet = props.forceVertical ? 'column' : 'row';
1619

20+
if (!props.children.length) {
21+
return null;
22+
}
23+
1724
return (
1825
<FooterContentStyled
26+
$margin={props.margin}
27+
$marginLeft={props.marginLeft}
28+
$marginRight={props.marginRight}
1929
aria-hidden={!props.children.length}
2030
contentDirection={props.contentDirection}
2131
flexDirectionDesktopTablet={flexDirectionDesktopTablet}

src/components/footer/footer.styled.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ type FooterStylesType = {
1010
contentDirection?: ContentDirectionType;
1111
flexDirectionDesktopTablet?: string;
1212
alignItems?: string;
13+
$margin?: boolean;
14+
$marginLeft?: boolean;
15+
$marginRight?: boolean;
1316
};
1417

1518
type RootContainerStyledType = FooterStylesType & {
@@ -36,4 +39,7 @@ export const FooterContentStyled = styled.div<FooterStylesType>`
3639
justify-content: ${props =>
3740
props.contentDirection === ContentDirectionType.HORIZONTAL ? 'flex-start' : 'center'};
3841
${props => getStyles(props.styles?.contentContainer)}
42+
margin: ${props => props.$margin && 'auto'};
43+
margin-left: ${props => props.$marginLeft && 'auto'};
44+
margin-right: ${props => props.$marginRight && 'auto'};
3945
`;

src/components/footer/footerStandAlone.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,23 @@ const FooterStandAloneComponent = (
8080
<FooterContent
8181
contentDirection={props.contentDirection}
8282
forceVertical={props.forceVertical}
83+
marginRight={true}
8384
styles={props.styles}
8485
>
8586
{firstContent}
8687
</FooterContent>
8788
<FooterContent
8889
contentDirection={props.contentDirection}
8990
forceVertical={props.forceVertical}
91+
margin={true}
9092
styles={props.styles}
9193
>
9294
{secondContent}
9395
</FooterContent>
9496
<FooterContent
9597
contentDirection={props.contentDirection}
9698
forceVertical={props.forceVertical}
99+
marginLeft={true}
97100
styles={props.styles}
98101
>
99102
{thridContent}

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

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,12 @@ describe('New Input Component', () => {
155155
expect(results).toHaveNoViolations();
156156
});
157157

158-
it('Should call onIconClick when user click on icon', async () => {
158+
it('Should call onLeftIconClick when user click on left icon', async () => {
159159
const onIconClick = jest.fn();
160160
const { container, getByRole } = renderProvider(
161161
<Input
162162
{...commonProps}
163-
icon={{ icon: 'UNICORN', altText: 'Open Info', onClick: onIconClick }}
163+
leftIcon={{ icon: 'UNICORN', altText: 'Open Info', onClick: onIconClick }}
164164
placeholder={'placeholder'}
165165
/>
166166
);
@@ -175,6 +175,26 @@ describe('New Input Component', () => {
175175
expect(results).toHaveNoViolations();
176176
});
177177

178+
it('Should call onRightIconClick when user click on right icon', async () => {
179+
const onIconClick = jest.fn();
180+
const { container, getByRole } = renderProvider(
181+
<Input
182+
{...commonProps}
183+
placeholder={'placeholder'}
184+
rightIcon={{ icon: 'UNICORN', altText: 'Open Info', onClick: onIconClick }}
185+
/>
186+
);
187+
188+
const triggerButton = getByRole('button', { name: 'Open Info' });
189+
fireEvent.click(triggerButton);
190+
expect(onIconClick).toHaveBeenCalled();
191+
192+
// A11Y and w3c validator
193+
const results = await axe(container);
194+
expect(container).toHTMLValidate();
195+
expect(results).toHaveNoViolations();
196+
});
197+
178198
it('Should be autoformated the text with mask', async () => {
179199
const onChange = jest.fn();
180200
const { container, getByRole } = renderProvider(
@@ -348,12 +368,36 @@ describe('New Input Component', () => {
348368
expect(results).toHaveNoViolations();
349369
});
350370

351-
it('Should show icon as img instead of as button', async () => {
371+
it('Should show left icon as img instead of as button', async () => {
372+
const iconClick = jest.fn();
373+
const { container, getByRole } = renderProvider(
374+
<Input
375+
{...commonProps}
376+
leftIcon={{ icon: 'UNICORN', altText: 'Open Info', onClick: iconClick }}
377+
placeholder={'placeholder'}
378+
/>
379+
);
380+
381+
const triggerButton = getByRole('button', { name: 'Open Info' });
382+
expect(triggerButton).toBeInTheDocument();
383+
384+
fireEvent.click(triggerButton);
385+
386+
expect(iconClick).toHaveBeenCalled();
387+
388+
// A11Y and w3c validator
389+
const results = await axe(container);
390+
expect(container).toHTMLValidate();
391+
expect(results).toHaveNoViolations();
392+
});
393+
394+
it('Should show right icon as img instead of as button', async () => {
395+
const iconClick = jest.fn();
352396
const { container, getByRole } = renderProvider(
353397
<Input
354398
{...commonProps}
355-
icon={{ icon: 'UNICORN', altText: 'Open Info' }}
356399
placeholder={'placeholder'}
400+
rightIcon={{ icon: 'UNICORN', altText: 'Open Info', onClick: iconClick }}
357401
/>
358402
);
359403

src/components/input/components/inputIcon.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,36 @@ import { IInputIcon } from '../types/input';
99
const InputIconStandAloneComponent = (
1010
props: IInputIcon,
1111
ref: React.ForwardedRef<HTMLDivElement>
12+
): JSX.Element | null => {
13+
const icon = props.leftIcon || props.rightIcon;
14+
if (!icon || props.loading) {
15+
return null;
16+
}
17+
18+
const onClick: React.MouseEventHandler<HTMLButtonElement> = event => {
19+
props.rightIcon?.onClick?.(event);
20+
props.leftIcon?.onClick?.(event);
21+
};
22+
23+
return (
24+
<InputIconStyled ref={ref} iconPosition={props.iconPosition} styles={props.styles}>
25+
<ElementOrIcon
26+
customIconStyles={props.styles?.inputIcon}
27+
disabled={props.disabled}
28+
{...props.rightIcon}
29+
{...props.leftIcon}
30+
onClick={onClick}
31+
/>
32+
</InputIconStyled>
33+
);
34+
};
35+
36+
export const InputIconStandAlone = React.forwardRef(InputIconStandAloneComponent);
37+
38+
// deprecated - remove this function when icon prop is removed
39+
const InputIconStandAloneDeprecatedComponent = (
40+
props: IInputIcon,
41+
ref: React.ForwardedRef<HTMLDivElement>
1242
): JSX.Element | null => {
1343
if (!props.icon || props.loading) {
1444
return null;
@@ -29,4 +59,6 @@ const InputIconStandAloneComponent = (
2959
);
3060
};
3161

32-
export const InputIconStandAlone = React.forwardRef(InputIconStandAloneComponent);
62+
export const InputIconStandAloneDeprecated = React.forwardRef(
63+
InputIconStandAloneDeprecatedComponent
64+
);

0 commit comments

Comments
 (0)