@aiaiai-pt/design-system 0.1.0 → 0.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.
- package/components/Panel.svelte +80 -35
- package/package.json +2 -2
- package/tokens/components.css +4 -0
package/components/Panel.svelte
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Panel
|
|
3
3
|
|
|
4
|
-
Slide-over drawer surface. Opens from the right edge.
|
|
4
|
+
Slide-over drawer surface. Opens from the left or right edge.
|
|
5
5
|
Consumes --panel-* tokens from components.css.
|
|
6
6
|
|
|
7
|
-
@example
|
|
7
|
+
@example Right (default)
|
|
8
8
|
<Panel open={showEditor} title="Edit Step" onclose={() => showEditor = false}>
|
|
9
9
|
Panel content here
|
|
10
10
|
</Panel>
|
|
11
11
|
|
|
12
|
-
@example
|
|
13
|
-
<Panel open
|
|
14
|
-
|
|
12
|
+
@example Left side
|
|
13
|
+
<Panel open side="left" title="History" onclose={() => showHistory = false}>
|
|
14
|
+
Navigation content
|
|
15
|
+
</Panel>
|
|
16
|
+
|
|
17
|
+
@example Persistent (no backdrop, inline layout)
|
|
18
|
+
<Panel open persistent side="left" title="History">
|
|
19
|
+
Always-visible sidebar content
|
|
15
20
|
</Panel>
|
|
16
21
|
-->
|
|
17
22
|
<script module>
|
|
@@ -21,6 +26,7 @@
|
|
|
21
26
|
<script>
|
|
22
27
|
/**
|
|
23
28
|
* @typedef {'default' | 'narrow' | 'wide'} Width
|
|
29
|
+
* @typedef {'left' | 'right'} Side
|
|
24
30
|
*/
|
|
25
31
|
|
|
26
32
|
let {
|
|
@@ -30,6 +36,10 @@
|
|
|
30
36
|
title,
|
|
31
37
|
/** @type {Width} */
|
|
32
38
|
width = 'default',
|
|
39
|
+
/** @type {Side} */
|
|
40
|
+
side = 'right',
|
|
41
|
+
/** @type {boolean} When true, removes backdrop and focus trap. Panel becomes an inline layout element. */
|
|
42
|
+
persistent = false,
|
|
33
43
|
/** @type {(() => void) | undefined} */
|
|
34
44
|
onclose,
|
|
35
45
|
/** @type {string} */
|
|
@@ -49,8 +59,9 @@
|
|
|
49
59
|
const FOCUSABLE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
50
60
|
|
|
51
61
|
// Focus trap: save previous focus, trap Tab, restore on close
|
|
62
|
+
// Skipped in persistent mode (panel is inline, not modal)
|
|
52
63
|
$effect(() => {
|
|
53
|
-
if (!open || !panelEl) return;
|
|
64
|
+
if (!open || !panelEl || persistent) return;
|
|
54
65
|
|
|
55
66
|
const previouslyFocused = /** @type {HTMLElement | null} */ (document.activeElement);
|
|
56
67
|
|
|
@@ -95,19 +106,21 @@
|
|
|
95
106
|
</script>
|
|
96
107
|
|
|
97
108
|
{#if open}
|
|
98
|
-
<!-- Backdrop -->
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
<!-- Backdrop (hidden in persistent mode) -->
|
|
110
|
+
{#if !persistent}
|
|
111
|
+
<div
|
|
112
|
+
class="panel-backdrop"
|
|
113
|
+
onclick={handleBackdropClick}
|
|
114
|
+
aria-hidden="true"
|
|
115
|
+
></div>
|
|
116
|
+
{/if}
|
|
104
117
|
|
|
105
118
|
<!-- Panel -->
|
|
106
119
|
<aside
|
|
107
120
|
bind:this={panelEl}
|
|
108
|
-
class="panel panel-{width} {className}"
|
|
109
|
-
role=
|
|
110
|
-
aria-modal=
|
|
121
|
+
class="panel panel-{width} panel-side-{side} {persistent ? 'panel-persistent' : ''} {className}"
|
|
122
|
+
role={persistent ? 'complementary' : 'dialog'}
|
|
123
|
+
aria-modal={persistent ? undefined : 'true'}
|
|
111
124
|
aria-label={!header ? title : undefined}
|
|
112
125
|
aria-labelledby={header ? headerId : undefined}
|
|
113
126
|
{...rest}
|
|
@@ -118,15 +131,17 @@
|
|
|
118
131
|
{:else if title}
|
|
119
132
|
<h2 class="panel-title">{title}</h2>
|
|
120
133
|
{/if}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
{#if !persistent}
|
|
135
|
+
<button
|
|
136
|
+
class="panel-close"
|
|
137
|
+
onclick={onclose}
|
|
138
|
+
aria-label="Close panel"
|
|
139
|
+
>
|
|
140
|
+
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
|
141
|
+
<path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
142
|
+
</svg>
|
|
143
|
+
</button>
|
|
144
|
+
{/if}
|
|
130
145
|
</div>
|
|
131
146
|
|
|
132
147
|
<div class="panel-body">
|
|
@@ -140,23 +155,43 @@
|
|
|
140
155
|
position: fixed;
|
|
141
156
|
inset: 0;
|
|
142
157
|
background: var(--panel-backdrop);
|
|
143
|
-
z-index:
|
|
158
|
+
z-index: var(--panel-z-backdrop);
|
|
144
159
|
animation: fade-in var(--duration-normal) var(--easing-enter);
|
|
145
160
|
}
|
|
146
161
|
|
|
147
162
|
.panel {
|
|
148
163
|
position: fixed;
|
|
149
164
|
top: 0;
|
|
150
|
-
right: 0;
|
|
151
165
|
bottom: 0;
|
|
152
166
|
background: var(--panel-bg);
|
|
153
|
-
border-left: var(--panel-border);
|
|
154
167
|
box-shadow: var(--panel-shadow);
|
|
155
168
|
border-radius: var(--panel-radius);
|
|
156
|
-
z-index:
|
|
169
|
+
z-index: var(--panel-z-panel);
|
|
157
170
|
display: flex;
|
|
158
171
|
flex-direction: column;
|
|
159
|
-
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.panel-side-right {
|
|
175
|
+
right: 0;
|
|
176
|
+
border-left: var(--panel-border);
|
|
177
|
+
animation: slide-in-right var(--panel-transition);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.panel-side-left {
|
|
181
|
+
left: 0;
|
|
182
|
+
border-right: var(--panel-border);
|
|
183
|
+
animation: slide-in-left var(--panel-transition);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.panel-persistent {
|
|
187
|
+
position: relative;
|
|
188
|
+
top: auto;
|
|
189
|
+
bottom: auto;
|
|
190
|
+
z-index: auto;
|
|
191
|
+
box-shadow: none;
|
|
192
|
+
flex-shrink: 0;
|
|
193
|
+
height: 100%;
|
|
194
|
+
animation: none;
|
|
160
195
|
}
|
|
161
196
|
|
|
162
197
|
.panel-default {
|
|
@@ -198,8 +233,8 @@
|
|
|
198
233
|
display: flex;
|
|
199
234
|
align-items: center;
|
|
200
235
|
justify-content: center;
|
|
201
|
-
width:
|
|
202
|
-
height:
|
|
236
|
+
width: var(--panel-close-size);
|
|
237
|
+
height: var(--panel-close-size);
|
|
203
238
|
border-radius: var(--radius-sm);
|
|
204
239
|
color: var(--color-text-secondary);
|
|
205
240
|
transition: all var(--duration-instant) var(--easing-default);
|
|
@@ -216,8 +251,8 @@
|
|
|
216
251
|
}
|
|
217
252
|
|
|
218
253
|
.panel-close svg {
|
|
219
|
-
width:
|
|
220
|
-
height:
|
|
254
|
+
width: var(--panel-close-icon-size);
|
|
255
|
+
height: var(--panel-close-icon-size);
|
|
221
256
|
}
|
|
222
257
|
|
|
223
258
|
.panel-body {
|
|
@@ -226,7 +261,7 @@
|
|
|
226
261
|
padding: var(--panel-padding);
|
|
227
262
|
}
|
|
228
263
|
|
|
229
|
-
@keyframes slide-in {
|
|
264
|
+
@keyframes slide-in-right {
|
|
230
265
|
from {
|
|
231
266
|
transform: translateX(100%);
|
|
232
267
|
}
|
|
@@ -235,6 +270,15 @@
|
|
|
235
270
|
}
|
|
236
271
|
}
|
|
237
272
|
|
|
273
|
+
@keyframes slide-in-left {
|
|
274
|
+
from {
|
|
275
|
+
transform: translateX(-100%);
|
|
276
|
+
}
|
|
277
|
+
to {
|
|
278
|
+
transform: translateX(0);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
238
282
|
@keyframes fade-in {
|
|
239
283
|
from {
|
|
240
284
|
opacity: 0;
|
|
@@ -245,7 +289,8 @@
|
|
|
245
289
|
}
|
|
246
290
|
|
|
247
291
|
@media (prefers-reduced-motion: reduce) {
|
|
248
|
-
.panel
|
|
292
|
+
.panel-side-right,
|
|
293
|
+
.panel-side-left {
|
|
249
294
|
animation: none;
|
|
250
295
|
}
|
|
251
296
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiaiai-pt/design-system",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Design system tokens and Svelte components for aiaiai products",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/aiaiai-pt/
|
|
9
|
+
"url": "https://github.com/aiaiai-pt/sistema.git"
|
|
10
10
|
},
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "public"
|
package/tokens/components.css
CHANGED
|
@@ -279,6 +279,10 @@
|
|
|
279
279
|
--panel-padding: var(--space-lg);
|
|
280
280
|
--panel-transition: var(--duration-normal) var(--easing-enter);
|
|
281
281
|
--panel-backdrop: var(--color-overlay);
|
|
282
|
+
--panel-close-size: 28px;
|
|
283
|
+
--panel-close-icon-size: 16px;
|
|
284
|
+
--panel-z-backdrop: 200;
|
|
285
|
+
--panel-z-panel: 201;
|
|
282
286
|
|
|
283
287
|
/* ═══════════════════════════════════════════════
|
|
284
288
|
STEPPER (wizard / multi-step flow)
|