@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.
- package/README.md +195 -0
- package/dist/components/Button/Button.d.ts +30 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/index.d.ts +3 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/Input/Input.d.ts +38 -0
- package/dist/components/Input/Input.d.ts.map +1 -0
- package/dist/components/Input/index.d.ts +3 -0
- package/dist/components/Input/index.d.ts.map +1 -0
- package/dist/icons/ArrowRight.d.ts +4 -0
- package/dist/icons/ArrowRight.d.ts.map +1 -0
- package/dist/icons/Check.d.ts +4 -0
- package/dist/icons/Check.d.ts.map +1 -0
- package/dist/icons/Icon.d.ts +14 -0
- package/dist/icons/Icon.d.ts.map +1 -0
- package/dist/icons/Search.d.ts +4 -0
- package/dist/icons/Search.d.ts.map +1 -0
- package/dist/icons/index.d.ts +6 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.css +1 -0
- package/dist/index.esm.js +124 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +136 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/index.d.ts +35 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/package.json +70 -0
- package/src/components/Button/Button.tsx +117 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Input/Input.tsx +145 -0
- package/src/components/Input/index.ts +2 -0
- package/src/icons/ArrowRight.tsx +9 -0
- package/src/icons/Check.tsx +8 -0
- package/src/icons/Icon.tsx +40 -0
- package/src/icons/Search.tsx +9 -0
- package/src/icons/index.ts +5 -0
- package/src/index.ts +16 -0
- package/src/styles/index.css +95 -0
- 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":"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","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,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,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 };
|
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";
|