hamzus-ui 0.0.134 → 0.0.135

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hamzus-ui",
3
- "version": "0.0.134",
3
+ "version": "0.0.135",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "svelte": "index.js",
@@ -114,6 +114,9 @@
114
114
  weeks.push(days.slice(i, i + 7));
115
115
  }
116
116
 
117
+ console.log(weeks);
118
+
119
+
117
120
  return weeks;
118
121
  }
119
122
 
@@ -240,7 +243,7 @@
240
243
  {#each week as dayData}
241
244
  <td>
242
245
  <div>
243
- <IconButton style={selectedDay != dayData.day && (currentYear == year && currentMonth == month && dayData.day == day) ? "background-color:var(--bg-3)" : ""} onClick={!dayData.currentMonth ? undefined : ()=>{handleUpdateValue(dayData.day)}} desabled={!dayData.currentMonth} variant={selectedDay == dayData.day && (selectedYear == currentYear && selectedMonth == currentMonth) ? "primary" : "ghost"}>{dayData.day}</IconButton>
246
+ <IconButton style={selectedDay != dayData.day && (currentYear == year && dayData.currentMonth && dayData.day == day) ? "background-color:var(--bg-3)" : ""} onClick={!dayData.currentMonth ? undefined : ()=>{handleUpdateValue(dayData.day)}} desabled={!dayData.currentMonth} variant={selectedDay == dayData.day && (selectedYear == currentYear && dayData.currentMonth) ? "primary" : "ghost"}>{dayData.day}</IconButton>
244
247
  </div>
245
248
  </td>
246
249
  {/each}
@@ -0,0 +1,467 @@
1
+ <script>
2
+ import * as DropdownMenu from '../DropdownMenu';
3
+ import Button from '../Button/Button.svelte';
4
+ import IconButton from '../IconButton/IconButton.svelte';
5
+ import { onMount } from 'svelte';
6
+ import Input from '../Input/Input.svelte';
7
+
8
+ export let value = '';
9
+ export let onChange = undefined;
10
+ export let label = '';
11
+ export let name = '';
12
+ export let variant = 'default'; // "default" | "collapse"
13
+ export let required = false;
14
+
15
+ const monthList = {
16
+ 1: 'janvier',
17
+ 2: 'février',
18
+ 3: 'mars',
19
+ 4: 'avril',
20
+ 5: 'mai',
21
+ 6: 'juin',
22
+ 7: 'juillet',
23
+ 8: 'août',
24
+ 9: 'septembre',
25
+ 10: 'octobre',
26
+ 11: 'novembre',
27
+ 12: 'décembre'
28
+ };
29
+ const yearList = getYearList();
30
+
31
+ const now = new Date();
32
+
33
+ const day = String(now.getDate());
34
+ const month = String(now.getMonth() + 1);
35
+ const year = now.getFullYear();
36
+
37
+ let toggleDisplay;
38
+
39
+ $: labelMonth = formatValue(value);
40
+
41
+ let currentYear = new Date().getFullYear();
42
+ let currentMonth = new Date().getMonth() + 1;
43
+
44
+ let selectedYear = new Date().getFullYear();
45
+ let selectedMonth = new Date().getMonth() + 1;
46
+ let selectedDay = null;
47
+
48
+ let weeks = generateCalendarMatrix(currentYear, currentMonth - 1);
49
+
50
+ let mode = 'day';
51
+
52
+ let inputMin
53
+ let hour = ""
54
+ let min = ""
55
+
56
+ function getYearList(startYear = 1997) {
57
+ const currentYear = new Date().getFullYear();
58
+
59
+ return Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear + 100 - i);
60
+ }
61
+
62
+ function formatValue(value) {
63
+ if (value === '') {
64
+ return 'selectionner une date';
65
+ }
66
+
67
+ const dateTimeData = value.split(" ");
68
+
69
+ const dateData = dateTimeData[0].split('-');
70
+
71
+ const day = parseInt(dateData[2]);
72
+ currentMonth = parseInt(dateData[1]);
73
+ currentYear = parseInt(dateData[0]);
74
+
75
+ const hourData = dateTimeData[1].split(':');
76
+
77
+ hour = hourData[0]
78
+ min = hourData[1]
79
+
80
+ weeks = generateCalendarMatrix(currentYear, currentMonth - 1);
81
+
82
+ return `${day} ${monthList[currentMonth]} ${currentYear} à ${hour}h${min}`;
83
+ }
84
+
85
+ function generateCalendarMatrix(year, month) {
86
+ const firstDay = new Date(year, month, 1);
87
+ const startWeekday = (firstDay.getDay() + 6) % 7; // 0 = lundi, ..., 6 = dimanche
88
+
89
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
90
+ const daysInPrevMonth = new Date(year, month, 0).getDate();
91
+
92
+ const days = [];
93
+
94
+ // Début : jours du mois précédent
95
+ for (let i = startWeekday - 1; i >= 0; i--) {
96
+ days.push({
97
+ day: daysInPrevMonth - i,
98
+ currentMonth: false
99
+ });
100
+ }
101
+
102
+ // Jours du mois courant
103
+ for (let i = 1; i <= daysInMonth; i++) {
104
+ days.push({
105
+ day: i,
106
+ currentMonth: true
107
+ });
108
+ }
109
+
110
+ // Fin : jours du mois suivant
111
+ const remaining = 7 - (days.length % 7);
112
+ if (remaining < 7) {
113
+ for (let i = 1; i <= remaining; i++) {
114
+ days.push({
115
+ day: i,
116
+ currentMonth: false
117
+ });
118
+ }
119
+ }
120
+
121
+ // Regrouper en semaines de 7 jours
122
+ const weeks = [];
123
+ for (let i = 0; i < days.length; i += 7) {
124
+ weeks.push(days.slice(i, i + 7));
125
+ }
126
+
127
+ console.log(weeks);
128
+
129
+ return weeks;
130
+ }
131
+
132
+ function gotoNextMonth() {
133
+ if (currentMonth === 12) {
134
+ currentYear++;
135
+ }
136
+ currentMonth = currentMonth === 12 ? 1 : currentMonth + 1;
137
+
138
+ weeks = generateCalendarMatrix(currentYear, currentMonth - 1);
139
+ }
140
+ function gotoPreviousMonth() {
141
+ if (currentMonth === 1) {
142
+ currentYear--;
143
+ }
144
+ currentMonth = currentMonth === 1 ? 12 : currentMonth - 1;
145
+
146
+ weeks = generateCalendarMatrix(currentYear, currentMonth - 1);
147
+ }
148
+
149
+ function handleUpdateValue(day) {
150
+ if (day !== null) {
151
+ selectedDay = day;
152
+ selectedYear = currentYear;
153
+ selectedMonth = currentMonth;
154
+ }
155
+
156
+ if (selectedDay === null) {
157
+ return
158
+ }
159
+
160
+ if (hour === "" || min === "" || hour.length < 2 || min.length < 2) {
161
+ return
162
+ }
163
+
164
+ const formatNumber = (num) => num.toString().padStart(2, '0');
165
+
166
+
167
+ value = `${currentYear}-${formatNumber(currentMonth)}-${formatNumber(selectedDay)} ${hour}:${min}:00`;
168
+
169
+ if (onChange !== undefined) {
170
+ onChange(value);
171
+ }
172
+
173
+ toggleDisplay();
174
+ }
175
+ function handleUpdateHour(inputValue) {
176
+
177
+ if (inputValue.length === 1 && inputValue > 2) {
178
+ inputValue = `0${inputValue}`
179
+ hour = inputValue
180
+ inputMin.focus()
181
+ return
182
+ }
183
+
184
+ if (inputValue.length > 2) {
185
+ inputValue = inputValue.slice((inputValue.length - 2),inputValue.length)
186
+ }
187
+ if (inputValue > 24) {
188
+ inputValue = 24
189
+ }
190
+
191
+ hour = inputValue
192
+
193
+ if (inputValue.length < 2) {
194
+ return
195
+ }
196
+
197
+ inputMin.focus()
198
+ handleUpdateValue(null)
199
+ }
200
+ function handleUpdateMin(inputValue) {
201
+
202
+ if (inputValue.length === 1 && inputValue > 6) {
203
+ inputValue = `0${inputValue}`
204
+ min = inputValue
205
+ }
206
+
207
+ if (inputValue.length > 2) {
208
+ inputValue = inputValue.slice((inputValue.length - 2),inputValue.length)
209
+ }
210
+ if (inputValue > 60) {
211
+ inputValue = 60
212
+ }
213
+
214
+ min = inputValue
215
+ handleUpdateValue(null)
216
+ }
217
+ </script>
218
+
219
+ <div class="date-picker {variant}">
220
+ {#if label}
221
+ <h5>
222
+ {label}
223
+ {#if required}
224
+ <span style="color:var(--red)">*</span>
225
+ {/if}
226
+ </h5>
227
+ {/if}
228
+ <DropdownMenu.Root triggerFullWidth bind:toggleDisplay>
229
+ <DropdownMenu.Trigger slot="trigger">
230
+ <div class="date-container">
231
+ <Button variant="outline" style="width:100%">
232
+ <input class="date-input" type="text" {required} {name} {value} />
233
+ <svg
234
+ width="24"
235
+ height="24"
236
+ viewBox="0 0 24 24"
237
+ fill="none"
238
+ xmlns="http://www.w3.org/2000/svg"
239
+ >
240
+ <path
241
+ d="M8 5.75C7.59 5.75 7.25 5.41 7.25 5V2C7.25 1.59 7.59 1.25 8 1.25C8.41 1.25 8.75 1.59 8.75 2V5C8.75 5.41 8.41 5.75 8 5.75Z"
242
+ fill="white"
243
+ />
244
+ <path
245
+ d="M16 5.75C15.59 5.75 15.25 5.41 15.25 5V2C15.25 1.59 15.59 1.25 16 1.25C16.41 1.25 16.75 1.59 16.75 2V5C16.75 5.41 16.41 5.75 16 5.75Z"
246
+ fill="white"
247
+ />
248
+ <path
249
+ d="M8.5 14.5003C8.37 14.5003 8.24 14.4703 8.12 14.4203C7.99 14.3703 7.89 14.3003 7.79 14.2103C7.61 14.0203 7.5 13.7703 7.5 13.5003C7.5 13.3703 7.53 13.2403 7.58 13.1203C7.63 13.0003 7.7 12.8903 7.79 12.7903C7.89 12.7003 7.99 12.6303 8.12 12.5803C8.48 12.4303 8.93 12.5103 9.21 12.7903C9.39 12.9803 9.5 13.2403 9.5 13.5003C9.5 13.5603 9.49 13.6303 9.48 13.7003C9.47 13.7603 9.45 13.8203 9.42 13.8803C9.4 13.9403 9.37 14.0003 9.33 14.0603C9.3 14.1103 9.25 14.1603 9.21 14.2103C9.02 14.3903 8.76 14.5003 8.5 14.5003Z"
250
+ fill="white"
251
+ />
252
+ <path
253
+ d="M12 14.5008C11.87 14.5008 11.74 14.4709 11.62 14.4209C11.49 14.3709 11.39 14.3008 11.29 14.2108C11.11 14.0208 11 13.7708 11 13.5008C11 13.3708 11.03 13.2408 11.08 13.1208C11.13 13.0008 11.2 12.8909 11.29 12.7909C11.39 12.7009 11.49 12.6308 11.62 12.5808C11.98 12.4208 12.43 12.5109 12.71 12.7909C12.89 12.9809 13 13.2408 13 13.5008C13 13.5608 12.99 13.6309 12.98 13.7009C12.97 13.7609 12.95 13.8209 12.92 13.8809C12.9 13.9409 12.87 14.0008 12.83 14.0608C12.8 14.1108 12.75 14.1608 12.71 14.2108C12.52 14.3908 12.26 14.5008 12 14.5008Z"
254
+ fill="white"
255
+ />
256
+ <path
257
+ d="M15.5 14.5008C15.37 14.5008 15.24 14.4709 15.12 14.4209C14.99 14.3709 14.89 14.3008 14.79 14.2108C14.75 14.1608 14.71 14.1108 14.67 14.0608C14.63 14.0008 14.6 13.9409 14.58 13.8809C14.55 13.8209 14.53 13.7609 14.52 13.7009C14.51 13.6309 14.5 13.5608 14.5 13.5008C14.5 13.2408 14.61 12.9809 14.79 12.7909C14.89 12.7009 14.99 12.6308 15.12 12.5808C15.49 12.4208 15.93 12.5109 16.21 12.7909C16.39 12.9809 16.5 13.2408 16.5 13.5008C16.5 13.5608 16.49 13.6309 16.48 13.7009C16.47 13.7609 16.45 13.8209 16.42 13.8809C16.4 13.9409 16.37 14.0008 16.33 14.0608C16.3 14.1108 16.25 14.1608 16.21 14.2108C16.02 14.3908 15.76 14.5008 15.5 14.5008Z"
258
+ fill="white"
259
+ />
260
+ <path
261
+ d="M8.5 17.9992C8.37 17.9992 8.24 17.9692 8.12 17.9192C8 17.8692 7.89 17.7992 7.79 17.7092C7.61 17.5192 7.5 17.2592 7.5 16.9992C7.5 16.8692 7.53 16.7392 7.58 16.6192C7.63 16.4892 7.7 16.3792 7.79 16.2892C8.16 15.9192 8.84 15.9192 9.21 16.2892C9.39 16.4792 9.5 16.7392 9.5 16.9992C9.5 17.2592 9.39 17.5192 9.21 17.7092C9.02 17.8892 8.76 17.9992 8.5 17.9992Z"
262
+ fill="white"
263
+ />
264
+ <path
265
+ d="M12 17.9992C11.74 17.9992 11.48 17.8892 11.29 17.7092C11.11 17.5192 11 17.2592 11 16.9992C11 16.8692 11.03 16.7392 11.08 16.6192C11.13 16.4892 11.2 16.3792 11.29 16.2892C11.66 15.9192 12.34 15.9192 12.71 16.2892C12.8 16.3792 12.87 16.4892 12.92 16.6192C12.97 16.7392 13 16.8692 13 16.9992C13 17.2592 12.89 17.5192 12.71 17.7092C12.52 17.8892 12.26 17.9992 12 17.9992Z"
266
+ fill="white"
267
+ />
268
+ <path
269
+ d="M15.5 18.0009C15.24 18.0009 14.98 17.8909 14.79 17.7109C14.7 17.6209 14.63 17.5109 14.58 17.3809C14.53 17.2609 14.5 17.1309 14.5 17.0009C14.5 16.8709 14.53 16.7409 14.58 16.6209C14.63 16.4909 14.7 16.3809 14.79 16.2909C15.02 16.0609 15.37 15.9509 15.69 16.0209C15.76 16.0309 15.82 16.0509 15.88 16.0809C15.94 16.1009 16 16.1309 16.06 16.1709C16.11 16.2009 16.16 16.2509 16.21 16.2909C16.39 16.4809 16.5 16.7409 16.5 17.0009C16.5 17.2609 16.39 17.5209 16.21 17.7109C16.02 17.8909 15.76 18.0009 15.5 18.0009Z"
270
+ fill="white"
271
+ />
272
+ <path
273
+ d="M20.5 9.83984H3.5C3.09 9.83984 2.75 9.49984 2.75 9.08984C2.75 8.67984 3.09 8.33984 3.5 8.33984H20.5C20.91 8.33984 21.25 8.67984 21.25 9.08984C21.25 9.49984 20.91 9.83984 20.5 9.83984Z"
274
+ fill="white"
275
+ />
276
+ <path
277
+ d="M16 22.75H8C4.35 22.75 2.25 20.65 2.25 17V8.5C2.25 4.85 4.35 2.75 8 2.75H16C19.65 2.75 21.75 4.85 21.75 8.5V17C21.75 20.65 19.65 22.75 16 22.75ZM8 4.25C5.14 4.25 3.75 5.64 3.75 8.5V17C3.75 19.86 5.14 21.25 8 21.25H16C18.86 21.25 20.25 19.86 20.25 17V8.5C20.25 5.64 18.86 4.25 16 4.25H8Z"
278
+ fill="white"
279
+ />
280
+ </svg>
281
+ {labelMonth}
282
+ </Button>
283
+ </div>
284
+ </DropdownMenu.Trigger>
285
+ <DropdownMenu.Content
286
+ slot="content"
287
+ width="260px"
288
+ style="background-color:var(--bg-1);padding:0px;row-gap:0px;"
289
+ >
290
+ <div class="date-picker-selector">
291
+ <div class="month-selector">
292
+ <IconButton onClick={gotoPreviousMonth} variant="ghost">
293
+ <svg
294
+ width="24"
295
+ height="24"
296
+ viewBox="0 0 24 24"
297
+ fill="none"
298
+ xmlns="http://www.w3.org/2000/svg"
299
+ >
300
+ <path
301
+ d="M15 20.6695C14.81 20.6695 14.62 20.5995 14.47 20.4495L7.95003 13.9295C6.89003 12.8695 6.89003 11.1295 7.95003 10.0695L14.47 3.54953C14.76 3.25953 15.24 3.25953 15.53 3.54953C15.82 3.83953 15.82 4.31953 15.53 4.60953L9.01003 11.1295C8.53003 11.6095 8.53003 12.3895 9.01003 12.8695L15.53 19.3895C15.82 19.6795 15.82 20.1595 15.53 20.4495C15.38 20.5895 15.19 20.6695 15 20.6695Z"
302
+ fill="white"
303
+ />
304
+ </svg>
305
+ </IconButton>
306
+ <h4>{monthList[currentMonth]} {currentYear}</h4>
307
+ <IconButton onClick={gotoNextMonth} variant="ghost">
308
+ <svg
309
+ width="24"
310
+ height="24"
311
+ viewBox="0 0 24 24"
312
+ fill="none"
313
+ xmlns="http://www.w3.org/2000/svg"
314
+ >
315
+ <path
316
+ d="M8.9101 20.6695C8.7201 20.6695 8.5301 20.5995 8.3801 20.4495C8.0901 20.1595 8.0901 19.6795 8.3801 19.3895L14.9001 12.8695C15.3801 12.3895 15.3801 11.6095 14.9001 11.1295L8.3801 4.60953C8.0901 4.31953 8.0901 3.83953 8.3801 3.54953C8.6701 3.25953 9.1501 3.25953 9.4401 3.54953L15.9601 10.0695C16.4701 10.5795 16.7601 11.2695 16.7601 11.9995C16.7601 12.7295 16.4801 13.4195 15.9601 13.9295L9.4401 20.4495C9.2901 20.5895 9.1001 20.6695 8.9101 20.6695Z"
317
+ fill="white"
318
+ />
319
+ </svg>
320
+ </IconButton>
321
+ </div>
322
+ {#if mode === 'day'}
323
+ <table class="calendar">
324
+ <thead>
325
+ <tr>
326
+ <th><h5>L</h5></th>
327
+ <th><h5>Ma</h5></th>
328
+ <th><h5>Me</h5></th>
329
+ <th><h5>J</h5></th>
330
+ <th><h5>V</h5></th>
331
+ <th><h5>S</h5></th>
332
+ <th><h5>D</h5></th>
333
+ </tr>
334
+ </thead>
335
+ <tbody>
336
+ {#each weeks as week}
337
+ <tr>
338
+ {#each week as dayData}
339
+ <td>
340
+ <div>
341
+ <IconButton
342
+ style={selectedDay != dayData.day &&
343
+ currentYear == year &&
344
+ dayData.currentMonth &&
345
+ dayData.day == day
346
+ ? 'background-color:var(--bg-3)'
347
+ : ''}
348
+ onClick={!dayData.currentMonth
349
+ ? undefined
350
+ : () => {
351
+ handleUpdateValue(dayData.day);
352
+ }}
353
+ desabled={!dayData.currentMonth}
354
+ variant={selectedDay == dayData.day &&
355
+ selectedYear == currentYear &&
356
+ dayData.currentMonth
357
+ ? 'primary'
358
+ : 'ghost'}>{dayData.day}</IconButton
359
+ >
360
+ </div>
361
+ </td>
362
+ {/each}
363
+ </tr>
364
+ {/each}
365
+ </tbody>
366
+ </table>
367
+ {/if}
368
+ <div class="bottom-content"></div>
369
+ </div>
370
+ <div class="hour-selector">
371
+ <Input onChange={(inputValue)=>{handleUpdateHour(inputValue)}} bind:value={hour} type="number" placeholder="00">
372
+ <h4 slot="endContent">h</h4>
373
+ </Input>
374
+ <Input bind:input={inputMin} onChange={(inputValue)=>{handleUpdateMin(inputValue)}} bind:value={min} type="number" placeholder="00">
375
+ <h4 slot="endContent">min</h4>
376
+ </Input>
377
+ </div>
378
+ </DropdownMenu.Content>
379
+ </DropdownMenu.Root>
380
+ </div>
381
+
382
+ <style>
383
+ .date-picker.collapse {
384
+ display: flex;
385
+ flex-direction: column;
386
+ padding: var(--pad-s);
387
+ background-color: var(--bg-2);
388
+ border-radius: var(--radius-l);
389
+ }
390
+ .date-picker.collapse .date-container {
391
+ padding: 0;
392
+ }
393
+ .date-container {
394
+ display: flex;
395
+ flex-direction: column;
396
+ padding: var(--pad-s);
397
+ background-color: var(--bg-2);
398
+ border-radius: var(--radius-l);
399
+ }
400
+
401
+ .date-picker-selector {
402
+ width: 100%;
403
+ }
404
+
405
+ .hour-selector {
406
+ display: flex;
407
+ column-gap: var(--pad-m);
408
+ padding: var(--pad-m);
409
+ }
410
+
411
+ .month-selector {
412
+ display: flex;
413
+ align-items: center;
414
+ justify-content: space-between;
415
+ padding: var(--pad-xxl) var(--pad-xxl) var(--pad-m) var(--pad-xxl);
416
+ }
417
+
418
+ .calendar {
419
+ border-collapse: collapse;
420
+ width: 100%;
421
+ }
422
+
423
+ .calendar tbody td {
424
+ background-color: var(--bg-2);
425
+ }
426
+
427
+ .calendar td > div {
428
+ display: flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ }
432
+
433
+ .calendar tr > th {
434
+ padding-bottom: var(--pad-m);
435
+ }
436
+ .calendar tr:first-child > td {
437
+ padding-top: var(--pad-m);
438
+ }
439
+
440
+ .calendar tr > td:last-child,
441
+ .calendar tr > th:last-child {
442
+ padding-right: var(--pad-xxl);
443
+ }
444
+ .calendar tr > td:first-child,
445
+ .calendar tr > th:first-child {
446
+ padding-left: var(--pad-xxl);
447
+ }
448
+
449
+ .calendar tr:last-child > td {
450
+ padding-bottom: var(--pad-m);
451
+ }
452
+
453
+ .bottom-content {
454
+ min-height: var(--radius-l);
455
+ background-color: var(--bg-2);
456
+ border-bottom-left-radius: var(--radius-l);
457
+ border-bottom-right-radius: var(--radius-l);
458
+ }
459
+
460
+ .date-input {
461
+ display: none;
462
+ }
463
+ :global(button:has(.date-input:user-invalid)) {
464
+ border: 1px solid var(--red);
465
+ background-color: var(--red-b);
466
+ }
467
+ </style>
@@ -0,0 +1,138 @@
1
+ <script>
2
+ import ScrollArea from '../ScrollArea/ScrollArea.svelte';
3
+ import Button from '../Button/Button.svelte';
4
+ import * as DropdownMenu from '../DropdownMenu';
5
+
6
+ export let name = '';
7
+ export let label = '';
8
+ export let value = '';
9
+ export let variant = '';
10
+ export let onChange = undefined;
11
+ export let required = false;
12
+
13
+ let targetDay = '';
14
+
15
+
16
+ const dayList = [
17
+ "01",
18
+ "02",
19
+ "03",
20
+ "04",
21
+ "05",
22
+ "06",
23
+ "07",
24
+ "08",
25
+ "09",
26
+ "10",
27
+ "11",
28
+ "12",
29
+ "13",
30
+ "14",
31
+ "15",
32
+ "16",
33
+ "17",
34
+ "18",
35
+ "19",
36
+ "20",
37
+ "21",
38
+ "22",
39
+ "23",
40
+ "24",
41
+ "25",
42
+ "26",
43
+ "27",
44
+ "28",
45
+ "29",
46
+ "30",
47
+ "31",
48
+ ]
49
+
50
+ function handleSelectYear(newValue) {
51
+ targetDay = newValue;
52
+
53
+ checkIfComplete();
54
+ }
55
+
56
+ function checkIfComplete() {
57
+ if (!targetDay) {
58
+ value = '';
59
+ return;
60
+ }
61
+ value = `${targetDay}`;
62
+
63
+ if (onChange !== undefined) {
64
+ onChange(value);
65
+ }
66
+ }
67
+ </script>
68
+
69
+
70
+ <div class="date-input-container {variant === "collapse" ? "collapse" : ""}">
71
+ {#if label}
72
+ <h5>
73
+ {label}
74
+ {#if required}
75
+ <span style="color:var(--red)">*</span>
76
+ {/if}
77
+ </h5>
78
+ {/if}
79
+ <div class="date-input">
80
+ <DropdownMenu.Root triggerFullWidth direction="bottom-left">
81
+ <DropdownMenu.Trigger slot="trigger">
82
+ <Button style="width:100%;" variant="outline">
83
+ <input class="date-input-value" {required} type="text" style="display: none;" {name} {value} />
84
+ <h4>{targetDay || 'dd'}</h4>
85
+ </Button>
86
+ </DropdownMenu.Trigger>
87
+ <DropdownMenu.Content slot="content" width="var(--hamzus-tigger-width)">
88
+ <div class="content">
89
+ <ScrollArea proximity={10} style="max-height:350px;">
90
+ {#each dayList as day}
91
+ <Button
92
+ onClick={() => {
93
+ handleSelectYear(day);
94
+ }}
95
+ style="width:100%;"
96
+ variant="ghost"
97
+ ><h4 style={targetDay == day ? 'color:var(--accent);' : ''}>{day}</h4></Button
98
+ >
99
+ {/each}
100
+ </ScrollArea>
101
+ </div>
102
+ </DropdownMenu.Content>
103
+ </DropdownMenu.Root>
104
+ </div>
105
+ </div>
106
+
107
+ <style>
108
+ .date-input-container.collapse {
109
+ display: flex;
110
+ flex-direction: column;
111
+ padding: var(--pad-s);
112
+ background-color: var(--bg-2);
113
+ border-radius: var(--radius-l);
114
+ }
115
+ .date-input-container.collapse .date-input {
116
+ padding: 0px;
117
+ }
118
+ .date-input {
119
+ display: flex;
120
+ flex-direction: column;
121
+ padding: var(--pad-s);
122
+ background-color: var(--bg-2);
123
+ border-radius: var(--radius-l);
124
+ }
125
+
126
+ .date-input:hover {
127
+ background-color: var(--bg-2);
128
+ }
129
+ .content {
130
+ display: flex;
131
+ max-height: 350px;
132
+ }
133
+
134
+ :global(button:has(.date-input-value:user-invalid)) {
135
+ border: 1px solid var(--red);
136
+ background-color: var(--red-b);
137
+ }
138
+ </style>
@@ -133,6 +133,10 @@
133
133
  // recuperer le contenue du trigger
134
134
  const triggerContent = getFirstChild(trigger);
135
135
 
136
+ if (triggerContent === null) {
137
+ return
138
+ }
139
+
136
140
  // recuperer la position du trigger par rapport a la fenetre
137
141
  const triggerRect = triggerContent.getBoundingClientRect();
138
142
 
@@ -12,6 +12,7 @@
12
12
  export let onChange = () => {};
13
13
  export let onFocus = () => {};
14
14
  export let onBlur = () => {};
15
+ export let input
15
16
  export let name = '';
16
17
  export let value = '';
17
18
  export let initialValue = value;
@@ -39,6 +40,7 @@
39
40
 
40
41
  // fnctions
41
42
  function formatInput(inputValue) {
43
+
42
44
  // verifier que c est un nombre
43
45
  if (type === 'number') {
44
46
  // Remplace les virgules par des points
@@ -151,6 +153,7 @@
151
153
  {required}
152
154
  disabled={isLoading ? true : disabled}
153
155
  {step}
156
+ bind:this={input}
154
157
  />
155
158
  <slot name="endContent" />
156
159
  {#if type == 'password'}
@@ -0,0 +1,164 @@
1
+ <script>
2
+ import ScrollArea from '../ScrollArea/ScrollArea.svelte';
3
+ import Button from '../Button/Button.svelte';
4
+ import * as DropdownMenu from '../DropdownMenu';
5
+
6
+ export let name = '';
7
+ export let label = '';
8
+ export let value = '';
9
+ export let variant = '';
10
+ export let onChange = undefined;
11
+ export let required = false;
12
+
13
+ let targetMonth = '';
14
+ let targetYear = '';
15
+
16
+ $: updateAfterValueHasChanged(value);
17
+
18
+ const monthList = {
19
+ 1: 'janvier',
20
+ 2: 'février',
21
+ 3: 'mars',
22
+ 4: 'avril',
23
+ 5: 'mai',
24
+ 6: 'juin',
25
+ 7: 'juillet',
26
+ 8: 'août',
27
+ 9: 'septembre',
28
+ 10: 'octobre',
29
+ 11: 'novembre',
30
+ 12: 'décembre'
31
+ };
32
+ const yearList = getYearList();
33
+
34
+ function getYearList(startYear = 1997) {
35
+ const currentYear = new Date().getFullYear();
36
+ return Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear - i);
37
+ }
38
+
39
+ function updateAfterValueHasChanged(value) {
40
+ if (!value) {
41
+ targetMonth = '';
42
+ targetYear = '';
43
+ }
44
+ // separer la valuer
45
+ const splittedValue = value.split('-');
46
+
47
+ targetYear = splittedValue[0];
48
+ targetMonth = parseInt(splittedValue[1]);
49
+ }
50
+
51
+ function handleSelectMonth(newValue) {
52
+ targetMonth = newValue;
53
+
54
+ checkIfComplete();
55
+ }
56
+
57
+ function handleSelectYear(newValue) {
58
+ targetYear = newValue;
59
+
60
+ checkIfComplete();
61
+ }
62
+
63
+ function checkIfComplete() {
64
+ if (!targetMonth || !targetYear) {
65
+ value = '';
66
+ return;
67
+ }
68
+
69
+ let formatedMonth = targetMonth;
70
+ if (targetMonth < 10) {
71
+ formatedMonth = `0${targetMonth}`;
72
+ }
73
+
74
+ value = `${targetYear}-${formatedMonth}`;
75
+
76
+ if (onChange !== undefined) {
77
+ onChange(value);
78
+ }
79
+ }
80
+ </script>
81
+
82
+
83
+ <div class="date-input-container {variant === "collapse" ? "collapse" : ""}">
84
+ {#if label}
85
+ <h5>
86
+ {label}
87
+ {#if required}
88
+ <span style="color:var(--red)">*</span>
89
+ {/if}
90
+ </h5>
91
+ {/if}
92
+ <div class="date-input">
93
+ <DropdownMenu.Root triggerFullWidth direction="bottom-left">
94
+ <DropdownMenu.Trigger slot="trigger">
95
+ <Button style="width:100%;" variant="outline">
96
+ <input class="date-input-value" {required} type="text" style="display: none;" {name} {value} />
97
+ <h4>{targetYear || 'aaaa'}-{monthList[targetMonth] || 'mm'}</h4>
98
+ </Button>
99
+ </DropdownMenu.Trigger>
100
+ <DropdownMenu.Content slot="content" width="var(--hamzus-tigger-width)">
101
+ <div class="content">
102
+ <ScrollArea proximity={10} style="max-height:350px;">
103
+ {#each yearList as year}
104
+ <Button
105
+ onClick={() => {
106
+ handleSelectYear(year);
107
+ }}
108
+ style="width:100%;"
109
+ variant="ghost"
110
+ ><h4 style={targetYear == year ? 'color:var(--accent);' : ''}>{year}</h4></Button
111
+ >
112
+ {/each}
113
+ </ScrollArea>
114
+ <ScrollArea proximity={10} style="max-height:350px;">
115
+ {#each Object.entries(monthList) as [inputValue, month]}
116
+ <Button
117
+ style="width:100%;"
118
+ variant="ghost"
119
+ onClick={() => {
120
+ handleSelectMonth(inputValue);
121
+ }}
122
+ ><h4 style={targetMonth == inputValue ? 'color:var(--accent);' : ''}>
123
+ {month}</h4></Button
124
+ >
125
+ {/each}
126
+ </ScrollArea>
127
+ </div>
128
+ </DropdownMenu.Content>
129
+ </DropdownMenu.Root>
130
+ </div>
131
+ </div>
132
+
133
+ <style>
134
+ .date-input-container.collapse {
135
+ display: flex;
136
+ flex-direction: column;
137
+ padding: var(--pad-s);
138
+ background-color: var(--bg-2);
139
+ border-radius: var(--radius-l);
140
+ }
141
+ .date-input-container.collapse .date-input {
142
+ padding: 0px;
143
+ }
144
+ .date-input {
145
+ display: flex;
146
+ flex-direction: column;
147
+ padding: var(--pad-s);
148
+ background-color: var(--bg-2);
149
+ border-radius: var(--radius-l);
150
+ }
151
+
152
+ .date-input:hover {
153
+ background-color: var(--bg-2);
154
+ }
155
+ .content {
156
+ display: flex;
157
+ max-height: 350px;
158
+ }
159
+
160
+ :global(button:has(.date-input-value:user-invalid)) {
161
+ border: 1px solid var(--red);
162
+ background-color: var(--red-b);
163
+ }
164
+ </style>
@@ -1,136 +1,128 @@
1
1
  <script>
2
- import ScrollArea from "../ScrollArea/ScrollArea.svelte";
3
- import Button from "../Button/Button.svelte";
4
- import * as DropdownMenu from "../DropdownMenu"
5
-
6
- export let name = ""
7
- export let label = ""
8
- export let value = ""
9
- export let onChange = undefined
10
-
11
- let targetMonth = ""
12
- let targetYear = ""
13
-
14
- $: updateAfterValueHasChanged(value)
15
-
16
- const monthList = {
17
- 1:"janvier",
18
- 2:"février",
19
- 3:"mars",
20
- 4:"avril",
21
- 5:"mai",
22
- 6:"juin",
23
- 7:"juillet",
24
- 8:"août",
25
- 9:"septembre",
26
- 10:"octobre",
27
- 11:"novembre",
28
- 12:"décembre",
29
- }
30
- const yearList = getYearList()
31
-
32
- function getYearList(startYear = 1997) {
33
- const currentYear = new Date().getFullYear();
34
- return Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear - i);
35
- }
36
-
37
- function updateAfterValueHasChanged(value) {
38
- if (!value) {
39
- targetMonth = ""
40
- targetYear = ""
41
- }
42
- // separer la valuer
43
- const splittedValue = value.split("-")
44
-
45
- targetYear = splittedValue[0]
46
- targetMonth = parseInt(splittedValue[1])
47
-
48
- }
49
-
50
- function handleSelectMonth(newValue) {
51
- targetMonth = newValue
52
-
53
- checkIfComplete()
54
- }
55
-
56
- function handleSelectYear(newValue) {
57
- targetYear = newValue
2
+ import ScrollArea from '../ScrollArea/ScrollArea.svelte';
3
+ import Button from '../Button/Button.svelte';
4
+ import * as DropdownMenu from '../DropdownMenu';
5
+
6
+ export let name = '';
7
+ export let label = '';
8
+ export let value = '';
9
+ export let variant = '';
10
+ export let onChange = undefined;
11
+ export let required = false;
12
+
13
+ let targetMonth = '';
14
+
15
+ const monthList = {
16
+ 1: 'janvier',
17
+ 2: 'février',
18
+ 3: 'mars',
19
+ 4: 'avril',
20
+ 5: 'mai',
21
+ 6: 'juin',
22
+ 7: 'juillet',
23
+ 8: 'août',
24
+ 9: 'septembre',
25
+ 10: 'octobre',
26
+ 11: 'novembre',
27
+ 12: 'décembre'
28
+ };
29
+
30
+
31
+
32
+ function handleSelectMonth(newValue) {
33
+ targetMonth = newValue;
34
+
35
+ checkIfComplete();
36
+ }
58
37
 
59
- checkIfComplete()
60
- }
61
38
 
62
- function checkIfComplete() {
63
- if (!targetMonth || !targetYear) {
64
- value = ""
65
- return
66
- }
39
+ function checkIfComplete() {
40
+ if (!targetMonth) {
41
+ value = '';
42
+ return;
43
+ }
67
44
 
68
- let formatedMonth = targetMonth
69
- if (targetMonth < 10) {
70
- formatedMonth = `0${targetMonth}`
71
- }
45
+ let formatedMonth = targetMonth;
46
+ if (targetMonth < 10) {
47
+ formatedMonth = `0${targetMonth}`;
48
+ }
72
49
 
73
- value = `${targetYear}-${formatedMonth}`
50
+ value = `${formatedMonth}`;
74
51
 
75
- if (onChange !== undefined) {
76
- onChange(value)
77
- }
78
- }
52
+ if (onChange !== undefined) {
53
+ onChange(value);
54
+ }
55
+ }
79
56
  </script>
80
57
 
81
58
 
82
- <input type="hidden" {name} {value}>
83
-
84
- {#if label}
85
- <h5>{label}</h5>
86
- {/if}
87
- <div class="date-input">
88
- <DropdownMenu.Root triggerFullWidth>
89
- <DropdownMenu.Trigger slot="trigger">
90
- <Button style="width:100%;" label="{targetYear || "aaaa"}-{monthList[targetMonth] || "mm"}" variant="ghost"></Button>
91
- </DropdownMenu.Trigger>
92
- <DropdownMenu.Content slot="content">
93
- <div class="content">
94
- <ScrollArea style="max-height:350px;">
95
- {#each yearList as year}
96
- <Button onClick={()=>{handleSelectYear(year)}} style="width:100%;" variant="ghost"><h4 style="{targetYear == year ? "color:var(--accent);" : ""}">{year}</h4></Button>
97
- {/each}
98
- </ScrollArea>
99
- <ScrollArea style="max-height:350px;">
100
- {#each Object.entries(monthList) as [inputValue, month]}
101
- <Button style="width:100%;" variant="ghost" onClick={()=>{handleSelectMonth(inputValue)}}><h4 style="{targetMonth == inputValue ? "color:var(--accent);" : ""}">{month}</h4></Button>
102
- {/each}
103
- </ScrollArea>
104
- </div>
105
-
106
- </DropdownMenu.Content>
107
- </DropdownMenu.Root>
108
- </div>
59
+ <div class="date-input-container {variant === "collapse" ? "collapse" : ""}">
60
+ {#if label}
61
+ <h5>
62
+ {label}
63
+ {#if required}
64
+ <span style="color:var(--red)">*</span>
65
+ {/if}
66
+ </h5>
67
+ {/if}
68
+ <div class="date-input">
69
+ <DropdownMenu.Root triggerFullWidth direction="bottom">
70
+ <DropdownMenu.Trigger slot="trigger">
71
+ <Button style="width:100%;" variant="outline">
72
+ <input class="date-input-value" {required} type="text" style="display: none;" {name} {value} />
73
+ <h4>{monthList[targetMonth] || 'mm'}</h4>
74
+ </Button>
75
+ </DropdownMenu.Trigger>
76
+ <DropdownMenu.Content slot="content" width="var(--hamzus-tigger-width)">
77
+ <div class="content">
78
+ <ScrollArea proximity={10} style="max-height:350px;">
79
+ {#each Object.entries(monthList) as [inputValue, month]}
80
+ <Button
81
+ style="width:100%;"
82
+ variant="ghost"
83
+ onClick={() => {
84
+ handleSelectMonth(inputValue);
85
+ }}
86
+ ><h4 style={targetMonth == inputValue ? 'color:var(--accent);' : ''}>
87
+ {month}</h4></Button
88
+ >
89
+ {/each}
90
+ </ScrollArea>
91
+ </div>
92
+ </DropdownMenu.Content>
93
+ </DropdownMenu.Root>
94
+ </div>
95
+ </div>
109
96
 
110
97
  <style>
111
-
98
+ .date-input-container.collapse {
99
+ display: flex;
100
+ flex-direction: column;
101
+ padding: var(--pad-s);
102
+ background-color: var(--bg-2);
103
+ border-radius: var(--radius-l);
104
+ }
105
+ .date-input-container.collapse .date-input {
106
+ padding: 0px;
107
+ }
112
108
  .date-input {
113
- appearance: none; /* Enlève le style par défaut des navigateurs */
114
- border: 1px solid var(--stroke);
115
- border-radius: var(--radius-xl);
116
- padding: var(--pad-xl);
117
- font-size: 16px;
118
- color: var(--font-2);
119
- background-color: var(--bg-1);
120
- outline: none;
121
- cursor: pointer;
122
- display: flex;
123
- column-gap: var(--pad-m);
109
+ display: flex;
110
+ flex-direction: column;
111
+ padding: var(--pad-s);
112
+ background-color: var(--bg-2);
113
+ border-radius: var(--radius-l);
124
114
  }
125
- .date-input:has(input:user-invalid){
126
- border: 1px solid var(--red);
127
- }
128
115
 
129
116
  .date-input:hover {
130
117
  background-color: var(--bg-2);
131
118
  }
132
- .content{
133
- display: flex;
134
- max-height: 350px;
119
+ .content {
120
+ display: flex;
121
+ max-height: 350px;
122
+ }
123
+
124
+ :global(button:has(.date-input-value:user-invalid)) {
125
+ border: 1px solid var(--red);
126
+ background-color: var(--red-b);
135
127
  }
136
- </style>
128
+ </style>
@@ -5,7 +5,7 @@
5
5
  import Switch from '../Switch/Switch.svelte';
6
6
  import * as Popover from '../Popover';
7
7
  import { tableData } from './table';
8
- import MonthPicker from '../MonthPicker/MonthPicker.svelte';
8
+ import MonthPicker from '../MonthOfYearPicker/MonthOfYearPicker.svelte';
9
9
  import DatePicker from '../DatePicker/DatePicker.svelte';
10
10
  import Input from '../Input/Input.svelte';
11
11
  import Checkbox from '../Checkboxes/Checkbox/Checkbox.svelte';
@@ -9,7 +9,7 @@
9
9
  import Switch from '../Switch/Switch.svelte';
10
10
  import { onDestroy } from 'svelte';
11
11
  import DatePicker from '../DatePicker/DatePicker.svelte';
12
- import MonthPicker from '../MonthPicker/MonthPicker.svelte';
12
+ import MonthPicker from '../MonthOfYearPicker/MonthOfYearPicker.svelte';
13
13
  import Checkbox from '../Checkboxes/Checkbox/Checkbox.svelte';
14
14
  // props
15
15
  export let tableId = null;
@@ -0,0 +1,145 @@
1
+ <script>
2
+ import * as DropdownMenu from '../DropdownMenu';
3
+ import Button from '../Button/Button.svelte';
4
+ import IconButton from '../IconButton/IconButton.svelte';
5
+ import { onMount } from 'svelte';
6
+ import Input from '../Input/Input.svelte';
7
+
8
+ export let value = '';
9
+ export let onChange = undefined;
10
+ export let label = '';
11
+ export let name = '';
12
+ export let variant = 'default'; // "default" | "collapse"
13
+ export let required = false;
14
+
15
+ let inputMin;
16
+ let hour = '';
17
+ let min = '';
18
+
19
+ onMount(() => {
20
+ if (value === '') {
21
+ return;
22
+ }
23
+
24
+ const hourData = value.split(':');
25
+
26
+ hour = hourData[0];
27
+ min = hourData[1];
28
+ });
29
+
30
+ function handleUpdateValue() {
31
+ if (hour === '' || min === '' || hour.length < 2 || min.length < 2) {
32
+ return;
33
+ }
34
+
35
+ const formatNumber = (num) => num.toString().padStart(2, '0');
36
+
37
+ value = `${hour}:${min}`;
38
+
39
+ if (onChange !== undefined) {
40
+ onChange(value);
41
+ }
42
+ }
43
+ function handleUpdateHour(inputValue) {
44
+ if (inputValue.length === 1 && inputValue > 2) {
45
+ inputValue = `0${inputValue}`;
46
+ hour = inputValue;
47
+ inputMin.focus();
48
+ return;
49
+ }
50
+
51
+ if (inputValue.length > 2) {
52
+ inputValue = inputValue.slice(inputValue.length - 2, inputValue.length);
53
+ }
54
+ if (inputValue > 24) {
55
+ inputValue = 24;
56
+ }
57
+
58
+ hour = inputValue;
59
+
60
+ if (inputValue.length < 2) {
61
+ return;
62
+ }
63
+
64
+ inputMin.focus();
65
+ handleUpdateValue();
66
+ }
67
+ function handleUpdateMin(inputValue) {
68
+ if (inputValue.length === 1 && inputValue > 6) {
69
+ inputValue = `0${inputValue}`;
70
+ min = inputValue;
71
+ }
72
+
73
+ if (inputValue.length > 2) {
74
+ inputValue = inputValue.slice(inputValue.length - 2, inputValue.length);
75
+ }
76
+ if (inputValue > 60) {
77
+ inputValue = 60;
78
+ }
79
+
80
+ min = inputValue;
81
+ handleUpdateValue();
82
+ }
83
+ </script>
84
+
85
+ <div class="date-picker {variant}">
86
+ {#if label}
87
+ <h5>
88
+ {label}
89
+ {#if required}
90
+ <span style="color:var(--red)">*</span>
91
+ {/if}
92
+ </h5>
93
+ {/if}
94
+ <div class="date-container">
95
+ <input type="text" style="display: none;" class="input-value" {name} {value} {required}>
96
+ <Input
97
+ onChange={(inputValue) => {
98
+ handleUpdateHour(inputValue);
99
+ }}
100
+ bind:value={hour}
101
+ type="number"
102
+ style="width: 100%;"
103
+ placeholder="00"
104
+ >
105
+ <h4 slot="endContent">h</h4>
106
+ </Input>
107
+ <Input
108
+ bind:input={inputMin}
109
+ onChange={(inputValue) => {
110
+ handleUpdateMin(inputValue);
111
+ }}
112
+ bind:value={min}
113
+ type="number"
114
+ style="width: 100%;"
115
+ placeholder="00"
116
+ >
117
+ <h4 slot="endContent">min</h4>
118
+ </Input>
119
+ </div>
120
+ </div>
121
+
122
+ <style>
123
+ .date-picker.collapse {
124
+ display: flex;
125
+ flex-direction: column;
126
+ padding: var(--pad-s);
127
+ background-color: var(--bg-2);
128
+ border-radius: var(--radius-l);
129
+ }
130
+ .date-picker.collapse .date-container {
131
+ padding: 0;
132
+ }
133
+ .date-container {
134
+ display: flex;
135
+ width: 100%;
136
+ padding: var(--pad-s);
137
+ background-color: var(--bg-2);
138
+ border-radius: var(--radius-l);
139
+ }
140
+
141
+ .date-container:has( .input-value:user-invalid) {
142
+ border: 1px solid var(--red);
143
+ background-color: var(--red-b);
144
+ }
145
+ </style>
@@ -0,0 +1,111 @@
1
+ <script>
2
+ import ScrollArea from '../ScrollArea/ScrollArea.svelte';
3
+ import Button from '../Button/Button.svelte';
4
+ import * as DropdownMenu from '../DropdownMenu';
5
+
6
+ export let name = '';
7
+ export let label = '';
8
+ export let value = '';
9
+ export let variant = '';
10
+ export let onChange = undefined;
11
+ export let required = false;
12
+
13
+ let targetYear = '';
14
+
15
+
16
+ const yearList = getYearList();
17
+
18
+ function getYearList(startYear = 1997) {
19
+ const currentYear = new Date().getFullYear();
20
+ return Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear - i);
21
+ }
22
+
23
+ function handleSelectYear(newValue) {
24
+ targetYear = newValue;
25
+
26
+ checkIfComplete();
27
+ }
28
+
29
+ function checkIfComplete() {
30
+ if (!targetYear) {
31
+ value = '';
32
+ return;
33
+ }
34
+ value = `${targetYear}`;
35
+
36
+ if (onChange !== undefined) {
37
+ onChange(value);
38
+ }
39
+ }
40
+ </script>
41
+
42
+
43
+ <div class="date-input-container {variant === "collapse" ? "collapse" : ""}">
44
+ {#if label}
45
+ <h5>
46
+ {label}
47
+ {#if required}
48
+ <span style="color:var(--red)">*</span>
49
+ {/if}
50
+ </h5>
51
+ {/if}
52
+ <div class="date-input">
53
+ <DropdownMenu.Root triggerFullWidth direction="bottom-left">
54
+ <DropdownMenu.Trigger slot="trigger">
55
+ <Button style="width:100%;" variant="outline">
56
+ <input class="date-input-value" {required} type="text" style="display: none;" {name} {value} />
57
+ <h4>{targetYear || 'aaaa'}</h4>
58
+ </Button>
59
+ </DropdownMenu.Trigger>
60
+ <DropdownMenu.Content slot="content" width="var(--hamzus-tigger-width)">
61
+ <div class="content">
62
+ <ScrollArea proximity={10} style="max-height:350px;">
63
+ {#each yearList as year}
64
+ <Button
65
+ onClick={() => {
66
+ handleSelectYear(year);
67
+ }}
68
+ style="width:100%;"
69
+ variant="ghost"
70
+ ><h4 style={targetYear == year ? 'color:var(--accent);' : ''}>{year}</h4></Button
71
+ >
72
+ {/each}
73
+ </ScrollArea>
74
+ </div>
75
+ </DropdownMenu.Content>
76
+ </DropdownMenu.Root>
77
+ </div>
78
+ </div>
79
+
80
+ <style>
81
+ .date-input-container.collapse {
82
+ display: flex;
83
+ flex-direction: column;
84
+ padding: var(--pad-s);
85
+ background-color: var(--bg-2);
86
+ border-radius: var(--radius-l);
87
+ }
88
+ .date-input-container.collapse .date-input {
89
+ padding: 0px;
90
+ }
91
+ .date-input {
92
+ display: flex;
93
+ flex-direction: column;
94
+ padding: var(--pad-s);
95
+ background-color: var(--bg-2);
96
+ border-radius: var(--radius-l);
97
+ }
98
+
99
+ .date-input:hover {
100
+ background-color: var(--bg-2);
101
+ }
102
+ .content {
103
+ display: flex;
104
+ max-height: 350px;
105
+ }
106
+
107
+ :global(button:has(.date-input-value:user-invalid)) {
108
+ border: 1px solid var(--red);
109
+ background-color: var(--red-b);
110
+ }
111
+ </style>