@ews-admin/global-design-system 1.1.0 → 1.1.2
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/components/ThemeToggle/ThemeToggle.d.ts +6 -0
- package/dist/components/ThemeToggle/ThemeToggle.d.ts.map +1 -0
- package/dist/components/ThemeToggle/index.d.ts +3 -0
- package/dist/components/ThemeToggle/index.d.ts.map +1 -0
- package/dist/index.css +3 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.css +3 -3
- package/dist/index.esm.js +91 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -1
- package/dist/theme/ThemeProvider.d.ts +10 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/themeConfig.d.ts +8 -0
- package/dist/theme/themeConfig.d.ts.map +1 -0
- package/dist/types/theme.d.ts +23 -0
- package/dist/types/theme.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/components/ThemeToggle/ThemeToggle.tsx +43 -0
- package/src/components/ThemeToggle/index.ts +2 -0
- package/src/index.ts +7 -0
- package/src/theme/ThemeProvider.tsx +67 -0
- package/src/theme/themeConfig.ts +40 -0
- package/src/types/theme.ts +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ews-admin/global-design-system",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
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",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"@storybook/react": "^7.5.0",
|
|
39
39
|
"@storybook/react-vite": "^7.5.0",
|
|
40
40
|
"@storybook/testing-library": "^0.2.2",
|
|
41
|
-
"@tailwindcss/postcss": "^4.1.13",
|
|
42
41
|
"@types/react": "^18.2.37",
|
|
43
42
|
"@types/react-dom": "^18.2.15",
|
|
44
43
|
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
|
45
44
|
"@typescript-eslint/parser": "^6.10.0",
|
|
45
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
46
46
|
"autoprefixer": "^10.4.21",
|
|
47
47
|
"eslint": "^8.53.0",
|
|
48
48
|
"eslint-plugin-react": "^7.33.2",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
54
54
|
"rollup-plugin-postcss": "^4.0.2",
|
|
55
55
|
"storybook": "^7.5.0",
|
|
56
|
-
"tailwindcss": "^4.
|
|
56
|
+
"tailwindcss": "^3.4.0",
|
|
57
57
|
"typescript": "^5.2.2",
|
|
58
58
|
"vite": "^4.5.0"
|
|
59
59
|
},
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useTheme } from "../../theme/ThemeProvider";
|
|
3
|
+
import { Theme } from "../../types/theme";
|
|
4
|
+
|
|
5
|
+
export interface ThemeToggleProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const ThemeToggle: React.FC<ThemeToggleProps> = ({ className }) => {
|
|
10
|
+
const { theme, setTheme } = useTheme();
|
|
11
|
+
|
|
12
|
+
const handleThemeChange = (newTheme: Theme) => {
|
|
13
|
+
setTheme(newTheme);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className={`flex items-center space-x-2 ${className || ""}`}>
|
|
18
|
+
<span className="text-sm font-medium text-gray-700">Theme:</span>
|
|
19
|
+
<div className="flex bg-gray-100 rounded-lg p-1">
|
|
20
|
+
<button
|
|
21
|
+
onClick={() => handleThemeChange("PROMED")}
|
|
22
|
+
className={`px-3 py-1 text-xs font-medium rounded-md transition-colors ${
|
|
23
|
+
theme === "PROMED"
|
|
24
|
+
? "bg-ews-primary text-white"
|
|
25
|
+
: "text-gray-600 hover:text-gray-900"
|
|
26
|
+
}`}
|
|
27
|
+
>
|
|
28
|
+
PROMED
|
|
29
|
+
</button>
|
|
30
|
+
<button
|
|
31
|
+
onClick={() => handleThemeChange("MED")}
|
|
32
|
+
className={`px-3 py-1 text-xs font-medium rounded-md transition-colors ${
|
|
33
|
+
theme === "MED"
|
|
34
|
+
? "bg-ews-primary text-white"
|
|
35
|
+
: "text-gray-600 hover:text-gray-900"
|
|
36
|
+
}`}
|
|
37
|
+
>
|
|
38
|
+
MED
|
|
39
|
+
</button>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,9 @@ export type { ErrorField, ErrorObject, ModalProps } from "./components/Modal";
|
|
|
16
16
|
export { Logo } from "./components/Logo";
|
|
17
17
|
export type { LogoProps } from "./components/Logo";
|
|
18
18
|
|
|
19
|
+
export { ThemeToggle } from "./components/ThemeToggle";
|
|
20
|
+
export type { ThemeToggleProps } from "./components/ThemeToggle";
|
|
21
|
+
|
|
19
22
|
// Molecules
|
|
20
23
|
export { SpecialtySearchAutocomplete } from "./molecules";
|
|
21
24
|
export type { Specialty, SpecialtySearchAutocompleteProps } from "./molecules";
|
|
@@ -30,6 +33,10 @@ export { cn, debounce, formatCurrency, formatDate, generateId } from "./utils";
|
|
|
30
33
|
// Hooks
|
|
31
34
|
export { useDebounce, useDebouncedCallback } from "./hooks";
|
|
32
35
|
|
|
36
|
+
// Theme
|
|
37
|
+
export { ThemeProvider, useTheme } from "./theme/ThemeProvider";
|
|
38
|
+
export type { Theme, ThemeConfig, ThemeContextType } from "./types/theme";
|
|
39
|
+
|
|
33
40
|
// Styles
|
|
34
41
|
import "./styles/index.css";
|
|
35
42
|
import "./styles/tailwind.css";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
ReactNode,
|
|
4
|
+
useContext,
|
|
5
|
+
useEffect,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
8
|
+
import { Theme, ThemeContextType } from "../types/theme";
|
|
9
|
+
import { THEMES } from "./themeConfig";
|
|
10
|
+
|
|
11
|
+
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
|
12
|
+
|
|
13
|
+
interface ThemeProviderProps {
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
defaultTheme?: Theme;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
19
|
+
children,
|
|
20
|
+
defaultTheme = "PROMED",
|
|
21
|
+
}) => {
|
|
22
|
+
const [theme, setTheme] = useState<Theme>(defaultTheme);
|
|
23
|
+
const [themeConfig, setThemeConfig] = useState(THEMES[defaultTheme]);
|
|
24
|
+
|
|
25
|
+
// Update theme config when theme changes
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
setThemeConfig(THEMES[theme]);
|
|
28
|
+
|
|
29
|
+
// Update CSS custom properties
|
|
30
|
+
const root = document.documentElement;
|
|
31
|
+
const colors = THEMES[theme].colors;
|
|
32
|
+
|
|
33
|
+
root.style.setProperty("--ews-primary", colors.primary);
|
|
34
|
+
root.style.setProperty("--ews-primary-hover", colors.primaryHover);
|
|
35
|
+
root.style.setProperty("--ews-primary-light", colors.primaryLight);
|
|
36
|
+
root.style.setProperty("--ews-secondary", colors.secondary);
|
|
37
|
+
root.style.setProperty("--ews-secondary-hover", colors.secondaryHover);
|
|
38
|
+
root.style.setProperty("--ews-success", colors.success);
|
|
39
|
+
root.style.setProperty("--ews-success-hover", colors.successHover);
|
|
40
|
+
root.style.setProperty("--ews-warning", colors.warning);
|
|
41
|
+
root.style.setProperty("--ews-warning-hover", colors.warningHover);
|
|
42
|
+
root.style.setProperty("--ews-error", colors.error);
|
|
43
|
+
root.style.setProperty("--ews-error-hover", colors.errorHover);
|
|
44
|
+
}, [theme]);
|
|
45
|
+
|
|
46
|
+
const handleSetTheme = (newTheme: Theme) => {
|
|
47
|
+
setTheme(newTheme);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const value: ThemeContextType = {
|
|
51
|
+
theme,
|
|
52
|
+
setTheme: handleSetTheme,
|
|
53
|
+
themeConfig,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const useTheme = (): ThemeContextType => {
|
|
62
|
+
const context = useContext(ThemeContext);
|
|
63
|
+
if (context === undefined) {
|
|
64
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
65
|
+
}
|
|
66
|
+
return context;
|
|
67
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ThemeConfig } from "../types/theme";
|
|
2
|
+
|
|
3
|
+
export const PROMED_THEME: ThemeConfig = {
|
|
4
|
+
name: "PROMED",
|
|
5
|
+
colors: {
|
|
6
|
+
primary: "#21596C",
|
|
7
|
+
secondary: "#3BA1A1",
|
|
8
|
+
primaryHover: "#1a4756",
|
|
9
|
+
secondaryHover: "#308181",
|
|
10
|
+
primaryLight: "#c0d0d4",
|
|
11
|
+
success: "#059669",
|
|
12
|
+
successHover: "#047857",
|
|
13
|
+
warning: "#d97706",
|
|
14
|
+
warningHover: "#b45309",
|
|
15
|
+
error: "#dc2626",
|
|
16
|
+
errorHover: "#b91c1c",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const MED_THEME: ThemeConfig = {
|
|
21
|
+
name: "MED",
|
|
22
|
+
colors: {
|
|
23
|
+
primary: "#3BA1A1", // Teal for patients (calming, trustworthy)
|
|
24
|
+
secondary: "#6B73FF", // Soft purple-blue (suggested secondary for MED)
|
|
25
|
+
primaryHover: "#308181",
|
|
26
|
+
secondaryHover: "#5a61e6",
|
|
27
|
+
primaryLight: "#a8d5d5",
|
|
28
|
+
success: "#059669",
|
|
29
|
+
successHover: "#047857",
|
|
30
|
+
warning: "#d97706",
|
|
31
|
+
warningHover: "#b45309",
|
|
32
|
+
error: "#dc2626",
|
|
33
|
+
errorHover: "#b91c1c",
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const THEMES = {
|
|
38
|
+
PROMED: PROMED_THEME,
|
|
39
|
+
MED: MED_THEME,
|
|
40
|
+
} as const;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type Theme = "PROMED" | "MED";
|
|
2
|
+
|
|
3
|
+
export interface ThemeConfig {
|
|
4
|
+
name: Theme;
|
|
5
|
+
colors: {
|
|
6
|
+
primary: string;
|
|
7
|
+
secondary: string;
|
|
8
|
+
primaryHover: string;
|
|
9
|
+
secondaryHover: string;
|
|
10
|
+
primaryLight: string;
|
|
11
|
+
success: string;
|
|
12
|
+
successHover: string;
|
|
13
|
+
warning: string;
|
|
14
|
+
warningHover: string;
|
|
15
|
+
error: string;
|
|
16
|
+
errorHover: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ThemeContextType {
|
|
21
|
+
theme: Theme;
|
|
22
|
+
setTheme: (theme: Theme) => void;
|
|
23
|
+
themeConfig: ThemeConfig;
|
|
24
|
+
}
|