@idds/js 1.0.38 → 1.0.40

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 (3) hide show
  1. package/dist/index.iife.js +263 -138
  2. package/dist/index.js +263 -138
  3. package/package.json +1 -1
@@ -121,17 +121,31 @@ var InaUI = (() => {
121
121
  // src/js/components/stateful/datepicker.js
122
122
  function initDatepicker() {
123
123
  document.querySelectorAll(".ina-date-picker").forEach((datepicker) => {
124
+ if (datepicker.dataset.initialized === "true") return;
125
+ datepicker.dataset.initialized = "true";
126
+ const mode = datepicker.dataset.mode || "single";
127
+ const format = datepicker.dataset.format || "d MMMM yyyy";
124
128
  const trigger = datepicker.querySelector(".ina-date-picker__trigger");
125
129
  const triggerText = trigger.querySelector(".ina-date-picker__trigger-text");
126
130
  const panel = datepicker.querySelector(".ina-date-picker__panel");
131
+ panel.style.display = "none";
127
132
  let panelContent = panel.querySelector(".ina-date-picker__panel-content");
128
133
  if (!panelContent) {
129
134
  panelContent = document.createElement("div");
130
135
  panelContent.className = "ina-date-picker__panel-content";
136
+ if (mode === "range" || mode === "multiple") {
137
+ panelContent.classList.add("ina-date-picker__panel-content--dual");
138
+ }
131
139
  panel.appendChild(panelContent);
140
+ } else {
141
+ if (mode === "range" || mode === "multiple") {
142
+ panelContent.classList.add("ina-date-picker__panel-content--dual");
143
+ }
132
144
  }
133
- let currentDate = /* @__PURE__ */ new Date();
145
+ let viewDate = /* @__PURE__ */ new Date();
134
146
  let selectedDate = null;
147
+ let selectedDates = [];
148
+ let rangeDate = [null, null];
135
149
  let isOpen = false;
136
150
  const MONTHS_ID = [
137
151
  "Januari",
@@ -163,18 +177,67 @@ var InaUI = (() => {
163
177
  ];
164
178
  const DAYS_SHORT = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"];
165
179
  function formatDate(date) {
180
+ if (!date) return "";
166
181
  const day = date.getDate().toString().padStart(2, "0");
167
182
  const monthIndex = date.getMonth();
168
183
  const year = date.getFullYear();
169
184
  return `${day} ${MONTHS_SHORT_ID[monthIndex]} ${year}`;
170
185
  }
171
- function createIcon(name, size = 16) {
172
- if (name === "chevron-left") {
173
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 6l-6 6l6 6" /></svg>`;
174
- }
175
- if (name === "chevron-right") {
176
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l6 6l-6 6" /></svg>`;
186
+ function updateTrigger() {
187
+ if (mode === "single") {
188
+ if (selectedDate) {
189
+ triggerText.textContent = formatDate(selectedDate);
190
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
191
+ triggerText.classList.remove(
192
+ "ina-date-picker__trigger-text--placeholder"
193
+ );
194
+ } else {
195
+ triggerText.textContent = "Pilih Tanggal";
196
+ triggerText.classList.remove("ina-date-picker__trigger-text--value");
197
+ triggerText.classList.add(
198
+ "ina-date-picker__trigger-text--placeholder"
199
+ );
200
+ }
201
+ } else if (mode === "range") {
202
+ if (rangeDate[0] && rangeDate[1]) {
203
+ const start = formatDate(rangeDate[0]);
204
+ const end = formatDate(rangeDate[1]);
205
+ triggerText.textContent = `${start} - ${end}`;
206
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
207
+ triggerText.classList.remove(
208
+ "ina-date-picker__trigger-text--placeholder"
209
+ );
210
+ } else if (rangeDate[0]) {
211
+ triggerText.textContent = `${formatDate(rangeDate[0])} - ...`;
212
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
213
+ } else {
214
+ triggerText.textContent = "Pilih Rentang Tanggal";
215
+ triggerText.classList.remove("ina-date-picker__trigger-text--value");
216
+ triggerText.classList.add(
217
+ "ina-date-picker__trigger-text--placeholder"
218
+ );
219
+ }
220
+ } else if (mode === "multiple") {
221
+ if (selectedDates.length > 0) {
222
+ triggerText.textContent = `${selectedDates.length} Tanggal Terpilih`;
223
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
224
+ triggerText.classList.remove(
225
+ "ina-date-picker__trigger-text--placeholder"
226
+ );
227
+ } else {
228
+ triggerText.textContent = "Pilih Beberapa Tanggal";
229
+ triggerText.classList.remove("ina-date-picker__trigger-text--value");
230
+ triggerText.classList.add(
231
+ "ina-date-picker__trigger-text--placeholder"
232
+ );
233
+ }
177
234
  }
235
+ }
236
+ function createIcon(name, size = 16) {
237
+ if (name === "chevron-left")
238
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6l6 6" /></svg>`;
239
+ if (name === "chevron-right")
240
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6l-6 6" /></svg>`;
178
241
  return "";
179
242
  }
180
243
  function createMonthPicker(initialMonth, onChange) {
@@ -185,16 +248,10 @@ var InaUI = (() => {
185
248
  const pickerTrigger = document.createElement("button");
186
249
  pickerTrigger.type = "button";
187
250
  pickerTrigger.className = "ina-month-picker__trigger ina-month-picker__trigger--size-sm";
188
- const updateTriggerText = () => {
189
- pickerTrigger.innerHTML = `
190
- <span class="ina-month-picker__trigger-text">${MONTHS_SHORT_ID[currentMonthIdx]}</span>
191
- `;
251
+ const updateText = () => {
252
+ pickerTrigger.innerHTML = `<span class="ina-month-picker__trigger-text">${MONTHS_SHORT_ID[currentMonthIdx]}</span>`;
192
253
  };
193
- updateTriggerText();
194
- pickerTrigger.addEventListener("click", (e) => {
195
- e.stopPropagation();
196
- togglePicker(!isPickerOpen);
197
- });
254
+ updateText();
198
255
  const pickerPanel = document.createElement("div");
199
256
  pickerPanel.className = "ina-month-picker__panel";
200
257
  const grid = document.createElement("div");
@@ -209,21 +266,18 @@ var InaUI = (() => {
209
266
  btn.addEventListener("click", (e) => {
210
267
  e.stopPropagation();
211
268
  currentMonthIdx = idx;
212
- updateTriggerText();
213
- grid.querySelectorAll(".ina-month-picker__month-option").forEach((b, i) => {
214
- if (i === idx)
215
- b.classList.add("ina-month-picker__month-option--selected");
216
- else
217
- b.classList.remove("ina-month-picker__month-option--selected");
218
- });
269
+ updateText();
219
270
  togglePicker(false);
220
271
  onChange(idx);
221
272
  });
222
273
  grid.appendChild(btn);
223
274
  });
224
275
  pickerPanel.appendChild(grid);
225
- container.appendChild(pickerTrigger);
226
- container.appendChild(pickerPanel);
276
+ container.append(pickerTrigger, pickerPanel);
277
+ pickerTrigger.addEventListener("click", (e) => {
278
+ e.stopPropagation();
279
+ togglePicker(!isPickerOpen);
280
+ });
227
281
  function togglePicker(show) {
228
282
  isPickerOpen = show;
229
283
  if (show) {
@@ -241,13 +295,7 @@ var InaUI = (() => {
241
295
  element: container,
242
296
  setMonth: (m) => {
243
297
  currentMonthIdx = m;
244
- updateTriggerText();
245
- grid.querySelectorAll(".ina-month-picker__month-option").forEach((b, i) => {
246
- if (i === m)
247
- b.classList.add("ina-month-picker__month-option--selected");
248
- else
249
- b.classList.remove("ina-month-picker__month-option--selected");
250
- });
298
+ updateText();
251
299
  }
252
300
  };
253
301
  }
@@ -260,16 +308,10 @@ var InaUI = (() => {
260
308
  const pickerTrigger = document.createElement("button");
261
309
  pickerTrigger.type = "button";
262
310
  pickerTrigger.className = "ina-year-picker__trigger ina-year-picker__trigger--size-sm";
263
- const updateTriggerText = () => {
264
- pickerTrigger.innerHTML = `
265
- <span class="ina-year-picker__trigger-text">${currentYearVal}</span>
266
- `;
311
+ const updateText = () => {
312
+ pickerTrigger.innerHTML = `<span class="ina-year-picker__trigger-text">${currentYearVal}</span>`;
267
313
  };
268
- updateTriggerText();
269
- pickerTrigger.addEventListener("click", (e) => {
270
- e.stopPropagation();
271
- togglePicker(!isPickerOpen);
272
- });
314
+ updateText();
273
315
  const pickerPanel = document.createElement("div");
274
316
  pickerPanel.className = "ina-year-picker__panel";
275
317
  const header = document.createElement("div");
@@ -310,7 +352,7 @@ var InaUI = (() => {
310
352
  btn.addEventListener("click", (e) => {
311
353
  e.stopPropagation();
312
354
  currentYearVal = y;
313
- updateTriggerText();
355
+ updateText();
314
356
  togglePicker(false);
315
357
  onChange(y);
316
358
  });
@@ -319,16 +361,18 @@ var InaUI = (() => {
319
361
  }
320
362
  pickerPanel.append(header, grid);
321
363
  container.append(pickerTrigger, pickerPanel);
364
+ pickerTrigger.addEventListener("click", (e) => {
365
+ e.stopPropagation();
366
+ togglePicker(!isPickerOpen);
367
+ });
322
368
  function togglePicker(show) {
323
369
  isPickerOpen = show;
324
370
  if (show) {
325
371
  decadeStart = Math.floor(currentYearVal / 20) * 20;
326
372
  renderGrid();
327
373
  pickerPanel.classList.add("ina-year-picker__panel--open");
328
- pickerTrigger.setAttribute("aria-expanded", "true");
329
374
  } else {
330
375
  pickerPanel.classList.remove("ina-year-picker__panel--open");
331
- pickerTrigger.setAttribute("aria-expanded", "false");
332
376
  }
333
377
  }
334
378
  document.addEventListener("click", (e) => {
@@ -338,131 +382,212 @@ var InaUI = (() => {
338
382
  element: container,
339
383
  setYear: (y) => {
340
384
  currentYearVal = y;
341
- updateTriggerText();
385
+ updateText();
342
386
  }
343
387
  };
344
388
  }
345
- function renderCalendar() {
346
- panelContent.innerHTML = "";
347
- const year = currentDate.getFullYear();
348
- const month = currentDate.getMonth();
349
- const calendarContainer = document.createElement("div");
350
- calendarContainer.className = "ina-date-picker__calendar-container";
389
+ function renderCalendarGrid(baseDate, isNextMonth = false) {
390
+ const year = baseDate.getFullYear();
391
+ const month = baseDate.getMonth();
392
+ const container = document.createElement("div");
393
+ if (!isNextMonth) {
394
+ container.className = "ina-date-picker__calendar-container";
395
+ } else {
396
+ container.className = "ina-date-picker__calendar";
397
+ }
351
398
  const header = document.createElement("div");
352
- header.className = "ina-date-picker__calendar-header";
353
- const prevBtn = document.createElement("button");
354
- prevBtn.className = "ina-date-picker__nav-button";
355
- prevBtn.type = "button";
356
- prevBtn.innerHTML = createIcon("chevron-left", 20);
357
- prevBtn.addEventListener("click", (e) => {
358
- e.stopPropagation();
359
- currentDate.setMonth(month - 1);
360
- renderCalendar();
361
- });
362
- const nextBtn = document.createElement("button");
363
- nextBtn.className = "ina-date-picker__nav-button";
364
- nextBtn.type = "button";
365
- nextBtn.innerHTML = createIcon("chevron-right", 20);
366
- nextBtn.addEventListener("click", (e) => {
367
- e.stopPropagation();
368
- currentDate.setMonth(month + 1);
369
- renderCalendar();
370
- });
371
- const controls = document.createElement("div");
372
- controls.className = "ina-date-picker__header-controls";
373
- const monthContainer = document.createElement("div");
374
- monthContainer.className = "ina-date-picker__dropdown-container";
375
- const monthPicker = createMonthPicker(month, (newMonth) => {
376
- currentDate.setMonth(newMonth);
377
- renderCalendar();
378
- });
379
- monthContainer.appendChild(monthPicker.element);
380
- const yearContainer = document.createElement("div");
381
- yearContainer.className = "ina-date-picker__dropdown-container";
382
- const yearPicker = createYearPicker(year, (newYear) => {
383
- currentDate.setFullYear(newYear);
384
- renderCalendar();
385
- });
386
- yearContainer.appendChild(yearPicker.element);
387
- controls.append(monthContainer, yearContainer);
388
- header.append(prevBtn, controls, nextBtn);
399
+ header.className = isNextMonth ? "ina-date-picker__next-month-header" : "ina-date-picker__calendar-header";
400
+ if (!isNextMonth) {
401
+ const prevBtn = document.createElement("button");
402
+ prevBtn.type = "button";
403
+ prevBtn.className = "ina-date-picker__nav-button";
404
+ prevBtn.innerHTML = createIcon("chevron-left");
405
+ prevBtn.onclick = (e) => {
406
+ e.stopPropagation();
407
+ viewDate.setMonth(viewDate.getMonth() - 1);
408
+ render();
409
+ };
410
+ header.appendChild(prevBtn);
411
+ } else {
412
+ const spacer = document.createElement("div");
413
+ spacer.style.width = "32px";
414
+ header.appendChild(spacer);
415
+ }
416
+ if (!isNextMonth) {
417
+ const controls = document.createElement("div");
418
+ controls.className = "ina-date-picker__header-controls";
419
+ const monthCont = document.createElement("div");
420
+ monthCont.className = "ina-date-picker__dropdown-container";
421
+ const monthPicker = createMonthPicker(month, (m) => {
422
+ viewDate.setMonth(m);
423
+ render();
424
+ });
425
+ monthCont.appendChild(monthPicker.element);
426
+ const yearCont = document.createElement("div");
427
+ yearCont.className = "ina-date-picker__dropdown-container";
428
+ const yearPicker = createYearPicker(year, (y) => {
429
+ viewDate.setFullYear(y);
430
+ render();
431
+ });
432
+ yearCont.appendChild(yearPicker.element);
433
+ controls.append(monthCont, yearCont);
434
+ header.appendChild(controls);
435
+ } else {
436
+ const title = document.createElement("div");
437
+ title.className = "ina-date-picker__calendar-title";
438
+ title.textContent = `${MONTHS_ID[month]} ${year}`;
439
+ header.appendChild(title);
440
+ }
441
+ const showNextBtn = mode === "single" && !isNextMonth || isNextMonth;
442
+ if (showNextBtn) {
443
+ const nextBtn = document.createElement("button");
444
+ nextBtn.type = "button";
445
+ nextBtn.className = "ina-date-picker__nav-button";
446
+ nextBtn.innerHTML = createIcon("chevron-right");
447
+ nextBtn.onclick = (e) => {
448
+ e.stopPropagation();
449
+ viewDate.setMonth(viewDate.getMonth() + 1);
450
+ render();
451
+ };
452
+ header.appendChild(nextBtn);
453
+ } else if (!isNextMonth) {
454
+ const spacer = document.createElement("div");
455
+ spacer.style.width = "32px";
456
+ header.appendChild(spacer);
457
+ }
389
458
  const grid = document.createElement("div");
390
459
  grid.className = "ina-date-picker__calendar-grid";
391
- DAYS_SHORT.forEach((day) => {
460
+ DAYS_SHORT.forEach((d) => {
392
461
  const dh = document.createElement("div");
393
462
  dh.className = "ina-date-picker__day-header";
394
- dh.textContent = day;
463
+ dh.textContent = d;
395
464
  grid.appendChild(dh);
396
465
  });
397
466
  const firstDayOfMonth = new Date(year, month, 1).getDay();
398
467
  const daysInMonth = new Date(year, month + 1, 0).getDate();
399
468
  const daysInPrevMonth = new Date(year, month, 0).getDate();
469
+ const today = /* @__PURE__ */ new Date();
400
470
  for (let i = firstDayOfMonth - 1; i >= 0; i--) {
401
- const dayBtn = document.createElement("button");
402
- dayBtn.type = "button";
403
- dayBtn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
404
- dayBtn.textContent = daysInPrevMonth - i;
405
- grid.appendChild(dayBtn);
471
+ const btn = document.createElement("button");
472
+ btn.type = "button";
473
+ btn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
474
+ btn.textContent = daysInPrevMonth - i;
475
+ grid.appendChild(btn);
406
476
  }
407
- const today = /* @__PURE__ */ new Date();
408
477
  for (let i = 1; i <= daysInMonth; i++) {
409
- const dayBtn = document.createElement("button");
410
- dayBtn.type = "button";
411
- dayBtn.className = "ina-date-picker__day";
412
- dayBtn.textContent = i;
478
+ const date = new Date(year, month, i);
479
+ const btn = document.createElement("button");
480
+ btn.type = "button";
481
+ btn.className = "ina-date-picker__day";
482
+ btn.textContent = i;
413
483
  let isSelected = false;
414
- if (selectedDate && selectedDate.getDate() === i && selectedDate.getMonth() === month && selectedDate.getFullYear() === year) {
415
- dayBtn.classList.add("ina-date-picker__day--selected");
416
- isSelected = true;
417
- }
418
- if (today.getDate() === i && today.getMonth() === month && today.getFullYear() === year) {
419
- dayBtn.classList.add("ina-date-picker__day--today");
484
+ let isInRange = false;
485
+ if (mode === "single" && selectedDate) {
486
+ if (date.toDateString() === selectedDate.toDateString())
487
+ isSelected = true;
488
+ } else if (mode === "multiple") {
489
+ if (selectedDates.some((d) => d.toDateString() === date.toDateString()))
490
+ isSelected = true;
491
+ } else if (mode === "range") {
492
+ const [start, end] = rangeDate;
493
+ if (start && date.toDateString() === start.toDateString())
494
+ isSelected = true;
495
+ if (end && date.toDateString() === end.toDateString())
496
+ isSelected = true;
497
+ if (start && end && date > start && date < end) isInRange = true;
420
498
  }
421
- if (!isSelected) {
422
- dayBtn.classList.add("ina-date-picker__day--hover");
423
- }
424
- dayBtn.addEventListener("click", (e) => {
499
+ if (isSelected) btn.classList.add("ina-date-picker__day--selected");
500
+ if (isInRange) btn.classList.add("ina-date-picker__day--in-range");
501
+ if (date.toDateString() === today.toDateString())
502
+ btn.classList.add("ina-date-picker__day--today");
503
+ if (!isSelected && !isInRange)
504
+ btn.classList.add("ina-date-picker__day--hover");
505
+ btn.onclick = (e) => {
425
506
  e.stopPropagation();
426
- selectedDate = new Date(year, month, i);
427
- triggerText.textContent = formatDate(selectedDate);
428
- triggerText.classList.add("ina-date-picker__trigger-text--value");
429
- triggerText.classList.remove(
430
- "ina-date-picker__trigger-text--placeholder"
431
- );
507
+ if (mode === "single") {
508
+ selectedDate = date;
509
+ close();
510
+ } else if (mode === "multiple") {
511
+ const existsIdx = selectedDates.findIndex(
512
+ (d) => d.toDateString() === date.toDateString()
513
+ );
514
+ if (existsIdx >= 0) selectedDates.splice(existsIdx, 1);
515
+ else selectedDates.push(date);
516
+ render();
517
+ } else if (mode === "range") {
518
+ const [start, end] = rangeDate;
519
+ if (!start || start && end) {
520
+ rangeDate = [date, null];
521
+ } else {
522
+ if (date < start) {
523
+ rangeDate = [date, start];
524
+ } else {
525
+ rangeDate = [start, date];
526
+ }
527
+ close();
528
+ }
529
+ render();
530
+ }
531
+ updateTrigger();
432
532
  datepicker.dispatchEvent(
433
- new CustomEvent("date:changed", { detail: { selectedDate } })
533
+ new CustomEvent("date:changed", {
534
+ detail: {
535
+ selectedDate: mode === "single" ? selectedDate : mode === "multiple" ? selectedDates : rangeDate
536
+ }
537
+ })
434
538
  );
435
- toggle(false);
436
- });
437
- grid.appendChild(dayBtn);
539
+ };
540
+ grid.appendChild(btn);
438
541
  }
439
- const currentCells = grid.children.length - 7;
440
- const remaining = 42 - currentCells;
542
+ const usedCells = grid.children.length - 7;
543
+ const remaining = 42 - usedCells;
441
544
  for (let i = 1; i <= remaining; i++) {
442
- const dayBtn = document.createElement("button");
443
- dayBtn.type = "button";
444
- dayBtn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
445
- dayBtn.textContent = i;
446
- grid.appendChild(dayBtn);
545
+ const btn = document.createElement("button");
546
+ btn.type = "button";
547
+ btn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
548
+ btn.textContent = i;
549
+ grid.appendChild(btn);
447
550
  }
448
- calendarContainer.append(header, grid);
449
- panelContent.appendChild(calendarContainer);
551
+ container.append(header, grid);
552
+ return container;
450
553
  }
451
- function toggle(show) {
452
- isOpen = show;
453
- if (show) {
454
- panel.classList.add("ina-date-picker__panel--open");
455
- renderCalendar();
456
- } else {
457
- panel.classList.remove("ina-date-picker__panel--open");
554
+ function render() {
555
+ panelContent.innerHTML = "";
556
+ const cal1 = renderCalendarGrid(viewDate);
557
+ panelContent.appendChild(cal1);
558
+ if (mode === "range" || mode === "multiple") {
559
+ const nextMonthDate = new Date(
560
+ viewDate.getFullYear(),
561
+ viewDate.getMonth() + 1,
562
+ 1
563
+ );
564
+ const cal2 = renderCalendarGrid(nextMonthDate, true);
565
+ panelContent.appendChild(cal2);
458
566
  }
459
567
  }
568
+ function open() {
569
+ isOpen = true;
570
+ panel.classList.add("ina-date-picker__panel--open");
571
+ panel.style.display = "block";
572
+ render();
573
+ }
574
+ function close() {
575
+ isOpen = false;
576
+ panel.classList.remove("ina-date-picker__panel--open");
577
+ panel.style.display = "none";
578
+ }
579
+ function toggle() {
580
+ if (isOpen) close();
581
+ else open();
582
+ }
460
583
  trigger.addEventListener("click", (e) => {
461
584
  e.stopPropagation();
462
- toggle(!isOpen);
585
+ toggle();
463
586
  });
464
587
  document.addEventListener("click", (e) => {
465
- if (!datepicker.contains(e.target)) toggle(false);
588
+ if (!datepicker.contains(e.target)) {
589
+ close();
590
+ }
466
591
  });
467
592
  });
468
593
  }
package/dist/index.js CHANGED
@@ -109,17 +109,31 @@ function initAccordion(rootSelector = `.${PREFIX}-accordion`) {
109
109
  // src/js/components/stateful/datepicker.js
110
110
  function initDatepicker() {
111
111
  document.querySelectorAll(".ina-date-picker").forEach((datepicker) => {
112
+ if (datepicker.dataset.initialized === "true") return;
113
+ datepicker.dataset.initialized = "true";
114
+ const mode = datepicker.dataset.mode || "single";
115
+ const format = datepicker.dataset.format || "d MMMM yyyy";
112
116
  const trigger = datepicker.querySelector(".ina-date-picker__trigger");
113
117
  const triggerText = trigger.querySelector(".ina-date-picker__trigger-text");
114
118
  const panel = datepicker.querySelector(".ina-date-picker__panel");
119
+ panel.style.display = "none";
115
120
  let panelContent = panel.querySelector(".ina-date-picker__panel-content");
116
121
  if (!panelContent) {
117
122
  panelContent = document.createElement("div");
118
123
  panelContent.className = "ina-date-picker__panel-content";
124
+ if (mode === "range" || mode === "multiple") {
125
+ panelContent.classList.add("ina-date-picker__panel-content--dual");
126
+ }
119
127
  panel.appendChild(panelContent);
128
+ } else {
129
+ if (mode === "range" || mode === "multiple") {
130
+ panelContent.classList.add("ina-date-picker__panel-content--dual");
131
+ }
120
132
  }
121
- let currentDate = /* @__PURE__ */ new Date();
133
+ let viewDate = /* @__PURE__ */ new Date();
122
134
  let selectedDate = null;
135
+ let selectedDates = [];
136
+ let rangeDate = [null, null];
123
137
  let isOpen = false;
124
138
  const MONTHS_ID = [
125
139
  "Januari",
@@ -151,18 +165,67 @@ function initDatepicker() {
151
165
  ];
152
166
  const DAYS_SHORT = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"];
153
167
  function formatDate(date) {
168
+ if (!date) return "";
154
169
  const day = date.getDate().toString().padStart(2, "0");
155
170
  const monthIndex = date.getMonth();
156
171
  const year = date.getFullYear();
157
172
  return `${day} ${MONTHS_SHORT_ID[monthIndex]} ${year}`;
158
173
  }
159
- function createIcon(name, size = 16) {
160
- if (name === "chevron-left") {
161
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 6l-6 6l6 6" /></svg>`;
162
- }
163
- if (name === "chevron-right") {
164
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l6 6l-6 6" /></svg>`;
174
+ function updateTrigger() {
175
+ if (mode === "single") {
176
+ if (selectedDate) {
177
+ triggerText.textContent = formatDate(selectedDate);
178
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
179
+ triggerText.classList.remove(
180
+ "ina-date-picker__trigger-text--placeholder"
181
+ );
182
+ } else {
183
+ triggerText.textContent = "Pilih Tanggal";
184
+ triggerText.classList.remove("ina-date-picker__trigger-text--value");
185
+ triggerText.classList.add(
186
+ "ina-date-picker__trigger-text--placeholder"
187
+ );
188
+ }
189
+ } else if (mode === "range") {
190
+ if (rangeDate[0] && rangeDate[1]) {
191
+ const start = formatDate(rangeDate[0]);
192
+ const end = formatDate(rangeDate[1]);
193
+ triggerText.textContent = `${start} - ${end}`;
194
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
195
+ triggerText.classList.remove(
196
+ "ina-date-picker__trigger-text--placeholder"
197
+ );
198
+ } else if (rangeDate[0]) {
199
+ triggerText.textContent = `${formatDate(rangeDate[0])} - ...`;
200
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
201
+ } else {
202
+ triggerText.textContent = "Pilih Rentang Tanggal";
203
+ triggerText.classList.remove("ina-date-picker__trigger-text--value");
204
+ triggerText.classList.add(
205
+ "ina-date-picker__trigger-text--placeholder"
206
+ );
207
+ }
208
+ } else if (mode === "multiple") {
209
+ if (selectedDates.length > 0) {
210
+ triggerText.textContent = `${selectedDates.length} Tanggal Terpilih`;
211
+ triggerText.classList.add("ina-date-picker__trigger-text--value");
212
+ triggerText.classList.remove(
213
+ "ina-date-picker__trigger-text--placeholder"
214
+ );
215
+ } else {
216
+ triggerText.textContent = "Pilih Beberapa Tanggal";
217
+ triggerText.classList.remove("ina-date-picker__trigger-text--value");
218
+ triggerText.classList.add(
219
+ "ina-date-picker__trigger-text--placeholder"
220
+ );
221
+ }
165
222
  }
223
+ }
224
+ function createIcon(name, size = 16) {
225
+ if (name === "chevron-left")
226
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6l6 6" /></svg>`;
227
+ if (name === "chevron-right")
228
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6l6 6l-6 6" /></svg>`;
166
229
  return "";
167
230
  }
168
231
  function createMonthPicker(initialMonth, onChange) {
@@ -173,16 +236,10 @@ function initDatepicker() {
173
236
  const pickerTrigger = document.createElement("button");
174
237
  pickerTrigger.type = "button";
175
238
  pickerTrigger.className = "ina-month-picker__trigger ina-month-picker__trigger--size-sm";
176
- const updateTriggerText = () => {
177
- pickerTrigger.innerHTML = `
178
- <span class="ina-month-picker__trigger-text">${MONTHS_SHORT_ID[currentMonthIdx]}</span>
179
- `;
239
+ const updateText = () => {
240
+ pickerTrigger.innerHTML = `<span class="ina-month-picker__trigger-text">${MONTHS_SHORT_ID[currentMonthIdx]}</span>`;
180
241
  };
181
- updateTriggerText();
182
- pickerTrigger.addEventListener("click", (e) => {
183
- e.stopPropagation();
184
- togglePicker(!isPickerOpen);
185
- });
242
+ updateText();
186
243
  const pickerPanel = document.createElement("div");
187
244
  pickerPanel.className = "ina-month-picker__panel";
188
245
  const grid = document.createElement("div");
@@ -197,21 +254,18 @@ function initDatepicker() {
197
254
  btn.addEventListener("click", (e) => {
198
255
  e.stopPropagation();
199
256
  currentMonthIdx = idx;
200
- updateTriggerText();
201
- grid.querySelectorAll(".ina-month-picker__month-option").forEach((b, i) => {
202
- if (i === idx)
203
- b.classList.add("ina-month-picker__month-option--selected");
204
- else
205
- b.classList.remove("ina-month-picker__month-option--selected");
206
- });
257
+ updateText();
207
258
  togglePicker(false);
208
259
  onChange(idx);
209
260
  });
210
261
  grid.appendChild(btn);
211
262
  });
212
263
  pickerPanel.appendChild(grid);
213
- container.appendChild(pickerTrigger);
214
- container.appendChild(pickerPanel);
264
+ container.append(pickerTrigger, pickerPanel);
265
+ pickerTrigger.addEventListener("click", (e) => {
266
+ e.stopPropagation();
267
+ togglePicker(!isPickerOpen);
268
+ });
215
269
  function togglePicker(show) {
216
270
  isPickerOpen = show;
217
271
  if (show) {
@@ -229,13 +283,7 @@ function initDatepicker() {
229
283
  element: container,
230
284
  setMonth: (m) => {
231
285
  currentMonthIdx = m;
232
- updateTriggerText();
233
- grid.querySelectorAll(".ina-month-picker__month-option").forEach((b, i) => {
234
- if (i === m)
235
- b.classList.add("ina-month-picker__month-option--selected");
236
- else
237
- b.classList.remove("ina-month-picker__month-option--selected");
238
- });
286
+ updateText();
239
287
  }
240
288
  };
241
289
  }
@@ -248,16 +296,10 @@ function initDatepicker() {
248
296
  const pickerTrigger = document.createElement("button");
249
297
  pickerTrigger.type = "button";
250
298
  pickerTrigger.className = "ina-year-picker__trigger ina-year-picker__trigger--size-sm";
251
- const updateTriggerText = () => {
252
- pickerTrigger.innerHTML = `
253
- <span class="ina-year-picker__trigger-text">${currentYearVal}</span>
254
- `;
299
+ const updateText = () => {
300
+ pickerTrigger.innerHTML = `<span class="ina-year-picker__trigger-text">${currentYearVal}</span>`;
255
301
  };
256
- updateTriggerText();
257
- pickerTrigger.addEventListener("click", (e) => {
258
- e.stopPropagation();
259
- togglePicker(!isPickerOpen);
260
- });
302
+ updateText();
261
303
  const pickerPanel = document.createElement("div");
262
304
  pickerPanel.className = "ina-year-picker__panel";
263
305
  const header = document.createElement("div");
@@ -298,7 +340,7 @@ function initDatepicker() {
298
340
  btn.addEventListener("click", (e) => {
299
341
  e.stopPropagation();
300
342
  currentYearVal = y;
301
- updateTriggerText();
343
+ updateText();
302
344
  togglePicker(false);
303
345
  onChange(y);
304
346
  });
@@ -307,16 +349,18 @@ function initDatepicker() {
307
349
  }
308
350
  pickerPanel.append(header, grid);
309
351
  container.append(pickerTrigger, pickerPanel);
352
+ pickerTrigger.addEventListener("click", (e) => {
353
+ e.stopPropagation();
354
+ togglePicker(!isPickerOpen);
355
+ });
310
356
  function togglePicker(show) {
311
357
  isPickerOpen = show;
312
358
  if (show) {
313
359
  decadeStart = Math.floor(currentYearVal / 20) * 20;
314
360
  renderGrid();
315
361
  pickerPanel.classList.add("ina-year-picker__panel--open");
316
- pickerTrigger.setAttribute("aria-expanded", "true");
317
362
  } else {
318
363
  pickerPanel.classList.remove("ina-year-picker__panel--open");
319
- pickerTrigger.setAttribute("aria-expanded", "false");
320
364
  }
321
365
  }
322
366
  document.addEventListener("click", (e) => {
@@ -326,131 +370,212 @@ function initDatepicker() {
326
370
  element: container,
327
371
  setYear: (y) => {
328
372
  currentYearVal = y;
329
- updateTriggerText();
373
+ updateText();
330
374
  }
331
375
  };
332
376
  }
333
- function renderCalendar() {
334
- panelContent.innerHTML = "";
335
- const year = currentDate.getFullYear();
336
- const month = currentDate.getMonth();
337
- const calendarContainer = document.createElement("div");
338
- calendarContainer.className = "ina-date-picker__calendar-container";
377
+ function renderCalendarGrid(baseDate, isNextMonth = false) {
378
+ const year = baseDate.getFullYear();
379
+ const month = baseDate.getMonth();
380
+ const container = document.createElement("div");
381
+ if (!isNextMonth) {
382
+ container.className = "ina-date-picker__calendar-container";
383
+ } else {
384
+ container.className = "ina-date-picker__calendar";
385
+ }
339
386
  const header = document.createElement("div");
340
- header.className = "ina-date-picker__calendar-header";
341
- const prevBtn = document.createElement("button");
342
- prevBtn.className = "ina-date-picker__nav-button";
343
- prevBtn.type = "button";
344
- prevBtn.innerHTML = createIcon("chevron-left", 20);
345
- prevBtn.addEventListener("click", (e) => {
346
- e.stopPropagation();
347
- currentDate.setMonth(month - 1);
348
- renderCalendar();
349
- });
350
- const nextBtn = document.createElement("button");
351
- nextBtn.className = "ina-date-picker__nav-button";
352
- nextBtn.type = "button";
353
- nextBtn.innerHTML = createIcon("chevron-right", 20);
354
- nextBtn.addEventListener("click", (e) => {
355
- e.stopPropagation();
356
- currentDate.setMonth(month + 1);
357
- renderCalendar();
358
- });
359
- const controls = document.createElement("div");
360
- controls.className = "ina-date-picker__header-controls";
361
- const monthContainer = document.createElement("div");
362
- monthContainer.className = "ina-date-picker__dropdown-container";
363
- const monthPicker = createMonthPicker(month, (newMonth) => {
364
- currentDate.setMonth(newMonth);
365
- renderCalendar();
366
- });
367
- monthContainer.appendChild(monthPicker.element);
368
- const yearContainer = document.createElement("div");
369
- yearContainer.className = "ina-date-picker__dropdown-container";
370
- const yearPicker = createYearPicker(year, (newYear) => {
371
- currentDate.setFullYear(newYear);
372
- renderCalendar();
373
- });
374
- yearContainer.appendChild(yearPicker.element);
375
- controls.append(monthContainer, yearContainer);
376
- header.append(prevBtn, controls, nextBtn);
387
+ header.className = isNextMonth ? "ina-date-picker__next-month-header" : "ina-date-picker__calendar-header";
388
+ if (!isNextMonth) {
389
+ const prevBtn = document.createElement("button");
390
+ prevBtn.type = "button";
391
+ prevBtn.className = "ina-date-picker__nav-button";
392
+ prevBtn.innerHTML = createIcon("chevron-left");
393
+ prevBtn.onclick = (e) => {
394
+ e.stopPropagation();
395
+ viewDate.setMonth(viewDate.getMonth() - 1);
396
+ render();
397
+ };
398
+ header.appendChild(prevBtn);
399
+ } else {
400
+ const spacer = document.createElement("div");
401
+ spacer.style.width = "32px";
402
+ header.appendChild(spacer);
403
+ }
404
+ if (!isNextMonth) {
405
+ const controls = document.createElement("div");
406
+ controls.className = "ina-date-picker__header-controls";
407
+ const monthCont = document.createElement("div");
408
+ monthCont.className = "ina-date-picker__dropdown-container";
409
+ const monthPicker = createMonthPicker(month, (m) => {
410
+ viewDate.setMonth(m);
411
+ render();
412
+ });
413
+ monthCont.appendChild(monthPicker.element);
414
+ const yearCont = document.createElement("div");
415
+ yearCont.className = "ina-date-picker__dropdown-container";
416
+ const yearPicker = createYearPicker(year, (y) => {
417
+ viewDate.setFullYear(y);
418
+ render();
419
+ });
420
+ yearCont.appendChild(yearPicker.element);
421
+ controls.append(monthCont, yearCont);
422
+ header.appendChild(controls);
423
+ } else {
424
+ const title = document.createElement("div");
425
+ title.className = "ina-date-picker__calendar-title";
426
+ title.textContent = `${MONTHS_ID[month]} ${year}`;
427
+ header.appendChild(title);
428
+ }
429
+ const showNextBtn = mode === "single" && !isNextMonth || isNextMonth;
430
+ if (showNextBtn) {
431
+ const nextBtn = document.createElement("button");
432
+ nextBtn.type = "button";
433
+ nextBtn.className = "ina-date-picker__nav-button";
434
+ nextBtn.innerHTML = createIcon("chevron-right");
435
+ nextBtn.onclick = (e) => {
436
+ e.stopPropagation();
437
+ viewDate.setMonth(viewDate.getMonth() + 1);
438
+ render();
439
+ };
440
+ header.appendChild(nextBtn);
441
+ } else if (!isNextMonth) {
442
+ const spacer = document.createElement("div");
443
+ spacer.style.width = "32px";
444
+ header.appendChild(spacer);
445
+ }
377
446
  const grid = document.createElement("div");
378
447
  grid.className = "ina-date-picker__calendar-grid";
379
- DAYS_SHORT.forEach((day) => {
448
+ DAYS_SHORT.forEach((d) => {
380
449
  const dh = document.createElement("div");
381
450
  dh.className = "ina-date-picker__day-header";
382
- dh.textContent = day;
451
+ dh.textContent = d;
383
452
  grid.appendChild(dh);
384
453
  });
385
454
  const firstDayOfMonth = new Date(year, month, 1).getDay();
386
455
  const daysInMonth = new Date(year, month + 1, 0).getDate();
387
456
  const daysInPrevMonth = new Date(year, month, 0).getDate();
457
+ const today = /* @__PURE__ */ new Date();
388
458
  for (let i = firstDayOfMonth - 1; i >= 0; i--) {
389
- const dayBtn = document.createElement("button");
390
- dayBtn.type = "button";
391
- dayBtn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
392
- dayBtn.textContent = daysInPrevMonth - i;
393
- grid.appendChild(dayBtn);
459
+ const btn = document.createElement("button");
460
+ btn.type = "button";
461
+ btn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
462
+ btn.textContent = daysInPrevMonth - i;
463
+ grid.appendChild(btn);
394
464
  }
395
- const today = /* @__PURE__ */ new Date();
396
465
  for (let i = 1; i <= daysInMonth; i++) {
397
- const dayBtn = document.createElement("button");
398
- dayBtn.type = "button";
399
- dayBtn.className = "ina-date-picker__day";
400
- dayBtn.textContent = i;
466
+ const date = new Date(year, month, i);
467
+ const btn = document.createElement("button");
468
+ btn.type = "button";
469
+ btn.className = "ina-date-picker__day";
470
+ btn.textContent = i;
401
471
  let isSelected = false;
402
- if (selectedDate && selectedDate.getDate() === i && selectedDate.getMonth() === month && selectedDate.getFullYear() === year) {
403
- dayBtn.classList.add("ina-date-picker__day--selected");
404
- isSelected = true;
405
- }
406
- if (today.getDate() === i && today.getMonth() === month && today.getFullYear() === year) {
407
- dayBtn.classList.add("ina-date-picker__day--today");
472
+ let isInRange = false;
473
+ if (mode === "single" && selectedDate) {
474
+ if (date.toDateString() === selectedDate.toDateString())
475
+ isSelected = true;
476
+ } else if (mode === "multiple") {
477
+ if (selectedDates.some((d) => d.toDateString() === date.toDateString()))
478
+ isSelected = true;
479
+ } else if (mode === "range") {
480
+ const [start, end] = rangeDate;
481
+ if (start && date.toDateString() === start.toDateString())
482
+ isSelected = true;
483
+ if (end && date.toDateString() === end.toDateString())
484
+ isSelected = true;
485
+ if (start && end && date > start && date < end) isInRange = true;
408
486
  }
409
- if (!isSelected) {
410
- dayBtn.classList.add("ina-date-picker__day--hover");
411
- }
412
- dayBtn.addEventListener("click", (e) => {
487
+ if (isSelected) btn.classList.add("ina-date-picker__day--selected");
488
+ if (isInRange) btn.classList.add("ina-date-picker__day--in-range");
489
+ if (date.toDateString() === today.toDateString())
490
+ btn.classList.add("ina-date-picker__day--today");
491
+ if (!isSelected && !isInRange)
492
+ btn.classList.add("ina-date-picker__day--hover");
493
+ btn.onclick = (e) => {
413
494
  e.stopPropagation();
414
- selectedDate = new Date(year, month, i);
415
- triggerText.textContent = formatDate(selectedDate);
416
- triggerText.classList.add("ina-date-picker__trigger-text--value");
417
- triggerText.classList.remove(
418
- "ina-date-picker__trigger-text--placeholder"
419
- );
495
+ if (mode === "single") {
496
+ selectedDate = date;
497
+ close();
498
+ } else if (mode === "multiple") {
499
+ const existsIdx = selectedDates.findIndex(
500
+ (d) => d.toDateString() === date.toDateString()
501
+ );
502
+ if (existsIdx >= 0) selectedDates.splice(existsIdx, 1);
503
+ else selectedDates.push(date);
504
+ render();
505
+ } else if (mode === "range") {
506
+ const [start, end] = rangeDate;
507
+ if (!start || start && end) {
508
+ rangeDate = [date, null];
509
+ } else {
510
+ if (date < start) {
511
+ rangeDate = [date, start];
512
+ } else {
513
+ rangeDate = [start, date];
514
+ }
515
+ close();
516
+ }
517
+ render();
518
+ }
519
+ updateTrigger();
420
520
  datepicker.dispatchEvent(
421
- new CustomEvent("date:changed", { detail: { selectedDate } })
521
+ new CustomEvent("date:changed", {
522
+ detail: {
523
+ selectedDate: mode === "single" ? selectedDate : mode === "multiple" ? selectedDates : rangeDate
524
+ }
525
+ })
422
526
  );
423
- toggle(false);
424
- });
425
- grid.appendChild(dayBtn);
527
+ };
528
+ grid.appendChild(btn);
426
529
  }
427
- const currentCells = grid.children.length - 7;
428
- const remaining = 42 - currentCells;
530
+ const usedCells = grid.children.length - 7;
531
+ const remaining = 42 - usedCells;
429
532
  for (let i = 1; i <= remaining; i++) {
430
- const dayBtn = document.createElement("button");
431
- dayBtn.type = "button";
432
- dayBtn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
433
- dayBtn.textContent = i;
434
- grid.appendChild(dayBtn);
533
+ const btn = document.createElement("button");
534
+ btn.type = "button";
535
+ btn.className = "ina-date-picker__day ina-date-picker__day--other-month ina-date-picker__day--disabled";
536
+ btn.textContent = i;
537
+ grid.appendChild(btn);
435
538
  }
436
- calendarContainer.append(header, grid);
437
- panelContent.appendChild(calendarContainer);
539
+ container.append(header, grid);
540
+ return container;
438
541
  }
439
- function toggle(show) {
440
- isOpen = show;
441
- if (show) {
442
- panel.classList.add("ina-date-picker__panel--open");
443
- renderCalendar();
444
- } else {
445
- panel.classList.remove("ina-date-picker__panel--open");
542
+ function render() {
543
+ panelContent.innerHTML = "";
544
+ const cal1 = renderCalendarGrid(viewDate);
545
+ panelContent.appendChild(cal1);
546
+ if (mode === "range" || mode === "multiple") {
547
+ const nextMonthDate = new Date(
548
+ viewDate.getFullYear(),
549
+ viewDate.getMonth() + 1,
550
+ 1
551
+ );
552
+ const cal2 = renderCalendarGrid(nextMonthDate, true);
553
+ panelContent.appendChild(cal2);
446
554
  }
447
555
  }
556
+ function open() {
557
+ isOpen = true;
558
+ panel.classList.add("ina-date-picker__panel--open");
559
+ panel.style.display = "block";
560
+ render();
561
+ }
562
+ function close() {
563
+ isOpen = false;
564
+ panel.classList.remove("ina-date-picker__panel--open");
565
+ panel.style.display = "none";
566
+ }
567
+ function toggle() {
568
+ if (isOpen) close();
569
+ else open();
570
+ }
448
571
  trigger.addEventListener("click", (e) => {
449
572
  e.stopPropagation();
450
- toggle(!isOpen);
573
+ toggle();
451
574
  });
452
575
  document.addEventListener("click", (e) => {
453
- if (!datepicker.contains(e.target)) toggle(false);
576
+ if (!datepicker.contains(e.target)) {
577
+ close();
578
+ }
454
579
  });
455
580
  });
456
581
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idds/js",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },