@ews-admin/global-design-system 1.1.10 → 1.1.12

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.
@@ -36,4 +36,17 @@ export declare function debounce<T extends (...args: any[]) => any>(func: T, wai
36
36
  * @returns Unique ID string
37
37
  */
38
38
  export declare function generateId(prefix?: string): string;
39
+ /**
40
+ * Utility function to format numeric input by removing non-digit characters
41
+ * @param value - String value to format
42
+ * @returns String with only numeric characters
43
+ */
44
+ export declare const formatNumeric: (value: string) => string;
45
+ /**
46
+ * Utility function to validate phone numbers
47
+ * Validates phone numbers with 1-15 digits, starting with a non-zero digit
48
+ * @param value - Phone number string to validate
49
+ * @returns Boolean indicating if the phone number is valid
50
+ */
51
+ export declare function isValidPhoneNumber(value: string): boolean;
39
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAE9B;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAW,GAAG,MAAM,CAK1E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAC5B,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,GACnC,MAAM,CAQR;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAMlC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,SAAQ,GAAG,MAAM,CAEjD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAE9B;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAW,GAAG,MAAM,CAK1E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAC5B,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,GACnC,MAAM,CAQR;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAMlC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,SAAQ,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAE7C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIzD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ews-admin/global-design-system",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "description": "EWS Global Design System - Reusable components for EWS applications",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -99,6 +99,62 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
99
99
  lg: "h-6 w-6",
100
100
  };
101
101
 
102
+ const isCheckbox = type === "checkbox";
103
+
104
+ // For checkboxes, render with or without label based on label prop
105
+ if (isCheckbox) {
106
+ if (label) {
107
+ // Render checkbox with built-in label
108
+ return (
109
+ <div className={cn("space-y-1", fullWidth ? "w-full" : "w-auto")}>
110
+ <div className="flex items-start space-x-3">
111
+ <input
112
+ id={inputId}
113
+ type={actualType}
114
+ className={cn(
115
+ "mt-0.5", // Slight top margin to align with first line of text
116
+ className
117
+ )}
118
+ ref={ref}
119
+ {...props}
120
+ />
121
+ <div className="flex-1">
122
+ <label
123
+ htmlFor={inputId}
124
+ className="block text-sm font-medium cursor-pointer text-ews-gray-700"
125
+ >
126
+ {label}
127
+ {required && <span className="ml-1 text-ews-error">*</span>}
128
+ </label>
129
+ {(error || helperText) && (
130
+ <p
131
+ className={cn(
132
+ "mt-1 text-sm",
133
+ error ? "text-ews-error" : "text-ews-gray-500"
134
+ )}
135
+ >
136
+ {error || helperText}
137
+ </p>
138
+ )}
139
+ </div>
140
+ </div>
141
+ </div>
142
+ );
143
+ } else {
144
+ // Render just the checkbox for external label usage
145
+ return (
146
+ <input
147
+ id={inputId}
148
+ type={actualType}
149
+ className={cn(className)}
150
+ ref={ref}
151
+ {...props}
152
+ />
153
+ );
154
+ }
155
+ }
156
+
157
+ // Default rendering for non-checkbox inputs
102
158
  return (
103
159
  <div className={cn("space-y-1", fullWidth ? "w-full" : "w-auto")}>
104
160
  {label && (
@@ -181,7 +181,7 @@ export function MultiSearchAutocomplete<T extends SearchableEntity>({
181
181
 
182
182
  // Default render functions
183
183
  const defaultRenderSelectedItem = (entity: T) => (
184
- <span className="inline-flex items-center px-3 py-1 text-sm font-medium rounded-full bg-ews-primary/10 text-ews-primary border border-ews-primary/20">
184
+ <span className="inline-flex items-center px-3 py-1 text-sm font-medium rounded-full border bg-ews-primary/10 text-ews-primary border-ews-primary/20">
185
185
  {getPrimaryText(entity)}
186
186
  <button
187
187
  type="button"
@@ -199,8 +199,10 @@ export function MultiSearchAutocomplete<T extends SearchableEntity>({
199
199
  <div className="flex items-center space-x-3">
200
200
  <div
201
201
  className={cn(
202
- "w-5 h-5 border-2 rounded flex items-center justify-center",
203
- isSelected ? "bg-ews-primary border-ews-primary" : "border-gray-300"
202
+ "flex justify-center items-center w-5 h-5 rounded border-2",
203
+ isSelected
204
+ ? "bg-ews-primary border-ews-primary"
205
+ : "border-ews-gray-300"
204
206
  )}
205
207
  >
206
208
  {isSelected && <Check className="w-3 h-3 text-white" />}
@@ -259,23 +261,23 @@ export function MultiSearchAutocomplete<T extends SearchableEntity>({
259
261
 
260
262
  {/* Dropdown */}
261
263
  {isOpen && !disabled && (
262
- <div className="absolute z-10 mt-1 w-full max-h-60 bg-white rounded-lg border border-gray-200 shadow-lg overflow-auto">
264
+ <div className="overflow-auto absolute z-10 mt-1 w-full max-h-60 bg-white rounded-lg border border-gray-200 shadow-lg">
263
265
  {loading || isSearching ? (
264
- <div className="px-4 py-3 text-sm text-gray-500 flex items-center">
265
- <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-ews-primary mr-2"></div>
266
+ <div className="flex items-center px-4 py-3 text-sm text-gray-500">
267
+ <div className="mr-2 w-4 h-4 rounded-full border-b-2 animate-spin border-ews-primary"></div>
266
268
  {isSearching ? "Searching..." : "Loading..."}
267
269
  </div>
268
270
  ) : searchError ? (
269
271
  <div className="px-4 py-3 text-sm text-red-600">
270
272
  <div className="flex items-center">
271
- <X className="w-4 h-4 mr-2" />
273
+ <X className="mr-2 w-4 h-4" />
272
274
  Error: {searchError}
273
275
  </div>
274
276
  </div>
275
277
  ) : error ? (
276
278
  <div className="px-4 py-3 text-sm text-red-600">
277
279
  <div className="flex items-center">
278
- <X className="w-4 h-4 mr-2" />
280
+ <X className="mr-2 w-4 h-4" />
279
281
  {error}
280
282
  </div>
281
283
  </div>
@@ -298,10 +300,10 @@ export function MultiSearchAutocomplete<T extends SearchableEntity>({
298
300
  type="button"
299
301
  onClick={() => handleItemToggle(item)}
300
302
  className={cn(
301
- "w-full px-4 py-3 text-left flex items-center transition-colors",
303
+ "flex items-center px-4 py-3 w-full text-left transition-colors",
302
304
  isSelected
303
- ? "bg-ews-primary/10 text-ews-primary border-l-4 border-ews-primary"
304
- : "hover:bg-ews-primary/5 text-gray-900"
305
+ ? "border-l-4 bg-ews-primary/10 text-ews-primary border-ews-primary"
306
+ : "text-gray-900 hover:bg-ews-primary/5"
305
307
  )}
306
308
  >
307
309
  {renderListItem
@@ -375,7 +375,7 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(
375
375
  htmlFor={selectId}
376
376
  className={cn(
377
377
  "block text-sm font-medium mb-1",
378
- hasError ? "text-ews-error" : "text-ews-gray-700",
378
+ "text-ews-gray-700",
379
379
  disabled && "text-ews-gray-400"
380
380
  )}
381
381
  >
package/src/index.ts CHANGED
@@ -42,7 +42,15 @@ export {
42
42
  export type { IconProps, SimpleIconProps } from "./icons";
43
43
 
44
44
  // Utils
45
- export { cn, debounce, formatCurrency, formatDate, generateId } from "./utils";
45
+ export {
46
+ cn,
47
+ debounce,
48
+ formatCurrency,
49
+ formatDate,
50
+ formatNumeric,
51
+ generateId,
52
+ isValidPhoneNumber,
53
+ } from "./utils";
46
54
 
47
55
  // Hooks
48
56
  export { useDebounce, useDebouncedCallback, useSelectField } from "./hooks";
@@ -145,7 +145,7 @@ export const SpecialtySearchAutocomplete: React.FC<
145
145
  "w-5 h-5 border-2 rounded flex items-center justify-center",
146
146
  isSelected
147
147
  ? "bg-ews-primary border-ews-primary"
148
- : "border-gray-300"
148
+ : "border-ews-gray-300"
149
149
  )}
150
150
  >
151
151
  {isSelected && (
@@ -287,4 +287,36 @@ div[tabindex]:focus {
287
287
  .hover-scale:hover {
288
288
  transform: scale(1.02);
289
289
  }
290
+
291
+ /* Custom checkbox styling for better control */
292
+ input[type="checkbox"] {
293
+ width: 1rem;
294
+ height: 1rem;
295
+ border-radius: 0.25rem;
296
+ border: 2px solid var(--ews-gray-300);
297
+ background-color: white;
298
+ cursor: pointer;
299
+ transition: all 0.2s ease-in-out;
300
+ accent-color: var(--ews-primary);
301
+ }
302
+
303
+ input[type="checkbox"]:hover {
304
+ border-color: var(--ews-primary);
305
+ }
306
+
307
+ input[type="checkbox"]:focus {
308
+ outline: none;
309
+ border-color: var(--ews-primary);
310
+ box-shadow: 0 0 0 2px var(--ews-primary);
311
+ }
312
+
313
+ input[type="checkbox"]:checked {
314
+ background-color: var(--ews-primary);
315
+ border-color: var(--ews-primary);
316
+ }
317
+
318
+ input[type="checkbox"]:disabled {
319
+ opacity: 0.5;
320
+ cursor: not-allowed;
321
+ }
290
322
  }
@@ -71,3 +71,24 @@ export function debounce<T extends (...args: any[]) => any>(
71
71
  export function generateId(prefix = "ews"): string {
72
72
  return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
73
73
  }
74
+
75
+ /**
76
+ * Utility function to format numeric input by removing non-digit characters
77
+ * @param value - String value to format
78
+ * @returns String with only numeric characters
79
+ */
80
+ export const formatNumeric = (value: string): string => {
81
+ return value.replace(/\D/g, "");
82
+ };
83
+
84
+ /**
85
+ * Utility function to validate phone numbers
86
+ * Validates phone numbers with 1-15 digits, starting with a non-zero digit
87
+ * @param value - Phone number string to validate
88
+ * @returns Boolean indicating if the phone number is valid
89
+ */
90
+ export function isValidPhoneNumber(value: string): boolean {
91
+ const trimmedValue = value.trim();
92
+ const phoneRegex = /^[0-9]\d{1,14}$/;
93
+ return phoneRegex.test(trimmedValue);
94
+ }