@ews-admin/global-design-system 1.0.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.
Files changed (42) hide show
  1. package/README.md +195 -0
  2. package/dist/components/Button/Button.d.ts +30 -0
  3. package/dist/components/Button/Button.d.ts.map +1 -0
  4. package/dist/components/Button/index.d.ts +3 -0
  5. package/dist/components/Button/index.d.ts.map +1 -0
  6. package/dist/components/Input/Input.d.ts +38 -0
  7. package/dist/components/Input/Input.d.ts.map +1 -0
  8. package/dist/components/Input/index.d.ts +3 -0
  9. package/dist/components/Input/index.d.ts.map +1 -0
  10. package/dist/icons/ArrowRight.d.ts +4 -0
  11. package/dist/icons/ArrowRight.d.ts.map +1 -0
  12. package/dist/icons/Check.d.ts +4 -0
  13. package/dist/icons/Check.d.ts.map +1 -0
  14. package/dist/icons/Icon.d.ts +14 -0
  15. package/dist/icons/Icon.d.ts.map +1 -0
  16. package/dist/icons/Search.d.ts +4 -0
  17. package/dist/icons/Search.d.ts.map +1 -0
  18. package/dist/icons/index.d.ts +6 -0
  19. package/dist/icons/index.d.ts.map +1 -0
  20. package/dist/index.css +1 -0
  21. package/dist/index.d.ts +121 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.esm.css +1 -0
  24. package/dist/index.esm.js +124 -0
  25. package/dist/index.esm.js.map +1 -0
  26. package/dist/index.js +136 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/utils/index.d.ts +35 -0
  29. package/dist/utils/index.d.ts.map +1 -0
  30. package/package.json +70 -0
  31. package/src/components/Button/Button.tsx +117 -0
  32. package/src/components/Button/index.ts +2 -0
  33. package/src/components/Input/Input.tsx +145 -0
  34. package/src/components/Input/index.ts +2 -0
  35. package/src/icons/ArrowRight.tsx +9 -0
  36. package/src/icons/Check.tsx +8 -0
  37. package/src/icons/Icon.tsx +40 -0
  38. package/src/icons/Search.tsx +9 -0
  39. package/src/icons/index.ts +5 -0
  40. package/src/index.ts +16 -0
  41. package/src/styles/index.css +95 -0
  42. package/src/utils/index.ts +68 -0
package/dist/index.js ADDED
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+
6
+ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
7
+
8
+ /**
9
+ * Utility function to merge class names
10
+ * @param inputs - Class values to merge
11
+ * @returns Merged class string
12
+ */
13
+ function cn(...inputs) {
14
+ return clsx(inputs);
15
+ }
16
+ /**
17
+ * Utility function to format currency
18
+ * @param amount - Amount to format
19
+ * @param currency - Currency code (default: 'USD')
20
+ * @returns Formatted currency string
21
+ */
22
+ function formatCurrency(amount, currency = "USD") {
23
+ return new Intl.NumberFormat("en-US", {
24
+ style: "currency",
25
+ currency,
26
+ }).format(amount);
27
+ }
28
+ /**
29
+ * Utility function to format date
30
+ * @param date - Date to format
31
+ * @param options - Intl.DateTimeFormat options
32
+ * @returns Formatted date string
33
+ */
34
+ function formatDate(date, options) {
35
+ const dateObj = new Date(date);
36
+ return new Intl.DateTimeFormat("en-US", {
37
+ year: "numeric",
38
+ month: "long",
39
+ day: "numeric",
40
+ ...options,
41
+ }).format(dateObj);
42
+ }
43
+ /**
44
+ * Utility function to debounce function calls
45
+ * @param func - Function to debounce
46
+ * @param wait - Wait time in milliseconds
47
+ * @returns Debounced function
48
+ */
49
+ function debounce(func, wait) {
50
+ let timeout;
51
+ return (...args) => {
52
+ clearTimeout(timeout);
53
+ timeout = setTimeout(() => func(...args), wait);
54
+ };
55
+ }
56
+ /**
57
+ * Utility function to generate unique ID
58
+ * @param prefix - Optional prefix for the ID
59
+ * @returns Unique ID string
60
+ */
61
+ function generateId(prefix = "ews") {
62
+ return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
63
+ }
64
+
65
+ const Button = React.forwardRef(({ className, variant = "primary", size = "md", loading = false, fullWidth = false, leftIcon, rightIcon, children, disabled, ...props }, ref) => {
66
+ const baseStyles = "inline-flex items-center justify-center font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none";
67
+ const variants = {
68
+ primary: "bg-[var(--ews-primary)] text-white hover:bg-[var(--ews-primary-hover)] focus:ring-[var(--ews-primary)]",
69
+ secondary: "bg-[var(--ews-gray-200)] text-[var(--ews-gray-900)] hover:bg-[var(--ews-gray-300)] focus:ring-[var(--ews-gray-500)]",
70
+ success: "bg-[var(--ews-success)] text-white hover:bg-[var(--ews-success-hover)] focus:ring-[var(--ews-success)]",
71
+ warning: "bg-[var(--ews-warning)] text-white hover:bg-[var(--ews-warning-hover)] focus:ring-[var(--ews-warning)]",
72
+ error: "bg-[var(--ews-error)] text-white hover:bg-[var(--ews-error-hover)] focus:ring-[var(--ews-error)]",
73
+ ghost: "bg-transparent text-[var(--ews-gray-700)] hover:bg-[var(--ews-gray-100)] focus:ring-[var(--ews-gray-500)]",
74
+ };
75
+ const sizes = {
76
+ sm: "px-3 py-1.5 text-sm",
77
+ md: "px-4 py-2 text-base",
78
+ lg: "px-6 py-3 text-lg",
79
+ };
80
+ return (jsxRuntime.jsxs("button", { className: cn(baseStyles, variants[variant], sizes[size], fullWidth && "w-full", className), ref: ref, disabled: disabled || loading, ...props, children: [loading && (jsxRuntime.jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] })), !loading && leftIcon && jsxRuntime.jsx("span", { className: "mr-2", children: leftIcon }), children, !loading && rightIcon && jsxRuntime.jsx("span", { className: "ml-2", children: rightIcon })] }));
81
+ });
82
+ Button.displayName = "Button";
83
+
84
+ const Input = React.forwardRef(({ className, variant = "default", size = "md", label, helperText, error, leftIcon, rightIcon, fullWidth = false, id, ...props }, ref) => {
85
+ const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
86
+ const hasError = Boolean(error);
87
+ const actualVariant = hasError ? "error" : variant;
88
+ const baseStyles = "block w-full rounded-md border transition-colors focus:outline-none focus:ring-2 focus:ring-offset-0";
89
+ const variants = {
90
+ default: "border-[var(--ews-gray-300)] focus:border-[var(--ews-primary)] focus:ring-[var(--ews-primary)]",
91
+ error: "border-[var(--ews-error)] focus:border-[var(--ews-error)] focus:ring-[var(--ews-error)]",
92
+ success: "border-[var(--ews-success)] focus:border-[var(--ews-success)] focus:ring-[var(--ews-success)]",
93
+ };
94
+ const sizes = {
95
+ sm: "px-3 py-1.5 text-sm",
96
+ md: "px-3 py-2 text-base",
97
+ lg: "px-4 py-3 text-lg",
98
+ };
99
+ const iconSizes = {
100
+ sm: "h-4 w-4",
101
+ md: "h-5 w-5",
102
+ lg: "h-6 w-6",
103
+ };
104
+ return (jsxRuntime.jsxs("div", { className: cn("space-y-1", fullWidth ? "w-full" : "w-auto"), children: [label && (jsxRuntime.jsx("label", { htmlFor: inputId, className: "block text-sm font-medium text-[var(--ews-gray-700)]", children: label })), jsxRuntime.jsxs("div", { className: "relative", children: [leftIcon && (jsxRuntime.jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: jsxRuntime.jsx("span", { className: cn("text-[var(--ews-gray-400)]", iconSizes[size]), children: leftIcon }) })), jsxRuntime.jsx("input", { id: inputId, className: cn(baseStyles, variants[actualVariant], sizes[size], leftIcon && "pl-10", rightIcon && "pr-10", className), ref: ref, ...props }), rightIcon && (jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: jsxRuntime.jsx("span", { className: cn("text-[var(--ews-gray-400)]", iconSizes[size]), children: rightIcon }) }))] }), (error || helperText) && (jsxRuntime.jsx("p", { className: cn("text-sm", error ? "text-[var(--ews-error)]" : "text-[var(--ews-gray-500)]"), children: error || helperText }))] }));
105
+ });
106
+ Input.displayName = "Input";
107
+
108
+ const Icon = React.forwardRef(({ size = "md", color = "currentColor", className, ...props }, ref) => {
109
+ const sizes = {
110
+ sm: "h-4 w-4",
111
+ md: "h-5 w-5",
112
+ lg: "h-6 w-6",
113
+ xl: "h-8 w-8",
114
+ };
115
+ return (jsxRuntime.jsx("svg", { ref: ref, className: `${sizes[size]} ${className || ""}`, fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props }));
116
+ });
117
+ Icon.displayName = "Icon";
118
+
119
+ const ArrowRight = (props) => (jsxRuntime.jsxs(Icon, { ...props, children: [jsxRuntime.jsx("path", { d: "M5 12h14" }), jsxRuntime.jsx("path", { d: "m12 5 7 7-7 7" })] }));
120
+
121
+ const Check = (props) => (jsxRuntime.jsx(Icon, { ...props, children: jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }));
122
+
123
+ const Search = (props) => (jsxRuntime.jsxs(Icon, { ...props, children: [jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }), jsxRuntime.jsx("path", { d: "m21 21-4.35-4.35" })] }));
124
+
125
+ exports.ArrowRight = ArrowRight;
126
+ exports.Button = Button;
127
+ exports.Check = Check;
128
+ exports.Icon = Icon;
129
+ exports.Input = Input;
130
+ exports.Search = Search;
131
+ exports.cn = cn;
132
+ exports.debounce = debounce;
133
+ exports.formatCurrency = formatCurrency;
134
+ exports.formatDate = formatDate;
135
+ exports.generateId = generateId;
136
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/utils/index.ts","../src/components/Button/Button.tsx","../src/components/Input/Input.tsx","../src/icons/Icon.tsx","../src/icons/ArrowRight.tsx","../src/icons/Check.tsx","../src/icons/Search.tsx"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { clsx, type ClassValue } from \"clsx\";\n\n/**\n * Utility function to merge class names\n * @param inputs - Class values to merge\n * @returns Merged class string\n */\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs);\n}\n\n/**\n * Utility function to format currency\n * @param amount - Amount to format\n * @param currency - Currency code (default: 'USD')\n * @returns Formatted currency string\n */\nexport function formatCurrency(amount: number, currency = \"USD\"): string {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency,\n }).format(amount);\n}\n\n/**\n * Utility function to format date\n * @param date - Date to format\n * @param options - Intl.DateTimeFormat options\n * @returns Formatted date string\n */\nexport function formatDate(\n date: Date | string | number,\n options?: Intl.DateTimeFormatOptions\n): string {\n const dateObj = new Date(date);\n return new Intl.DateTimeFormat(\"en-US\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n ...options,\n }).format(dateObj);\n}\n\n/**\n * Utility function to debounce function calls\n * @param func - Function to debounce\n * @param wait - Wait time in milliseconds\n * @returns Debounced function\n */\nexport function debounce<T extends (...args: any[]) => any>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout>;\n return (...args: Parameters<T>) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => func(...args), wait);\n };\n}\n\n/**\n * Utility function to generate unique ID\n * @param prefix - Optional prefix for the ID\n * @returns Unique ID string\n */\nexport function generateId(prefix = \"ews\"): string {\n return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;\n}\n","import React from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Button variant\n */\n variant?: \"primary\" | \"secondary\" | \"success\" | \"warning\" | \"error\" | \"ghost\";\n /**\n * Button size\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Whether the button is in a loading state\n */\n loading?: boolean;\n /**\n * Whether the button should take full width\n */\n fullWidth?: boolean;\n /**\n * Icon to display before the button text\n */\n leftIcon?: React.ReactNode;\n /**\n * Icon to display after the button text\n */\n rightIcon?: React.ReactNode;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant = \"primary\",\n size = \"md\",\n loading = false,\n fullWidth = false,\n leftIcon,\n rightIcon,\n children,\n disabled,\n ...props\n },\n ref\n ) => {\n const baseStyles =\n \"inline-flex items-center justify-center font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none\";\n\n const variants = {\n primary:\n \"bg-[var(--ews-primary)] text-white hover:bg-[var(--ews-primary-hover)] focus:ring-[var(--ews-primary)]\",\n secondary:\n \"bg-[var(--ews-gray-200)] text-[var(--ews-gray-900)] hover:bg-[var(--ews-gray-300)] focus:ring-[var(--ews-gray-500)]\",\n success:\n \"bg-[var(--ews-success)] text-white hover:bg-[var(--ews-success-hover)] focus:ring-[var(--ews-success)]\",\n warning:\n \"bg-[var(--ews-warning)] text-white hover:bg-[var(--ews-warning-hover)] focus:ring-[var(--ews-warning)]\",\n error:\n \"bg-[var(--ews-error)] text-white hover:bg-[var(--ews-error-hover)] focus:ring-[var(--ews-error)]\",\n ghost:\n \"bg-transparent text-[var(--ews-gray-700)] hover:bg-[var(--ews-gray-100)] focus:ring-[var(--ews-gray-500)]\",\n };\n\n const sizes = {\n sm: \"px-3 py-1.5 text-sm\",\n md: \"px-4 py-2 text-base\",\n lg: \"px-6 py-3 text-lg\",\n };\n\n return (\n <button\n className={cn(\n baseStyles,\n variants[variant],\n sizes[size],\n fullWidth && \"w-full\",\n className\n )}\n ref={ref}\n disabled={disabled || loading}\n {...props}\n >\n {loading && (\n <svg\n className=\"animate-spin -ml-1 mr-2 h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n )}\n {!loading && leftIcon && <span className=\"mr-2\">{leftIcon}</span>}\n {children}\n {!loading && rightIcon && <span className=\"ml-2\">{rightIcon}</span>}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n\nexport { Button };\n","import React from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface InputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n /**\n * Input variant\n */\n variant?: \"default\" | \"error\" | \"success\";\n /**\n * Input size\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Label for the input\n */\n label?: string;\n /**\n * Helper text to display below the input\n */\n helperText?: string;\n /**\n * Error message to display\n */\n error?: string;\n /**\n * Icon to display before the input\n */\n leftIcon?: React.ReactNode;\n /**\n * Icon to display after the input\n */\n rightIcon?: React.ReactNode;\n /**\n * Whether the input should take full width\n */\n fullWidth?: boolean;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className,\n variant = \"default\",\n size = \"md\",\n label,\n helperText,\n error,\n leftIcon,\n rightIcon,\n fullWidth = false,\n id,\n ...props\n },\n ref\n ) => {\n const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;\n const hasError = Boolean(error);\n const actualVariant = hasError ? \"error\" : variant;\n\n const baseStyles =\n \"block w-full rounded-md border transition-colors focus:outline-none focus:ring-2 focus:ring-offset-0\";\n\n const variants = {\n default:\n \"border-[var(--ews-gray-300)] focus:border-[var(--ews-primary)] focus:ring-[var(--ews-primary)]\",\n error:\n \"border-[var(--ews-error)] focus:border-[var(--ews-error)] focus:ring-[var(--ews-error)]\",\n success:\n \"border-[var(--ews-success)] focus:border-[var(--ews-success)] focus:ring-[var(--ews-success)]\",\n };\n\n const sizes = {\n sm: \"px-3 py-1.5 text-sm\",\n md: \"px-3 py-2 text-base\",\n lg: \"px-4 py-3 text-lg\",\n };\n\n const iconSizes = {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-6 w-6\",\n };\n\n return (\n <div className={cn(\"space-y-1\", fullWidth ? \"w-full\" : \"w-auto\")}>\n {label && (\n <label\n htmlFor={inputId}\n className=\"block text-sm font-medium text-[var(--ews-gray-700)]\"\n >\n {label}\n </label>\n )}\n <div className=\"relative\">\n {leftIcon && (\n <div className=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\n <span\n className={cn(\"text-[var(--ews-gray-400)]\", iconSizes[size])}\n >\n {leftIcon}\n </span>\n </div>\n )}\n <input\n id={inputId}\n className={cn(\n baseStyles,\n variants[actualVariant],\n sizes[size],\n leftIcon && \"pl-10\",\n rightIcon && \"pr-10\",\n className\n )}\n ref={ref}\n {...props}\n />\n {rightIcon && (\n <div className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\">\n <span\n className={cn(\"text-[var(--ews-gray-400)]\", iconSizes[size])}\n >\n {rightIcon}\n </span>\n </div>\n )}\n </div>\n {(error || helperText) && (\n <p\n className={cn(\n \"text-sm\",\n error ? \"text-[var(--ews-error)]\" : \"text-[var(--ews-gray-500)]\"\n )}\n >\n {error || helperText}\n </p>\n )}\n </div>\n );\n }\n);\n\nInput.displayName = \"Input\";\n\nexport { Input };\n","import React from \"react\";\n\nexport interface IconProps extends React.SVGProps<SVGSVGElement> {\n /**\n * Icon size\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n /**\n * Icon color\n */\n color?: string;\n}\n\nconst Icon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ size = \"md\", color = \"currentColor\", className, ...props }, ref) => {\n const sizes = {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-6 w-6\",\n xl: \"h-8 w-8\",\n };\n\n return (\n <svg\n ref={ref}\n className={`${sizes[size]} ${className || \"\"}`}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n />\n );\n }\n);\n\nIcon.displayName = \"Icon\";\n\nexport { Icon };\n","import React from \"react\";\nimport { Icon, IconProps } from \"./Icon\";\n\nexport const ArrowRight: React.FC<Omit<IconProps, \"children\">> = (props) => (\n <Icon {...props}>\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </Icon>\n);\n","import React from \"react\";\nimport { Icon, IconProps } from \"./Icon\";\n\nexport const Check: React.FC<Omit<IconProps, \"children\">> = (props) => (\n <Icon {...props}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Icon>\n);\n","import React from \"react\";\nimport { Icon, IconProps } from \"./Icon\";\n\nexport const Search: React.FC<Omit<IconProps, \"children\">> = (props) => (\n <Icon {...props}>\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.35-4.35\" />\n </Icon>\n);\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;AAAA,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,QAAQ,EAAE,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAQ,SAAS,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;;ACE/W;;;;AAIG;AACG,SAAU,EAAE,CAAC,GAAG,MAAoB,EAAA;AACxC,IAAA,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB;AAEA;;;;;AAKG;SACa,cAAc,CAAC,MAAc,EAAE,QAAQ,GAAG,KAAK,EAAA;AAC7D,IAAA,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;AACpC,QAAA,KAAK,EAAE,UAAU;QACjB,QAAQ;AACT,KAAA,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AACnB;AAEA;;;;;AAKG;AACG,SAAU,UAAU,CACxB,IAA4B,EAC5B,OAAoC,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;AAC9B,IAAA,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;AACtC,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,KAAK,EAAE,MAAM;AACb,QAAA,GAAG,EAAE,SAAS;AACd,QAAA,GAAG,OAAO;AACX,KAAA,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AACpB;AAEA;;;;;AAKG;AACG,SAAU,QAAQ,CACtB,IAAO,EACP,IAAY,EAAA;AAEZ,IAAA,IAAI,OAAsC;AAC1C,IAAA,OAAO,CAAC,GAAG,IAAmB,KAAI;QAChC,YAAY,CAAC,OAAO,CAAC;AACrB,QAAA,OAAO,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC;AACjD,IAAA,CAAC;AACH;AAEA;;;;AAIG;AACG,SAAU,UAAU,CAAC,MAAM,GAAG,KAAK,EAAA;IACvC,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AAC/D;;ACpCA,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAC7B,CACE,EACE,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,OAAO,GAAG,KAAK,EACf,SAAS,GAAG,KAAK,EACjB,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EACT,EACD,GAAG,KACD;IACF,MAAM,UAAU,GACd,uLAAuL;AAEzL,IAAA,MAAM,QAAQ,GAAG;AACf,QAAA,OAAO,EACL,wGAAwG;AAC1G,QAAA,SAAS,EACP,qHAAqH;AACvH,QAAA,OAAO,EACL,wGAAwG;AAC1G,QAAA,OAAO,EACL,wGAAwG;AAC1G,QAAA,KAAK,EACH,kGAAkG;AACpG,QAAA,KAAK,EACH,2GAA2G;KAC9G;AAED,IAAA,MAAM,KAAK,GAAG;AACZ,QAAA,EAAE,EAAE,qBAAqB;AACzB,QAAA,EAAE,EAAE,qBAAqB;AACzB,QAAA,EAAE,EAAE,mBAAmB;KACxB;AAED,IAAA,QACEA,eAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,EAAE,CACX,UAAU,EACV,QAAQ,CAAC,OAAO,CAAC,EACjB,KAAK,CAAC,IAAI,CAAC,EACX,SAAS,IAAI,QAAQ,EACrB,SAAS,CACV,EACD,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAAA,GACzB,KAAK,EAAA,QAAA,EAAA,CAER,OAAO,KACNA,eAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,iCAAiC,EAC3C,KAAK,EAAC,4BAA4B,EAClC,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,WAAW,EAAA,QAAA,EAAA,CAEnBC,cAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAC,YAAY,EACtB,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,CAAC,EAAC,IAAI,EACN,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EAAA,CACf,EACFA,cAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAC,YAAY,EACtB,IAAI,EAAC,cAAc,EACnB,CAAC,EAAC,iHAAiH,EAAA,CACnH,CAAA,EAAA,CACE,CACP,EACA,CAAC,OAAO,IAAI,QAAQ,IAAIA,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,MAAM,EAAA,QAAA,EAAE,QAAQ,EAAA,CAAQ,EAChE,QAAQ,EACR,CAAC,OAAO,IAAI,SAAS,IAAIA,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,MAAM,EAAA,QAAA,EAAE,SAAS,EAAA,CAAQ,CAAA,EAAA,CAC5D;AAEb,CAAC;AAGH,MAAM,CAAC,WAAW,GAAG,QAAQ;;AC3E7B,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAC5B,CACE,EACE,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,KAAK,EACL,UAAU,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,SAAS,GAAG,KAAK,EACjB,EAAE,EACF,GAAG,KAAK,EACT,EACD,GAAG,KACD;IACF,MAAM,OAAO,GAAG,EAAE,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,CAAE;AACxE,IAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;IAC/B,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO;IAElD,MAAM,UAAU,GACd,sGAAsG;AAExG,IAAA,MAAM,QAAQ,GAAG;AACf,QAAA,OAAO,EACL,gGAAgG;AAClG,QAAA,KAAK,EACH,yFAAyF;AAC3F,QAAA,OAAO,EACL,+FAA+F;KAClG;AAED,IAAA,MAAM,KAAK,GAAG;AACZ,QAAA,EAAE,EAAE,qBAAqB;AACzB,QAAA,EAAE,EAAE,qBAAqB;AACzB,QAAA,EAAE,EAAE,mBAAmB;KACxB;AAED,IAAA,MAAM,SAAS,GAAG;AAChB,QAAA,EAAE,EAAE,SAAS;AACb,QAAA,EAAE,EAAE,SAAS;AACb,QAAA,EAAE,EAAE,SAAS;KACd;AAED,IAAA,QACED,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC,EAAA,QAAA,EAAA,CAC7D,KAAK,KACJC,cAAA,CAAA,OAAA,EAAA,EACE,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,sDAAsD,EAAA,QAAA,EAE/D,KAAK,EAAA,CACA,CACT,EACDD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,UAAU,EAAA,QAAA,EAAA,CACtB,QAAQ,KACPC,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,sEAAsE,YACnFA,cAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAA,QAAA,EAE3D,QAAQ,EAAA,CACJ,GACH,CACP,EACDA,cAAA,CAAA,OAAA,EAAA,EACE,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,EAAE,CACX,UAAU,EACV,QAAQ,CAAC,aAAa,CAAC,EACvB,KAAK,CAAC,IAAI,CAAC,EACX,QAAQ,IAAI,OAAO,EACnB,SAAS,IAAI,OAAO,EACpB,SAAS,CACV,EACD,GAAG,EAAE,GAAG,EAAA,GACJ,KAAK,EAAA,CACT,EACD,SAAS,KACRA,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uEAAuE,EAAA,QAAA,EACpFA,cAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAA,QAAA,EAE3D,SAAS,EAAA,CACL,EAAA,CACH,CACP,CAAA,EAAA,CACG,EACL,CAAC,KAAK,IAAI,UAAU,MACnBA,sBACE,SAAS,EAAE,EAAE,CACX,SAAS,EACT,KAAK,GAAG,yBAAyB,GAAG,4BAA4B,CACjE,EAAA,QAAA,EAEA,KAAK,IAAI,UAAU,GAClB,CACL,CAAA,EAAA,CACG;AAEV,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;ACjI3B,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAC3B,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,GAAG,cAAc,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAI;AACpE,IAAA,MAAM,KAAK,GAAG;AACZ,QAAA,EAAE,EAAE,SAAS;AACb,QAAA,EAAE,EAAE,SAAS;AACb,QAAA,EAAE,EAAE,SAAS;AACb,QAAA,EAAE,EAAE,SAAS;KACd;AAED,IAAA,QACEA,cAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,CAAA,CAAA,EAAI,SAAS,IAAI,EAAE,CAAA,CAAE,EAC9C,IAAI,EAAC,MAAM,EACX,MAAM,EAAE,KAAK,EACb,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,KAClB,KAAK,EAAA,CACT;AAEN,CAAC;AAGH,IAAI,CAAC,WAAW,GAAG,MAAM;;AClClB,MAAM,UAAU,GAA0C,CAAC,KAAK,MACrED,eAAA,CAAC,IAAI,EAAA,EAAA,GAAK,KAAK,EAAA,QAAA,EAAA,CACbC,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,UAAU,EAAA,CAAG,EACrBA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,eAAe,EAAA,CAAG,CAAA,EAAA,CACrB;;MCJI,KAAK,GAA0C,CAAC,KAAK,MAChEA,cAAA,CAAC,IAAI,EAAA,EAAA,GAAK,KAAK,YACbA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,iBAAiB,EAAA,CAAG,EAAA,CACvB;;ACHF,MAAM,MAAM,GAA0C,CAAC,KAAK,MACjED,gBAAC,IAAI,EAAA,EAAA,GAAK,KAAK,EAAA,QAAA,EAAA,CACbC,2BAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,EAAA,CAAG,EAChCA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,kBAAkB,EAAA,CAAG,CAAA,EAAA,CACxB;;;;;;;;;;;;;;","x_google_ignoreList":[0]}
@@ -0,0 +1,35 @@
1
+ import { type ClassValue } from "clsx";
2
+ /**
3
+ * Utility function to merge class names
4
+ * @param inputs - Class values to merge
5
+ * @returns Merged class string
6
+ */
7
+ export declare function cn(...inputs: ClassValue[]): string;
8
+ /**
9
+ * Utility function to format currency
10
+ * @param amount - Amount to format
11
+ * @param currency - Currency code (default: 'USD')
12
+ * @returns Formatted currency string
13
+ */
14
+ export declare function formatCurrency(amount: number, currency?: string): string;
15
+ /**
16
+ * Utility function to format date
17
+ * @param date - Date to format
18
+ * @param options - Intl.DateTimeFormat options
19
+ * @returns Formatted date string
20
+ */
21
+ export declare function formatDate(date: Date | string | number, options?: Intl.DateTimeFormatOptions): string;
22
+ /**
23
+ * Utility function to debounce function calls
24
+ * @param func - Function to debounce
25
+ * @param wait - Wait time in milliseconds
26
+ * @returns Debounced function
27
+ */
28
+ export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
29
+ /**
30
+ * Utility function to generate unique ID
31
+ * @param prefix - Optional prefix for the ID
32
+ * @returns Unique ID string
33
+ */
34
+ export declare function generateId(prefix?: string): string;
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAQ,GAAG,MAAM,CAKvE;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"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@ews-admin/global-design-system",
3
+ "version": "1.0.0",
4
+ "description": "EWS Global Design System - Reusable components for EWS applications",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "src"
11
+ ],
12
+ "keywords": [
13
+ "design-system",
14
+ "react",
15
+ "components",
16
+ "ui",
17
+ "ews"
18
+ ],
19
+ "author": "EWS - Erco Web Solutions",
20
+ "license": "MIT",
21
+ "peerDependencies": {
22
+ "react": ">=16.8.0",
23
+ "react-dom": ">=16.8.0"
24
+ },
25
+ "devDependencies": {
26
+ "@babel/core": "^7.23.0",
27
+ "@babel/preset-env": "^7.23.0",
28
+ "@babel/preset-react": "^7.22.0",
29
+ "@babel/preset-typescript": "^7.23.0",
30
+ "@rollup/plugin-babel": "^6.0.4",
31
+ "@rollup/plugin-commonjs": "^25.0.7",
32
+ "@rollup/plugin-node-resolve": "^15.2.3",
33
+ "@rollup/plugin-typescript": "^11.1.5",
34
+ "@storybook/addon-essentials": "^7.5.0",
35
+ "@storybook/addon-interactions": "^7.5.0",
36
+ "@storybook/addon-links": "^7.5.0",
37
+ "@storybook/blocks": "^7.5.0",
38
+ "@storybook/react": "^7.5.0",
39
+ "@storybook/react-vite": "^7.5.0",
40
+ "@storybook/testing-library": "^0.2.2",
41
+ "@types/react": "^18.2.37",
42
+ "@types/react-dom": "^18.2.15",
43
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
44
+ "@typescript-eslint/parser": "^6.10.0",
45
+ "eslint": "^8.53.0",
46
+ "eslint-plugin-react": "^7.33.2",
47
+ "eslint-plugin-react-hooks": "^4.6.0",
48
+ "rollup": "^4.6.1",
49
+ "rollup-plugin-dts": "^6.1.0",
50
+ "rollup-plugin-peer-deps-external": "^2.2.4",
51
+ "rollup-plugin-postcss": "^4.0.2",
52
+ "storybook": "^7.5.0",
53
+ "typescript": "^5.2.2",
54
+ "vite": "^4.5.0"
55
+ },
56
+ "dependencies": {
57
+ "clsx": "^2.0.0",
58
+ "react": "^18.2.0",
59
+ "react-dom": "^18.2.0"
60
+ },
61
+ "scripts": {
62
+ "build": "rollup -c",
63
+ "dev": "rollup -c -w",
64
+ "storybook": "storybook dev -p 6006",
65
+ "build-storybook": "storybook build",
66
+ "test": "jest",
67
+ "lint": "eslint src --ext .ts,.tsx",
68
+ "type-check": "tsc --noEmit"
69
+ }
70
+ }
@@ -0,0 +1,117 @@
1
+ import React from "react";
2
+ import { cn } from "../../utils";
3
+
4
+ export interface ButtonProps
5
+ extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
+ /**
7
+ * Button variant
8
+ */
9
+ variant?: "primary" | "secondary" | "success" | "warning" | "error" | "ghost";
10
+ /**
11
+ * Button size
12
+ */
13
+ size?: "sm" | "md" | "lg";
14
+ /**
15
+ * Whether the button is in a loading state
16
+ */
17
+ loading?: boolean;
18
+ /**
19
+ * Whether the button should take full width
20
+ */
21
+ fullWidth?: boolean;
22
+ /**
23
+ * Icon to display before the button text
24
+ */
25
+ leftIcon?: React.ReactNode;
26
+ /**
27
+ * Icon to display after the button text
28
+ */
29
+ rightIcon?: React.ReactNode;
30
+ }
31
+
32
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
33
+ (
34
+ {
35
+ className,
36
+ variant = "primary",
37
+ size = "md",
38
+ loading = false,
39
+ fullWidth = false,
40
+ leftIcon,
41
+ rightIcon,
42
+ children,
43
+ disabled,
44
+ ...props
45
+ },
46
+ ref
47
+ ) => {
48
+ const baseStyles =
49
+ "inline-flex items-center justify-center font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none";
50
+
51
+ const variants = {
52
+ primary:
53
+ "bg-[var(--ews-primary)] text-white hover:bg-[var(--ews-primary-hover)] focus:ring-[var(--ews-primary)]",
54
+ secondary:
55
+ "bg-[var(--ews-gray-200)] text-[var(--ews-gray-900)] hover:bg-[var(--ews-gray-300)] focus:ring-[var(--ews-gray-500)]",
56
+ success:
57
+ "bg-[var(--ews-success)] text-white hover:bg-[var(--ews-success-hover)] focus:ring-[var(--ews-success)]",
58
+ warning:
59
+ "bg-[var(--ews-warning)] text-white hover:bg-[var(--ews-warning-hover)] focus:ring-[var(--ews-warning)]",
60
+ error:
61
+ "bg-[var(--ews-error)] text-white hover:bg-[var(--ews-error-hover)] focus:ring-[var(--ews-error)]",
62
+ ghost:
63
+ "bg-transparent text-[var(--ews-gray-700)] hover:bg-[var(--ews-gray-100)] focus:ring-[var(--ews-gray-500)]",
64
+ };
65
+
66
+ const sizes = {
67
+ sm: "px-3 py-1.5 text-sm",
68
+ md: "px-4 py-2 text-base",
69
+ lg: "px-6 py-3 text-lg",
70
+ };
71
+
72
+ return (
73
+ <button
74
+ className={cn(
75
+ baseStyles,
76
+ variants[variant],
77
+ sizes[size],
78
+ fullWidth && "w-full",
79
+ className
80
+ )}
81
+ ref={ref}
82
+ disabled={disabled || loading}
83
+ {...props}
84
+ >
85
+ {loading && (
86
+ <svg
87
+ className="animate-spin -ml-1 mr-2 h-4 w-4"
88
+ xmlns="http://www.w3.org/2000/svg"
89
+ fill="none"
90
+ viewBox="0 0 24 24"
91
+ >
92
+ <circle
93
+ className="opacity-25"
94
+ cx="12"
95
+ cy="12"
96
+ r="10"
97
+ stroke="currentColor"
98
+ strokeWidth="4"
99
+ />
100
+ <path
101
+ className="opacity-75"
102
+ fill="currentColor"
103
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
104
+ />
105
+ </svg>
106
+ )}
107
+ {!loading && leftIcon && <span className="mr-2">{leftIcon}</span>}
108
+ {children}
109
+ {!loading && rightIcon && <span className="ml-2">{rightIcon}</span>}
110
+ </button>
111
+ );
112
+ }
113
+ );
114
+
115
+ Button.displayName = "Button";
116
+
117
+ export { Button };
@@ -0,0 +1,2 @@
1
+ export { Button } from "./Button";
2
+ export type { ButtonProps } from "./Button";
@@ -0,0 +1,145 @@
1
+ import React from "react";
2
+ import { cn } from "../../utils";
3
+
4
+ export interface InputProps
5
+ extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
6
+ /**
7
+ * Input variant
8
+ */
9
+ variant?: "default" | "error" | "success";
10
+ /**
11
+ * Input size
12
+ */
13
+ size?: "sm" | "md" | "lg";
14
+ /**
15
+ * Label for the input
16
+ */
17
+ label?: string;
18
+ /**
19
+ * Helper text to display below the input
20
+ */
21
+ helperText?: string;
22
+ /**
23
+ * Error message to display
24
+ */
25
+ error?: string;
26
+ /**
27
+ * Icon to display before the input
28
+ */
29
+ leftIcon?: React.ReactNode;
30
+ /**
31
+ * Icon to display after the input
32
+ */
33
+ rightIcon?: React.ReactNode;
34
+ /**
35
+ * Whether the input should take full width
36
+ */
37
+ fullWidth?: boolean;
38
+ }
39
+
40
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
41
+ (
42
+ {
43
+ className,
44
+ variant = "default",
45
+ size = "md",
46
+ label,
47
+ helperText,
48
+ error,
49
+ leftIcon,
50
+ rightIcon,
51
+ fullWidth = false,
52
+ id,
53
+ ...props
54
+ },
55
+ ref
56
+ ) => {
57
+ const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
58
+ const hasError = Boolean(error);
59
+ const actualVariant = hasError ? "error" : variant;
60
+
61
+ const baseStyles =
62
+ "block w-full rounded-md border transition-colors focus:outline-none focus:ring-2 focus:ring-offset-0";
63
+
64
+ const variants = {
65
+ default:
66
+ "border-[var(--ews-gray-300)] focus:border-[var(--ews-primary)] focus:ring-[var(--ews-primary)]",
67
+ error:
68
+ "border-[var(--ews-error)] focus:border-[var(--ews-error)] focus:ring-[var(--ews-error)]",
69
+ success:
70
+ "border-[var(--ews-success)] focus:border-[var(--ews-success)] focus:ring-[var(--ews-success)]",
71
+ };
72
+
73
+ const sizes = {
74
+ sm: "px-3 py-1.5 text-sm",
75
+ md: "px-3 py-2 text-base",
76
+ lg: "px-4 py-3 text-lg",
77
+ };
78
+
79
+ const iconSizes = {
80
+ sm: "h-4 w-4",
81
+ md: "h-5 w-5",
82
+ lg: "h-6 w-6",
83
+ };
84
+
85
+ return (
86
+ <div className={cn("space-y-1", fullWidth ? "w-full" : "w-auto")}>
87
+ {label && (
88
+ <label
89
+ htmlFor={inputId}
90
+ className="block text-sm font-medium text-[var(--ews-gray-700)]"
91
+ >
92
+ {label}
93
+ </label>
94
+ )}
95
+ <div className="relative">
96
+ {leftIcon && (
97
+ <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
98
+ <span
99
+ className={cn("text-[var(--ews-gray-400)]", iconSizes[size])}
100
+ >
101
+ {leftIcon}
102
+ </span>
103
+ </div>
104
+ )}
105
+ <input
106
+ id={inputId}
107
+ className={cn(
108
+ baseStyles,
109
+ variants[actualVariant],
110
+ sizes[size],
111
+ leftIcon && "pl-10",
112
+ rightIcon && "pr-10",
113
+ className
114
+ )}
115
+ ref={ref}
116
+ {...props}
117
+ />
118
+ {rightIcon && (
119
+ <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
120
+ <span
121
+ className={cn("text-[var(--ews-gray-400)]", iconSizes[size])}
122
+ >
123
+ {rightIcon}
124
+ </span>
125
+ </div>
126
+ )}
127
+ </div>
128
+ {(error || helperText) && (
129
+ <p
130
+ className={cn(
131
+ "text-sm",
132
+ error ? "text-[var(--ews-error)]" : "text-[var(--ews-gray-500)]"
133
+ )}
134
+ >
135
+ {error || helperText}
136
+ </p>
137
+ )}
138
+ </div>
139
+ );
140
+ }
141
+ );
142
+
143
+ Input.displayName = "Input";
144
+
145
+ export { Input };
@@ -0,0 +1,2 @@
1
+ export { Input } from "./Input";
2
+ export type { InputProps } from "./Input";
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { Icon, IconProps } from "./Icon";
3
+
4
+ export const ArrowRight: React.FC<Omit<IconProps, "children">> = (props) => (
5
+ <Icon {...props}>
6
+ <path d="M5 12h14" />
7
+ <path d="m12 5 7 7-7 7" />
8
+ </Icon>
9
+ );
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import { Icon, IconProps } from "./Icon";
3
+
4
+ export const Check: React.FC<Omit<IconProps, "children">> = (props) => (
5
+ <Icon {...props}>
6
+ <path d="M20 6 9 17l-5-5" />
7
+ </Icon>
8
+ );
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+
3
+ export interface IconProps extends React.SVGProps<SVGSVGElement> {
4
+ /**
5
+ * Icon size
6
+ */
7
+ size?: "sm" | "md" | "lg" | "xl";
8
+ /**
9
+ * Icon color
10
+ */
11
+ color?: string;
12
+ }
13
+
14
+ const Icon = React.forwardRef<SVGSVGElement, IconProps>(
15
+ ({ size = "md", color = "currentColor", className, ...props }, ref) => {
16
+ const sizes = {
17
+ sm: "h-4 w-4",
18
+ md: "h-5 w-5",
19
+ lg: "h-6 w-6",
20
+ xl: "h-8 w-8",
21
+ };
22
+
23
+ return (
24
+ <svg
25
+ ref={ref}
26
+ className={`${sizes[size]} ${className || ""}`}
27
+ fill="none"
28
+ stroke={color}
29
+ strokeWidth="2"
30
+ strokeLinecap="round"
31
+ strokeLinejoin="round"
32
+ {...props}
33
+ />
34
+ );
35
+ }
36
+ );
37
+
38
+ Icon.displayName = "Icon";
39
+
40
+ export { Icon };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { Icon, IconProps } from "./Icon";
3
+
4
+ export const Search: React.FC<Omit<IconProps, "children">> = (props) => (
5
+ <Icon {...props}>
6
+ <circle cx="11" cy="11" r="8" />
7
+ <path d="m21 21-4.35-4.35" />
8
+ </Icon>
9
+ );
@@ -0,0 +1,5 @@
1
+ export { ArrowRight } from "./ArrowRight";
2
+ export { Check } from "./Check";
3
+ export { Icon } from "./Icon";
4
+ export type { IconProps } from "./Icon";
5
+ export { Search } from "./Search";
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ // Components
2
+ export { Button } from "./components/Button";
3
+ export type { ButtonProps } from "./components/Button";
4
+
5
+ export { Input } from "./components/Input";
6
+ export type { InputProps } from "./components/Input";
7
+
8
+ // Icons
9
+ export { ArrowRight, Check, Icon, Search } from "./icons";
10
+ export type { IconProps } from "./icons";
11
+
12
+ // Utils
13
+ export { cn, debounce, formatCurrency, formatDate, generateId } from "./utils";
14
+
15
+ // Styles
16
+ import "./styles/index.css";