@safestrong/ppa-component-library 1.7.2 → 1.8.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.
package/dist/index.d.mts CHANGED
@@ -19,11 +19,13 @@ declare namespace Button {
19
19
  }) => React.JSX.Element;
20
20
  }
21
21
 
22
- declare function TextInput({ label, labelFor, icon, outerclass, ...attr }: Readonly<React.InputHTMLAttributes<HTMLInputElement> & {
22
+ declare function TextInput({ label, labelFor, icon, outerclass, isdarkmode, inputclass, ...attr }: Readonly<React.InputHTMLAttributes<HTMLInputElement> & {
23
23
  label?: string;
24
24
  labelFor?: string;
25
25
  icon?: IconProp;
26
26
  outerclass?: string;
27
+ isdarkmode?: boolean;
28
+ inputclass?: string;
27
29
  }>): React.JSX.Element;
28
30
 
29
31
  declare function Slider(attr: Readonly<React.InputHTMLAttributes<HTMLInputElement>>): React.JSX.Element;
@@ -34,6 +36,7 @@ type SingleSelect = React.InputHTMLAttributes<HTMLInputElement> & {
34
36
  placeholder?: string;
35
37
  stateaction?: (param: any) => void;
36
38
  outerclass?: string;
39
+ isdarkmode?: boolean;
37
40
  options?: {
38
41
  label: string;
39
42
  value: string;
@@ -113,6 +116,7 @@ type MultiSelect = {
113
116
  label?: string;
114
117
  labelHtml?: string;
115
118
  outerclass?: string;
119
+ isdarkmode?: boolean;
116
120
  options?: Option[];
117
121
  stringOptions?: string[];
118
122
  state: {
package/dist/index.d.ts CHANGED
@@ -19,11 +19,13 @@ declare namespace Button {
19
19
  }) => React.JSX.Element;
20
20
  }
21
21
 
22
- declare function TextInput({ label, labelFor, icon, outerclass, ...attr }: Readonly<React.InputHTMLAttributes<HTMLInputElement> & {
22
+ declare function TextInput({ label, labelFor, icon, outerclass, isdarkmode, inputclass, ...attr }: Readonly<React.InputHTMLAttributes<HTMLInputElement> & {
23
23
  label?: string;
24
24
  labelFor?: string;
25
25
  icon?: IconProp;
26
26
  outerclass?: string;
27
+ isdarkmode?: boolean;
28
+ inputclass?: string;
27
29
  }>): React.JSX.Element;
28
30
 
29
31
  declare function Slider(attr: Readonly<React.InputHTMLAttributes<HTMLInputElement>>): React.JSX.Element;
@@ -34,6 +36,7 @@ type SingleSelect = React.InputHTMLAttributes<HTMLInputElement> & {
34
36
  placeholder?: string;
35
37
  stateaction?: (param: any) => void;
36
38
  outerclass?: string;
39
+ isdarkmode?: boolean;
37
40
  options?: {
38
41
  label: string;
39
42
  value: string;
@@ -113,6 +116,7 @@ type MultiSelect = {
113
116
  label?: string;
114
117
  labelHtml?: string;
115
118
  outerclass?: string;
119
+ isdarkmode?: boolean;
116
120
  options?: Option[];
117
121
  stringOptions?: string[];
118
122
  state: {
package/dist/index.js CHANGED
@@ -101,6 +101,7 @@ function Button(_a) {
101
101
  return /* @__PURE__ */ import_react.default.createElement(
102
102
  "button",
103
103
  __spreadProps(__spreadValues({}, rest), {
104
+ disabled: rest.disabled || isLoading,
104
105
  className: `${!icon && "py-[0.84rem]"} ${className} ${btnType == "secondary" && "btn__secondary"} btn__primary ${label ? "" : "!p-[0.87rem]"}`
105
106
  }),
106
107
  buttonIcon && icon && /* @__PURE__ */ import_react.default.createElement(
@@ -146,25 +147,56 @@ function getBtnClass(idx) {
146
147
  // src/components/TextInput.tsx
147
148
  var import_react2 = __toESM(require("react"));
148
149
  var import_react_fontawesome2 = require("@fortawesome/react-fontawesome");
149
- var input__icon = "w-[2rem] p-[0.9rem] px-[0.7rem] text-[1.2rem] bg-[var(--color-background-icon)] text-[var(--color-icon-input)] mr-2 group-focus-within:text-[var(--color-primary)]";
150
+ var input__icon = "w-[2rem] p-[0.9rem] px-[0.7rem] text-[1.2rem] bg-[var(--color-background-icon)] text-[var(--color-icon-input)] mr-2 group-focus-within:text-[var(--color-primary)] ";
150
151
  function TextInput(_a) {
151
152
  var _b = _a, {
152
153
  label,
153
154
  labelFor,
154
155
  icon,
155
- outerclass
156
+ outerclass,
157
+ isdarkmode,
158
+ inputclass
156
159
  } = _b, attr = __objRest(_b, [
157
160
  "label",
158
161
  "labelFor",
159
162
  "icon",
160
- "outerclass"
163
+ "outerclass",
164
+ "isdarkmode",
165
+ "inputclass"
161
166
  ]);
162
- return /* @__PURE__ */ import_react2.default.createElement("div", { className: `group ${outerclass} w-full` }, label && /* @__PURE__ */ import_react2.default.createElement("label", { htmlFor: labelFor, className: "text-input__label" }, label), /* @__PURE__ */ import_react2.default.createElement("div", { className: `text-input__wrapper overflow-hidden ${attr.className}` }, icon && /* @__PURE__ */ import_react2.default.createElement(import_react_fontawesome2.FontAwesomeIcon, { icon, className: input__icon }), /* @__PURE__ */ import_react2.default.createElement(
163
- "input",
164
- __spreadProps(__spreadValues({}, attr), {
165
- className: `text-input w-full ${icon && "!pl-[0.3rem]"}`
166
- })
167
- )));
167
+ function getThemedClass(prefix) {
168
+ return `var(--color${isdarkmode ? "-dark" : ""}${prefix})`;
169
+ }
170
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: `group ${outerclass} w-full` }, label && /* @__PURE__ */ import_react2.default.createElement(
171
+ "label",
172
+ {
173
+ htmlFor: labelFor,
174
+ className: "text-input__label",
175
+ style: {
176
+ color: getThemedClass("-text-secondary")
177
+ }
178
+ },
179
+ label
180
+ ), /* @__PURE__ */ import_react2.default.createElement(
181
+ "div",
182
+ {
183
+ className: `text-input__wrapper overflow-hidden ${attr.className}`,
184
+ style: {
185
+ borderColor: getThemedClass("-border"),
186
+ background: getThemedClass("-bg-surface")
187
+ }
188
+ },
189
+ icon && /* @__PURE__ */ import_react2.default.createElement(import_react_fontawesome2.FontAwesomeIcon, { icon, className: input__icon }),
190
+ /* @__PURE__ */ import_react2.default.createElement(
191
+ "input",
192
+ __spreadProps(__spreadValues({}, attr), {
193
+ className: `text-input w-full ${icon && "!pl-[0.3rem]"} ${inputclass}`,
194
+ style: {
195
+ color: getThemedClass("-text-primary")
196
+ }
197
+ })
198
+ )
199
+ ));
168
200
  }
169
201
 
170
202
  // src/components/Slider.tsx
@@ -188,13 +220,15 @@ var import_react_fontawesome4 = require("@fortawesome/react-fontawesome");
188
220
  var import_free_solid_svg_icons3 = require("@fortawesome/free-solid-svg-icons");
189
221
  function SingleSelect(attr) {
190
222
  var _b;
191
- const _a = attr, { options = [], stringOptions = [] } = _a, attrInput = __objRest(_a, ["options", "stringOptions"]);
223
+ const _a = attr, { options = [], stringOptions = [], isdarkmode } = _a, attrInput = __objRest(_a, ["options", "stringOptions", "isdarkmode"]);
224
+ const inputValue = attrInput.value;
192
225
  const [keyword, setKeyword] = (0, import_react4.useState)("");
193
226
  const [selected, setSelected] = (0, import_react4.useState)({
194
227
  label: "",
195
228
  value: ""
196
229
  });
197
230
  function selectItem({ label, value }, e) {
231
+ var _a2;
198
232
  const triggerManual = attrInput.onChange;
199
233
  if (triggerManual) {
200
234
  triggerManual == null ? void 0 : triggerManual({
@@ -202,14 +236,9 @@ function SingleSelect(attr) {
202
236
  });
203
237
  }
204
238
  setSelected({ label, value });
205
- if (attr.stateaction) {
206
- if (stringOptions) attr.stateaction(value);
207
- if (options) attr.stateaction({ label, value });
208
- }
239
+ (_a2 = attr.stateaction) == null ? void 0 : _a2.call(attr, stringOptions ? value : { label, value });
209
240
  setKeyword("");
210
- setTimeout(() => {
211
- e.target.blur();
212
- }, 250);
241
+ e.currentTarget.blur();
213
242
  }
214
243
  function autoUpdateValue(updatedValue) {
215
244
  if (updatedValue) {
@@ -231,40 +260,91 @@ function SingleSelect(attr) {
231
260
  );
232
261
  }, [keyword, availableOptions]);
233
262
  (0, import_react4.useEffect)(() => {
234
- attrInput.value && autoUpdateValue(attrInput.value);
235
- }, [attrInput.value]);
236
- return /* @__PURE__ */ import_react4.default.createElement("div", { className: `w-full group ${attr.outerclass}` }, attrInput.label && /* @__PURE__ */ import_react4.default.createElement("label", { className: "text-input__label", htmlFor: attrInput.labelHtml }, attrInput.label), /* @__PURE__ */ import_react4.default.createElement("div", { className: `${attrInput.className} text-input__wrapper relative` }, /* @__PURE__ */ import_react4.default.createElement(
237
- "input",
238
- __spreadProps(__spreadValues(__spreadValues({}, attrInput), attrInput.onChange ? { onChange: attrInput.onChange } : {}), {
239
- value: (_b = attrInput.value) != null ? _b : selected.value,
240
- type: "hidden"
241
- })
242
- ), /* @__PURE__ */ import_react4.default.createElement(
243
- "input",
263
+ inputValue && autoUpdateValue(inputValue);
264
+ }, [inputValue]);
265
+ function getThemedClass(prefix) {
266
+ return `var(--color${isdarkmode ? "-dark" : ""}${prefix})`;
267
+ }
268
+ const placeholderClass = `${input2} select-item-placeholder-${isdarkmode ? "dark" : ""}`;
269
+ const optionHoverClass = `select-item-hover${isdarkmode ? "-dark" : ""}`;
270
+ return /* @__PURE__ */ import_react4.default.createElement("div", { className: `w-full group ${attr.outerclass}` }, attrInput.label && /* @__PURE__ */ import_react4.default.createElement(
271
+ "label",
244
272
  {
245
- value: keyword,
246
- type: "search",
247
- onChange: (e) => setKeyword(e.target.value),
248
- className: `${attrInput.name}-keyword ${input2} ${selected.value && "placeholder:text-[var(--color-text-primary)]"}`,
249
- placeholder: selected.value ? selected.label : attrInput.placeholder
250
- }
251
- ), /* @__PURE__ */ import_react4.default.createElement("div", { className: "select-item__wrapper" }, filteredOptions.length == 0 && keyword != "" && /* @__PURE__ */ import_react4.default.createElement("button", { disabled: true, className: "select-item text-[var(--color-danger)]" }, "Tidak ada Item"), filteredOptions.map(({ label, value }) => /* @__PURE__ */ import_react4.default.createElement(
252
- "button",
273
+ className: "text-input__label",
274
+ htmlFor: attrInput.labelHtml,
275
+ style: { color: getThemedClass("-text-secondary") }
276
+ },
277
+ attrInput.label
278
+ ), /* @__PURE__ */ import_react4.default.createElement(
279
+ "div",
253
280
  {
254
- type: "button",
255
- onClick: (e) => selectItem({ label, value }, e),
256
- key: value,
257
- className: "select-item"
281
+ className: `${attrInput.className} text-input__wrapper relative`,
282
+ style: {
283
+ borderColor: getThemedClass("-border"),
284
+ background: getThemedClass("-bg-surface")
285
+ }
258
286
  },
259
- label,
260
- selected.value == value && /* @__PURE__ */ import_react4.default.createElement(
261
- import_react_fontawesome4.FontAwesomeIcon,
287
+ /* @__PURE__ */ import_react4.default.createElement(
288
+ "input",
289
+ __spreadProps(__spreadValues(__spreadValues({
290
+ type: "hidden"
291
+ }, attrInput), attrInput.onChange ? { onChange: attrInput.onChange } : {}), {
292
+ value: (_b = attrInput.value) != null ? _b : selected.value
293
+ })
294
+ ),
295
+ /* @__PURE__ */ import_react4.default.createElement(
296
+ "input",
262
297
  {
263
- icon: import_free_solid_svg_icons3.faCheck,
264
- className: "text-[var(--color-primary)]"
298
+ type: "search",
299
+ value: keyword,
300
+ autoComplete: "off",
301
+ onChange: (e) => setKeyword(e.target.value),
302
+ className: `${attrInput.name}-keyword ${placeholderClass}`,
303
+ placeholder: selected.value ? selected.label : attrInput.placeholder,
304
+ style: {
305
+ color: selected.value ? getThemedClass("-text-primary") : void 0
306
+ }
265
307
  }
266
- )
267
- ))), /* @__PURE__ */ import_react4.default.createElement(import_react_fontawesome4.FontAwesomeIcon, { icon: import_free_solid_svg_icons3.faChevronDown, className: input__icon2 })));
308
+ ),
309
+ /* @__PURE__ */ import_react4.default.createElement(
310
+ "div",
311
+ {
312
+ className: "select-item__wrapper",
313
+ style: {
314
+ borderColor: getThemedClass("-border"),
315
+ background: getThemedClass("-bg-surface")
316
+ }
317
+ },
318
+ filteredOptions.length == 0 && keyword != "" && /* @__PURE__ */ import_react4.default.createElement(
319
+ "button",
320
+ {
321
+ disabled: true,
322
+ className: "select-item",
323
+ style: { color: "var(--color-danger)" }
324
+ },
325
+ "Tidak ada Item"
326
+ ),
327
+ filteredOptions.map(({ label, value }) => /* @__PURE__ */ import_react4.default.createElement(
328
+ "button",
329
+ {
330
+ key: value,
331
+ type: "button",
332
+ className: `select-item ${optionHoverClass}`,
333
+ onClick: (e) => selectItem({ label, value }, e),
334
+ style: { color: getThemedClass("-text-secondary") }
335
+ },
336
+ label,
337
+ selected.value == value && /* @__PURE__ */ import_react4.default.createElement(
338
+ import_react_fontawesome4.FontAwesomeIcon,
339
+ {
340
+ icon: import_free_solid_svg_icons3.faCheck,
341
+ style: { color: "var(--color-info)" }
342
+ }
343
+ )
344
+ ))
345
+ ),
346
+ /* @__PURE__ */ import_react4.default.createElement(import_react_fontawesome4.FontAwesomeIcon, { icon: import_free_solid_svg_icons3.faChevronDown, style: { color: getThemedClass("-icon-input"), paddingRight: "0.7rem" } })
347
+ ));
268
348
  }
269
349
  SingleSelect.autoFill = autoFillInput;
270
350
  function autoFillInput(value, elName, list2) {
@@ -274,7 +354,6 @@ function autoFillInput(value, elName, list2) {
274
354
  const el = document.querySelector(`.${elName}-keyword`);
275
355
  el == null ? void 0 : el.setAttribute("placeholder", `${filtered == null ? void 0 : filtered.label}`);
276
356
  }
277
- var input__icon2 = "pr-[0.7rem] text-[var(--color-icon-input)]";
278
357
  var input2 = "text-input peer ... w-full";
279
358
 
280
359
  // src/components/Tooltip.tsx
@@ -421,8 +500,10 @@ function MultiSelect(_a) {
421
500
  "label",
422
501
  "labelHtml"
423
502
  ]);
424
- const { options = [], stringOptions = [] } = attr;
503
+ const { options = [], stringOptions = [], isdarkmode } = attr;
425
504
  const [keyword, setKeyword] = (0, import_react10.useState)("");
505
+ const optionHoverClass = `select-item-hover${isdarkmode ? "-dark" : ""}`;
506
+ const placeholderClass = `${input3} select-item-placeholder-${isdarkmode ? "dark" : ""}`;
426
507
  const availableOptions = (0, import_react10.useMemo)(() => {
427
508
  const isDefaultOption = options && options.length > 0;
428
509
  if (!isDefaultOption)
@@ -450,42 +531,98 @@ function MultiSelect(_a) {
450
531
  const isAllSelected = state.value.length == availableOptions.length;
451
532
  state.select(isAllSelected ? [] : availableOptions);
452
533
  }, [state.value]);
453
- return /* @__PURE__ */ import_react10.default.createElement("div", { className: `group w-full ${attr.outerclass}` }, label && /* @__PURE__ */ import_react10.default.createElement("label", { className: "text-input__label", htmlFor: labelHtml }, label), /* @__PURE__ */ import_react10.default.createElement("div", { className: "text-input__wrapper relative" }, /* @__PURE__ */ import_react10.default.createElement(
454
- "input",
534
+ function getThemedClass(prefix) {
535
+ return `var(--color${isdarkmode ? "-dark" : ""}${prefix})`;
536
+ }
537
+ return /* @__PURE__ */ import_react10.default.createElement("div", { className: `group w-full ${attr.outerclass}` }, label && /* @__PURE__ */ import_react10.default.createElement(
538
+ "label",
455
539
  {
456
- value: keyword,
457
- type: "search",
458
- placeholder: `${state.value.length} Dipilih`,
459
- className: `${input3} ${state.value.length > 0 && "placeholder:text-[var(--color-text-primary)]"}`,
460
- onChange: (e) => setKeyword(e.target.value)
461
- }
462
- ), /* @__PURE__ */ import_react10.default.createElement("div", { className: "select-item__wrapper select-multiple__wrapper" }, getFiltered().length == 0 && keyword != "" && /* @__PURE__ */ import_react10.default.createElement("button", { disabled: true, className: "select-item text-[var(--color-danger)]" }, "Tidak ada Item"), getFiltered().map(({ label: label2, value }) => /* @__PURE__ */ import_react10.default.createElement(
463
- "button",
540
+ htmlFor: labelHtml,
541
+ className: "text-input__label",
542
+ style: { color: getThemedClass("-text-secondary") }
543
+ },
544
+ label
545
+ ), /* @__PURE__ */ import_react10.default.createElement(
546
+ "div",
464
547
  {
465
- type: "button",
466
- onClick: () => selectItem({ label: label2, value }),
467
- key: value,
468
- className: "select-item"
548
+ className: "text-input__wrapper relative",
549
+ style: {
550
+ borderColor: getThemedClass("-border"),
551
+ background: getThemedClass("-bg-surface")
552
+ }
469
553
  },
470
- label2,
471
- isItemExist(value) && /* @__PURE__ */ import_react10.default.createElement(
472
- import_react_fontawesome7.FontAwesomeIcon,
554
+ /* @__PURE__ */ import_react10.default.createElement(
555
+ "input",
473
556
  {
474
- icon: import_free_solid_svg_icons6.faCheck,
475
- className: "text-[var(--color-primary)]"
557
+ type: "search",
558
+ value: keyword,
559
+ autoComplete: "off",
560
+ className: `${input3} ${placeholderClass}`,
561
+ onChange: (e) => setKeyword(e.target.value),
562
+ placeholder: `${state.value.length} Dipilih`,
563
+ style: {
564
+ color: state.value.length > 0 ? getThemedClass("-text-primary") : void 0
565
+ }
476
566
  }
567
+ ),
568
+ /* @__PURE__ */ import_react10.default.createElement(
569
+ "div",
570
+ {
571
+ className: "select-item__wrapper select-multiple__wrapper",
572
+ style: {
573
+ borderColor: getThemedClass("-border"),
574
+ background: getThemedClass("-bg-surface")
575
+ }
576
+ },
577
+ getFiltered().length == 0 && keyword != "" && /* @__PURE__ */ import_react10.default.createElement(
578
+ "button",
579
+ {
580
+ disabled: true,
581
+ className: "select-item",
582
+ style: { color: "var(--color-danger)" }
583
+ },
584
+ "Tidak ada Item"
585
+ ),
586
+ getFiltered().map(({ label: label2, value }) => /* @__PURE__ */ import_react10.default.createElement(
587
+ "button",
588
+ {
589
+ key: value,
590
+ type: "button",
591
+ onClick: () => selectItem({ label: label2, value }),
592
+ className: `select-item ${optionHoverClass}`,
593
+ style: { color: getThemedClass("-text-secondary") }
594
+ },
595
+ label2,
596
+ isItemExist(value) && /* @__PURE__ */ import_react10.default.createElement(
597
+ import_react_fontawesome7.FontAwesomeIcon,
598
+ {
599
+ icon: import_free_solid_svg_icons6.faCheck,
600
+ style: { color: "var(--color-info)" }
601
+ }
602
+ )
603
+ ))
604
+ ),
605
+ /* @__PURE__ */ import_react10.default.createElement(
606
+ "button",
607
+ {
608
+ type: "button",
609
+ className: "cursor-pointer",
610
+ onClick: selectUnSelectAll
611
+ },
612
+ /* @__PURE__ */ import_react10.default.createElement(
613
+ import_react_fontawesome7.FontAwesomeIcon,
614
+ {
615
+ icon: import_free_solid_svg_icons6.faListCheck,
616
+ style: {
617
+ color: getThemedClass("-icon-input"),
618
+ paddingRight: "0.7rem",
619
+ fontSize: "1.2rem"
620
+ }
621
+ }
622
+ )
477
623
  )
478
- ))), /* @__PURE__ */ import_react10.default.createElement(
479
- "button",
480
- {
481
- type: "button",
482
- className: "cursor-pointer",
483
- onClick: selectUnSelectAll
484
- },
485
- /* @__PURE__ */ import_react10.default.createElement(import_react_fontawesome7.FontAwesomeIcon, { icon: import_free_solid_svg_icons6.faListCheck, className: input__icon3 })
486
- )));
624
+ ));
487
625
  }
488
- var input__icon3 = "pr-[0.7rem] text-[1.2rem] text-[var(--color-icon-input)]";
489
626
  var input3 = "text-input peer ... w-full";
490
627
 
491
628
  // src/components/ThemeToggle.tsx
@@ -528,6 +665,7 @@ function Dashboard() {
528
665
  return /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex items-center gap-[1rem]" }, /* @__PURE__ */ import_react12.default.createElement(
529
666
  MultiSelect,
530
667
  {
668
+ isdarkmode: true,
531
669
  label: "Multi Select",
532
670
  stringOptions: stringList,
533
671
  state: { value: selectedItem, select: setSelectedItem }