@cleartrip/ct-design-single-select-chip 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,137 @@
1
+ import React, { forwardRef, memo, useState } from 'react';
2
+
3
+ import { Chip } from '@cleartrip/ct-design-chip';
4
+ import { Box } from '@cleartrip/ct-design-box';
5
+ import { Container, ContainerRef } from '@cleartrip/ct-design-container';
6
+ import { Typography } from '@cleartrip/ct-design-typography';
7
+ import { useStyles } from '@cleartrip/ct-design-style-manager';
8
+ import useIsomorphicEffect from '@cleartrip/ct-design-use-isomorphic-effect';
9
+
10
+ import { ISingleSelectProps, SingleChipProps } from './type';
11
+ import { ChipOrientation } from './constants';
12
+ import { singleSelectChipStaticStyles } from './style';
13
+
14
+ interface ChipAtomsProps {
15
+ data: SingleChipProps[];
16
+ selectedChip: string | null;
17
+ onClickCb: (chip: SingleChipProps) => () => void;
18
+ chipStyleConfig?: ISingleSelectProps['styleConfig'] extends infer T
19
+ ? T extends { chip?: infer C }
20
+ ? C
21
+ : never
22
+ : never;
23
+ }
24
+
25
+ const ChipAtoms = memo(({ data, selectedChip, onClickCb, chipStyleConfig }: ChipAtomsProps) => {
26
+ return (
27
+ <>
28
+ {data.map((item) => {
29
+ const isSelected = item?.id === selectedChip;
30
+
31
+ return (
32
+ <Chip
33
+ key={item?.id}
34
+ id={item?.id}
35
+ label={item?.label}
36
+ onClick={onClickCb(item)}
37
+ size='sm'
38
+ isSelected={isSelected}
39
+ styleConfig={{
40
+ labelContainer: [singleSelectChipStaticStyles.chipLabelStyles],
41
+ root: [singleSelectChipStaticStyles.chipRootStyles, singleSelectChipStaticStyles.chipBoxShadow],
42
+ ...(chipStyleConfig || {}),
43
+ }}
44
+ />
45
+ );
46
+ })}
47
+ </>
48
+ );
49
+ });
50
+
51
+ ChipAtoms.displayName = 'ChipAtoms';
52
+
53
+ const SingleSelectChip = forwardRef<ContainerRef, ISingleSelectProps>(
54
+ ({ onChange, data, orientation = ChipOrientation.row, selected = null, prompt, styleConfig = {} }, ref) => {
55
+ const { hasError = false, Icon: promptIcon, message: promptMessage } = prompt || {};
56
+
57
+ const {
58
+ root: customRootStyles = [],
59
+ chipContainer: chipContainerStyles = [],
60
+ promptBox: promptBoxStyles = [],
61
+ promptIconContainer: promptIconContainerStyles = [],
62
+ promptMessageTypography: promptMessageTypographyStyles,
63
+ chip: chipStyleConfig,
64
+ } = styleConfig;
65
+
66
+ const [selectedChip, setSelectedChip] = useState<string | null>(selected ?? null);
67
+
68
+ useIsomorphicEffect(() => {
69
+ if ((selected ?? null) !== selectedChip) {
70
+ setSelectedChip(selected ?? null);
71
+ }
72
+ }, [selected]);
73
+
74
+ const onClickCb = (chip: SingleChipProps) => () => {
75
+ const { id } = chip ?? {};
76
+
77
+ if (selectedChip !== id) {
78
+ setSelectedChip(id);
79
+ onChange?.(id);
80
+ }
81
+ };
82
+
83
+ const dynamicStyles = useStyles(
84
+ () => ({
85
+ chipWrapper: {
86
+ flexDirection: orientation === ChipOrientation.row ? 'row' : 'column',
87
+ },
88
+ }),
89
+ [orientation],
90
+ );
91
+
92
+ return (
93
+ <Container ref={ref} styleConfig={{ root: [...(customRootStyles || [])] }}>
94
+ <Container
95
+ styleConfig={{
96
+ root: [singleSelectChipStaticStyles.chipWrapper, dynamicStyles.chipWrapper, ...chipContainerStyles],
97
+ }}
98
+ >
99
+ <ChipAtoms data={data} selectedChip={selectedChip} onClickCb={onClickCb} chipStyleConfig={chipStyleConfig} />
100
+ </Container>
101
+
102
+ {(promptIcon || promptMessage) && (
103
+ <Box
104
+ boxSize='pico'
105
+ horizontal
106
+ styleConfig={{
107
+ root: [singleSelectChipStaticStyles.promptBoxStyles, ...(promptBoxStyles || [])],
108
+ }}
109
+ >
110
+ {promptIcon && (
111
+ <Container
112
+ styleConfig={{
113
+ root: [singleSelectChipStaticStyles.promptIconStyles, ...promptIconContainerStyles],
114
+ }}
115
+ >
116
+ {promptIcon}
117
+ </Container>
118
+ )}
119
+ {promptMessage && (
120
+ <Typography
121
+ variant='B3'
122
+ color={hasError ? 'warning' : 'success'}
123
+ styleConfig={promptMessageTypographyStyles}
124
+ >
125
+ {promptMessage}
126
+ </Typography>
127
+ )}
128
+ </Box>
129
+ )}
130
+ </Container>
131
+ );
132
+ },
133
+ );
134
+
135
+ SingleSelectChip.displayName = 'SingleSelectChip';
136
+
137
+ export default memo(SingleSelectChip);
@@ -0,0 +1,4 @@
1
+ export enum ChipOrientation {
2
+ row = 'row',
3
+ column = 'column',
4
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { default as SingleSelectChip } from './SingleSelectChip';
2
+ export type * from './type';
3
+ export * from './constants';
package/src/style.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { makeStyles } from '@cleartrip/ct-design-style-manager';
2
+
3
+ export const singleSelectChipStaticStyles = makeStyles((theme) => {
4
+ return {
5
+ chipWrapper: {
6
+ display: 'flex',
7
+ position: 'relative',
8
+ alignItems: 'center',
9
+ flexWrap: 'wrap',
10
+ borderRadius: theme.border.radius[8],
11
+ alignSelf: 'flex-start',
12
+ rowGap: theme.spacing[3],
13
+ columnGap: theme.spacing[3],
14
+ },
15
+ promptBoxStyles: {
16
+ display: 'flex',
17
+ alignItems: 'center',
18
+ marginTop: theme.spacing[2],
19
+ marginLeft: theme.spacing[3],
20
+ },
21
+ promptIconStyles: {
22
+ display: 'flex',
23
+ justifyContent: 'center',
24
+ alignItems: 'center',
25
+ height: theme.size[4],
26
+ width: theme.size[4],
27
+ paddingRight: theme.spacing[1],
28
+ },
29
+ chipLabelStyles: {
30
+ paddingVertical: 0,
31
+ paddingHorizontal: 4,
32
+ },
33
+ chipRootStyles: {
34
+ borderRadius: 30,
35
+ paddingVertical: theme.spacing['1.5'],
36
+ paddingHorizontal: theme.spacing[2],
37
+ borderWidth: 0,
38
+ },
39
+ chipBoxShadow: {
40
+ shadowColor: 'rgb(231, 231, 231)',
41
+ shadowOffset: { width: 0, height: 0 },
42
+ shadowOpacity: 1,
43
+ shadowRadius: 1,
44
+ elevation: 1,
45
+ borderWidth: 1,
46
+ },
47
+ };
48
+ });
package/src/type.ts ADDED
@@ -0,0 +1,51 @@
1
+ import type { IFieldPrompt, Styles } from '@cleartrip/ct-design-types';
2
+ import { TypographyStyleConfigProps } from '@cleartrip/ct-design-typography';
3
+ import type { IChipProps, IChipStyleConfig } from '@cleartrip/ct-design-chip';
4
+ import { ChipOrientation } from './constants';
5
+ /**
6
+ * Props for a single chip in the SingleSelectChip component.
7
+ * Extends IChipProps but removes onClick, onDismiss, and isSelected properties
8
+ * since those are controlled by the parent SingleSelectChip.
9
+ */
10
+ export type SingleChipProps = Omit<IChipProps, 'onClick' | 'onDismiss' | 'isSelected'> & {
11
+ /** Unique identifier for the chip */
12
+ id: string;
13
+ };
14
+
15
+ export type ChipOrientationType = `${ChipOrientation}`;
16
+
17
+ /**
18
+ * Style configuration props for SingleSelectChip component.
19
+ */
20
+ export interface ISingleSelectStyleProps {
21
+ /** Styles for the root container */
22
+ root?: Styles[];
23
+ /** Styles for the chip container */
24
+ chipContainer?: Styles[];
25
+ /** Styles for the prompt box */
26
+ promptBox?: Styles[];
27
+ /** Styles for the prompt icon container */
28
+ promptIconContainer?: Styles[];
29
+ /** Styles for the prompt message text */
30
+ promptMessageTypography?: TypographyStyleConfigProps;
31
+ /** Styles for individual chips */
32
+ chip?: IChipStyleConfig;
33
+ }
34
+
35
+ /**
36
+ * Props for the SingleSelectChip component.
37
+ */
38
+ export interface ISingleSelectProps {
39
+ /** Array of chip data to be displayed */
40
+ data: SingleChipProps[];
41
+ /** Orientation of the chips - either row or column */
42
+ orientation?: ChipOrientationType;
43
+ /** Callback function called when selection changes */
44
+ onChange: (selected: string) => void;
45
+ /** Currently selected chip ID */
46
+ selected?: string | null;
47
+ /** Prompt configuration for the input field */
48
+ prompt?: IFieldPrompt;
49
+ /** Custom styling configuration for the component */
50
+ styleConfig?: ISingleSelectStyleProps;
51
+ }