@cleartrip/ct-design-checkbox 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,127 @@
1
+ import { forwardRef, MouseEvent } from 'react';
2
+
3
+ import { Container } from '@cleartrip/ct-design-container';
4
+ import { Typography, TypographyVariant } from '@cleartrip/ct-design-typography';
5
+ import { CheckboxTick } from '@cleartrip/ct-design-icons';
6
+ import { makeStyles, useStyles, useWebMergeStyles } from '@cleartrip/ct-design-style-manager';
7
+
8
+ import { getBorderStyles, getLabelColor } from './style';
9
+ import { ICheckbox } from './type';
10
+ import { css } from '@emotion/css';
11
+
12
+ const webStaticStyles = {
13
+ disabledRoot: css({
14
+ cursor: 'not-allowed',
15
+ }),
16
+ };
17
+ const staticCheckboxStyles = makeStyles((theme) => ({
18
+ root: {
19
+ display: 'flex',
20
+ flexDirection: 'row',
21
+ alignItems: 'center',
22
+ gap: theme?.spacing[2],
23
+ cursor: 'pointer',
24
+ userSelect: 'none',
25
+ },
26
+ hiddenInput: {
27
+ position: 'absolute',
28
+ opacity: 0,
29
+ width: 0,
30
+ height: 0,
31
+ margin: 0,
32
+ padding: 0,
33
+ border: 'none',
34
+ pointerEvents: 'none',
35
+ },
36
+ checkboxIconContainer: {
37
+ width: theme?.spacing[5],
38
+ height: theme?.spacing[5],
39
+ borderRadius: theme?.border.radius[4],
40
+ borderStyle: theme?.border.style.solid,
41
+ display: 'flex',
42
+ alignItems: 'center',
43
+ justifyContent: 'center',
44
+ },
45
+ }));
46
+
47
+ const Checkbox = forwardRef<HTMLInputElement, ICheckbox>(
48
+ (
49
+ { id, label, disabled = false, onChange, checked = false, styleConfig, isFullClickEnabled = true, rootProps = {} },
50
+ ref,
51
+ ) => {
52
+ const dynamicStyles = useStyles(
53
+ (theme) => ({
54
+ checkboxIconContainer: getBorderStyles(theme, checked, disabled),
55
+ label: {
56
+ color: getLabelColor(disabled),
57
+ },
58
+ }),
59
+ [checked, disabled],
60
+ );
61
+
62
+ const {
63
+ root: customRootStyles = [],
64
+ checkboxIconContainer: customCheckboxIconStyles = [],
65
+ labelContainer: customLabelContainerStyles = [],
66
+ } = styleConfig || {};
67
+
68
+ const handleCheckboxChange = () => {
69
+ if (disabled) return;
70
+ onChange?.({ id, label, disabled, checked: !checked });
71
+ };
72
+
73
+ const handleRootClick = () => {
74
+ if (disabled || !isFullClickEnabled) return;
75
+ handleCheckboxChange();
76
+ };
77
+
78
+ const handleIconClick = (event: MouseEvent<HTMLSpanElement>) => {
79
+ if (isFullClickEnabled) return;
80
+ event.stopPropagation();
81
+ handleCheckboxChange();
82
+ };
83
+
84
+ const mergedRootClassName = useWebMergeStyles(
85
+ [staticCheckboxStyles.root, ...(disabled ? [webStaticStyles.disabledRoot] : []), ...customRootStyles],
86
+ [disabled, customRootStyles],
87
+ );
88
+
89
+ const mergedInputClassName = useWebMergeStyles([staticCheckboxStyles.hiddenInput], []);
90
+
91
+ const mergedCheckboxIconClassName = useWebMergeStyles(
92
+ [staticCheckboxStyles.checkboxIconContainer, dynamicStyles.checkboxIconContainer, ...customCheckboxIconStyles],
93
+ [dynamicStyles.checkboxIconContainer, customCheckboxIconStyles],
94
+ );
95
+
96
+ return (
97
+ <div id={`${id}-root`} className={mergedRootClassName} onClick={handleRootClick} {...rootProps}>
98
+ <input
99
+ ref={ref}
100
+ id={id}
101
+ type='checkbox'
102
+ checked={checked}
103
+ disabled={disabled}
104
+ onChange={handleCheckboxChange}
105
+ className={mergedInputClassName}
106
+ aria-labelledby={`${id}-label`}
107
+ />
108
+ <span className={mergedCheckboxIconClassName} onClick={handleIconClick}>
109
+ {checked && <CheckboxTick />}
110
+ </span>
111
+ <Container styleConfig={{ root: customLabelContainerStyles }}>
112
+ {typeof label === 'string' ? (
113
+ <Typography variant={TypographyVariant.P2} styleConfig={{ root: [dynamicStyles.label] }}>
114
+ {label}
115
+ </Typography>
116
+ ) : (
117
+ label
118
+ )}
119
+ </Container>
120
+ </div>
121
+ );
122
+ },
123
+ );
124
+
125
+ Checkbox.displayName = 'Checkbox';
126
+
127
+ export default Checkbox;
@@ -0,0 +1,2 @@
1
+ export { default as Checkbox } from './Checkbox.native';
2
+ export type * from './type';
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default as Checkbox } from './Checkbox';
2
+ export type * from './type';
package/src/style.ts ADDED
@@ -0,0 +1,54 @@
1
+ import type { Theme } from '@cleartrip/ct-design-theme';
2
+ import { TypographyColor, TypographyColorType } from '@cleartrip/ct-design-typography';
3
+
4
+ type CheckboxStyle = {
5
+ borderWidth: number;
6
+ borderColor?: string;
7
+ backgroundColor: string;
8
+ };
9
+
10
+ export const getBorderStyles = (theme: Theme, isSelected: boolean, isDisabled: boolean): CheckboxStyle => {
11
+ switch (true) {
12
+ case isDisabled: {
13
+ if (isSelected) {
14
+ return {
15
+ borderWidth: theme.border.width.none,
16
+ backgroundColor: theme.color.background.disabledSecondary,
17
+ // @ts-ignore web only property
18
+ cursor: 'not-allowed',
19
+ };
20
+ }
21
+ return {
22
+ borderWidth: theme.border.width.sm,
23
+ borderColor: theme.color.border.disabled,
24
+ // @ts-ignore web only property
25
+ cursor: 'not-allowed',
26
+ backgroundColor: theme.color.background.disabled,
27
+ };
28
+ }
29
+ case isSelected: {
30
+ return {
31
+ borderWidth: theme.border.width.none,
32
+ backgroundColor: theme.color.background.primary,
33
+ // @ts-ignore web only property
34
+ cursor: 'pointer',
35
+ };
36
+ }
37
+ default: {
38
+ return {
39
+ borderWidth: theme.border.width.sm,
40
+ borderColor: theme.color.border.defaultDark,
41
+ backgroundColor: theme.color.background.neutral,
42
+ // @ts-ignore web only property
43
+ cursor: 'pointer',
44
+ };
45
+ }
46
+ }
47
+ };
48
+
49
+ export const getLabelColor = (isDisabled: boolean): TypographyColorType => {
50
+ if (isDisabled) {
51
+ return TypographyColor.DISABLED;
52
+ }
53
+ return TypographyColor.PRIMARY;
54
+ };
package/src/type.ts ADDED
@@ -0,0 +1,58 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import type { Styles } from '@cleartrip/ct-design-types';
4
+
5
+ /**
6
+ * Represents a single option consumable by Checkbox / CheckboxGroup.
7
+ */
8
+ export interface ICheckboxOption {
9
+ /** Unique identifier for the checkbox option */
10
+ id: string;
11
+ /** Whether the checkbox is disabled */
12
+ disabled?: boolean;
13
+ /** Whether the checkbox is checked/selected */
14
+ checked?: boolean;
15
+ /** Label content to display next to the checkbox (can be string or React node) */
16
+ label?: ReactNode | string;
17
+ }
18
+
19
+ /**
20
+ * Interface for Checkbox component props
21
+ */
22
+ export interface ICheckbox {
23
+ /** Unique identifier for the checkbox */
24
+ id: string;
25
+
26
+ /** Whether the checkbox is disabled */
27
+ disabled?: boolean;
28
+
29
+ /** Label content to display next to the checkbox */
30
+ label?: ReactNode | string;
31
+
32
+ /** Current checked state of the checkbox */
33
+ checked: boolean;
34
+
35
+ /** Callback function when checkbox state changes */
36
+ onChange?: (checkboxOption: ICheckboxOption) => void;
37
+
38
+ /** Optional styling configuration for different parts of the checkbox */
39
+ styleConfig?: {
40
+ /** Styles for the root container */
41
+ root?: Styles[];
42
+ /** Styles for the checkbox icon container */
43
+ checkboxIconContainer?: Styles[];
44
+ /** Styles for the label container */
45
+ labelContainer?: Styles[];
46
+ };
47
+
48
+ /** Whether the entire checkbox area is clickable */
49
+ isFullClickEnabled?: boolean;
50
+
51
+ /** Additional props forwarded to the root element */
52
+ rootProps?: Record<string, unknown>;
53
+ }
54
+
55
+ /**
56
+ * @deprecated Use `ICheckbox` instead — kept as an alias for backward type compatibility.
57
+ */
58
+ export type CheckboxProps = ICheckbox;