@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.
- package/README.md +125 -0
- package/dist/components/Alert.svelte +335 -0
- package/dist/components/Alert.svelte.d.ts +24 -0
- package/dist/components/AutocompleteInput.svelte +356 -0
- package/dist/components/AutocompleteInput.svelte.d.ts +72 -0
- package/dist/components/Badge.svelte +185 -0
- package/dist/components/Badge.svelte.d.ts +20 -0
- package/dist/components/Button.svelte +415 -0
- package/dist/components/Button.svelte.d.ts +34 -0
- package/dist/components/Card.svelte +181 -0
- package/dist/components/Card.svelte.d.ts +24 -0
- package/dist/components/CardBody.svelte +78 -0
- package/dist/components/CardBody.svelte.d.ts +12 -0
- package/dist/components/CardFooter.svelte +81 -0
- package/dist/components/CardFooter.svelte.d.ts +14 -0
- package/dist/components/CardHeader.svelte +186 -0
- package/dist/components/CardHeader.svelte.d.ts +21 -0
- package/dist/components/Col.svelte +172 -0
- package/dist/components/Col.svelte.d.ts +26 -0
- package/dist/components/Container.svelte +118 -0
- package/dist/components/Container.svelte.d.ts +14 -0
- package/dist/components/Drawer.svelte +233 -0
- package/dist/components/Drawer.svelte.d.ts +13 -0
- package/dist/components/Dropdown.svelte +190 -0
- package/dist/components/Dropdown.svelte.d.ts +26 -0
- package/dist/components/DropdownItem.svelte +103 -0
- package/dist/components/DropdownItem.svelte.d.ts +22 -0
- package/dist/components/DurationInput.svelte +170 -0
- package/dist/components/DurationInput.svelte.d.ts +27 -0
- package/dist/components/EditableTable.svelte +647 -0
- package/dist/components/EditableTable.svelte.d.ts +74 -0
- package/dist/components/EmptyState.svelte +192 -0
- package/dist/components/EmptyState.svelte.d.ts +22 -0
- package/dist/components/FormField.svelte +260 -0
- package/dist/components/FormField.svelte.d.ts +68 -0
- package/dist/components/GridView.svelte +1022 -0
- package/dist/components/GridView.svelte.d.ts +38 -0
- package/dist/components/GridView.types.d.ts +28 -0
- package/dist/components/GridView.types.js +1 -0
- package/dist/components/LoadingSpinner.svelte +253 -0
- package/dist/components/LoadingSpinner.svelte.d.ts +17 -0
- package/dist/components/Modal.svelte +473 -0
- package/dist/components/Modal.svelte.d.ts +42 -0
- package/dist/components/PhoneInput.svelte +406 -0
- package/dist/components/PhoneInput.svelte.d.ts +31 -0
- package/dist/components/PhotoUpload.svelte +529 -0
- package/dist/components/PhotoUpload.svelte.d.ts +46 -0
- package/dist/components/Row.svelte +153 -0
- package/dist/components/Row.svelte.d.ts +18 -0
- package/dist/icons/PawPrintIcon.svelte +41 -0
- package/dist/icons/PawPrintIcon.svelte.d.ts +14 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +49 -0
- package/dist/styles/forms.css +182 -0
- package/dist/styles/tokens.css +243 -0
- package/dist/utils/duration.d.ts +20 -0
- package/dist/utils/duration.js +40 -0
- package/dist/utils/scrollLock.d.ts +7 -0
- package/dist/utils/scrollLock.js +26 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @groundbrick/svelte-ui
|
|
2
|
+
|
|
3
|
+
Reusable **Svelte 5** UI components (design system). Themeable via CSS variables,
|
|
4
|
+
extensible via props, `class` passthrough and snippets.
|
|
5
|
+
|
|
6
|
+
These components were extracted to be reused across projects. They have sensible
|
|
7
|
+
default styling and behavior, but every visual aspect can be re-themed by
|
|
8
|
+
overriding CSS custom properties.
|
|
9
|
+
|
|
10
|
+
## Install (workspace)
|
|
11
|
+
|
|
12
|
+
```jsonc
|
|
13
|
+
// consumer app package.json
|
|
14
|
+
{
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@groundbrick/svelte-ui": "workspace:*"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Build the package before the consuming app (the monorepo build runs packages
|
|
22
|
+
first):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm -F @groundbrick/svelte-ui build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Peer dependencies
|
|
29
|
+
|
|
30
|
+
| Dependency | Required | Notes |
|
|
31
|
+
| ---------------- | -------- | ------------------------------------------------------------------ |
|
|
32
|
+
| `svelte` | yes | `^5.25.0` (runes). |
|
|
33
|
+
| `@200systems/shared` | yes | Used by `PhoneInput` (phone parsing/formatting utilities). |
|
|
34
|
+
| `bootstrap` | optional | Components use Bootstrap 5 classes (`.row`, `.dropdown`, etc.). Load its CSS/JS in the app. |
|
|
35
|
+
| `bootstrap-icons`| optional | Some built-in icons use `bi bi-*` classes. |
|
|
36
|
+
|
|
37
|
+
The consuming app is responsible for loading Bootstrap and Bootstrap Icons (as
|
|
38
|
+
the AgendaPet app already does in its root layout).
|
|
39
|
+
|
|
40
|
+
## Theming
|
|
41
|
+
|
|
42
|
+
Import the default tokens once (e.g. in your root layout), then override any CSS
|
|
43
|
+
variable to re-theme. Components reference tokens exclusively, so changing one
|
|
44
|
+
token re-skins every component that uses it.
|
|
45
|
+
|
|
46
|
+
```svelte
|
|
47
|
+
<script>
|
|
48
|
+
import '@groundbrick/svelte-ui/styles/tokens.css';
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<!-- Re-theme a subtree (e.g. per-tenant branding) by overriding variables -->
|
|
52
|
+
<div style="--color-primary: #0aa; --radius-full: 8px;">
|
|
53
|
+
<Button>Themed button</Button>
|
|
54
|
+
</div>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
You can also skip the bundled tokens entirely and define your own
|
|
58
|
+
`--color-primary`, `--spacing-*`, `--radius-*`, `--shadow-*`, etc.
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
```svelte
|
|
63
|
+
<script lang="ts">
|
|
64
|
+
import { Button, Card, CardBody, Alert, Badge, EmptyState } from '@groundbrick/svelte-ui';
|
|
65
|
+
import '@groundbrick/svelte-ui/styles/tokens.css';
|
|
66
|
+
|
|
67
|
+
let saving = $state(false);
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<Card variant="elevated">
|
|
71
|
+
<CardBody>
|
|
72
|
+
<Alert variant="info">Welcome back!</Alert>
|
|
73
|
+
<Badge variant="success">Active</Badge>
|
|
74
|
+
<Button variant="primary" loading={saving} onclick={() => (saving = true)}>
|
|
75
|
+
Save
|
|
76
|
+
</Button>
|
|
77
|
+
</CardBody>
|
|
78
|
+
</Card>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Components
|
|
82
|
+
|
|
83
|
+
| Component | Purpose |
|
|
84
|
+
| ------------------------------------------ | --------------------------------------------------- |
|
|
85
|
+
| `Button` | Button/link with variants, sizes and loading state. |
|
|
86
|
+
| `Dropdown`, `DropdownItem` | Bootstrap-based dropdown menu. |
|
|
87
|
+
| `Card`, `CardHeader`, `CardBody`, `CardFooter` | Card primitives. |
|
|
88
|
+
| `FormField` | Labelled input/textarea/select field. |
|
|
89
|
+
| `PhoneInput` | E.164 phone input with country selector. |
|
|
90
|
+
| `DurationInput` | Hours + minutes duration input. |
|
|
91
|
+
| `AutocompleteInput` | Async/debounced autocomplete field. |
|
|
92
|
+
| `Badge` | Pill/solid badges with variants. |
|
|
93
|
+
| `EmptyState` | Empty-state placeholder with illustration. |
|
|
94
|
+
| `LoadingSpinner` | Centered/full-screen spinner. |
|
|
95
|
+
| `Container`, `Row`, `Col` | Lightweight flex layout helpers. |
|
|
96
|
+
| `Modal`, `Drawer` | Overlays (with body scroll lock). |
|
|
97
|
+
| `GridView` | Responsive data grid: search, sort, pagination, drag-reorder, row actions. |
|
|
98
|
+
| `EditableTable` | Inline-editable table with add/remove rows. |
|
|
99
|
+
| `PhotoUpload` | Headless photo uploader (upload/remove/compress via callbacks). |
|
|
100
|
+
| `PawPrintIcon` | Inline SVG paw icon. |
|
|
101
|
+
|
|
102
|
+
### Dependency-injection props (decoupled components)
|
|
103
|
+
|
|
104
|
+
Some components delegate app-specific concerns through props instead of importing
|
|
105
|
+
app code:
|
|
106
|
+
|
|
107
|
+
- **`GridView`**: `resolveImageUrl(value, folder)` (image cells), `formatDate(value)`
|
|
108
|
+
(date cells, defaults to pt-PT), `hasPermission(code)` (row-action gating,
|
|
109
|
+
defaults to allow-all).
|
|
110
|
+
- **`PhotoUpload`** (headless): `onUpload(file, { folder })` returns the uploaded
|
|
111
|
+
URL, `onRemove()` deletes, optional `compress(file, opts)`, plus
|
|
112
|
+
`onError`/`onFileSelected`/`onUploaded`/`onRemoved` notifications.
|
|
113
|
+
|
|
114
|
+
### Utilities
|
|
115
|
+
|
|
116
|
+
- `lockBodyScroll()`, `unlockBodyScroll()` - reference-counted body scroll lock.
|
|
117
|
+
- `minutesToHoursAndMinutes()`, `hoursAndMinutesToMinutes()` - duration helpers.
|
|
118
|
+
|
|
119
|
+
## Notes
|
|
120
|
+
|
|
121
|
+
- Components are decoupled from any app: permission/feature gating present in the
|
|
122
|
+
original AgendaPet `Button`/`DropdownItem` was intentionally removed here, and
|
|
123
|
+
app utilities used by `GridView`/`PhotoUpload` are injected via props.
|
|
124
|
+
- `GridView` keeps the original Svelte 4 (`export let`) syntax; Svelte 5 runs it
|
|
125
|
+
in legacy mode. All other components use runes.
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
interface AlertProps {
|
|
5
|
+
/** Variante semântica do alerta */
|
|
6
|
+
variant?: 'success' | 'info' | 'warning' | 'danger' | 'primary' | 'secondary';
|
|
7
|
+
/** Título do alerta (opcional) */
|
|
8
|
+
title?: string;
|
|
9
|
+
/** Permite fechar o alerta */
|
|
10
|
+
dismissible?: boolean;
|
|
11
|
+
/** Ícone customizado (Bootstrap Icons class) */
|
|
12
|
+
icon?: string;
|
|
13
|
+
/** Mostrar inline (sem margem inferior) */
|
|
14
|
+
inline?: boolean;
|
|
15
|
+
/** Estilo compacto (pill shape, sem título) */
|
|
16
|
+
compact?: boolean;
|
|
17
|
+
/** Classes CSS adicionais */
|
|
18
|
+
class?: string;
|
|
19
|
+
/** Callback ao fechar */
|
|
20
|
+
ondismiss?: () => void;
|
|
21
|
+
/** Conteúdo do alerta */
|
|
22
|
+
children?: Snippet;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
variant = 'info',
|
|
27
|
+
title,
|
|
28
|
+
dismissible = false,
|
|
29
|
+
icon,
|
|
30
|
+
inline = false,
|
|
31
|
+
compact = false,
|
|
32
|
+
class: additionalClasses = '',
|
|
33
|
+
ondismiss,
|
|
34
|
+
children
|
|
35
|
+
}: AlertProps = $props();
|
|
36
|
+
|
|
37
|
+
let visible = $state(true);
|
|
38
|
+
|
|
39
|
+
// Ícones padrão por variante
|
|
40
|
+
const defaultIcons: Record<string, string> = {
|
|
41
|
+
success: 'bi-check-circle-fill',
|
|
42
|
+
info: 'bi-info-circle-fill',
|
|
43
|
+
warning: 'bi-exclamation-triangle-fill',
|
|
44
|
+
danger: 'bi-x-circle-fill',
|
|
45
|
+
primary: 'bi-bell-fill',
|
|
46
|
+
secondary: 'bi-chat-fill'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const alertIcon = $derived(icon ?? defaultIcons[variant]);
|
|
50
|
+
|
|
51
|
+
function handleDismiss() {
|
|
52
|
+
visible = false;
|
|
53
|
+
ondismiss?.();
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
{#if visible}
|
|
58
|
+
{#if compact}
|
|
59
|
+
<!-- Compact/Inline Alert (pill shape) -->
|
|
60
|
+
<div
|
|
61
|
+
class="ap-alert-compact ap-alert-compact-{variant} {additionalClasses}"
|
|
62
|
+
class:ap-alert-inline={inline}
|
|
63
|
+
role="alert"
|
|
64
|
+
>
|
|
65
|
+
{#if alertIcon}
|
|
66
|
+
<i class="{alertIcon} ap-alert-compact-icon"></i>
|
|
67
|
+
{/if}
|
|
68
|
+
{#if children}
|
|
69
|
+
{@render children()}
|
|
70
|
+
{/if}
|
|
71
|
+
</div>
|
|
72
|
+
{:else}
|
|
73
|
+
<!-- Standard Alert with icon badge -->
|
|
74
|
+
<div
|
|
75
|
+
class="ap-alert ap-alert-{variant} {additionalClasses}"
|
|
76
|
+
class:ap-alert-inline={inline}
|
|
77
|
+
role="alert"
|
|
78
|
+
>
|
|
79
|
+
<div class="ap-alert-icon">
|
|
80
|
+
<i class={alertIcon}></i>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="ap-alert-content">
|
|
83
|
+
{#if title}
|
|
84
|
+
<div class="ap-alert-title">{title}</div>
|
|
85
|
+
{/if}
|
|
86
|
+
{#if children}
|
|
87
|
+
<div class="ap-alert-message">
|
|
88
|
+
{@render children()}
|
|
89
|
+
</div>
|
|
90
|
+
{/if}
|
|
91
|
+
</div>
|
|
92
|
+
{#if dismissible}
|
|
93
|
+
<button
|
|
94
|
+
type="button"
|
|
95
|
+
class="ap-alert-close"
|
|
96
|
+
onclick={handleDismiss}
|
|
97
|
+
aria-label="Fechar"
|
|
98
|
+
>
|
|
99
|
+
<i class="bi-x-lg"></i>
|
|
100
|
+
</button>
|
|
101
|
+
{/if}
|
|
102
|
+
</div>
|
|
103
|
+
{/if}
|
|
104
|
+
{/if}
|
|
105
|
+
|
|
106
|
+
<style>
|
|
107
|
+
/* ============================================
|
|
108
|
+
ALERT - AgendaPet Design System
|
|
109
|
+
============================================ */
|
|
110
|
+
|
|
111
|
+
/* Standard Alert */
|
|
112
|
+
.ap-alert {
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
gap: 0.875rem;
|
|
116
|
+
padding: 1rem 1.25rem;
|
|
117
|
+
border-radius: var(--radius-lg);
|
|
118
|
+
margin-bottom: var(--spacing-md);
|
|
119
|
+
border: 1px solid;
|
|
120
|
+
position: relative;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.ap-alert-inline {
|
|
124
|
+
margin-bottom: 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Icon Badge */
|
|
128
|
+
.ap-alert-icon {
|
|
129
|
+
flex-shrink: 0;
|
|
130
|
+
width: 32px;
|
|
131
|
+
height: 32px;
|
|
132
|
+
border-radius: 8px;
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
font-size: 1rem;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Content */
|
|
140
|
+
.ap-alert-content {
|
|
141
|
+
flex: 1;
|
|
142
|
+
min-width: 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.ap-alert-title {
|
|
146
|
+
font-size: var(--font-size-sm);
|
|
147
|
+
font-weight: var(--font-weight-medium);
|
|
148
|
+
margin-bottom: 0.25rem;
|
|
149
|
+
line-height: 1.4;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.ap-alert-message {
|
|
153
|
+
font-size: var(--font-size-xs);
|
|
154
|
+
line-height: 1.4;
|
|
155
|
+
opacity: 0.85;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.ap-alert-message :global(p:last-child) {
|
|
159
|
+
margin-bottom: 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Close Button */
|
|
163
|
+
.ap-alert-close {
|
|
164
|
+
flex-shrink: 0;
|
|
165
|
+
background: transparent;
|
|
166
|
+
border: none;
|
|
167
|
+
padding: 0.25rem;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
opacity: 0.5;
|
|
170
|
+
transition: opacity var(--transition-fast);
|
|
171
|
+
border-radius: var(--radius-sm);
|
|
172
|
+
line-height: 1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.ap-alert-close:hover {
|
|
176
|
+
opacity: 1;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.ap-alert-close:focus-visible {
|
|
180
|
+
outline: 2px solid currentColor;
|
|
181
|
+
outline-offset: 2px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* ===== STANDARD VARIANTS ===== */
|
|
185
|
+
|
|
186
|
+
/* Success */
|
|
187
|
+
.ap-alert-success {
|
|
188
|
+
background-color: var(--color-success-bg);
|
|
189
|
+
border-color: var(--color-success-border) !important;
|
|
190
|
+
color: var(--color-success-text);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.ap-alert-success .ap-alert-icon {
|
|
194
|
+
background-color: rgba(24, 183, 126, 0.15);
|
|
195
|
+
color: var(--color-success);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Info */
|
|
199
|
+
.ap-alert-info {
|
|
200
|
+
background-color: var(--color-info-bg);
|
|
201
|
+
border-color: var(--color-info-border) !important;
|
|
202
|
+
color: var(--color-info-text);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.ap-alert-info .ap-alert-icon {
|
|
206
|
+
background-color: rgba(24, 167, 214, 0.15);
|
|
207
|
+
color: var(--color-info);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* Warning */
|
|
211
|
+
.ap-alert-warning {
|
|
212
|
+
background-color: var(--color-warning-bg);
|
|
213
|
+
border-color: var(--color-warning-border) !important;
|
|
214
|
+
color: var(--color-warning-text);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.ap-alert-warning .ap-alert-icon {
|
|
218
|
+
background-color: rgba(242, 183, 5, 0.15);
|
|
219
|
+
color: #D99E00;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* Danger */
|
|
223
|
+
.ap-alert-danger {
|
|
224
|
+
background-color: var(--color-danger-bg);
|
|
225
|
+
border-color: var(--color-danger-border) !important;
|
|
226
|
+
color: var(--color-danger-text);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.ap-alert-danger .ap-alert-icon {
|
|
230
|
+
background-color: rgba(228, 71, 90, 0.15);
|
|
231
|
+
color: var(--color-danger);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Primary */
|
|
235
|
+
.ap-alert-primary {
|
|
236
|
+
background-color: var(--color-primary-light);
|
|
237
|
+
border-color: var(--color-primary) !important;
|
|
238
|
+
color: var(--color-primary-dark);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.ap-alert-primary .ap-alert-icon {
|
|
242
|
+
background-color: rgba(123, 63, 242, 0.15);
|
|
243
|
+
color: var(--color-primary);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* Secondary */
|
|
247
|
+
.ap-alert-secondary {
|
|
248
|
+
background-color: var(--color-gray-100);
|
|
249
|
+
border-color: var(--color-gray-300) !important;
|
|
250
|
+
color: var(--color-gray-700);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.ap-alert-secondary .ap-alert-icon {
|
|
254
|
+
background-color: rgba(108, 117, 125, 0.15);
|
|
255
|
+
color: var(--color-secondary);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* ============================================
|
|
259
|
+
COMPACT ALERT (Pill shape)
|
|
260
|
+
============================================ */
|
|
261
|
+
.ap-alert-compact {
|
|
262
|
+
display: inline-flex;
|
|
263
|
+
align-items: center;
|
|
264
|
+
gap: 0.5rem;
|
|
265
|
+
padding: 0.5rem 0.875rem;
|
|
266
|
+
border-radius: var(--radius-full);
|
|
267
|
+
font-size: var(--font-size-xs);
|
|
268
|
+
font-weight: var(--font-weight-medium);
|
|
269
|
+
margin-bottom: var(--spacing-sm);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.ap-alert-compact.ap-alert-inline {
|
|
273
|
+
margin-bottom: 0;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.ap-alert-compact-icon {
|
|
277
|
+
flex-shrink: 0;
|
|
278
|
+
font-size: 0.875rem;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Compact Variants */
|
|
282
|
+
.ap-alert-compact-success {
|
|
283
|
+
background-color: var(--color-success-bg);
|
|
284
|
+
color: var(--color-success-text);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.ap-alert-compact-success .ap-alert-compact-icon {
|
|
288
|
+
color: var(--color-success);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.ap-alert-compact-info {
|
|
292
|
+
background-color: var(--color-info-bg);
|
|
293
|
+
color: var(--color-info-text);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.ap-alert-compact-info .ap-alert-compact-icon {
|
|
297
|
+
color: var(--color-info);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.ap-alert-compact-warning {
|
|
301
|
+
background-color: var(--color-warning-bg);
|
|
302
|
+
color: var(--color-warning-text);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.ap-alert-compact-warning .ap-alert-compact-icon {
|
|
306
|
+
color: #D99E00;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.ap-alert-compact-danger {
|
|
310
|
+
background-color: var(--color-danger-bg);
|
|
311
|
+
color: var(--color-danger-text);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.ap-alert-compact-danger .ap-alert-compact-icon {
|
|
315
|
+
color: var(--color-danger);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.ap-alert-compact-primary {
|
|
319
|
+
background-color: var(--color-primary-light);
|
|
320
|
+
color: var(--color-primary-dark);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.ap-alert-compact-primary .ap-alert-compact-icon {
|
|
324
|
+
color: var(--color-primary);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.ap-alert-compact-secondary {
|
|
328
|
+
background-color: var(--color-gray-100);
|
|
329
|
+
color: var(--color-gray-700);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.ap-alert-compact-secondary .ap-alert-compact-icon {
|
|
333
|
+
color: var(--color-secondary);
|
|
334
|
+
}
|
|
335
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
interface AlertProps {
|
|
3
|
+
/** Variante semântica do alerta */
|
|
4
|
+
variant?: 'success' | 'info' | 'warning' | 'danger' | 'primary' | 'secondary';
|
|
5
|
+
/** Título do alerta (opcional) */
|
|
6
|
+
title?: string;
|
|
7
|
+
/** Permite fechar o alerta */
|
|
8
|
+
dismissible?: boolean;
|
|
9
|
+
/** Ícone customizado (Bootstrap Icons class) */
|
|
10
|
+
icon?: string;
|
|
11
|
+
/** Mostrar inline (sem margem inferior) */
|
|
12
|
+
inline?: boolean;
|
|
13
|
+
/** Estilo compacto (pill shape, sem título) */
|
|
14
|
+
compact?: boolean;
|
|
15
|
+
/** Classes CSS adicionais */
|
|
16
|
+
class?: string;
|
|
17
|
+
/** Callback ao fechar */
|
|
18
|
+
ondismiss?: () => void;
|
|
19
|
+
/** Conteúdo do alerta */
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
}
|
|
22
|
+
declare const Alert: import("svelte").Component<AlertProps, {}, "">;
|
|
23
|
+
type Alert = ReturnType<typeof Alert>;
|
|
24
|
+
export default Alert;
|