Skip to content

Commit a9e887b

Browse files
author
Hector Arce De Las Heras
committed
Add custom content feature to FunctionalitiesModule and ListOptions components
This commit introduces a new feature that allows the FunctionalitiesModule and ListOptions components to display custom content. This is achieved by adding a `content` property to these components and their corresponding types. The `content` property is of type `React.ReactNode`, allowing for flexible rendering of custom content. Updates have been made to the corresponding test and story files to reflect this new feature. A new story, `FunctionalitiesModuleWithContent`, has been added to demonstrate the usage of the new feature. These changes enhance the flexibility of the FunctionalitiesModule and ListOptions components, allowing them to be used in a wider range of contexts within the application.
1 parent c323764 commit a9e887b

File tree

8 files changed

+73
-14
lines changed

8 files changed

+73
-14
lines changed

src/components/listOptions/__tests__/listOptions.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const MOCK = {
3131
value: 2,
3232
},
3333
],
34+
content: <div>Content</div>,
3435
onOptionClick: jest.fn(),
3536
};
3637

src/components/listOptions/listOptionsStandAlone.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export const ListOptionsStandAlone = React.forwardRef(
6565
</Text>
6666
</TitleWrapperStyled>
6767
)}
68+
{props.content}
6869
<OptionsWrapperStyled
6970
ref={listEl as React.RefObject<HTMLUListElement>}
7071
as={'ul'}
@@ -73,7 +74,12 @@ export const ListOptionsStandAlone = React.forwardRef(
7374
styles={props.styles}
7475
>
7576
{props.options.map((option, index) => {
76-
const selected = isSelected(option, props.selectedValue, props.multiSelect);
77+
const selected = isSelected(
78+
option,
79+
props.selectedValue,
80+
props.multiSelect,
81+
props.caseSensitive
82+
);
7783
const optionComponent = (
7884
<Option
7985
key={`${id}Option${index}`}

src/components/listOptions/stories/argtypes.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ export const argtypes = (variants: IThemeObjectVariants, themeSelected: string):
6262
category: CATEGORY_CONTROL.MODIFIERS,
6363
},
6464
},
65+
content: {
66+
description: 'Content to show before the options',
67+
type: { name: 'string' },
68+
control: { type: 'text' },
69+
table: {
70+
type: {
71+
summary: 'React.ReactNode',
72+
},
73+
category: CATEGORY_CONTROL.CONTENT,
74+
},
75+
},
6576
options: {
6677
description: 'List of options',
6778
type: { name: 'array', required: true },
@@ -188,5 +199,16 @@ export const argtypes = (variants: IThemeObjectVariants, themeSelected: string):
188199
category: CATEGORY_CONTROL.CUSTOMIZATION,
189200
},
190201
},
202+
caseSensitive: {
203+
description: 'Indicates if the search is case sensitive',
204+
control: { type: 'boolean' },
205+
type: { name: 'boolean' },
206+
table: {
207+
type: {
208+
summary: 'boolean',
209+
},
210+
category: CATEGORY_CONTROL.MODIFIERS,
211+
},
212+
},
191213
};
192214
};

src/components/listOptions/types/listOptions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ export interface IListOptionsStandAlone {
2525
styles: ListOptionsPropsStylesType;
2626
type?: ListOptionsType;
2727
options: ListOptionsOptionType[];
28+
caseSensitive?: boolean;
2829
charsHighlighted?: string;
2930
selectedValue?: string | number | string[] | number[] | null;
3031
title?: ListOptionsTitleType;
32+
content?: React.ReactNode;
3133
onOptionClick?: (
3234
value,
3335
event: React.KeyboardEvent<HTMLDivElement> | React.MouseEvent<HTMLDivElement>

src/components/listOptions/utils/listOptions.utils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@ import { ListOptionsOptionType } from '../types';
33
export const isSelected = (
44
option: ListOptionsOptionType,
55
selectedValue?: string | number | (string | number)[] | null,
6-
isMultiSelect?: boolean
6+
isMultiSelect?: boolean,
7+
caseSensitive?: boolean
78
): boolean => {
89
if (selectedValue !== null && selectedValue !== undefined && option.value !== undefined) {
910
if (isMultiSelect) {
1011
return Boolean(Array.isArray(selectedValue) && selectedValue.includes(option.value));
1112
}
12-
return Boolean(selectedValue === option.value);
13+
if (caseSensitive) {
14+
return Boolean(selectedValue === option.value);
15+
}
16+
return Boolean(
17+
selectedValue.toLocaleString().toLocaleLowerCase() ===
18+
option.value.toLocaleString().toLocaleLowerCase()
19+
);
1320
}
1421
return false;
1522
};

src/components/oliveMenu/oliveMenu.styled.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export const OliveMenuStyled = styled.div<OliveMenuStylesProps>`
1414

1515
export const ButtonContainer = styled.div<OliveMenuStylesProps>`
1616
${({ styles }) => getStyles(styles.buttonContainer)};
17+
> button {
18+
${({ styles }) => getStyles(styles.button)};
19+
}
1720
`;
1821

1922
export const ListboxStyled = styled.div<OliveMenuStylesProps>`

src/components/oliveMenu/types/oliveMenuTheme.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CommonStyleType, DeviceBreakpointsType, POSITIONS } from '@/types';
33
export type OliveMenuGlobalStylesType = {
44
container?: CommonStyleType;
55
buttonContainer?: CommonStyleType;
6-
button?: {
6+
button?: CommonStyleType & {
77
[key in DeviceBreakpointsType]?: {
88
size?: string;
99
};

src/components/popover/popoverControlled.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useScrollBlock } from '@/hooks/useScrollBlock/useScrollBlock';
99
import { useStyles } from '@/hooks/useStyles/useStyles';
1010
import { ErrorBoundary, FallbackComponent } from '@/provider/errorBoundary';
1111
import { focusFirstDescendant, trapFocus } from '@/utils';
12+
import { convertDurationToNumber } from '@/utils/stringUtility/string.utility';
1213

1314
import { PopoverStandAlone } from './popoverStandAlone';
1415
import { PopoverComponentType, PopoverVariantStylesType } from './types';
@@ -146,18 +147,35 @@ const PopoverControlledComponent = React.forwardRef(
146147
}
147148
}, [props.open]);
148149

150+
// deprecated - Remove the condition when `exitDuration`, `duration` and `delay' are type string
151+
const animationExitDuration = () => {
152+
if (
153+
typeof animationConfig?.animationOptions?.exitDuration === 'string' ||
154+
typeof animationConfig?.animationOptions?.duration === 'string' ||
155+
typeof animationConfig?.animationOptions?.delay === 'string'
156+
) {
157+
const exitDuration = convertDurationToNumber(
158+
animationConfig?.animationOptions?.exitDuration
159+
);
160+
const duration = convertDurationToNumber(animationConfig?.animationOptions?.duration);
161+
const delay = convertDurationToNumber(animationConfig?.animationOptions?.delay);
162+
163+
return (exitDuration || duration || 0) + (delay || 0);
164+
}
165+
return (
166+
((animationConfig?.animationOptions?.exitDuration ||
167+
animationConfig?.animationOptions?.duration ||
168+
0) +
169+
(animationConfig?.animationOptions?.delay || 0)) *
170+
MILISECONDS
171+
);
172+
};
173+
149174
const waitForAnimation = () => {
150175
return new Promise<void>(resolve => {
151-
setTimeout(
152-
() => {
153-
resolve();
154-
},
155-
((animationConfig.animationOptions?.exitDuration ||
156-
animationConfig.animationOptions?.duration ||
157-
0) +
158-
(animationConfig.animationOptions?.delay || 0)) *
159-
MILISECONDS
160-
);
176+
setTimeout(() => {
177+
resolve();
178+
}, animationExitDuration());
161179
});
162180
};
163181

0 commit comments

Comments
 (0)