Skip to content

Commit 0ed451b

Browse files
committed
add themechooser for Vite
1 parent 1df097a commit 0ed451b

File tree

7 files changed

+133
-48
lines changed

7 files changed

+133
-48
lines changed

examples/ecommerce-jewellery-store/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<link
1010
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
1111
rel="stylesheet">
12+
<link href="https://unpkg.com/@progress/[email protected]/dist/default-main.css" rel="stylesheet" />
1213
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
1314
<title>Ecommerce Jewellery Store</title>
1415

examples/ecommerce-jewellery-store/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
"@progress/kendo-react-progressbars": "^9.0.0",
3535
"@progress/kendo-react-treeview": "^9.0.0",
3636
"@progress/kendo-svg-icons": "^4.0.0",
37-
"@progress/kendo-theme-default": "^10.0.1",
3837
"@progress/kendo-theme-utils": "^10.0.1",
3938
"react": "^18.3.1",
4039
"react-dom": "^18.3.1",

examples/ecommerce-jewellery-store/src/App.tsx

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,42 @@ import ThankYou from "./pages/ThankYou";
66
import PaymentDetails from "./pages/PaymentDetails";
77
import { AllProductsListView } from "./pages/AllProductsListView";
88
import Home from "./pages/Home";
9-
import "@progress/kendo-theme-default/dist/all.css";
109
import "@progress/kendo-theme-utils/dist/all.scss";
1110
import { SizedParent } from "./components/SizedParent";
1211
import { DetailedCategory } from "./pages/DetailedCategory";
1312
import { ProductDetails } from "./pages/ProductsDetails";
1413
import { CartProvider } from "./helpers/CartContext";
1514
import { AdminProvider } from './helpers/AdminContext';
1615
import { CategoriesProvider } from './helpers/CategoriesContext';
17-
import { ShoppingCartList } from "./components/ShoppingCartList"; // Adjust path if necessary
16+
import { ThemeProvider } from './helpers/ThemeContext';
17+
import { ShoppingCartList } from "./components/ShoppingCartList";
1818

1919
function App() {
2020
return (
21-
<CartProvider>
22-
<AdminProvider>
23-
<CategoriesProvider>
24-
<Router basename="/kendo-react/ecommerce-jewellery-store">
25-
<Header />
26-
<SizedParent>
27-
<Routes>
28-
<Route path="/" element={<Home />} />
29-
<Route path="/paymentdetails" element={<PaymentDetails />} />
30-
<Route path="/thankyou" element={<ThankYou />} />
31-
<Route path="/contacts" element={<Contacts />} />
32-
<Route path="/products" element={<AllProductsListView />} />
33-
<Route path="/category" element={<DetailedCategory />} />
34-
<Route path="/product/:id" element={<ProductDetails />} />
35-
<Route path="/shoppingcart" element={<ShoppingCartList />} />
36-
</Routes>
37-
</SizedParent>
38-
<Footer />
39-
</Router>
40-
</CategoriesProvider>
41-
</AdminProvider>
42-
</CartProvider>
21+
<ThemeProvider>
22+
<CartProvider>
23+
<AdminProvider>
24+
<CategoriesProvider>
25+
<Router basename="/kendo-react/ecommerce-jewellery-store">
26+
<Header />
27+
<SizedParent>
28+
<Routes>
29+
<Route path="/" element={<Home />} />
30+
<Route path="/paymentdetails" element={<PaymentDetails />} />
31+
<Route path="/thankyou" element={<ThankYou />} />
32+
<Route path="/contacts" element={<Contacts />} />
33+
<Route path="/products" element={<AllProductsListView />} />
34+
<Route path="/category" element={<DetailedCategory />} />
35+
<Route path="/product/:id" element={<ProductDetails />} />
36+
<Route path="/shoppingcart" element={<ShoppingCartList />} />
37+
</Routes>
38+
</SizedParent>
39+
<Footer />
40+
</Router>
41+
</CategoriesProvider>
42+
</AdminProvider>
43+
</CartProvider>
44+
</ThemeProvider>
4345
);
4446
}
4547

examples/ecommerce-jewellery-store/src/components/Footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import viloraLogo from '@/assets/vilora-logo.png';
1212

1313
const Footer: React.FC = () => {
1414
return (
15-
<section className="k-py-10 k-px-12 header">
15+
<section className="k-py-10 k-px-12 footer">
1616
<div className="k-d-flex k-flex-wrap k-justify-content-between k-gap-8 k-text-align-left">
1717
<div className="k-flex-basis-250 k-flex-grow-1 k-mb-4 k-mt-6" style={{marginLeft: '50px'}}>
1818
<a href="#" className="k-d-block k-mb-4 k-text-align-center">
Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,44 @@
11
import React from "react";
22
import { useNavigate } from "react-router-dom";
33
import { Menu, MenuItemModel, MenuSelectEvent } from "@progress/kendo-react-layout";
4-
import { Button } from "@progress/kendo-react-buttons";
4+
import { Button, DropDownButton } from "@progress/kendo-react-buttons";
55
import { SvgIcon } from "@progress/kendo-react-common";
66
import { InputPrefix, InputSeparator, TextBox, Switch } from "@progress/kendo-react-inputs";
7-
import { searchIcon, userIcon, cartIcon } from "@progress/kendo-svg-icons";
7+
import { searchIcon, userIcon, cartIcon, paletteIcon } from "@progress/kendo-svg-icons";
88
import viloraLogo from "@/assets/vilora-logo.png";
99
import items from "../data/items";
10+
import themeItems from "../data/themeItems";
1011
import { AppBar, AppBarSection } from "@progress/kendo-react-layout";
1112
import { useAdminContext } from "../helpers/AdminContext";
12-
import { useCategoriesContext } from "../helpers/CategoriesContext";
13+
import { useCategoriesContext } from "../helpers/CategoriesContext";
14+
import { useThemeContext } from "../helpers/ThemeContext";
1315

1416
interface CustomMenuItemModel extends MenuItemModel {
1517
page?: string;
1618
}
1719

18-
1920
const Header: React.FC = () => {
2021
const navigate = useNavigate();
2122
const { toggleRole } = useAdminContext();
2223
const { setSelectedCategory } = useCategoriesContext();
24+
const { theme, setTheme } = useThemeContext();
25+
26+
const handleThemeChange = (event: any) => {
27+
const selectedTheme = themeItems.find((item) => item.themeName === event.item.themeName);
28+
if (selectedTheme) {
29+
setTheme(selectedTheme.link);
30+
console.log("Theme changed to:", selectedTheme.link);
31+
} else {
32+
console.error("Selected theme not found:", event.item.themeName);
33+
}
34+
};
2335

2436
const handleCartClick = () => {
2537
navigate("/shoppingcart");
2638
};
2739

2840
const handleSwitchChange = () => {
29-
toggleRole();
41+
toggleRole();
3042
};
3143

3244
const handleMenuSelect = (event: MenuSelectEvent) => {
@@ -36,25 +48,26 @@ const Header: React.FC = () => {
3648
navigate(selectedItem.page);
3749
return;
3850
}
39-
51+
4052
const selectedCategory = selectedItem.text;
4153
if (selectedCategory === "All") {
42-
setSelectedCategory(null);
54+
setSelectedCategory(null);
4355
} else {
44-
setSelectedCategory(selectedCategory ?? null);
45-
navigate("/category");
56+
setSelectedCategory(selectedCategory ?? null);
57+
navigate("/category");
4658
}
4759
};
4860

4961
return (
62+
<>
63+
<link id="theme-link" rel="stylesheet" href={theme} />
5064
<AppBar themeColor="inherit">
5165
<AppBarSection className="k-flex-basis-0 k-flex-grow k-gap-2 k-align-items-center" style={{ paddingLeft: "50px" }}>
52-
<a href="#" className="k-d-sm-flex" style={{ marginRight: "50px" }}>
66+
<a href="/" className="k-d-sm-flex" style={{ marginRight: "50px" }}>
5367
<img src={viloraLogo} alt="Logo" />
5468
</a>
5569
<Menu items={items} onSelect={handleMenuSelect} />
5670
</AppBarSection>
57-
5871
<AppBarSection className="k-flex-basis-0 k-flex-grow k-justify-content-end k-gap-1.5">
5972
<TextBox
6073
placeholder="Search"
@@ -71,21 +84,19 @@ const Header: React.FC = () => {
7184
style={{ width: 300 }}
7285
/>
7386
<Button svgIcon={userIcon} fillMode="flat" className="k-ml-2" />
74-
<Button
75-
svgIcon={cartIcon}
87+
<Button svgIcon={cartIcon} fillMode="flat" className="k-ml-2" onClick={handleCartClick} />
88+
<DropDownButton
89+
svgIcon={paletteIcon}
90+
items={themeItems}
91+
textField="themeName"
7692
fillMode="flat"
77-
className="k-ml-2"
78-
onClick={handleCartClick}
79-
/>
80-
<Switch
81-
className="switch-width"
82-
onLabel="Admin"
83-
offLabel="Client"
84-
onChange={handleSwitchChange}
93+
onItemClick={handleThemeChange}
8594
/>
95+
<Switch className="switch-width" onLabel="Admin" offLabel="Client" onChange={handleSwitchChange} />
8696
</AppBarSection>
8797
</AppBar>
98+
</>
8899
);
89100
};
90101

91-
export default Header;
102+
export default Header;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const themeItems = [
2+
{
3+
themeName: "Main",
4+
link: "https://unpkg.com/@progress/[email protected]/dist/default-main.css",
5+
},
6+
{
7+
themeName: "Main Dark",
8+
link: "https://unpkg.com/@progress/[email protected]/dist/default-main-dark.css",
9+
},
10+
{
11+
themeName: "Ocean Blue",
12+
link: "https://unpkg.com/@progress/[email protected]/dist/default-ocean-blue-a11y.css",
13+
},
14+
{
15+
themeName: "Nordic",
16+
link: "https://unpkg.com/@progress/[email protected]/dist/default-nordic.css",
17+
},
18+
{
19+
themeName: "Purple",
20+
link: "https://unpkg.com/@progress/[email protected]/dist/default-purple.css",
21+
},
22+
];
23+
24+
export default themeItems;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { createContext, useContext, useState, useEffect } from "react";
2+
3+
interface ThemeContextProps {
4+
theme: string;
5+
setTheme: (theme: string) => void;
6+
}
7+
8+
const ThemeContext = createContext<ThemeContextProps>({
9+
theme: "https://unpkg.com/@progress/[email protected]/dist/default-main.css",
10+
setTheme: () => {},
11+
});
12+
13+
export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
14+
const [theme, setThemeState] = useState<string>(() =>
15+
typeof window !== "undefined"
16+
? localStorage.getItem("theme") ||
17+
"https://unpkg.com/@progress/[email protected]/dist/default-main.css"
18+
: "https://unpkg.com/@progress/[email protected]/dist/default-main.css"
19+
);
20+
21+
const setTheme = (newTheme: string) => {
22+
setThemeState(newTheme);
23+
if (typeof window !== "undefined") {
24+
localStorage.setItem("theme", newTheme);
25+
}
26+
};
27+
28+
useEffect(() => {
29+
const themeLink = document.getElementById("theme-link") as HTMLLinkElement;
30+
if (themeLink) {
31+
themeLink.href = theme;
32+
}
33+
34+
document.body.classList.add("k-body");
35+
36+
return () => {
37+
document.body.classList.remove("k-body");
38+
};
39+
}, [theme]);
40+
41+
return (
42+
<ThemeContext.Provider value={{ theme, setTheme }}>
43+
{children}
44+
</ThemeContext.Provider>
45+
);
46+
};
47+
48+
export const useThemeContext = () => useContext(ThemeContext);

0 commit comments

Comments
 (0)