fuma 0.5.1 → 1.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/README.md +1 -1
- package/dist/private/Meta.svelte +32 -27
- package/dist/private/Meta.svelte.d.ts +1 -0
- package/dist/private/api.d.ts +1 -1
- package/dist/ui/badge/Badge.svelte +4 -3
- package/dist/ui/button/ButtonCopy.svelte +32 -26
- package/dist/ui/button/ButtonDelete.svelte +23 -21
- package/dist/ui/button/ButtonDelete.svelte.d.ts +1 -0
- package/dist/ui/card/Card.svelte +13 -10
- package/dist/ui/card/Card.svelte.d.ts +1 -0
- package/dist/ui/card/CardBasic.svelte +5 -4
- package/dist/ui/card/CardBasic.svelte.d.ts +1 -0
- package/dist/ui/card/CardCollapse.svelte +35 -31
- package/dist/ui/card/CardCollapse.svelte.d.ts +1 -0
- package/dist/ui/card/CardFullScreen.svelte +8 -6
- package/dist/ui/card/CardFullScreen.svelte.d.ts +3 -0
- package/dist/ui/card/CardLink.svelte +5 -4
- package/dist/ui/card/CardLink.svelte.d.ts +1 -0
- package/dist/ui/dialog/Dialog.svelte +41 -34
- package/dist/ui/dialog/Dialog.svelte.d.ts +1 -0
- package/dist/ui/dialog/DialogConfirm.svelte +6 -4
- package/dist/ui/dialog/DialogConfirm.svelte.d.ts +1 -0
- package/dist/ui/drawer/Drawer.svelte +47 -38
- package/dist/ui/drawer/Drawer.svelte.d.ts +16 -0
- package/dist/ui/form/Form.svelte +101 -83
- package/dist/ui/form/Form.svelte.d.ts +1 -0
- package/dist/ui/form/FormInput.svelte +12 -6
- package/dist/ui/form/FormInput.svelte.d.ts +30 -8
- package/dist/ui/form/FormSection.svelte +24 -17
- package/dist/ui/form/formInput.d.ts +7 -4
- package/dist/ui/icon/Icon.svelte +35 -32
- package/dist/ui/index.d.ts +0 -1
- package/dist/ui/index.js +0 -1
- package/dist/ui/input/FormControl.svelte +48 -36
- package/dist/ui/input/FormControl.svelte.d.ts +7 -9
- package/dist/ui/input/InputBoolean.svelte +29 -22
- package/dist/ui/input/InputBoolean.svelte.d.ts +5 -1
- package/dist/ui/input/InputCheckboxs.svelte +37 -34
- package/dist/ui/input/InputCheckboxs.svelte.d.ts +5 -1
- package/dist/ui/input/InputCheckboxsMenu.svelte +64 -47
- package/dist/ui/input/InputCheckboxsMenu.svelte.d.ts +5 -1
- package/dist/ui/input/InputCheckboxsTree.svelte +9 -6
- package/dist/ui/input/InputCheckboxsTreeNodes.svelte +36 -28
- package/dist/ui/input/InputCombo.svelte +76 -65
- package/dist/ui/input/InputCombo.svelte.d.ts +5 -1
- package/dist/ui/input/InputDate.svelte +36 -29
- package/dist/ui/input/InputDateTime.svelte +37 -30
- package/dist/ui/input/InputImage.svelte +52 -45
- package/dist/ui/input/InputImage.svelte.d.ts +1 -0
- package/dist/ui/input/InputImagePreview.svelte +24 -20
- package/dist/ui/input/InputNumber.svelte +28 -22
- package/dist/ui/input/InputNumber.svelte.d.ts +1 -5
- package/dist/ui/input/InputOptionInParam.svelte +12 -10
- package/dist/ui/input/InputOptions.svelte +40 -34
- package/dist/ui/input/InputPassword.svelte +22 -18
- package/dist/ui/input/InputPassword.svelte.d.ts +5 -1
- package/dist/ui/input/InputRadio.svelte +51 -46
- package/dist/ui/input/InputRadio.svelte.d.ts +5 -1
- package/dist/ui/input/InputRelation.svelte +119 -111
- package/dist/ui/input/InputRelation.svelte.d.ts +6 -12
- package/dist/ui/input/InputRelations.svelte +94 -90
- package/dist/ui/input/InputRelations.svelte.d.ts +5 -12
- package/dist/ui/input/InputSearch.svelte +13 -10
- package/dist/ui/input/InputSelect.svelte +59 -46
- package/dist/ui/input/InputText.svelte +29 -28
- package/dist/ui/input/InputText.svelte.d.ts +0 -3
- package/dist/ui/input/InputTextarea.svelte +20 -19
- package/dist/ui/input/InputTextarea.svelte.d.ts +1 -5
- package/dist/ui/input/InputTime.svelte +43 -35
- package/dist/ui/input/RelationAfter.svelte +13 -9
- package/dist/ui/input/SelectorList.svelte +16 -12
- package/dist/ui/input/SelectorList.svelte.d.ts +4 -0
- package/dist/ui/input/textRich/InputTextRich.svelte +63 -54
- package/dist/ui/input/textRich/InputTextRich.svelte.d.ts +5 -1
- package/dist/ui/input/textRich/SuggesionList.svelte +13 -9
- package/dist/ui/input/textRich/ToolMark.svelte +12 -9
- package/dist/ui/input/textRich/ToolMarkColor.svelte +16 -12
- package/dist/ui/input/textRich/ToolMarkLink.svelte +46 -38
- package/dist/ui/input/textRich/ToolMenu.svelte +34 -19
- package/dist/ui/input/textRich/ToolMenuAlign.svelte +13 -9
- package/dist/ui/input/textRich/ToolMenuInsert.svelte +12 -7
- package/dist/ui/input/textRich/ToolMenuNode.svelte +14 -10
- package/dist/ui/input/textRich/ToolsBar.svelte +17 -13
- package/dist/ui/login/Login.svelte +37 -31
- package/dist/ui/menu/ContextMenu.svelte +37 -31
- package/dist/ui/menu/ContextMenu.svelte.d.ts +1 -0
- package/dist/ui/menu/DropDown.svelte +92 -83
- package/dist/ui/menu/DropDown.svelte.d.ts +1 -0
- package/dist/ui/menu/DropDownMenu.svelte +25 -18
- package/dist/ui/menu/DropDownMenu.svelte.d.ts +1 -0
- package/dist/ui/mode/ToggleMode.svelte +19 -15
- package/dist/ui/mode/ToggleMode.svelte.d.ts +7 -1
- package/dist/ui/pagination/Pagination.svelte +9 -8
- package/dist/ui/placeholder/Placeholder.svelte +4 -3
- package/dist/ui/placeholder/Placeholder.svelte.d.ts +1 -0
- package/dist/ui/placeholder/PlaceholderImage.svelte +6 -4
- package/dist/ui/placeholder/PlaceholderImage.svelte.d.ts +1 -0
- package/dist/ui/range/RangePicker.svelte +76 -63
- package/dist/ui/range/RangePickerButton.svelte +43 -35
- package/dist/ui/table/Table.svelte +35 -28
- package/dist/ui/table/TableBody.svelte +18 -12
- package/dist/ui/table/TableCell.svelte +13 -10
- package/dist/ui/table/TableFieldsEdition.svelte +57 -51
- package/dist/ui/table/TableHead.svelte +19 -20
- package/dist/ui/table/TableViewSelect.svelte +50 -37
- package/dist/ui/table/cell/TableCellArray.svelte +5 -3
- package/dist/ui/table/cell/TableCellBoolean.svelte +4 -3
- package/dist/ui/table/cell/TableCellNumber.svelte +2 -1
- package/dist/ui/table/cell/TableCellString.svelte +5 -2
- package/dist/ui/table/head/TableHeadBoolean.svelte +6 -3
- package/dist/ui/table/head/TableHeadDate.svelte +54 -47
- package/dist/ui/table/head/TableHeadDefault.svelte +5 -2
- package/dist/ui/table/head/TableHeadNumber.svelte +65 -53
- package/dist/ui/table/head/TableHeadSelect.svelte +47 -41
- package/dist/ui/table/head/TableHeadString.svelte +14 -8
- package/dist/ui/tabs/Tabs.svelte +8 -5
- package/dist/ui/tabs/TabsIcon.svelte +31 -28
- package/package.json +32 -33
- package/dist/ui/slot/Slot.svelte +0 -35
- package/dist/ui/slot/Slot.svelte.d.ts +0 -22
- package/dist/ui/slot/Span.svelte +0 -4
- package/dist/ui/slot/Span.svelte.d.ts +0 -16
- package/dist/ui/slot/index.d.ts +0 -1
- package/dist/ui/slot/index.js +0 -1
|
@@ -5,13 +5,17 @@ declare const __propDef: {
|
|
|
5
5
|
class?: string | undefined;
|
|
6
6
|
classLabel?: string | undefined;
|
|
7
7
|
key?: string | undefined;
|
|
8
|
-
label?: string | import("svelte").
|
|
8
|
+
label?: string | import("svelte").Snippet<[]> | undefined;
|
|
9
|
+
labelAppend?: import("svelte").Snippet<[]> | null | undefined;
|
|
9
10
|
error?: string | undefined;
|
|
10
11
|
hint?: string | undefined;
|
|
11
12
|
prefix?: string | number | undefined;
|
|
12
13
|
prefixFor?: string | number | undefined;
|
|
13
14
|
enhanceDisabled?: boolean | undefined;
|
|
14
15
|
labelPosition?: ("top" | "left" | "right") | undefined;
|
|
16
|
+
children?: import("svelte").Snippet<[{
|
|
17
|
+
key: string;
|
|
18
|
+
}]> | undefined;
|
|
15
19
|
} & {
|
|
16
20
|
input?: import("svelte/elements.js").HTMLInputAttributes | undefined;
|
|
17
21
|
inputElement?: HTMLInputElement | undefined;
|
|
@@ -1,116 +1,128 @@
|
|
|
1
|
-
<script generics="RelationItem extends {id: string}">
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export let
|
|
16
|
-
export let
|
|
17
|
-
let
|
|
18
|
-
export
|
|
19
|
-
export let
|
|
20
|
-
export let
|
|
21
|
-
|
|
22
|
-
export
|
|
23
|
-
export let
|
|
24
|
-
export let
|
|
25
|
-
export let
|
|
26
|
-
export let
|
|
27
|
-
let
|
|
28
|
-
export
|
|
29
|
-
export let
|
|
30
|
-
let
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
let
|
|
34
|
-
|
|
35
|
-
let
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
1
|
+
<script lang="ts" generics="RelationItem extends {id: string}">
|
|
2
|
+
import { createEventDispatcher, tick, type ComponentProps, type Snippet } from 'svelte'
|
|
3
|
+
import type { HTMLInputAttributes } from 'svelte/elements'
|
|
4
|
+
import debounce from 'debounce'
|
|
5
|
+
import { toast } from 'svelte-sonner'
|
|
6
|
+
import { mdiClose } from '@mdi/js'
|
|
7
|
+
|
|
8
|
+
import { USE_COERCE_JSON } from '../../utils/constant.js'
|
|
9
|
+
import { Icon } from '../icon/index.js'
|
|
10
|
+
import { DropDown } from '../menu/index.js'
|
|
11
|
+
import { FormControl, SelectorList } from './index.js'
|
|
12
|
+
import type { TippyProps } from '../../utils/tippy.js'
|
|
13
|
+
import RelationAfter from './RelationAfter.svelte'
|
|
14
|
+
|
|
15
|
+
export let key = Math.random().toString()
|
|
16
|
+
export let label = ''
|
|
17
|
+
export let search: (q: string) => Promise<RelationItem[]>
|
|
18
|
+
export let createUrl = ''
|
|
19
|
+
export let createTitle = 'Nouveau'
|
|
20
|
+
export let createIcon: string | undefined = undefined
|
|
21
|
+
let item: RelationItem | null = null
|
|
22
|
+
export { item as value }
|
|
23
|
+
export let error = ''
|
|
24
|
+
export let placeholder = ''
|
|
25
|
+
export let tippyProps: Partial<TippyProps> = {}
|
|
26
|
+
export let dropdownProps: ComponentProps<DropDown> = {}
|
|
27
|
+
export let flatMode = false
|
|
28
|
+
export let slotItem: Snippet<[RelationItem]>
|
|
29
|
+
export let slotSuggestion: Snippet<[RelationItem]> = slotItem
|
|
30
|
+
export let input: HTMLInputAttributes | undefined = undefined
|
|
31
|
+
export let append: Snippet | undefined = undefined
|
|
32
|
+
|
|
33
|
+
let klass = ''
|
|
34
|
+
export { klass as class }
|
|
35
|
+
export let classList = ''
|
|
36
|
+
|
|
37
|
+
let inputElement: HTMLInputElement
|
|
38
|
+
|
|
39
|
+
let proposedItems: RelationItem[] = []
|
|
40
|
+
|
|
41
|
+
let isLoading = false
|
|
42
|
+
let isError = false
|
|
43
|
+
let focusIndex = 0
|
|
44
|
+
let searchValue = ''
|
|
45
|
+
|
|
46
|
+
const dispatch = createEventDispatcher<{ input: { value: RelationItem } }>()
|
|
47
|
+
|
|
48
|
+
export async function clear() {
|
|
49
|
+
searchValue = ''
|
|
50
|
+
item = null
|
|
51
|
+
await tick()
|
|
52
|
+
inputElement.focus()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function select(index = focusIndex) {
|
|
56
|
+
item = proposedItems[index]
|
|
57
|
+
dispatch('input', { value: item })
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function searchItems(searchValue = '') {
|
|
61
|
+
try {
|
|
62
|
+
isLoading = true
|
|
63
|
+
isError = false
|
|
64
|
+
focusIndex = 0
|
|
65
|
+
proposedItems = await search(searchValue)
|
|
66
|
+
} catch (error) {
|
|
67
|
+
toast.error('Erreur')
|
|
68
|
+
isError = true
|
|
69
|
+
console.error(error)
|
|
70
|
+
} finally {
|
|
71
|
+
isLoading = false
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const searchItemsDebounce = debounce(searchItems, 150)
|
|
76
|
+
|
|
77
|
+
function handleFocus() {
|
|
78
|
+
searchItems()
|
|
79
|
+
}
|
|
80
|
+
async function handleBlur() {
|
|
81
|
+
searchValue = ''
|
|
82
|
+
}
|
|
68
83
|
</script>
|
|
69
84
|
|
|
70
85
|
<DropDown {tippyProps} disable={flatMode} {...dropdownProps}>
|
|
71
86
|
<div class="contents" slot="activator">
|
|
72
|
-
<FormControl {key} {label} {error} class={klass}
|
|
73
|
-
|
|
74
|
-
<div class="
|
|
75
|
-
<input
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
<FormControl {key} {label} {error} class={klass}>
|
|
88
|
+
{#snippet children({ key })}
|
|
89
|
+
<div class="flex grow gap-2" class:hidden={item}>
|
|
90
|
+
<div class="input input-bordered flex grow items-center pr-2">
|
|
91
|
+
<input
|
|
92
|
+
type="text"
|
|
93
|
+
id={key}
|
|
94
|
+
bind:this={inputElement}
|
|
95
|
+
bind:value={searchValue}
|
|
96
|
+
on:input={(e) => searchItemsDebounce(e.currentTarget.value)}
|
|
97
|
+
on:focus={handleFocus}
|
|
98
|
+
on:blur={handleBlur}
|
|
99
|
+
autocomplete="off"
|
|
100
|
+
{placeholder}
|
|
101
|
+
class="grow"
|
|
102
|
+
size={8}
|
|
103
|
+
{...input}
|
|
104
|
+
/>
|
|
105
|
+
<RelationAfter {isLoading} {createUrl} {createTitle} {createIcon} />
|
|
106
|
+
</div>
|
|
107
|
+
{@render append?.()}
|
|
91
108
|
</div>
|
|
92
|
-
<slot name="append" />
|
|
93
|
-
</div>
|
|
94
109
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
</
|
|
110
|
+
{#if item}
|
|
111
|
+
<div class="flex h-12 items-center gap-2 rounded-lg border bg-base-100 pl-4 pr-2">
|
|
112
|
+
<div class="grow">
|
|
113
|
+
{@render slotItem(item)}
|
|
114
|
+
</div>
|
|
115
|
+
<button type="button" on:click={() => clear()} class="btn btn-square btn-sm">
|
|
116
|
+
<Icon path={mdiClose} />
|
|
117
|
+
</button>
|
|
103
118
|
</div>
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
value="{USE_COERCE_JSON}{JSON.stringify({ id: item.id })}"
|
|
112
|
-
/>
|
|
113
|
-
{/if}
|
|
119
|
+
<input
|
|
120
|
+
type="hidden"
|
|
121
|
+
name={key}
|
|
122
|
+
value="{USE_COERCE_JSON}{JSON.stringify({ id: item.id })}"
|
|
123
|
+
/>
|
|
124
|
+
{/if}
|
|
125
|
+
{/snippet}
|
|
114
126
|
</FormControl>
|
|
115
127
|
</div>
|
|
116
128
|
|
|
@@ -124,10 +136,6 @@ async function handleBlur() {
|
|
|
124
136
|
class="w-full min-w-40 {classList}"
|
|
125
137
|
on:select={({ detail }) => select(detail)}
|
|
126
138
|
>
|
|
127
|
-
|
|
128
|
-
<Slot slot={slotSuggestion} args={proposedItems[index]}>
|
|
129
|
-
{proposedItems[index].id}
|
|
130
|
-
</Slot>
|
|
131
|
-
</slot>
|
|
139
|
+
{@render slotSuggestion(proposedItems[index])}
|
|
132
140
|
</SelectorList>
|
|
133
141
|
</DropDown>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type Snippet } from 'svelte';
|
|
2
3
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
4
|
import type { TippyProps } from '../../utils/tippy.js';
|
|
4
|
-
import type { ComponentAndProps } from '../../utils/component.js';
|
|
5
5
|
declare class __sveltets_Render<RelationItem extends {
|
|
6
6
|
id: string;
|
|
7
7
|
}> {
|
|
@@ -31,11 +31,13 @@ declare class __sveltets_Render<RelationItem extends {
|
|
|
31
31
|
hide?: (() => void) | undefined;
|
|
32
32
|
show?: (() => void) | undefined;
|
|
33
33
|
setTippyProps?: ((props: Partial<TippyProps>) => void) | undefined;
|
|
34
|
+
children?: Snippet<[]> | undefined;
|
|
34
35
|
} | undefined;
|
|
35
36
|
flatMode?: boolean | undefined;
|
|
36
|
-
slotItem
|
|
37
|
-
slotSuggestion?:
|
|
37
|
+
slotItem: Snippet<[RelationItem]>;
|
|
38
|
+
slotSuggestion?: Snippet<[RelationItem]> | undefined;
|
|
38
39
|
input?: HTMLInputAttributes | undefined;
|
|
40
|
+
append?: Snippet<[]> | undefined;
|
|
39
41
|
class?: string | undefined;
|
|
40
42
|
classList?: string | undefined;
|
|
41
43
|
clear?: (() => Promise<void>) | undefined;
|
|
@@ -47,15 +49,7 @@ declare class __sveltets_Render<RelationItem extends {
|
|
|
47
49
|
} & {
|
|
48
50
|
[evt: string]: CustomEvent<any>;
|
|
49
51
|
};
|
|
50
|
-
slots(): {
|
|
51
|
-
append: {};
|
|
52
|
-
item: {
|
|
53
|
-
item: RelationItem | null;
|
|
54
|
-
};
|
|
55
|
-
suggestion: {
|
|
56
|
-
item: RelationItem;
|
|
57
|
-
};
|
|
58
|
-
};
|
|
52
|
+
slots(): {};
|
|
59
53
|
}
|
|
60
54
|
export type InputRelationProps<RelationItem extends {
|
|
61
55
|
id: string;
|
|
@@ -1,82 +1,94 @@
|
|
|
1
|
-
<script generics="RelationItem extends {id: string}">
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export let
|
|
17
|
-
export let
|
|
18
|
-
export let
|
|
19
|
-
export let
|
|
20
|
-
export let
|
|
21
|
-
export let
|
|
22
|
-
export let
|
|
23
|
-
export let
|
|
24
|
-
let
|
|
25
|
-
export
|
|
26
|
-
export let
|
|
27
|
-
let
|
|
28
|
-
let
|
|
29
|
-
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
let
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
1
|
+
<script lang="ts" generics="RelationItem extends {id: string}">
|
|
2
|
+
import type { HTMLInputAttributes } from 'svelte/elements'
|
|
3
|
+
|
|
4
|
+
import { createEventDispatcher, tick, type Snippet } from 'svelte'
|
|
5
|
+
import { slide } from 'svelte/transition'
|
|
6
|
+
import { toast } from 'svelte-sonner'
|
|
7
|
+
import { mdiClose } from '@mdi/js'
|
|
8
|
+
import debounce from 'debounce'
|
|
9
|
+
|
|
10
|
+
import { USE_COERCE_JSON } from '../../utils/constant.js'
|
|
11
|
+
import { Icon } from '../icon/index.js'
|
|
12
|
+
import { FormControl, SelectorList } from './index.js'
|
|
13
|
+
import { DropDown } from '../menu/index.js'
|
|
14
|
+
import RelationAfter from './RelationAfter.svelte'
|
|
15
|
+
|
|
16
|
+
export let key = ''
|
|
17
|
+
export let label = ''
|
|
18
|
+
export let search: (q: string) => Promise<RelationItem[]>
|
|
19
|
+
export let createUrl = ''
|
|
20
|
+
export let createTitle = ''
|
|
21
|
+
export let createIcon: string | undefined = undefined
|
|
22
|
+
export let error = ''
|
|
23
|
+
export let placeholder = ''
|
|
24
|
+
export let flatMode = false
|
|
25
|
+
export let slotItem: Snippet<[RelationItem]>
|
|
26
|
+
export let slotSuggestion: Snippet<[RelationItem]> = slotItem
|
|
27
|
+
export let input: HTMLInputAttributes | undefined = undefined
|
|
28
|
+
export let append: Snippet | undefined = undefined
|
|
29
|
+
|
|
30
|
+
let klass = ''
|
|
31
|
+
export { klass as class }
|
|
32
|
+
export let classList = ''
|
|
33
|
+
|
|
34
|
+
let proposedItems: RelationItem[] = []
|
|
35
|
+
let items: RelationItem[] | null = null
|
|
36
|
+
export { items as value }
|
|
37
|
+
|
|
38
|
+
let isLoading = false
|
|
39
|
+
let isError = false
|
|
40
|
+
let focusIndex = 0
|
|
41
|
+
let searchValue = ''
|
|
42
|
+
|
|
43
|
+
let dropdown: DropDown
|
|
44
|
+
const dispatch = createEventDispatcher<{ input: { value: string[]; items: RelationItem[] } }>()
|
|
45
|
+
let inputSearch: HTMLInputElement
|
|
46
|
+
|
|
47
|
+
async function select(index = focusIndex) {
|
|
48
|
+
const proposedItem = proposedItems[index]
|
|
49
|
+
if (!proposedItem) return
|
|
50
|
+
if (!items) items = [proposedItem]
|
|
51
|
+
else items = [...items, proposedItem]
|
|
52
|
+
dropdown.hide()
|
|
53
|
+
inputSearch.select()
|
|
54
|
+
proposedItems = [...proposedItems.slice(0, index), ...proposedItems.slice(index + 1)]
|
|
55
|
+
dispatch('input', { value: items.map(({ id }) => id), items })
|
|
56
|
+
await tick()
|
|
57
|
+
setTimeout(() => dropdown.show(), 200)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function remove(index: number) {
|
|
61
|
+
if (!items?.length) return
|
|
62
|
+
items = [...items.slice(0, index), ...items.slice(index + 1)]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function searchItems(searchValue = '') {
|
|
66
|
+
try {
|
|
67
|
+
isLoading = true
|
|
68
|
+
isError = false
|
|
69
|
+
focusIndex = 0
|
|
70
|
+
const res = await search(searchValue)
|
|
71
|
+
const currentIds = items?.map(({ id }) => id) || []
|
|
72
|
+
proposedItems = res.filter(({ id }) => !currentIds.includes(id))
|
|
73
|
+
} catch (error) {
|
|
74
|
+
toast.error('Erreur')
|
|
75
|
+
isError = true
|
|
76
|
+
console.error(error)
|
|
77
|
+
} finally {
|
|
78
|
+
isLoading = false
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const searchItemsDebounce = debounce(searchItems, 150)
|
|
83
|
+
|
|
84
|
+
function handleFocus() {
|
|
85
|
+
searchItems()
|
|
86
|
+
// dropdown.show()
|
|
87
|
+
}
|
|
88
|
+
async function handleBlur() {
|
|
89
|
+
// dropdown.hide()
|
|
90
|
+
searchValue = ''
|
|
91
|
+
}
|
|
80
92
|
</script>
|
|
81
93
|
|
|
82
94
|
<DropDown bind:this={dropdown} disable={flatMode}>
|
|
@@ -90,11 +102,7 @@ async function handleBlur() {
|
|
|
90
102
|
transition:slide|local={{ axis: 'x', duration: 200 }}
|
|
91
103
|
class="badge badge-outline badge-lg items-center whitespace-nowrap pr-0 text-right"
|
|
92
104
|
>
|
|
93
|
-
|
|
94
|
-
<Slot slot={slotItem} args={item}>
|
|
95
|
-
{item.id}
|
|
96
|
-
</Slot>
|
|
97
|
-
</slot>
|
|
105
|
+
{@render slotItem(item)}
|
|
98
106
|
<div
|
|
99
107
|
class="btn btn-circle btn-ghost btn-xs ml-1 mr-[2px] h-[18px] min-h-[18px] w-[18px]"
|
|
100
108
|
role="button"
|
|
@@ -127,7 +135,7 @@ async function handleBlur() {
|
|
|
127
135
|
|
|
128
136
|
<RelationAfter {isLoading} {createUrl} {createTitle} {createIcon} />
|
|
129
137
|
</div>
|
|
130
|
-
|
|
138
|
+
{@render append?.()}
|
|
131
139
|
</div>
|
|
132
140
|
</div>
|
|
133
141
|
|
|
@@ -149,10 +157,6 @@ async function handleBlur() {
|
|
|
149
157
|
class="w-full min-w-40 {classList}"
|
|
150
158
|
on:select={({ detail }) => select(detail)}
|
|
151
159
|
>
|
|
152
|
-
|
|
153
|
-
<Slot slot={slotSuggestion} args={proposedItems[index]}>
|
|
154
|
-
{proposedItems[index].id}
|
|
155
|
-
</Slot>
|
|
156
|
-
</slot>
|
|
160
|
+
{@render slotSuggestion(proposedItems[index])}
|
|
157
161
|
</SelectorList>
|
|
158
162
|
</DropDown>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import type
|
|
3
|
+
import { type Snippet } from 'svelte';
|
|
4
4
|
declare class __sveltets_Render<RelationItem extends {
|
|
5
5
|
id: string;
|
|
6
6
|
}> {
|
|
@@ -14,9 +14,10 @@ declare class __sveltets_Render<RelationItem extends {
|
|
|
14
14
|
error?: string | undefined;
|
|
15
15
|
placeholder?: string | undefined;
|
|
16
16
|
flatMode?: boolean | undefined;
|
|
17
|
-
slotItem
|
|
18
|
-
slotSuggestion?:
|
|
17
|
+
slotItem: Snippet<[RelationItem]>;
|
|
18
|
+
slotSuggestion?: Snippet<[RelationItem]> | undefined;
|
|
19
19
|
input?: HTMLInputAttributes | undefined;
|
|
20
|
+
append?: Snippet<[]> | undefined;
|
|
20
21
|
class?: string | undefined;
|
|
21
22
|
classList?: string | undefined;
|
|
22
23
|
value?: RelationItem[] | null | undefined;
|
|
@@ -29,15 +30,7 @@ declare class __sveltets_Render<RelationItem extends {
|
|
|
29
30
|
} & {
|
|
30
31
|
[evt: string]: CustomEvent<any>;
|
|
31
32
|
};
|
|
32
|
-
slots(): {
|
|
33
|
-
item: {
|
|
34
|
-
item: RelationItem;
|
|
35
|
-
};
|
|
36
|
-
append: {};
|
|
37
|
-
suggestion: {
|
|
38
|
-
item: RelationItem;
|
|
39
|
-
};
|
|
40
|
-
};
|
|
33
|
+
slots(): {};
|
|
41
34
|
}
|
|
42
35
|
export type InputRelationsProps<RelationItem extends {
|
|
43
36
|
id: string;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
let
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { mdiClose } from '@mdi/js'
|
|
3
|
+
import { browser } from '$app/environment'
|
|
4
|
+
import { page } from '$app/stores'
|
|
5
|
+
import { Icon } from '../icon/index.js'
|
|
6
|
+
import { InputText } from './index.js'
|
|
7
|
+
|
|
8
|
+
let klass = ''
|
|
9
|
+
export { klass as class }
|
|
10
|
+
export let key = 'search'
|
|
11
|
+
export let value = $page.url.searchParams.get(key) || ''
|
|
12
|
+
|
|
13
|
+
let inputElement: HTMLInputElement
|
|
11
14
|
</script>
|
|
12
15
|
|
|
13
16
|
<InputText
|