@idds/js 1.0.68 → 1.0.69

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 +1183 -720
  2. package/dist/index.js +281 -195
  3. package/package.json +1 -1
@@ -23,6 +23,7 @@ var InaUI = (() => {
23
23
  initAccordion: () => initAccordion,
24
24
  initButtonGroup: () => initButtonGroup,
25
25
  initCheckbox: () => initCheckbox,
26
+ initChip: () => initChip,
26
27
  initDatepicker: () => initDatepicker,
27
28
  initDropdown: () => initDropdown,
28
29
  initFileUpload: () => initFileUpload,
@@ -30,7 +31,10 @@ var InaUI = (() => {
30
31
  initFileUploadItem: () => initFileUploadItem,
31
32
  initImgCompare: () => initImgCompare,
32
33
  initModal: () => initModal,
34
+ initPagination: () => initPagination,
35
+ initRadioButton: () => initRadioButton,
33
36
  initRangeDatepicker: () => initRangeDatepicker,
37
+ initSelectDropdown: () => initSelectDropdown,
34
38
  initSingleFileUpload: () => initSingleFileUpload,
35
39
  initTab: () => initTab,
36
40
  initTimepicker: () => initTimepicker,
@@ -829,6 +833,197 @@ var InaUI = (() => {
829
833
  });
830
834
  }
831
835
 
836
+ // src/js/components/stateful/select-dropdown.js
837
+ var PREFIX2 = "ina";
838
+ function getDropdownState(root) {
839
+ return {
840
+ isOpen: root.getAttribute("data-state") === "open",
841
+ values: JSON.parse(root.getAttribute("data-values") || "[]"),
842
+ isMultiple: root.getAttribute("data-multiple") === "true",
843
+ isSearchable: root.getAttribute("data-searchable") !== "false"
844
+ };
845
+ }
846
+ function setDropdownState(root, newState) {
847
+ if (newState.isOpen !== void 0) {
848
+ root.setAttribute("data-state", newState.isOpen ? "open" : "closed");
849
+ const trigger = root.querySelector(`.${PREFIX2}-select-dropdown__trigger`);
850
+ if (trigger) trigger.setAttribute("aria-expanded", newState.isOpen);
851
+ const panel = root.querySelector(`.${PREFIX2}-select-dropdown__panel`);
852
+ if (panel) {
853
+ if (newState.isOpen) {
854
+ panel.style.removeProperty("display");
855
+ } else {
856
+ panel.style.display = "none";
857
+ }
858
+ }
859
+ }
860
+ if (newState.values !== void 0) {
861
+ root.setAttribute("data-values", JSON.stringify(newState.values));
862
+ updateTriggerUI(root, newState.values, newState.isMultiple);
863
+ }
864
+ }
865
+ function closeAllSelectDropdowns(exceptRoot = null) {
866
+ document.querySelectorAll(`.${PREFIX2}-select-dropdown[data-state="open"]`).forEach((root) => {
867
+ if (root !== exceptRoot) {
868
+ setDropdownState(root, { isOpen: false });
869
+ }
870
+ });
871
+ }
872
+ function updateTriggerUI(root, values, isMultiple) {
873
+ const trigger = root.querySelector(`.${PREFIX2}-select-dropdown__trigger`);
874
+ const input = trigger.querySelector("input");
875
+ const textSpan = trigger.querySelector(
876
+ `.${PREFIX2}-select-dropdown__trigger-text`
877
+ );
878
+ const placeholder = input ? input.getAttribute("placeholder") : textSpan ? textSpan.getAttribute("data-placeholder") : "Select...";
879
+ const options = root.querySelectorAll(`.${PREFIX2}-select-dropdown__option`);
880
+ const getLabel = (val) => {
881
+ const opt = Array.from(options).find(
882
+ (o) => o.getAttribute("data-value") === val
883
+ );
884
+ return opt ? opt.textContent.trim() : val;
885
+ };
886
+ let label = "";
887
+ if (values.length === 0) {
888
+ } else if (isMultiple) {
889
+ label = values.length > 3 ? `${values.length} data terpilih` : values.map(getLabel).join(", ");
890
+ } else {
891
+ label = getLabel(values[0]);
892
+ }
893
+ if (input) {
894
+ input.value = !isMultiple && values.length > 0 && root.getAttribute("data-state") !== "open" ? label : "";
895
+ if (values.length > 0) {
896
+ input.placeholder = label;
897
+ } else {
898
+ input.placeholder = "Select...";
899
+ }
900
+ } else if (textSpan) {
901
+ textSpan.textContent = values.length > 0 ? label : placeholder;
902
+ textSpan.classList.toggle(
903
+ `${PREFIX2}-select-dropdown__trigger-text--placeholder`,
904
+ values.length === 0
905
+ );
906
+ }
907
+ options.forEach((opt) => {
908
+ const val = opt.getAttribute("data-value");
909
+ const isSelected = values.includes(val);
910
+ if (isMultiple) {
911
+ opt.classList.toggle(
912
+ `${PREFIX2}-select-dropdown__option--selected-multiple`,
913
+ isSelected
914
+ );
915
+ const cb = opt.querySelector(
916
+ `.${PREFIX2}-select-dropdown__option-checkbox`
917
+ );
918
+ if (cb)
919
+ cb.classList.toggle(
920
+ `${PREFIX2}-select-dropdown__option-checkbox--checked`,
921
+ isSelected
922
+ );
923
+ } else {
924
+ opt.classList.toggle(
925
+ `${PREFIX2}-select-dropdown__option--selected-single`,
926
+ isSelected
927
+ );
928
+ }
929
+ });
930
+ }
931
+ function initSelectDropdown() {
932
+ if (window.__inaSelectDropdownInitialized) return;
933
+ document.addEventListener("click", (e) => {
934
+ const target = e.target;
935
+ const trigger = target.closest(`.${PREFIX2}-select-dropdown__trigger`);
936
+ const option = target.closest(`.${PREFIX2}-select-dropdown__option`);
937
+ const root = target.closest(`.${PREFIX2}-select-dropdown`);
938
+ if (trigger) {
939
+ if (root) {
940
+ const state = getDropdownState(root);
941
+ if (target.tagName === "INPUT" && state.isOpen) {
942
+ return;
943
+ }
944
+ closeAllSelectDropdowns(root);
945
+ setDropdownState(root, { isOpen: !state.isOpen });
946
+ if (!state.isOpen) {
947
+ const input = trigger.querySelector("input");
948
+ if (input) input.focus();
949
+ }
950
+ }
951
+ return;
952
+ }
953
+ if (option && root) {
954
+ const state = getDropdownState(root);
955
+ const val = option.getAttribute("data-value");
956
+ let newValues = [...state.values];
957
+ if (state.isMultiple) {
958
+ if (newValues.includes(val)) {
959
+ newValues = newValues.filter((v) => v !== val);
960
+ } else {
961
+ newValues.push(val);
962
+ }
963
+ setDropdownState(root, { values: newValues });
964
+ } else {
965
+ newValues = [val];
966
+ setDropdownState(root, { values: newValues, isOpen: false });
967
+ }
968
+ root.dispatchEvent(
969
+ new CustomEvent("change", {
970
+ detail: {
971
+ value: state.isMultiple ? newValues : newValues[0]
972
+ }
973
+ })
974
+ );
975
+ e.stopPropagation();
976
+ return;
977
+ }
978
+ if (!root) {
979
+ closeAllSelectDropdowns();
980
+ }
981
+ });
982
+ document.addEventListener("input", (e) => {
983
+ if (e.target.matches(`.${PREFIX2}-select-dropdown__trigger-input`)) {
984
+ const root = e.target.closest(`.${PREFIX2}-select-dropdown`);
985
+ if (root) {
986
+ const term = e.target.value.toLowerCase();
987
+ const options = root.querySelectorAll(
988
+ `.${PREFIX2}-select-dropdown__option`
989
+ );
990
+ if (root.getAttribute("data-state") !== "open") {
991
+ setDropdownState(root, { isOpen: true });
992
+ }
993
+ options.forEach((opt) => {
994
+ const text = opt.textContent.trim().toLowerCase();
995
+ opt.style.display = text.includes(term) ? "" : "none";
996
+ });
997
+ }
998
+ }
999
+ });
1000
+ window.__inaSelectDropdownInitialized = true;
1001
+ }
1002
+
1003
+ // src/js/components/stateful/radio-button.js
1004
+ function initRadioButton() {
1005
+ const radioGroups = document.querySelectorAll(`.${PREFIX}-radio-input`);
1006
+ radioGroups.forEach((group) => {
1007
+ if (group.dataset.initialized === "true") return;
1008
+ group.dataset.initialized = "true";
1009
+ const inputs = group.querySelectorAll('input[type="radio"]');
1010
+ const displayTargetId = group.dataset.displayTarget;
1011
+ const displayTarget = displayTargetId ? document.getElementById(displayTargetId) : null;
1012
+ const updateDisplay = () => {
1013
+ if (!displayTarget) return;
1014
+ const selected = Array.from(inputs).find((input) => input.checked);
1015
+ const value = selected ? selected.value : "";
1016
+ displayTarget.textContent = `Selected: ${value || "None"}`;
1017
+ };
1018
+ if (inputs.length > 0) {
1019
+ inputs.forEach((input) => {
1020
+ input.addEventListener("change", updateDisplay);
1021
+ });
1022
+ updateDisplay();
1023
+ }
1024
+ });
1025
+ }
1026
+
832
1027
  // src/js/components/stateful/file-upload.js
833
1028
  var ICONS = {
834
1029
  upload: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"></path><polyline points="16 6 12 2 8 6"></polyline><line x1="12" y1="2" x2="12" y2="16"></line></svg>`,
@@ -1352,103 +1547,468 @@ var InaUI = (() => {
1352
1547
  });
1353
1548
  }
1354
1549
 
1355
- // src/js/components/stateless/img-compare.js
1356
- function initImgCompare(rootSelector = `.${PREFIX}-img-compare`) {
1357
- document.querySelectorAll(rootSelector).forEach((imgCompare) => {
1358
- const sliderEl = document.createElement("input");
1359
- sliderEl.type = "range";
1360
- sliderEl.min = "0";
1361
- sliderEl.max = "100";
1362
- sliderEl.value = "50";
1363
- sliderEl.setAttribute("aria-label", "Percentage of the image to show");
1364
- sliderEl.setAttribute("aria-valuenow", "50");
1365
- sliderEl.setAttribute("aria-valuemin", "0");
1366
- sliderEl.setAttribute("aria-valuemax", "100");
1367
- sliderEl.classList.add("ina-ss-img__slider");
1368
- sliderEl.addEventListener("input", () => {
1369
- imgCompare.style.setProperty(
1370
- `--${PREFIX}-position`,
1371
- `${sliderEl.value}%`
1372
- );
1373
- });
1374
- const sliderLineEl = document.createElement("div");
1375
- sliderLineEl.classList.add("ina-ss-img__slider-line");
1376
- const sliderButtonEl = document.createElement("button");
1377
- sliderButtonEl.classList.add("ina-ss-img__slider-button");
1378
- imgCompare.appendChild(sliderEl);
1379
- imgCompare.appendChild(sliderLineEl);
1380
- imgCompare.appendChild(sliderButtonEl);
1381
- });
1382
- }
1383
-
1384
- // src/js/components/stateful/timepicker.js
1385
- function initTimepicker() {
1386
- document.querySelectorAll(`.${PREFIX}-time-picker`).forEach((picker) => {
1387
- if (picker.dataset.initialized === "true") return;
1388
- picker.dataset.initialized = "true";
1389
- const input = picker.querySelector(`.${PREFIX}-time-picker__input`);
1390
- const wrapper = picker.querySelector(`.${PREFIX}-time-picker__wrapper`);
1391
- if (!input || !wrapper) return;
1392
- const format = picker.dataset.format || "HH:mm";
1393
- const use12Hours = picker.dataset.use12Hours === "true" || picker.getAttribute("data-use-12-hours") === "true" || /a/i.test(format);
1394
- const showSecond = picker.dataset.showSecond === "true";
1395
- const disabled = picker.classList.contains(
1396
- `${PREFIX}-time-picker--disabled`
1550
+ // src/js/components/stateful/range-datepicker.js
1551
+ function initRangeDatepicker() {
1552
+ document.querySelectorAll(".ina-ss-range-datepicker").forEach((rangeDatepicker) => {
1553
+ let currentDate = /* @__PURE__ */ new Date();
1554
+ let currentDateLeft = /* @__PURE__ */ new Date();
1555
+ let currentDateRight = new Date(
1556
+ currentDateLeft.getFullYear(),
1557
+ currentDateLeft.getMonth() + 1,
1558
+ currentDateLeft.getDate()
1397
1559
  );
1398
- const allowClear = picker.dataset.allowClear !== "false";
1399
- let isOpen = false;
1400
- let internalValue = input.value || "";
1401
- let panel = picker.querySelector(`.${PREFIX}-time-picker__panel`);
1402
- if (!panel) {
1403
- panel = document.createElement("div");
1404
- panel.className = `${PREFIX}-time-picker__panel`;
1405
- panel.style.display = "none";
1406
- picker.appendChild(panel);
1407
- }
1408
- let content = panel.querySelector(`.${PREFIX}-time-picker__content`);
1409
- if (!content) {
1410
- content = document.createElement("div");
1411
- content.className = `${PREFIX}-time-picker__content`;
1412
- panel.appendChild(content);
1413
- } else {
1414
- content.innerHTML = "";
1415
- }
1416
- let actions = panel.querySelector(`.${PREFIX}-time-picker__actions`);
1417
- if (!actions) {
1418
- actions = document.createElement("div");
1419
- actions.className = `${PREFIX}-time-picker__actions`;
1420
- const confirmBtn = document.createElement("button");
1421
- confirmBtn.type = "button";
1422
- confirmBtn.className = `${PREFIX}-time-picker__confirm-button`;
1423
- confirmBtn.textContent = "Pilih";
1424
- confirmBtn.onclick = (e) => {
1425
- e.stopPropagation();
1426
- close();
1427
- };
1428
- actions.appendChild(confirmBtn);
1429
- panel.appendChild(actions);
1430
- }
1431
- const parseTime = (timeStr) => {
1432
- if (!timeStr) return { hours: 0, minutes: 0, seconds: 0, period: "AM" };
1433
- let hours = 0, minutes = 0, seconds = 0, period = "AM";
1434
- try {
1435
- if (use12Hours) {
1436
- const [time, p] = timeStr.split(" ");
1437
- const [h, m, s] = time.split(":");
1438
- hours = parseInt(h || "0", 10);
1439
- minutes = parseInt(m || "0", 10);
1440
- seconds = parseInt(s || "0", 10);
1441
- period = p || "AM";
1442
- } else {
1443
- const [h, m, s] = timeStr.split(":");
1444
- hours = parseInt(h || "0", 10);
1445
- minutes = parseInt(m || "0", 10);
1446
- seconds = parseInt(s || "0", 10);
1447
- }
1448
- } catch (e) {
1449
- console.warn("Invalid time format", timeStr);
1560
+ let selectedDateTarget = null;
1561
+ let fromSelectedDate = null;
1562
+ let toSelectedDate = null;
1563
+ let selectedDate = null;
1564
+ const MONTHS = [
1565
+ "Januari",
1566
+ "Februari",
1567
+ "Maret",
1568
+ "April",
1569
+ "Mei",
1570
+ "Juni",
1571
+ "Juli",
1572
+ "Agustus",
1573
+ "September",
1574
+ "Oktober",
1575
+ "November",
1576
+ "Desember"
1577
+ ];
1578
+ const DAYS = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"];
1579
+ const rangeDatepickerTrigger = rangeDatepicker.querySelector(
1580
+ `.ina-ss-range-datepicker__trigger`
1581
+ );
1582
+ const rangeDatepickerPopover = rangeDatepicker.querySelector(
1583
+ `.ina-ss-range-datepicker__popover`
1584
+ );
1585
+ const datePickerLeftDate = rangeDatepicker.querySelector(
1586
+ `.ina-ss-range-datepicker__left-date`
1587
+ );
1588
+ const datePickerRightDate = rangeDatepicker.querySelector(
1589
+ `.ina-ss-range-datepicker__right-date`
1590
+ );
1591
+ const datepickerMonthLeftTrigger = datePickerLeftDate.querySelector(
1592
+ `.ina-ss-range-datepicker__month-trigger`
1593
+ );
1594
+ const datepickerMonthRightTrigger = datePickerRightDate.querySelector(
1595
+ `.ina-ss-range-datepicker__month-trigger`
1596
+ );
1597
+ const datepickerLeftContent = datePickerLeftDate.querySelector(
1598
+ `.ina-ss-range-datepicker__content`
1599
+ );
1600
+ const datepickerRightContent = datePickerRightDate.querySelector(
1601
+ `.ina-ss-range-datepicker__content`
1602
+ );
1603
+ const prevMonthButtonLeft = datePickerLeftDate.querySelector(
1604
+ `.ina-ss-range-datepicker__nav-prev`
1605
+ );
1606
+ const nextMonthButtonLeft = datePickerLeftDate.querySelector(
1607
+ `.ina-ss-range-datepicker__nav-next`
1608
+ );
1609
+ const prevMonthButtonRight = datePickerRightDate.querySelector(
1610
+ `.ina-ss-range-datepicker__nav-prev`
1611
+ );
1612
+ const nextMonthButtonRight = datePickerRightDate.querySelector(
1613
+ `.ina-ss-range-datepicker__nav-next`
1614
+ );
1615
+ function renderCalendar(targetEl, year, month) {
1616
+ const rangeDatepickerMonthTrigger = targetEl.querySelector(
1617
+ `.ina-ss-range-datepicker__month-trigger`
1618
+ );
1619
+ const rangeDatepickerMonthPopover = targetEl.querySelector(
1620
+ `.ina-ss-range-datepicker__month-popover`
1621
+ );
1622
+ const rangeDatepickerMonthItem = targetEl.querySelectorAll(
1623
+ `.ina-ss-range-datepicker__month-item`
1624
+ );
1625
+ const rangeDatepickerYearTrigger = targetEl.querySelector(
1626
+ `.ina-ss-range-datepicker__year-trigger`
1627
+ );
1628
+ const targetContentEl = targetEl.querySelector(
1629
+ `.ina-ss-range-datepicker__content`
1630
+ );
1631
+ targetContentEl.innerHTML = "";
1632
+ rangeDatepickerMonthTrigger.textContent = MONTHS[month].substring(0, 3);
1633
+ rangeDatepickerYearTrigger.textContent = year;
1634
+ DAYS.forEach((day) => {
1635
+ const dayNameWrapper = document.createElement("div");
1636
+ dayNameWrapper.className = `ina-ss-range-datepicker__dayname-wrapper`;
1637
+ const dayNameEl = document.createElement("span");
1638
+ dayNameEl.className = `ina-ss-range-datepicker__dayname`;
1639
+ dayNameEl.textContent = day.substring(0, 3);
1640
+ dayNameWrapper.appendChild(dayNameEl);
1641
+ targetContentEl.appendChild(dayNameWrapper);
1642
+ });
1643
+ const firstDayOfMonth = new Date(year, month, 1).getDay();
1644
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
1645
+ const daysInPrevMonth = new Date(year, month, 0).getDate();
1646
+ for (let i = 0; i < firstDayOfMonth; i++) {
1647
+ const dayEl = document.createElement("button");
1648
+ dayEl.className = `ina-ss-range-datepicker__calendar-day outside-month`;
1649
+ dayEl.textContent = daysInPrevMonth - firstDayOfMonth + 1 + i;
1650
+ dayEl.disabled = true;
1651
+ targetContentEl.appendChild(dayEl);
1450
1652
  }
1451
- return { hours, minutes, seconds, period };
1653
+ const today = /* @__PURE__ */ new Date();
1654
+ for (let i = 1; i <= daysInMonth; i++) {
1655
+ const dayEl = document.createElement("button");
1656
+ dayEl.className = `ina-ss-range-datepicker__calendar-day`;
1657
+ dayEl.textContent = i;
1658
+ dayEl.dataset.date = new Date(year, month, i).toISOString();
1659
+ if (fromSelectedDate && new Date(year, month, i).getTime() === fromSelectedDate?.getTime()) {
1660
+ dayEl.classList.add("selected-from");
1661
+ }
1662
+ if (toSelectedDate && new Date(year, month, i).getTime() === toSelectedDate?.getTime()) {
1663
+ dayEl.classList.add("selected-to");
1664
+ }
1665
+ if (toSelectedDate && new Date(year, month, i) === toSelectedDate) {
1666
+ dayEl.classList.add("selected-to");
1667
+ }
1668
+ if (fromSelectedDate && toSelectedDate && new Date(year, month, i) > fromSelectedDate && new Date(year, month, i) < toSelectedDate) {
1669
+ dayEl.classList.add("selected-range");
1670
+ }
1671
+ if (year === today.getFullYear() && month === today.getMonth() && i === today.getDate()) {
1672
+ const marker = document.createElement("span");
1673
+ marker.className = `ina-ss-range-datepicker__today-marker`;
1674
+ marker.textContent = "Hari ini";
1675
+ dayEl.appendChild(marker);
1676
+ dayEl.classList.add("today");
1677
+ }
1678
+ if (selectedDate && year === selectedDate.getFullYear() && month === selectedDate.getMonth() && i === selectedDate.getDate()) {
1679
+ dayEl.classList.add("selected");
1680
+ }
1681
+ targetContentEl.appendChild(dayEl);
1682
+ }
1683
+ const totalCells = 42;
1684
+ const cellsRendered = firstDayOfMonth + daysInMonth;
1685
+ const remainingCells = totalCells - cellsRendered;
1686
+ for (let i = 1; i <= remainingCells; i++) {
1687
+ const dayEl = document.createElement("button");
1688
+ dayEl.className = `ina-ss-range-datepicker__calendar-day outside-month`;
1689
+ dayEl.textContent = i;
1690
+ dayEl.disabled = true;
1691
+ targetContentEl.appendChild(dayEl);
1692
+ }
1693
+ }
1694
+ function handleChangeDate(target) {
1695
+ if (fromSelectedDate && toSelectedDate) {
1696
+ if (target.classList.contains(
1697
+ `ina-ss-range-datepicker__calendar-day`
1698
+ ) && !target.classList.contains("outside-month")) {
1699
+ const targetDate = new Date(target.dataset.date);
1700
+ if (target.classList.contains("selected-from") || target.classList.contains("selected-to")) {
1701
+ const fromSelectedDateLeftEl = datepickerLeftContent.querySelector(
1702
+ `.ina-ss-range-datepicker__calendar-day.selected-from`
1703
+ );
1704
+ const fromSelectedDateRightEl = datepickerRightContent.querySelector(
1705
+ `.ina-ss-range-datepicker__calendar-day.selected-from`
1706
+ );
1707
+ fromSelectedDateLeftEl?.classList.remove("selected-from");
1708
+ fromSelectedDateRightEl?.classList.remove("selected-from");
1709
+ const toSelectedDateLeftEl = datepickerLeftContent.querySelector(
1710
+ `.ina-ss-range-datepicker__calendar-day.selected-to`
1711
+ );
1712
+ const toSelectedDateRightEl = datepickerRightContent.querySelector(
1713
+ `.ina-ss-range-datepicker__calendar-day.selected-to`
1714
+ );
1715
+ toSelectedDateLeftEl?.classList.remove("selected-to");
1716
+ toSelectedDateRightEl?.classList.remove("selected-to");
1717
+ target.classList.add("selected-from");
1718
+ target.classList.add("selected-to");
1719
+ fromSelectedDate = targetDate;
1720
+ toSelectedDate = targetDate;
1721
+ }
1722
+ if (targetDate < fromSelectedDate) {
1723
+ const fromSelectedDateLeftEl = datepickerLeftContent.querySelector(
1724
+ `.ina-ss-range-datepicker__calendar-day.selected-from`
1725
+ );
1726
+ const fromSelectedDateRightEl = datepickerRightContent.querySelector(
1727
+ `.ina-ss-range-datepicker__calendar-day.selected-from`
1728
+ );
1729
+ fromSelectedDateLeftEl?.classList.remove("selected-from");
1730
+ fromSelectedDateRightEl?.classList.remove("selected-from");
1731
+ fromSelectedDate = targetDate;
1732
+ target.classList.add("selected-from");
1733
+ }
1734
+ if (targetDate > toSelectedDate || targetDate > fromSelectedDate) {
1735
+ const toSelectedDateLeftEl = datepickerLeftContent.querySelector(
1736
+ `.ina-ss-range-datepicker__calendar-day.selected-to`
1737
+ );
1738
+ const toSelectedDateRightEl = datepickerRightContent.querySelector(
1739
+ `.ina-ss-range-datepicker__calendar-day.selected-to`
1740
+ );
1741
+ toSelectedDateLeftEl?.classList.remove("selected-to");
1742
+ toSelectedDateRightEl?.classList.remove("selected-to");
1743
+ toSelectedDate = targetDate;
1744
+ target.classList.add("selected-to");
1745
+ }
1746
+ const leftDays = datepickerLeftContent.querySelectorAll(
1747
+ ".ina-ss-range-datepicker__calendar-day"
1748
+ );
1749
+ const rightDays = datepickerRightContent.querySelectorAll(
1750
+ ".ina-ss-range-datepicker__calendar-day"
1751
+ );
1752
+ const leftDaysArray = Array.from(leftDays);
1753
+ const rightDaysArray = Array.from(rightDays);
1754
+ const leftFromIndex = leftDaysArray.findIndex(
1755
+ (btn) => btn.classList.contains("selected-from")
1756
+ );
1757
+ const rightFromIndex = rightDaysArray.findIndex(
1758
+ (btn) => btn.classList.contains("selected-from")
1759
+ );
1760
+ const leftToIndex = leftDaysArray.findIndex(
1761
+ (btn) => btn.classList.contains("selected-to")
1762
+ );
1763
+ const rightToIndex = rightDaysArray.findIndex(
1764
+ (btn) => btn.classList.contains("selected-to")
1765
+ );
1766
+ leftDaysArray.forEach(
1767
+ (btn) => btn.classList.remove("selected-range")
1768
+ );
1769
+ rightDaysArray.forEach(
1770
+ (btn) => btn.classList.remove("selected-range")
1771
+ );
1772
+ if (leftFromIndex !== -1 && leftToIndex !== -1 && rightFromIndex === -1 && rightToIndex === -1) {
1773
+ for (let i = leftFromIndex + 1; i <= leftToIndex - 1; i++) {
1774
+ leftDaysArray[i].classList.add("selected-range");
1775
+ }
1776
+ }
1777
+ if (leftFromIndex !== -1 && rightToIndex !== -1) {
1778
+ for (let i = leftFromIndex + 1; i < leftDaysArray.length; i++) {
1779
+ leftDaysArray[i].classList.add("selected-range");
1780
+ }
1781
+ for (let i = 0; i < rightToIndex; i++) {
1782
+ rightDaysArray[i].classList.add("selected-range");
1783
+ }
1784
+ }
1785
+ if (leftFromIndex === -1 && leftToIndex === -1 && rightFromIndex !== -1 && rightToIndex !== -1) {
1786
+ for (let i = rightFromIndex + 1; i <= rightToIndex - 1; i++) {
1787
+ rightDaysArray[i].classList.add("selected-range");
1788
+ }
1789
+ }
1790
+ }
1791
+ } else {
1792
+ if (target.classList.contains(
1793
+ `ina-ss-range-datepicker__calendar-day`
1794
+ ) && !target.classList.contains("outside-month")) {
1795
+ if (target.classList.contains("selected-from") && target.classList.contains("selected-to")) {
1796
+ target.classList.remove("selected-from");
1797
+ target.classList.remove("selected-to");
1798
+ selectedDateTarget = null;
1799
+ } else {
1800
+ target.classList.add("selected-from");
1801
+ target.classList.add("selected-to");
1802
+ selectedDateTarget = target;
1803
+ }
1804
+ fromSelectedDate = selectedDateTarget ? new Date(selectedDateTarget.dataset.date) : null;
1805
+ toSelectedDate = selectedDateTarget ? new Date(selectedDateTarget.dataset.date) : null;
1806
+ }
1807
+ }
1808
+ rangeDatepicker.dispatchEvent(
1809
+ new CustomEvent("date:changed", {
1810
+ detail: {
1811
+ selectedDate: {
1812
+ from: fromSelectedDate,
1813
+ to: toSelectedDate
1814
+ }
1815
+ }
1816
+ })
1817
+ );
1818
+ }
1819
+ datepickerLeftContent.addEventListener("click", (e) => {
1820
+ const target = e.target;
1821
+ if (!target) return;
1822
+ handleChangeDate(target);
1823
+ });
1824
+ datepickerRightContent.addEventListener("click", (e) => {
1825
+ const target = e.target;
1826
+ if (!target) return;
1827
+ handleChangeDate(target);
1828
+ });
1829
+ function togglePopover() {
1830
+ if (rangeDatepickerPopover.style.display === "none" || rangeDatepickerPopover.style.display === "") {
1831
+ rangeDatepickerPopover.style.display = "flex";
1832
+ renderCalendar(
1833
+ datePickerLeftDate,
1834
+ currentDateLeft.getFullYear(),
1835
+ currentDateLeft.getMonth()
1836
+ );
1837
+ renderCalendar(
1838
+ datePickerRightDate,
1839
+ currentDateRight.getFullYear(),
1840
+ currentDateRight.getMonth()
1841
+ );
1842
+ } else {
1843
+ rangeDatepickerPopover.style.display = "none";
1844
+ }
1845
+ }
1846
+ function getMonthDifference(d1, d2) {
1847
+ let months;
1848
+ months = (d2.getFullYear() - d1.getFullYear()) * 12;
1849
+ months -= d1.getMonth();
1850
+ months += d2.getMonth();
1851
+ return months;
1852
+ }
1853
+ rangeDatepickerTrigger.addEventListener("click", (e) => {
1854
+ e.stopPropagation();
1855
+ togglePopover();
1856
+ });
1857
+ prevMonthButtonLeft.addEventListener("click", () => {
1858
+ currentDateLeft.setMonth(currentDateLeft.getMonth() - 1);
1859
+ renderCalendar(
1860
+ datePickerLeftDate,
1861
+ currentDateLeft.getFullYear(),
1862
+ currentDateLeft.getMonth()
1863
+ );
1864
+ });
1865
+ nextMonthButtonLeft.addEventListener("click", () => {
1866
+ const monthDiff = getMonthDifference(currentDateLeft, currentDateRight);
1867
+ currentDateLeft.setMonth(currentDateLeft.getMonth() + 1);
1868
+ renderCalendar(
1869
+ datePickerLeftDate,
1870
+ currentDateLeft.getFullYear(),
1871
+ currentDateLeft.getMonth()
1872
+ );
1873
+ if (monthDiff === 1) {
1874
+ currentDateRight.setMonth(currentDateRight.getMonth() + 1);
1875
+ renderCalendar(
1876
+ datePickerRightDate,
1877
+ currentDateRight.getFullYear(),
1878
+ currentDateRight.getMonth()
1879
+ );
1880
+ }
1881
+ });
1882
+ prevMonthButtonRight.addEventListener("click", () => {
1883
+ const monthDiff = getMonthDifference(currentDateLeft, currentDateRight);
1884
+ currentDateRight.setMonth(currentDateRight.getMonth() - 1);
1885
+ renderCalendar(
1886
+ datePickerRightDate,
1887
+ currentDateRight.getFullYear(),
1888
+ currentDateRight.getMonth()
1889
+ );
1890
+ if (monthDiff === 1) {
1891
+ currentDateLeft.setMonth(currentDateRight.getMonth() - 1);
1892
+ renderCalendar(
1893
+ datePickerLeftDate,
1894
+ currentDateLeft.getFullYear(),
1895
+ currentDateLeft.getMonth()
1896
+ );
1897
+ }
1898
+ });
1899
+ nextMonthButtonRight.addEventListener("click", () => {
1900
+ currentDateRight.setMonth(currentDateRight.getMonth() + 1);
1901
+ renderCalendar(
1902
+ datePickerRightDate,
1903
+ currentDateRight.getFullYear(),
1904
+ currentDateRight.getMonth()
1905
+ );
1906
+ });
1907
+ document.addEventListener("click", (e) => {
1908
+ if (!rangeDatepickerPopover.contains(e.target) && e.target !== rangeDatepickerTrigger && !rangeDatepickerTrigger.contains(e.target)) {
1909
+ rangeDatepickerPopover.style.display = "none";
1910
+ }
1911
+ });
1912
+ });
1913
+ }
1914
+
1915
+ // src/js/components/stateless/img-compare.js
1916
+ function initImgCompare(rootSelector = `.${PREFIX}-img-compare`) {
1917
+ document.querySelectorAll(rootSelector).forEach((imgCompare) => {
1918
+ const sliderEl = document.createElement("input");
1919
+ sliderEl.type = "range";
1920
+ sliderEl.min = "0";
1921
+ sliderEl.max = "100";
1922
+ sliderEl.value = "50";
1923
+ sliderEl.setAttribute("aria-label", "Percentage of the image to show");
1924
+ sliderEl.setAttribute("aria-valuenow", "50");
1925
+ sliderEl.setAttribute("aria-valuemin", "0");
1926
+ sliderEl.setAttribute("aria-valuemax", "100");
1927
+ sliderEl.classList.add("ina-ss-img__slider");
1928
+ sliderEl.addEventListener("input", () => {
1929
+ imgCompare.style.setProperty(
1930
+ `--${PREFIX}-position`,
1931
+ `${sliderEl.value}%`
1932
+ );
1933
+ });
1934
+ const sliderLineEl = document.createElement("div");
1935
+ sliderLineEl.classList.add("ina-ss-img__slider-line");
1936
+ const sliderButtonEl = document.createElement("button");
1937
+ sliderButtonEl.classList.add("ina-ss-img__slider-button");
1938
+ imgCompare.appendChild(sliderEl);
1939
+ imgCompare.appendChild(sliderLineEl);
1940
+ imgCompare.appendChild(sliderButtonEl);
1941
+ });
1942
+ }
1943
+
1944
+ // src/js/components/stateful/timepicker.js
1945
+ function initTimepicker() {
1946
+ document.querySelectorAll(`.${PREFIX}-time-picker`).forEach((picker) => {
1947
+ if (picker.dataset.initialized === "true") return;
1948
+ picker.dataset.initialized = "true";
1949
+ const input = picker.querySelector(`.${PREFIX}-time-picker__input`);
1950
+ const wrapper = picker.querySelector(`.${PREFIX}-time-picker__wrapper`);
1951
+ if (!input || !wrapper) return;
1952
+ const format = picker.dataset.format || "HH:mm";
1953
+ const use12Hours = picker.dataset.use12Hours === "true" || picker.getAttribute("data-use-12-hours") === "true" || /a/i.test(format);
1954
+ const showSecond = picker.dataset.showSecond === "true";
1955
+ const disabled = picker.classList.contains(
1956
+ `${PREFIX}-time-picker--disabled`
1957
+ );
1958
+ const allowClear = picker.dataset.allowClear !== "false";
1959
+ let isOpen = false;
1960
+ let internalValue = input.value || "";
1961
+ let panel = picker.querySelector(`.${PREFIX}-time-picker__panel`);
1962
+ if (!panel) {
1963
+ panel = document.createElement("div");
1964
+ panel.className = `${PREFIX}-time-picker__panel`;
1965
+ panel.style.display = "none";
1966
+ picker.appendChild(panel);
1967
+ }
1968
+ let content = panel.querySelector(`.${PREFIX}-time-picker__content`);
1969
+ if (!content) {
1970
+ content = document.createElement("div");
1971
+ content.className = `${PREFIX}-time-picker__content`;
1972
+ panel.appendChild(content);
1973
+ } else {
1974
+ content.innerHTML = "";
1975
+ }
1976
+ let actions = panel.querySelector(`.${PREFIX}-time-picker__actions`);
1977
+ if (!actions) {
1978
+ actions = document.createElement("div");
1979
+ actions.className = `${PREFIX}-time-picker__actions`;
1980
+ const confirmBtn = document.createElement("button");
1981
+ confirmBtn.type = "button";
1982
+ confirmBtn.className = `${PREFIX}-time-picker__confirm-button`;
1983
+ confirmBtn.textContent = "Pilih";
1984
+ confirmBtn.onclick = (e) => {
1985
+ e.stopPropagation();
1986
+ close();
1987
+ };
1988
+ actions.appendChild(confirmBtn);
1989
+ panel.appendChild(actions);
1990
+ }
1991
+ const parseTime = (timeStr) => {
1992
+ if (!timeStr) return { hours: 0, minutes: 0, seconds: 0, period: "AM" };
1993
+ let hours = 0, minutes = 0, seconds = 0, period = "AM";
1994
+ try {
1995
+ if (use12Hours) {
1996
+ const [time, p] = timeStr.split(" ");
1997
+ const [h, m, s] = time.split(":");
1998
+ hours = parseInt(h || "0", 10);
1999
+ minutes = parseInt(m || "0", 10);
2000
+ seconds = parseInt(s || "0", 10);
2001
+ period = p || "AM";
2002
+ } else {
2003
+ const [h, m, s] = timeStr.split(":");
2004
+ hours = parseInt(h || "0", 10);
2005
+ minutes = parseInt(m || "0", 10);
2006
+ seconds = parseInt(s || "0", 10);
2007
+ }
2008
+ } catch (e) {
2009
+ console.warn("Invalid time format", timeStr);
2010
+ }
2011
+ return { hours, minutes, seconds, period };
1452
2012
  };
1453
2013
  const formatTime = (h, m, s, p) => {
1454
2014
  const pad = (n) => n.toString().padStart(2, "0");
@@ -1488,661 +2048,370 @@ var InaUI = (() => {
1488
2048
  option.addEventListener("click", (e) => {
1489
2049
  e.stopPropagation();
1490
2050
  const val = parseInt(option.dataset.value, 10);
1491
- if (type === "hour")
1492
- currentTime.hours = use12Hours && val === 12 ? 0 : val;
1493
- if (type === "hour") currentTime.hours = val;
1494
- if (type === "minute") currentTime.minutes = val;
1495
- if (type === "second") currentTime.seconds = val;
1496
- updateInput();
1497
- colContent.querySelectorAll(`.${PREFIX}-time-picker__option`).forEach(
1498
- (el) => el.classList.remove(`${PREFIX}-time-picker__option--selected`)
1499
- );
1500
- option.classList.add(`${PREFIX}-time-picker__option--selected`);
1501
- });
1502
- colContent.appendChild(option);
1503
- }
1504
- return column;
1505
- };
1506
- const renderPeriodColumn = () => {
1507
- const column = document.createElement("div");
1508
- column.className = `${PREFIX}-time-picker__column ${PREFIX}-time-picker__column--period`;
1509
- const colContent = document.createElement("div");
1510
- colContent.className = `${PREFIX}-time-picker__column-content`;
1511
- column.appendChild(colContent);
1512
- ["AM", "PM"].forEach((p) => {
1513
- const option = document.createElement("div");
1514
- option.className = `${PREFIX}-time-picker__option`;
1515
- option.textContent = p;
1516
- if (currentTime.period === p)
1517
- option.classList.add(`${PREFIX}-time-picker__option--selected`);
1518
- option.addEventListener("click", (e) => {
1519
- e.stopPropagation();
1520
- currentTime.period = p;
1521
- updateInput();
1522
- colContent.querySelectorAll(`.${PREFIX}-time-picker__option`).forEach(
1523
- (el) => el.classList.remove(`${PREFIX}-time-picker__option--selected`)
1524
- );
1525
- option.classList.add(`${PREFIX}-time-picker__option--selected`);
1526
- });
1527
- colContent.appendChild(option);
1528
- });
1529
- return column;
1530
- };
1531
- const updateInput = () => {
1532
- const val = formatTime(
1533
- currentTime.hours,
1534
- currentTime.minutes,
1535
- currentTime.seconds,
1536
- currentTime.period
1537
- );
1538
- input.value = val;
1539
- picker.dataset.value = val;
1540
- input.dispatchEvent(new Event("change", { bubbles: true }));
1541
- };
1542
- const buildPanel = () => {
1543
- content.innerHTML = "";
1544
- content.appendChild(renderColumn("hour", use12Hours ? 13 : 24));
1545
- content.appendChild(renderColumn("minute", 60));
1546
- if (showSecond) content.appendChild(renderColumn("second", 60));
1547
- if (use12Hours) content.appendChild(renderPeriodColumn());
1548
- };
1549
- const open = () => {
1550
- if (disabled) return;
1551
- isOpen = true;
1552
- picker.classList.add(`${PREFIX}-time-picker--open`);
1553
- panel.style.display = "block";
1554
- currentTime = parseTime(input.value);
1555
- buildPanel();
1556
- document.dispatchEvent(
1557
- new CustomEvent("closeTimePicker", { detail: { exclude: picker } })
1558
- );
1559
- };
1560
- const close = () => {
1561
- isOpen = false;
1562
- picker.classList.remove(`${PREFIX}-time-picker--open`);
1563
- panel.style.display = "none";
1564
- };
1565
- const toggle = (e) => {
1566
- e.stopPropagation();
1567
- if (isOpen) close();
1568
- else open();
1569
- };
1570
- wrapper.addEventListener("click", toggle);
1571
- input.addEventListener("click", (e) => {
1572
- });
1573
- document.addEventListener("click", (e) => {
1574
- if (!picker.contains(e.target)) close();
1575
- });
1576
- document.addEventListener("closeTimePicker", (e) => {
1577
- if (e.detail && e.detail.exclude !== picker) close();
1578
- });
1579
- const clearBtn = picker.querySelector(
1580
- `.${PREFIX}-time-picker__clear-button`
1581
- );
1582
- if (clearBtn && allowClear) {
1583
- clearBtn.addEventListener("click", (e) => {
1584
- e.stopPropagation();
1585
- input.value = "";
1586
- currentTime = { hours: 0, minutes: 0, seconds: 0, period: "AM" };
1587
- picker.dataset.value = "";
1588
- input.dispatchEvent(new Event("change", { bubbles: true }));
1589
- });
1590
- }
1591
- });
1592
- }
1593
-
1594
- // src/js/index.js
1595
- var PREFIX = "ina";
1596
-
1597
- // src/js/components/stateful/button-group.js
1598
- function initButtonGroup(rootSelector = `.${PREFIX}-button-group`) {
1599
- const buttonGroups = document.querySelectorAll(rootSelector);
1600
- buttonGroups.forEach((buttonGroup) => {
1601
- if (buttonGroup.__inaButtonGroupInitialized) return;
1602
- const buttons = buttonGroup.querySelectorAll(
1603
- `.${PREFIX}-button-group__button`
1604
- );
1605
- const updateState = (clickedButton) => {
1606
- const isDisabled = clickedButton.hasAttribute("disabled") || clickedButton.classList.contains(
1607
- `${PREFIX}-button-group__button--disabled`
1608
- );
1609
- if (isDisabled) return;
1610
- const value = clickedButton.getAttribute("data-value");
1611
- buttons.forEach((btn) => {
1612
- if (btn === clickedButton) {
1613
- btn.classList.add(`${PREFIX}-button-group__button--selected`);
1614
- btn.setAttribute("aria-pressed", "true");
1615
- } else {
1616
- btn.classList.remove(`${PREFIX}-button-group__button--selected`);
1617
- btn.setAttribute("aria-pressed", "false");
1618
- }
1619
- });
1620
- buttonGroup.dispatchEvent(
1621
- new CustomEvent("button-group:change", {
1622
- detail: { value },
1623
- bubbles: true,
1624
- composed: true
1625
- })
1626
- );
1627
- };
1628
- buttons.forEach((button) => {
1629
- button.addEventListener("click", (e) => {
1630
- if (button.type !== "submit") {
1631
- e.preventDefault();
1632
- }
1633
- updateState(button);
1634
- });
1635
- });
1636
- buttonGroup.__inaButtonGroupInitialized = true;
1637
- });
1638
- }
1639
-
1640
- // src/js/components/stateful/dropdown.js
1641
- function initDropdown(rootSelector = `.${PREFIX}-dropdown`) {
1642
- document.querySelectorAll(rootSelector).forEach((dropdown) => {
1643
- const trigger = dropdown.querySelector(`.${PREFIX}-dropdown__trigger`);
1644
- const input = dropdown.querySelector(`.${PREFIX}-dropdown__input`);
1645
- const menu = dropdown.querySelector(`.${PREFIX}-dropdown__menu`);
1646
- const menuItems = menu.querySelectorAll("li[role='option']");
1647
- const menuId = menu.id;
1648
- let activeIndex = -1;
1649
- menuItems.forEach((item, index) => {
1650
- item.id = `${menuId}-item-${index}`;
1651
- });
1652
- const toggleMenu = (show) => {
1653
- const isCurrentlyShown = dropdown.classList.contains("show");
1654
- const isShown = show !== void 0 ? show : !isCurrentlyShown;
1655
- if (isShown === isCurrentlyShown) {
1656
- return;
1657
- }
1658
- dropdown.classList.toggle("show", isShown);
1659
- trigger.setAttribute("aria-expanded", isShown);
1660
- if (isShown) {
1661
- input.focus();
1662
- } else {
1663
- input.blur();
1664
- removeHighlight();
1665
- activeIndex = -1;
1666
- input.removeAttribute("aria-activedescendant");
1667
- }
1668
- };
1669
- const filterItems = () => {
1670
- const filterValue = input.value.toLowerCase();
1671
- let hasVisibleItems = false;
1672
- activeIndex = -1;
1673
- removeHighlight();
1674
- input.removeAttribute("aria-activedescendant");
1675
- const activeItem = menu.querySelector("li[role='option'].selected");
1676
- if (activeItem && input.value !== activeItem.textContent.trim()) {
1677
- activeItem.classList.remove("selected");
1678
- }
1679
- menuItems.forEach((item) => {
1680
- const itemText = item.textContent.toLowerCase();
1681
- const isMatch = itemText.includes(filterValue);
1682
- item.classList.toggle("hidden", !isMatch);
1683
- if (isMatch) hasVisibleItems = true;
1684
- });
1685
- if (!dropdown.classList.contains("show") && hasVisibleItems) {
1686
- toggleMenu(true);
2051
+ if (type === "hour")
2052
+ currentTime.hours = use12Hours && val === 12 ? 0 : val;
2053
+ if (type === "hour") currentTime.hours = val;
2054
+ if (type === "minute") currentTime.minutes = val;
2055
+ if (type === "second") currentTime.seconds = val;
2056
+ updateInput();
2057
+ colContent.querySelectorAll(`.${PREFIX}-time-picker__option`).forEach(
2058
+ (el) => el.classList.remove(`${PREFIX}-time-picker__option--selected`)
2059
+ );
2060
+ option.classList.add(`${PREFIX}-time-picker__option--selected`);
2061
+ });
2062
+ colContent.appendChild(option);
1687
2063
  }
2064
+ return column;
1688
2065
  };
1689
- const selectItem = (item) => {
1690
- const itemText = item.textContent.trim();
1691
- input.value = itemText;
1692
- menuItems.forEach((li) => {
1693
- li.classList.remove("selected");
2066
+ const renderPeriodColumn = () => {
2067
+ const column = document.createElement("div");
2068
+ column.className = `${PREFIX}-time-picker__column ${PREFIX}-time-picker__column--period`;
2069
+ const colContent = document.createElement("div");
2070
+ colContent.className = `${PREFIX}-time-picker__column-content`;
2071
+ column.appendChild(colContent);
2072
+ ["AM", "PM"].forEach((p) => {
2073
+ const option = document.createElement("div");
2074
+ option.className = `${PREFIX}-time-picker__option`;
2075
+ option.textContent = p;
2076
+ if (currentTime.period === p)
2077
+ option.classList.add(`${PREFIX}-time-picker__option--selected`);
2078
+ option.addEventListener("click", (e) => {
2079
+ e.stopPropagation();
2080
+ currentTime.period = p;
2081
+ updateInput();
2082
+ colContent.querySelectorAll(`.${PREFIX}-time-picker__option`).forEach(
2083
+ (el) => el.classList.remove(`${PREFIX}-time-picker__option--selected`)
2084
+ );
2085
+ option.classList.add(`${PREFIX}-time-picker__option--selected`);
2086
+ });
2087
+ colContent.appendChild(option);
1694
2088
  });
1695
- if (item) {
1696
- item.classList.add("selected");
1697
- dropdown.dispatchEvent(
1698
- new CustomEvent("dropdown:changed", {
1699
- detail: { value: itemText }
1700
- })
1701
- );
1702
- }
1703
- toggleMenu(false);
2089
+ return column;
1704
2090
  };
1705
- const setHighlight = (index) => {
1706
- removeHighlight();
1707
- const visibleItems = menu.querySelectorAll(
1708
- "li[role='option']:not(.hidden)"
2091
+ const updateInput = () => {
2092
+ const val = formatTime(
2093
+ currentTime.hours,
2094
+ currentTime.minutes,
2095
+ currentTime.seconds,
2096
+ currentTime.period
1709
2097
  );
1710
- if (visibleItems.length === 0) return;
1711
- if (index < 0) index = 0;
1712
- else if (index >= visibleItems.length) index = visibleItems.length - 1;
1713
- const itemToHighlight = visibleItems[index];
1714
- if (itemToHighlight) {
1715
- itemToHighlight.classList.add("highlighted");
1716
- input.setAttribute("aria-activedescendant", itemToHighlight.id);
1717
- itemToHighlight.scrollIntoView({
1718
- behavior: "smooth",
1719
- block: "nearest"
1720
- });
1721
- activeIndex = index;
1722
- }
2098
+ input.value = val;
2099
+ picker.dataset.value = val;
2100
+ input.dispatchEvent(new Event("change", { bubbles: true }));
1723
2101
  };
1724
- const removeHighlight = () => {
1725
- menuItems.forEach((item) => item.classList.remove("highlighted"));
2102
+ const buildPanel = () => {
2103
+ content.innerHTML = "";
2104
+ content.appendChild(renderColumn("hour", use12Hours ? 13 : 24));
2105
+ content.appendChild(renderColumn("minute", 60));
2106
+ if (showSecond) content.appendChild(renderColumn("second", 60));
2107
+ if (use12Hours) content.appendChild(renderPeriodColumn());
1726
2108
  };
1727
- trigger.addEventListener("click", () => {
1728
- toggleMenu();
1729
- });
1730
- input.addEventListener("input", filterItems);
1731
- menu.addEventListener("click", (e) => {
1732
- const option = e.target.closest("li[role='option']");
1733
- if (option) {
1734
- e.preventDefault();
1735
- selectItem(option);
1736
- }
2109
+ const open = () => {
2110
+ if (disabled) return;
2111
+ isOpen = true;
2112
+ picker.classList.add(`${PREFIX}-time-picker--open`);
2113
+ panel.style.display = "block";
2114
+ currentTime = parseTime(input.value);
2115
+ buildPanel();
2116
+ document.dispatchEvent(
2117
+ new CustomEvent("closeTimePicker", { detail: { exclude: picker } })
2118
+ );
2119
+ };
2120
+ const close = () => {
2121
+ isOpen = false;
2122
+ picker.classList.remove(`${PREFIX}-time-picker--open`);
2123
+ panel.style.display = "none";
2124
+ };
2125
+ const toggle = (e) => {
2126
+ e.stopPropagation();
2127
+ if (isOpen) close();
2128
+ else open();
2129
+ };
2130
+ wrapper.addEventListener("click", toggle);
2131
+ input.addEventListener("click", (e) => {
1737
2132
  });
1738
2133
  document.addEventListener("click", (e) => {
1739
- if (!dropdown.contains(e.target)) {
1740
- toggleMenu(false);
1741
- }
2134
+ if (!picker.contains(e.target)) close();
1742
2135
  });
1743
- input.addEventListener("keydown", (e) => {
1744
- const { key } = e;
1745
- const isMenuOpen = dropdown.classList.contains("show");
1746
- switch (key) {
1747
- case "ArrowDown":
1748
- e.preventDefault();
1749
- if (!isMenuOpen) {
1750
- toggleMenu(true);
1751
- }
1752
- setHighlight(activeIndex + 1);
1753
- break;
1754
- case "ArrowUp":
1755
- e.preventDefault();
1756
- if (isMenuOpen) {
1757
- setHighlight(activeIndex - 1);
1758
- }
1759
- break;
1760
- case "Enter":
1761
- e.preventDefault();
1762
- const firstVisible = menu.querySelector(
1763
- "li[role='option']:not(.hidden)"
1764
- );
1765
- const activeItem = menu.querySelector(".highlighted");
1766
- if (isMenuOpen && activeItem) {
1767
- selectItem(activeItem);
1768
- } else if (isMenuOpen && firstVisible) {
1769
- toggleMenu(false);
1770
- }
1771
- break;
1772
- case "Escape":
1773
- e.preventDefault();
1774
- toggleMenu(false);
1775
- break;
1776
- case "Tab":
1777
- toggleMenu(false);
1778
- break;
1779
- }
2136
+ document.addEventListener("closeTimePicker", (e) => {
2137
+ if (e.detail && e.detail.exclude !== picker) close();
1780
2138
  });
1781
- });
1782
- }
1783
-
1784
- // src/js/components/stateful/range-datepicker.js
1785
- function initRangeDatepicker() {
1786
- document.querySelectorAll(".ina-ss-range-datepicker").forEach((rangeDatepicker) => {
1787
- let currentDate = /* @__PURE__ */ new Date();
1788
- let currentDateLeft = /* @__PURE__ */ new Date();
1789
- let currentDateRight = new Date(
1790
- currentDateLeft.getFullYear(),
1791
- currentDateLeft.getMonth() + 1,
1792
- currentDateLeft.getDate()
1793
- );
1794
- let selectedDateTarget = null;
1795
- let fromSelectedDate = null;
1796
- let toSelectedDate = null;
1797
- let selectedDate = null;
1798
- const MONTHS = [
1799
- "Januari",
1800
- "Februari",
1801
- "Maret",
1802
- "April",
1803
- "Mei",
1804
- "Juni",
1805
- "Juli",
1806
- "Agustus",
1807
- "September",
1808
- "Oktober",
1809
- "November",
1810
- "Desember"
1811
- ];
1812
- const DAYS = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"];
1813
- const rangeDatepickerTrigger = rangeDatepicker.querySelector(
1814
- `.ina-ss-range-datepicker__trigger`
1815
- );
1816
- const rangeDatepickerPopover = rangeDatepicker.querySelector(
1817
- `.ina-ss-range-datepicker__popover`
1818
- );
1819
- const datePickerLeftDate = rangeDatepicker.querySelector(
1820
- `.ina-ss-range-datepicker__left-date`
1821
- );
1822
- const datePickerRightDate = rangeDatepicker.querySelector(
1823
- `.ina-ss-range-datepicker__right-date`
1824
- );
1825
- const datepickerMonthLeftTrigger = datePickerLeftDate.querySelector(
1826
- `.ina-ss-range-datepicker__month-trigger`
1827
- );
1828
- const datepickerMonthRightTrigger = datePickerRightDate.querySelector(
1829
- `.ina-ss-range-datepicker__month-trigger`
1830
- );
1831
- const datepickerLeftContent = datePickerLeftDate.querySelector(
1832
- `.ina-ss-range-datepicker__content`
1833
- );
1834
- const datepickerRightContent = datePickerRightDate.querySelector(
1835
- `.ina-ss-range-datepicker__content`
1836
- );
1837
- const prevMonthButtonLeft = datePickerLeftDate.querySelector(
1838
- `.ina-ss-range-datepicker__nav-prev`
1839
- );
1840
- const nextMonthButtonLeft = datePickerLeftDate.querySelector(
1841
- `.ina-ss-range-datepicker__nav-next`
1842
- );
1843
- const prevMonthButtonRight = datePickerRightDate.querySelector(
1844
- `.ina-ss-range-datepicker__nav-prev`
1845
- );
1846
- const nextMonthButtonRight = datePickerRightDate.querySelector(
1847
- `.ina-ss-range-datepicker__nav-next`
2139
+ const clearBtn = picker.querySelector(
2140
+ `.${PREFIX}-time-picker__clear-button`
1848
2141
  );
1849
- function renderCalendar(targetEl, year, month) {
1850
- const rangeDatepickerMonthTrigger = targetEl.querySelector(
1851
- `.ina-ss-range-datepicker__month-trigger`
1852
- );
1853
- const rangeDatepickerMonthPopover = targetEl.querySelector(
1854
- `.ina-ss-range-datepicker__month-popover`
1855
- );
1856
- const rangeDatepickerMonthItem = targetEl.querySelectorAll(
1857
- `.ina-ss-range-datepicker__month-item`
1858
- );
1859
- const rangeDatepickerYearTrigger = targetEl.querySelector(
1860
- `.ina-ss-range-datepicker__year-trigger`
1861
- );
1862
- const targetContentEl = targetEl.querySelector(
1863
- `.ina-ss-range-datepicker__content`
1864
- );
1865
- targetContentEl.innerHTML = "";
1866
- rangeDatepickerMonthTrigger.textContent = MONTHS[month].substring(0, 3);
1867
- rangeDatepickerYearTrigger.textContent = year;
1868
- DAYS.forEach((day) => {
1869
- const dayNameWrapper = document.createElement("div");
1870
- dayNameWrapper.className = `ina-ss-range-datepicker__dayname-wrapper`;
1871
- const dayNameEl = document.createElement("span");
1872
- dayNameEl.className = `ina-ss-range-datepicker__dayname`;
1873
- dayNameEl.textContent = day.substring(0, 3);
1874
- dayNameWrapper.appendChild(dayNameEl);
1875
- targetContentEl.appendChild(dayNameWrapper);
2142
+ if (clearBtn && allowClear) {
2143
+ clearBtn.addEventListener("click", (e) => {
2144
+ e.stopPropagation();
2145
+ input.value = "";
2146
+ currentTime = { hours: 0, minutes: 0, seconds: 0, period: "AM" };
2147
+ picker.dataset.value = "";
2148
+ input.dispatchEvent(new Event("change", { bubbles: true }));
1876
2149
  });
1877
- const firstDayOfMonth = new Date(year, month, 1).getDay();
1878
- const daysInMonth = new Date(year, month + 1, 0).getDate();
1879
- const daysInPrevMonth = new Date(year, month, 0).getDate();
1880
- for (let i = 0; i < firstDayOfMonth; i++) {
1881
- const dayEl = document.createElement("button");
1882
- dayEl.className = `ina-ss-range-datepicker__calendar-day outside-month`;
1883
- dayEl.textContent = daysInPrevMonth - firstDayOfMonth + 1 + i;
1884
- dayEl.disabled = true;
1885
- targetContentEl.appendChild(dayEl);
1886
- }
1887
- const today = /* @__PURE__ */ new Date();
1888
- for (let i = 1; i <= daysInMonth; i++) {
1889
- const dayEl = document.createElement("button");
1890
- dayEl.className = `ina-ss-range-datepicker__calendar-day`;
1891
- dayEl.textContent = i;
1892
- dayEl.dataset.date = new Date(year, month, i).toISOString();
1893
- if (fromSelectedDate && new Date(year, month, i).getTime() === fromSelectedDate?.getTime()) {
1894
- dayEl.classList.add("selected-from");
1895
- }
1896
- if (toSelectedDate && new Date(year, month, i).getTime() === toSelectedDate?.getTime()) {
1897
- dayEl.classList.add("selected-to");
1898
- }
1899
- if (toSelectedDate && new Date(year, month, i) === toSelectedDate) {
1900
- dayEl.classList.add("selected-to");
1901
- }
1902
- if (fromSelectedDate && toSelectedDate && new Date(year, month, i) > fromSelectedDate && new Date(year, month, i) < toSelectedDate) {
1903
- dayEl.classList.add("selected-range");
1904
- }
1905
- if (year === today.getFullYear() && month === today.getMonth() && i === today.getDate()) {
1906
- const marker = document.createElement("span");
1907
- marker.className = `ina-ss-range-datepicker__today-marker`;
1908
- marker.textContent = "Hari ini";
1909
- dayEl.appendChild(marker);
1910
- dayEl.classList.add("today");
1911
- }
1912
- if (selectedDate && year === selectedDate.getFullYear() && month === selectedDate.getMonth() && i === selectedDate.getDate()) {
1913
- dayEl.classList.add("selected");
1914
- }
1915
- targetContentEl.appendChild(dayEl);
1916
- }
1917
- const totalCells = 42;
1918
- const cellsRendered = firstDayOfMonth + daysInMonth;
1919
- const remainingCells = totalCells - cellsRendered;
1920
- for (let i = 1; i <= remainingCells; i++) {
1921
- const dayEl = document.createElement("button");
1922
- dayEl.className = `ina-ss-range-datepicker__calendar-day outside-month`;
1923
- dayEl.textContent = i;
1924
- dayEl.disabled = true;
1925
- targetContentEl.appendChild(dayEl);
1926
- }
1927
2150
  }
1928
- function handleChangeDate(target) {
1929
- if (fromSelectedDate && toSelectedDate) {
1930
- if (target.classList.contains(
1931
- `ina-ss-range-datepicker__calendar-day`
1932
- ) && !target.classList.contains("outside-month")) {
1933
- const targetDate = new Date(target.dataset.date);
1934
- if (target.classList.contains("selected-from") || target.classList.contains("selected-to")) {
1935
- const fromSelectedDateLeftEl = datepickerLeftContent.querySelector(
1936
- `.ina-ss-range-datepicker__calendar-day.selected-from`
1937
- );
1938
- const fromSelectedDateRightEl = datepickerRightContent.querySelector(
1939
- `.ina-ss-range-datepicker__calendar-day.selected-from`
1940
- );
1941
- fromSelectedDateLeftEl?.classList.remove("selected-from");
1942
- fromSelectedDateRightEl?.classList.remove("selected-from");
1943
- const toSelectedDateLeftEl = datepickerLeftContent.querySelector(
1944
- `.ina-ss-range-datepicker__calendar-day.selected-to`
1945
- );
1946
- const toSelectedDateRightEl = datepickerRightContent.querySelector(
1947
- `.ina-ss-range-datepicker__calendar-day.selected-to`
1948
- );
1949
- toSelectedDateLeftEl?.classList.remove("selected-to");
1950
- toSelectedDateRightEl?.classList.remove("selected-to");
1951
- target.classList.add("selected-from");
1952
- target.classList.add("selected-to");
1953
- fromSelectedDate = targetDate;
1954
- toSelectedDate = targetDate;
1955
- }
1956
- if (targetDate < fromSelectedDate) {
1957
- const fromSelectedDateLeftEl = datepickerLeftContent.querySelector(
1958
- `.ina-ss-range-datepicker__calendar-day.selected-from`
1959
- );
1960
- const fromSelectedDateRightEl = datepickerRightContent.querySelector(
1961
- `.ina-ss-range-datepicker__calendar-day.selected-from`
1962
- );
1963
- fromSelectedDateLeftEl?.classList.remove("selected-from");
1964
- fromSelectedDateRightEl?.classList.remove("selected-from");
1965
- fromSelectedDate = targetDate;
1966
- target.classList.add("selected-from");
2151
+ });
2152
+ }
2153
+
2154
+ // src/js/components/stateful/chip.js
2155
+ var PREFIX3 = "ina";
2156
+ function initChip(rootSelector = `.${PREFIX3}-chip`) {
2157
+ const chips = document.querySelectorAll(rootSelector);
2158
+ chips.forEach((container) => {
2159
+ if (container.__inaChipInitialized) return;
2160
+ const showCustomization = container.getAttribute("data-show-customization") === "true";
2161
+ const customizationLabel = container.getAttribute("data-customization-label") || "Kustomisasi";
2162
+ let selectedValue = container.getAttribute("data-selected") || "";
2163
+ const list = container.querySelector(`.${PREFIX3}-chip__list`);
2164
+ const items = list ? list.querySelectorAll(`.${PREFIX3}-chip__item`) : [];
2165
+ let customFieldContainer = container.querySelector(
2166
+ `.${PREFIX3}-chip__custom-field`
2167
+ );
2168
+ const updateUI = () => {
2169
+ items.forEach((item) => {
2170
+ const itemValue = item.getAttribute("data-value");
2171
+ const isSelected = itemValue === selectedValue;
2172
+ if (isSelected) {
2173
+ item.classList.add(`${PREFIX3}-chip__item--selected`);
2174
+ } else {
2175
+ item.classList.remove(`${PREFIX3}-chip__item--selected`);
2176
+ }
2177
+ });
2178
+ if (showCustomization) {
2179
+ const isCustomToggleSelected = selectedValue === customizationLabel;
2180
+ let isStandard = false;
2181
+ items.forEach((item) => {
2182
+ if (item.getAttribute("data-value") === selectedValue && item.textContent.trim() !== customizationLabel) {
2183
+ isStandard = true;
1967
2184
  }
1968
- if (targetDate > toSelectedDate || targetDate > fromSelectedDate) {
1969
- const toSelectedDateLeftEl = datepickerLeftContent.querySelector(
1970
- `.ina-ss-range-datepicker__calendar-day.selected-to`
1971
- );
1972
- const toSelectedDateRightEl = datepickerRightContent.querySelector(
1973
- `.ina-ss-range-datepicker__calendar-day.selected-to`
1974
- );
1975
- toSelectedDateLeftEl?.classList.remove("selected-to");
1976
- toSelectedDateRightEl?.classList.remove("selected-to");
1977
- toSelectedDate = targetDate;
1978
- target.classList.add("selected-to");
2185
+ });
2186
+ const toggleBtn = Array.from(items).find(
2187
+ (i) => i.textContent.trim() === customizationLabel
2188
+ );
2189
+ const showInput = toggleBtn && selectedValue === toggleBtn.getAttribute("data-value") || !isStandard && selectedValue !== "";
2190
+ if (showInput) {
2191
+ if (!customFieldContainer) {
2192
+ customFieldContainer = document.createElement("div");
2193
+ customFieldContainer.className = `${PREFIX3}-chip__custom-field`;
2194
+ container.appendChild(customFieldContainer);
1979
2195
  }
1980
- const leftDays = datepickerLeftContent.querySelectorAll(
1981
- ".ina-ss-range-datepicker__calendar-day"
1982
- );
1983
- const rightDays = datepickerRightContent.querySelectorAll(
1984
- ".ina-ss-range-datepicker__calendar-day"
1985
- );
1986
- const leftDaysArray = Array.from(leftDays);
1987
- const rightDaysArray = Array.from(rightDays);
1988
- const leftFromIndex = leftDaysArray.findIndex(
1989
- (btn) => btn.classList.contains("selected-from")
1990
- );
1991
- const rightFromIndex = rightDaysArray.findIndex(
1992
- (btn) => btn.classList.contains("selected-from")
1993
- );
1994
- const leftToIndex = leftDaysArray.findIndex(
1995
- (btn) => btn.classList.contains("selected-to")
1996
- );
1997
- const rightToIndex = rightDaysArray.findIndex(
1998
- (btn) => btn.classList.contains("selected-to")
2196
+ let input = customFieldContainer.querySelector(
2197
+ `.${PREFIX3}-chip__input`
1999
2198
  );
2000
- leftDaysArray.forEach(
2001
- (btn) => btn.classList.remove("selected-range")
2002
- );
2003
- rightDaysArray.forEach(
2004
- (btn) => btn.classList.remove("selected-range")
2005
- );
2006
- if (leftFromIndex !== -1 && leftToIndex !== -1 && rightFromIndex === -1 && rightToIndex === -1) {
2007
- for (let i = leftFromIndex + 1; i <= leftToIndex - 1; i++) {
2008
- leftDaysArray[i].classList.add("selected-range");
2009
- }
2010
- }
2011
- if (leftFromIndex !== -1 && rightToIndex !== -1) {
2012
- for (let i = leftFromIndex + 1; i < leftDaysArray.length; i++) {
2013
- leftDaysArray[i].classList.add("selected-range");
2014
- }
2015
- for (let i = 0; i < rightToIndex; i++) {
2016
- rightDaysArray[i].classList.add("selected-range");
2017
- }
2018
- }
2019
- if (leftFromIndex === -1 && leftToIndex === -1 && rightFromIndex !== -1 && rightToIndex !== -1) {
2020
- for (let i = rightFromIndex + 1; i <= rightToIndex - 1; i++) {
2021
- rightDaysArray[i].classList.add("selected-range");
2199
+ if (!input) {
2200
+ customFieldContainer.innerHTML = `
2201
+ <div class="${PREFIX3}-text-field ${PREFIX3}-text-field--size-medium ${PREFIX3}-text-field--variant-outline ${PREFIX3}-chip__input">
2202
+ <div class="${PREFIX3}-text-field__wrapper">
2203
+ <input type="text" class="${PREFIX3}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? selectedValue : ""}" />
2204
+ </div>
2205
+ </div>
2206
+ `;
2207
+ input = customFieldContainer.querySelector("input");
2208
+ input.addEventListener("blur", (e) => {
2209
+ const val = e.target.value;
2210
+ if (val.trim()) {
2211
+ handleSelect(val);
2212
+ } else {
2213
+ handleSelect("");
2214
+ }
2215
+ });
2216
+ input.addEventListener("keydown", (e) => {
2217
+ if (e.key === "Enter") {
2218
+ handleSelect(e.target.value);
2219
+ e.target.blur();
2220
+ }
2221
+ });
2222
+ } else {
2223
+ const inputEl = customFieldContainer.querySelector("input");
2224
+ if (inputEl && document.activeElement !== inputEl) {
2225
+ inputEl.value = !isStandard ? selectedValue : "";
2022
2226
  }
2023
2227
  }
2024
- }
2025
- } else {
2026
- if (target.classList.contains(
2027
- `ina-ss-range-datepicker__calendar-day`
2028
- ) && !target.classList.contains("outside-month")) {
2029
- if (target.classList.contains("selected-from") && target.classList.contains("selected-to")) {
2030
- target.classList.remove("selected-from");
2031
- target.classList.remove("selected-to");
2032
- selectedDateTarget = null;
2033
- } else {
2034
- target.classList.add("selected-from");
2035
- target.classList.add("selected-to");
2036
- selectedDateTarget = target;
2228
+ customFieldContainer.style.display = "block";
2229
+ } else {
2230
+ if (customFieldContainer) {
2231
+ customFieldContainer.style.display = "none";
2037
2232
  }
2038
- fromSelectedDate = selectedDateTarget ? new Date(selectedDateTarget.dataset.date) : null;
2039
- toSelectedDate = selectedDateTarget ? new Date(selectedDateTarget.dataset.date) : null;
2040
2233
  }
2041
2234
  }
2042
- rangeDatepicker.dispatchEvent(
2043
- new CustomEvent("date:changed", {
2044
- detail: {
2045
- selectedDate: {
2046
- from: fromSelectedDate,
2047
- to: toSelectedDate
2048
- }
2049
- }
2235
+ };
2236
+ const handleSelect = (val) => {
2237
+ selectedValue = val;
2238
+ container.setAttribute("data-selected", val);
2239
+ updateUI();
2240
+ container.dispatchEvent(
2241
+ new CustomEvent("chip:select", {
2242
+ detail: { value: val },
2243
+ bubbles: true
2050
2244
  })
2051
2245
  );
2052
- }
2053
- datepickerLeftContent.addEventListener("click", (e) => {
2054
- const target = e.target;
2055
- if (!target) return;
2056
- handleChangeDate(target);
2057
- });
2058
- datepickerRightContent.addEventListener("click", (e) => {
2059
- const target = e.target;
2060
- if (!target) return;
2061
- handleChangeDate(target);
2062
- });
2063
- function togglePopover() {
2064
- if (rangeDatepickerPopover.style.display === "none" || rangeDatepickerPopover.style.display === "") {
2065
- rangeDatepickerPopover.style.display = "flex";
2066
- renderCalendar(
2067
- datePickerLeftDate,
2068
- currentDateLeft.getFullYear(),
2069
- currentDateLeft.getMonth()
2070
- );
2071
- renderCalendar(
2072
- datePickerRightDate,
2073
- currentDateRight.getFullYear(),
2074
- currentDateRight.getMonth()
2075
- );
2076
- } else {
2077
- rangeDatepickerPopover.style.display = "none";
2078
- }
2079
- }
2080
- function getMonthDifference(d1, d2) {
2081
- let months;
2082
- months = (d2.getFullYear() - d1.getFullYear()) * 12;
2083
- months -= d1.getMonth();
2084
- months += d2.getMonth();
2085
- return months;
2086
- }
2087
- rangeDatepickerTrigger.addEventListener("click", (e) => {
2088
- e.stopPropagation();
2089
- togglePopover();
2090
- });
2091
- prevMonthButtonLeft.addEventListener("click", () => {
2092
- currentDateLeft.setMonth(currentDateLeft.getMonth() - 1);
2093
- renderCalendar(
2094
- datePickerLeftDate,
2095
- currentDateLeft.getFullYear(),
2096
- currentDateLeft.getMonth()
2097
- );
2246
+ };
2247
+ items.forEach((item) => {
2248
+ item.addEventListener("click", (e) => {
2249
+ const val = item.getAttribute("data-value");
2250
+ const label = item.textContent.trim();
2251
+ if (showCustomization && label === customizationLabel) {
2252
+ handleSelect(val);
2253
+ } else {
2254
+ handleSelect(val);
2255
+ }
2256
+ });
2098
2257
  });
2099
- nextMonthButtonLeft.addEventListener("click", () => {
2100
- const monthDiff = getMonthDifference(currentDateLeft, currentDateRight);
2101
- currentDateLeft.setMonth(currentDateLeft.getMonth() + 1);
2102
- renderCalendar(
2103
- datePickerLeftDate,
2104
- currentDateLeft.getFullYear(),
2105
- currentDateLeft.getMonth()
2106
- );
2107
- if (monthDiff === 1) {
2108
- currentDateRight.setMonth(currentDateRight.getMonth() + 1);
2109
- renderCalendar(
2110
- datePickerRightDate,
2111
- currentDateRight.getFullYear(),
2112
- currentDateRight.getMonth()
2258
+ updateUI();
2259
+ container.__inaChipInitialized = true;
2260
+ });
2261
+ }
2262
+
2263
+ // src/js/components/stateful/pagination.js
2264
+ function initPagination() {
2265
+ document.querySelectorAll(`.${PREFIX}-pagination`).forEach((container) => {
2266
+ if (container.dataset.initialized === "true") return;
2267
+ container.dataset.initialized = "true";
2268
+ const navButtonsContainer = container.querySelector(
2269
+ `.${PREFIX}-pagination__nav-buttons`
2270
+ );
2271
+ const pageInfo = container.querySelector(
2272
+ `.${PREFIX}-pagination__page-info`
2273
+ );
2274
+ const firstBtn = container.querySelector('[data-action="first"]');
2275
+ const prevBtn = container.querySelector('[data-action="prev"]');
2276
+ const nextBtn = container.querySelector('[data-action="next"]');
2277
+ const lastBtn = container.querySelector('[data-action="last"]');
2278
+ const pageSizeSelect = container.querySelector('[data-role="page-size"]');
2279
+ if (!navButtonsContainer || !pageInfo) return;
2280
+ let currentPage = parseInt(container.dataset.current || "1", 10);
2281
+ let totalPages = parseInt(container.dataset.total || "10", 10);
2282
+ let pageSize = parseInt(container.dataset.pageSize || "10", 10);
2283
+ let pageButtons = [];
2284
+ const updateUI = () => {
2285
+ pageInfo.textContent = `Halaman ${currentPage} dari ${totalPages}`;
2286
+ const isFirst = currentPage === 1;
2287
+ if (firstBtn) {
2288
+ firstBtn.disabled = isFirst;
2289
+ firstBtn.classList.toggle(
2290
+ `${PREFIX}-pagination__nav-button--disabled`,
2291
+ isFirst
2292
+ );
2293
+ firstBtn.classList.toggle(
2294
+ `${PREFIX}-pagination__nav-button--enabled`,
2295
+ !isFirst
2113
2296
  );
2114
2297
  }
2115
- });
2116
- prevMonthButtonRight.addEventListener("click", () => {
2117
- const monthDiff = getMonthDifference(currentDateLeft, currentDateRight);
2118
- currentDateRight.setMonth(currentDateRight.getMonth() - 1);
2119
- renderCalendar(
2120
- datePickerRightDate,
2121
- currentDateRight.getFullYear(),
2122
- currentDateRight.getMonth()
2123
- );
2124
- if (monthDiff === 1) {
2125
- currentDateLeft.setMonth(currentDateRight.getMonth() - 1);
2126
- renderCalendar(
2127
- datePickerLeftDate,
2128
- currentDateLeft.getFullYear(),
2129
- currentDateLeft.getMonth()
2298
+ if (prevBtn) {
2299
+ prevBtn.disabled = isFirst;
2300
+ prevBtn.classList.toggle(
2301
+ `${PREFIX}-pagination__nav-button--disabled`,
2302
+ isFirst
2303
+ );
2304
+ prevBtn.classList.toggle(
2305
+ `${PREFIX}-pagination__nav-button--enabled`,
2306
+ !isFirst
2130
2307
  );
2131
2308
  }
2132
- });
2133
- nextMonthButtonRight.addEventListener("click", () => {
2134
- currentDateRight.setMonth(currentDateRight.getMonth() + 1);
2135
- renderCalendar(
2136
- datePickerRightDate,
2137
- currentDateRight.getFullYear(),
2138
- currentDateRight.getMonth()
2139
- );
2140
- });
2141
- document.addEventListener("click", (e) => {
2142
- if (!rangeDatepickerPopover.contains(e.target) && e.target !== rangeDatepickerTrigger && !rangeDatepickerTrigger.contains(e.target)) {
2143
- rangeDatepickerPopover.style.display = "none";
2309
+ const isLast = currentPage === totalPages;
2310
+ if (nextBtn) {
2311
+ nextBtn.disabled = isLast;
2312
+ nextBtn.classList.toggle(
2313
+ `${PREFIX}-pagination__nav-button--disabled`,
2314
+ isLast
2315
+ );
2316
+ nextBtn.classList.toggle(
2317
+ `${PREFIX}-pagination__nav-button--enabled`,
2318
+ !isLast
2319
+ );
2144
2320
  }
2145
- });
2321
+ if (lastBtn) {
2322
+ lastBtn.disabled = isLast;
2323
+ lastBtn.classList.toggle(
2324
+ `${PREFIX}-pagination__nav-button--disabled`,
2325
+ isLast
2326
+ );
2327
+ lastBtn.classList.toggle(
2328
+ `${PREFIX}-pagination__nav-button--enabled`,
2329
+ !isLast
2330
+ );
2331
+ }
2332
+ renderPageNumbers();
2333
+ };
2334
+ const renderPageNumbers = () => {
2335
+ let start, end;
2336
+ if (currentPage === 1) {
2337
+ start = 1;
2338
+ end = Math.min(3, totalPages);
2339
+ } else if (currentPage === totalPages) {
2340
+ start = Math.max(1, totalPages - 2);
2341
+ end = totalPages;
2342
+ } else {
2343
+ start = currentPage - 1;
2344
+ end = currentPage + 1;
2345
+ }
2346
+ if (start < 1) start = 1;
2347
+ if (end > totalPages) end = totalPages;
2348
+ pageButtons.forEach((btn) => btn.remove());
2349
+ pageButtons = [];
2350
+ const refNode = nextBtn || null;
2351
+ for (let i = start; i <= end; i++) {
2352
+ const isActive = i === currentPage;
2353
+ const button = document.createElement("button");
2354
+ button.type = "button";
2355
+ button.textContent = i;
2356
+ button.className = `${PREFIX}-pagination__page-button ${PREFIX}-pagination__page-button--${isActive ? "active" : "enabled"}`;
2357
+ button.addEventListener("click", (e) => {
2358
+ e.stopPropagation();
2359
+ if (i !== currentPage) {
2360
+ goToPage(i);
2361
+ }
2362
+ });
2363
+ navButtonsContainer.insertBefore(button, refNode);
2364
+ pageButtons.push(button);
2365
+ }
2366
+ };
2367
+ const goToPage = (page) => {
2368
+ if (page < 1) page = 1;
2369
+ if (page > totalPages) page = totalPages;
2370
+ if (page === currentPage) return;
2371
+ currentPage = page;
2372
+ container.dataset.current = currentPage;
2373
+ updateUI();
2374
+ dispatchChange();
2375
+ };
2376
+ const dispatchChange = () => {
2377
+ container.dispatchEvent(
2378
+ new CustomEvent("pagination:change", {
2379
+ bubbles: true,
2380
+ detail: {
2381
+ page: currentPage,
2382
+ pageSize,
2383
+ totalPages
2384
+ }
2385
+ })
2386
+ );
2387
+ };
2388
+ if (firstBtn)
2389
+ firstBtn.addEventListener("click", () => {
2390
+ if (currentPage > 1) goToPage(1);
2391
+ });
2392
+ if (prevBtn)
2393
+ prevBtn.addEventListener("click", () => {
2394
+ if (currentPage > 1) goToPage(currentPage - 1);
2395
+ });
2396
+ if (nextBtn)
2397
+ nextBtn.addEventListener("click", () => {
2398
+ if (currentPage < totalPages) goToPage(currentPage + 1);
2399
+ });
2400
+ if (lastBtn)
2401
+ lastBtn.addEventListener("click", () => {
2402
+ if (currentPage < totalPages) goToPage(totalPages);
2403
+ });
2404
+ if (pageSizeSelect) {
2405
+ pageSizeSelect.addEventListener("change", (e) => {
2406
+ pageSize = parseInt(e.target.value, 10);
2407
+ currentPage = 1;
2408
+ container.dataset.pageSize = pageSize;
2409
+ container.dataset.current = currentPage;
2410
+ updateUI();
2411
+ dispatchChange();
2412
+ });
2413
+ }
2414
+ updateUI();
2146
2415
  });
2147
2416
  }
2148
2417
 
@@ -2215,6 +2484,196 @@ var InaUI = (() => {
2215
2484
  }
2216
2485
  }
2217
2486
 
2487
+ // src/js/index.js
2488
+ var PREFIX = "ina";
2489
+
2490
+ // src/js/components/stateful/button-group.js
2491
+ function initButtonGroup(rootSelector = `.${PREFIX}-button-group`) {
2492
+ const buttonGroups = document.querySelectorAll(rootSelector);
2493
+ buttonGroups.forEach((buttonGroup) => {
2494
+ if (buttonGroup.__inaButtonGroupInitialized) return;
2495
+ const buttons = buttonGroup.querySelectorAll(
2496
+ `.${PREFIX}-button-group__button`
2497
+ );
2498
+ const updateState = (clickedButton) => {
2499
+ const isDisabled = clickedButton.hasAttribute("disabled") || clickedButton.classList.contains(
2500
+ `${PREFIX}-button-group__button--disabled`
2501
+ );
2502
+ if (isDisabled) return;
2503
+ const value = clickedButton.getAttribute("data-value");
2504
+ buttons.forEach((btn) => {
2505
+ if (btn === clickedButton) {
2506
+ btn.classList.add(`${PREFIX}-button-group__button--selected`);
2507
+ btn.setAttribute("aria-pressed", "true");
2508
+ } else {
2509
+ btn.classList.remove(`${PREFIX}-button-group__button--selected`);
2510
+ btn.setAttribute("aria-pressed", "false");
2511
+ }
2512
+ });
2513
+ buttonGroup.dispatchEvent(
2514
+ new CustomEvent("button-group:change", {
2515
+ detail: { value },
2516
+ bubbles: true,
2517
+ composed: true
2518
+ })
2519
+ );
2520
+ };
2521
+ buttons.forEach((button) => {
2522
+ button.addEventListener("click", (e) => {
2523
+ if (button.type !== "submit") {
2524
+ e.preventDefault();
2525
+ }
2526
+ updateState(button);
2527
+ });
2528
+ });
2529
+ buttonGroup.__inaButtonGroupInitialized = true;
2530
+ });
2531
+ }
2532
+
2533
+ // src/js/components/stateful/dropdown.js
2534
+ function initDropdown(rootSelector = `.${PREFIX}-dropdown`) {
2535
+ document.querySelectorAll(rootSelector).forEach((dropdown) => {
2536
+ const trigger = dropdown.querySelector(`.${PREFIX}-dropdown__trigger`);
2537
+ const input = dropdown.querySelector(`.${PREFIX}-dropdown__input`);
2538
+ const menu = dropdown.querySelector(`.${PREFIX}-dropdown__menu`);
2539
+ const menuItems = menu.querySelectorAll("li[role='option']");
2540
+ const menuId = menu.id;
2541
+ let activeIndex = -1;
2542
+ menuItems.forEach((item, index) => {
2543
+ item.id = `${menuId}-item-${index}`;
2544
+ });
2545
+ const toggleMenu = (show) => {
2546
+ const isCurrentlyShown = dropdown.classList.contains("show");
2547
+ const isShown = show !== void 0 ? show : !isCurrentlyShown;
2548
+ if (isShown === isCurrentlyShown) {
2549
+ return;
2550
+ }
2551
+ dropdown.classList.toggle("show", isShown);
2552
+ trigger.setAttribute("aria-expanded", isShown);
2553
+ if (isShown) {
2554
+ input.focus();
2555
+ } else {
2556
+ input.blur();
2557
+ removeHighlight();
2558
+ activeIndex = -1;
2559
+ input.removeAttribute("aria-activedescendant");
2560
+ }
2561
+ };
2562
+ const filterItems = () => {
2563
+ const filterValue = input.value.toLowerCase();
2564
+ let hasVisibleItems = false;
2565
+ activeIndex = -1;
2566
+ removeHighlight();
2567
+ input.removeAttribute("aria-activedescendant");
2568
+ const activeItem = menu.querySelector("li[role='option'].selected");
2569
+ if (activeItem && input.value !== activeItem.textContent.trim()) {
2570
+ activeItem.classList.remove("selected");
2571
+ }
2572
+ menuItems.forEach((item) => {
2573
+ const itemText = item.textContent.toLowerCase();
2574
+ const isMatch = itemText.includes(filterValue);
2575
+ item.classList.toggle("hidden", !isMatch);
2576
+ if (isMatch) hasVisibleItems = true;
2577
+ });
2578
+ if (!dropdown.classList.contains("show") && hasVisibleItems) {
2579
+ toggleMenu(true);
2580
+ }
2581
+ };
2582
+ const selectItem = (item) => {
2583
+ const itemText = item.textContent.trim();
2584
+ input.value = itemText;
2585
+ menuItems.forEach((li) => {
2586
+ li.classList.remove("selected");
2587
+ });
2588
+ if (item) {
2589
+ item.classList.add("selected");
2590
+ dropdown.dispatchEvent(
2591
+ new CustomEvent("dropdown:changed", {
2592
+ detail: { value: itemText }
2593
+ })
2594
+ );
2595
+ }
2596
+ toggleMenu(false);
2597
+ };
2598
+ const setHighlight = (index) => {
2599
+ removeHighlight();
2600
+ const visibleItems = menu.querySelectorAll(
2601
+ "li[role='option']:not(.hidden)"
2602
+ );
2603
+ if (visibleItems.length === 0) return;
2604
+ if (index < 0) index = 0;
2605
+ else if (index >= visibleItems.length) index = visibleItems.length - 1;
2606
+ const itemToHighlight = visibleItems[index];
2607
+ if (itemToHighlight) {
2608
+ itemToHighlight.classList.add("highlighted");
2609
+ input.setAttribute("aria-activedescendant", itemToHighlight.id);
2610
+ itemToHighlight.scrollIntoView({
2611
+ behavior: "smooth",
2612
+ block: "nearest"
2613
+ });
2614
+ activeIndex = index;
2615
+ }
2616
+ };
2617
+ const removeHighlight = () => {
2618
+ menuItems.forEach((item) => item.classList.remove("highlighted"));
2619
+ };
2620
+ trigger.addEventListener("click", () => {
2621
+ toggleMenu();
2622
+ });
2623
+ input.addEventListener("input", filterItems);
2624
+ menu.addEventListener("click", (e) => {
2625
+ const option = e.target.closest("li[role='option']");
2626
+ if (option) {
2627
+ e.preventDefault();
2628
+ selectItem(option);
2629
+ }
2630
+ });
2631
+ document.addEventListener("click", (e) => {
2632
+ if (!dropdown.contains(e.target)) {
2633
+ toggleMenu(false);
2634
+ }
2635
+ });
2636
+ input.addEventListener("keydown", (e) => {
2637
+ const { key } = e;
2638
+ const isMenuOpen = dropdown.classList.contains("show");
2639
+ switch (key) {
2640
+ case "ArrowDown":
2641
+ e.preventDefault();
2642
+ if (!isMenuOpen) {
2643
+ toggleMenu(true);
2644
+ }
2645
+ setHighlight(activeIndex + 1);
2646
+ break;
2647
+ case "ArrowUp":
2648
+ e.preventDefault();
2649
+ if (isMenuOpen) {
2650
+ setHighlight(activeIndex - 1);
2651
+ }
2652
+ break;
2653
+ case "Enter":
2654
+ e.preventDefault();
2655
+ const firstVisible = menu.querySelector(
2656
+ "li[role='option']:not(.hidden)"
2657
+ );
2658
+ const activeItem = menu.querySelector(".highlighted");
2659
+ if (isMenuOpen && activeItem) {
2660
+ selectItem(activeItem);
2661
+ } else if (isMenuOpen && firstVisible) {
2662
+ toggleMenu(false);
2663
+ }
2664
+ break;
2665
+ case "Escape":
2666
+ e.preventDefault();
2667
+ toggleMenu(false);
2668
+ break;
2669
+ case "Tab":
2670
+ toggleMenu(false);
2671
+ break;
2672
+ }
2673
+ });
2674
+ });
2675
+ }
2676
+
2218
2677
  // src/js/bundle.js
2219
2678
  if (typeof window !== void 0) {
2220
2679
  document.addEventListener("DOMContentLoaded", () => {
@@ -2230,9 +2689,13 @@ var InaUI = (() => {
2230
2689
  initImgCompare();
2231
2690
  initModal();
2232
2691
  initRangeDatepicker();
2692
+ initRadioButton();
2233
2693
  initTab();
2234
2694
  initTimepicker();
2235
2695
  initToggle();
2696
+ initPagination();
2697
+ initSelectDropdown();
2698
+ initChip();
2236
2699
  });
2237
2700
  }
2238
2701
  return __toCommonJS(bundle_exports);