@verma-consulting/design-library 0.1.38 → 0.1.40

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
@@ -67,11 +67,20 @@ declare const FormDialog: ({ open, setOpen, title, actions, children, maxWidth,
67
67
  maxWidth?: string | undefined;
68
68
  }) => react_jsx_runtime.JSX.Element;
69
69
 
70
- declare const InputFileUpload: ({ name, onChange, title }: {
71
- name?: string | undefined;
72
- onChange?: (() => null) | undefined;
73
- title?: string | undefined;
74
- }) => react_jsx_runtime.JSX.Element;
70
+ type InputFileUploadProps = {
71
+ name?: string;
72
+ onChange?: (event: React__default.ChangeEvent<HTMLInputElement>) => void;
73
+ /** Primary label (e.g. “Upload document”). */
74
+ title?: string;
75
+ /** Secondary line under the title (e.g. accepted types). */
76
+ subtitle?: string;
77
+ accept?: string;
78
+ multiple?: boolean;
79
+ disabled?: boolean;
80
+ /** Stretch to the width of the parent container. */
81
+ fullWidth?: boolean;
82
+ };
83
+ declare const InputFileUpload: React__default.FC<InputFileUploadProps>;
75
84
 
76
85
  type ImageUploadAvatarProps = {
77
86
  name?: string;
@@ -162,7 +171,8 @@ interface SearchableSelectProps {
162
171
  size?: "small" | "medium";
163
172
  style?: React__default.CSSProperties;
164
173
  disabled?: boolean;
165
- onClear?: () => void;
174
+ /** If `null` or omitted, the clear control is not shown. Pass a handler to enable clear. */
175
+ onClear?: (() => void) | null;
166
176
  defaultEditMode?: boolean;
167
177
  multiple?: boolean;
168
178
  }
package/dist/index.d.ts CHANGED
@@ -67,11 +67,20 @@ declare const FormDialog: ({ open, setOpen, title, actions, children, maxWidth,
67
67
  maxWidth?: string | undefined;
68
68
  }) => react_jsx_runtime.JSX.Element;
69
69
 
70
- declare const InputFileUpload: ({ name, onChange, title }: {
71
- name?: string | undefined;
72
- onChange?: (() => null) | undefined;
73
- title?: string | undefined;
74
- }) => react_jsx_runtime.JSX.Element;
70
+ type InputFileUploadProps = {
71
+ name?: string;
72
+ onChange?: (event: React__default.ChangeEvent<HTMLInputElement>) => void;
73
+ /** Primary label (e.g. “Upload document”). */
74
+ title?: string;
75
+ /** Secondary line under the title (e.g. accepted types). */
76
+ subtitle?: string;
77
+ accept?: string;
78
+ multiple?: boolean;
79
+ disabled?: boolean;
80
+ /** Stretch to the width of the parent container. */
81
+ fullWidth?: boolean;
82
+ };
83
+ declare const InputFileUpload: React__default.FC<InputFileUploadProps>;
75
84
 
76
85
  type ImageUploadAvatarProps = {
77
86
  name?: string;
@@ -162,7 +171,8 @@ interface SearchableSelectProps {
162
171
  size?: "small" | "medium";
163
172
  style?: React__default.CSSProperties;
164
173
  disabled?: boolean;
165
- onClear?: () => void;
174
+ /** If `null` or omitted, the clear control is not shown. Pass a handler to enable clear. */
175
+ onClear?: (() => void) | null;
166
176
  defaultEditMode?: boolean;
167
177
  multiple?: boolean;
168
178
  }
package/dist/index.js CHANGED
@@ -393,7 +393,7 @@ var import_icons_material = require("@mui/icons-material");
393
393
  var import_jsx_runtime4 = require("react/jsx-runtime");
394
394
  var BootstrapDialog = (0, import_styles2.styled)(import_material3.Dialog)(({ theme }) => ({
395
395
  "& .MuiDialog-paper": {
396
- borderRadius: "24px"
396
+ borderRadius: 24
397
397
  },
398
398
  "& .MuiDialogContent-root": {
399
399
  padding: theme.spacing(4)
@@ -484,6 +484,9 @@ var glassSurface = (theme) => ({
484
484
  WebkitBackdropFilter: "blur(18px) saturate(155%)",
485
485
  boxShadow: theme.palette.mode === "dark" ? "0 16px 40px rgba(0,0,0,0.34)" : "0 14px 34px rgba(15, 23, 42, 0.12)"
486
486
  });
487
+ var glassHover = (theme) => ({
488
+ background: theme.palette.mode === "dark" ? `linear-gradient(160deg, ${(0, import_styles4.alpha)("#374151", 0.8)} 0%, ${(0, import_styles4.alpha)("#1F2937", 0.74)} 100%)` : `linear-gradient(160deg, ${(0, import_styles4.alpha)("#FFFFFF", 0.97)} 0%, ${(0, import_styles4.alpha)("#EEF5FF", 0.86)} 100%)`
489
+ });
487
490
 
488
491
  // src/InputFileUpload.tsx
489
492
  var import_jsx_runtime5 = require("react/jsx-runtime");
@@ -498,33 +501,113 @@ var VisuallyHiddenInput = (0, import_styles5.styled)("input")({
498
501
  whiteSpace: "nowrap",
499
502
  width: 1
500
503
  });
501
- var InputFileUpload = ({ name = "", onChange = () => null, title = "" }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
502
- import_material4.Button,
503
- {
504
- role: void 0,
505
- component: "label",
506
- size: "small",
507
- variant: "contained",
508
- tabIndex: -1,
509
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_material2.CloudUpload, { fontSize: "inherit" }),
510
- sx: {
511
- ...(theme) => glassSurface(theme),
512
- textTransform: "none",
513
- borderRadius: 999,
514
- px: 2.25,
515
- py: 0.75,
516
- color: "text.primary",
517
- borderColor: (theme) => (0, import_styles5.alpha)(theme.palette.primary.main, 0.24),
518
- "&:hover": {
519
- borderColor: (theme) => (0, import_styles5.alpha)(theme.palette.primary.main, 0.42)
520
- }
521
- },
522
- children: [
523
- title,
524
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VisuallyHiddenInput, { type: "file", name, onChange })
525
- ]
526
- }
527
- );
504
+ var InputFileUpload = ({
505
+ name = "",
506
+ onChange = () => null,
507
+ title = "Choose file",
508
+ subtitle = "Tap to browse",
509
+ accept,
510
+ multiple,
511
+ disabled = false,
512
+ fullWidth = false
513
+ }) => {
514
+ const theme = (0, import_styles5.useTheme)();
515
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
516
+ import_material4.Box,
517
+ {
518
+ component: "label",
519
+ sx: (t) => ({
520
+ ...glassSurface(t),
521
+ display: fullWidth ? "flex" : "inline-flex",
522
+ alignItems: "center",
523
+ gap: 2,
524
+ width: fullWidth ? "100%" : "auto",
525
+ maxWidth: "100%",
526
+ px: 2.25,
527
+ py: 1.75,
528
+ borderRadius: 2.5,
529
+ cursor: disabled ? "not-allowed" : "pointer",
530
+ opacity: disabled ? 0.52 : 1,
531
+ pointerEvents: disabled ? "none" : "auto",
532
+ transition: "box-shadow 0.2s ease, transform 0.2s ease",
533
+ borderStyle: "dashed",
534
+ borderWidth: 1,
535
+ borderColor: (0, import_styles5.alpha)(
536
+ t.palette.primary.main,
537
+ t.palette.mode === "dark" ? 0.35 : 0.28
538
+ ),
539
+ "&:hover": !disabled ? {
540
+ ...glassHover(t),
541
+ borderColor: (0, import_styles5.alpha)(t.palette.primary.main, 0.45),
542
+ boxShadow: t.palette.mode === "dark" ? "0 12px 28px rgba(0,0,0,0.38)" : "0 12px 28px rgba(15, 23, 42, 0.12)"
543
+ } : void 0,
544
+ "&:focus-within": {
545
+ outline: `2px solid ${(0, import_styles5.alpha)(t.palette.primary.main, 0.45)}`,
546
+ outlineOffset: 2
547
+ }
548
+ }),
549
+ children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
551
+ import_material4.Box,
552
+ {
553
+ "aria-hidden": true,
554
+ sx: {
555
+ flexShrink: 0,
556
+ width: 44,
557
+ height: 44,
558
+ borderRadius: 2,
559
+ display: "flex",
560
+ alignItems: "center",
561
+ justifyContent: "center",
562
+ background: (0, import_styles5.alpha)(
563
+ theme.palette.primary.main,
564
+ theme.palette.mode === "dark" ? 0.22 : 0.12
565
+ ),
566
+ border: `1px solid ${(0, import_styles5.alpha)(theme.palette.primary.main, 0.25)}`,
567
+ color: "primary.main"
568
+ },
569
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_material2.CloudUpload, { sx: { fontSize: 22 } })
570
+ }
571
+ ),
572
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { sx: { flex: 1, minWidth: 0, textAlign: "left" }, children: [
573
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
574
+ import_material4.Typography,
575
+ {
576
+ variant: "subtitle2",
577
+ component: "span",
578
+ display: "block",
579
+ fontWeight: 700,
580
+ color: "text.primary",
581
+ letterSpacing: "-0.01em",
582
+ children: title
583
+ }
584
+ ),
585
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
586
+ import_material4.Typography,
587
+ {
588
+ variant: "caption",
589
+ color: "text.secondary",
590
+ display: "block",
591
+ sx: { mt: 0.25 },
592
+ children: subtitle
593
+ }
594
+ )
595
+ ] }),
596
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
597
+ VisuallyHiddenInput,
598
+ {
599
+ type: "file",
600
+ name,
601
+ onChange,
602
+ accept,
603
+ multiple,
604
+ disabled
605
+ }
606
+ )
607
+ ]
608
+ }
609
+ );
610
+ };
528
611
  var InputFileUpload_default = InputFileUpload;
529
612
 
530
613
  // src/ImageUploadAvatar.tsx
@@ -707,9 +790,7 @@ var FormSnackBar = ({
707
790
  const idRef = (0, import_react3.useRef)(0);
708
791
  const prevOpenRef = (0, import_react3.useRef)(!!(snackBar == null ? void 0 : snackBar.open));
709
792
  const prevSignatureRef = (0, import_react3.useRef)("");
710
- const timersRef = (0, import_react3.useRef)(
711
- {}
712
- );
793
+ const timersRef = (0, import_react3.useRef)({});
713
794
  const type = (_a2 = snackBar.type) != null ? _a2 : "";
714
795
  const message = (_b = snackBar.message) != null ? _b : "";
715
796
  const severity = isSnackbarType(type) ? type : "info";
@@ -781,7 +862,7 @@ var FormSnackBar = ({
781
862
  sx: {
782
863
  width: "100%",
783
864
  pointerEvents: "auto",
784
- borderRadius: 3,
865
+ borderRadius: 2,
785
866
  px: { xs: 1.25, sm: 1.5 },
786
867
  py: 0.875,
787
868
  alignItems: "center",
@@ -985,7 +1066,7 @@ var Pill = ({
985
1066
  color: color || "primary",
986
1067
  sx: {
987
1068
  ...glassSurface(theme),
988
- borderRadius: "999px",
1069
+ borderRadius: 16,
989
1070
  padding: "8px 16px",
990
1071
  minHeight: 38,
991
1072
  textTransform: "none",
@@ -1068,7 +1149,7 @@ var IOSSwitch = (0, import_styles11.styled)((props) => /* @__PURE__ */ (0, impor
1068
1149
  boxShadow: theme.palette.mode === "dark" ? "0 2px 8px rgba(0,0,0,0.38)" : "0 2px 6px rgba(15,23,42,0.24)"
1069
1150
  },
1070
1151
  "& .MuiSwitch-track": {
1071
- borderRadius: 30 / 2,
1152
+ borderRadius: 16,
1072
1153
  background: theme.palette.mode === "light" ? "linear-gradient(120deg, rgba(245,248,255,0.92) 0%, rgba(224,232,245,0.92) 100%)" : "linear-gradient(120deg, rgba(55,65,81,0.74) 0%, rgba(31,41,55,0.8) 100%)",
1073
1154
  border: `1px solid ${(0, import_styles11.alpha)("#FFFFFF", theme.palette.mode === "dark" ? 0.16 : 0.56)}`,
1074
1155
  backdropFilter: "blur(10px) saturate(145%)",
@@ -1104,7 +1185,7 @@ var StatusPill = ({ status }) => {
1104
1185
  ...glassSurface(theme),
1105
1186
  minHeight: 38,
1106
1187
  fontWeight: 700,
1107
- borderRadius: "999px",
1188
+ borderRadius: 16,
1108
1189
  px: 1.25,
1109
1190
  letterSpacing: "0.01em",
1110
1191
  color: (_a2 = statusColorMap[status]) != null ? _a2 : theme.palette.text.primary,
@@ -1214,7 +1295,7 @@ var SearchableSelect = import_react6.default.memo(
1214
1295
  size = "small",
1215
1296
  style,
1216
1297
  disabled = false,
1217
- onClear,
1298
+ onClear = null,
1218
1299
  defaultEditMode = false,
1219
1300
  multiple = false
1220
1301
  }) => {
@@ -1248,8 +1329,6 @@ var SearchableSelect = import_react6.default.memo(
1248
1329
  event.stopPropagation();
1249
1330
  if (onClear) {
1250
1331
  onClear();
1251
- } else {
1252
- onChange("");
1253
1332
  }
1254
1333
  setEditMode(false);
1255
1334
  setOpen(false);
@@ -1274,6 +1353,7 @@ var SearchableSelect = import_react6.default.memo(
1274
1353
  }
1275
1354
  }, [selected, multiple]);
1276
1355
  const isValueEmpty = !value.trim();
1356
+ const showClear = onClear != null;
1277
1357
  return editMode ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.FormControl, { fullWidth: true, style, disabled, size, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1278
1358
  import_material13.Autocomplete,
1279
1359
  {
@@ -1365,7 +1445,7 @@ var SearchableSelect = import_react6.default.memo(
1365
1445
  InputProps: {
1366
1446
  ...params.InputProps,
1367
1447
  sx: {
1368
- borderRadius: 1.75,
1448
+ borderRadius: 2,
1369
1449
  backdropFilter: "blur(10px)",
1370
1450
  pr: 1.5,
1371
1451
  background: glassBackground,
@@ -1388,7 +1468,7 @@ var SearchableSelect = import_react6.default.memo(
1388
1468
  }
1389
1469
  },
1390
1470
  endAdornment: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
1391
- !isValueEmpty && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1471
+ showClear && !isValueEmpty && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1392
1472
  import_material13.IconButton,
1393
1473
  {
1394
1474
  "aria-label": `clear ${name}`,
@@ -1425,8 +1505,22 @@ var SearchableSelect = import_react6.default.memo(
1425
1505
  className: classes.defaultMode,
1426
1506
  style,
1427
1507
  children: [
1428
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.FormLabel, { className: classes.formLabel, sx: { color: "text.secondary" }, children: label }),
1429
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.Typography, { className: classes.formValue, sx: { color: "text.primary" }, children: displayValue })
1508
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1509
+ import_material13.FormLabel,
1510
+ {
1511
+ className: classes.formLabel,
1512
+ sx: { color: "text.secondary" },
1513
+ children: label
1514
+ }
1515
+ ),
1516
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1517
+ import_material13.Typography,
1518
+ {
1519
+ className: classes.formValue,
1520
+ sx: { color: "text.primary" },
1521
+ children: displayValue
1522
+ }
1523
+ )
1430
1524
  ]
1431
1525
  }
1432
1526
  );