@safestrong/ppa-component-library 1.7.3 → 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
@@ -147,25 +147,56 @@ function getBtnClass(idx) {
147
147
  // src/components/TextInput.tsx
148
148
  var import_react2 = __toESM(require("react"));
149
149
  var import_react_fontawesome2 = require("@fortawesome/react-fontawesome");
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
+ 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)] ";
151
151
  function TextInput(_a) {
152
152
  var _b = _a, {
153
153
  label,
154
154
  labelFor,
155
155
  icon,
156
- outerclass
156
+ outerclass,
157
+ isdarkmode,
158
+ inputclass
157
159
  } = _b, attr = __objRest(_b, [
158
160
  "label",
159
161
  "labelFor",
160
162
  "icon",
161
- "outerclass"
163
+ "outerclass",
164
+ "isdarkmode",
165
+ "inputclass"
162
166
  ]);
163
- 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(
164
- "input",
165
- __spreadProps(__spreadValues({}, attr), {
166
- className: `text-input w-full ${icon && "!pl-[0.3rem]"}`
167
- })
168
- )));
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
+ ));
169
200
  }
170
201
 
171
202
  // src/components/Slider.tsx
@@ -189,13 +220,15 @@ var import_react_fontawesome4 = require("@fortawesome/react-fontawesome");
189
220
  var import_free_solid_svg_icons3 = require("@fortawesome/free-solid-svg-icons");
190
221
  function SingleSelect(attr) {
191
222
  var _b;
192
- 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;
193
225
  const [keyword, setKeyword] = (0, import_react4.useState)("");
194
226
  const [selected, setSelected] = (0, import_react4.useState)({
195
227
  label: "",
196
228
  value: ""
197
229
  });
198
230
  function selectItem({ label, value }, e) {
231
+ var _a2;
199
232
  const triggerManual = attrInput.onChange;
200
233
  if (triggerManual) {
201
234
  triggerManual == null ? void 0 : triggerManual({
@@ -203,14 +236,9 @@ function SingleSelect(attr) {
203
236
  });
204
237
  }
205
238
  setSelected({ label, value });
206
- if (attr.stateaction) {
207
- if (stringOptions) attr.stateaction(value);
208
- if (options) attr.stateaction({ label, value });
209
- }
239
+ (_a2 = attr.stateaction) == null ? void 0 : _a2.call(attr, stringOptions ? value : { label, value });
210
240
  setKeyword("");
211
- setTimeout(() => {
212
- e.target.blur();
213
- }, 250);
241
+ e.currentTarget.blur();
214
242
  }
215
243
  function autoUpdateValue(updatedValue) {
216
244
  if (updatedValue) {
@@ -232,40 +260,91 @@ function SingleSelect(attr) {
232
260
  );
233
261
  }, [keyword, availableOptions]);
234
262
  (0, import_react4.useEffect)(() => {
235
- attrInput.value && autoUpdateValue(attrInput.value);
236
- }, [attrInput.value]);
237
- 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(
238
- "input",
239
- __spreadProps(__spreadValues(__spreadValues({}, attrInput), attrInput.onChange ? { onChange: attrInput.onChange } : {}), {
240
- value: (_b = attrInput.value) != null ? _b : selected.value,
241
- type: "hidden"
242
- })
243
- ), /* @__PURE__ */ import_react4.default.createElement(
244
- "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",
245
272
  {
246
- value: keyword,
247
- type: "search",
248
- onChange: (e) => setKeyword(e.target.value),
249
- className: `${attrInput.name}-keyword ${input2} ${selected.value && "placeholder:text-[var(--color-text-primary)]"}`,
250
- placeholder: selected.value ? selected.label : attrInput.placeholder
251
- }
252
- ), /* @__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(
253
- "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",
254
280
  {
255
- type: "button",
256
- onClick: (e) => selectItem({ label, value }, e),
257
- key: value,
258
- className: "select-item"
281
+ className: `${attrInput.className} text-input__wrapper relative`,
282
+ style: {
283
+ borderColor: getThemedClass("-border"),
284
+ background: getThemedClass("-bg-surface")
285
+ }
259
286
  },
260
- label,
261
- selected.value == value && /* @__PURE__ */ import_react4.default.createElement(
262
- 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",
263
297
  {
264
- icon: import_free_solid_svg_icons3.faCheck,
265
- 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
+ }
266
307
  }
267
- )
268
- ))), /* @__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
+ ));
269
348
  }
270
349
  SingleSelect.autoFill = autoFillInput;
271
350
  function autoFillInput(value, elName, list2) {
@@ -275,7 +354,6 @@ function autoFillInput(value, elName, list2) {
275
354
  const el = document.querySelector(`.${elName}-keyword`);
276
355
  el == null ? void 0 : el.setAttribute("placeholder", `${filtered == null ? void 0 : filtered.label}`);
277
356
  }
278
- var input__icon2 = "pr-[0.7rem] text-[var(--color-icon-input)]";
279
357
  var input2 = "text-input peer ... w-full";
280
358
 
281
359
  // src/components/Tooltip.tsx
@@ -422,8 +500,10 @@ function MultiSelect(_a) {
422
500
  "label",
423
501
  "labelHtml"
424
502
  ]);
425
- const { options = [], stringOptions = [] } = attr;
503
+ const { options = [], stringOptions = [], isdarkmode } = attr;
426
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" : ""}`;
427
507
  const availableOptions = (0, import_react10.useMemo)(() => {
428
508
  const isDefaultOption = options && options.length > 0;
429
509
  if (!isDefaultOption)
@@ -451,42 +531,98 @@ function MultiSelect(_a) {
451
531
  const isAllSelected = state.value.length == availableOptions.length;
452
532
  state.select(isAllSelected ? [] : availableOptions);
453
533
  }, [state.value]);
454
- 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(
455
- "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",
456
539
  {
457
- value: keyword,
458
- type: "search",
459
- placeholder: `${state.value.length} Dipilih`,
460
- className: `${input3} ${state.value.length > 0 && "placeholder:text-[var(--color-text-primary)]"}`,
461
- onChange: (e) => setKeyword(e.target.value)
462
- }
463
- ), /* @__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(
464
- "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",
465
547
  {
466
- type: "button",
467
- onClick: () => selectItem({ label: label2, value }),
468
- key: value,
469
- className: "select-item"
548
+ className: "text-input__wrapper relative",
549
+ style: {
550
+ borderColor: getThemedClass("-border"),
551
+ background: getThemedClass("-bg-surface")
552
+ }
470
553
  },
471
- label2,
472
- isItemExist(value) && /* @__PURE__ */ import_react10.default.createElement(
473
- import_react_fontawesome7.FontAwesomeIcon,
554
+ /* @__PURE__ */ import_react10.default.createElement(
555
+ "input",
474
556
  {
475
- icon: import_free_solid_svg_icons6.faCheck,
476
- 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
+ }
477
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
+ )
478
623
  )
479
- ))), /* @__PURE__ */ import_react10.default.createElement(
480
- "button",
481
- {
482
- type: "button",
483
- className: "cursor-pointer",
484
- onClick: selectUnSelectAll
485
- },
486
- /* @__PURE__ */ import_react10.default.createElement(import_react_fontawesome7.FontAwesomeIcon, { icon: import_free_solid_svg_icons6.faListCheck, className: input__icon3 })
487
- )));
624
+ ));
488
625
  }
489
- var input__icon3 = "pr-[0.7rem] text-[1.2rem] text-[var(--color-icon-input)]";
490
626
  var input3 = "text-input peer ... w-full";
491
627
 
492
628
  // src/components/ThemeToggle.tsx
@@ -529,6 +665,7 @@ function Dashboard() {
529
665
  return /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex items-center gap-[1rem]" }, /* @__PURE__ */ import_react12.default.createElement(
530
666
  MultiSelect,
531
667
  {
668
+ isdarkmode: true,
532
669
  label: "Multi Select",
533
670
  stringOptions: stringList,
534
671
  state: { value: selectedItem, select: setSelectedItem }