@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,38 @@
1
+ import type { ActionItem, Column } from "./GridView.types.js";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const GridView: $$__sveltets_2_IsomorphicComponent<{
16
+ data?: any[];
17
+ columns?: Column[];
18
+ loading?: boolean;
19
+ emptyMessage?: string;
20
+ searchable?: boolean;
21
+ searchPlaceholder?: string;
22
+ selectable?: boolean;
23
+ draggable?: boolean;
24
+ onRowClick?: ((row: any) => void) | undefined;
25
+ onSelectionChange?: ((selectedRows: any[]) => void) | undefined;
26
+ onReorder?: ((orderedIds: number[]) => Promise<void>) | undefined;
27
+ actions?: ActionItem[];
28
+ paginated?: boolean;
29
+ pageSize?: number;
30
+ persistKey?: string | undefined;
31
+ /** Resolve an image cell value to a URL. Defaults to identity (use value as-is). */ resolveImageUrl?: (value: string, folder?: string) => string;
32
+ /** Format a date cell value. Defaults to pt-PT locale date. */ formatDate?: (value: any) => string;
33
+ /** Permission check for row actions. Defaults to allow-all. */ hasPermission?: (permission: string) => boolean;
34
+ }, {
35
+ [evt: string]: CustomEvent<any>;
36
+ }, {}, {}, string>;
37
+ type GridView = InstanceType<typeof GridView>;
38
+ export default GridView;
@@ -0,0 +1,28 @@
1
+ /** Column definition for GridView. */
2
+ export interface Column {
3
+ key: string;
4
+ title: string;
5
+ sortable?: boolean;
6
+ type?: "text" | "date" | "number" | "image" | "badge" | "custom";
7
+ width?: string;
8
+ /** Include in search but don't render in the grid */
9
+ hidden?: boolean;
10
+ customRender?: (value: any, row: any) => string;
11
+ badgeVariant?: (value: any) => "primary" | "secondary" | "success" | "danger" | "warning" | "info";
12
+ /** For image type: which folder the image is from (passed to resolveImageUrl) */
13
+ imageFolder?: string;
14
+ /** For custom type: Svelte component to render */
15
+ component?: any;
16
+ /** Props factory for the custom component */
17
+ componentProps?: (value: any, row: any) => Record<string, any>;
18
+ }
19
+ /** A row action shown in the per-row actions menu. */
20
+ export interface ActionItem {
21
+ label: string;
22
+ onClick: (item: any) => void | Promise<void>;
23
+ icon?: string;
24
+ /** Permission code checked via the `hasPermission` prop (app-defined). */
25
+ permission?: string;
26
+ condition?: (item: any) => boolean;
27
+ variant?: "primary" | "secondary" | "success" | "danger" | "warning" | "info";
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,253 @@
1
+ <script lang="ts">
2
+ interface LoadingSpinnerProps {
3
+ /** Mensagem de carregamento */
4
+ message?: string;
5
+ /** Tamanho do spinner */
6
+ size?: 'sm' | 'md' | 'lg';
7
+ /** Variante de cor */
8
+ variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark' | 'gradient';
9
+ /** Ocupar tela inteira */
10
+ fullScreen?: boolean;
11
+ /** Centralizado */
12
+ centered?: boolean;
13
+ /** Classes CSS adicionais */
14
+ class?: string;
15
+ }
16
+
17
+ let {
18
+ message = 'A carregar...',
19
+ size = 'md',
20
+ variant = 'primary',
21
+ fullScreen = false,
22
+ centered = true,
23
+ class: additionalClasses = ''
24
+ }: LoadingSpinnerProps = $props();
25
+
26
+ const sizeClasses: Record<string, string> = {
27
+ sm: 'ap-spinner-sm',
28
+ md: 'ap-spinner-md',
29
+ lg: 'ap-spinner-lg'
30
+ };
31
+
32
+ const variantClasses: Record<string, string> = {
33
+ primary: 'ap-spinner-primary',
34
+ secondary: 'ap-spinner-secondary',
35
+ success: 'ap-spinner-success',
36
+ danger: 'ap-spinner-danger',
37
+ warning: 'ap-spinner-warning',
38
+ info: 'ap-spinner-info',
39
+ light: 'ap-spinner-light',
40
+ dark: 'ap-spinner-dark',
41
+ gradient: 'ap-spinner-gradient'
42
+ };
43
+
44
+ const containerClass = $derived([
45
+ 'ap-loading',
46
+ fullScreen ? 'ap-loading-fullscreen' : '',
47
+ centered ? 'ap-loading-centered' : '',
48
+ additionalClasses
49
+ ].filter(Boolean).join(' '));
50
+ </script>
51
+
52
+ <div class={containerClass}>
53
+ <div class="ap-loading-content">
54
+ <div class="ap-spinner {sizeClasses[size]} {variantClasses[variant]}" role="status">
55
+ <span class="visually-hidden">{message}</span>
56
+ </div>
57
+ {#if message}
58
+ <p class="ap-loading-message">{message}</p>
59
+ {/if}
60
+ </div>
61
+ </div>
62
+
63
+ <style>
64
+ /* ============================================
65
+ LOADING SPINNER - AgendaPet Design System
66
+ ============================================ */
67
+ .ap-loading {
68
+ display: flex;
69
+ justify-content: center;
70
+ align-items: center;
71
+ }
72
+
73
+ .ap-loading-centered {
74
+ padding: var(--spacing-2xl);
75
+ min-height: 200px;
76
+ }
77
+
78
+ .ap-loading-fullscreen {
79
+ position: fixed;
80
+ top: 0;
81
+ left: 0;
82
+ right: 0;
83
+ bottom: 0;
84
+ min-height: 100vh;
85
+ background: rgba(255, 255, 255, 0.95);
86
+ z-index: var(--z-modal);
87
+ backdrop-filter: blur(2px);
88
+ }
89
+
90
+ .ap-loading-content {
91
+ display: flex;
92
+ flex-direction: column;
93
+ align-items: center;
94
+ gap: var(--spacing-md);
95
+ }
96
+
97
+ /* ===== SPINNER BASE ===== */
98
+ .ap-spinner {
99
+ border: 4px solid rgba(0, 0, 0, 0.1);
100
+ border-radius: 50%;
101
+ animation: ap-spin 1s linear infinite;
102
+ position: relative;
103
+ }
104
+
105
+ .ap-spinner::after {
106
+ content: '';
107
+ position: absolute;
108
+ top: -4px;
109
+ left: -4px;
110
+ right: -4px;
111
+ bottom: -4px;
112
+ border: 4px solid transparent;
113
+ border-radius: 50%;
114
+ animation: ap-spin 1s linear infinite reverse;
115
+ }
116
+
117
+ /* ===== SIZES ===== */
118
+ .ap-spinner-sm {
119
+ width: 1.5rem;
120
+ height: 1.5rem;
121
+ border-width: 2px;
122
+ }
123
+
124
+ .ap-spinner-sm::after {
125
+ top: -2px;
126
+ left: -2px;
127
+ right: -2px;
128
+ bottom: -2px;
129
+ border-width: 2px;
130
+ }
131
+
132
+ .ap-spinner-md {
133
+ width: 3rem;
134
+ height: 3rem;
135
+ border-width: 4px;
136
+ }
137
+
138
+ .ap-spinner-lg {
139
+ width: 4rem;
140
+ height: 4rem;
141
+ border-width: 5px;
142
+ }
143
+
144
+ .ap-spinner-lg::after {
145
+ top: -5px;
146
+ left: -5px;
147
+ right: -5px;
148
+ bottom: -5px;
149
+ border-width: 5px;
150
+ }
151
+
152
+ /* ===== COLOR VARIANTS ===== */
153
+ .ap-spinner-primary {
154
+ border-left-color: var(--color-primary);
155
+ }
156
+
157
+ .ap-spinner-primary::after {
158
+ border-top-color: var(--color-primary);
159
+ }
160
+
161
+ .ap-spinner-secondary {
162
+ border-left-color: var(--color-secondary);
163
+ }
164
+
165
+ .ap-spinner-secondary::after {
166
+ border-top-color: var(--color-secondary);
167
+ }
168
+
169
+ .ap-spinner-success {
170
+ border-left-color: var(--color-success);
171
+ }
172
+
173
+ .ap-spinner-success::after {
174
+ border-top-color: var(--color-success);
175
+ }
176
+
177
+ .ap-spinner-danger {
178
+ border-left-color: var(--color-danger);
179
+ }
180
+
181
+ .ap-spinner-danger::after {
182
+ border-top-color: var(--color-danger);
183
+ }
184
+
185
+ .ap-spinner-warning {
186
+ border-left-color: var(--color-warning);
187
+ }
188
+
189
+ .ap-spinner-warning::after {
190
+ border-top-color: var(--color-warning);
191
+ }
192
+
193
+ .ap-spinner-info {
194
+ border-left-color: var(--color-info);
195
+ }
196
+
197
+ .ap-spinner-info::after {
198
+ border-top-color: var(--color-info);
199
+ }
200
+
201
+ .ap-spinner-light {
202
+ border-left-color: var(--color-gray-300);
203
+ }
204
+
205
+ .ap-spinner-light::after {
206
+ border-top-color: var(--color-gray-300);
207
+ }
208
+
209
+ .ap-spinner-dark {
210
+ border-left-color: var(--color-gray-900);
211
+ }
212
+
213
+ .ap-spinner-dark::after {
214
+ border-top-color: var(--color-gray-900);
215
+ }
216
+
217
+ /* Gradient variant */
218
+ .ap-spinner-gradient {
219
+ border-left-color: #7B3FF2;
220
+ border-top-color: #15B9FF;
221
+ }
222
+
223
+ .ap-spinner-gradient::after {
224
+ border-top-color: #E414FF;
225
+ border-right-color: #7B3FF2;
226
+ }
227
+
228
+ /* ===== MESSAGE ===== */
229
+ .ap-loading-message {
230
+ color: var(--color-text-muted);
231
+ font-size: var(--font-size-sm);
232
+ margin: 0;
233
+ font-weight: var(--font-weight-medium);
234
+ }
235
+
236
+ /* ===== ANIMATION ===== */
237
+ @keyframes ap-spin {
238
+ to {
239
+ transform: rotate(360deg);
240
+ }
241
+ }
242
+
243
+ /* ===== RESPONSIVE ===== */
244
+ @media (max-width: 576px) {
245
+ .ap-loading-centered {
246
+ padding: var(--spacing-xl);
247
+ }
248
+
249
+ .ap-loading-message {
250
+ font-size: var(--font-size-xs);
251
+ }
252
+ }
253
+ </style>
@@ -0,0 +1,17 @@
1
+ interface LoadingSpinnerProps {
2
+ /** Mensagem de carregamento */
3
+ message?: string;
4
+ /** Tamanho do spinner */
5
+ size?: 'sm' | 'md' | 'lg';
6
+ /** Variante de cor */
7
+ variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark' | 'gradient';
8
+ /** Ocupar tela inteira */
9
+ fullScreen?: boolean;
10
+ /** Centralizado */
11
+ centered?: boolean;
12
+ /** Classes CSS adicionais */
13
+ class?: string;
14
+ }
15
+ declare const LoadingSpinner: import("svelte").Component<LoadingSpinnerProps, {}, "">;
16
+ type LoadingSpinner = ReturnType<typeof LoadingSpinner>;
17
+ export default LoadingSpinner;