rune-lab 0.0.4 → 0.0.6-rc0
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/LICENSE +1 -1
- package/README.md +40 -40
- package/dist/components/UIShowcase.svelte +184 -338
- package/dist/components/layout/ThemeSelector.svelte +25 -7
- package/dist/components/layout/URLDisplay.svelte +11 -17
- package/dist/core/theme/constants.d.ts +29 -0
- package/dist/core/theme/constants.js +61 -0
- package/dist/index.d.ts +4 -13
- package/dist/index.js +8 -42
- package/dist/mod.d.ts +5 -0
- package/dist/mod.js +12 -0
- package/dist/stores/api.svelte.d.ts +11 -0
- package/dist/stores/api.svelte.js +30 -0
- package/dist/stores/app.svelte.js +6 -6
- package/dist/stores/auth.svelte.d.ts +9 -10
- package/dist/stores/auth.svelte.js +21 -14
- package/dist/stores/{layout/footer.svelte.d.ts → footer.svelte.d.ts} +10 -10
- package/dist/stores/{layout/footer.svelte.js → footer.svelte.js} +4 -4
- package/dist/stores/theme.svelte.d.ts +4 -6
- package/dist/stores/theme.svelte.js +25 -33
- package/package.json +36 -64
- package/dist/components/dt/Altharun.svelte +0 -74
- package/dist/components/dt/Altharun.svelte.d.ts +0 -3
- package/dist/components/dt/Kyntharil.svelte +0 -97
- package/dist/components/dt/Kyntharil.svelte.d.ts +0 -3
- package/dist/components/dt/MetadataTable.svelte +0 -70
- package/dist/components/dt/MetadataTable.svelte.d.ts +0 -9
- package/dist/components/dt/SchemaDisplay.svelte +0 -154
- package/dist/components/dt/SchemaDisplay.svelte.d.ts +0 -7
- package/dist/components/layout/Footer.svelte +0 -88
- package/dist/components/layout/Footer.svelte.d.ts +0 -3
- package/dist/components/layout/NavBar.svelte +0 -114
- package/dist/components/layout/NavBar.svelte.d.ts +0 -3
- package/dist/components/layout/SignInCard.svelte +0 -72
- package/dist/components/layout/SignInCard.svelte.d.ts +0 -3
- package/dist/forge.svelte.d.ts +0 -18
- package/dist/forge.svelte.js +0 -37
- package/dist/theme/index.d.ts +0 -4
- package/dist/theme/index.js +0 -2
- package/dist/theme/static.d.ts +0 -16
- package/dist/theme/static.js +0 -45
- package/dist/tools/format.d.ts +0 -20
- package/dist/tools/format.js +0 -25
- package/dist/tools/pdf.d.ts +0 -1
- package/dist/tools/pdf.js +0 -320
|
@@ -1,363 +1,209 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let progress = $state(0);
|
|
11
|
-
let rating = $state(3);
|
|
12
|
-
let selected = $state("Option 1");
|
|
13
|
-
let steps = $state(1);
|
|
14
|
-
let toast = $state("");
|
|
2
|
+
import ThemeSelector from "./layout/ThemeSelector.svelte";
|
|
3
|
+
import {
|
|
4
|
+
PaintBucket,
|
|
5
|
+
Puzzle,
|
|
6
|
+
Ruler,
|
|
7
|
+
ChartBar,
|
|
8
|
+
Sparkle
|
|
9
|
+
} from "lucide-svelte";
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
// State management with Svelte 5 runes
|
|
12
|
+
let activeTab = $state(0);
|
|
13
|
+
let modalOpen = $state(false);
|
|
14
|
+
let drawerOpen = $state(false);
|
|
15
|
+
let loading = $state(false);
|
|
16
|
+
let progress = $state(0);
|
|
17
|
+
let selected = $state("Option 1");
|
|
18
|
+
let toast = $state("");
|
|
19
|
+
|
|
20
|
+
// Color variants for demonstration
|
|
21
|
+
const colors = ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'];
|
|
22
|
+
const sizes = ['xs', 'sm', 'md', 'lg'];
|
|
23
|
+
|
|
24
|
+
// Define tabs with icon components (not JSX syntax)
|
|
25
|
+
const tabs = [
|
|
26
|
+
{ title: 'Basic UI', icon: PaintBucket },
|
|
27
|
+
{ title: 'Components', icon: Puzzle },
|
|
28
|
+
{ title: 'Layout', icon: Ruler },
|
|
29
|
+
{ title: 'Data Display', icon: ChartBar },
|
|
30
|
+
{ title: 'Feedback', icon: Sparkle }
|
|
31
|
+
];
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
</script>
|
|
60
|
-
|
|
61
|
-
<div class="min-h-screen bg-base-200 p-4">
|
|
62
|
-
<!-- Header with Theme Demo -->
|
|
63
|
-
<div class="text-center mb-8 hero bg-base-100 rounded-box p-8">
|
|
64
|
-
<div class="hero-content text-center">
|
|
65
|
-
<div>
|
|
66
|
-
<h1 class="text-5xl font-bold mb-4">DaisyUI Showcase</h1>
|
|
67
|
-
<p class="text-xl opacity-75 mb-6">A comprehensive demonstration of DaisyUI components with Svelte 5</p>
|
|
68
|
-
<div class="flex justify-center gap-2">
|
|
69
|
-
<button class="btn btn-primary" onclick={() => modalOpen = true}>Open Modal</button>
|
|
70
|
-
<button class="btn btn-secondary" onclick={() => drawerOpen = true}>Open Drawer</button>
|
|
71
|
-
<ThemeSelector />
|
|
33
|
+
// Simulate loading
|
|
34
|
+
function simulateLoading() {
|
|
35
|
+
loading = true;
|
|
36
|
+
setTimeout(() => loading = false, 2000);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Show toast message
|
|
40
|
+
function showToast(message: string) {
|
|
41
|
+
toast = message;
|
|
42
|
+
setTimeout(() => toast = "", 3000);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Progress bar simulation
|
|
46
|
+
$effect(() => {
|
|
47
|
+
const interval = setInterval(() => {
|
|
48
|
+
if (progress < 100) {
|
|
49
|
+
progress += 1;
|
|
50
|
+
} else {
|
|
51
|
+
progress = 0;
|
|
52
|
+
}
|
|
53
|
+
}, 100);
|
|
54
|
+
|
|
55
|
+
return () => clearInterval(interval);
|
|
56
|
+
});
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<div class="min-h-screen bg-base-200 p-4">
|
|
60
|
+
<!-- Header with Theme Demo -->
|
|
61
|
+
<div class="text-center mb-8 hero bg-base-100 rounded-box p-8">
|
|
62
|
+
<div class="hero-content text-center">
|
|
63
|
+
<div>
|
|
64
|
+
<h1 class="text-5xl font-bold mb-4">DaisyUI Showcase</h1>
|
|
65
|
+
<p class="text-xl opacity-75 mb-6">A comprehensive demonstration of DaisyUI components with Svelte 5</p>
|
|
66
|
+
<div class="flex justify-center gap-2">
|
|
67
|
+
<button class="btn btn-primary" onclick={() => modalOpen = true}>Open Modal</button>
|
|
68
|
+
<button class="btn btn-secondary" onclick={() => drawerOpen = true}>Open Drawer</button>
|
|
69
|
+
<button class="btn" onclick={() => showToast("This is a toast message!")}>Show Toast</button>
|
|
70
|
+
<ThemeSelector />
|
|
71
|
+
</div>
|
|
72
72
|
</div>
|
|
73
73
|
</div>
|
|
74
74
|
</div>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
{/each}
|
|
103
|
-
</div>
|
|
104
|
-
<div class="divider">Sizes</div>
|
|
105
|
-
<div class="flex flex-wrap gap-2 items-center">
|
|
106
|
-
{#each sizes as size}
|
|
107
|
-
<button class="btn btn-{size}">{size}</button>
|
|
108
|
-
{/each}
|
|
109
|
-
</div>
|
|
110
|
-
<div class="divider">States</div>
|
|
111
|
-
<div class="flex flex-wrap gap-2">
|
|
112
|
-
<button class="btn btn-primary loading">Loading</button>
|
|
113
|
-
<button class="btn btn-disabled">Disabled</button>
|
|
114
|
-
<button class="btn btn-outline">Outline</button>
|
|
115
|
-
<button class="btn btn-link">Link</button>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
|
|
120
|
-
<!-- Form Elements -->
|
|
121
|
-
<div class="card bg-base-100 shadow-xl">
|
|
122
|
-
<div class="card-body">
|
|
123
|
-
<h2 class="card-title">Form Elements</h2>
|
|
124
|
-
<div class="form-control gap-4">
|
|
125
|
-
<label class="input-group">
|
|
126
|
-
<span>Email</span>
|
|
127
|
-
<input type="text" placeholder="info@site.com" class="input input-bordered" />
|
|
128
|
-
</label>
|
|
129
|
-
|
|
130
|
-
<select class="select select-bordered w-full" bind:value={selected}>
|
|
131
|
-
<option>Option 1</option>
|
|
132
|
-
<option>Option 2</option>
|
|
133
|
-
<option>Option 3</option>
|
|
134
|
-
</select>
|
|
135
|
-
|
|
136
|
-
<div class="flex gap-4">
|
|
137
|
-
<label class="label cursor-pointer">
|
|
138
|
-
<span class="label-text mr-2">Toggle</span>
|
|
139
|
-
<input type="checkbox" class="toggle toggle-primary" />
|
|
140
|
-
</label>
|
|
141
|
-
|
|
142
|
-
<label class="label cursor-pointer">
|
|
143
|
-
<span class="label-text mr-2">Radio</span>
|
|
144
|
-
<input type="radio" name="radio-10" class="radio radio-primary" />
|
|
145
|
-
</label>
|
|
75
|
+
|
|
76
|
+
<!-- Navigation Tabs -->
|
|
77
|
+
<div class="tabs tabs-boxed justify-center mb-8">
|
|
78
|
+
{#each tabs as tab, i}
|
|
79
|
+
<button
|
|
80
|
+
class="tab {activeTab === i ? 'tab-active' : ''}"
|
|
81
|
+
onclick={() => activeTab = i}
|
|
82
|
+
>
|
|
83
|
+
<tab.icon size={18} class="mr-2" />
|
|
84
|
+
{tab.title}
|
|
85
|
+
</button>
|
|
86
|
+
{/each}
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<!-- Main Content -->
|
|
90
|
+
<div class="container mx-auto">
|
|
91
|
+
{#if activeTab === 0}
|
|
92
|
+
<!-- Basic UI Elements -->
|
|
93
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
94
|
+
<!-- Buttons Showcase -->
|
|
95
|
+
<div class="card bg-base-100 shadow-xl">
|
|
96
|
+
<div class="card-body">
|
|
97
|
+
<h2 class="card-title">Buttons</h2>
|
|
98
|
+
<div class="flex flex-wrap gap-2">
|
|
99
|
+
{#each colors as color}
|
|
100
|
+
<button class="btn btn-{color}">{color}</button>
|
|
101
|
+
{/each}
|
|
146
102
|
</div>
|
|
147
|
-
|
|
148
|
-
<
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
{:else if activeTab === 1}
|
|
155
|
-
<!-- Advanced Components -->
|
|
156
|
-
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
157
|
-
<!-- Dropdown and Menu -->
|
|
158
|
-
<div class="card bg-base-100 shadow-xl">
|
|
159
|
-
<div class="card-body">
|
|
160
|
-
<h2 class="card-title">Dropdowns & Menus</h2>
|
|
161
|
-
<div class="flex flex-wrap gap-4">
|
|
162
|
-
<div class="dropdown">
|
|
163
|
-
<button class="btn m-1">Dropdown</button>
|
|
164
|
-
<ul class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
|
165
|
-
<li><button class="w-full text-left">Item 1</button></li>
|
|
166
|
-
<li><button class="w-full text-left">Item 2</button></li>
|
|
167
|
-
</ul>
|
|
103
|
+
<div class="divider">Sizes</div>
|
|
104
|
+
<div class="flex flex-wrap gap-2 items-center">
|
|
105
|
+
{#each sizes as size}
|
|
106
|
+
<button class="btn btn-{size}">{size}</button>
|
|
107
|
+
{/each}
|
|
168
108
|
</div>
|
|
169
|
-
|
|
170
|
-
<div class="
|
|
171
|
-
<
|
|
172
|
-
<
|
|
109
|
+
<div class="divider">States</div>
|
|
110
|
+
<div class="flex flex-wrap gap-2">
|
|
111
|
+
<button class="btn btn-primary loading">Loading</button>
|
|
112
|
+
<button class="btn btn-disabled">Disabled</button>
|
|
113
|
+
<button class="btn btn-outline">Outline</button>
|
|
114
|
+
<button class="btn btn-link">Link</button>
|
|
173
115
|
</div>
|
|
174
116
|
</div>
|
|
175
117
|
</div>
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
<h2 class="card-title">Hero Section</h2>
|
|
204
|
-
<div class="hero bg-base-200 rounded-box">
|
|
205
|
-
<div class="hero-content text-center">
|
|
206
|
-
<div class="max-w-md">
|
|
207
|
-
<h1 class="text-5xl font-bold">Hello there</h1>
|
|
208
|
-
<p class="py-6">This is a sample hero section with a button below.</p>
|
|
209
|
-
<button class="btn btn-primary">Get Started</button>
|
|
118
|
+
|
|
119
|
+
<!-- Form Elements -->
|
|
120
|
+
<div class="card bg-base-100 shadow-xl">
|
|
121
|
+
<div class="card-body">
|
|
122
|
+
<h2 class="card-title">Form Elements</h2>
|
|
123
|
+
<div class="form-control gap-4">
|
|
124
|
+
<label class="input-group">
|
|
125
|
+
<span>Email</span>
|
|
126
|
+
<input type="text" placeholder="info@site.com" class="input input-bordered" />
|
|
127
|
+
</label>
|
|
128
|
+
|
|
129
|
+
<select class="select select-bordered w-full" bind:value={selected}>
|
|
130
|
+
<option>Option 1</option>
|
|
131
|
+
<option>Option 2</option>
|
|
132
|
+
<option>Option 3</option>
|
|
133
|
+
</select>
|
|
134
|
+
|
|
135
|
+
<div class="flex gap-4">
|
|
136
|
+
<label class="label cursor-pointer">
|
|
137
|
+
<span class="label-text mr-2">Toggle</span>
|
|
138
|
+
<input type="checkbox" class="toggle toggle-primary" />
|
|
139
|
+
</label>
|
|
140
|
+
|
|
141
|
+
<label class="label cursor-pointer">
|
|
142
|
+
<span class="label-text mr-2">Radio</span>
|
|
143
|
+
<input type="radio" name="radio-10" class="radio radio-primary" />
|
|
144
|
+
</label>
|
|
210
145
|
</div>
|
|
146
|
+
|
|
147
|
+
<input type="range" min="0" max="100" class="range range-primary" />
|
|
211
148
|
</div>
|
|
212
149
|
</div>
|
|
213
150
|
</div>
|
|
214
151
|
</div>
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
</
|
|
227
|
-
</div>
|
|
228
|
-
</div>
|
|
229
|
-
</div>
|
|
230
|
-
|
|
231
|
-
{:else if activeTab === 3}
|
|
232
|
-
<!-- Data Display -->
|
|
233
|
-
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
234
|
-
<!-- Stats -->
|
|
235
|
-
<div class="card bg-base-100 shadow-xl">
|
|
236
|
-
<div class="card-body">
|
|
237
|
-
<h2 class="card-title">Statistics</h2>
|
|
238
|
-
<div class="stats shadow">
|
|
239
|
-
{#each stats as stat}
|
|
240
|
-
<div class="stat">
|
|
241
|
-
<div class="stat-title">{stat.title}</div>
|
|
242
|
-
<div class="stat-value">{stat.value}</div>
|
|
243
|
-
<div class="stat-desc">{stat.desc}</div>
|
|
244
|
-
</div>
|
|
245
|
-
{/each}
|
|
246
|
-
</div>
|
|
247
|
-
</div>
|
|
248
|
-
</div>
|
|
249
|
-
|
|
250
|
-
<!-- Table -->
|
|
251
|
-
<div class="card bg-base-100 shadow-xl">
|
|
252
|
-
<div class="card-body">
|
|
253
|
-
<h2 class="card-title">Table</h2>
|
|
254
|
-
<div class="overflow-x-auto">
|
|
255
|
-
<table class="table">
|
|
256
|
-
<thead>
|
|
257
|
-
<tr>
|
|
258
|
-
<th>Name</th>
|
|
259
|
-
<th>Job</th>
|
|
260
|
-
<th>Action</th>
|
|
261
|
-
</tr>
|
|
262
|
-
</thead>
|
|
263
|
-
<tbody>
|
|
264
|
-
<tr>
|
|
265
|
-
<td>Cy Ganderton</td>
|
|
266
|
-
<td>Quality Control Specialist</td>
|
|
267
|
-
<td><button class="btn btn-xs">Details</button></td>
|
|
268
|
-
</tr>
|
|
269
|
-
<tr>
|
|
270
|
-
<td>Hart Hagerty</td>
|
|
271
|
-
<td>Desktop Support Technician</td>
|
|
272
|
-
<td><button class="btn btn-xs">Details</button></td>
|
|
273
|
-
</tr>
|
|
274
|
-
</tbody>
|
|
275
|
-
</table>
|
|
276
|
-
</div>
|
|
152
|
+
{/if}
|
|
153
|
+
<!-- Other tab content would go here -->
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<!-- Modal -->
|
|
157
|
+
{#if modalOpen}
|
|
158
|
+
<div class="modal modal-open">
|
|
159
|
+
<div class="modal-box">
|
|
160
|
+
<h3 class="font-bold text-lg">Modal Title</h3>
|
|
161
|
+
<p class="py-4">This is a sample modal dialog using DaisyUI.</p>
|
|
162
|
+
<div class="modal-action">
|
|
163
|
+
<button class="btn" onclick={() => modalOpen = false}>Close</button>
|
|
277
164
|
</div>
|
|
278
165
|
</div>
|
|
166
|
+
<button
|
|
167
|
+
class="modal-backdrop"
|
|
168
|
+
onclick={() => modalOpen = false}
|
|
169
|
+
onkeydown={(e) => e.key === 'Escape' && (modalOpen = false)}
|
|
170
|
+
aria-label="Close modal"
|
|
171
|
+
></button>
|
|
279
172
|
</div>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
<
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
</
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
<!-- Progress & Loading -->
|
|
299
|
-
<div class="card bg-base-100 shadow-xl">
|
|
300
|
-
<div class="card-body">
|
|
301
|
-
<h2 class="card-title">Progress & Loading</h2>
|
|
302
|
-
<progress class="progress w-full" value={progress} max="100"></progress>
|
|
303
|
-
<div class="flex gap-2 mt-4">
|
|
304
|
-
<button class="btn" onclick={simulateLoading}>
|
|
305
|
-
{loading ? 'Loading...' : 'Simulate Loading'}
|
|
306
|
-
</button>
|
|
307
|
-
{#if loading}
|
|
308
|
-
<span class="loading loading-spinner loading-lg"></span>
|
|
309
|
-
{/if}
|
|
310
|
-
</div>
|
|
311
|
-
</div>
|
|
173
|
+
{/if}
|
|
174
|
+
|
|
175
|
+
<!-- Drawer -->
|
|
176
|
+
{#if drawerOpen}
|
|
177
|
+
<div class="drawer drawer-end drawer-open">
|
|
178
|
+
<input id="my-drawer" type="checkbox" class="drawer-toggle" checked />
|
|
179
|
+
<div class="drawer-side">
|
|
180
|
+
<button
|
|
181
|
+
class="drawer-overlay"
|
|
182
|
+
onclick={() => drawerOpen = false}
|
|
183
|
+
onkeydown={(e) => e.key === 'Escape' && (drawerOpen = false)}
|
|
184
|
+
aria-label="Close drawer"
|
|
185
|
+
></button>
|
|
186
|
+
<ul class="menu p-4 w-80 min-h-full bg-base-200 text-base-content">
|
|
187
|
+
<li><button class="w-full text-left">Sidebar Item 1</button></li>
|
|
188
|
+
<li><button class="w-full text-left">Sidebar Item 2</button></li>
|
|
189
|
+
</ul>
|
|
312
190
|
</div>
|
|
313
191
|
</div>
|
|
314
192
|
{/if}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
<h3 class="font-bold text-lg">Modal Title</h3>
|
|
322
|
-
<p class="py-4">This is a sample modal dialog using DaisyUI.</p>
|
|
323
|
-
<div class="modal-action">
|
|
324
|
-
<button class="btn" onclick={() => modalOpen = false}>Close</button>
|
|
193
|
+
|
|
194
|
+
<!-- Toast -->
|
|
195
|
+
{#if toast}
|
|
196
|
+
<div class="toast toast-end">
|
|
197
|
+
<div class="alert alert-info">
|
|
198
|
+
<span>{toast}</span>
|
|
325
199
|
</div>
|
|
326
200
|
</div>
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
<input id="my-drawer" type="checkbox" class="drawer-toggle" checked />
|
|
334
|
-
<div class="drawer-side">
|
|
335
|
-
<button
|
|
336
|
-
class="drawer-overlay"
|
|
337
|
-
onclick={() => drawerOpen = false}
|
|
338
|
-
onkeydown={(e) => e.key === 'Escape' && (drawerOpen = false)}
|
|
339
|
-
>.</button>
|
|
340
|
-
<ul class="menu p-4 w-80 min-h-full bg-base-200 text-base-content">
|
|
341
|
-
<li><button class="w-full text-left">Sidebar Item 1</button></li>
|
|
342
|
-
<li><button class="w-full text-left">Sidebar Item 2</button></li>
|
|
343
|
-
</ul>
|
|
344
|
-
</div>
|
|
345
|
-
</div>
|
|
346
|
-
{/if}
|
|
347
|
-
|
|
348
|
-
<!-- Toast -->
|
|
349
|
-
{#if toast}
|
|
350
|
-
<div class="toast toast-end">
|
|
351
|
-
<div class="alert alert-info">
|
|
352
|
-
<span>{toast}</span>
|
|
201
|
+
{/if}
|
|
202
|
+
|
|
203
|
+
<!-- Footer -->
|
|
204
|
+
<footer class="footer footer-center p-4 bg-base-300 text-base-content mt-8">
|
|
205
|
+
<div>
|
|
206
|
+
<p>Made with 💝 using Svelte 5 and DaisyUI</p>
|
|
353
207
|
</div>
|
|
354
|
-
</
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
<!-- Footer -->
|
|
358
|
-
<footer class="footer footer-center p-4 bg-base-300 text-base-content mt-8">
|
|
359
|
-
<div>
|
|
360
|
-
<p>Made with 💝 using Svelte 5 and DaisyUI</p>
|
|
361
|
-
</div>
|
|
362
|
-
</footer>
|
|
363
|
-
</div>
|
|
208
|
+
</footer>
|
|
209
|
+
</div>
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { Brush } from "lucide-svelte";
|
|
2
3
|
import { themeStore } from '../../stores/theme.svelte.js';
|
|
3
|
-
|
|
4
|
+
|
|
4
5
|
// Local state using runes
|
|
5
6
|
let showDropdown = $state(false);
|
|
6
7
|
|
|
7
8
|
// Initialize theme on mount
|
|
8
|
-
|
|
9
|
+
$effect(() => {
|
|
10
|
+
themeStore.init();
|
|
11
|
+
});
|
|
9
12
|
|
|
10
13
|
// Get available themes
|
|
11
14
|
const themes = themeStore.getAvailableThemes();
|
|
@@ -18,23 +21,38 @@
|
|
|
18
21
|
|
|
19
22
|
<div class="relative">
|
|
20
23
|
<button
|
|
21
|
-
class="btn"
|
|
24
|
+
class="btn btn-ghost btn-circle"
|
|
22
25
|
onclick={() => showDropdown = !showDropdown}
|
|
26
|
+
aria-label="Select theme"
|
|
23
27
|
>
|
|
24
|
-
<span>
|
|
28
|
+
<span class="flex items-center gap-1">
|
|
29
|
+
{#if themeStore.themeConfig.icon}
|
|
30
|
+
<span>{themeStore.themeConfig.icon}</span>
|
|
31
|
+
{:else}
|
|
32
|
+
<Brush size={20} />
|
|
33
|
+
{/if}
|
|
34
|
+
<span>{themeStore.currentTheme}</span>
|
|
35
|
+
</span>
|
|
25
36
|
</button>
|
|
26
37
|
|
|
27
38
|
{#if showDropdown}
|
|
28
|
-
<
|
|
39
|
+
<div
|
|
40
|
+
class="fixed inset-0 z-10"
|
|
41
|
+
role="button"
|
|
42
|
+
tabindex="0"
|
|
43
|
+
onclick={() => showDropdown = false}
|
|
44
|
+
onkeydown={(e) => e.key === 'Escape' && (showDropdown = false)}
|
|
45
|
+
></div>
|
|
46
|
+
<ul class="absolute right-0 top-full mt-2 min-w-56 p-2 bg-base-100 border border-base-300 rounded-xl shadow-lg z-20 max-h-96 overflow-y-auto">
|
|
29
47
|
{#each themes as theme}
|
|
30
48
|
<li>
|
|
31
49
|
<button
|
|
32
|
-
class="w-full flex items-center gap-2 px-
|
|
50
|
+
class="w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-base-200 transition-colors duration-200 rounded-lg
|
|
33
51
|
{themeStore.currentTheme === theme.name ? 'bg-base-300' : ''}"
|
|
34
52
|
onclick={() => handleThemeSelect(theme.name)}
|
|
35
53
|
>
|
|
36
54
|
<span>{theme.icon}</span>
|
|
37
|
-
<span>{theme.name}</span>
|
|
55
|
+
<span class="capitalize">{theme.name}</span>
|
|
38
56
|
</button>
|
|
39
57
|
</li>
|
|
40
58
|
{/each}
|