@justin_evo/evo-ui 1.1.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 (80) hide show
  1. package/README.md +3 -3
  2. package/dist/TopNav/TopNav.d.ts +19 -0
  3. package/dist/declarations.d.ts +6 -6
  4. package/dist/evo-ui.css +1 -1
  5. package/dist/index.cjs.js +1 -1
  6. package/dist/index.es.js +3301 -3197
  7. package/package.json +52 -52
  8. package/src/Alert/Alert.tsx +49 -49
  9. package/src/AutoComplete/AutoComplete.tsx +810 -810
  10. package/src/Badge/Badge.tsx +53 -53
  11. package/src/Breadcrumb/Breadcrumb.tsx +53 -53
  12. package/src/Button/Button.tsx +125 -125
  13. package/src/Card/Card.tsx +257 -257
  14. package/src/Checkbox/Checkbox.tsx +59 -59
  15. package/src/CommandPalette/CommandPalette.tsx +185 -185
  16. package/src/Container/Container.tsx +31 -31
  17. package/src/Divider/Divider.tsx +31 -31
  18. package/src/Form/Form.tsx +185 -185
  19. package/src/Grid/Grid.tsx +66 -66
  20. package/src/ImageCropper/ImageCropper.tsx +911 -911
  21. package/src/Input/Input.tsx +74 -74
  22. package/src/Modal/Modal.tsx +77 -77
  23. package/src/Nav/Nav.tsx +708 -708
  24. package/src/Notification/Notification.tsx +1503 -1503
  25. package/src/Pagination/Pagination.tsx +76 -76
  26. package/src/Radio/Radio.tsx +69 -69
  27. package/src/RichTextArea/RichTextArea.tsx +886 -869
  28. package/src/Select/Select.tsx +515 -515
  29. package/src/Skeleton/Skeleton.tsx +70 -70
  30. package/src/Stack/Stack.tsx +52 -52
  31. package/src/Table/Table.tsx +335 -335
  32. package/src/Tabs/Tabs.tsx +90 -90
  33. package/src/Theme/ThemeProvider.tsx +253 -253
  34. package/src/Theme/ThemeToggle.tsx +79 -79
  35. package/src/Toggle/Toggle.tsx +48 -48
  36. package/src/Tooltip/Tooltip.tsx +38 -38
  37. package/src/TopNav/TopNav.tsx +1163 -994
  38. package/src/TreeSelect/TreeSelect.tsx +825 -825
  39. package/src/css/alert.module.scss +93 -93
  40. package/src/css/autocomplete.module.scss +416 -416
  41. package/src/css/badge.module.scss +82 -82
  42. package/src/css/base/_color.scss +159 -159
  43. package/src/css/base/_theme.scss +237 -237
  44. package/src/css/base/_variables.scss +161 -161
  45. package/src/css/breadcrumb.module.scss +50 -50
  46. package/src/css/button.module.scss +385 -385
  47. package/src/css/card.module.scss +217 -217
  48. package/src/css/checkbox.module.scss +123 -120
  49. package/src/css/commandpalette.module.scss +211 -211
  50. package/src/css/container.module.scss +18 -18
  51. package/src/css/divider.module.scss +41 -41
  52. package/src/css/form.module.scss +245 -245
  53. package/src/css/imagecropper.module.scss +397 -397
  54. package/src/css/input.module.scss +89 -89
  55. package/src/css/modal.module.scss +105 -105
  56. package/src/css/nav.module.scss +494 -494
  57. package/src/css/notification.module.scss +691 -691
  58. package/src/css/pagination.module.scss +63 -63
  59. package/src/css/radio.module.scss +89 -89
  60. package/src/css/richtextarea.module.scss +307 -307
  61. package/src/css/select.module.scss +525 -525
  62. package/src/css/skeleton.module.scss +30 -30
  63. package/src/css/table.module.scss +386 -386
  64. package/src/css/tabs.module.scss +63 -63
  65. package/src/css/theme-toggle.module.scss +83 -83
  66. package/src/css/toggle.module.scss +54 -54
  67. package/src/css/tooltip.module.scss +97 -97
  68. package/src/css/topnav.module.scss +568 -396
  69. package/src/css/treeselect.module.scss +558 -558
  70. package/src/css/utilities/_borders.scss +111 -111
  71. package/src/css/utilities/_colors.scss +66 -66
  72. package/src/css/utilities/_effects.scss +216 -216
  73. package/src/css/utilities/_layout.scss +181 -181
  74. package/src/css/utilities/_position.scss +75 -75
  75. package/src/css/utilities/_sizing.scss +138 -138
  76. package/src/css/utilities/_spacing.scss +99 -99
  77. package/src/css/utilities/_typography.scss +121 -121
  78. package/src/css/utilities/index.scss +24 -24
  79. package/src/declarations.d.ts +6 -6
  80. 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;