@1001-digital/layers.base 0.0.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/.editorconfig +12 -0
- package/.nuxtrc +1 -0
- package/.playground/app.config.ts +5 -0
- package/.playground/app.vue +3 -0
- package/.playground/nuxt.config.ts +12 -0
- package/.playground/pages/index.vue +626 -0
- package/AGENTS.md +51 -0
- package/README.md +13 -0
- package/app/app.vue +3 -0
- package/app/assets/styles/base/base.css +52 -0
- package/app/assets/styles/base/forms.css +129 -0
- package/app/assets/styles/base/reset.css +159 -0
- package/app/assets/styles/index.css +28 -0
- package/app/assets/styles/utilities/animations.css +77 -0
- package/app/assets/styles/utilities/utilities.css +58 -0
- package/app/assets/styles/variables/borders.css +18 -0
- package/app/assets/styles/variables/colors.css +75 -0
- package/app/assets/styles/variables/components/alerts.css +13 -0
- package/app/assets/styles/variables/components/buttons.css +18 -0
- package/app/assets/styles/variables/components/cards.css +7 -0
- package/app/assets/styles/variables/components/dialogs.css +7 -0
- package/app/assets/styles/variables/components/forms.css +5 -0
- package/app/assets/styles/variables/components/images.css +5 -0
- package/app/assets/styles/variables/components/index.css +6 -0
- package/app/assets/styles/variables/effects.css +3 -0
- package/app/assets/styles/variables/fonts.css +36 -0
- package/app/assets/styles/variables/index.css +15 -0
- package/app/assets/styles/variables/layout.css +7 -0
- package/app/assets/styles/variables/sizes.css +24 -0
- package/app/assets/styles/variables/timing.css +5 -0
- package/app/assets/styles/variables/ui.css +18 -0
- package/app/assets/styles/variables/z-index.css +7 -0
- package/app/components/Actions.vue +57 -0
- package/app/components/Alert.vue +78 -0
- package/app/components/Button.vue +196 -0
- package/app/components/Card.vue +62 -0
- package/app/components/Dialog.client.vue +217 -0
- package/app/components/Form/Form.vue +27 -0
- package/app/components/Form/FormCheckbox.vue +88 -0
- package/app/components/Form/FormGroup.vue +36 -0
- package/app/components/Form/FormInputGroup.vue +55 -0
- package/app/components/Form/FormItem.vue +53 -0
- package/app/components/Form/FormLabel.vue +39 -0
- package/app/components/Form/FormRadioGroup.vue +109 -0
- package/app/components/Form/FormSelect.vue +155 -0
- package/app/components/HelloWorld.vue +10 -0
- package/app/components/Icon.vue +48 -0
- package/app/components/Loading.vue +58 -0
- package/app/components/Tag.vue +47 -0
- package/app/components/Tags.vue +13 -0
- package/app.config.ts +14 -0
- package/eslint.config.js +3 -0
- package/nuxt.config.ts +19 -0
- package/package.json +29 -0
- package/tsconfig.json +3 -0
package/.editorconfig
ADDED
package/.nuxtrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
typescript.includeWorkspace = true
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
|
|
3
|
+
export default defineNuxtConfig({
|
|
4
|
+
extends: ['..'],
|
|
5
|
+
modules: ['@nuxt/eslint'],
|
|
6
|
+
eslint: {
|
|
7
|
+
config: {
|
|
8
|
+
// Use the generated ESLint config for lint root project as well
|
|
9
|
+
rootDir: fileURLToPath(new URL('..', import.meta.url))
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
})
|
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<main class="library">
|
|
3
|
+
<header class="library-header">
|
|
4
|
+
<h1>Base Layer Component Library</h1>
|
|
5
|
+
<nav class="library-nav">
|
|
6
|
+
<a href="#colors">Colors</a>
|
|
7
|
+
<a href="#typography">Typography</a>
|
|
8
|
+
<a href="#spacing">Spacing</a>
|
|
9
|
+
<a href="#icons">Icons</a>
|
|
10
|
+
<a href="#buttons">Buttons</a>
|
|
11
|
+
<a href="#alerts">Alerts</a>
|
|
12
|
+
<a href="#cards">Cards</a>
|
|
13
|
+
<a href="#tags">Tags</a>
|
|
14
|
+
<a href="#forms">Forms</a>
|
|
15
|
+
<a href="#actions">Actions</a>
|
|
16
|
+
<a href="#dialogs">Dialogs</a>
|
|
17
|
+
</nav>
|
|
18
|
+
</header>
|
|
19
|
+
|
|
20
|
+
<!-- Design Tokens -->
|
|
21
|
+
<section id="design-tokens">
|
|
22
|
+
<h2>Design Tokens</h2>
|
|
23
|
+
|
|
24
|
+
<!-- Colors -->
|
|
25
|
+
<article id="colors">
|
|
26
|
+
<h3>Colors</h3>
|
|
27
|
+
|
|
28
|
+
<div class="token-group">
|
|
29
|
+
<h4>Gray Scale</h4>
|
|
30
|
+
<div class="color-grid">
|
|
31
|
+
<div v-for="shade in grayShades" :key="shade" class="color-swatch">
|
|
32
|
+
<div :style="{ background: `var(--gray-${shade})` }" />
|
|
33
|
+
<code>--gray-{{ shade }}</code>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="token-group">
|
|
39
|
+
<h4>Z-Colors (Theme Aware)</h4>
|
|
40
|
+
<div class="color-grid">
|
|
41
|
+
<div v-for="z in zColors" :key="z" class="color-swatch">
|
|
42
|
+
<div :style="{ background: `var(--gray-z-${z})` }" />
|
|
43
|
+
<code>--gray-z-{{ z }}</code>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="token-group">
|
|
49
|
+
<h4>Semantic Colors</h4>
|
|
50
|
+
<div class="color-grid">
|
|
51
|
+
<div v-for="color in semanticColors" :key="color" class="color-swatch">
|
|
52
|
+
<div :style="{ background: `var(--${color})` }" />
|
|
53
|
+
<code>--{{ color }}</code>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</article>
|
|
58
|
+
|
|
59
|
+
<!-- Typography -->
|
|
60
|
+
<article id="typography">
|
|
61
|
+
<h3>Typography</h3>
|
|
62
|
+
|
|
63
|
+
<div class="token-group">
|
|
64
|
+
<h4>Font Sizes</h4>
|
|
65
|
+
<div class="type-samples">
|
|
66
|
+
<div v-for="size in fontSizes" :key="size" class="type-sample">
|
|
67
|
+
<span :style="{ fontSize: `var(--font-${size})` }">The quick brown fox</span>
|
|
68
|
+
<code>--font-{{ size }}</code>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="token-group">
|
|
74
|
+
<h4>UI Typography</h4>
|
|
75
|
+
<div class="type-sample">
|
|
76
|
+
<span class="ui-text">UI Font Style (Monospace, Uppercase)</span>
|
|
77
|
+
<code>--ui-font-family</code>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</article>
|
|
81
|
+
|
|
82
|
+
<!-- Spacing -->
|
|
83
|
+
<article id="spacing">
|
|
84
|
+
<h3>Spacing</h3>
|
|
85
|
+
|
|
86
|
+
<div class="token-group">
|
|
87
|
+
<h4>Size Scale</h4>
|
|
88
|
+
<div class="spacing-samples">
|
|
89
|
+
<div v-for="n in sizes" :key="n" class="spacing-sample">
|
|
90
|
+
<div class="spacing-box" :style="{ width: `var(--size-${n})`, height: `var(--size-${n})` }" />
|
|
91
|
+
<code>--size-{{ n }}</code>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="token-group">
|
|
97
|
+
<h4>Semantic Spacers</h4>
|
|
98
|
+
<div class="spacing-samples">
|
|
99
|
+
<div v-for="spacer in spacers" :key="spacer" class="spacing-sample">
|
|
100
|
+
<div class="spacing-box"
|
|
101
|
+
:style="{ width: `var(--spacer${spacer === 'default' ? '' : `-${spacer}`})`, height: `var(--spacer${spacer === 'default' ? '' : `-${spacer}`})` }" />
|
|
102
|
+
<code>--spacer{{ spacer === 'default' ? '' : `-${spacer}` }}</code>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</article>
|
|
107
|
+
</section>
|
|
108
|
+
|
|
109
|
+
<!-- Components -->
|
|
110
|
+
<section id="components">
|
|
111
|
+
<h2>Components</h2>
|
|
112
|
+
|
|
113
|
+
<!-- Icon -->
|
|
114
|
+
<article id="icons">
|
|
115
|
+
<h3>Icon</h3>
|
|
116
|
+
<div class="icon-grid">
|
|
117
|
+
<div v-for="type in iconTypes" :key="type" class="icon-sample">
|
|
118
|
+
<Icon :type="type" />
|
|
119
|
+
<code>{{ type }}</code>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</article>
|
|
123
|
+
|
|
124
|
+
<!-- Button -->
|
|
125
|
+
<article id="buttons">
|
|
126
|
+
<h3>Button</h3>
|
|
127
|
+
|
|
128
|
+
<div class="component-demo">
|
|
129
|
+
<h4>Default</h4>
|
|
130
|
+
<div class="demo-row">
|
|
131
|
+
<Button>Default</Button>
|
|
132
|
+
<Button disabled>Disabled</Button>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<div class="component-demo">
|
|
137
|
+
<h4>Variants</h4>
|
|
138
|
+
<div class="demo-row">
|
|
139
|
+
<Button class="primary">Primary</Button>
|
|
140
|
+
<Button class="small">Small</Button>
|
|
141
|
+
<Button class="link">Link</Button>
|
|
142
|
+
<Button class="inline">Inline</Button>
|
|
143
|
+
<Button class="danger">Danger</Button>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="component-demo">
|
|
148
|
+
<h4>With Icons</h4>
|
|
149
|
+
<div class="demo-row">
|
|
150
|
+
<Button>
|
|
151
|
+
<Icon type="add" />
|
|
152
|
+
<span>Add Item</span>
|
|
153
|
+
</Button>
|
|
154
|
+
<Button class="primary">
|
|
155
|
+
<Icon type="check" />
|
|
156
|
+
<span>Confirm</span>
|
|
157
|
+
</Button>
|
|
158
|
+
<Button>
|
|
159
|
+
<Icon type="edit" />
|
|
160
|
+
</Button>
|
|
161
|
+
<Button class="small">
|
|
162
|
+
<Icon type="edit" />
|
|
163
|
+
</Button>
|
|
164
|
+
<Button class="link">
|
|
165
|
+
<Icon type="link" />
|
|
166
|
+
<span>Link</span>
|
|
167
|
+
</Button>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
</article>
|
|
171
|
+
|
|
172
|
+
<!-- Alert -->
|
|
173
|
+
<article id="alerts">
|
|
174
|
+
<h3>Alert</h3>
|
|
175
|
+
|
|
176
|
+
<div class="component-demo">
|
|
177
|
+
<h4>Info (Default)</h4>
|
|
178
|
+
<Alert type="info">
|
|
179
|
+
<h1>Information</h1>
|
|
180
|
+
<p>This is an informational alert message.</p>
|
|
181
|
+
</Alert>
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<div class="component-demo">
|
|
185
|
+
<h4>Error</h4>
|
|
186
|
+
<Alert type="error">
|
|
187
|
+
<h1>Error</h1>
|
|
188
|
+
<p>Something went wrong. Please try again.</p>
|
|
189
|
+
</Alert>
|
|
190
|
+
</div>
|
|
191
|
+
</article>
|
|
192
|
+
|
|
193
|
+
<!-- Card -->
|
|
194
|
+
<article id="cards">
|
|
195
|
+
<h3>Card</h3>
|
|
196
|
+
|
|
197
|
+
<div class="component-demo">
|
|
198
|
+
<div class="card-grid">
|
|
199
|
+
<Card>
|
|
200
|
+
<h4>Default Card</h4>
|
|
201
|
+
<p>Card content goes here.</p>
|
|
202
|
+
</Card>
|
|
203
|
+
|
|
204
|
+
<Card class="borderless">
|
|
205
|
+
<h4>Borderless</h4>
|
|
206
|
+
<p>Card without border.</p>
|
|
207
|
+
</Card>
|
|
208
|
+
|
|
209
|
+
<Card class="highlight">
|
|
210
|
+
<h4>Highlight</h4>
|
|
211
|
+
<p>Card with highlight background.</p>
|
|
212
|
+
</Card>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</article>
|
|
216
|
+
|
|
217
|
+
<!-- Tags -->
|
|
218
|
+
<article id="tags">
|
|
219
|
+
<h3>Tag / Tags</h3>
|
|
220
|
+
|
|
221
|
+
<div class="component-demo">
|
|
222
|
+
<h4>Basic Tags</h4>
|
|
223
|
+
<Tags>
|
|
224
|
+
<Tag>Tag 1</Tag>
|
|
225
|
+
<Tag>Tag 2</Tag>
|
|
226
|
+
<Tag>Tag 3</Tag>
|
|
227
|
+
</Tags>
|
|
228
|
+
</div>
|
|
229
|
+
|
|
230
|
+
<div class="component-demo">
|
|
231
|
+
<h4>Dismissable Tags</h4>
|
|
232
|
+
<Tags>
|
|
233
|
+
<Tag v-for="tag in dismissableTags" :key="tag" dismissable @dismiss="dismissableTags = dismissableTags.filter(t => t !== tag)">
|
|
234
|
+
{{ tag }}
|
|
235
|
+
</Tag>
|
|
236
|
+
</Tags>
|
|
237
|
+
<Button v-if="dismissableTags.length === 0" class="small" @click="dismissableTags = ['Dismissable 1', 'Dismissable 2', 'Dismissable 3']">
|
|
238
|
+
Reset Tags
|
|
239
|
+
</Button>
|
|
240
|
+
</div>
|
|
241
|
+
</article>
|
|
242
|
+
|
|
243
|
+
<!-- Forms -->
|
|
244
|
+
<article id="forms">
|
|
245
|
+
<h3>Form Components</h3>
|
|
246
|
+
|
|
247
|
+
<div class="component-demo">
|
|
248
|
+
<h4>Form with FormGroup and FormLabel</h4>
|
|
249
|
+
<Form>
|
|
250
|
+
<FormGroup>
|
|
251
|
+
<FormLabel label="Email">
|
|
252
|
+
<input type="email" placeholder="Enter your email" autocomplete="email" />
|
|
253
|
+
</FormLabel>
|
|
254
|
+
</FormGroup>
|
|
255
|
+
|
|
256
|
+
<FormGroup>
|
|
257
|
+
<FormLabel label="Password">
|
|
258
|
+
<input type="password" placeholder="Enter your password" autocomplete="current-password" />
|
|
259
|
+
</FormLabel>
|
|
260
|
+
</FormGroup>
|
|
261
|
+
|
|
262
|
+
<FormGroup>
|
|
263
|
+
<FormLabel label="Options">
|
|
264
|
+
<FormRadioGroup v-model="selectedOption" :options="radioOptions" name="option" />
|
|
265
|
+
</FormLabel>
|
|
266
|
+
</FormGroup>
|
|
267
|
+
</Form>
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<div class="component-demo">
|
|
271
|
+
<h4>FormItem with Prefix/Suffix</h4>
|
|
272
|
+
<FormItem>
|
|
273
|
+
<template #prefix>$</template>
|
|
274
|
+
<input type="text" placeholder="Amount" />
|
|
275
|
+
</FormItem>
|
|
276
|
+
|
|
277
|
+
<FormItem>
|
|
278
|
+
<input type="text" placeholder="Search" />
|
|
279
|
+
<template #suffix>
|
|
280
|
+
<Icon type="loader" />
|
|
281
|
+
</template>
|
|
282
|
+
</FormItem>
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
<div class="component-demo">
|
|
286
|
+
<h4>FormInputGroup</h4>
|
|
287
|
+
<FormInputGroup>
|
|
288
|
+
<input type="text" placeholder="Enter value" />
|
|
289
|
+
<Button class="primary">Submit</Button>
|
|
290
|
+
</FormInputGroup>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<div class="component-demo">
|
|
294
|
+
<h4>Select</h4>
|
|
295
|
+
<select>
|
|
296
|
+
<option>Option 1</option>
|
|
297
|
+
<option>Option 2</option>
|
|
298
|
+
<option>Option 3</option>
|
|
299
|
+
</select>
|
|
300
|
+
|
|
301
|
+
<select class="small">
|
|
302
|
+
<option>Small Select</option>
|
|
303
|
+
<option>Option 2</option>
|
|
304
|
+
</select>
|
|
305
|
+
</div>
|
|
306
|
+
|
|
307
|
+
<div class="component-demo">
|
|
308
|
+
<h4>FormSelect (Reka UI)</h4>
|
|
309
|
+
<FormLabel label="Single Select">
|
|
310
|
+
<FormItem>
|
|
311
|
+
<FormSelect v-model="selectedFruit" :options="fruitOptions" placeholder="Select a fruit..." />
|
|
312
|
+
</FormItem>
|
|
313
|
+
</FormLabel>
|
|
314
|
+
<p>Selected: {{ selectedFruit || 'None' }}</p>
|
|
315
|
+
|
|
316
|
+
<FormLabel label="Multi Select">
|
|
317
|
+
<FormItem>
|
|
318
|
+
<FormSelect v-model="selectedFruits" :options="fruitOptions" multiple placeholder="Select fruits..." />
|
|
319
|
+
</FormItem>
|
|
320
|
+
</FormLabel>
|
|
321
|
+
<p>Selected: {{ selectedFruits?.length ? selectedFruits.join(', ') : 'None' }}</p>
|
|
322
|
+
|
|
323
|
+
<FormLabel label="With Prefix Icon">
|
|
324
|
+
<FormItem>
|
|
325
|
+
<template #prefix>
|
|
326
|
+
<Icon type="home" />
|
|
327
|
+
</template>
|
|
328
|
+
<FormSelect v-model="selectedFruit" :options="fruitOptions" placeholder="Select..." />
|
|
329
|
+
</FormItem>
|
|
330
|
+
</FormLabel>
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
<div class="component-demo">
|
|
334
|
+
<h4>Checkbox</h4>
|
|
335
|
+
<FormCheckbox v-model="acceptTerms">
|
|
336
|
+
Accept terms and conditions
|
|
337
|
+
</FormCheckbox>
|
|
338
|
+
<p>Accepted: {{ acceptTerms }}</p>
|
|
339
|
+
</div>
|
|
340
|
+
</article>
|
|
341
|
+
|
|
342
|
+
<!-- Actions -->
|
|
343
|
+
<article id="actions">
|
|
344
|
+
<h3>Actions</h3>
|
|
345
|
+
|
|
346
|
+
<div class="component-demo">
|
|
347
|
+
<h4>Default (Right-aligned)</h4>
|
|
348
|
+
<Actions>
|
|
349
|
+
<Button>Cancel</Button>
|
|
350
|
+
<Button class="primary">Submit</Button>
|
|
351
|
+
</Actions>
|
|
352
|
+
</div>
|
|
353
|
+
|
|
354
|
+
<div class="component-demo">
|
|
355
|
+
<h4>Left-aligned</h4>
|
|
356
|
+
<Actions class="left">
|
|
357
|
+
<Button>Action 1</Button>
|
|
358
|
+
<Button>Action 2</Button>
|
|
359
|
+
</Actions>
|
|
360
|
+
</div>
|
|
361
|
+
</article>
|
|
362
|
+
|
|
363
|
+
<!-- Dialog/Modal -->
|
|
364
|
+
<article id="dialogs">
|
|
365
|
+
<h3>Dialog / Modal</h3>
|
|
366
|
+
|
|
367
|
+
<div class="component-demo">
|
|
368
|
+
<h4>Dialog</h4>
|
|
369
|
+
<Button @click="showDialog = true">Open Dialog</Button>
|
|
370
|
+
|
|
371
|
+
<Dialog v-model:open="showDialog" title="Dialog Title">
|
|
372
|
+
<p>Dialog with title and close button.</p>
|
|
373
|
+
<Actions>
|
|
374
|
+
<Button @click="showDialog = false">Cancel</Button>
|
|
375
|
+
<Button class="primary" @click="showDialog = false">Confirm</Button>
|
|
376
|
+
</Actions>
|
|
377
|
+
</Dialog>
|
|
378
|
+
</div>
|
|
379
|
+
</article>
|
|
380
|
+
</section>
|
|
381
|
+
</main>
|
|
382
|
+
</template>
|
|
383
|
+
|
|
384
|
+
<script setup lang="ts">
|
|
385
|
+
const grayShades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
|
|
386
|
+
const zColors = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
387
|
+
const semanticColors = ['primary', 'muted', 'error', 'success']
|
|
388
|
+
const fontSizes = ['xs', 'sm', 'base', 'lg', 'xl', '2xl', '3xl']
|
|
389
|
+
const sizes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
390
|
+
const spacers = ['xs', 'sm', 'default', 'md', 'lg', 'xl']
|
|
391
|
+
const iconTypes = [
|
|
392
|
+
'add', 'check', 'chevron-down', 'chevron-left', 'chevron-right',
|
|
393
|
+
'chevron-up', 'close', 'code', 'discord', 'edit', 'email',
|
|
394
|
+
'folder', 'github', 'home', 'image', 'link', 'loader',
|
|
395
|
+
'maximize', 'times', 'trash', 'twitter', 'user', 'website', 'withdraw'
|
|
396
|
+
]
|
|
397
|
+
|
|
398
|
+
const showDialog = ref(false)
|
|
399
|
+
|
|
400
|
+
// Dismissable tags demo
|
|
401
|
+
const dismissableTags = ref(['Dismissable 1', 'Dismissable 2', 'Dismissable 3'])
|
|
402
|
+
|
|
403
|
+
// FormCheckbox demo data
|
|
404
|
+
const acceptTerms = ref(false)
|
|
405
|
+
|
|
406
|
+
// FormRadioGroup demo data
|
|
407
|
+
const selectedOption = ref('a')
|
|
408
|
+
const radioOptions = [
|
|
409
|
+
{ value: 'a', label: 'Option A' },
|
|
410
|
+
{ value: 'b', label: 'Option B' },
|
|
411
|
+
]
|
|
412
|
+
|
|
413
|
+
// FormSelect demo data
|
|
414
|
+
const selectedFruit = ref<string>()
|
|
415
|
+
const selectedFruits = ref<string[]>([])
|
|
416
|
+
const fruitOptions = [
|
|
417
|
+
{ value: 'apple', label: 'Apple' },
|
|
418
|
+
{ value: 'banana', label: 'Banana' },
|
|
419
|
+
{ value: 'cherry', label: 'Cherry' },
|
|
420
|
+
{ value: 'date', label: 'Date' },
|
|
421
|
+
{ value: 'elderberry', label: 'Elderberry' },
|
|
422
|
+
]
|
|
423
|
+
</script>
|
|
424
|
+
|
|
425
|
+
<style scoped>
|
|
426
|
+
.library {
|
|
427
|
+
max-width: var(--content-width);
|
|
428
|
+
margin: 0 auto;
|
|
429
|
+
padding: var(--spacer-lg);
|
|
430
|
+
display: grid;
|
|
431
|
+
gap: var(--spacer-xl);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.library-header {
|
|
435
|
+
border-bottom: var(--border);
|
|
436
|
+
padding-bottom: var(--spacer-lg);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.library-header h1 {
|
|
440
|
+
font-size: var(--font-2xl);
|
|
441
|
+
margin-bottom: var(--spacer);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.library-nav {
|
|
445
|
+
display: flex;
|
|
446
|
+
gap: var(--spacer);
|
|
447
|
+
flex-wrap: wrap;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.library-nav a {
|
|
451
|
+
font-family: var(--ui-font-family);
|
|
452
|
+
font-size: var(--ui-font-size);
|
|
453
|
+
text-transform: var(--ui-text-transform);
|
|
454
|
+
color: var(--muted);
|
|
455
|
+
text-decoration: none;
|
|
456
|
+
|
|
457
|
+
&:hover {
|
|
458
|
+
color: var(--color);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
section {
|
|
463
|
+
display: grid;
|
|
464
|
+
gap: var(--spacer-lg);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
section>h2 {
|
|
468
|
+
font-size: var(--font-xl);
|
|
469
|
+
border-bottom: var(--border);
|
|
470
|
+
padding-bottom: var(--spacer-sm);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
article {
|
|
474
|
+
display: grid;
|
|
475
|
+
gap: var(--spacer);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
article>h3 {
|
|
479
|
+
font-family: var(--ui-font-family);
|
|
480
|
+
font-size: var(--ui-font-size);
|
|
481
|
+
text-transform: var(--ui-text-transform);
|
|
482
|
+
color: var(--muted);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.token-group {
|
|
486
|
+
display: grid;
|
|
487
|
+
gap: var(--spacer-sm);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.token-group h4 {
|
|
491
|
+
font-size: var(--font-sm);
|
|
492
|
+
color: var(--muted);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/* Color swatches */
|
|
496
|
+
.color-grid {
|
|
497
|
+
display: flex;
|
|
498
|
+
flex-wrap: wrap;
|
|
499
|
+
gap: var(--spacer-sm);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.color-swatch {
|
|
503
|
+
display: grid;
|
|
504
|
+
gap: var(--spacer-xs);
|
|
505
|
+
text-align: center;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.color-swatch>div {
|
|
509
|
+
width: var(--size-8);
|
|
510
|
+
height: var(--size-8);
|
|
511
|
+
border: var(--border);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.color-swatch code {
|
|
515
|
+
font-size: var(--font-xs);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/* Typography samples */
|
|
519
|
+
.type-samples {
|
|
520
|
+
display: grid;
|
|
521
|
+
gap: var(--spacer-sm);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.type-sample {
|
|
525
|
+
display: flex;
|
|
526
|
+
align-items: baseline;
|
|
527
|
+
gap: var(--spacer);
|
|
528
|
+
padding: var(--spacer-xs) 0;
|
|
529
|
+
border-bottom: var(--border);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.type-sample code {
|
|
533
|
+
font-size: var(--font-xs);
|
|
534
|
+
color: var(--muted);
|
|
535
|
+
margin-left: auto;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.ui-text {
|
|
539
|
+
font-family: var(--ui-font-family);
|
|
540
|
+
font-size: var(--ui-font-size);
|
|
541
|
+
text-transform: var(--ui-text-transform);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/* Spacing samples */
|
|
545
|
+
.spacing-samples {
|
|
546
|
+
display: flex;
|
|
547
|
+
flex-wrap: wrap;
|
|
548
|
+
gap: var(--spacer);
|
|
549
|
+
align-items: flex-end;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.spacing-sample {
|
|
553
|
+
display: flex;
|
|
554
|
+
flex-direction: column;
|
|
555
|
+
align-items: center;
|
|
556
|
+
gap: var(--spacer-xs);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
.spacing-box {
|
|
560
|
+
background: var(--primary);
|
|
561
|
+
min-width: var(--size-1);
|
|
562
|
+
min-height: var(--size-1);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.spacing-sample code {
|
|
566
|
+
font-size: var(--font-xs);
|
|
567
|
+
color: var(--muted);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/* Icon grid */
|
|
571
|
+
.icon-grid {
|
|
572
|
+
display: grid;
|
|
573
|
+
grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
|
|
574
|
+
gap: var(--spacer);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.icon-sample {
|
|
578
|
+
display: flex;
|
|
579
|
+
flex-direction: column;
|
|
580
|
+
align-items: center;
|
|
581
|
+
gap: var(--spacer-xs);
|
|
582
|
+
padding: var(--spacer-sm);
|
|
583
|
+
border: var(--border);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.icon-sample .icon {
|
|
587
|
+
font-size: var(--font-xl);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.icon-sample code {
|
|
591
|
+
font-size: var(--font-xs);
|
|
592
|
+
color: var(--muted);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/* Component demos */
|
|
596
|
+
.component-demo {
|
|
597
|
+
display: grid;
|
|
598
|
+
gap: var(--spacer-sm);
|
|
599
|
+
padding: var(--spacer);
|
|
600
|
+
background: var(--gray-z-0);
|
|
601
|
+
border: var(--border);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.component-demo h4 {
|
|
605
|
+
font-size: var(--font-sm);
|
|
606
|
+
color: var(--muted);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.demo-row {
|
|
610
|
+
display: flex;
|
|
611
|
+
flex-wrap: wrap;
|
|
612
|
+
gap: var(--spacer-sm);
|
|
613
|
+
align-items: center;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.card-grid {
|
|
617
|
+
display: grid;
|
|
618
|
+
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
|
619
|
+
gap: var(--spacer);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
.card-grid h4 {
|
|
623
|
+
font-size: var(--font-base);
|
|
624
|
+
color: var(--color);
|
|
625
|
+
}
|
|
626
|
+
</style>
|