flowbite-svelte 1.19.0 → 1.20.0
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/dist/accordion/AccordionItem.svelte +15 -1
- package/dist/alert/Alert.svelte +15 -2
- package/dist/badge/Badge.svelte +19 -2
- package/dist/banner/Banner.svelte +16 -1
- package/dist/bottom-navigation/BottomNavItem.svelte +7 -1
- package/dist/breadcrumb/BreadcrumbItem.svelte +3 -1
- package/dist/carousel/Carousel.svelte +35 -4
- package/dist/datepicker/Datepicker.svelte +69 -6
- package/dist/device-mockups/Android.svelte +5 -1
- package/dist/device-mockups/DefaultMockup.svelte +5 -1
- package/dist/device-mockups/Ios.svelte +5 -1
- package/dist/device-mockups/Laptop.svelte +5 -1
- package/dist/device-mockups/Smartwatch.svelte +5 -1
- package/dist/device-mockups/Tablet.svelte +5 -1
- package/dist/dialog/Dialog.svelte +38 -7
- package/dist/drawer/Drawer.svelte +29 -2
- package/dist/forms/button-toggle/ButtonToggle.svelte +9 -1
- package/dist/forms/button-toggle/ButtonToggleGroup.svelte +14 -1
- package/dist/forms/button-toggle/CheckIcon.svelte +13 -1
- package/dist/forms/checkbox/Checkbox.svelte +18 -1
- package/dist/forms/fileupload/Fileupload.svelte +14 -1
- package/dist/forms/floating-label/FloatingLabelInput.svelte +48 -5
- package/dist/forms/input-addon/InputAddon.svelte +12 -1
- package/dist/forms/input-field/Input.svelte +60 -9
- package/dist/forms/phoneinput/PhoneInput.svelte +14 -2
- package/dist/forms/phoneinput/PhoneInput.svelte.d.ts +1 -1
- package/dist/forms/radio/Radio.svelte +14 -1
- package/dist/forms/search/Search.svelte +16 -1
- package/dist/forms/select/MultiSelect.svelte +10 -1
- package/dist/forms/select/Select.svelte +20 -1
- package/dist/forms/tags/Tags.svelte +35 -11
- package/dist/forms/textarea/Textarea.svelte +27 -2
- package/dist/forms/textarea/theme.js +3 -1
- package/dist/forms/timepicker/Timepicker.svelte +143 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/kanban/KanbanBoard.svelte +98 -0
- package/dist/kanban/KanbanBoard.svelte.d.ts +4 -0
- package/dist/kanban/KanbanCard.svelte +58 -0
- package/dist/kanban/KanbanCard.svelte.d.ts +16 -0
- package/dist/kanban/index.d.ts +3 -0
- package/dist/kanban/index.js +3 -0
- package/dist/kanban/theme.d.ts +108 -0
- package/dist/kanban/theme.js +43 -0
- package/dist/mega-menu/MegaMenu.svelte +1 -8
- package/dist/modal/Modal.svelte +30 -2
- package/dist/navbar/NavHamburger.svelte +1 -1
- package/dist/navbar/NavLi.svelte +3 -1
- package/dist/navbar/NavUl.svelte +14 -1
- package/dist/pagination/theme.js +4 -1
- package/dist/popover/Popover.svelte +13 -1
- package/dist/progress/Progressbar.svelte +14 -1
- package/dist/progress/Progressradial.svelte +28 -2
- package/dist/rating/AdvancedRating.svelte +5 -1
- package/dist/rating/CustomIcon.svelte +13 -1
- package/dist/rating/Heart.svelte +19 -2
- package/dist/rating/Review.svelte +6 -3
- package/dist/rating/Review.svelte.d.ts +0 -1
- package/dist/rating/Star.svelte +12 -1
- package/dist/rating/Thumbup.svelte +19 -2
- package/dist/sidebar/Sidebar.svelte +30 -2
- package/dist/sidebar/SidebarButton.svelte +5 -1
- package/dist/sidebar/SidebarDropdownWrapper.svelte +18 -1
- package/dist/skeleton/CardPlaceholder.svelte +8 -2
- package/dist/skeleton/ImagePlaceholder.svelte +3 -1
- package/dist/skeleton/TestimonialPlaceholder.svelte +5 -1
- package/dist/skeleton/VideoPlaceholder.svelte +3 -1
- package/dist/speed-dial/SpeedDial.svelte +13 -1
- package/dist/speed-dial/SpeedDialButton.svelte +12 -1
- package/dist/spinner/Spinner.svelte +8 -2
- package/dist/step-indicator/StepIndicator.svelte +14 -2
- package/dist/stepper/DetailedStepper.svelte +1 -1
- package/dist/stepper/ProgressStepper.svelte +3 -1
- package/dist/stepper/TimelineStepper.svelte +3 -1
- package/dist/stepper/VerticalStepper.svelte +1 -1
- package/dist/table/TableSearch.svelte +26 -2
- package/dist/theme/themeUtils.js +3 -1
- package/dist/theme/themes.d.ts +1 -0
- package/dist/theme/themes.js +1 -0
- package/dist/timeline/GroupItem.svelte +10 -2
- package/dist/timeline/TimelineItem.svelte +24 -2
- package/dist/toast/Toast.svelte +17 -2
- package/dist/tooltip/Tooltip.svelte +12 -4
- package/dist/types.d.ts +27 -1
- package/dist/typography/paragraph/P.svelte +14 -1
- package/dist/utils/CloseButton.svelte +10 -2
- package/dist/utils/Popper.svelte +38 -2
- package/dist/virtuallist/VirtualList.svelte +8 -1
- package/package.json +12 -4
|
@@ -13,7 +13,32 @@
|
|
|
13
13
|
import { parse, isValid, isBefore, isAfter } from "date-fns";
|
|
14
14
|
import { getTheme } from "../../theme/themeUtils";
|
|
15
15
|
|
|
16
|
-
let {
|
|
16
|
+
let {
|
|
17
|
+
id = "time",
|
|
18
|
+
endId = "end-time",
|
|
19
|
+
value = $bindable("00:00"),
|
|
20
|
+
endValue = $bindable("00:00"),
|
|
21
|
+
min = "",
|
|
22
|
+
max = "",
|
|
23
|
+
required = true,
|
|
24
|
+
disabled = false,
|
|
25
|
+
inputColor,
|
|
26
|
+
buttonColor = "primary",
|
|
27
|
+
Icon,
|
|
28
|
+
iconClass = "h-5 w-5 text-gray-500 dark:text-gray-400",
|
|
29
|
+
type = "default",
|
|
30
|
+
optionLabel = "Options",
|
|
31
|
+
options = [],
|
|
32
|
+
size = "md",
|
|
33
|
+
divClass,
|
|
34
|
+
inputClass,
|
|
35
|
+
selectClass,
|
|
36
|
+
timerangeLabel = "Choose time range",
|
|
37
|
+
timerangeButtonLabel = "Save time",
|
|
38
|
+
timeIntervals = [],
|
|
39
|
+
columns = 2,
|
|
40
|
+
onselect
|
|
41
|
+
}: TimepickerProps = $props();
|
|
17
42
|
|
|
18
43
|
const theme = getTheme("timepicker");
|
|
19
44
|
|
|
@@ -22,7 +47,6 @@
|
|
|
22
47
|
|
|
23
48
|
// State
|
|
24
49
|
let selectedOption = $state("");
|
|
25
|
-
let dropdownOpen = $state(false);
|
|
26
50
|
let showTimerange = $state(false);
|
|
27
51
|
|
|
28
52
|
// Helper functions using date-fns
|
|
@@ -117,7 +141,6 @@
|
|
|
117
141
|
}
|
|
118
142
|
|
|
119
143
|
function handleDropdownSelect(option: TimePickerOption): void {
|
|
120
|
-
dropdownOpen = false;
|
|
121
144
|
selectedOption = option.value;
|
|
122
145
|
notifyChange();
|
|
123
146
|
}
|
|
@@ -133,7 +156,6 @@
|
|
|
133
156
|
}
|
|
134
157
|
|
|
135
158
|
function applyTimerange(): void {
|
|
136
|
-
dropdownOpen = false;
|
|
137
159
|
notifyChange();
|
|
138
160
|
}
|
|
139
161
|
|
|
@@ -165,7 +187,19 @@
|
|
|
165
187
|
{#if type !== "inline-buttons"}
|
|
166
188
|
<ButtonGroup {size} class={styles.buttonGroup({ class: clsx(theme?.buttonGroup, divClass) })}>
|
|
167
189
|
{#if type === "default"}
|
|
168
|
-
<Input
|
|
190
|
+
<Input
|
|
191
|
+
{id}
|
|
192
|
+
color={inputColor}
|
|
193
|
+
type="time"
|
|
194
|
+
{min}
|
|
195
|
+
{max}
|
|
196
|
+
{required}
|
|
197
|
+
{disabled}
|
|
198
|
+
class={styles.input({ class: clsx(styles.inputWithIcon(), theme?.input, inputClass) })}
|
|
199
|
+
bind:value
|
|
200
|
+
oninput={(e) => handleTimeChange(e)}
|
|
201
|
+
onchange={(e) => handleTimeChange(e)}
|
|
202
|
+
/>
|
|
169
203
|
<div class={styles.iconWrapper({ class: clsx(theme?.iconWrapper) })}>
|
|
170
204
|
{#if Icon}
|
|
171
205
|
<Icon class={iconClass} />
|
|
@@ -176,10 +210,34 @@
|
|
|
176
210
|
{/if}
|
|
177
211
|
</div>
|
|
178
212
|
{:else if type === "select"}
|
|
179
|
-
<Input
|
|
213
|
+
<Input
|
|
214
|
+
{id}
|
|
215
|
+
color={inputColor}
|
|
216
|
+
type="time"
|
|
217
|
+
{min}
|
|
218
|
+
{max}
|
|
219
|
+
{required}
|
|
220
|
+
{disabled}
|
|
221
|
+
class={styles.input({ class: clsx(theme?.input, inputClass) })}
|
|
222
|
+
bind:value
|
|
223
|
+
oninput={(e) => handleTimeChange(e)}
|
|
224
|
+
onchange={(e) => handleTimeChange(e)}
|
|
225
|
+
/>
|
|
180
226
|
<Select selectClass={styles.select({ class: clsx(theme?.select, selectClass) })} onchange={handleOptionSelect} items={options} value={selectedOption} />
|
|
181
227
|
{:else if type === "dropdown"}
|
|
182
|
-
<Input
|
|
228
|
+
<Input
|
|
229
|
+
{id}
|
|
230
|
+
color={inputColor}
|
|
231
|
+
type="time"
|
|
232
|
+
{min}
|
|
233
|
+
{max}
|
|
234
|
+
{required}
|
|
235
|
+
{disabled}
|
|
236
|
+
class={styles.input({ class: clsx(theme?.input, inputClass) })}
|
|
237
|
+
bind:value
|
|
238
|
+
oninput={(e) => handleTimeChange(e)}
|
|
239
|
+
onchange={(e) => handleTimeChange(e)}
|
|
240
|
+
/>
|
|
183
241
|
<Button color={buttonColor} class={styles.button({ class: clsx(theme?.button) })}>
|
|
184
242
|
{optionLabel}
|
|
185
243
|
<svg class={styles.buttonIcon({ class: clsx(theme?.buttonIcon) })} aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -195,7 +253,19 @@
|
|
|
195
253
|
</Dropdown>
|
|
196
254
|
{:else if type === "range"}
|
|
197
255
|
<div class={styles.rangeInputWrapper({ class: clsx(theme?.rangeInputWrapper) })}>
|
|
198
|
-
<Input
|
|
256
|
+
<Input
|
|
257
|
+
{id}
|
|
258
|
+
color={inputColor}
|
|
259
|
+
type="time"
|
|
260
|
+
{min}
|
|
261
|
+
{max}
|
|
262
|
+
{required}
|
|
263
|
+
{disabled}
|
|
264
|
+
class={styles.input({ class: clsx(theme?.rangeInput, styles.rangeInput(), inputClass) })}
|
|
265
|
+
bind:value
|
|
266
|
+
oninput={(e) => handleTimeChange(e)}
|
|
267
|
+
onchange={(e) => handleTimeChange(e)}
|
|
268
|
+
/>
|
|
199
269
|
<button type="button" class={styles.rangeButton({ class: clsx(theme?.rangeButton) })} onclick={() => document.getElementById(id)?.click()} aria-label="Open time picker">
|
|
200
270
|
{#if Icon}
|
|
201
271
|
<Icon class={iconClass} />
|
|
@@ -208,7 +278,19 @@
|
|
|
208
278
|
</div>
|
|
209
279
|
<span class={styles.rangeSeparator({ class: clsx(theme?.rangeSeparator) })}>-</span>
|
|
210
280
|
<div class={styles.rangeInputWrapper({ class: clsx(theme?.rangeInputWrapper) })}>
|
|
211
|
-
<Input
|
|
281
|
+
<Input
|
|
282
|
+
id={endId}
|
|
283
|
+
color={inputColor}
|
|
284
|
+
type="time"
|
|
285
|
+
{min}
|
|
286
|
+
{max}
|
|
287
|
+
{required}
|
|
288
|
+
{disabled}
|
|
289
|
+
class={styles.input({ class: clsx(styles.rangeInput(), theme?.rangeInput, inputClass) })}
|
|
290
|
+
bind:value={endValue}
|
|
291
|
+
oninput={(e) => handleTimeChange(e, true)}
|
|
292
|
+
onchange={(e) => handleTimeChange(e, true)}
|
|
293
|
+
/>
|
|
212
294
|
<button type="button" class={styles.rangeButton({ class: clsx(theme?.rangeButton) })} onclick={() => document.getElementById(endId)?.click()} aria-label="Open end time picker">
|
|
213
295
|
{#if Icon}
|
|
214
296
|
<Icon class={iconClass} />
|
|
@@ -231,11 +313,35 @@
|
|
|
231
313
|
<div class={styles.dropdownTimeRow({ class: clsx(theme?.dropdownTimeRow) })}>
|
|
232
314
|
<div class={styles.dropdownTimeCol({ class: clsx(theme?.dropdownTimeCol) })}>
|
|
233
315
|
<Label for={id}>Start time:</Label>
|
|
234
|
-
<Input
|
|
316
|
+
<Input
|
|
317
|
+
{id}
|
|
318
|
+
color={inputColor}
|
|
319
|
+
type="time"
|
|
320
|
+
{min}
|
|
321
|
+
{max}
|
|
322
|
+
{required}
|
|
323
|
+
{disabled}
|
|
324
|
+
class={styles.dropdownTimeInput({ class: clsx(theme?.dropdownTimeInput, inputClass) })}
|
|
325
|
+
bind:value
|
|
326
|
+
oninput={(e) => handleTimeChange(e)}
|
|
327
|
+
onchange={(e) => handleTimeChange(e)}
|
|
328
|
+
/>
|
|
235
329
|
</div>
|
|
236
330
|
<div class={styles.dropdownTimeCol({ class: clsx(theme?.dropdownTimeCol) })}>
|
|
237
331
|
<Label for={endId}>End time:</Label>
|
|
238
|
-
<Input
|
|
332
|
+
<Input
|
|
333
|
+
id={endId}
|
|
334
|
+
color={inputColor}
|
|
335
|
+
type="time"
|
|
336
|
+
{min}
|
|
337
|
+
{max}
|
|
338
|
+
{required}
|
|
339
|
+
{disabled}
|
|
340
|
+
class={styles.dropdownTimeInput({ class: clsx(theme?.dropdownTimeInput, inputClass) })}
|
|
341
|
+
bind:value={endValue}
|
|
342
|
+
oninput={(e) => handleTimeChange(e, true)}
|
|
343
|
+
onchange={(e) => handleTimeChange(e, true)}
|
|
344
|
+
/>
|
|
239
345
|
</div>
|
|
240
346
|
</div>
|
|
241
347
|
<Button color={buttonColor} class={styles.dropdownButton({ class: clsx(theme?.dropdownButton) })} onclick={applyTimerange}>
|
|
@@ -252,11 +358,35 @@
|
|
|
252
358
|
<div class={styles.toggleTimeRow({ class: clsx(theme?.toggleTimeRow) })}>
|
|
253
359
|
<div class={styles.toggleTimeCol({ class: clsx(theme?.toggleTimeCol) })}>
|
|
254
360
|
<Label for={id}>Start time:</Label>
|
|
255
|
-
<Input
|
|
361
|
+
<Input
|
|
362
|
+
{id}
|
|
363
|
+
color={inputColor}
|
|
364
|
+
type="time"
|
|
365
|
+
{min}
|
|
366
|
+
{max}
|
|
367
|
+
{required}
|
|
368
|
+
{disabled}
|
|
369
|
+
class={styles.toggleTimeInput({ class: clsx(theme?.toggleTimeInput, inputClass) })}
|
|
370
|
+
bind:value
|
|
371
|
+
oninput={(e) => handleTimeChange(e)}
|
|
372
|
+
onchange={(e) => handleTimeChange(e)}
|
|
373
|
+
/>
|
|
256
374
|
</div>
|
|
257
375
|
<div class={styles.toggleTimeCol({ class: clsx(theme?.toggleTimeCol) })}>
|
|
258
376
|
<Label for={endId}>End time:</Label>
|
|
259
|
-
<Input
|
|
377
|
+
<Input
|
|
378
|
+
id={endId}
|
|
379
|
+
color={inputColor}
|
|
380
|
+
type="time"
|
|
381
|
+
{min}
|
|
382
|
+
{max}
|
|
383
|
+
{required}
|
|
384
|
+
{disabled}
|
|
385
|
+
class={styles.toggleTimeInput({ class: clsx(theme?.toggleTimeInput, inputClass) })}
|
|
386
|
+
bind:value={endValue}
|
|
387
|
+
oninput={(e) => handleTimeChange(e, true)}
|
|
388
|
+
onchange={(e) => handleTimeChange(e, true)}
|
|
389
|
+
/>
|
|
260
390
|
</div>
|
|
261
391
|
</div>
|
|
262
392
|
{/if}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { KanbanBoardProps, KanbanCardType, KanbanColumnType } from "../types";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { kanbanBoard } from "./theme";
|
|
5
|
+
import { getTheme } from "../theme/themeUtils";
|
|
6
|
+
import KanbanCard from "./KanbanCard.svelte";
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
columns = $bindable([]),
|
|
10
|
+
onMove = (_card: KanbanCardType, _from: KanbanColumnType, _to: KanbanColumnType) => {},
|
|
11
|
+
onAddCard = (_col: KanbanColumnType) => {},
|
|
12
|
+
class: className,
|
|
13
|
+
classes,
|
|
14
|
+
...restProps
|
|
15
|
+
}: KanbanBoardProps = $props();
|
|
16
|
+
|
|
17
|
+
const theme = getTheme("kanbanBoard");
|
|
18
|
+
|
|
19
|
+
// Changed from KanbanCard to KanbanCardType
|
|
20
|
+
let draggedCard = $state<KanbanCardType | null>(null);
|
|
21
|
+
let sourceColumnId = $state<string | number | null>(null);
|
|
22
|
+
let dragOverColumnId = $state<string | number | null>(null);
|
|
23
|
+
|
|
24
|
+
const styles = kanbanBoard();
|
|
25
|
+
|
|
26
|
+
// Changed parameter type from KanbanCard to KanbanCardType
|
|
27
|
+
function handleDragStart(card: KanbanCardType, colId: string | number) {
|
|
28
|
+
draggedCard = card;
|
|
29
|
+
sourceColumnId = colId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function handleDragOver(e: DragEvent, colId: string | number) {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
dragOverColumnId = colId;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function handleDragLeave(e: DragEvent) {
|
|
38
|
+
const currentTarget = e.currentTarget as HTMLElement;
|
|
39
|
+
const relatedTarget = e.relatedTarget as Node | null;
|
|
40
|
+
if (!relatedTarget || !currentTarget.contains(relatedTarget)) {
|
|
41
|
+
dragOverColumnId = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function handleDrop(e: DragEvent, targetColId: string | number) {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
dragOverColumnId = null;
|
|
48
|
+
|
|
49
|
+
if (draggedCard === null || sourceColumnId === null) return;
|
|
50
|
+
if (sourceColumnId === targetColId) {
|
|
51
|
+
draggedCard = null;
|
|
52
|
+
sourceColumnId = null;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const fromCol = columns.find((c) => c.id === sourceColumnId);
|
|
57
|
+
const toCol = columns.find((c) => c.id === targetColId);
|
|
58
|
+
if (!fromCol || !toCol) return;
|
|
59
|
+
|
|
60
|
+
fromCol.cards = fromCol.cards.filter((c) => c.id !== draggedCard!.id);
|
|
61
|
+
toCol.cards = [...toCol.cards, draggedCard!];
|
|
62
|
+
|
|
63
|
+
onMove(draggedCard, fromCol, toCol);
|
|
64
|
+
|
|
65
|
+
draggedCard = null;
|
|
66
|
+
sourceColumnId = null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function handleDragEnd() {
|
|
70
|
+
draggedCard = null;
|
|
71
|
+
sourceColumnId = null;
|
|
72
|
+
dragOverColumnId = null;
|
|
73
|
+
}
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<div {...restProps} class={styles.container({ class: clsx(theme?.container, className) })}>
|
|
77
|
+
{#each columns as col (col.id)}
|
|
78
|
+
<div
|
|
79
|
+
role="group"
|
|
80
|
+
aria-label={`${col.title} column drop zone`}
|
|
81
|
+
class={styles.column({ isDragOver: dragOverColumnId === col.id, class: clsx(theme?.column, classes?.column) })}
|
|
82
|
+
ondragover={(e) => handleDragOver(e, col.id)}
|
|
83
|
+
ondragleave={(e) => handleDragLeave(e)}
|
|
84
|
+
ondrop={(e) => handleDrop(e, col.id)}
|
|
85
|
+
style={col.color ? `border-top: 4px solid ${col.color}` : ""}
|
|
86
|
+
>
|
|
87
|
+
<h2 class={styles.columnTitle({ class: clsx(theme?.columnTitle, classes?.columnTitle) })}>{col.title}</h2>
|
|
88
|
+
|
|
89
|
+
<div class={styles.cardList({ class: clsx(theme?.cardList, classes?.cardList) })} role="list" aria-label={`${col.title} cards`}>
|
|
90
|
+
{#each col.cards as card (card.id)}
|
|
91
|
+
<KanbanCard {card} {classes} isDragging={draggedCard?.id === card.id} onDragStart={() => handleDragStart(card, col.id)} onDragEnd={handleDragEnd} />
|
|
92
|
+
{/each}
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<button class={styles.addButton({ class: clsx(theme?.addButton, classes?.addButton) })} onclick={() => onAddCard(col)} aria-label={`Add card to ${col.title}`}>+ Add card</button>
|
|
96
|
+
</div>
|
|
97
|
+
{/each}
|
|
98
|
+
</div>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import type { KanbanCardProps } from "../types";
|
|
4
|
+
import { kanbanCard } from "./theme";
|
|
5
|
+
import { getTheme } from "../theme/themeUtils";
|
|
6
|
+
|
|
7
|
+
let { card, isDragging = false, onDragStart, onDragEnd, classes, ...restProps }: KanbanCardProps = $props();
|
|
8
|
+
|
|
9
|
+
const theme = getTheme("kanbanCard");
|
|
10
|
+
const styles = kanbanCard();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
14
|
+
<article
|
|
15
|
+
role="listitem"
|
|
16
|
+
draggable="true"
|
|
17
|
+
{...restProps}
|
|
18
|
+
ondragstart={(ev) => onDragStart?.(card, ev)}
|
|
19
|
+
ondragend={(ev) => onDragEnd?.(ev)}
|
|
20
|
+
tabindex="0"
|
|
21
|
+
aria-grabbed={isDragging}
|
|
22
|
+
aria-label={card.title}
|
|
23
|
+
class={styles.card({ isDragging, class: clsx(theme?.card, classes?.card) })}
|
|
24
|
+
>
|
|
25
|
+
<p class={styles.cardTitle({ class: clsx(theme?.cardTitle, classes?.cardTitle) })}>
|
|
26
|
+
{card.title}
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
{#if card.description}
|
|
30
|
+
<p class={styles.cardDescription({ class: clsx(theme?.cardDescription, classes?.cardDescription) })}>
|
|
31
|
+
{card.description}
|
|
32
|
+
</p>
|
|
33
|
+
{/if}
|
|
34
|
+
|
|
35
|
+
{#if card.tags?.length}
|
|
36
|
+
<div class={styles.cardTags({ class: clsx(theme?.cardTags, classes?.cardTags) })}>
|
|
37
|
+
{#each card.tags as tag, i (i)}
|
|
38
|
+
<span class={styles.cardTag({ class: clsx(theme?.cardTag, classes?.cardTag) })}>
|
|
39
|
+
{tag}
|
|
40
|
+
</span>
|
|
41
|
+
{/each}
|
|
42
|
+
</div>
|
|
43
|
+
{/if}
|
|
44
|
+
</article>
|
|
45
|
+
|
|
46
|
+
<!--
|
|
47
|
+
@component
|
|
48
|
+
[Go to docs](https://flowbite-svelte.com/)
|
|
49
|
+
## Type
|
|
50
|
+
[KanbanCardProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2082)
|
|
51
|
+
## Props
|
|
52
|
+
@prop card
|
|
53
|
+
@prop isDragging = false
|
|
54
|
+
@prop onDragStart
|
|
55
|
+
@prop onDragEnd
|
|
56
|
+
@prop classes
|
|
57
|
+
@prop ...restProps
|
|
58
|
+
-->
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { KanbanCardProps } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* [Go to docs](https://flowbite-svelte.com/)
|
|
4
|
+
* ## Type
|
|
5
|
+
* [KanbanCardProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2082)
|
|
6
|
+
* ## Props
|
|
7
|
+
* @prop card
|
|
8
|
+
* @prop isDragging = false
|
|
9
|
+
* @prop onDragStart
|
|
10
|
+
* @prop onDragEnd
|
|
11
|
+
* @prop classes
|
|
12
|
+
* @prop ...restProps
|
|
13
|
+
*/
|
|
14
|
+
declare const KanbanCard: import("svelte").Component<KanbanCardProps, {}, "">;
|
|
15
|
+
type KanbanCard = ReturnType<typeof KanbanCard>;
|
|
16
|
+
export default KanbanCard;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { type VariantProps } from "tailwind-variants";
|
|
2
|
+
import type { Classes } from "../theme/themeUtils";
|
|
3
|
+
export type KanbanBoardVariants = VariantProps<typeof kanbanBoard> & Classes<typeof kanbanBoard>;
|
|
4
|
+
export type KanbanCardVariants = VariantProps<typeof kanbanCard> & Classes<typeof kanbanCard>;
|
|
5
|
+
export declare const kanbanBoard: import("tailwind-variants").TVReturnType<{
|
|
6
|
+
isDragOver: {
|
|
7
|
+
true: {
|
|
8
|
+
column: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
isDragging: {
|
|
12
|
+
true: {
|
|
13
|
+
card: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
}, {
|
|
17
|
+
container: string;
|
|
18
|
+
column: string;
|
|
19
|
+
columnTitle: string;
|
|
20
|
+
cardList: string;
|
|
21
|
+
card: string;
|
|
22
|
+
cardTitle: string;
|
|
23
|
+
cardDescription: string;
|
|
24
|
+
cardTags: string;
|
|
25
|
+
cardTag: string;
|
|
26
|
+
addButton: string;
|
|
27
|
+
}, undefined, {
|
|
28
|
+
isDragOver: {
|
|
29
|
+
true: {
|
|
30
|
+
column: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
isDragging: {
|
|
34
|
+
true: {
|
|
35
|
+
card: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
}, {
|
|
39
|
+
container: string;
|
|
40
|
+
column: string;
|
|
41
|
+
columnTitle: string;
|
|
42
|
+
cardList: string;
|
|
43
|
+
card: string;
|
|
44
|
+
cardTitle: string;
|
|
45
|
+
cardDescription: string;
|
|
46
|
+
cardTags: string;
|
|
47
|
+
cardTag: string;
|
|
48
|
+
addButton: string;
|
|
49
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
50
|
+
isDragOver: {
|
|
51
|
+
true: {
|
|
52
|
+
column: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
isDragging: {
|
|
56
|
+
true: {
|
|
57
|
+
card: string;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
}, {
|
|
61
|
+
container: string;
|
|
62
|
+
column: string;
|
|
63
|
+
columnTitle: string;
|
|
64
|
+
cardList: string;
|
|
65
|
+
card: string;
|
|
66
|
+
cardTitle: string;
|
|
67
|
+
cardDescription: string;
|
|
68
|
+
cardTags: string;
|
|
69
|
+
cardTag: string;
|
|
70
|
+
addButton: string;
|
|
71
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
72
|
+
export declare const kanbanCard: import("tailwind-variants").TVReturnType<{
|
|
73
|
+
isDragging: {
|
|
74
|
+
true: {
|
|
75
|
+
card: string;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
}, {
|
|
79
|
+
card: string;
|
|
80
|
+
cardTitle: string;
|
|
81
|
+
cardDescription: string;
|
|
82
|
+
cardTags: string;
|
|
83
|
+
cardTag: string;
|
|
84
|
+
}, undefined, {
|
|
85
|
+
isDragging: {
|
|
86
|
+
true: {
|
|
87
|
+
card: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
}, {
|
|
91
|
+
card: string;
|
|
92
|
+
cardTitle: string;
|
|
93
|
+
cardDescription: string;
|
|
94
|
+
cardTags: string;
|
|
95
|
+
cardTag: string;
|
|
96
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
97
|
+
isDragging: {
|
|
98
|
+
true: {
|
|
99
|
+
card: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
}, {
|
|
103
|
+
card: string;
|
|
104
|
+
cardTitle: string;
|
|
105
|
+
cardDescription: string;
|
|
106
|
+
cardTags: string;
|
|
107
|
+
cardTag: string;
|
|
108
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
export const kanbanBoard = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
container: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3 md:gap-4 p-2 md:p-4",
|
|
5
|
+
column: "w-full rounded-xl shadow-sm p-3 md:p-4 flex flex-col bg-surface-elevated text-surface-foreground transition-colors",
|
|
6
|
+
columnTitle: "text-sm md:text-base font-semibold mb-2 md:mb-3",
|
|
7
|
+
cardList: "flex flex-col gap-2 flex-1 min-h-[60px]",
|
|
8
|
+
card: "bg-surface text-surface-foreground rounded-lg p-2.5 md:p-3 shadow-sm cursor-grab active:cursor-grabbing transition-all hover:bg-surface-hover hover:shadow-md",
|
|
9
|
+
cardTitle: "font-medium text-sm md:text-base",
|
|
10
|
+
cardDescription: "text-xs md:text-sm text-muted mt-1",
|
|
11
|
+
cardTags: "flex flex-wrap gap-1 mt-2",
|
|
12
|
+
cardTag: "text-[10px] md:text-xs bg-primary/10 text-primary px-1.5 md:px-2 py-0.5 rounded-full",
|
|
13
|
+
addButton: "mt-2 md:mt-3 w-full bg-primary text-primary-foreground rounded-lg py-1.5 text-xs md:text-sm font-medium hover:bg-primary/90 transition-colors focus:ring-2 focus:ring-primary focus:ring-offset-2"
|
|
14
|
+
},
|
|
15
|
+
variants: {
|
|
16
|
+
isDragOver: {
|
|
17
|
+
true: {
|
|
18
|
+
column: "ring-2 ring-primary"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
isDragging: {
|
|
22
|
+
true: {
|
|
23
|
+
card: "opacity-50"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
export const kanbanCard = tv({
|
|
29
|
+
slots: {
|
|
30
|
+
card: "bg-surface text-surface-foreground rounded-lg p-2.5 md:p-3 shadow-sm cursor-grab active:cursor-grabbing transition-all hover:bg-surface-hover hover:shadow-md",
|
|
31
|
+
cardTitle: "font-medium text-sm md:text-base",
|
|
32
|
+
cardDescription: "text-xs md:text-sm text-muted mt-1",
|
|
33
|
+
cardTags: "flex flex-wrap gap-1 mt-2",
|
|
34
|
+
cardTag: "text-[10px] md:text-xs bg-primary/10 text-primary px-1.5 md:px-2 py-0.5 rounded-full"
|
|
35
|
+
},
|
|
36
|
+
variants: {
|
|
37
|
+
isDragging: {
|
|
38
|
+
true: {
|
|
39
|
+
card: "opacity-50"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { megamenu } from "./theme";
|
|
3
3
|
import clsx from "clsx";
|
|
4
|
-
import type { MegaMenuProps
|
|
4
|
+
import type { MegaMenuProps } from "..";
|
|
5
5
|
import Popper from "../utils/Popper.svelte";
|
|
6
6
|
import { getTheme, warnThemeDeprecation } from "../theme/themeUtils";
|
|
7
7
|
|
|
@@ -10,14 +10,7 @@
|
|
|
10
10
|
// ulClass, extraClass
|
|
11
11
|
warnThemeDeprecation("MegaMenu", { ulClass, extraClass }, { ulClass: "ul", extraClass: "extra" });
|
|
12
12
|
const styling = $derived(classes ?? { ul: ulClass, extra: extraClass });
|
|
13
|
-
|
|
14
13
|
const theme = getTheme("megamenu");
|
|
15
|
-
|
|
16
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
17
|
-
interface LinkTypeLike extends LinkType {
|
|
18
|
-
[propName: string]: any;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
14
|
const { base, div, ul, extra: extraCls } = $derived(megamenu({ full, hasExtra: !!extra }));
|
|
22
15
|
</script>
|
|
23
16
|
|
package/dist/modal/Modal.svelte
CHANGED
|
@@ -8,7 +8,27 @@
|
|
|
8
8
|
import { fade } from "svelte/transition";
|
|
9
9
|
import { modal as modalStyle } from "./theme";
|
|
10
10
|
|
|
11
|
-
let {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
header,
|
|
14
|
+
footer,
|
|
15
|
+
title,
|
|
16
|
+
open = $bindable(false),
|
|
17
|
+
permanent = false,
|
|
18
|
+
dismissable = true,
|
|
19
|
+
closeBtnClass,
|
|
20
|
+
headerClass,
|
|
21
|
+
bodyClass,
|
|
22
|
+
footerClass,
|
|
23
|
+
size = "md",
|
|
24
|
+
placement,
|
|
25
|
+
class: className,
|
|
26
|
+
classes,
|
|
27
|
+
transitionParams,
|
|
28
|
+
transition = fade,
|
|
29
|
+
fullscreen = false,
|
|
30
|
+
...restProps
|
|
31
|
+
}: ModalProps = $props();
|
|
12
32
|
|
|
13
33
|
// form, header, footer, body, close
|
|
14
34
|
warnThemeDeprecation("Modal", { headerClass, bodyClass, footerClass, closeBtnClass }, { bodyClass: "body", headerClass: "header", footerClass: "footer", closeBtnClass: "close" });
|
|
@@ -22,7 +42,15 @@
|
|
|
22
42
|
const { base, header: headerCls, footer: footerCls, body } = $derived(modalStyle({ placement, size }));
|
|
23
43
|
</script>
|
|
24
44
|
|
|
25
|
-
<Dialog
|
|
45
|
+
<Dialog
|
|
46
|
+
bind:open
|
|
47
|
+
{transition}
|
|
48
|
+
dismissable={dismissable && !title && !permanent}
|
|
49
|
+
transitionParams={paramsOptions}
|
|
50
|
+
{classes}
|
|
51
|
+
{...restProps}
|
|
52
|
+
class={base({ fullscreen, class: clsx(theme?.base, className) })}
|
|
53
|
+
>
|
|
26
54
|
{#if title || header}
|
|
27
55
|
<div class={headerCls({ class: clsx(theme?.header, styling.header) })}>
|
|
28
56
|
{#if title}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const navBreakpoint = getContext<NavbarBreakpoint>("breakpoint");
|
|
19
19
|
const { base, menu } = navbarHamburger({ breakpoint: navBreakpoint });
|
|
20
20
|
|
|
21
|
-
const toggle: MouseEventHandler<HTMLButtonElement> = (
|
|
21
|
+
const toggle: MouseEventHandler<HTMLButtonElement> = () => {
|
|
22
22
|
navState.hidden = !navState.hidden;
|
|
23
23
|
};
|
|
24
24
|
</script>
|
package/dist/navbar/NavLi.svelte
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
const theme = getTheme("navbarLi");
|
|
14
14
|
|
|
15
15
|
let active = $derived(navState.activeUrl ? restProps.href === navState.activeUrl : false);
|
|
16
|
-
let liClass = $derived(
|
|
16
|
+
let liClass = $derived(
|
|
17
|
+
navbarLi({ breakpoint: navBreakpoint, hidden: navState.hidden, class: clsx(active ? (activeClass ?? navState.activeClass) : (nonActiveClass ?? navState.nonActiveClass), theme, className) })
|
|
18
|
+
);
|
|
17
19
|
|
|
18
20
|
function handleClick(event: any) {
|
|
19
21
|
// Close the mobile menu when a link is clicked
|