@idds/js 1.0.99 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2956,34 +2956,59 @@ var InaUI = (() => {
2956
2956
  if (container.__inaChipInitialized) return;
2957
2957
  const showCustomization = container.getAttribute("data-show-customization") === "true";
2958
2958
  const customizationLabel = container.getAttribute("data-customization-label") || "Kustomisasi";
2959
+ const isMultiple = container.getAttribute("data-multiple") === "true";
2959
2960
  let selectedValue = container.getAttribute("data-selected") || "";
2960
2961
  const list = container.querySelector(`.${PREFIX4}-chip__list`);
2961
2962
  const items = list ? list.querySelectorAll(`.${PREFIX4}-chip__item`) : [];
2962
2963
  let customFieldContainer = container.querySelector(
2963
2964
  `.${PREFIX4}-chip__custom-field`
2964
2965
  );
2966
+ const getNormalizedSelected = () => {
2967
+ if (!selectedValue) return [];
2968
+ return isMultiple ? selectedValue.split(",").map((s) => s.trim()).filter(Boolean) : [selectedValue];
2969
+ };
2965
2970
  const updateUI = () => {
2966
- items.forEach((item) => {
2971
+ const normSelected = getNormalizedSelected();
2972
+ const getInitialFocusIndex = () => {
2973
+ if (normSelected.length > 0) {
2974
+ const standardValues = Array.from(items).filter((item) => item.textContent.trim() !== customizationLabel).map((item) => item.getAttribute("data-value"));
2975
+ const hasCustomVal = normSelected.some(
2976
+ (val) => !standardValues.includes(val) && val !== ""
2977
+ );
2978
+ if (hasCustomVal && showCustomization) {
2979
+ return items.length - 1;
2980
+ }
2981
+ const firstSelectedIndex = Array.from(items).findIndex(
2982
+ (opt) => normSelected.includes(opt.getAttribute("data-value"))
2983
+ );
2984
+ if (firstSelectedIndex !== -1) return firstSelectedIndex;
2985
+ }
2986
+ return 0;
2987
+ };
2988
+ const focusedIndex = getInitialFocusIndex();
2989
+ items.forEach((item, index2) => {
2967
2990
  const itemValue = item.getAttribute("data-value");
2968
- const isSelected = itemValue === selectedValue;
2991
+ const isSelected = normSelected.includes(itemValue) || showCustomization && item.textContent.trim() === customizationLabel && normSelected.some(
2992
+ (val) => !Array.from(items).filter((i) => i.textContent.trim() !== customizationLabel).map((i) => i.getAttribute("data-value")).includes(val) && val !== ""
2993
+ );
2969
2994
  if (isSelected) {
2970
2995
  item.classList.add(`${PREFIX4}-chip__item--selected`);
2971
2996
  } else {
2972
2997
  item.classList.remove(`${PREFIX4}-chip__item--selected`);
2973
2998
  }
2999
+ item.setAttribute("tabindex", index2 === focusedIndex ? "0" : "-1");
2974
3000
  });
2975
3001
  if (showCustomization) {
2976
- const isCustomToggleSelected = selectedValue === customizationLabel;
2977
- let isStandard = false;
2978
- items.forEach((item) => {
2979
- if (item.getAttribute("data-value") === selectedValue && item.textContent.trim() !== customizationLabel) {
2980
- isStandard = true;
2981
- }
2982
- });
3002
+ const standardValues = Array.from(items).filter((item) => item.textContent.trim() !== customizationLabel).map((item) => item.getAttribute("data-value"));
3003
+ const customValues = normSelected.filter(
3004
+ (val) => !standardValues.includes(val) && val !== ""
3005
+ );
3006
+ const isStandard = customValues.length === 0;
3007
+ const primaryCustomValue = customValues[customValues.length - 1] || "";
2983
3008
  const toggleBtn = Array.from(items).find(
2984
3009
  (i) => i.textContent.trim() === customizationLabel
2985
3010
  );
2986
- const showInput = toggleBtn && selectedValue === toggleBtn.getAttribute("data-value") || !isStandard && selectedValue !== "";
3011
+ const showInput = toggleBtn && normSelected.includes(toggleBtn.getAttribute("data-value")) || !isStandard && normSelected.length > 0;
2987
3012
  if (showInput) {
2988
3013
  if (!customFieldContainer) {
2989
3014
  customFieldContainer = document.createElement("div");
@@ -2997,7 +3022,7 @@ var InaUI = (() => {
2997
3022
  customFieldContainer.innerHTML = `
2998
3023
  <div class="${PREFIX4}-text-field ${PREFIX4}-text-field--size-medium ${PREFIX4}-text-field--variant-outline ${PREFIX4}-chip__input">
2999
3024
  <div class="${PREFIX4}-text-field__wrapper">
3000
- <input type="text" class="${PREFIX4}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? selectedValue : ""}" />
3025
+ <input type="text" class="${PREFIX4}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? primaryCustomValue : ""}" />
3001
3026
  </div>
3002
3027
  </div>
3003
3028
  `;
@@ -3005,21 +3030,21 @@ var InaUI = (() => {
3005
3030
  input.addEventListener("blur", (e) => {
3006
3031
  const val = e.target.value;
3007
3032
  if (val.trim()) {
3008
- handleSelect(val);
3009
- } else {
3010
- handleSelect("");
3033
+ handleSelect(val.trim());
3011
3034
  }
3012
3035
  });
3013
3036
  input.addEventListener("keydown", (e) => {
3014
3037
  if (e.key === "Enter") {
3015
- handleSelect(e.target.value);
3038
+ if (e.target.value.trim()) {
3039
+ handleSelect(e.target.value.trim());
3040
+ }
3016
3041
  e.target.blur();
3017
3042
  }
3018
3043
  });
3019
3044
  } else {
3020
3045
  const inputEl = customFieldContainer.querySelector("input");
3021
3046
  if (inputEl && document.activeElement !== inputEl) {
3022
- inputEl.value = !isStandard ? selectedValue : "";
3047
+ inputEl.value = !isStandard ? primaryCustomValue : "";
3023
3048
  }
3024
3049
  }
3025
3050
  customFieldContainer.style.display = "block";
@@ -3031,17 +3056,41 @@ var InaUI = (() => {
3031
3056
  }
3032
3057
  };
3033
3058
  const handleSelect = (val) => {
3034
- selectedValue = val;
3035
- container.setAttribute("data-selected", val);
3059
+ if (!val) return;
3060
+ let finalVal = val;
3061
+ if (isMultiple) {
3062
+ const normSelected = getNormalizedSelected();
3063
+ let newSelected;
3064
+ if (normSelected.includes(val)) {
3065
+ newSelected = normSelected.filter((v) => v !== val);
3066
+ } else {
3067
+ newSelected = [...normSelected, val];
3068
+ }
3069
+ finalVal = newSelected;
3070
+ selectedValue = newSelected.join(",");
3071
+ } else {
3072
+ selectedValue = val;
3073
+ }
3074
+ container.setAttribute("data-selected", selectedValue);
3036
3075
  updateUI();
3037
3076
  container.dispatchEvent(
3038
3077
  new CustomEvent("chip:select", {
3039
- detail: { value: val },
3078
+ detail: { value: finalVal },
3040
3079
  bubbles: true
3041
3080
  })
3042
3081
  );
3043
3082
  };
3044
- items.forEach((item) => {
3083
+ let currentFocusedIndex = -1;
3084
+ const setItemFocus = (index2) => {
3085
+ items.forEach((item, i) => {
3086
+ item.setAttribute("tabindex", i === index2 ? "0" : "-1");
3087
+ });
3088
+ if (items[index2]) {
3089
+ items[index2].focus();
3090
+ currentFocusedIndex = index2;
3091
+ }
3092
+ };
3093
+ items.forEach((item, index2) => {
3045
3094
  item.addEventListener("click", (e) => {
3046
3095
  const val = item.getAttribute("data-value");
3047
3096
  const label = item.textContent.trim();
@@ -3051,6 +3100,39 @@ var InaUI = (() => {
3051
3100
  handleSelect(val);
3052
3101
  }
3053
3102
  });
3103
+ item.addEventListener("focus", () => {
3104
+ currentFocusedIndex = index2;
3105
+ });
3106
+ item.addEventListener("keydown", (e) => {
3107
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") {
3108
+ e.preventDefault();
3109
+ const nextIndex = (index2 + 1) % items.length;
3110
+ setItemFocus(nextIndex);
3111
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
3112
+ e.preventDefault();
3113
+ const prevIndex = (index2 - 1 + items.length) % items.length;
3114
+ setItemFocus(prevIndex);
3115
+ }
3116
+ if (e.key === " " || e.key === "Enter") {
3117
+ e.preventDefault();
3118
+ const val = item.getAttribute("data-value");
3119
+ const label = item.textContent.trim();
3120
+ if (showCustomization && label === customizationLabel) {
3121
+ handleSelect(val);
3122
+ setTimeout(() => {
3123
+ const customFieldContainer2 = container.querySelector(
3124
+ `.${PREFIX4}-chip__custom-field`
3125
+ );
3126
+ if (customFieldContainer2) {
3127
+ const inputEl = customFieldContainer2.querySelector("input");
3128
+ if (inputEl) inputEl.focus();
3129
+ }
3130
+ }, 50);
3131
+ } else {
3132
+ handleSelect(val);
3133
+ }
3134
+ }
3135
+ });
3054
3136
  });
3055
3137
  updateUI();
3056
3138
  container.__inaChipInitialized = true;
package/dist/index.js CHANGED
@@ -3036,34 +3036,59 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3036
3036
  if (container.__inaChipInitialized) return;
3037
3037
  const showCustomization = container.getAttribute("data-show-customization") === "true";
3038
3038
  const customizationLabel = container.getAttribute("data-customization-label") || "Kustomisasi";
3039
+ const isMultiple = container.getAttribute("data-multiple") === "true";
3039
3040
  let selectedValue = container.getAttribute("data-selected") || "";
3040
3041
  const list = container.querySelector(`.${PREFIX5}-chip__list`);
3041
3042
  const items = list ? list.querySelectorAll(`.${PREFIX5}-chip__item`) : [];
3042
3043
  let customFieldContainer = container.querySelector(
3043
3044
  `.${PREFIX5}-chip__custom-field`
3044
3045
  );
3046
+ const getNormalizedSelected = () => {
3047
+ if (!selectedValue) return [];
3048
+ return isMultiple ? selectedValue.split(",").map((s) => s.trim()).filter(Boolean) : [selectedValue];
3049
+ };
3045
3050
  const updateUI = () => {
3046
- items.forEach((item) => {
3051
+ const normSelected = getNormalizedSelected();
3052
+ const getInitialFocusIndex = () => {
3053
+ if (normSelected.length > 0) {
3054
+ const standardValues = Array.from(items).filter((item) => item.textContent.trim() !== customizationLabel).map((item) => item.getAttribute("data-value"));
3055
+ const hasCustomVal = normSelected.some(
3056
+ (val) => !standardValues.includes(val) && val !== ""
3057
+ );
3058
+ if (hasCustomVal && showCustomization) {
3059
+ return items.length - 1;
3060
+ }
3061
+ const firstSelectedIndex = Array.from(items).findIndex(
3062
+ (opt) => normSelected.includes(opt.getAttribute("data-value"))
3063
+ );
3064
+ if (firstSelectedIndex !== -1) return firstSelectedIndex;
3065
+ }
3066
+ return 0;
3067
+ };
3068
+ const focusedIndex = getInitialFocusIndex();
3069
+ items.forEach((item, index2) => {
3047
3070
  const itemValue = item.getAttribute("data-value");
3048
- const isSelected = itemValue === selectedValue;
3071
+ const isSelected = normSelected.includes(itemValue) || showCustomization && item.textContent.trim() === customizationLabel && normSelected.some(
3072
+ (val) => !Array.from(items).filter((i) => i.textContent.trim() !== customizationLabel).map((i) => i.getAttribute("data-value")).includes(val) && val !== ""
3073
+ );
3049
3074
  if (isSelected) {
3050
3075
  item.classList.add(`${PREFIX5}-chip__item--selected`);
3051
3076
  } else {
3052
3077
  item.classList.remove(`${PREFIX5}-chip__item--selected`);
3053
3078
  }
3079
+ item.setAttribute("tabindex", index2 === focusedIndex ? "0" : "-1");
3054
3080
  });
3055
3081
  if (showCustomization) {
3056
- const isCustomToggleSelected = selectedValue === customizationLabel;
3057
- let isStandard = false;
3058
- items.forEach((item) => {
3059
- if (item.getAttribute("data-value") === selectedValue && item.textContent.trim() !== customizationLabel) {
3060
- isStandard = true;
3061
- }
3062
- });
3082
+ const standardValues = Array.from(items).filter((item) => item.textContent.trim() !== customizationLabel).map((item) => item.getAttribute("data-value"));
3083
+ const customValues = normSelected.filter(
3084
+ (val) => !standardValues.includes(val) && val !== ""
3085
+ );
3086
+ const isStandard = customValues.length === 0;
3087
+ const primaryCustomValue = customValues[customValues.length - 1] || "";
3063
3088
  const toggleBtn = Array.from(items).find(
3064
3089
  (i) => i.textContent.trim() === customizationLabel
3065
3090
  );
3066
- const showInput = toggleBtn && selectedValue === toggleBtn.getAttribute("data-value") || !isStandard && selectedValue !== "";
3091
+ const showInput = toggleBtn && normSelected.includes(toggleBtn.getAttribute("data-value")) || !isStandard && normSelected.length > 0;
3067
3092
  if (showInput) {
3068
3093
  if (!customFieldContainer) {
3069
3094
  customFieldContainer = document.createElement("div");
@@ -3077,7 +3102,7 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3077
3102
  customFieldContainer.innerHTML = `
3078
3103
  <div class="${PREFIX5}-text-field ${PREFIX5}-text-field--size-medium ${PREFIX5}-text-field--variant-outline ${PREFIX5}-chip__input">
3079
3104
  <div class="${PREFIX5}-text-field__wrapper">
3080
- <input type="text" class="${PREFIX5}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? selectedValue : ""}" />
3105
+ <input type="text" class="${PREFIX5}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? primaryCustomValue : ""}" />
3081
3106
  </div>
3082
3107
  </div>
3083
3108
  `;
@@ -3085,21 +3110,21 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3085
3110
  input.addEventListener("blur", (e) => {
3086
3111
  const val = e.target.value;
3087
3112
  if (val.trim()) {
3088
- handleSelect(val);
3089
- } else {
3090
- handleSelect("");
3113
+ handleSelect(val.trim());
3091
3114
  }
3092
3115
  });
3093
3116
  input.addEventListener("keydown", (e) => {
3094
3117
  if (e.key === "Enter") {
3095
- handleSelect(e.target.value);
3118
+ if (e.target.value.trim()) {
3119
+ handleSelect(e.target.value.trim());
3120
+ }
3096
3121
  e.target.blur();
3097
3122
  }
3098
3123
  });
3099
3124
  } else {
3100
3125
  const inputEl = customFieldContainer.querySelector("input");
3101
3126
  if (inputEl && document.activeElement !== inputEl) {
3102
- inputEl.value = !isStandard ? selectedValue : "";
3127
+ inputEl.value = !isStandard ? primaryCustomValue : "";
3103
3128
  }
3104
3129
  }
3105
3130
  customFieldContainer.style.display = "block";
@@ -3111,17 +3136,41 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3111
3136
  }
3112
3137
  };
3113
3138
  const handleSelect = (val) => {
3114
- selectedValue = val;
3115
- container.setAttribute("data-selected", val);
3139
+ if (!val) return;
3140
+ let finalVal = val;
3141
+ if (isMultiple) {
3142
+ const normSelected = getNormalizedSelected();
3143
+ let newSelected;
3144
+ if (normSelected.includes(val)) {
3145
+ newSelected = normSelected.filter((v) => v !== val);
3146
+ } else {
3147
+ newSelected = [...normSelected, val];
3148
+ }
3149
+ finalVal = newSelected;
3150
+ selectedValue = newSelected.join(",");
3151
+ } else {
3152
+ selectedValue = val;
3153
+ }
3154
+ container.setAttribute("data-selected", selectedValue);
3116
3155
  updateUI();
3117
3156
  container.dispatchEvent(
3118
3157
  new CustomEvent("chip:select", {
3119
- detail: { value: val },
3158
+ detail: { value: finalVal },
3120
3159
  bubbles: true
3121
3160
  })
3122
3161
  );
3123
3162
  };
3124
- items.forEach((item) => {
3163
+ let currentFocusedIndex = -1;
3164
+ const setItemFocus = (index2) => {
3165
+ items.forEach((item, i) => {
3166
+ item.setAttribute("tabindex", i === index2 ? "0" : "-1");
3167
+ });
3168
+ if (items[index2]) {
3169
+ items[index2].focus();
3170
+ currentFocusedIndex = index2;
3171
+ }
3172
+ };
3173
+ items.forEach((item, index2) => {
3125
3174
  item.addEventListener("click", (e) => {
3126
3175
  const val = item.getAttribute("data-value");
3127
3176
  const label = item.textContent.trim();
@@ -3131,6 +3180,39 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3131
3180
  handleSelect(val);
3132
3181
  }
3133
3182
  });
3183
+ item.addEventListener("focus", () => {
3184
+ currentFocusedIndex = index2;
3185
+ });
3186
+ item.addEventListener("keydown", (e) => {
3187
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") {
3188
+ e.preventDefault();
3189
+ const nextIndex = (index2 + 1) % items.length;
3190
+ setItemFocus(nextIndex);
3191
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
3192
+ e.preventDefault();
3193
+ const prevIndex = (index2 - 1 + items.length) % items.length;
3194
+ setItemFocus(prevIndex);
3195
+ }
3196
+ if (e.key === " " || e.key === "Enter") {
3197
+ e.preventDefault();
3198
+ const val = item.getAttribute("data-value");
3199
+ const label = item.textContent.trim();
3200
+ if (showCustomization && label === customizationLabel) {
3201
+ handleSelect(val);
3202
+ setTimeout(() => {
3203
+ const customFieldContainer2 = container.querySelector(
3204
+ `.${PREFIX5}-chip__custom-field`
3205
+ );
3206
+ if (customFieldContainer2) {
3207
+ const inputEl = customFieldContainer2.querySelector("input");
3208
+ if (inputEl) inputEl.focus();
3209
+ }
3210
+ }, 50);
3211
+ } else {
3212
+ handleSelect(val);
3213
+ }
3214
+ }
3215
+ });
3134
3216
  });
3135
3217
  updateUI();
3136
3218
  container.__inaChipInitialized = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idds/js",
3
- "version": "1.0.99",
3
+ "version": "1.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },