@groundbrick/svelte-ui 0.1.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 (60) hide show
  1. package/README.md +125 -0
  2. package/dist/components/Alert.svelte +335 -0
  3. package/dist/components/Alert.svelte.d.ts +24 -0
  4. package/dist/components/AutocompleteInput.svelte +356 -0
  5. package/dist/components/AutocompleteInput.svelte.d.ts +72 -0
  6. package/dist/components/Badge.svelte +185 -0
  7. package/dist/components/Badge.svelte.d.ts +20 -0
  8. package/dist/components/Button.svelte +415 -0
  9. package/dist/components/Button.svelte.d.ts +34 -0
  10. package/dist/components/Card.svelte +181 -0
  11. package/dist/components/Card.svelte.d.ts +24 -0
  12. package/dist/components/CardBody.svelte +78 -0
  13. package/dist/components/CardBody.svelte.d.ts +12 -0
  14. package/dist/components/CardFooter.svelte +81 -0
  15. package/dist/components/CardFooter.svelte.d.ts +14 -0
  16. package/dist/components/CardHeader.svelte +186 -0
  17. package/dist/components/CardHeader.svelte.d.ts +21 -0
  18. package/dist/components/Col.svelte +172 -0
  19. package/dist/components/Col.svelte.d.ts +26 -0
  20. package/dist/components/Container.svelte +118 -0
  21. package/dist/components/Container.svelte.d.ts +14 -0
  22. package/dist/components/Drawer.svelte +233 -0
  23. package/dist/components/Drawer.svelte.d.ts +13 -0
  24. package/dist/components/Dropdown.svelte +190 -0
  25. package/dist/components/Dropdown.svelte.d.ts +26 -0
  26. package/dist/components/DropdownItem.svelte +103 -0
  27. package/dist/components/DropdownItem.svelte.d.ts +22 -0
  28. package/dist/components/DurationInput.svelte +170 -0
  29. package/dist/components/DurationInput.svelte.d.ts +27 -0
  30. package/dist/components/EditableTable.svelte +647 -0
  31. package/dist/components/EditableTable.svelte.d.ts +74 -0
  32. package/dist/components/EmptyState.svelte +192 -0
  33. package/dist/components/EmptyState.svelte.d.ts +22 -0
  34. package/dist/components/FormField.svelte +260 -0
  35. package/dist/components/FormField.svelte.d.ts +68 -0
  36. package/dist/components/GridView.svelte +1022 -0
  37. package/dist/components/GridView.svelte.d.ts +38 -0
  38. package/dist/components/GridView.types.d.ts +28 -0
  39. package/dist/components/GridView.types.js +1 -0
  40. package/dist/components/LoadingSpinner.svelte +253 -0
  41. package/dist/components/LoadingSpinner.svelte.d.ts +17 -0
  42. package/dist/components/Modal.svelte +473 -0
  43. package/dist/components/Modal.svelte.d.ts +42 -0
  44. package/dist/components/PhoneInput.svelte +406 -0
  45. package/dist/components/PhoneInput.svelte.d.ts +31 -0
  46. package/dist/components/PhotoUpload.svelte +529 -0
  47. package/dist/components/PhotoUpload.svelte.d.ts +46 -0
  48. package/dist/components/Row.svelte +153 -0
  49. package/dist/components/Row.svelte.d.ts +18 -0
  50. package/dist/icons/PawPrintIcon.svelte +41 -0
  51. package/dist/icons/PawPrintIcon.svelte.d.ts +14 -0
  52. package/dist/index.d.ts +41 -0
  53. package/dist/index.js +49 -0
  54. package/dist/styles/forms.css +182 -0
  55. package/dist/styles/tokens.css +243 -0
  56. package/dist/utils/duration.d.ts +20 -0
  57. package/dist/utils/duration.js +40 -0
  58. package/dist/utils/scrollLock.d.ts +7 -0
  59. package/dist/utils/scrollLock.js +26 -0
  60. package/package.json +66 -0
@@ -0,0 +1,415 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+
4
+ interface ButtonProps {
5
+ /** Visual variant */
6
+ variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark' | 'outline-primary' | 'outline-secondary' | 'outline-success' | 'outline-danger' | 'outline-warning' | 'link' | 'ghost' | 'gradient';
7
+ /** Button size */
8
+ size?: 'sm' | 'md' | 'lg';
9
+ /** Optional HTML id */
10
+ id?: string;
11
+ /** Take the full container width */
12
+ fullWidth?: boolean;
13
+ /** Disabled state */
14
+ disabled?: boolean;
15
+ /** Loading state (shows a spinner and disables the button) */
16
+ loading?: boolean;
17
+ /** HTML button type */
18
+ type?: 'button' | 'submit' | 'reset';
19
+ /** Click callback */
20
+ onclick?: (event: MouseEvent) => void;
21
+ /** Button content */
22
+ children?: Snippet;
23
+ /** Icon to the left of the text */
24
+ icon?: Snippet;
25
+ /** Icon to the right of the text */
26
+ iconRight?: Snippet;
27
+ /** ARIA label for accessibility */
28
+ ariaLabel?: string;
29
+ /** Additional CSS classes */
30
+ class?: string;
31
+ /** URL for navigation (renders as a link) */
32
+ href?: string;
33
+ }
34
+
35
+ let {
36
+ variant = 'primary',
37
+ size = 'md',
38
+ id,
39
+ fullWidth = false,
40
+ disabled = false,
41
+ loading = false,
42
+ type = 'button',
43
+ onclick,
44
+ children,
45
+ icon,
46
+ iconRight,
47
+ ariaLabel,
48
+ class: additionalClasses = '',
49
+ href
50
+ }: ButtonProps = $props();
51
+
52
+ // Disabled when explicitly disabled or while loading.
53
+ let isDisabled = $derived(disabled || loading);
54
+
55
+ const buttonClass = $derived([
56
+ 'ap-btn',
57
+ `ap-btn-${variant}`,
58
+ size !== 'md' ? `ap-btn-${size}` : '',
59
+ fullWidth ? 'ap-btn-full' : '',
60
+ additionalClasses
61
+ ].filter(Boolean).join(' '));
62
+ </script>
63
+
64
+ {#if href}
65
+ <a
66
+ {id}
67
+ href={isDisabled ? undefined : href}
68
+ class={buttonClass}
69
+ class:disabled={isDisabled}
70
+ onclick={isDisabled ? undefined : onclick}
71
+ aria-label={ariaLabel}
72
+ aria-busy={loading}
73
+ aria-disabled={isDisabled}
74
+ tabindex={isDisabled ? -1 : undefined}
75
+ role="button"
76
+ >
77
+ {#if loading}
78
+ <span class="ap-btn-spinner" role="status" aria-hidden="true"></span>
79
+ {/if}
80
+
81
+ {#if icon && !loading}
82
+ <span class="ap-btn-icon">
83
+ {@render icon()}
84
+ </span>
85
+ {/if}
86
+
87
+ {#if children}
88
+ {@render children()}
89
+ {/if}
90
+
91
+ {#if iconRight && !loading}
92
+ <span class="ap-btn-icon ap-btn-icon-right">
93
+ {@render iconRight()}
94
+ </span>
95
+ {/if}
96
+ </a>
97
+ {:else}
98
+ <button
99
+ {id}
100
+ {type}
101
+ class={buttonClass}
102
+ disabled={isDisabled}
103
+ onclick={onclick}
104
+ aria-label={ariaLabel}
105
+ aria-busy={loading}
106
+ >
107
+ {#if loading}
108
+ <span class="ap-btn-spinner" role="status" aria-hidden="true"></span>
109
+ {/if}
110
+
111
+ {#if icon && !loading}
112
+ <span class="ap-btn-icon">
113
+ {@render icon()}
114
+ </span>
115
+ {/if}
116
+
117
+ {#if children}
118
+ {@render children()}
119
+ {/if}
120
+
121
+ {#if iconRight && !loading}
122
+ <span class="ap-btn-icon ap-btn-icon-right">
123
+ {@render iconRight()}
124
+ </span>
125
+ {/if}
126
+ </button>
127
+ {/if}
128
+
129
+ <style>
130
+ /* ============================================
131
+ BUTTON
132
+ ============================================ */
133
+ .ap-btn {
134
+ display: inline-flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ gap: 0.5rem;
138
+ padding: 0.625rem 1.125rem;
139
+ font-family: var(--font-family-base);
140
+ font-size: var(--font-size-sm);
141
+ font-weight: var(--font-weight-medium);
142
+ line-height: 1.4;
143
+ text-decoration: none;
144
+ border: none;
145
+ border-radius: var(--radius-full);
146
+ cursor: pointer;
147
+ transition: all var(--transition-base);
148
+ user-select: none;
149
+ position: relative;
150
+ white-space: nowrap;
151
+ }
152
+
153
+ /* ===== SIZES ===== */
154
+ .ap-btn-sm {
155
+ padding: 0.375rem 0.875rem;
156
+ font-size: var(--font-size-xs);
157
+ gap: 0.375rem;
158
+ }
159
+
160
+ .ap-btn-lg {
161
+ padding: 0.75rem 1.5rem;
162
+ font-size: var(--font-size-base);
163
+ gap: 0.625rem;
164
+ }
165
+
166
+ .ap-btn-full {
167
+ width: 100%;
168
+ }
169
+
170
+ /* ===== PRIMARY ===== */
171
+ .ap-btn-primary {
172
+ background: var(--color-primary);
173
+ color: white;
174
+ box-shadow: var(--shadow-primary);
175
+ }
176
+
177
+ .ap-btn-primary:hover:not(:disabled):not(.disabled) {
178
+ background: var(--color-primary-hover);
179
+ transform: translateY(-1px);
180
+ box-shadow: var(--shadow-primary-hover);
181
+ }
182
+
183
+ .ap-btn-primary:active:not(:disabled):not(.disabled) {
184
+ background: var(--color-primary-active);
185
+ transform: translateY(0);
186
+ }
187
+
188
+ /* ===== GRADIENT ===== */
189
+ .ap-btn-gradient {
190
+ background: var(--gradient-brand);
191
+ color: white;
192
+ box-shadow: var(--shadow-primary);
193
+ }
194
+
195
+ .ap-btn-gradient:hover:not(:disabled):not(.disabled) {
196
+ background: var(--gradient-brand-hover);
197
+ transform: translateY(-1px);
198
+ box-shadow: var(--shadow-gradient);
199
+ filter: saturate(1.06);
200
+ }
201
+
202
+ .ap-btn-gradient:active:not(:disabled):not(.disabled) {
203
+ transform: translateY(0);
204
+ }
205
+
206
+ /* ===== SECONDARY ===== */
207
+ .ap-btn-secondary {
208
+ background: var(--color-secondary);
209
+ color: white;
210
+ }
211
+
212
+ .ap-btn-secondary:hover:not(:disabled):not(.disabled) {
213
+ background: var(--color-secondary-hover);
214
+ transform: translateY(-1px);
215
+ }
216
+
217
+ /* ===== SUCCESS ===== */
218
+ .ap-btn-success {
219
+ background: var(--color-success);
220
+ color: white;
221
+ box-shadow: var(--shadow-success);
222
+ }
223
+
224
+ .ap-btn-success:hover:not(:disabled):not(.disabled) {
225
+ background: var(--color-success-hover);
226
+ transform: translateY(-1px);
227
+ }
228
+
229
+ /* ===== DANGER ===== */
230
+ .ap-btn-danger {
231
+ background: var(--color-danger);
232
+ color: white;
233
+ box-shadow: var(--shadow-danger);
234
+ }
235
+
236
+ .ap-btn-danger:hover:not(:disabled):not(.disabled) {
237
+ background: var(--color-danger-hover);
238
+ transform: translateY(-1px);
239
+ }
240
+
241
+ /* ===== WARNING ===== */
242
+ .ap-btn-warning {
243
+ background: var(--color-warning);
244
+ color: white;
245
+ }
246
+
247
+ .ap-btn-warning:hover:not(:disabled):not(.disabled) {
248
+ background: var(--color-warning-hover);
249
+ transform: translateY(-1px);
250
+ }
251
+
252
+ /* ===== INFO ===== */
253
+ .ap-btn-info {
254
+ background: var(--color-info);
255
+ color: white;
256
+ }
257
+
258
+ .ap-btn-info:hover:not(:disabled):not(.disabled) {
259
+ background: var(--color-info-hover);
260
+ transform: translateY(-1px);
261
+ }
262
+
263
+ /* ===== LIGHT ===== */
264
+ .ap-btn-light {
265
+ background: var(--color-bg-surface-2);
266
+ color: var(--color-text);
267
+ border: 1px solid var(--color-border-subtle);
268
+ }
269
+
270
+ .ap-btn-light:hover:not(:disabled):not(.disabled) {
271
+ background: var(--color-gray-200);
272
+ transform: translateY(-1px);
273
+ }
274
+
275
+ /* ===== DARK ===== */
276
+ .ap-btn-dark {
277
+ background: var(--color-gray-800);
278
+ color: white;
279
+ }
280
+
281
+ .ap-btn-dark:hover:not(:disabled):not(.disabled) {
282
+ background: var(--color-gray-900);
283
+ transform: translateY(-1px);
284
+ }
285
+
286
+ /* ===== OUTLINE VARIANTS ===== */
287
+ .ap-btn-outline-primary {
288
+ background: transparent;
289
+ color: var(--color-primary);
290
+ border: 1.5px solid var(--color-primary);
291
+ }
292
+
293
+ .ap-btn-outline-primary:hover:not(:disabled):not(.disabled) {
294
+ background: var(--color-primary);
295
+ color: white;
296
+ transform: translateY(-1px);
297
+ }
298
+
299
+ .ap-btn-outline-secondary {
300
+ background: transparent;
301
+ color: var(--color-secondary);
302
+ border: 1.5px solid var(--color-secondary);
303
+ }
304
+
305
+ .ap-btn-outline-secondary:hover:not(:disabled):not(.disabled) {
306
+ background: var(--color-secondary);
307
+ color: white;
308
+ transform: translateY(-1px);
309
+ }
310
+
311
+ .ap-btn-outline-success {
312
+ background: transparent;
313
+ color: var(--color-success);
314
+ border: 1.5px solid var(--color-success);
315
+ }
316
+
317
+ .ap-btn-outline-success:hover:not(:disabled):not(.disabled) {
318
+ background: var(--color-success);
319
+ color: white;
320
+ transform: translateY(-1px);
321
+ }
322
+
323
+ .ap-btn-outline-danger {
324
+ background: transparent;
325
+ color: var(--color-danger);
326
+ border: 1.5px solid var(--color-danger);
327
+ }
328
+
329
+ .ap-btn-outline-danger:hover:not(:disabled):not(.disabled) {
330
+ background: var(--color-danger);
331
+ color: white;
332
+ transform: translateY(-1px);
333
+ }
334
+
335
+ .ap-btn-outline-warning {
336
+ background: transparent;
337
+ color: var(--color-warning-text);
338
+ border: 1.5px solid var(--color-warning);
339
+ }
340
+
341
+ .ap-btn-outline-warning:hover:not(:disabled):not(.disabled) {
342
+ background: var(--color-warning);
343
+ color: var(--color-warning-text);
344
+ transform: translateY(-1px);
345
+ }
346
+
347
+ /* ===== LINK ===== */
348
+ .ap-btn-link {
349
+ background: transparent;
350
+ color: var(--color-primary);
351
+ padding: 0.375rem 0.5rem;
352
+ border-radius: var(--radius-sm);
353
+ }
354
+
355
+ .ap-btn-link:hover:not(:disabled):not(.disabled) {
356
+ color: var(--color-primary-hover);
357
+ text-decoration: underline;
358
+ }
359
+
360
+ /* ===== GHOST ===== */
361
+ .ap-btn-ghost {
362
+ background: transparent;
363
+ color: var(--color-text);
364
+ padding: 0.5rem 0.75rem;
365
+ }
366
+
367
+ .ap-btn-ghost:hover:not(:disabled):not(.disabled) {
368
+ background: var(--color-bg-surface-2);
369
+ }
370
+
371
+ .ap-btn-ghost:active:not(:disabled):not(.disabled) {
372
+ background: var(--color-gray-200);
373
+ }
374
+
375
+ /* ===== STATES ===== */
376
+ .ap-btn:disabled,
377
+ .ap-btn.disabled {
378
+ cursor: not-allowed;
379
+ opacity: 0.6;
380
+ pointer-events: none;
381
+ }
382
+
383
+ .ap-btn:focus-visible {
384
+ outline: none;
385
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
386
+ }
387
+
388
+ /* ===== ICON ===== */
389
+ .ap-btn-icon {
390
+ display: inline-flex;
391
+ align-items: center;
392
+ justify-content: center;
393
+ flex-shrink: 0;
394
+ }
395
+
396
+ .ap-btn-icon-right {
397
+ order: 1;
398
+ }
399
+
400
+ /* ===== SPINNER ===== */
401
+ .ap-btn-spinner {
402
+ width: 1em;
403
+ height: 1em;
404
+ border: 2px solid currentColor;
405
+ border-right-color: transparent;
406
+ border-radius: 50%;
407
+ animation: ap-btn-spin 0.75s linear infinite;
408
+ }
409
+
410
+ @keyframes ap-btn-spin {
411
+ to {
412
+ transform: rotate(360deg);
413
+ }
414
+ }
415
+ </style>
@@ -0,0 +1,34 @@
1
+ import type { Snippet } from "svelte";
2
+ interface ButtonProps {
3
+ /** Visual variant */
4
+ variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark' | 'outline-primary' | 'outline-secondary' | 'outline-success' | 'outline-danger' | 'outline-warning' | 'link' | 'ghost' | 'gradient';
5
+ /** Button size */
6
+ size?: 'sm' | 'md' | 'lg';
7
+ /** Optional HTML id */
8
+ id?: string;
9
+ /** Take the full container width */
10
+ fullWidth?: boolean;
11
+ /** Disabled state */
12
+ disabled?: boolean;
13
+ /** Loading state (shows a spinner and disables the button) */
14
+ loading?: boolean;
15
+ /** HTML button type */
16
+ type?: 'button' | 'submit' | 'reset';
17
+ /** Click callback */
18
+ onclick?: (event: MouseEvent) => void;
19
+ /** Button content */
20
+ children?: Snippet;
21
+ /** Icon to the left of the text */
22
+ icon?: Snippet;
23
+ /** Icon to the right of the text */
24
+ iconRight?: Snippet;
25
+ /** ARIA label for accessibility */
26
+ ariaLabel?: string;
27
+ /** Additional CSS classes */
28
+ class?: string;
29
+ /** URL for navigation (renders as a link) */
30
+ href?: string;
31
+ }
32
+ declare const Button: import("svelte").Component<ButtonProps, {}, "">;
33
+ type Button = ReturnType<typeof Button>;
34
+ export default Button;
@@ -0,0 +1,181 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+
4
+ interface CardProps {
5
+ /** Variante visual do card */
6
+ variant?: 'default' | 'outlined' | 'elevated' | 'accent';
7
+ /** Padding interno do card */
8
+ padding?: 'none' | 'sm' | 'md' | 'lg';
9
+ /** Conteúdo do card */
10
+ children?: Snippet;
11
+ /** Efeito hover (elevação ao passar mouse) */
12
+ hover?: boolean;
13
+ /** Card clicável (adiciona cursor pointer e efeitos) */
14
+ clickable?: boolean;
15
+ /** Callback ao clicar (só funciona se clickable=true) */
16
+ onclick?: () => void;
17
+ /** Adicionar sombra ao card */
18
+ shadow?: boolean;
19
+ /** Classes CSS adicionais */
20
+ class?: string;
21
+ /** Estilos inline */
22
+ style?: string;
23
+ }
24
+
25
+ let {
26
+ variant = 'default',
27
+ padding = 'none',
28
+ children,
29
+ hover = false,
30
+ clickable = false,
31
+ onclick,
32
+ shadow = false,
33
+ class: additionalClasses = '',
34
+ style
35
+ }: CardProps = $props();
36
+
37
+ const cardClass = $derived([
38
+ 'ap-card',
39
+ `ap-card-${variant}`,
40
+ padding !== 'none' ? `ap-card-padding-${padding}` : '',
41
+ hover ? 'ap-card-hover' : '',
42
+ clickable ? 'ap-card-clickable' : '',
43
+ shadow ? 'ap-card-shadow' : '',
44
+ additionalClasses
45
+ ].filter(Boolean).join(' '));
46
+
47
+ // Handler de click
48
+ function handleClick() {
49
+ if (clickable && onclick) {
50
+ onclick();
51
+ }
52
+ }
53
+
54
+ // Handler de teclado (Enter e Space)
55
+ function handleKeyDown(event: KeyboardEvent) {
56
+ if (clickable && onclick && (event.key === 'Enter' || event.key === ' ')) {
57
+ event.preventDefault();
58
+ onclick();
59
+ }
60
+ }
61
+ </script>
62
+
63
+ {#if clickable}
64
+ <div
65
+ class={cardClass}
66
+ {style}
67
+ onclick={handleClick}
68
+ onkeydown={handleKeyDown}
69
+ role="button"
70
+ tabindex="0"
71
+ >
72
+ {@render children?.()}
73
+ </div>
74
+ {:else}
75
+ <div class={cardClass} {style}>
76
+ {@render children?.()}
77
+ </div>
78
+ {/if}
79
+
80
+ <style>
81
+ /* ============================================
82
+ CARD - AgendaPet Design System
83
+ ============================================ */
84
+ .ap-card {
85
+ background: var(--color-bg-surface);
86
+ border-radius: var(--radius-xl);
87
+ transition: all var(--transition-base);
88
+ overflow: hidden;
89
+ position: relative;
90
+ }
91
+
92
+ /* ===== VARIANTS ===== */
93
+ .ap-card-default {
94
+ border: 1px solid var(--color-border-subtle);
95
+ box-shadow: var(--shadow-soft);
96
+ }
97
+
98
+ .ap-card-outlined {
99
+ border: 2px solid var(--color-primary);
100
+ box-shadow: none;
101
+ }
102
+
103
+ .ap-card-elevated {
104
+ border: none;
105
+ box-shadow: var(--shadow-lg);
106
+ }
107
+
108
+ .ap-card-accent {
109
+ border: 1px solid var(--color-border-subtle);
110
+ border-top: none;
111
+ box-shadow: var(--shadow-soft);
112
+ }
113
+
114
+ .ap-card-accent::before {
115
+ content: '';
116
+ position: absolute;
117
+ top: 0;
118
+ left: 0;
119
+ right: 0;
120
+ height: 4px;
121
+ background: var(--gradient-brand);
122
+ border-radius: var(--radius-xl) var(--radius-xl) 0 0;
123
+ }
124
+
125
+ /* ===== PADDING ===== */
126
+ .ap-card-padding-sm {
127
+ padding: var(--spacing-sm);
128
+ }
129
+
130
+ .ap-card-padding-md {
131
+ padding: var(--spacing-md);
132
+ }
133
+
134
+ .ap-card-padding-lg {
135
+ padding: var(--spacing-lg);
136
+ }
137
+
138
+ /* ===== SHADOW ===== */
139
+ .ap-card-shadow {
140
+ box-shadow: var(--shadow-soft);
141
+ }
142
+
143
+ /* ===== HOVER STATE ===== */
144
+ .ap-card-hover:hover {
145
+ transform: translateY(-2px);
146
+ box-shadow: var(--shadow-hover);
147
+ }
148
+
149
+ /* ===== CLICKABLE STATE ===== */
150
+ .ap-card-clickable {
151
+ cursor: pointer;
152
+ user-select: none;
153
+ }
154
+
155
+ .ap-card-clickable:hover {
156
+ transform: translateY(-2px);
157
+ box-shadow: var(--shadow-hover);
158
+ }
159
+
160
+ .ap-card-clickable:focus {
161
+ outline: 2px solid var(--color-primary);
162
+ outline-offset: 2px;
163
+ }
164
+
165
+ .ap-card-clickable:focus:not(:focus-visible) {
166
+ outline: none;
167
+ }
168
+
169
+ .ap-card-clickable:active {
170
+ transform: translateY(0);
171
+ box-shadow: var(--shadow-sm);
172
+ }
173
+
174
+ /* ===== TRANSITIONS ===== */
175
+ .ap-card-hover,
176
+ .ap-card-clickable {
177
+ transition:
178
+ transform var(--transition-base),
179
+ box-shadow var(--transition-base);
180
+ }
181
+ </style>
@@ -0,0 +1,24 @@
1
+ import type { Snippet } from "svelte";
2
+ interface CardProps {
3
+ /** Variante visual do card */
4
+ variant?: 'default' | 'outlined' | 'elevated' | 'accent';
5
+ /** Padding interno do card */
6
+ padding?: 'none' | 'sm' | 'md' | 'lg';
7
+ /** Conteúdo do card */
8
+ children?: Snippet;
9
+ /** Efeito hover (elevação ao passar mouse) */
10
+ hover?: boolean;
11
+ /** Card clicável (adiciona cursor pointer e efeitos) */
12
+ clickable?: boolean;
13
+ /** Callback ao clicar (só funciona se clickable=true) */
14
+ onclick?: () => void;
15
+ /** Adicionar sombra ao card */
16
+ shadow?: boolean;
17
+ /** Classes CSS adicionais */
18
+ class?: string;
19
+ /** Estilos inline */
20
+ style?: string;
21
+ }
22
+ declare const Card: import("svelte").Component<CardProps, {}, "">;
23
+ type Card = ReturnType<typeof Card>;
24
+ export default Card;