Skip to content

Commit 29a50b4

Browse files
authored
Merge pull request #28 from kubit-ui/feature/new-features-and-improvements
Feature/new features and improvements
2 parents 2698076 + c392f09 commit 29a50b4

File tree

76 files changed

+2907
-507
lines changed

Some content is hidden

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

76 files changed

+2907
-507
lines changed

package.json

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kubit-ui-web/react-components",
3-
"version": "1.11.0",
3+
"version": "1.12.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",
@@ -19,6 +19,7 @@
1919
"main": "./dist/cjs/index.js",
2020
"module": "./dist/esm/index.js",
2121
"types": "./dist/esm/index.d.ts",
22+
"type": "module",
2223
"engines": {
2324
"node": ">=20.x",
2425
"npm": ">=7.0.0"
@@ -87,12 +88,12 @@
8788
"license": "Apache-2.0",
8889
"devDependencies": {
8990
"@babel/core": "^7.25.2",
90-
"@babel/preset-env": "^7.25.3",
91+
"@babel/preset-env": "^7.25.4",
9192
"@babel/preset-react": "^7.24.7",
9293
"@babel/preset-typescript": "^7.24.7",
9394
"@eslint/compat": "^1.1.1",
9495
"@eslint/eslintrc": "^3.1.0",
95-
"@eslint/js": "^9.9.0",
96+
"@eslint/js": "^9.9.1",
9697
"@storybook/addon-a11y": "^8.2.9",
9798
"@storybook/addon-controls": "^8.2.9",
9899
"@storybook/addon-coverage": "^1.0.4",
@@ -103,7 +104,7 @@
103104
"@storybook/blocks": "^8.2.9",
104105
"@storybook/react": "^8.2.9",
105106
"@storybook/react-vite": "^8.2.9",
106-
"@testing-library/jest-dom": "^6.4.8",
107+
"@testing-library/jest-dom": "^6.5.0",
107108
"@testing-library/react": "^16.0.0",
108109
"@testing-library/react-hooks": "^8.0.1",
109110
"@testing-library/user-event": "^14.5.2",
@@ -115,16 +116,16 @@
115116
"@types/react-dom": "^18.3.0",
116117
"@types/styled-components": "^5.1.34",
117118
"@types/ungap__structured-clone": "^1.2.0",
118-
"@typescript-eslint/eslint-plugin": "^8.2.0",
119-
"@typescript-eslint/parser": "^8.2.0",
119+
"@typescript-eslint/eslint-plugin": "^8.3.0",
120+
"@typescript-eslint/parser": "^8.3.0",
120121
"@ungap/structured-clone": "^1.2.0",
121122
"@vitejs/plugin-react": "^4.3.1",
122123
"babel-jest": "^29.7.0",
123124
"cpy-cli": "^5.0.0",
124-
"eslint": "^9.9.0",
125+
"eslint": "^9.9.1",
125126
"eslint-config-prettier": "^9.1.0",
126127
"eslint-config-standard-with-typescript": "^43.0.1",
127-
"eslint-import-resolver-typescript": "^3.6.1",
128+
"eslint-import-resolver-typescript": "^3.6.3",
128129
"eslint-plugin-import": "^2.29.1",
129130
"eslint-plugin-jest": "^28.8.0",
130131
"eslint-plugin-jsx-a11y": "^6.9.0",
@@ -134,7 +135,7 @@
134135
"eslint-plugin-promise": "^7.1.0",
135136
"eslint-plugin-react": "^7.35.0",
136137
"eslint-plugin-react-hooks": "^4.6.2",
137-
"eslint-plugin-react-refresh": "^0.4.10",
138+
"eslint-plugin-react-refresh": "^0.4.11",
138139
"eslint-plugin-storybook": "^0.8.0",
139140
"eslint-plugin-unused-imports": "^4.1.3",
140141
"globals": "^15.9.0",
@@ -152,13 +153,13 @@
152153
"react-transition-group": "^4.4.5",
153154
"sort-imports": "^1.1.0",
154155
"storybook": "^8.2.9",
155-
"ts-jest": "^29.2.4",
156+
"ts-jest": "^29.2.5",
156157
"tsc-alias": "1.8.10",
157158
"typedoc": "^0.26.6",
158-
"typedoc-plugin-markdown": "^4.2.5",
159+
"typedoc-plugin-markdown": "^4.2.6",
159160
"typescript": "^5.5.4",
160161
"vite": "^5.4.2",
161-
"vite-tsconfig-paths": "^4.3.2",
162+
"vite-tsconfig-paths": "^5.0.1",
162163
"yarn-deduplicate": "^6.0.2"
163164
},
164165
"dependencies": {

src/components/accordion/stories/accordion.stories.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from 'react';
44
import { ICONS } from '@/assets';
55
import { ReplaceContent } from '@/components/storybook/replaceContent/replaceContent';
66
import { TextComponentType } from '@/components/text';
7+
import { ToggleUnControlled } from '@/components/toggle/toggleUnControlled';
78
import { STYLES_NAME } from '@/constants';
89
import { themesObject, variantsObject } from '@/designSystem/themesObject';
910

@@ -40,6 +41,20 @@ export const Accordion: Story = {
4041
subHeaderContent: 'Hi, i am a subheader content',
4142
triggerComponent: TextComponentType.H3,
4243
footerContent: <ReplaceContent />,
44+
headerRightContent: (
45+
<ToggleUnControlled
46+
aria-label="toggle aria label"
47+
inputValues={{
48+
rightInputValue: 'on option',
49+
centerInputValue: 'undeterminated option',
50+
leftInputValue: 'off option',
51+
leftIconAltText: 'on option',
52+
}}
53+
offIcon={{ icon: ICONS.ICON_CHEVRON_UP }}
54+
variant="DEFAULT"
55+
onIcon={{ icon: ICONS.ICON_CHEVRON_DOWN }}
56+
/>
57+
),
4358
themeArgs: themesObject[themeSelected][STYLES_NAME.ACCORDION],
4459
},
4560
};

src/components/actionBottomSheet/actionBottomSheet.styled.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export const ActionBottomSheetHeaderStyled = styled.div<IActionBottomSheetStyles
2525
${props => getStyles(props.styles)}
2626
`;
2727

28+
export const ActionBottomSheetControlStyled = styled.div<IActionBottomSheetStyles>`
29+
${props => getStyles(props.styles)}
30+
`;
31+
32+
export const ActionBottomSheetActionStyled = styled.div<IActionBottomSheetStyles>`
33+
${props => getStyles(props.styles)}
34+
`;
35+
2836
export const ActionBottomSheetIconSyled = styled.div<IActionBottomSheetStyles>`
2937
display: flex;
3038
${props => getStyles(props.styles)}

src/components/actionBottomSheet/actionBottomSheetControlled.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ const ActionBottomSheetControlledStructureComponent = React.forwardRef(
3030
);
3131
const device = useMediaDevice();
3232

33-
const condition = React.useMemo(
33+
const conditional = React.useMemo(
3434
() =>
3535
device !== DeviceBreakpointsType.DESKTOP && device !== DeviceBreakpointsType.LARGE_DESKTOP,
3636
[device]
3737
);
3838

39-
const { scrollableRef, shadowRef } = useScrollEffect(
40-
condition,
41-
styles.header?.[device]?.box_shadow,
42-
SCROLL_DISTANCE
43-
);
39+
const { scrollableRef, shadowRef } = useScrollEffect({
40+
conditional,
41+
shadowStyles: styles.controlContainer?.[device]?.box_shadow,
42+
shadowVisible: SCROLL_DISTANCE,
43+
});
4444

4545
return (
4646
<ActionBottomSheetStandAlone

src/components/actionBottomSheet/actionBottomSheetStandAlone.tsx

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import { ElementOrIcon } from '@/components/elementOrIcon';
44
import { Text } from '@/components/text/text';
55
import { TextComponentType } from '@/components/text/types/component';
66

7+
import { Link } from '../link';
78
import {
9+
ActionBottomSheetActionStyled,
810
ActionBottomSheetContentStyled,
11+
ActionBottomSheetControlStyled,
912
ActionBottomSheetHeaderContentStyled,
1013
ActionBottomSheetHeaderStyled,
1114
ActionBottomSheetIconSyled,
@@ -18,40 +21,60 @@ const ActionBottomSheetStandAloneComponent = (
1821
{ hasHeader = true, scrollableRef, shadowRef, ...props }: IActionBottomSheetStandAlone,
1922
ref: React.ForwardedRef<HTMLDivElement> | undefined | null
2023
): JSX.Element => {
24+
// Parent container Ref
25+
const actionBottomRef = React.useRef<HTMLDivElement | null>(null);
26+
27+
// Expose the ref to the parent component
28+
React.useImperativeHandle(ref, () => {
29+
return actionBottomRef.current as HTMLDivElement;
30+
}, []);
31+
32+
// Set the parent componente ref for the scrollableRef function
33+
React.useEffect(() => {
34+
scrollableRef(actionBottomRef.current);
35+
}, []);
36+
2137
return (
2238
<ActionBottomSheetStyled
23-
ref={ref}
39+
ref={actionBottomRef}
2440
$height={props.height}
2541
data-testid={`${props.dataTestId}Container`}
2642
styles={props.styles.container}
2743
>
2844
{hasHeader && (
29-
<ActionBottomSheetHeaderStyled ref={shadowRef} styles={props.styles.header}>
30-
<ActionBottomSheetIconSyled styles={props.styles.closeIconContainer}>
31-
<ElementOrIcon
32-
customIconStyles={props.styles.closeIcon}
33-
dataTestId={`${props.dataTestId}Icon`}
34-
{...props.closeIcon}
35-
/>
36-
</ActionBottomSheetIconSyled>
37-
<ActionBottomSheetTitleSyled styles={props.styles}>
38-
<Text
39-
component={TextComponentType.H5}
40-
customTypography={props.styles.title}
41-
dataTestId={`${props.dataTestId}Title`}
42-
{...props.title}
43-
>
44-
{props.title?.content}
45-
</Text>
46-
</ActionBottomSheetTitleSyled>
47-
{props.headerContent && (
48-
<ActionBottomSheetHeaderContentStyled styles={props.styles}>
49-
{props.headerContent}
50-
</ActionBottomSheetHeaderContentStyled>
51-
)}
52-
</ActionBottomSheetHeaderStyled>
45+
<>
46+
<ActionBottomSheetControlStyled ref={shadowRef} styles={props.styles.controlContainer}>
47+
<ActionBottomSheetActionStyled styles={props.styles.actionLinkContainer}>
48+
{props.actionLink && <Link {...props.actionLink} />}
49+
</ActionBottomSheetActionStyled>
50+
<ActionBottomSheetIconSyled styles={props.styles.closeIconContainer}>
51+
<ElementOrIcon
52+
customIconStyles={props.styles.closeIcon}
53+
dataTestId={`${props.dataTestId}Icon`}
54+
{...props.closeIcon}
55+
/>
56+
</ActionBottomSheetIconSyled>
57+
</ActionBottomSheetControlStyled>
58+
<ActionBottomSheetHeaderStyled styles={props.styles.header}>
59+
<ActionBottomSheetTitleSyled styles={props.styles}>
60+
<Text
61+
component={TextComponentType.H5}
62+
customTypography={props.styles.title}
63+
dataTestId={`${props.dataTestId}Title`}
64+
{...props.title}
65+
>
66+
{props.title?.content}
67+
</Text>
68+
</ActionBottomSheetTitleSyled>
69+
{props.headerContent && (
70+
<ActionBottomSheetHeaderContentStyled styles={props.styles}>
71+
{props.headerContent}
72+
</ActionBottomSheetHeaderContentStyled>
73+
)}
74+
</ActionBottomSheetHeaderStyled>
75+
</>
5376
)}
54-
<ActionBottomSheetContentStyled ref={scrollableRef} styles={props.styles.content}>
77+
<ActionBottomSheetContentStyled styles={props.styles.content}>
5578
{props.children}
5679
</ActionBottomSheetContentStyled>
5780
</ActionBottomSheetStyled>

src/components/actionBottomSheet/stories/actionBottomSheet.stories.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,16 @@ export const ActionBottomSheet: Story = {
4141
['aria-label']: 'ariaLabelButton',
4242
},
4343
headerContent: <ReplaceContent />,
44-
children: <ReplaceContent />,
44+
children: (
45+
<>
46+
<ReplaceContent />
47+
<ReplaceContent />
48+
<ReplaceContent />
49+
<ReplaceContent />
50+
<ReplaceContent />
51+
<ReplaceContent />
52+
</>
53+
),
4554
open: true,
4655
themeArgs: themesObject[themeSelected][STYLES_NAME.ACTION_BOTTOM_SHEET],
4756
},

src/components/actionBottomSheet/types/actionBottomSheet.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { IElementOrIcon } from '@/components/elementOrIcon';
2+
import { ILink } from '@/components/link';
23
import { IPopoverControlled } from '@/components/popover';
34
import { IText } from '@/components/text';
45
import { CustomTokenTypes, DeviceBreakpointsType } from '@/types';
@@ -21,6 +22,7 @@ export interface IActionBottomSheetStandAlone {
2122
children: React.ReactNode;
2223
styles: ActionBottomSheetVariantStylesType;
2324
closeIcon?: IElementOrIcon;
25+
actionLink?: ILink;
2426
title?: ActionBottomSheetTextType;
2527
hasHeader?: boolean;
2628
dataTestId?: string;

src/components/actionBottomSheet/types/actionBottomSheetTheme.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { CommonStyleType, IconTypes, TypographyTypes } from '@/types';
99
export type ActionBottomSheetVariantStylesType = {
1010
container?: CommonStyleType;
1111
header?: CommonStyleType;
12+
controlContainer?: CommonStyleType;
13+
actionLinkContainer?: CommonStyleType;
1214
closeIconContainer?: CommonStyleType;
1315
closeIcon?: IconTypes;
1416
titleContainer?: CommonStyleType;

src/components/calendar/calendarStandAlone.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,14 @@ const CalendarStandAloneComponent = (
5050
/>
5151
<CalendarSelectorStyled>
5252
{!showMonthSelector && !showYearSelector && showDaySelector && (
53-
<TableStyled role={ROLES.GRID}>
53+
<TableStyled
54+
aria-label={props.currentDate.toLocaleDateString(props.locale, {
55+
timeZone: 'UTC',
56+
month: 'long',
57+
year: 'numeric',
58+
})}
59+
role={ROLES.GRID}
60+
>
5461
<Header
5562
formatWeekDayOption={props.formatWeekDayOption}
5663
isSundayFirst={props.sundayFirst}

src/components/calendar/list/list.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ import { NEUTRAL_DATE } from '@/types';
99
import { WEEK_DAYS } from '../constants/constants';
1010
import {
1111
getAllDaysInMonth,
12-
getAvailableDaysAfterCurrentDate,
13-
getAvailableDaysBeforeCurrentDate,
12+
getDaysAndEmptyDaysUntilMaxDate,
1413
getFirstDayOfMonth,
14+
getFirstEmptyAndDisabledDays,
1515
getStateDay,
1616
groupDaysByWeeks,
17-
handleKeyDownAndRightMove,
17+
handleKeyDownMove,
18+
handleKeyLeftMove,
19+
handleKeyPageDownMove,
20+
handleKeyPageUpMove,
21+
handleKeyRightMove,
1822
handleKeyTabMove,
19-
handleKeyUpAndLeftMove,
23+
handleKeyUpMove,
2024
} from '../utils/';
2125
// styles
2226
import {
@@ -51,18 +55,16 @@ export const List = ({
5155
const [ghostDateSelected, setGhostDateSelected] = React.useState<Date | 0>(0);
5256

5357
const handleKeyMoveConfig = {
54-
emptyDaysList,
5558
dayList,
56-
isAfter: dateHelpers.isAfter,
5759
maxDate: props.maxDate,
5860
currentDate: props.currentDate,
5961
minDate: props.minDate,
60-
availableDaysBeforeCurrentDate: getAvailableDaysBeforeCurrentDate(
62+
firstEmptyAndDisabledDays: getFirstEmptyAndDisabledDays(
6163
emptyDaysList,
6264
props.minDate,
6365
props.currentDate
6466
),
65-
availableDaysAfterCurrentDate: getAvailableDaysAfterCurrentDate(
67+
daysAndEmptyDaysUntilMaxDate: getDaysAndEmptyDaysUntilMaxDate(
6668
emptyDaysList,
6769
props.maxDate,
6870
props.currentDate
@@ -73,11 +75,13 @@ export const List = ({
7375
() => ({
7476
calendarBlankDaysSize: emptyDaysList.length,
7577
size: dayList.length,
76-
keyDownMove: handleKeyDownAndRightMove(handleKeyMoveConfig),
77-
keyUpMove: handleKeyUpAndLeftMove(handleKeyMoveConfig),
78-
keyRightMove: handleKeyDownAndRightMove(handleKeyMoveConfig),
79-
keyLeftMove: handleKeyUpAndLeftMove(handleKeyMoveConfig),
78+
keyDownMove: handleKeyDownMove(handleKeyMoveConfig),
79+
keyUpMove: handleKeyUpMove(handleKeyMoveConfig),
80+
keyRightMove: handleKeyRightMove(handleKeyMoveConfig),
81+
keyLeftMove: handleKeyLeftMove(handleKeyMoveConfig),
8082
keyTabMove: handleKeyTabMove,
83+
keyPageDownMove: handleKeyPageDownMove(handleKeyMoveConfig),
84+
keyPageUpMove: handleKeyPageUpMove(handleKeyMoveConfig),
8185
currentFocusSelected:
8286
(selectedDate[0] ? selectedDate[0].getDate() : new Date().getDate()) +
8387
emptyDaysList.length -

0 commit comments

Comments
 (0)