fuma 2.1.6 → 2.5.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.
Files changed (89) hide show
  1. package/dist/_doc/data.d.ts +3 -1
  2. package/dist/_doc/data.js +6 -2
  3. package/dist/command/index.d.ts +1 -1
  4. package/dist/command/index.js +1 -1
  5. package/dist/command/{command.svelte.js → useCommand.svelte.js} +1 -1
  6. package/dist/input/InputBoolean.svelte +41 -8
  7. package/dist/input/InputBoolean.svelte.d.ts +7 -0
  8. package/dist/input/InputCheckboxes.svelte +123 -0
  9. package/dist/input/InputCheckboxes.svelte.d.ts +19 -0
  10. package/dist/input/InputDateTime.svelte +199 -0
  11. package/dist/input/InputDateTime.svelte.d.ts +26 -0
  12. package/dist/input/InputMultiSelect.svelte +324 -0
  13. package/dist/input/{InputRelation.svelte.d.ts → InputMultiSelect.svelte.d.ts} +32 -13
  14. package/dist/input/InputNumber.svelte +43 -6
  15. package/dist/input/InputNumber.svelte.d.ts +8 -0
  16. package/dist/input/InputRadio.svelte +62 -24
  17. package/dist/input/InputRadio.svelte.d.ts +3 -0
  18. package/dist/input/InputRange.svelte +24 -4
  19. package/dist/input/InputRange.svelte.d.ts +9 -0
  20. package/dist/input/InputSelect.svelte +216 -62
  21. package/dist/input/InputSelect.svelte.d.ts +91 -6
  22. package/dist/input/InputSelectNative.svelte +51 -19
  23. package/dist/input/InputSelectNative.svelte.d.ts +8 -0
  24. package/dist/input/InputString.svelte +21 -6
  25. package/dist/input/InputString.svelte.d.ts +7 -0
  26. package/dist/input/InputTextarea.svelte +58 -11
  27. package/dist/input/InputTextarea.svelte.d.ts +14 -0
  28. package/dist/input/index.d.ts +4 -1
  29. package/dist/input/index.js +4 -1
  30. package/dist/input/useItems.svelte.d.ts +38 -0
  31. package/dist/input/useItems.svelte.js +142 -0
  32. package/dist/loading/Loading.svelte +3 -2
  33. package/dist/loading/Loading.svelte.d.ts +3 -2
  34. package/dist/popover/Popover.svelte +1 -2
  35. package/dist/popover/Popover.svelte.d.ts +13 -0
  36. package/dist/popover/index.d.ts +1 -1
  37. package/dist/popover/index.js +1 -1
  38. package/dist/popover/{popover.svelte.d.ts → usePopover.svelte.d.ts} +2 -1
  39. package/dist/popover/usePopover.svelte.js +145 -0
  40. package/dist/remote/useForm.d.ts +4 -5
  41. package/dist/remote/useForm.js +9 -4
  42. package/dist/state/index.d.ts +1 -1
  43. package/dist/state/index.js +1 -1
  44. package/dist/ui/button/ButtonDelete.svelte +6 -3
  45. package/dist/ui/button/ButtonDelete.svelte.d.ts +1 -1
  46. package/dist/ui/dialog/Dialog.svelte +5 -5
  47. package/dist/ui/drawer/Drawer.svelte +74 -26
  48. package/dist/ui/drawer/Drawer.svelte.d.ts +10 -4
  49. package/dist/ui/drawer/index.d.ts +1 -0
  50. package/dist/ui/drawer/index.js +1 -0
  51. package/dist/ui/drawer/inertBackground.d.ts +13 -0
  52. package/dist/ui/drawer/inertBackground.js +59 -0
  53. package/dist/ui/drawer/useLayer.svelte.d.ts +1 -1
  54. package/dist/ui/drawer/useLayer.svelte.js +11 -7
  55. package/dist/ui/index.d.ts +1 -0
  56. package/dist/ui/index.js +1 -0
  57. package/dist/ui/menu/ContextMenu.svelte +30 -17
  58. package/dist/ui/menu/ContextMenu.svelte.d.ts +2 -3
  59. package/dist/ui/menu/DropDown.svelte +1 -1
  60. package/dist/ui/menu/DropDown.svelte.d.ts +1 -1
  61. package/dist/ui/menu/DropDownMenu.svelte +12 -10
  62. package/dist/ui/menu/DropDownMenu.svelte.d.ts +2 -3
  63. package/dist/ui/menu/index.d.ts +0 -1
  64. package/dist/ui/menu/index.js +0 -2
  65. package/dist/ui/range/RangePicker.svelte +25 -13
  66. package/dist/ui/range/RangePicker.svelte.d.ts +9 -25
  67. package/dist/ui/range/RangePickerButton.svelte +49 -32
  68. package/dist/ui/range/RangePickerButton.svelte.d.ts +1 -1
  69. package/dist/ui/table/Table.svelte +16 -16
  70. package/dist/ui/table/Table.svelte.d.ts +1 -1
  71. package/dist/ui/table/TableFieldsEdition.svelte +25 -23
  72. package/dist/ui/table/TableHead.svelte +5 -1
  73. package/dist/ui/table/cell/TableCellBoolean.svelte +2 -2
  74. package/dist/ui/table/head/OrderButtons.svelte +21 -20
  75. package/dist/ui/table/head/OrderButtons.svelte.d.ts +2 -0
  76. package/dist/ui/table/head/TableHeadDate.svelte +66 -57
  77. package/dist/ui/table/head/TableHeadNumber.svelte +58 -22
  78. package/dist/ui/table/head/TableHeadSelect.svelte +31 -28
  79. package/dist/ui/table/head/TableHeadString.svelte +12 -8
  80. package/dist/ui/table/index.d.ts +1 -1
  81. package/dist/ui/table/index.js +1 -1
  82. package/package.json +7 -4
  83. package/dist/input/InputRelation.svelte +0 -200
  84. package/dist/popover/popover.svelte.js +0 -106
  85. package/dist/ui/table/TableViewSelect.svelte +0 -142
  86. package/dist/ui/table/TableViewSelect.svelte.d.ts +0 -11
  87. /package/dist/command/{command.svelte.d.ts → useCommand.svelte.d.ts} +0 -0
  88. /package/dist/state/{param.svelte.d.ts → param.d.ts} +0 -0
  89. /package/dist/state/{param.svelte.js → param.js} +0 -0
@@ -2,36 +2,49 @@
2
2
  import { CalendarRangeIcon } from '@lucide/svelte'
3
3
  import { slide } from 'svelte/transition'
4
4
  import { goto } from '$app/navigation'
5
- import { param, urlParam } from '../../state/param.svelte.js'
6
- import { DropDown } from '../menu/index.js'
5
+ import { InputDateTime } from '../../input/index.js'
6
+ import { usePopover } from '../../popover/index.js'
7
+ import { param, urlParam } from '../../state/param.js'
7
8
  import { formatRangeShort } from './format.js'
8
9
  import { type RangeAsDate, RangePicker } from './index.js'
9
10
  import { jsonParse } from '../../utils/jsonParse.js'
10
11
 
11
- let dropDown: DropDown
12
12
  let rangePicker: RangePicker
13
13
 
14
14
  let {
15
15
  key = 'range',
16
- range = $bindable(
17
- jsonParse<RangeAsDate>(param.get(key), {
18
- start: null,
19
- end: null
20
- })
21
- ),
16
+ range = $bindable(parseRange(param.get(key))),
22
17
  minDate,
23
18
  maxDate,
24
19
  class: klass = '',
25
20
  classLabel = ''
26
21
  }: {
27
22
  key?: string
28
- range: RangeAsDate
23
+ range?: RangeAsDate
29
24
  minDate?: Date | number | string
30
25
  maxDate?: Date | number | string
31
26
  class?: string
32
27
  classLabel?: string
33
28
  } = $props()
34
29
 
30
+ const popover = usePopover()
31
+
32
+ // Le paramètre d'URL porte des chaînes ISO: sans cette reprise, `range` contiendrait des
33
+ // chaînes là où tout le reste — `updateURL`, `InputDateTime` — attend des `Date`.
34
+ function parseRange(value?: string | null): RangeAsDate {
35
+ const { start, end } = jsonParse<{ start?: string; end?: string }>(value, {})
36
+ return { start: start ? new Date(start) : null, end: end ? new Date(end) : null }
37
+ }
38
+
39
+ // Le light-dismiss (clic à l'extérieur) ne passe pas par `hide()`, donc pas par
40
+ // `onHide`: on suit `isOpen` pour que l'URL soit à jour à chaque fermeture.
41
+ let wasOpen = false
42
+ $effect(() => {
43
+ const { isOpen } = popover
44
+ if (wasOpen && !isOpen) updateURL()
45
+ wasOpen = isOpen
46
+ })
47
+
35
48
  let isValidPeriod = $derived(!!range.start && !!range.end)
36
49
 
37
50
  function getLabel(_range?: Partial<RangeAsDate>) {
@@ -53,29 +66,27 @@
53
66
  }
54
67
  </script>
55
68
 
56
- <DropDown bind:this={dropDown} tippyProps={{ onHidden: updateURL }} class="max-h-full">
57
- {#snippet activator()}
58
- <button class="min-width-0 btn flex-nowrap btn-sm {klass}">
59
- <CalendarRangeIcon class="opacity-60" size={20} />
60
- {#if isValidPeriod}
61
- <span
62
- transition:slide={{ axis: 'x', duration: 200 }}
63
- class="text-xs font-medium whitespace-nowrap opacity-80 {classLabel}"
64
- >
65
- {getLabel(range)}
66
- </span>
67
- {/if}
68
- </button>
69
- {/snippet}
69
+ <button
70
+ class={['min-width-0 btn flex-nowrap btn-sm', !isValidPeriod && 'btn-square', klass]}
71
+ {...popover.trigger}
72
+ >
73
+ <CalendarRangeIcon class="opacity-70" size={20} />
74
+ {#if isValidPeriod}
75
+ <span
76
+ transition:slide={{ axis: 'x', duration: 200 }}
77
+ class="text-xs font-medium whitespace-nowrap opacity-80 {classLabel}"
78
+ >
79
+ {getLabel(range)}
80
+ </span>
81
+ {/if}
82
+ </button>
70
83
 
84
+ <div {...popover.content} class="rounded-box border bg-base-100 p-1 shadow-xl">
71
85
  <RangePicker bind:this={rangePicker} numberOfMonths={1} bind:range {minDate} {maxDate} />
72
86
 
73
87
  <div class="flex gap-2 p-2">
74
- <!--
75
- <InputString label="A partir de" bind:value={range.start} class="grow" />
76
- <InputString label="Jusqu'à" bind:value={range.end} class="grow" />
77
- -->
78
- <span>TODO: same problème with input...</span>
88
+ <InputDateTime label="À partir de" bind:value={range.start} class="grow" />
89
+ <InputDateTime label="Jusqu'à" bind:value={range.end} class="grow" />
79
90
  </div>
80
91
 
81
92
  <div class="m-2 flex justify-end gap-2">
@@ -86,12 +97,18 @@
86
97
  onclick={() => {
87
98
  range = { start: null, end: null }
88
99
  rangePicker.clear()
89
- dropDown.hide()
100
+ popover.hide()
90
101
  }}
91
102
  >
92
103
  Effacer
93
104
  </button>
94
105
  {/if}
95
- <button class="btn" onclick={() => dropDown.hide()}> Valider </button>
106
+ <button class="btn" onclick={() => popover.hide()}> Valider </button>
96
107
  </div>
97
- </DropDown>
108
+ </div>
109
+
110
+ <style>
111
+ div[popover] {
112
+ border-color: color-mix(in oklab, var(--color-base-content) 20%, #0000);
113
+ }
114
+ </style>
@@ -1,7 +1,7 @@
1
1
  import { type RangeAsDate } from './index.js';
2
2
  type $$ComponentProps = {
3
3
  key?: string;
4
- range: RangeAsDate;
4
+ range?: RangeAsDate;
5
5
  minDate?: Date | number | string;
6
6
  maxDate?: Date | number | string;
7
7
  class?: string;
@@ -1,6 +1,5 @@
1
1
  <script lang="ts" generics="Item extends ItemBase">
2
- import type { Snippet } from 'svelte'
3
- import { afterNavigate } from '$app/navigation'
2
+ import { type Snippet, untrack } from 'svelte'
4
3
  import {
5
4
  context,
6
5
  createKeys,
@@ -35,25 +34,26 @@
35
34
  onclick?: (item?: Item) => void
36
35
  } = $props()
37
36
 
38
- $effect(() => {
39
- const { KEY_FIELDS_VISIBLE, KEY_FIELDS_HIDDEN, KEY_FIELDS_ORDER } = createKeys(key)
40
- context.set(key, {
41
- KEY_FIELDS_VISIBLE,
42
- KEY_FIELDS_HIDDEN,
43
- KEY_FIELDS_ORDER
44
- })
45
- })
37
+ // Posé à l'initialisation et non dans un `$effect`: un effet ne tourne pas au rendu
38
+ // serveur, et `TableFieldsEdition` lirait un contexte vide. `key` identifie la table
39
+ // pour toute sa durée de vie.
40
+ const tableKey = untrack(() => key)
41
+ context.set(tableKey, createKeys(tableKey))
46
42
 
47
- const initFields = () => (fields = syncFieldsWithParams(key, fields))
48
- initFields()
49
- afterNavigate(initFields)
43
+ // Dérivé, et non écrit dans la prop `fields`: Svelte annule l'écriture locale d'une prop
44
+ // non liée dès que le parent en recalcule la valeur. Un parent qui déclare ses colonnes
45
+ // dans un `$derived` les reproduit à chaque rafraîchissement de `load` — celui que
46
+ // déclenche une remote function, sans navigation — et la table repartait alors sans
47
+ // `_visible`, donc sans une seule colonne. `syncFieldsWithParams` lit `page.url`: le
48
+ // dérivé suit aussi les changements de paramètres, ce dont `afterNavigate` se chargeait.
49
+ const fieldsSynced = $derived(syncFieldsWithParams(tableKey, fields))
50
50
  </script>
51
51
 
52
- <div class="{klass} overflow-x-auto rounded-lg border bg-base-100" class:min-h-[320px]={!hideBody}>
52
+ <div class="{klass} overflow-x-auto rounded-box border bg-base-100" class:min-h-[320px]={!hideBody}>
53
53
  <table class="table relative">
54
- <TableHead {fields} {key} {onCreateField} />
54
+ <TableHead fields={fieldsSynced} {key} {onCreateField} />
55
55
  {#if !hideBody && items.length}
56
- <TableBody {fields} {items} {actions} {classRow} {onclick} />
56
+ <TableBody fields={fieldsSynced} {items} {actions} {classRow} {onclick} />
57
57
  {/if}
58
58
  </table>
59
59
 
@@ -1,4 +1,4 @@
1
- import type { Snippet } from 'svelte';
1
+ import { type Snippet } from 'svelte';
2
2
  import { type ItemBase, type TableField } from './index.js';
3
3
  declare function $$render<Item extends ItemBase>(): {
4
4
  props: {
@@ -1,18 +1,20 @@
1
1
  <script lang="ts" generics="Item extends ItemBase">
2
2
  import {
3
3
  CheckIcon,
4
- CircleCheckIcon,
5
- CircleIcon,
4
+ DotIcon,
6
5
  EllipsisIcon,
6
+ FunnelIcon,
7
7
  GripIcon,
8
+ LockKeyholeIcon,
9
+ MoveVerticalIcon,
8
10
  PlusIcon
9
11
  } from '@lucide/svelte'
10
12
  import { goto } from '$app/navigation'
11
13
  import { page } from '$app/state'
12
14
  import { listEditable } from '../../action/list/index.js'
13
15
  import { tip } from '../../action/tip.js'
14
- import { param, urlParam } from '../../state/param.svelte.js'
15
- import { DropDown } from '../menu/index.js'
16
+ import { Popover } from '../../popover/index.js'
17
+ import { param, urlParam } from '../../state/param.js'
16
18
  import { context } from './context.js'
17
19
  import type { ItemBase, TableField } from './index.js'
18
20
  import { jsonParse } from '../../utils/jsonParse.js'
@@ -64,31 +66,28 @@
64
66
  </script>
65
67
 
66
68
  <th class="sticky right-0 z-10 p-0 px-1" align="right">
67
- <DropDown
68
- hideOnNav={false}
69
- class="max-h-none px-0"
70
- tippyProps={{ appendTo: () => document.body, placement: 'bottom-end' }}
71
- >
72
- {#snippet activator()}
69
+ <Popover placement="bottom-end" class="px-0 py-1">
70
+ {#snippet trigger(popover)}
73
71
  <button
74
72
  type="button"
75
73
  class="btn btn-square btn-ghost backdrop-blur btn-sm"
76
- use:tip={{ content: 'Dénfinir les champs' }}
74
+ use:tip={{ content: 'Modifier les colonnes' }}
75
+ {...popover.trigger}
77
76
  >
78
77
  <EllipsisIcon />
79
78
  </button>
80
79
  {/snippet}
81
80
 
82
- {#snippet children({ tip })}
81
+ {#snippet children(popover)}
83
82
  {#if onCreateField}
84
- <div class="bordered flex items-center gap-2 border-b pr-1 pb-1 pl-2">
83
+ <div class="flex items-center gap-2 border-b pr-1 pb-1 pl-2">
85
84
  <span class=" font-semibold opacity-70">Champs</span>
86
85
  <button
87
86
  type="button"
88
87
  class="btn ml-auto btn-square btn-sm"
89
88
  onclick={() => {
90
89
  if (onCreateField) onCreateField()
91
- tip?.hide()
90
+ popover.hide()
92
91
  }}
93
92
  >
94
93
  <PlusIcon title="Ajouter un champ" />
@@ -108,35 +107,38 @@
108
107
  <a
109
108
  draggable="false"
110
109
  href={getFieldHref(field)}
111
- class="menu-item w-full"
110
+ class="menu-item group w-full pr-1"
112
111
  class:disabled={field.locked}
113
112
  data-sveltekit-keepfocus
114
113
  data-sveltekit-replacestate
115
114
  data-sveltekit-noscroll
116
115
  >
117
116
  {#if field.locked}
118
- <CheckIcon class="fill-base-content/50" size={21} />
117
+ <LockKeyholeIcon class="mx-0.5 text-primary" size={17} />
119
118
  {:else if param.has(field.key)}
120
- <CircleCheckIcon class="fill-primary" size={21} />
119
+ <FunnelIcon class="mx-0.5 text-primary" size={17} />
121
120
  {:else if field._visible}
122
- <CheckIcon class="fill-success" size={21} />
121
+ <CheckIcon class="text-success" size={21} />
123
122
  {:else}
124
- <CircleIcon class="fill-base-content/50" size={21} />
123
+ <DotIcon class="text-base-content/50" size={21} />
125
124
  {/if}
126
125
 
127
- <span>{field.label}</span>
126
+ <span class=" font-normal">{field.label}</span>
128
127
 
129
128
  <span
130
- class="drag-button btn ml-auto btn-square btn-ghost btn-xs"
129
+ class={[
130
+ 'drag-button btn ml-auto btn-square btn-soft btn-xs',
131
+ 'opacity-0 group-hover:opacity-100'
132
+ ]}
131
133
  onclick={(e) => e.preventDefault()}
132
134
  role="none"
133
135
  >
134
- <GripIcon size={18} class="fill-base-content/80" />
136
+ <MoveVerticalIcon size={18} class="text-base-content/70" />
135
137
  </span>
136
138
  </a>
137
139
  {/each}
138
140
  </div>
139
141
  </div>
140
142
  {/snippet}
141
- </DropDown>
143
+ </Popover>
142
144
  </th>
@@ -34,7 +34,11 @@
34
34
  {:else if field.type === 'date'}
35
35
  <TableHeadDate {field} />
36
36
  {:else if field.options}
37
- <TableHeadSelect {field} options={field.options} />
37
+ <TableHeadSelect
38
+ {field}
39
+ options={field.options}
40
+ multiSelect={field.type === 'multiselect'}
41
+ />
38
42
  {/if}
39
43
  {/each}
40
44
  <TableFieldsEdition {fields} {key} {onCreateField} />
@@ -6,8 +6,8 @@
6
6
 
7
7
  <td>
8
8
  {#if cell}
9
- <CheckIcon class="fill-success" />
9
+ <CheckIcon class="text-success" />
10
10
  {:else}
11
- <XIcon class="fill-error" />
11
+ <XIcon class="text-error" />
12
12
  {/if}
13
13
  </td>
@@ -7,11 +7,15 @@
7
7
  order = $bindable(),
8
8
  IconAsc = ArrowDownNarrowWideIcon,
9
9
  IconDesc = ArrowDownWideNarrowIcon,
10
+ labelAsc = 'Ascendant',
11
+ labelDesc = 'Descendant',
10
12
  onChange
11
13
  }: {
12
14
  order: Order
13
15
  IconAsc?: Component<IconProps>
14
16
  IconDesc?: Component<IconProps>
17
+ labelAsc?: string
18
+ labelDesc?: string
15
19
  onChange?: (order: Order) => void
16
20
  } = $props()
17
21
 
@@ -22,24 +26,21 @@
22
26
  }
23
27
  </script>
24
28
 
25
- <div class="p-1 pt-2">
26
- <span class="text-sm font-semibold opacity-70">Ordre:</span>
27
- <div class="grid grid-cols-2 gap-2 pt-2">
28
- <button
29
- class="btn ring-primary"
30
- class:ring-2={order === 'asc'}
31
- onclick={handleOrderClick('asc')}
32
- >
33
- <IconAsc />
34
- <span>Ascendant</span>
35
- </button>
36
- <button
37
- class="btn ring-primary"
38
- class:ring-2={order === 'desc'}
39
- onclick={handleOrderClick('desc')}
40
- >
41
- <IconDesc />
42
- <span>Descendant</span>
43
- </button>
44
- </div>
29
+ <div class="m-2 grid grid-cols-2 gap-1">
30
+ <button
31
+ class="btn ring-primary btn-sm"
32
+ class:ring-2={order === 'asc'}
33
+ onclick={handleOrderClick('asc')}
34
+ >
35
+ <IconAsc size={16} />
36
+ <span>{labelAsc}</span>
37
+ </button>
38
+ <button
39
+ class="btn ring-primary btn-sm"
40
+ class:ring-2={order === 'desc'}
41
+ onclick={handleOrderClick('desc')}
42
+ >
43
+ <IconDesc size={16} />
44
+ <span>{labelDesc}</span>
45
+ </button>
45
46
  </div>
@@ -5,6 +5,8 @@ type $$ComponentProps = {
5
5
  order: Order;
6
6
  IconAsc?: Component<IconProps>;
7
7
  IconDesc?: Component<IconProps>;
8
+ labelAsc?: string;
9
+ labelDesc?: string;
8
10
  onChange?: (order: Order) => void;
9
11
  };
10
12
  declare const OrderButtons: Component<$$ComponentProps, {}, "order">;
@@ -2,8 +2,9 @@
2
2
  import { CalendarArrowDownIcon, CalendarArrowUpIcon, CalendarSearchIcon } from '@lucide/svelte'
3
3
  import { goto } from '$app/navigation'
4
4
  import { page } from '$app/state'
5
- import { urlParam } from '../../../state/param.svelte.js'
6
- import { DropDown } from '../../menu/index.js'
5
+ import { InputDateTime } from '../../../input/index.js'
6
+ import { Popover, type PopoverType } from '../../../popover/index.js'
7
+ import { urlParam } from '../../../state/param.js'
7
8
  import { formatRange } from '../../range/format.js'
8
9
  import { type RangeAsDate, RangePicker } from '../../range/index.js'
9
10
  import type { ItemBase, TableField } from '../index.js'
@@ -12,7 +13,6 @@
12
13
 
13
14
  let { field }: { field: Omit<TableField<Item>, 'cell'> } = $props()
14
15
 
15
- let dropDown: DropDown
16
16
  let rangePicker: RangePicker
17
17
 
18
18
  let initialValue = jsonParse<{
@@ -59,11 +59,11 @@
59
59
  )
60
60
  }
61
61
 
62
- function handleReset() {
62
+ function handleReset(popover: PopoverType) {
63
63
  isValidPeriod = false
64
64
  range.start = null
65
65
  range = { start: null, end: null }
66
- dropDown.hide()
66
+ popover.hide()
67
67
  rangePicker.clear()
68
68
  goto(urlParam.without(field.key, 'skip', 'take'), {
69
69
  replaceState: true,
@@ -74,15 +74,10 @@
74
74
  </script>
75
75
 
76
76
  <th class="p-1">
77
- <DropDown
78
- bind:this={dropDown}
79
- tippyProps={{ appendTo: () => document.body }}
80
- hideOnNav={false}
81
- class="max-h-none"
82
- >
83
- {#snippet activator()}
84
- <button class="menu-item min-h-8 w-full flex-wrap gap-y-1">
85
- <div class="flex gap-2">
77
+ <Popover class="p-1">
78
+ {#snippet trigger(popover)}
79
+ <button class="menu-item min-h-8 w-full flex-wrap gap-y-1" {...popover.trigger}>
80
+ <div class="flex items-center gap-2">
86
81
  <span>{field.label}</span>
87
82
  {#if !isValidPeriod}
88
83
  <CalendarSearchIcon size={15} class="opacity-50" />
@@ -95,56 +90,70 @@
95
90
  </span>
96
91
  {/if}
97
92
  {#if order === 'asc'}
98
- <CalendarArrowDownIcon size={18} class="fill-primary" />
93
+ <CalendarArrowDownIcon size={15} class="text-primary" />
99
94
  {:else if order === 'desc'}
100
- <CalendarArrowUpIcon size={18} class="fill-primary" />
95
+ <CalendarArrowUpIcon size={15} class="text-primary" />
101
96
  {/if}
102
97
  </button>
103
98
  {/snippet}
104
99
 
105
- {#if field.sortable !== false}
106
- <OrderButtons
107
- bind:order
108
- onChange={() => {
109
- updateUrl()
110
- dropDown.hide()
111
- }}
112
- IconAsc={CalendarArrowDownIcon}
113
- IconDesc={CalendarArrowUpIcon}
114
- />
115
- {/if}
100
+ {#snippet children(popover)}
101
+ {#if field.sortable !== false}
102
+ <OrderButtons
103
+ bind:order
104
+ onChange={() => {
105
+ updateUrl()
106
+ popover.hide()
107
+ }}
108
+ IconAsc={CalendarArrowDownIcon}
109
+ IconDesc={CalendarArrowUpIcon}
110
+ labelAsc="Ancien d'abord"
111
+ labelDesc="Récent d'abord"
112
+ />
113
+ {/if}
116
114
 
117
- <form
118
- onsubmit={(e) => {
119
- e.preventDefault()
120
- dropDown.hide()
121
- }}
122
- data-sveltekit-replacestate
123
- class="flex flex-col font-normal"
124
- class:mt-6={field.sortable !== false}
125
- >
126
- <RangePicker
127
- bind:this={rangePicker}
128
- numberOfMonths={1}
129
- on:change={({ detail: newRange }) => {
130
- range = newRange
131
- updateUrl()
115
+ <form
116
+ onsubmit={(e) => {
117
+ e.preventDefault()
118
+ popover.hide()
132
119
  }}
133
- />
134
-
135
- <input class="hidden" type="text" name="start" value={range.start?.toJSON()} />
136
- <input class="hidden" type="text" name="end" value={range.end?.toJSON()} />
120
+ data-sveltekit-replacestate
121
+ class="flex flex-col font-normal"
122
+ class:mt-6={field.sortable !== false}
123
+ >
124
+ <RangePicker
125
+ bind:this={rangePicker}
126
+ numberOfMonths={1}
127
+ onchange={(newRange) => {
128
+ range = newRange
129
+ updateUrl()
130
+ }}
131
+ />
137
132
 
138
- <div class="m-2 flex gap-2">
139
- <!-- <InputTime label="A partir de" bind:value={range.start} class="grow" on:input={updateUrl} />
140
- <InputTime label="Jusqu'à" bind:value={range.end} class="grow" on:input={updateUrl} /> -->
141
- <span>TODO: same problème with input...</span>
142
- </div>
133
+ <div class="m-2 flex gap-2">
134
+ <InputDateTime
135
+ label="À partir de"
136
+ name="start"
137
+ bind:value={range.start}
138
+ class="grow"
139
+ onchange={updateUrl}
140
+ />
141
+ <InputDateTime
142
+ label="Jusqu'à"
143
+ name="end"
144
+ bind:value={range.end}
145
+ class="grow"
146
+ onchange={updateUrl}
147
+ />
148
+ </div>
143
149
 
144
- <div class="m-2 flex flex-row-reverse gap-2">
145
- <button class="btn">Ok</button>
146
- <button class="btn btn-ghost" type="button" onclick={handleReset}>Effacer</button>
147
- </div>
148
- </form>
149
- </DropDown>
150
+ <div class="m-2 flex flex-row-reverse gap-2">
151
+ <button class="btn">Ok</button>
152
+ <button class="btn btn-ghost" type="button" onclick={() => handleReset(popover)}>
153
+ Effacer
154
+ </button>
155
+ </div>
156
+ </form>
157
+ {/snippet}
158
+ </Popover>
150
159
  </th>