@idds/js 1.0.99 → 1.2.1

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,66 @@ 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
+ );
2994
+ const isDisabled = item.hasAttribute("disabled");
2969
2995
  if (isSelected) {
2970
2996
  item.classList.add(`${PREFIX4}-chip__item--selected`);
2971
2997
  } else {
2972
2998
  item.classList.remove(`${PREFIX4}-chip__item--selected`);
2973
2999
  }
3000
+ if (isDisabled) {
3001
+ item.classList.add(`${PREFIX4}-chip__item--disabled`);
3002
+ }
3003
+ item.setAttribute(
3004
+ "tabindex",
3005
+ index2 === focusedIndex && !isDisabled ? "0" : "-1"
3006
+ );
2974
3007
  });
2975
3008
  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
- });
3009
+ const standardValues = Array.from(items).filter((item) => item.textContent.trim() !== customizationLabel).map((item) => item.getAttribute("data-value"));
3010
+ const customValues = normSelected.filter(
3011
+ (val) => !standardValues.includes(val) && val !== ""
3012
+ );
3013
+ const isStandard = customValues.length === 0;
3014
+ const primaryCustomValue = customValues[customValues.length - 1] || "";
2983
3015
  const toggleBtn = Array.from(items).find(
2984
3016
  (i) => i.textContent.trim() === customizationLabel
2985
3017
  );
2986
- const showInput = toggleBtn && selectedValue === toggleBtn.getAttribute("data-value") || !isStandard && selectedValue !== "";
3018
+ const showInput = toggleBtn && normSelected.includes(toggleBtn.getAttribute("data-value")) || !isStandard && normSelected.length > 0;
2987
3019
  if (showInput) {
2988
3020
  if (!customFieldContainer) {
2989
3021
  customFieldContainer = document.createElement("div");
@@ -2997,7 +3029,7 @@ var InaUI = (() => {
2997
3029
  customFieldContainer.innerHTML = `
2998
3030
  <div class="${PREFIX4}-text-field ${PREFIX4}-text-field--size-medium ${PREFIX4}-text-field--variant-outline ${PREFIX4}-chip__input">
2999
3031
  <div class="${PREFIX4}-text-field__wrapper">
3000
- <input type="text" class="${PREFIX4}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? selectedValue : ""}" />
3032
+ <input type="text" class="${PREFIX4}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? primaryCustomValue : ""}" />
3001
3033
  </div>
3002
3034
  </div>
3003
3035
  `;
@@ -3005,21 +3037,21 @@ var InaUI = (() => {
3005
3037
  input.addEventListener("blur", (e) => {
3006
3038
  const val = e.target.value;
3007
3039
  if (val.trim()) {
3008
- handleSelect(val);
3009
- } else {
3010
- handleSelect("");
3040
+ handleSelect(val.trim());
3011
3041
  }
3012
3042
  });
3013
3043
  input.addEventListener("keydown", (e) => {
3014
3044
  if (e.key === "Enter") {
3015
- handleSelect(e.target.value);
3045
+ if (e.target.value.trim()) {
3046
+ handleSelect(e.target.value.trim());
3047
+ }
3016
3048
  e.target.blur();
3017
3049
  }
3018
3050
  });
3019
3051
  } else {
3020
3052
  const inputEl = customFieldContainer.querySelector("input");
3021
3053
  if (inputEl && document.activeElement !== inputEl) {
3022
- inputEl.value = !isStandard ? selectedValue : "";
3054
+ inputEl.value = !isStandard ? primaryCustomValue : "";
3023
3055
  }
3024
3056
  }
3025
3057
  customFieldContainer.style.display = "block";
@@ -3031,18 +3063,50 @@ var InaUI = (() => {
3031
3063
  }
3032
3064
  };
3033
3065
  const handleSelect = (val) => {
3034
- selectedValue = val;
3035
- container.setAttribute("data-selected", val);
3066
+ if (!val) return;
3067
+ let finalVal = val;
3068
+ if (isMultiple) {
3069
+ const normSelected = getNormalizedSelected();
3070
+ let newSelected;
3071
+ if (normSelected.includes(val)) {
3072
+ newSelected = normSelected.filter((v) => v !== val);
3073
+ } else {
3074
+ newSelected = [...normSelected, val];
3075
+ }
3076
+ finalVal = newSelected;
3077
+ selectedValue = newSelected.join(",");
3078
+ } else {
3079
+ const normSelected = getNormalizedSelected();
3080
+ if (normSelected.includes(val)) {
3081
+ selectedValue = "";
3082
+ finalVal = "";
3083
+ } else {
3084
+ selectedValue = val;
3085
+ }
3086
+ }
3087
+ container.setAttribute("data-selected", selectedValue);
3036
3088
  updateUI();
3037
3089
  container.dispatchEvent(
3038
3090
  new CustomEvent("chip:select", {
3039
- detail: { value: val },
3091
+ detail: { value: finalVal },
3040
3092
  bubbles: true
3041
3093
  })
3042
3094
  );
3043
3095
  };
3044
- items.forEach((item) => {
3096
+ let currentFocusedIndex = -1;
3097
+ const setItemFocus = (index2) => {
3098
+ items.forEach((item, i) => {
3099
+ item.setAttribute("tabindex", i === index2 ? "0" : "-1");
3100
+ });
3101
+ if (items[index2]) {
3102
+ items[index2].focus();
3103
+ currentFocusedIndex = index2;
3104
+ }
3105
+ };
3106
+ items.forEach((item, index2) => {
3045
3107
  item.addEventListener("click", (e) => {
3108
+ if (item.hasAttribute("disabled")) return;
3109
+ currentFocusedIndex = index2;
3046
3110
  const val = item.getAttribute("data-value");
3047
3111
  const label = item.textContent.trim();
3048
3112
  if (showCustomization && label === customizationLabel) {
@@ -3051,6 +3115,43 @@ var InaUI = (() => {
3051
3115
  handleSelect(val);
3052
3116
  }
3053
3117
  });
3118
+ item.addEventListener("keydown", (e) => {
3119
+ if (item.hasAttribute("disabled")) return;
3120
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") {
3121
+ e.preventDefault();
3122
+ let nextIndex = (index2 + 1) % items.length;
3123
+ while (items[nextIndex].hasAttribute("disabled") && nextIndex !== index2) {
3124
+ nextIndex = (nextIndex + 1) % items.length;
3125
+ }
3126
+ setItemFocus(nextIndex);
3127
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
3128
+ e.preventDefault();
3129
+ let prevIndex = (index2 - 1 + items.length) % items.length;
3130
+ while (items[prevIndex].hasAttribute("disabled") && prevIndex !== index2) {
3131
+ prevIndex = (prevIndex - 1 + items.length) % items.length;
3132
+ }
3133
+ setItemFocus(prevIndex);
3134
+ }
3135
+ if (e.key === " " || e.key === "Enter") {
3136
+ e.preventDefault();
3137
+ const val = item.getAttribute("data-value");
3138
+ const label = item.textContent.trim();
3139
+ if (showCustomization && label === customizationLabel) {
3140
+ handleSelect(val);
3141
+ setTimeout(() => {
3142
+ const customFieldContainer2 = container.querySelector(
3143
+ `.${PREFIX4}-chip__custom-field`
3144
+ );
3145
+ if (customFieldContainer2) {
3146
+ const inputEl = customFieldContainer2.querySelector("input");
3147
+ if (inputEl) inputEl.focus();
3148
+ }
3149
+ }, 50);
3150
+ } else {
3151
+ handleSelect(val);
3152
+ }
3153
+ }
3154
+ });
3054
3155
  });
3055
3156
  updateUI();
3056
3157
  container.__inaChipInitialized = true;
package/dist/index.js CHANGED
@@ -3036,34 +3036,66 @@ 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
+ );
3074
+ const isDisabled = item.hasAttribute("disabled");
3049
3075
  if (isSelected) {
3050
3076
  item.classList.add(`${PREFIX5}-chip__item--selected`);
3051
3077
  } else {
3052
3078
  item.classList.remove(`${PREFIX5}-chip__item--selected`);
3053
3079
  }
3080
+ if (isDisabled) {
3081
+ item.classList.add(`${PREFIX5}-chip__item--disabled`);
3082
+ }
3083
+ item.setAttribute(
3084
+ "tabindex",
3085
+ index2 === focusedIndex && !isDisabled ? "0" : "-1"
3086
+ );
3054
3087
  });
3055
3088
  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
- });
3089
+ const standardValues = Array.from(items).filter((item) => item.textContent.trim() !== customizationLabel).map((item) => item.getAttribute("data-value"));
3090
+ const customValues = normSelected.filter(
3091
+ (val) => !standardValues.includes(val) && val !== ""
3092
+ );
3093
+ const isStandard = customValues.length === 0;
3094
+ const primaryCustomValue = customValues[customValues.length - 1] || "";
3063
3095
  const toggleBtn = Array.from(items).find(
3064
3096
  (i) => i.textContent.trim() === customizationLabel
3065
3097
  );
3066
- const showInput = toggleBtn && selectedValue === toggleBtn.getAttribute("data-value") || !isStandard && selectedValue !== "";
3098
+ const showInput = toggleBtn && normSelected.includes(toggleBtn.getAttribute("data-value")) || !isStandard && normSelected.length > 0;
3067
3099
  if (showInput) {
3068
3100
  if (!customFieldContainer) {
3069
3101
  customFieldContainer = document.createElement("div");
@@ -3077,7 +3109,7 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3077
3109
  customFieldContainer.innerHTML = `
3078
3110
  <div class="${PREFIX5}-text-field ${PREFIX5}-text-field--size-medium ${PREFIX5}-text-field--variant-outline ${PREFIX5}-chip__input">
3079
3111
  <div class="${PREFIX5}-text-field__wrapper">
3080
- <input type="text" class="${PREFIX5}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? selectedValue : ""}" />
3112
+ <input type="text" class="${PREFIX5}-text-field__input" placeholder="Masukkan data yang Anda inginkan" value="${!isStandard ? primaryCustomValue : ""}" />
3081
3113
  </div>
3082
3114
  </div>
3083
3115
  `;
@@ -3085,21 +3117,21 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3085
3117
  input.addEventListener("blur", (e) => {
3086
3118
  const val = e.target.value;
3087
3119
  if (val.trim()) {
3088
- handleSelect(val);
3089
- } else {
3090
- handleSelect("");
3120
+ handleSelect(val.trim());
3091
3121
  }
3092
3122
  });
3093
3123
  input.addEventListener("keydown", (e) => {
3094
3124
  if (e.key === "Enter") {
3095
- handleSelect(e.target.value);
3125
+ if (e.target.value.trim()) {
3126
+ handleSelect(e.target.value.trim());
3127
+ }
3096
3128
  e.target.blur();
3097
3129
  }
3098
3130
  });
3099
3131
  } else {
3100
3132
  const inputEl = customFieldContainer.querySelector("input");
3101
3133
  if (inputEl && document.activeElement !== inputEl) {
3102
- inputEl.value = !isStandard ? selectedValue : "";
3134
+ inputEl.value = !isStandard ? primaryCustomValue : "";
3103
3135
  }
3104
3136
  }
3105
3137
  customFieldContainer.style.display = "block";
@@ -3111,18 +3143,50 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3111
3143
  }
3112
3144
  };
3113
3145
  const handleSelect = (val) => {
3114
- selectedValue = val;
3115
- container.setAttribute("data-selected", val);
3146
+ if (!val) return;
3147
+ let finalVal = val;
3148
+ if (isMultiple) {
3149
+ const normSelected = getNormalizedSelected();
3150
+ let newSelected;
3151
+ if (normSelected.includes(val)) {
3152
+ newSelected = normSelected.filter((v) => v !== val);
3153
+ } else {
3154
+ newSelected = [...normSelected, val];
3155
+ }
3156
+ finalVal = newSelected;
3157
+ selectedValue = newSelected.join(",");
3158
+ } else {
3159
+ const normSelected = getNormalizedSelected();
3160
+ if (normSelected.includes(val)) {
3161
+ selectedValue = "";
3162
+ finalVal = "";
3163
+ } else {
3164
+ selectedValue = val;
3165
+ }
3166
+ }
3167
+ container.setAttribute("data-selected", selectedValue);
3116
3168
  updateUI();
3117
3169
  container.dispatchEvent(
3118
3170
  new CustomEvent("chip:select", {
3119
- detail: { value: val },
3171
+ detail: { value: finalVal },
3120
3172
  bubbles: true
3121
3173
  })
3122
3174
  );
3123
3175
  };
3124
- items.forEach((item) => {
3176
+ let currentFocusedIndex = -1;
3177
+ const setItemFocus = (index2) => {
3178
+ items.forEach((item, i) => {
3179
+ item.setAttribute("tabindex", i === index2 ? "0" : "-1");
3180
+ });
3181
+ if (items[index2]) {
3182
+ items[index2].focus();
3183
+ currentFocusedIndex = index2;
3184
+ }
3185
+ };
3186
+ items.forEach((item, index2) => {
3125
3187
  item.addEventListener("click", (e) => {
3188
+ if (item.hasAttribute("disabled")) return;
3189
+ currentFocusedIndex = index2;
3126
3190
  const val = item.getAttribute("data-value");
3127
3191
  const label = item.textContent.trim();
3128
3192
  if (showCustomization && label === customizationLabel) {
@@ -3131,6 +3195,43 @@ function initChip(rootSelector = `.${PREFIX5}-chip`) {
3131
3195
  handleSelect(val);
3132
3196
  }
3133
3197
  });
3198
+ item.addEventListener("keydown", (e) => {
3199
+ if (item.hasAttribute("disabled")) return;
3200
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") {
3201
+ e.preventDefault();
3202
+ let nextIndex = (index2 + 1) % items.length;
3203
+ while (items[nextIndex].hasAttribute("disabled") && nextIndex !== index2) {
3204
+ nextIndex = (nextIndex + 1) % items.length;
3205
+ }
3206
+ setItemFocus(nextIndex);
3207
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
3208
+ e.preventDefault();
3209
+ let prevIndex = (index2 - 1 + items.length) % items.length;
3210
+ while (items[prevIndex].hasAttribute("disabled") && prevIndex !== index2) {
3211
+ prevIndex = (prevIndex - 1 + items.length) % items.length;
3212
+ }
3213
+ setItemFocus(prevIndex);
3214
+ }
3215
+ if (e.key === " " || e.key === "Enter") {
3216
+ e.preventDefault();
3217
+ const val = item.getAttribute("data-value");
3218
+ const label = item.textContent.trim();
3219
+ if (showCustomization && label === customizationLabel) {
3220
+ handleSelect(val);
3221
+ setTimeout(() => {
3222
+ const customFieldContainer2 = container.querySelector(
3223
+ `.${PREFIX5}-chip__custom-field`
3224
+ );
3225
+ if (customFieldContainer2) {
3226
+ const inputEl = customFieldContainer2.querySelector("input");
3227
+ if (inputEl) inputEl.focus();
3228
+ }
3229
+ }, 50);
3230
+ } else {
3231
+ handleSelect(val);
3232
+ }
3233
+ }
3234
+ });
3134
3235
  });
3135
3236
  updateUI();
3136
3237
  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.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },