@idds/js 1.0.34 → 1.0.36

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.
@@ -119,7 +119,7 @@ var InaUI = (() => {
119
119
 
120
120
  // src/js/components/stateful/datepicker.js
121
121
  function initDatepicker() {
122
- document.querySelectorAll(`.${PREFIX}-datepicker`).forEach((datepicker) => {
122
+ document.querySelectorAll(".ina-date-picker").forEach((datepicker) => {
123
123
  let currentDate = /* @__PURE__ */ new Date();
124
124
  let selectedDateTarget = null;
125
125
  let selectedDate = null;
@@ -139,59 +139,59 @@ var InaUI = (() => {
139
139
  ];
140
140
  const DAYS = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"];
141
141
  const datepickerTrigger = datepicker.querySelector(
142
- `.${PREFIX}-datepicker__trigger`
142
+ ".ina-date-picker__trigger"
143
143
  );
144
144
  const datepickerPopover = datepicker.querySelector(
145
- `.${PREFIX}-datepicker__popover`
145
+ ".ina-date-picker__popover"
146
146
  );
147
147
  const datepickerMonthTrigger = datepicker.querySelector(
148
- `.${PREFIX}-datepicker__month-trigger`
148
+ ".ina-date-picker__month-trigger"
149
149
  );
150
150
  const datepickerMonthPopover = datepicker.querySelector(
151
- `.${PREFIX}-datepicker__month-popover`
151
+ ".ina-date-picker__month-popover"
152
152
  );
153
153
  const datepickerMonthItem = datepicker.querySelectorAll(
154
- `.${PREFIX}-datepicker__month-item`
154
+ ".ina-date-picker__month-item"
155
155
  );
156
156
  const datepickerYearTrigger = datepicker.querySelector(
157
- `.${PREFIX}-datepicker__year-trigger`
157
+ ".ina-date-picker__year-trigger"
158
158
  );
159
159
  const datepickerYearPopover = datepicker.querySelector(
160
- `.${PREFIX}-datepicker__year-popover`
160
+ ".ina-date-picker__year-popover"
161
161
  );
162
162
  const datepickerYearPrevButton = datepicker.querySelector(
163
- `.${PREFIX}-datepicker__year-nav-prev`
163
+ ".ina-date-picker__year-nav-prev"
164
164
  );
165
165
  const datepickerYearCurrent = datepicker.querySelector(
166
- `.${PREFIX}-datepicker__year-current`
166
+ ".ina-date-picker__year-current"
167
167
  );
168
168
  const datepickerYearNextButton = datepicker.querySelector(
169
- `.${PREFIX}-datepicker__year-nav-next`
169
+ ".ina-date-picker__year-nav-next"
170
170
  );
171
171
  const datepickerYearContent = datepicker.querySelector(
172
- `.${PREFIX}-datepicker__year-content`
172
+ ".ina-date-picker__year-content"
173
173
  );
174
174
  const datepickerYearItem = datepicker.querySelectorAll(
175
- `.${PREFIX}-datepicker__year-item`
175
+ ".ina-date-picker__year-item"
176
176
  );
177
177
  const datepickerContent = datepicker.querySelector(
178
- `.${PREFIX}-datepicker__content`
178
+ ".ina-date-picker__content"
179
179
  );
180
180
  const prevMonthButton = datepicker.querySelector(
181
- `.${PREFIX}-datepicker__nav-prev`
181
+ ".ina-date-picker__nav-prev"
182
182
  );
183
183
  const nextMonthButton = datepicker.querySelector(
184
- `.${PREFIX}-datepicker__nav-next`
184
+ ".ina-date-picker__nav-next"
185
185
  );
186
186
  const datepickerSubmitButton = datepicker.querySelector(
187
- `.${PREFIX}-datepicker__submit`
187
+ ".ina-date-picker__submit"
188
188
  );
189
189
  function renderYear(startYear, endYear) {
190
190
  datepickerYearContent.innerHTML = "";
191
191
  datepickerYearCurrent.textContent = `${startYear} - ${endYear}`;
192
192
  for (let y = startYear; y <= endYear; y++) {
193
193
  const yearEl = document.createElement("button");
194
- yearEl.className = `${PREFIX}-datepicker__year-item`;
194
+ yearEl.className = "ina-date-picker__year-item";
195
195
  yearEl.textContent = y;
196
196
  yearEl.dataset.year = y;
197
197
  if (y === currentDate.getFullYear()) {
@@ -206,9 +206,9 @@ var InaUI = (() => {
206
206
  datepickerYearTrigger.textContent = year;
207
207
  DAYS.forEach((day) => {
208
208
  const dayNameWrapper = document.createElement("div");
209
- dayNameWrapper.className = `${PREFIX}-datepicker__dayname-wrapper`;
209
+ dayNameWrapper.className = "ina-date-picker__dayname-wrapper";
210
210
  const dayNameEl = document.createElement("span");
211
- dayNameEl.className = `${PREFIX}-datepicker__dayname`;
211
+ dayNameEl.className = "ina-date-picker__dayname";
212
212
  dayNameEl.textContent = day.substring(0, 3);
213
213
  dayNameWrapper.appendChild(dayNameEl);
214
214
  datepickerContent.appendChild(dayNameWrapper);
@@ -218,7 +218,7 @@ var InaUI = (() => {
218
218
  const daysInPrevMonth = new Date(year, month, 0).getDate();
219
219
  for (let i = 0; i < firstDayOfMonth; i++) {
220
220
  const dayEl = document.createElement("button");
221
- dayEl.className = `${PREFIX}-datepicker__calendar-day outside-month`;
221
+ dayEl.className = "ina-date-picker__calendar-day outside-month";
222
222
  dayEl.textContent = daysInPrevMonth - firstDayOfMonth + 1 + i;
223
223
  dayEl.disabled = true;
224
224
  datepickerContent.appendChild(dayEl);
@@ -226,12 +226,12 @@ var InaUI = (() => {
226
226
  const today = /* @__PURE__ */ new Date();
227
227
  for (let i = 1; i <= daysInMonth; i++) {
228
228
  const dayEl = document.createElement("button");
229
- dayEl.className = `${PREFIX}-datepicker__calendar-day`;
229
+ dayEl.className = "ina-date-picker__calendar-day";
230
230
  dayEl.textContent = i;
231
231
  dayEl.dataset.date = new Date(year, month, i).toISOString();
232
232
  if (year === today.getFullYear() && month === today.getMonth() && i === today.getDate()) {
233
233
  const marker = document.createElement("span");
234
- marker.className = `${PREFIX}-datepicker__today-marker`;
234
+ marker.className = "ina-date-picker__today-marker";
235
235
  marker.textContent = "Hari ini";
236
236
  dayEl.appendChild(marker);
237
237
  dayEl.classList.add("today");
@@ -246,7 +246,7 @@ var InaUI = (() => {
246
246
  const remainingCells = totalCells - cellsRendered;
247
247
  for (let i = 1; i <= remainingCells; i++) {
248
248
  const dayEl = document.createElement("button");
249
- dayEl.className = `${PREFIX}-datepicker__calendar-day outside-month`;
249
+ dayEl.className = "ina-date-picker__calendar-day outside-month";
250
250
  dayEl.textContent = i;
251
251
  dayEl.disabled = true;
252
252
  datepickerContent.appendChild(dayEl);
@@ -254,7 +254,7 @@ var InaUI = (() => {
254
254
  datepickerMonthPopover.innerHTML = "";
255
255
  MONTHS.forEach((monthName, index) => {
256
256
  const monthEl = document.createElement("button");
257
- monthEl.className = `${PREFIX}-datepicker__month-item`;
257
+ monthEl.className = "ina-date-picker__month-item";
258
258
  monthEl.textContent = monthName.substring(0, 3);
259
259
  monthEl.dataset.month = index;
260
260
  if (index === month) {
@@ -268,7 +268,7 @@ var InaUI = (() => {
268
268
  datepickerYearCurrent.textContent = `${startYear} - ${endYear}`;
269
269
  for (let y = startYear; y <= endYear; y++) {
270
270
  const yearEl = document.createElement("button");
271
- yearEl.className = `${PREFIX}-datepicker__year-item`;
271
+ yearEl.className = "ina-date-picker__year-item";
272
272
  yearEl.textContent = y;
273
273
  yearEl.dataset.year = y;
274
274
  if (y === year) {
@@ -337,7 +337,7 @@ var InaUI = (() => {
337
337
  datepickerMonthPopover.addEventListener("click", (e) => {
338
338
  e.stopPropagation();
339
339
  const target = e.target;
340
- if (target.classList.contains(`${PREFIX}-datepicker__month-item`)) {
340
+ if (target.classList.contains("ina-date-picker__month-item")) {
341
341
  const monthIndex = parseInt(target.dataset.month);
342
342
  currentDate.setMonth(monthIndex);
343
343
  renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
@@ -347,12 +347,12 @@ var InaUI = (() => {
347
347
  datepickerYearPopover.addEventListener("click", (e) => {
348
348
  e.stopPropagation();
349
349
  const target = e.target;
350
- if (target.classList.contains(`${PREFIX}-datepicker__year-nav-prev`)) {
350
+ if (target.classList.contains("ina-date-picker__year-nav-prev")) {
351
351
  const currentYearRange = datepickerYearCurrent.textContent.split(" - ").map((y) => parseInt(y));
352
352
  const newStartYear = currentYearRange[0] - 20;
353
353
  const newEndYear = currentYearRange[1] - 20;
354
354
  renderYear(newStartYear, newEndYear);
355
- } else if (target.classList.contains(`${PREFIX}-datepicker__year-nav-next`)) {
355
+ } else if (target.classList.contains("ina-date-picker__year-nav-next")) {
356
356
  const currentYearRange = datepickerYearCurrent.textContent.split(" - ").map((y) => parseInt(y));
357
357
  const newStartYear = currentYearRange[0] + 20;
358
358
  const newEndYear = currentYearRange[1] + 20;
@@ -362,7 +362,7 @@ var InaUI = (() => {
362
362
  datepickerYearContent.addEventListener("click", (e) => {
363
363
  e.stopPropagation();
364
364
  const target = e.target;
365
- if (target.classList.contains(`${PREFIX}-datepicker__year-item`)) {
365
+ if (target.classList.contains("ina-date-picker__year-item")) {
366
366
  const yearValue = parseInt(target.dataset.year);
367
367
  currentDate.setFullYear(yearValue);
368
368
  renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
@@ -371,13 +371,13 @@ var InaUI = (() => {
371
371
  });
372
372
  datepickerContent.addEventListener("click", (e) => {
373
373
  const target = e.target;
374
- if (target.classList.contains(`${PREFIX}-datepicker__calendar-day`) && !target.classList.contains("outside-month")) {
374
+ if (target.classList.contains("ina-date-picker__calendar-day") && !target.classList.contains("outside-month")) {
375
375
  if (target.classList.contains("selected")) {
376
376
  target.classList.remove("selected");
377
377
  selectedDateTarget = null;
378
378
  } else {
379
379
  const selectedDateEl = datepickerContent.querySelector(
380
- `.${PREFIX}-datepicker__calendar-day.selected`
380
+ ".ina-date-picker__calendar-day.selected"
381
381
  );
382
382
  selectedDateEl?.classList.remove("selected");
383
383
  target.classList.add("selected");
@@ -1214,31 +1214,72 @@ var InaUI = (() => {
1214
1214
  }
1215
1215
 
1216
1216
  // src/js/components/stateless/toast.js
1217
- function showToast(message, variant = "default", duration = 3e3) {
1218
- const toastContainer = document.createElement("div");
1219
- toastContainer.className = "ina-ss-toast--container";
1217
+ function showToast(optionsOrMessage, variant = "default", duration = 3e3) {
1218
+ let message, title, state, style, position, actionHtml;
1219
+ if (typeof optionsOrMessage === "object") {
1220
+ message = optionsOrMessage.message || "";
1221
+ title = optionsOrMessage.title;
1222
+ state = optionsOrMessage.state || "default";
1223
+ style = optionsOrMessage.style || "solid";
1224
+ duration = optionsOrMessage.duration || 3e3;
1225
+ position = optionsOrMessage.position || "top-right";
1226
+ actionHtml = optionsOrMessage.actionHtml || "";
1227
+ } else {
1228
+ message = optionsOrMessage;
1229
+ state = variant;
1230
+ style = "solid";
1231
+ position = "top-right";
1232
+ actionHtml = "";
1233
+ }
1234
+ let containerId = `ina-toast-container-${position}`;
1235
+ let container = document.getElementById(containerId);
1236
+ if (!container) {
1237
+ container = document.createElement("div");
1238
+ container.id = containerId;
1239
+ container.className = `ina-toast-container ina-toast-container--${position}`;
1240
+ document.body.appendChild(container);
1241
+ }
1242
+ const toastItem = document.createElement("div");
1243
+ toastItem.className = "ina-toast-item";
1220
1244
  const toast = document.createElement("div");
1221
- toast.className = `ina-ss-toast ina-ss-toast--${variant}`;
1222
- const iconEl = document.createElement("div");
1223
- iconEl.className = "ina-ss-toast__icon";
1224
- toast.appendChild(iconEl);
1225
- const contentEl = document.createElement("span");
1226
- contentEl.textContent = message;
1227
- toast.appendChild(contentEl);
1228
- const closeEl = document.createElement("button");
1229
- closeEl.className = "ina-ss-toast__close";
1230
- toast.appendChild(closeEl);
1231
- closeEl.addEventListener("click", () => {
1232
- toast.classList.remove("show");
1233
- toast.addEventListener("transitionend", () => toast.remove());
1234
- });
1235
- toastContainer.appendChild(toast);
1236
- document.body.appendChild(toastContainer);
1237
- requestAnimationFrame(() => toast.classList.add("show"));
1238
- setTimeout(() => {
1239
- toast.classList.remove("show");
1240
- toast.addEventListener("transitionend", () => toast.remove());
1241
- }, duration);
1245
+ toast.className = `ina-toast ina-toast--state-${state} ina-toast--style-${style} ina-toast--visible`;
1246
+ const iconMap = {
1247
+ default: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>',
1248
+ destructive: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',
1249
+ positive: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>'
1250
+ };
1251
+ const iconHtml = iconMap[state] || iconMap.default;
1252
+ let contentHtml = `
1253
+ <div class="ina-toast__icon">${iconHtml}</div>
1254
+ <div class="ina-toast__content">
1255
+ <div class="ina-toast__text-area">
1256
+ ${title ? `<p class="ina-toast__title">${title}</p>` : ""}
1257
+ ${message ? `<p class="ina-toast__description">${message}</p>` : ""}
1258
+ </div>
1259
+ ${actionHtml ? `<div class="ina-toast__action-area">${actionHtml}</div>` : ""}
1260
+ </div>
1261
+ <button class="ina-toast__close-button">
1262
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="ina-toast__close-icon"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
1263
+ </button>
1264
+ `;
1265
+ toast.innerHTML = contentHtml;
1266
+ toastItem.appendChild(toast);
1267
+ const closeBtn = toast.querySelector(".ina-toast__close-button");
1268
+ const close = () => {
1269
+ toast.classList.remove("ina-toast--visible");
1270
+ toast.classList.add("ina-toast--hidden");
1271
+ setTimeout(() => {
1272
+ if (toastItem.parentNode) toastItem.parentNode.removeChild(toastItem);
1273
+ if (container.children.length === 0) {
1274
+ if (container.parentNode) container.parentNode.removeChild(container);
1275
+ }
1276
+ }, 300);
1277
+ };
1278
+ closeBtn.addEventListener("click", close);
1279
+ container.appendChild(toastItem);
1280
+ if (duration > 0) {
1281
+ setTimeout(close, duration);
1282
+ }
1242
1283
  }
1243
1284
 
1244
1285
  // src/js/bundle.js
package/dist/index.js CHANGED
@@ -108,7 +108,7 @@ function initAccordion(rootSelector = `.${PREFIX}-accordion`) {
108
108
 
109
109
  // src/js/components/stateful/datepicker.js
110
110
  function initDatepicker() {
111
- document.querySelectorAll(`.${PREFIX}-datepicker`).forEach((datepicker) => {
111
+ document.querySelectorAll(".ina-date-picker").forEach((datepicker) => {
112
112
  let currentDate = /* @__PURE__ */ new Date();
113
113
  let selectedDateTarget = null;
114
114
  let selectedDate = null;
@@ -128,59 +128,59 @@ function initDatepicker() {
128
128
  ];
129
129
  const DAYS = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"];
130
130
  const datepickerTrigger = datepicker.querySelector(
131
- `.${PREFIX}-datepicker__trigger`
131
+ ".ina-date-picker__trigger"
132
132
  );
133
133
  const datepickerPopover = datepicker.querySelector(
134
- `.${PREFIX}-datepicker__popover`
134
+ ".ina-date-picker__popover"
135
135
  );
136
136
  const datepickerMonthTrigger = datepicker.querySelector(
137
- `.${PREFIX}-datepicker__month-trigger`
137
+ ".ina-date-picker__month-trigger"
138
138
  );
139
139
  const datepickerMonthPopover = datepicker.querySelector(
140
- `.${PREFIX}-datepicker__month-popover`
140
+ ".ina-date-picker__month-popover"
141
141
  );
142
142
  const datepickerMonthItem = datepicker.querySelectorAll(
143
- `.${PREFIX}-datepicker__month-item`
143
+ ".ina-date-picker__month-item"
144
144
  );
145
145
  const datepickerYearTrigger = datepicker.querySelector(
146
- `.${PREFIX}-datepicker__year-trigger`
146
+ ".ina-date-picker__year-trigger"
147
147
  );
148
148
  const datepickerYearPopover = datepicker.querySelector(
149
- `.${PREFIX}-datepicker__year-popover`
149
+ ".ina-date-picker__year-popover"
150
150
  );
151
151
  const datepickerYearPrevButton = datepicker.querySelector(
152
- `.${PREFIX}-datepicker__year-nav-prev`
152
+ ".ina-date-picker__year-nav-prev"
153
153
  );
154
154
  const datepickerYearCurrent = datepicker.querySelector(
155
- `.${PREFIX}-datepicker__year-current`
155
+ ".ina-date-picker__year-current"
156
156
  );
157
157
  const datepickerYearNextButton = datepicker.querySelector(
158
- `.${PREFIX}-datepicker__year-nav-next`
158
+ ".ina-date-picker__year-nav-next"
159
159
  );
160
160
  const datepickerYearContent = datepicker.querySelector(
161
- `.${PREFIX}-datepicker__year-content`
161
+ ".ina-date-picker__year-content"
162
162
  );
163
163
  const datepickerYearItem = datepicker.querySelectorAll(
164
- `.${PREFIX}-datepicker__year-item`
164
+ ".ina-date-picker__year-item"
165
165
  );
166
166
  const datepickerContent = datepicker.querySelector(
167
- `.${PREFIX}-datepicker__content`
167
+ ".ina-date-picker__content"
168
168
  );
169
169
  const prevMonthButton = datepicker.querySelector(
170
- `.${PREFIX}-datepicker__nav-prev`
170
+ ".ina-date-picker__nav-prev"
171
171
  );
172
172
  const nextMonthButton = datepicker.querySelector(
173
- `.${PREFIX}-datepicker__nav-next`
173
+ ".ina-date-picker__nav-next"
174
174
  );
175
175
  const datepickerSubmitButton = datepicker.querySelector(
176
- `.${PREFIX}-datepicker__submit`
176
+ ".ina-date-picker__submit"
177
177
  );
178
178
  function renderYear(startYear, endYear) {
179
179
  datepickerYearContent.innerHTML = "";
180
180
  datepickerYearCurrent.textContent = `${startYear} - ${endYear}`;
181
181
  for (let y = startYear; y <= endYear; y++) {
182
182
  const yearEl = document.createElement("button");
183
- yearEl.className = `${PREFIX}-datepicker__year-item`;
183
+ yearEl.className = "ina-date-picker__year-item";
184
184
  yearEl.textContent = y;
185
185
  yearEl.dataset.year = y;
186
186
  if (y === currentDate.getFullYear()) {
@@ -195,9 +195,9 @@ function initDatepicker() {
195
195
  datepickerYearTrigger.textContent = year;
196
196
  DAYS.forEach((day) => {
197
197
  const dayNameWrapper = document.createElement("div");
198
- dayNameWrapper.className = `${PREFIX}-datepicker__dayname-wrapper`;
198
+ dayNameWrapper.className = "ina-date-picker__dayname-wrapper";
199
199
  const dayNameEl = document.createElement("span");
200
- dayNameEl.className = `${PREFIX}-datepicker__dayname`;
200
+ dayNameEl.className = "ina-date-picker__dayname";
201
201
  dayNameEl.textContent = day.substring(0, 3);
202
202
  dayNameWrapper.appendChild(dayNameEl);
203
203
  datepickerContent.appendChild(dayNameWrapper);
@@ -207,7 +207,7 @@ function initDatepicker() {
207
207
  const daysInPrevMonth = new Date(year, month, 0).getDate();
208
208
  for (let i = 0; i < firstDayOfMonth; i++) {
209
209
  const dayEl = document.createElement("button");
210
- dayEl.className = `${PREFIX}-datepicker__calendar-day outside-month`;
210
+ dayEl.className = "ina-date-picker__calendar-day outside-month";
211
211
  dayEl.textContent = daysInPrevMonth - firstDayOfMonth + 1 + i;
212
212
  dayEl.disabled = true;
213
213
  datepickerContent.appendChild(dayEl);
@@ -215,12 +215,12 @@ function initDatepicker() {
215
215
  const today = /* @__PURE__ */ new Date();
216
216
  for (let i = 1; i <= daysInMonth; i++) {
217
217
  const dayEl = document.createElement("button");
218
- dayEl.className = `${PREFIX}-datepicker__calendar-day`;
218
+ dayEl.className = "ina-date-picker__calendar-day";
219
219
  dayEl.textContent = i;
220
220
  dayEl.dataset.date = new Date(year, month, i).toISOString();
221
221
  if (year === today.getFullYear() && month === today.getMonth() && i === today.getDate()) {
222
222
  const marker = document.createElement("span");
223
- marker.className = `${PREFIX}-datepicker__today-marker`;
223
+ marker.className = "ina-date-picker__today-marker";
224
224
  marker.textContent = "Hari ini";
225
225
  dayEl.appendChild(marker);
226
226
  dayEl.classList.add("today");
@@ -235,7 +235,7 @@ function initDatepicker() {
235
235
  const remainingCells = totalCells - cellsRendered;
236
236
  for (let i = 1; i <= remainingCells; i++) {
237
237
  const dayEl = document.createElement("button");
238
- dayEl.className = `${PREFIX}-datepicker__calendar-day outside-month`;
238
+ dayEl.className = "ina-date-picker__calendar-day outside-month";
239
239
  dayEl.textContent = i;
240
240
  dayEl.disabled = true;
241
241
  datepickerContent.appendChild(dayEl);
@@ -243,7 +243,7 @@ function initDatepicker() {
243
243
  datepickerMonthPopover.innerHTML = "";
244
244
  MONTHS.forEach((monthName, index) => {
245
245
  const monthEl = document.createElement("button");
246
- monthEl.className = `${PREFIX}-datepicker__month-item`;
246
+ monthEl.className = "ina-date-picker__month-item";
247
247
  monthEl.textContent = monthName.substring(0, 3);
248
248
  monthEl.dataset.month = index;
249
249
  if (index === month) {
@@ -257,7 +257,7 @@ function initDatepicker() {
257
257
  datepickerYearCurrent.textContent = `${startYear} - ${endYear}`;
258
258
  for (let y = startYear; y <= endYear; y++) {
259
259
  const yearEl = document.createElement("button");
260
- yearEl.className = `${PREFIX}-datepicker__year-item`;
260
+ yearEl.className = "ina-date-picker__year-item";
261
261
  yearEl.textContent = y;
262
262
  yearEl.dataset.year = y;
263
263
  if (y === year) {
@@ -326,7 +326,7 @@ function initDatepicker() {
326
326
  datepickerMonthPopover.addEventListener("click", (e) => {
327
327
  e.stopPropagation();
328
328
  const target = e.target;
329
- if (target.classList.contains(`${PREFIX}-datepicker__month-item`)) {
329
+ if (target.classList.contains("ina-date-picker__month-item")) {
330
330
  const monthIndex = parseInt(target.dataset.month);
331
331
  currentDate.setMonth(monthIndex);
332
332
  renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
@@ -336,12 +336,12 @@ function initDatepicker() {
336
336
  datepickerYearPopover.addEventListener("click", (e) => {
337
337
  e.stopPropagation();
338
338
  const target = e.target;
339
- if (target.classList.contains(`${PREFIX}-datepicker__year-nav-prev`)) {
339
+ if (target.classList.contains("ina-date-picker__year-nav-prev")) {
340
340
  const currentYearRange = datepickerYearCurrent.textContent.split(" - ").map((y) => parseInt(y));
341
341
  const newStartYear = currentYearRange[0] - 20;
342
342
  const newEndYear = currentYearRange[1] - 20;
343
343
  renderYear(newStartYear, newEndYear);
344
- } else if (target.classList.contains(`${PREFIX}-datepicker__year-nav-next`)) {
344
+ } else if (target.classList.contains("ina-date-picker__year-nav-next")) {
345
345
  const currentYearRange = datepickerYearCurrent.textContent.split(" - ").map((y) => parseInt(y));
346
346
  const newStartYear = currentYearRange[0] + 20;
347
347
  const newEndYear = currentYearRange[1] + 20;
@@ -351,7 +351,7 @@ function initDatepicker() {
351
351
  datepickerYearContent.addEventListener("click", (e) => {
352
352
  e.stopPropagation();
353
353
  const target = e.target;
354
- if (target.classList.contains(`${PREFIX}-datepicker__year-item`)) {
354
+ if (target.classList.contains("ina-date-picker__year-item")) {
355
355
  const yearValue = parseInt(target.dataset.year);
356
356
  currentDate.setFullYear(yearValue);
357
357
  renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
@@ -360,13 +360,13 @@ function initDatepicker() {
360
360
  });
361
361
  datepickerContent.addEventListener("click", (e) => {
362
362
  const target = e.target;
363
- if (target.classList.contains(`${PREFIX}-datepicker__calendar-day`) && !target.classList.contains("outside-month")) {
363
+ if (target.classList.contains("ina-date-picker__calendar-day") && !target.classList.contains("outside-month")) {
364
364
  if (target.classList.contains("selected")) {
365
365
  target.classList.remove("selected");
366
366
  selectedDateTarget = null;
367
367
  } else {
368
368
  const selectedDateEl = datepickerContent.querySelector(
369
- `.${PREFIX}-datepicker__calendar-day.selected`
369
+ ".ina-date-picker__calendar-day.selected"
370
370
  );
371
371
  selectedDateEl?.classList.remove("selected");
372
372
  target.classList.add("selected");
@@ -1191,6 +1191,202 @@ if (typeof window !== void 0) {
1191
1191
  });
1192
1192
  }
1193
1193
 
1194
+ // src/js/components/stateful/timepicker.js
1195
+ function initTimepicker() {
1196
+ const pickers = document.querySelectorAll(".ina-time-picker");
1197
+ pickers.forEach((picker) => {
1198
+ if (picker.dataset.initialized === "true") return;
1199
+ picker.dataset.initialized = "true";
1200
+ const input = picker.querySelector(".ina-time-picker__input");
1201
+ const wrapper = picker.querySelector(".ina-time-picker__wrapper");
1202
+ if (!input || !wrapper) return;
1203
+ const format = picker.dataset.format || "HH:mm";
1204
+ const use12Hours = picker.dataset.use12Hours === "true";
1205
+ const showSecond = picker.dataset.showSecond === "true";
1206
+ const disabled = picker.classList.contains("ina-time-picker--disabled");
1207
+ const allowClear = picker.dataset.allowClear !== "false";
1208
+ let isOpen = false;
1209
+ let internalValue = input.value || "";
1210
+ let panel = picker.querySelector(".ina-time-picker__panel");
1211
+ if (!panel) {
1212
+ panel = document.createElement("div");
1213
+ panel.className = "ina-time-picker__panel";
1214
+ panel.style.display = "none";
1215
+ picker.appendChild(panel);
1216
+ }
1217
+ const content = document.createElement("div");
1218
+ content.className = "ina-time-picker__content";
1219
+ panel.appendChild(content);
1220
+ const actions = document.createElement("div");
1221
+ actions.className = "ina-time-picker__actions";
1222
+ const confirmBtn = document.createElement("button");
1223
+ confirmBtn.type = "button";
1224
+ confirmBtn.className = "ina-time-picker__confirm-button";
1225
+ confirmBtn.textContent = "Pilih";
1226
+ actions.appendChild(confirmBtn);
1227
+ panel.appendChild(actions);
1228
+ const parseTime = (timeStr) => {
1229
+ if (!timeStr) return { hours: 0, minutes: 0, seconds: 0, period: "AM" };
1230
+ const parts = timeStr.split(":");
1231
+ let hours = 0, minutes = 0, seconds = 0, period = "AM";
1232
+ if (use12Hours) {
1233
+ const timePart = timeStr.split(" ")[0];
1234
+ const periodPart = timeStr.split(" ")[1] || "AM";
1235
+ const tParts = timePart.split(":");
1236
+ hours = parseInt(tParts[0] || "0", 10);
1237
+ minutes = parseInt(tParts[1] || "0", 10);
1238
+ seconds = parseInt(tParts[2] || "0", 10);
1239
+ period = periodPart;
1240
+ } else {
1241
+ hours = parseInt(parts[0] || "0", 10);
1242
+ minutes = parseInt(parts[1] || "0", 10);
1243
+ seconds = parseInt(parts[2] || "0", 10);
1244
+ }
1245
+ return { hours, minutes, seconds, period };
1246
+ };
1247
+ const formatTime = (h, m, s, p) => {
1248
+ const pad = (n) => n.toString().padStart(2, "0");
1249
+ if (use12Hours) {
1250
+ let displayHours = h;
1251
+ if (displayHours === 0) displayHours = 12;
1252
+ if (showSecond) {
1253
+ return `${pad(displayHours)}:${pad(m)}:${pad(s)} ${p}`;
1254
+ }
1255
+ return `${pad(displayHours)}:${pad(m)} ${p}`;
1256
+ } else {
1257
+ if (showSecond) {
1258
+ return `${pad(h)}:${pad(m)}:${pad(s)}`;
1259
+ }
1260
+ return `${pad(h)}:${pad(m)}`;
1261
+ }
1262
+ };
1263
+ let currentTime = parseTime(internalValue);
1264
+ const renderColumn = (type, max) => {
1265
+ const column = document.createElement("div");
1266
+ column.className = `ina-time-picker__column ina-time-picker__column--${type}`;
1267
+ const colContent = document.createElement("div");
1268
+ colContent.className = "ina-time-picker__column-content";
1269
+ column.appendChild(colContent);
1270
+ const start = type === "hour" && use12Hours ? 1 : 0;
1271
+ const end = type === "hour" && use12Hours ? 12 : max - 1;
1272
+ for (let i = start; i <= end; i++) {
1273
+ const option = document.createElement("div");
1274
+ option.className = "ina-time-picker__option";
1275
+ option.textContent = i.toString().padStart(2, "0");
1276
+ option.dataset.value = i;
1277
+ let isSelected = false;
1278
+ if (type === "hour") {
1279
+ isSelected = currentTime.hours === i || use12Hours && currentTime.hours === 0 && i === 12;
1280
+ } else if (type === "minute") {
1281
+ isSelected = currentTime.minutes === i;
1282
+ } else if (type === "second") {
1283
+ isSelected = currentTime.seconds === i;
1284
+ }
1285
+ if (isSelected)
1286
+ option.classList.add("ina-time-picker__option--selected");
1287
+ option.addEventListener("click", (e) => {
1288
+ e.stopPropagation();
1289
+ const val = parseInt(option.dataset.value, 10);
1290
+ if (type === "hour") currentTime.hours = val;
1291
+ if (type === "minute") currentTime.minutes = val;
1292
+ if (type === "second") currentTime.seconds = val;
1293
+ updateInput();
1294
+ colContent.querySelectorAll(".ina-time-picker__option").forEach(
1295
+ (el) => el.classList.remove("ina-time-picker__option--selected")
1296
+ );
1297
+ option.classList.add("ina-time-picker__option--selected");
1298
+ });
1299
+ colContent.appendChild(option);
1300
+ }
1301
+ return column;
1302
+ };
1303
+ const renderPeriodColumn = () => {
1304
+ const column = document.createElement("div");
1305
+ column.className = `ina-time-picker__column ina-time-picker__column--period`;
1306
+ const colContent = document.createElement("div");
1307
+ colContent.className = "ina-time-picker__column-content";
1308
+ column.appendChild(colContent);
1309
+ ["AM", "PM"].forEach((p) => {
1310
+ const option = document.createElement("div");
1311
+ option.className = "ina-time-picker__option";
1312
+ option.textContent = p;
1313
+ if (currentTime.period === p)
1314
+ option.classList.add("ina-time-picker__option--selected");
1315
+ option.addEventListener("click", (e) => {
1316
+ e.stopPropagation();
1317
+ currentTime.period = p;
1318
+ updateInput();
1319
+ colContent.querySelectorAll(".ina-time-picker__option").forEach(
1320
+ (el) => el.classList.remove("ina-time-picker__option--selected")
1321
+ );
1322
+ option.classList.add("ina-time-picker__option--selected");
1323
+ });
1324
+ colContent.appendChild(option);
1325
+ });
1326
+ return column;
1327
+ };
1328
+ const updateInput = () => {
1329
+ const val = formatTime(
1330
+ currentTime.hours,
1331
+ currentTime.minutes,
1332
+ currentTime.seconds,
1333
+ currentTime.period
1334
+ );
1335
+ input.value = val;
1336
+ picker.dataset.value = val;
1337
+ input.dispatchEvent(new Event("change", { bubbles: true }));
1338
+ };
1339
+ const buildPanel = () => {
1340
+ content.innerHTML = "";
1341
+ content.appendChild(renderColumn("hour", use12Hours ? 13 : 24));
1342
+ content.appendChild(renderColumn("minute", 60));
1343
+ if (showSecond) content.appendChild(renderColumn("second", 60));
1344
+ if (use12Hours) content.appendChild(renderPeriodColumn());
1345
+ };
1346
+ const open = () => {
1347
+ if (disabled) return;
1348
+ isOpen = true;
1349
+ picker.classList.add("ina-time-picker--open");
1350
+ panel.style.display = "block";
1351
+ currentTime = parseTime(input.value);
1352
+ buildPanel();
1353
+ };
1354
+ const close = () => {
1355
+ isOpen = false;
1356
+ picker.classList.remove("ina-time-picker--open");
1357
+ panel.style.display = "none";
1358
+ };
1359
+ const toggle = (e) => {
1360
+ e.stopPropagation();
1361
+ if (isOpen) close();
1362
+ else open();
1363
+ };
1364
+ wrapper.addEventListener("click", toggle);
1365
+ document.addEventListener("click", (e) => {
1366
+ if (!picker.contains(e.target)) {
1367
+ close();
1368
+ }
1369
+ });
1370
+ confirmBtn.addEventListener("click", (e) => {
1371
+ e.stopPropagation();
1372
+ close();
1373
+ });
1374
+ input.addEventListener("change", () => {
1375
+ currentTime = parseTime(input.value);
1376
+ });
1377
+ const clearBtn = picker.querySelector(".ina-time-picker__clear-button");
1378
+ if (clearBtn && allowClear) {
1379
+ clearBtn.addEventListener("click", (e) => {
1380
+ e.stopPropagation();
1381
+ input.value = "";
1382
+ currentTime = { hours: 0, minutes: 0, seconds: 0, period: "AM" };
1383
+ picker.dataset.value = "";
1384
+ input.dispatchEvent(new Event("change", { bubbles: true }));
1385
+ });
1386
+ }
1387
+ });
1388
+ }
1389
+
1194
1390
  // src/js/index.js
1195
1391
  var PREFIX = "ina-ss";
1196
1392
  function initAll() {
@@ -1206,6 +1402,7 @@ function initAll() {
1206
1402
  initRangeDatepicker();
1207
1403
  initTab();
1208
1404
  initToggle();
1405
+ initTimepicker();
1209
1406
  }
1210
1407
  export {
1211
1408
  PREFIX,
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@idds/js",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "Design system JS",
7
+ "description": "Vanilla Javascript UI component library for INA Digital Design System",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.js",
10
10
  "unpkg": "dist/index.iife.js",
package/readme.md CHANGED
@@ -1,9 +1,9 @@
1
- # @idds/jss
1
+ # @idds/js
2
2
 
3
- Sebuah pustaka styling yang siap di‑consume oleh berbagai proyek.
3
+ Vanilla Javascript UI component library for INA Digital Design System
4
4
 
5
5
  ## Instalasi
6
6
 
7
7
  ```bash
8
- npm i @idds/jss
8
+ npm i @idds/js
9
9
  ```