@justin_evo/evo-ui 1.2.0 → 1.2.1

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.
Files changed (77) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +70 -70
  3. package/dist/declarations.d.ts +6 -6
  4. package/package.json +52 -52
  5. package/src/Alert/Alert.tsx +49 -49
  6. package/src/AutoComplete/AutoComplete.tsx +810 -810
  7. package/src/Badge/Badge.tsx +53 -53
  8. package/src/Breadcrumb/Breadcrumb.tsx +53 -53
  9. package/src/Button/Button.tsx +125 -125
  10. package/src/Card/Card.tsx +257 -257
  11. package/src/Checkbox/Checkbox.tsx +59 -59
  12. package/src/CommandPalette/CommandPalette.tsx +185 -185
  13. package/src/Container/Container.tsx +31 -31
  14. package/src/Divider/Divider.tsx +31 -31
  15. package/src/Form/Form.tsx +185 -185
  16. package/src/Grid/Grid.tsx +66 -66
  17. package/src/ImageCropper/ImageCropper.tsx +911 -911
  18. package/src/Input/Input.tsx +74 -74
  19. package/src/Modal/Modal.tsx +77 -77
  20. package/src/Nav/Nav.tsx +708 -708
  21. package/src/Notification/Notification.tsx +1503 -1503
  22. package/src/Pagination/Pagination.tsx +76 -76
  23. package/src/Radio/Radio.tsx +69 -69
  24. package/src/RichTextArea/RichTextArea.tsx +886 -886
  25. package/src/Select/Select.tsx +515 -515
  26. package/src/Skeleton/Skeleton.tsx +70 -70
  27. package/src/Stack/Stack.tsx +52 -52
  28. package/src/Table/Table.tsx +335 -335
  29. package/src/Tabs/Tabs.tsx +90 -90
  30. package/src/Theme/ThemeProvider.tsx +253 -253
  31. package/src/Theme/ThemeToggle.tsx +79 -79
  32. package/src/Toggle/Toggle.tsx +48 -48
  33. package/src/Tooltip/Tooltip.tsx +38 -38
  34. package/src/TopNav/TopNav.tsx +1163 -1163
  35. package/src/TreeSelect/TreeSelect.tsx +825 -825
  36. package/src/css/alert.module.scss +93 -93
  37. package/src/css/autocomplete.module.scss +416 -416
  38. package/src/css/badge.module.scss +82 -82
  39. package/src/css/base/_color.scss +159 -159
  40. package/src/css/base/_theme.scss +237 -237
  41. package/src/css/base/_variables.scss +161 -161
  42. package/src/css/breadcrumb.module.scss +50 -50
  43. package/src/css/button.module.scss +385 -385
  44. package/src/css/card.module.scss +217 -217
  45. package/src/css/checkbox.module.scss +123 -123
  46. package/src/css/commandpalette.module.scss +211 -211
  47. package/src/css/container.module.scss +18 -18
  48. package/src/css/divider.module.scss +41 -41
  49. package/src/css/form.module.scss +245 -245
  50. package/src/css/imagecropper.module.scss +397 -397
  51. package/src/css/input.module.scss +89 -89
  52. package/src/css/modal.module.scss +105 -105
  53. package/src/css/nav.module.scss +494 -494
  54. package/src/css/notification.module.scss +691 -691
  55. package/src/css/pagination.module.scss +63 -63
  56. package/src/css/radio.module.scss +89 -89
  57. package/src/css/richtextarea.module.scss +307 -307
  58. package/src/css/select.module.scss +525 -525
  59. package/src/css/skeleton.module.scss +30 -30
  60. package/src/css/table.module.scss +386 -386
  61. package/src/css/tabs.module.scss +63 -63
  62. package/src/css/theme-toggle.module.scss +83 -83
  63. package/src/css/toggle.module.scss +54 -54
  64. package/src/css/tooltip.module.scss +97 -97
  65. package/src/css/topnav.module.scss +568 -568
  66. package/src/css/treeselect.module.scss +558 -558
  67. package/src/css/utilities/_borders.scss +111 -111
  68. package/src/css/utilities/_colors.scss +66 -66
  69. package/src/css/utilities/_effects.scss +216 -216
  70. package/src/css/utilities/_layout.scss +181 -181
  71. package/src/css/utilities/_position.scss +75 -75
  72. package/src/css/utilities/_sizing.scss +138 -138
  73. package/src/css/utilities/_spacing.scss +99 -99
  74. package/src/css/utilities/_typography.scss +121 -121
  75. package/src/css/utilities/index.scss +24 -24
  76. package/src/declarations.d.ts +6 -6
  77. package/src/index.ts +60 -60
package/src/Card/Card.tsx CHANGED
@@ -1,257 +1,257 @@
1
- import {
2
- forwardRef,
3
- createElement,
4
- type AnchorHTMLAttributes,
5
- type ButtonHTMLAttributes,
6
- type CSSProperties,
7
- type HTMLAttributes,
8
- type ReactNode,
9
- type Ref,
10
- } from 'react';
11
- import styles from '../css/card.module.scss';
12
-
13
- // ============================================================
14
- // EvoCard
15
- // ------------------------------------------------------------
16
- // Compose-based card primitive. The API takes after Radix:
17
- // <EvoCard.Root> is the documented surface; <EvoCard> is kept
18
- // as an ergonomic alias that forwards to Root.
19
- //
20
- // Visual axes are deliberately minimal — three structural
21
- // variants (elevated / outlined / ghost). All colour comes
22
- // from semantic theme tokens, so dark mode is automatic.
23
- //
24
- // When `interactive` is set the root is rendered as a real
25
- // <button type="button"> or, if `href` is provided, a real
26
- // <a>. We never use <div onClick> — keyboard users and screen
27
- // readers get first-class treatment.
28
- // ============================================================
29
-
30
- export type EvoCardVariant = 'elevated' | 'outlined' | 'ghost';
31
- export type EvoCardOrientation = 'vertical' | 'horizontal' | 'responsive';
32
- export type EvoCardHeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
33
-
34
- interface EvoCardRootBase {
35
- variant?: EvoCardVariant;
36
- orientation?: EvoCardOrientation;
37
- children: ReactNode;
38
- }
39
-
40
- interface EvoCardRootStaticProps
41
- extends EvoCardRootBase,
42
- Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
43
- interactive?: false;
44
- href?: never;
45
- }
46
-
47
- interface EvoCardRootButtonProps
48
- extends EvoCardRootBase,
49
- Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'type'> {
50
- interactive: true;
51
- href?: never;
52
- /** @default 'button' (never auto-submits) */
53
- type?: 'button' | 'submit' | 'reset';
54
- }
55
-
56
- interface EvoCardRootAnchorProps
57
- extends EvoCardRootBase,
58
- Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'children' | 'href'> {
59
- interactive: true;
60
- href: string;
61
- }
62
-
63
- export type EvoCardRootProps =
64
- | EvoCardRootStaticProps
65
- | EvoCardRootButtonProps
66
- | EvoCardRootAnchorProps;
67
-
68
- function cx(...parts: Array<string | undefined | false | null>) {
69
- return parts.filter(Boolean).join(' ');
70
- }
71
-
72
- function rootClasses(
73
- variant: EvoCardVariant,
74
- orientation: EvoCardOrientation,
75
- interactive: boolean,
76
- className?: string,
77
- ) {
78
- return cx(
79
- styles.root,
80
- styles[variant],
81
- styles[`orient-${orientation}`],
82
- interactive && styles.interactive,
83
- className,
84
- );
85
- }
86
-
87
- export const EvoCardRoot = forwardRef<HTMLElement, EvoCardRootProps>(
88
- function EvoCardRoot(props, ref) {
89
- const {
90
- variant = 'elevated',
91
- orientation = 'vertical',
92
- interactive,
93
- className,
94
- children,
95
- ...rest
96
- } = props as EvoCardRootStaticProps &
97
- Partial<EvoCardRootAnchorProps> &
98
- Partial<EvoCardRootButtonProps> & { interactive?: boolean };
99
-
100
- const isInteractive = interactive === true;
101
- const classes = rootClasses(variant, orientation, isInteractive, className);
102
-
103
- if (isInteractive && typeof (rest as { href?: string }).href === 'string') {
104
- const anchorRest = rest as AnchorHTMLAttributes<HTMLAnchorElement>;
105
- return (
106
- <a ref={ref as Ref<HTMLAnchorElement>} className={classes} {...anchorRest}>
107
- {children}
108
- </a>
109
- );
110
- }
111
-
112
- if (isInteractive) {
113
- const { type = 'button', ...buttonRest } =
114
- rest as ButtonHTMLAttributes<HTMLButtonElement>;
115
- return (
116
- <button
117
- ref={ref as Ref<HTMLButtonElement>}
118
- type={type}
119
- className={classes}
120
- {...buttonRest}
121
- >
122
- {children}
123
- </button>
124
- );
125
- }
126
-
127
- return (
128
- <div
129
- ref={ref as Ref<HTMLDivElement>}
130
- className={classes}
131
- {...(rest as HTMLAttributes<HTMLDivElement>)}
132
- >
133
- {children}
134
- </div>
135
- );
136
- },
137
- );
138
- EvoCardRoot.displayName = 'EvoCardRoot';
139
-
140
- // ----- Section slots -----
141
-
142
- export type EvoCardHeaderProps = HTMLAttributes<HTMLDivElement>;
143
- export type EvoCardBodyProps = HTMLAttributes<HTMLDivElement>;
144
- export type EvoCardFooterProps = HTMLAttributes<HTMLDivElement>;
145
-
146
- export const EvoCardHeader = forwardRef<HTMLDivElement, EvoCardHeaderProps>(
147
- function EvoCardHeader({ className, ...rest }, ref) {
148
- return <div ref={ref} className={cx(styles.header, className)} {...rest} />;
149
- },
150
- );
151
- EvoCardHeader.displayName = 'EvoCardHeader';
152
-
153
- export const EvoCardBody = forwardRef<HTMLDivElement, EvoCardBodyProps>(
154
- function EvoCardBody({ className, ...rest }, ref) {
155
- return <div ref={ref} className={cx(styles.body, className)} {...rest} />;
156
- },
157
- );
158
- EvoCardBody.displayName = 'EvoCardBody';
159
-
160
- export const EvoCardFooter = forwardRef<HTMLDivElement, EvoCardFooterProps>(
161
- function EvoCardFooter({ className, ...rest }, ref) {
162
- return <div ref={ref} className={cx(styles.footer, className)} {...rest} />;
163
- },
164
- );
165
- EvoCardFooter.displayName = 'EvoCardFooter';
166
-
167
- // ----- Title (configurable heading level) -----
168
-
169
- export interface EvoCardTitleProps extends HTMLAttributes<HTMLHeadingElement> {
170
- /** Semantic level. Visual size is fixed by the stylesheet. @default 'h3' */
171
- as?: EvoCardHeadingLevel;
172
- children: ReactNode;
173
- }
174
-
175
- export const EvoCardTitle = forwardRef<HTMLHeadingElement, EvoCardTitleProps>(
176
- function EvoCardTitle({ as = 'h3', className, children, ...rest }, ref) {
177
- return createElement(
178
- as,
179
- { ref, className: cx(styles.title, className), ...rest },
180
- children,
181
- );
182
- },
183
- );
184
- EvoCardTitle.displayName = 'EvoCardTitle';
185
-
186
- // ----- Description -----
187
-
188
- export type EvoCardDescriptionProps = HTMLAttributes<HTMLParagraphElement>;
189
-
190
- export const EvoCardDescription = forwardRef<
191
- HTMLParagraphElement,
192
- EvoCardDescriptionProps
193
- >(function EvoCardDescription({ className, ...rest }, ref) {
194
- return <p ref={ref} className={cx(styles.description, className)} {...rest} />;
195
- });
196
- EvoCardDescription.displayName = 'EvoCardDescription';
197
-
198
- // ----- Media -----
199
-
200
- export interface EvoCardMediaProps extends HTMLAttributes<HTMLDivElement> {
201
- /** Convenience: renders an <img>. Omit and pass children for custom media. */
202
- src?: string;
203
- /** Required when `src` is set. Empty string marks the image as decorative. */
204
- alt?: string;
205
- /** e.g. 16/9 or '4/3'. Applied when no explicit dimensions are given. */
206
- aspectRatio?: number | string;
207
- children?: ReactNode;
208
- }
209
-
210
- export const EvoCardMedia = forwardRef<HTMLDivElement, EvoCardMediaProps>(
211
- function EvoCardMedia(
212
- { src, alt, aspectRatio, className, style, children, ...rest },
213
- ref,
214
- ) {
215
- const mediaStyle: CSSProperties | undefined =
216
- aspectRatio != null
217
- ? { aspectRatio: aspectRatio as CSSProperties['aspectRatio'], ...style }
218
- : style;
219
- return (
220
- <div
221
- ref={ref}
222
- className={cx(styles.media, className)}
223
- style={mediaStyle}
224
- {...rest}
225
- >
226
- {src ? <img src={src} alt={alt ?? ''} className={styles.mediaImg} /> : children}
227
- </div>
228
- );
229
- },
230
- );
231
- EvoCardMedia.displayName = 'EvoCardMedia';
232
-
233
- // ----- Compound export -----
234
- //
235
- // `EvoCard` is callable (forwards to Root) AND carries the sub-components
236
- // as static properties so consumers can write either:
237
- // <EvoCard variant="outlined">…</EvoCard>
238
- // <EvoCard.Root variant="outlined">…</EvoCard.Root>
239
-
240
- type EvoCardComponent = typeof EvoCardRoot & {
241
- Root: typeof EvoCardRoot;
242
- Header: typeof EvoCardHeader;
243
- Title: typeof EvoCardTitle;
244
- Description: typeof EvoCardDescription;
245
- Body: typeof EvoCardBody;
246
- Footer: typeof EvoCardFooter;
247
- Media: typeof EvoCardMedia;
248
- };
249
-
250
- export const EvoCard = EvoCardRoot as EvoCardComponent;
251
- EvoCard.Root = EvoCardRoot;
252
- EvoCard.Header = EvoCardHeader;
253
- EvoCard.Title = EvoCardTitle;
254
- EvoCard.Description = EvoCardDescription;
255
- EvoCard.Body = EvoCardBody;
256
- EvoCard.Footer = EvoCardFooter;
257
- EvoCard.Media = EvoCardMedia;
1
+ import {
2
+ forwardRef,
3
+ createElement,
4
+ type AnchorHTMLAttributes,
5
+ type ButtonHTMLAttributes,
6
+ type CSSProperties,
7
+ type HTMLAttributes,
8
+ type ReactNode,
9
+ type Ref,
10
+ } from 'react';
11
+ import styles from '../css/card.module.scss';
12
+
13
+ // ============================================================
14
+ // EvoCard
15
+ // ------------------------------------------------------------
16
+ // Compose-based card primitive. The API takes after Radix:
17
+ // <EvoCard.Root> is the documented surface; <EvoCard> is kept
18
+ // as an ergonomic alias that forwards to Root.
19
+ //
20
+ // Visual axes are deliberately minimal — three structural
21
+ // variants (elevated / outlined / ghost). All colour comes
22
+ // from semantic theme tokens, so dark mode is automatic.
23
+ //
24
+ // When `interactive` is set the root is rendered as a real
25
+ // <button type="button"> or, if `href` is provided, a real
26
+ // <a>. We never use <div onClick> — keyboard users and screen
27
+ // readers get first-class treatment.
28
+ // ============================================================
29
+
30
+ export type EvoCardVariant = 'elevated' | 'outlined' | 'ghost';
31
+ export type EvoCardOrientation = 'vertical' | 'horizontal' | 'responsive';
32
+ export type EvoCardHeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
33
+
34
+ interface EvoCardRootBase {
35
+ variant?: EvoCardVariant;
36
+ orientation?: EvoCardOrientation;
37
+ children: ReactNode;
38
+ }
39
+
40
+ interface EvoCardRootStaticProps
41
+ extends EvoCardRootBase,
42
+ Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
43
+ interactive?: false;
44
+ href?: never;
45
+ }
46
+
47
+ interface EvoCardRootButtonProps
48
+ extends EvoCardRootBase,
49
+ Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'type'> {
50
+ interactive: true;
51
+ href?: never;
52
+ /** @default 'button' (never auto-submits) */
53
+ type?: 'button' | 'submit' | 'reset';
54
+ }
55
+
56
+ interface EvoCardRootAnchorProps
57
+ extends EvoCardRootBase,
58
+ Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'children' | 'href'> {
59
+ interactive: true;
60
+ href: string;
61
+ }
62
+
63
+ export type EvoCardRootProps =
64
+ | EvoCardRootStaticProps
65
+ | EvoCardRootButtonProps
66
+ | EvoCardRootAnchorProps;
67
+
68
+ function cx(...parts: Array<string | undefined | false | null>) {
69
+ return parts.filter(Boolean).join(' ');
70
+ }
71
+
72
+ function rootClasses(
73
+ variant: EvoCardVariant,
74
+ orientation: EvoCardOrientation,
75
+ interactive: boolean,
76
+ className?: string,
77
+ ) {
78
+ return cx(
79
+ styles.root,
80
+ styles[variant],
81
+ styles[`orient-${orientation}`],
82
+ interactive && styles.interactive,
83
+ className,
84
+ );
85
+ }
86
+
87
+ export const EvoCardRoot = forwardRef<HTMLElement, EvoCardRootProps>(
88
+ function EvoCardRoot(props, ref) {
89
+ const {
90
+ variant = 'elevated',
91
+ orientation = 'vertical',
92
+ interactive,
93
+ className,
94
+ children,
95
+ ...rest
96
+ } = props as EvoCardRootStaticProps &
97
+ Partial<EvoCardRootAnchorProps> &
98
+ Partial<EvoCardRootButtonProps> & { interactive?: boolean };
99
+
100
+ const isInteractive = interactive === true;
101
+ const classes = rootClasses(variant, orientation, isInteractive, className);
102
+
103
+ if (isInteractive && typeof (rest as { href?: string }).href === 'string') {
104
+ const anchorRest = rest as AnchorHTMLAttributes<HTMLAnchorElement>;
105
+ return (
106
+ <a ref={ref as Ref<HTMLAnchorElement>} className={classes} {...anchorRest}>
107
+ {children}
108
+ </a>
109
+ );
110
+ }
111
+
112
+ if (isInteractive) {
113
+ const { type = 'button', ...buttonRest } =
114
+ rest as ButtonHTMLAttributes<HTMLButtonElement>;
115
+ return (
116
+ <button
117
+ ref={ref as Ref<HTMLButtonElement>}
118
+ type={type}
119
+ className={classes}
120
+ {...buttonRest}
121
+ >
122
+ {children}
123
+ </button>
124
+ );
125
+ }
126
+
127
+ return (
128
+ <div
129
+ ref={ref as Ref<HTMLDivElement>}
130
+ className={classes}
131
+ {...(rest as HTMLAttributes<HTMLDivElement>)}
132
+ >
133
+ {children}
134
+ </div>
135
+ );
136
+ },
137
+ );
138
+ EvoCardRoot.displayName = 'EvoCardRoot';
139
+
140
+ // ----- Section slots -----
141
+
142
+ export type EvoCardHeaderProps = HTMLAttributes<HTMLDivElement>;
143
+ export type EvoCardBodyProps = HTMLAttributes<HTMLDivElement>;
144
+ export type EvoCardFooterProps = HTMLAttributes<HTMLDivElement>;
145
+
146
+ export const EvoCardHeader = forwardRef<HTMLDivElement, EvoCardHeaderProps>(
147
+ function EvoCardHeader({ className, ...rest }, ref) {
148
+ return <div ref={ref} className={cx(styles.header, className)} {...rest} />;
149
+ },
150
+ );
151
+ EvoCardHeader.displayName = 'EvoCardHeader';
152
+
153
+ export const EvoCardBody = forwardRef<HTMLDivElement, EvoCardBodyProps>(
154
+ function EvoCardBody({ className, ...rest }, ref) {
155
+ return <div ref={ref} className={cx(styles.body, className)} {...rest} />;
156
+ },
157
+ );
158
+ EvoCardBody.displayName = 'EvoCardBody';
159
+
160
+ export const EvoCardFooter = forwardRef<HTMLDivElement, EvoCardFooterProps>(
161
+ function EvoCardFooter({ className, ...rest }, ref) {
162
+ return <div ref={ref} className={cx(styles.footer, className)} {...rest} />;
163
+ },
164
+ );
165
+ EvoCardFooter.displayName = 'EvoCardFooter';
166
+
167
+ // ----- Title (configurable heading level) -----
168
+
169
+ export interface EvoCardTitleProps extends HTMLAttributes<HTMLHeadingElement> {
170
+ /** Semantic level. Visual size is fixed by the stylesheet. @default 'h3' */
171
+ as?: EvoCardHeadingLevel;
172
+ children: ReactNode;
173
+ }
174
+
175
+ export const EvoCardTitle = forwardRef<HTMLHeadingElement, EvoCardTitleProps>(
176
+ function EvoCardTitle({ as = 'h3', className, children, ...rest }, ref) {
177
+ return createElement(
178
+ as,
179
+ { ref, className: cx(styles.title, className), ...rest },
180
+ children,
181
+ );
182
+ },
183
+ );
184
+ EvoCardTitle.displayName = 'EvoCardTitle';
185
+
186
+ // ----- Description -----
187
+
188
+ export type EvoCardDescriptionProps = HTMLAttributes<HTMLParagraphElement>;
189
+
190
+ export const EvoCardDescription = forwardRef<
191
+ HTMLParagraphElement,
192
+ EvoCardDescriptionProps
193
+ >(function EvoCardDescription({ className, ...rest }, ref) {
194
+ return <p ref={ref} className={cx(styles.description, className)} {...rest} />;
195
+ });
196
+ EvoCardDescription.displayName = 'EvoCardDescription';
197
+
198
+ // ----- Media -----
199
+
200
+ export interface EvoCardMediaProps extends HTMLAttributes<HTMLDivElement> {
201
+ /** Convenience: renders an <img>. Omit and pass children for custom media. */
202
+ src?: string;
203
+ /** Required when `src` is set. Empty string marks the image as decorative. */
204
+ alt?: string;
205
+ /** e.g. 16/9 or '4/3'. Applied when no explicit dimensions are given. */
206
+ aspectRatio?: number | string;
207
+ children?: ReactNode;
208
+ }
209
+
210
+ export const EvoCardMedia = forwardRef<HTMLDivElement, EvoCardMediaProps>(
211
+ function EvoCardMedia(
212
+ { src, alt, aspectRatio, className, style, children, ...rest },
213
+ ref,
214
+ ) {
215
+ const mediaStyle: CSSProperties | undefined =
216
+ aspectRatio != null
217
+ ? { aspectRatio: aspectRatio as CSSProperties['aspectRatio'], ...style }
218
+ : style;
219
+ return (
220
+ <div
221
+ ref={ref}
222
+ className={cx(styles.media, className)}
223
+ style={mediaStyle}
224
+ {...rest}
225
+ >
226
+ {src ? <img src={src} alt={alt ?? ''} className={styles.mediaImg} /> : children}
227
+ </div>
228
+ );
229
+ },
230
+ );
231
+ EvoCardMedia.displayName = 'EvoCardMedia';
232
+
233
+ // ----- Compound export -----
234
+ //
235
+ // `EvoCard` is callable (forwards to Root) AND carries the sub-components
236
+ // as static properties so consumers can write either:
237
+ // <EvoCard variant="outlined">…</EvoCard>
238
+ // <EvoCard.Root variant="outlined">…</EvoCard.Root>
239
+
240
+ type EvoCardComponent = typeof EvoCardRoot & {
241
+ Root: typeof EvoCardRoot;
242
+ Header: typeof EvoCardHeader;
243
+ Title: typeof EvoCardTitle;
244
+ Description: typeof EvoCardDescription;
245
+ Body: typeof EvoCardBody;
246
+ Footer: typeof EvoCardFooter;
247
+ Media: typeof EvoCardMedia;
248
+ };
249
+
250
+ export const EvoCard = EvoCardRoot as EvoCardComponent;
251
+ EvoCard.Root = EvoCardRoot;
252
+ EvoCard.Header = EvoCardHeader;
253
+ EvoCard.Title = EvoCardTitle;
254
+ EvoCard.Description = EvoCardDescription;
255
+ EvoCard.Body = EvoCardBody;
256
+ EvoCard.Footer = EvoCardFooter;
257
+ EvoCard.Media = EvoCardMedia;
@@ -1,59 +1,59 @@
1
- import React from 'react';
2
- import styles from '../css/checkbox.module.scss';
3
-
4
- interface EvoCheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
5
- label?: string;
6
- helperText?: string;
7
- indeterminate?: boolean;
8
- }
9
-
10
- interface EvoCheckboxGroupProps {
11
- children: React.ReactNode;
12
- label?: string;
13
- className?: string;
14
- }
15
-
16
- const EvoCheckboxGroup = ({ children, label, className = '' }: EvoCheckboxGroupProps) => (
17
- <fieldset className={`${styles.group} ${className}`}>
18
- {label && <legend className={styles.groupLabel}>{label}</legend>}
19
- {children}
20
- </fieldset>
21
- );
22
-
23
- export const EvoCheckbox = ({
24
- label,
25
- helperText,
26
- indeterminate = false,
27
- className = '',
28
- disabled,
29
- id,
30
- ...rest
31
- }: EvoCheckboxProps) => {
32
- const inputRef = React.useRef<HTMLInputElement>(null);
33
-
34
- React.useEffect(() => {
35
- if (inputRef.current) inputRef.current.indeterminate = indeterminate;
36
- }, [indeterminate]);
37
-
38
- const inputId = id ?? label?.toLowerCase().replace(/\s+/g, '-');
39
-
40
- return (
41
- <div className={[styles.checkbox, disabled ? styles.disabled : '', className].filter(Boolean).join(' ')}>
42
- <input
43
- type="checkbox"
44
- id={inputId}
45
- ref={inputRef}
46
- disabled={disabled}
47
- className={styles.input}
48
- {...rest}
49
- />
50
- <label htmlFor={inputId} className={styles.label}>
51
- <span className={styles.checkmark} />
52
- <span className={styles.labelText}>{label}</span>
53
- </label>
54
- {helperText && <p className={styles.helperText}>{helperText}</p>}
55
- </div>
56
- );
57
- };
58
-
59
- EvoCheckbox.Group = EvoCheckboxGroup;
1
+ import React from 'react';
2
+ import styles from '../css/checkbox.module.scss';
3
+
4
+ interface EvoCheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
5
+ label?: string;
6
+ helperText?: string;
7
+ indeterminate?: boolean;
8
+ }
9
+
10
+ interface EvoCheckboxGroupProps {
11
+ children: React.ReactNode;
12
+ label?: string;
13
+ className?: string;
14
+ }
15
+
16
+ const EvoCheckboxGroup = ({ children, label, className = '' }: EvoCheckboxGroupProps) => (
17
+ <fieldset className={`${styles.group} ${className}`}>
18
+ {label && <legend className={styles.groupLabel}>{label}</legend>}
19
+ {children}
20
+ </fieldset>
21
+ );
22
+
23
+ export const EvoCheckbox = ({
24
+ label,
25
+ helperText,
26
+ indeterminate = false,
27
+ className = '',
28
+ disabled,
29
+ id,
30
+ ...rest
31
+ }: EvoCheckboxProps) => {
32
+ const inputRef = React.useRef<HTMLInputElement>(null);
33
+
34
+ React.useEffect(() => {
35
+ if (inputRef.current) inputRef.current.indeterminate = indeterminate;
36
+ }, [indeterminate]);
37
+
38
+ const inputId = id ?? label?.toLowerCase().replace(/\s+/g, '-');
39
+
40
+ return (
41
+ <div className={[styles.checkbox, disabled ? styles.disabled : '', className].filter(Boolean).join(' ')}>
42
+ <input
43
+ type="checkbox"
44
+ id={inputId}
45
+ ref={inputRef}
46
+ disabled={disabled}
47
+ className={styles.input}
48
+ {...rest}
49
+ />
50
+ <label htmlFor={inputId} className={styles.label}>
51
+ <span className={styles.checkmark} />
52
+ <span className={styles.labelText}>{label}</span>
53
+ </label>
54
+ {helperText && <p className={styles.helperText}>{helperText}</p>}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ EvoCheckbox.Group = EvoCheckboxGroup;