igniteui-cli 15.2.2-alpha.3 → 15.3.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 (175) hide show
  1. package/lib/PromptSession.js +1 -1
  2. package/lib/commands/ai-config.d.ts +9 -2
  3. package/lib/commands/ai-config.js +49 -14
  4. package/lib/commands/build.js +7 -12
  5. package/lib/commands/new.js +4 -1
  6. package/package.json +4 -4
  7. package/templates/blazor/igb/projects/ai-config/files/skills/AGENTS.md +0 -5
  8. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/SKILL.md +3 -1
  9. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/charts.md +7 -35
  10. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/data-display.md +1 -54
  11. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/feedback.md +0 -38
  12. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/form-controls.md +0 -68
  13. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/layout-manager.md +1 -124
  14. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/layout.md +0 -62
  15. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-generate-from-image-design/references/gotchas.md +29 -6
  16. package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-theming/SKILL.md +2 -2
  17. package/templates/react/igr-ts/accordion/default/index.js +2 -1
  18. package/templates/react/igr-ts/avatar/default/index.js +2 -1
  19. package/templates/react/igr-ts/badge/default/index.js +2 -1
  20. package/templates/react/igr-ts/banner/default/index.js +2 -1
  21. package/templates/react/igr-ts/button/default/index.js +2 -1
  22. package/templates/react/igr-ts/button-group/default/index.js +2 -1
  23. package/templates/react/igr-ts/calendar/default/index.js +2 -1
  24. package/templates/react/igr-ts/card/default/index.js +2 -1
  25. package/templates/react/igr-ts/checkbox/default/index.js +2 -1
  26. package/templates/react/igr-ts/chip/default/index.js +2 -1
  27. package/templates/react/igr-ts/circular-progress/default/index.js +2 -1
  28. package/templates/react/igr-ts/constants.d.ts +2 -0
  29. package/templates/react/igr-ts/constants.js +5 -0
  30. package/templates/react/igr-ts/custom-templates/subscription-form/index.js +2 -1
  31. package/templates/react/igr-ts/date-picker/default/index.js +2 -1
  32. package/templates/react/igr-ts/divider/default/index.js +2 -1
  33. package/templates/react/igr-ts/dropdown/default/index.js +2 -1
  34. package/templates/react/igr-ts/expansion-panel/default/index.js +2 -1
  35. package/templates/react/igr-ts/form/default/index.js +2 -1
  36. package/templates/react/igr-ts/grid/basic/index.js +2 -1
  37. package/templates/react/igr-ts/icon/default/index.js +2 -1
  38. package/templates/react/igr-ts/icon-button/default/index.js +2 -1
  39. package/templates/react/igr-ts/input/default/index.js +2 -1
  40. package/templates/react/igr-ts/linear-progress/default/index.js +2 -1
  41. package/templates/react/igr-ts/list/default/index.js +2 -1
  42. package/templates/react/igr-ts/navbar/default/index.js +2 -1
  43. package/templates/react/igr-ts/projects/_base/files/package.json +2 -1
  44. package/templates/react/igr-ts/projects/_base/files/src/app/app.tsx +4 -2
  45. package/templates/react/igr-ts/projects/_base/files/src/setupTests.ts +12 -0
  46. package/templates/react/igr-ts/projects/_base/files/styles.css +6 -0
  47. package/templates/react/igr-ts/projects/_base_with_home/files/index.html +2 -1
  48. package/templates/react/igr-ts/projects/_base_with_home/files/src/app/home/home.tsx +60 -10
  49. package/templates/react/igr-ts/projects/_base_with_home/files/src/app/home/style.module.css +79 -20
  50. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-components/SKILL.md +0 -8
  51. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-components/reference/CHARTS-GRIDS.md +6 -36
  52. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-components/reference/COMPONENT-CATALOGUE.md +8 -142
  53. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-components/reference/EVENT-HANDLING.md +2 -0
  54. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-customize-theme/SKILL.md +7 -14
  55. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md +2 -0
  56. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md +0 -8
  57. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-generate-from-image-design/SKILL.md +2 -2
  58. package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-generate-from-image-design/reference/component-mapping.md +60 -74
  59. package/templates/react/igr-ts/projects/empty/index.js +2 -2
  60. package/templates/react/igr-ts/projects/side-nav/files/src/app/app-routes.tsx +5 -0
  61. package/templates/react/igr-ts/projects/side-nav/files/src/app/app.css +82 -0
  62. package/templates/react/igr-ts/projects/side-nav/files/src/app/app.tsx +104 -0
  63. package/templates/react/igr-ts/projects/side-nav/files/src/app/home/home.tsx +69 -0
  64. package/templates/react/igr-ts/projects/side-nav/files/src/app/home/style.module.css +105 -0
  65. package/templates/react/igr-ts/projects/{top-nav → side-nav}/index.d.ts +2 -2
  66. package/templates/react/igr-ts/projects/{top-nav → side-nav}/index.js +7 -7
  67. package/templates/react/igr-ts/projects/side-nav-auth/files/index.html +19 -0
  68. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/app-routes.tsx +24 -0
  69. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/app.css +84 -0
  70. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/app.tsx +124 -0
  71. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/AuthContext.tsx +73 -0
  72. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/AuthGuard.tsx +14 -0
  73. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/Login.module.css +93 -0
  74. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/Login.tsx +69 -0
  75. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/LoginBar.module.css +42 -0
  76. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/LoginBar.tsx +44 -0
  77. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/LoginDialog.module.css +14 -0
  78. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/LoginDialog.tsx +49 -0
  79. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/Register.module.css +74 -0
  80. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/components/Register.tsx +67 -0
  81. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/models/external-login.ts +10 -0
  82. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/models/login.ts +4 -0
  83. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/models/register-info.ts +6 -0
  84. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/models/user.ts +19 -0
  85. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/pages/Profile.module.css +87 -0
  86. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/pages/Profile.tsx +42 -0
  87. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/pages/RedirectFacebook.tsx +44 -0
  88. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/pages/RedirectGoogle.tsx +40 -0
  89. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/pages/RedirectMicrosoft.tsx +40 -0
  90. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/authentication.ts +37 -0
  91. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/external-auth-config.ts +44 -0
  92. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/externalAuth.ts +272 -0
  93. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/fakeBackend.ts +88 -0
  94. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/jwtUtil.ts +10 -0
  95. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/pkce.ts +29 -0
  96. package/templates/react/igr-ts/projects/side-nav-auth/files/src/app/authentication/services/userStore.ts +39 -0
  97. package/templates/react/igr-ts/projects/side-nav-auth/index.d.ts +15 -0
  98. package/templates/react/igr-ts/projects/side-nav-auth/index.js +46 -0
  99. package/templates/react/igr-ts/projects/side-nav-mini/files/src/app/app-routes.tsx +5 -0
  100. package/templates/react/igr-ts/projects/side-nav-mini/files/src/app/app.css +109 -0
  101. package/templates/react/igr-ts/projects/side-nav-mini/files/src/app/app.test.tsx +20 -0
  102. package/templates/react/igr-ts/projects/side-nav-mini/files/src/app/app.tsx +81 -0
  103. package/templates/react/igr-ts/projects/side-nav-mini/files/src/app/home/home.tsx +69 -0
  104. package/templates/react/igr-ts/projects/side-nav-mini/files/src/app/home/style.module.css +105 -0
  105. package/templates/react/igr-ts/projects/side-nav-mini/index.d.ts +15 -0
  106. package/templates/react/igr-ts/projects/side-nav-mini/index.js +46 -0
  107. package/templates/react/igr-ts/projects/side-nav-mini-auth/files/src/app/app.css +106 -0
  108. package/templates/react/igr-ts/projects/side-nav-mini-auth/files/src/app/app.tsx +101 -0
  109. package/templates/react/igr-ts/projects/side-nav-mini-auth/index.d.ts +15 -0
  110. package/templates/react/igr-ts/projects/side-nav-mini-auth/index.js +50 -0
  111. package/templates/react/igr-ts/radio-group/default/index.js +2 -1
  112. package/templates/react/igr-ts/rating/default/index.js +2 -1
  113. package/templates/react/igr-ts/ripple/default/index.js +2 -1
  114. package/templates/react/igr-ts/slider/default/index.js +2 -1
  115. package/templates/react/igr-ts/switch/default/index.js +2 -1
  116. package/templates/react/igr-ts/tabs/default/index.js +2 -1
  117. package/templates/react/igr-ts/text-area/default/index.js +2 -1
  118. package/templates/react/igr-ts/tree/default/index.js +2 -1
  119. package/templates/webcomponents/igc-ts/grid/default/index.js +1 -1
  120. package/templates/webcomponents/igc-ts/grid/grid-editing/index.js +1 -1
  121. package/templates/webcomponents/igc-ts/grid/grid-summaries/index.js +1 -1
  122. package/templates/webcomponents/igc-ts/projects/_base/files/package.json +1 -1
  123. package/templates/webcomponents/igc-ts/projects/_base/files/src/app/app.ts +6 -1
  124. package/templates/webcomponents/igc-ts/projects/_base/files/styles.css +1 -0
  125. package/templates/webcomponents/igc-ts/projects/_base_with_home/files/index.html +2 -0
  126. package/templates/webcomponents/igc-ts/projects/_base_with_home/files/package.json +2 -2
  127. package/templates/webcomponents/igc-ts/projects/_base_with_home/files/src/app/home/home.ts +103 -9
  128. package/templates/webcomponents/igc-ts/projects/_base_with_home/files/src/assets/wc.png +0 -0
  129. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-choose-components/SKILL.md +122 -160
  130. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-customize-component-theme/SKILL.md +83 -311
  131. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-customize-component-theme/references/mcp-setup.md +69 -0
  132. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-generate-from-image-design/SKILL.md +4 -1
  133. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-generate-from-image-design/references/component-mapping.md +60 -61
  134. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-generate-from-image-design/references/gotchas.md +15 -11
  135. package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-optimize-bundle-size/SKILL.md +23 -274
  136. package/templates/webcomponents/igc-ts/projects/empty/index.js +1 -1
  137. package/templates/webcomponents/igc-ts/projects/side-nav/files/index.html +21 -0
  138. package/templates/webcomponents/igc-ts/projects/side-nav/files/src/app/app-routing.ts +9 -0
  139. package/templates/webcomponents/igc-ts/projects/side-nav/files/src/app/app.ts +192 -22
  140. package/templates/webcomponents/igc-ts/projects/side-nav/files/src/app/home/home.ts +175 -0
  141. package/templates/webcomponents/igc-ts/projects/side-nav/index.js +1 -1
  142. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/index.html +25 -0
  143. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/app-routing.ts +37 -0
  144. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/app.ts +251 -0
  145. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/login-bar/login-bar.ts +124 -0
  146. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/login-dialog/login-dialog.ts +253 -0
  147. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/models/external-login.ts +10 -0
  148. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/models/login.ts +4 -0
  149. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/models/register-info.ts +6 -0
  150. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/models/user.ts +19 -0
  151. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/authentication.ts +37 -0
  152. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/external-auth-config.ts +44 -0
  153. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/externalAuth.ts +272 -0
  154. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/fakeBackend.ts +88 -0
  155. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/jwtUtil.ts +10 -0
  156. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/pkce.ts +29 -0
  157. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/authentication/services/userStore.ts +39 -0
  158. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/profile/profile.ts +142 -0
  159. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/redirect/redirect-facebook.ts +57 -0
  160. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/redirect/redirect-google.ts +53 -0
  161. package/templates/webcomponents/igc-ts/projects/side-nav-auth/files/src/app/redirect/redirect-microsoft.ts +53 -0
  162. package/templates/webcomponents/igc-ts/projects/side-nav-auth/index.d.ts +15 -0
  163. package/templates/webcomponents/igc-ts/projects/side-nav-auth/index.js +46 -0
  164. package/templates/webcomponents/igc-ts/projects/side-nav-mini/files/src/app/app-routing.ts +13 -0
  165. package/templates/webcomponents/igc-ts/projects/side-nav-mini/files/src/app/app.ts +238 -0
  166. package/templates/webcomponents/igc-ts/projects/side-nav-mini/index.d.ts +14 -0
  167. package/templates/webcomponents/igc-ts/projects/side-nav-mini/index.js +45 -0
  168. package/templates/webcomponents/igc-ts/projects/side-nav-mini-auth/files/src/app/app.ts +258 -0
  169. package/templates/webcomponents/igc-ts/projects/side-nav-mini-auth/index.d.ts +15 -0
  170. package/templates/webcomponents/igc-ts/projects/side-nav-mini-auth/index.js +50 -0
  171. package/templates/webcomponents/igc-ts/tree/default/index.js +1 -1
  172. package/templates/react/igr-ts/projects/top-nav/files/src/app/app.css +0 -62
  173. package/templates/react/igr-ts/projects/top-nav/files/src/app/app.tsx +0 -18
  174. package/templates/react/igr-ts/projects/top-nav/files/src/components/navigation-header/index.tsx +0 -19
  175. /package/templates/react/igr-ts/projects/{top-nav → side-nav}/files/src/app/app.test.tsx +0 -0
@@ -0,0 +1,104 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { Outlet, useLocation, useNavigate } from "react-router-dom";
3
+ import {
4
+ IgrIcon,
5
+ IgrNavDrawer,
6
+ IgrNavDrawerItem,
7
+ registerIcon,
8
+ } from "igniteui-react";
9
+ import { configureTheme } from "igniteui-webcomponents";
10
+ import { routes } from "./app-routes";
11
+ import "igniteui-webcomponents/themes/light/material.css";
12
+ import "./app.css";
13
+
14
+ configureTheme('material', 'light');
15
+
16
+ const materialIcons = [
17
+ ['home', 'action/svg/production/ic_home_24px.svg'],
18
+ ['menu', 'navigation/svg/production/ic_menu_24px.svg'],
19
+ ['apps', 'navigation/svg/production/ic_apps_24px.svg'],
20
+ ['code', 'action/svg/production/ic_code_24px.svg'],
21
+ ['build', 'action/svg/production/ic_build_24px.svg'],
22
+ ['palette', 'image/svg/production/ic_palette_24px.svg'],
23
+ ] as const;
24
+
25
+ materialIcons.forEach(([name, path]) =>
26
+ registerIcon(name, `https://unpkg.com/material-design-icons@3.0.1/${path}`, "material")
27
+ );
28
+
29
+ export default function App() {
30
+ const name = "$(name)";
31
+ const location = useLocation();
32
+ const navigate = useNavigate();
33
+ const [drawerOpen, setDrawerOpen] = useState(true);
34
+ const [drawerPosition, setDrawerPosition] = useState<"relative" | "start">("relative");
35
+
36
+ const visibleRoutes = useMemo(() => {
37
+ return routes.filter((route) => route.path && route.text);
38
+ }, []);
39
+
40
+ useEffect(() => {
41
+ const mediaQuery = window.matchMedia("(min-width: 1025px)");
42
+ const updateDrawerState = () => {
43
+ setDrawerOpen(mediaQuery.matches);
44
+ setDrawerPosition(mediaQuery.matches ? "relative" : "start");
45
+ };
46
+
47
+ updateDrawerState();
48
+ mediaQuery.addEventListener("change", updateDrawerState);
49
+
50
+ return () => mediaQuery.removeEventListener("change", updateDrawerState);
51
+ }, []);
52
+
53
+ const handleRouteClick = (path: string) => {
54
+ navigate(path);
55
+
56
+ if (window.matchMedia("(max-width: 1024px)").matches) {
57
+ setDrawerOpen(false);
58
+ }
59
+ };
60
+
61
+ return (
62
+ <div className="app">
63
+ <header className="app__navbar">
64
+ <button
65
+ className="app__menu-button"
66
+ type="button"
67
+ aria-label="Toggle navigation"
68
+ onClick={() => setDrawerOpen((open) => !open)}
69
+ >
70
+ <IgrIcon name="menu" collection="material" />
71
+ </button>
72
+ <h1 className="app__title">{name}</h1>
73
+ </header>
74
+ <div className="app__body">
75
+ <IgrNavDrawer
76
+ className="app__drawer"
77
+ open={drawerOpen}
78
+ position={drawerPosition}
79
+ >
80
+ {visibleRoutes.map((route) => (
81
+ <IgrNavDrawerItem
82
+ key={route.path}
83
+ active={location.pathname === route.path}
84
+ onClick={() => handleRouteClick(route.path)}
85
+ >
86
+ <IgrIcon
87
+ slot="icon"
88
+ name={route.icon || "home"}
89
+ collection="material"
90
+ style={{
91
+ color: location.pathname === route.path ? "#0075D2" : undefined,
92
+ }}
93
+ />
94
+ <span slot="content">{route.text}</span>
95
+ </IgrNavDrawerItem>
96
+ ))}
97
+ </IgrNavDrawer>
98
+ <main className="app__content">
99
+ <Outlet />
100
+ </main>
101
+ </div>
102
+ </div>
103
+ );
104
+ }
@@ -0,0 +1,69 @@
1
+ import logo from "/logo.svg";
2
+ import { IgrIcon } from "igniteui-react";
3
+ import styles from "./style.module.css";
4
+
5
+ export default function App() {
6
+ return (
7
+ <main className={styles.home}>
8
+ <div className={styles.intro}>
9
+ <h1 className={styles.header}>Welcome to Ignite UI for React!</h1>
10
+ <p className={styles.description}>
11
+ A routed application shell with a responsive side navigation drawer and curated Ignite UI resources.
12
+ </p>
13
+ </div>
14
+
15
+ <img src={logo} className={styles.logo} alt="Ignite UI for React" />
16
+
17
+ <div className={styles.resources} role="navigation" aria-label="Ignite UI resources">
18
+ <a
19
+ className={styles.resource}
20
+ target="_blank"
21
+ rel="noopener noreferrer"
22
+ href="https://www.infragistics.com/products/ignite-ui-react"
23
+ >
24
+ <IgrIcon className={styles.resourceIcon} name="apps" collection="material" />
25
+ <span>
26
+ <strong>Component Demos</strong>
27
+ <small>Browse React components and examples</small>
28
+ </span>
29
+ </a>
30
+ <a
31
+ className={styles.resource}
32
+ target="_blank"
33
+ rel="noopener noreferrer"
34
+ href="https://github.com/IgniteUI/igniteui-react"
35
+ >
36
+ <IgrIcon className={styles.resourceIcon} name="code" collection="material" />
37
+ <span>
38
+ <strong>React Repository</strong>
39
+ <small>Explore Ignite UI for React on GitHub</small>
40
+ </span>
41
+ </a>
42
+ <a
43
+ className={styles.resource}
44
+ target="_blank"
45
+ rel="noopener noreferrer"
46
+ href="https://github.com/IgniteUI/igniteui-cli"
47
+ >
48
+ <IgrIcon className={styles.resourceIcon} name="build" collection="material" />
49
+ <span>
50
+ <strong>Ignite UI CLI</strong>
51
+ <small>Review the CLI source and project tooling</small>
52
+ </span>
53
+ </a>
54
+ <a
55
+ className={styles.resource}
56
+ target="_blank"
57
+ rel="noopener noreferrer"
58
+ href="https://www.figma.com/@infragistics"
59
+ >
60
+ <IgrIcon className={styles.resourceIcon} name="palette" collection="material" />
61
+ <span>
62
+ <strong>Figma UI Kit</strong>
63
+ <small>Open Infragistics design resources</small>
64
+ </span>
65
+ </a>
66
+ </div>
67
+ </main>
68
+ );
69
+ }
@@ -0,0 +1,105 @@
1
+ :local(.home) {
2
+ width: 100%;
3
+ max-width: 920px;
4
+ margin: auto;
5
+ padding: 48px 24px;
6
+ box-sizing: border-box;
7
+ font-family: "Titillium Web", "Segoe UI", Arial, sans-serif;
8
+ }
9
+
10
+ :local(.intro) {
11
+ max-width: 720px;
12
+ margin: 0 auto 24px;
13
+ text-align: center;
14
+ }
15
+
16
+ :local(.header) {
17
+ margin: 0 0 12px;
18
+ color: #09f;
19
+ font-size: 3rem;
20
+ font-weight: 600;
21
+ line-height: 1.2;
22
+ }
23
+
24
+ :local(.description) {
25
+ margin: 0;
26
+ color: #000;
27
+ font-size: 1.125rem;
28
+ line-height: 1.5;
29
+ }
30
+
31
+ :local(.logo) {
32
+ display: block;
33
+ width: 500px;
34
+ height: 350px;
35
+ margin: 0 auto 28px;
36
+ max-width: 100%;
37
+ object-fit: contain;
38
+ }
39
+
40
+ :local(.resources) {
41
+ display: grid;
42
+ grid-template-columns: repeat(2, 300px);
43
+ justify-content: center;
44
+ margin: 0 auto;
45
+ gap: 4px 64px;
46
+ }
47
+
48
+ :local(.resource) {
49
+ display: flex;
50
+ align-items: center;
51
+ min-height: 64px;
52
+ padding: 6px 0;
53
+ color: rgba(0, 0, 0, .74);
54
+ text-align: left;
55
+ text-decoration: none;
56
+ }
57
+
58
+ :local(.resource):hover strong {
59
+ text-decoration: underline;
60
+ }
61
+
62
+ :local(.resourceIcon) {
63
+ flex: 0 0 28px;
64
+ margin-right: 16px;
65
+ color: #09f;
66
+ font-size: 28px;
67
+ }
68
+
69
+ :local(.resource) strong,
70
+ :local(.resource) small {
71
+ display: block;
72
+ }
73
+
74
+ :local(.resource) strong {
75
+ margin-bottom: 2px;
76
+ color: #731963;
77
+ font-size: 1rem;
78
+ }
79
+
80
+ :local(.resource) small {
81
+ color: #000;
82
+ font-size: 0.875rem;
83
+ line-height: 1.4;
84
+ }
85
+
86
+ @media (max-width: 768px) {
87
+ :local(.home) {
88
+ padding: 32px 16px;
89
+ }
90
+
91
+ :local(.header) {
92
+ font-size: 2.25rem;
93
+ }
94
+
95
+ :local(.logo) {
96
+ width: 100%;
97
+ height: 240px;
98
+ }
99
+
100
+ :local(.resources) {
101
+ grid-template-columns: minmax(0, 300px);
102
+ justify-content: center;
103
+ gap: 4px;
104
+ }
105
+ }
@@ -1,6 +1,6 @@
1
1
  import { ProjectTemplate } from "@igniteui/cli-core";
2
2
  import { BaseWithHomeIgrTsProject } from "../_base_with_home";
3
- export declare class TopNavIgrTsProject extends BaseWithHomeIgrTsProject implements ProjectTemplate {
3
+ export declare class SideNavIgrTsProject extends BaseWithHomeIgrTsProject implements ProjectTemplate {
4
4
  id: string;
5
5
  name: string;
6
6
  description: string;
@@ -11,5 +11,5 @@ export declare class TopNavIgrTsProject extends BaseWithHomeIgrTsProject impleme
11
11
  isHidden: boolean;
12
12
  get templatePaths(): string[];
13
13
  }
14
- declare const _default: TopNavIgrTsProject;
14
+ declare const _default: SideNavIgrTsProject;
15
15
  export default _default;
@@ -23,15 +23,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.TopNavIgrTsProject = void 0;
26
+ exports.SideNavIgrTsProject = void 0;
27
27
  const path = __importStar(require("path"));
28
28
  const _base_with_home_1 = require("../_base_with_home");
29
- class TopNavIgrTsProject extends _base_with_home_1.BaseWithHomeIgrTsProject {
29
+ class SideNavIgrTsProject extends _base_with_home_1.BaseWithHomeIgrTsProject {
30
30
  constructor() {
31
31
  super(...arguments);
32
- this.id = "top-nav";
33
- this.name = "Default top navigation";
34
- this.description = "Project structure with top navigation menu";
32
+ this.id = "side-nav";
33
+ this.name = "Side navigation default";
34
+ this.description = "Project structure with side navigation drawer";
35
35
  this.dependencies = [];
36
36
  this.framework = "react";
37
37
  this.projectType = "igr-ts";
@@ -42,5 +42,5 @@ class TopNavIgrTsProject extends _base_with_home_1.BaseWithHomeIgrTsProject {
42
42
  return [...super.templatePaths, path.join(__dirname, "files")];
43
43
  }
44
44
  }
45
- exports.TopNavIgrTsProject = TopNavIgrTsProject;
46
- exports.default = new TopNavIgrTsProject();
45
+ exports.SideNavIgrTsProject = SideNavIgrTsProject;
46
+ exports.default = new SideNavIgrTsProject();
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Ignite UI for React</title>
8
+ <link href="https://fonts.googleapis.com/css?family=Titillium+Web:300,400,600,700" rel="stylesheet">
9
+ <link rel="stylesheet" href="./styles.css">
10
+ <!-- Facebook JS SDK — required only when facebook is configured in external-auth-config.ts.
11
+ Remove this script if you are not using Facebook login. -->
12
+ <script async defer crossorigin="anonymous"
13
+ src="https://connect.facebook.net/en_US/sdk.js"></script>
14
+ </head>
15
+ <body>
16
+ <div id="root"></div>
17
+ </body>
18
+ <script type="module" src="/src/main.tsx"></script>
19
+ </html>
@@ -0,0 +1,24 @@
1
+ import Home from './home/home';
2
+ import Profile from './authentication/pages/Profile';
3
+ import RedirectGoogle from './authentication/pages/RedirectGoogle';
4
+ import RedirectMicrosoft from './authentication/pages/RedirectMicrosoft';
5
+ import RedirectFacebook from './authentication/pages/RedirectFacebook';
6
+ import { AuthGuard } from './authentication/AuthGuard';
7
+
8
+ export const routes = [
9
+ { path: '/', element: <Home />, text: 'Home', icon: 'home' },
10
+ {
11
+ path: '/auth/profile',
12
+ element: (
13
+ <AuthGuard>
14
+ <Profile />
15
+ </AuthGuard>
16
+ ),
17
+ text: 'Profile',
18
+ icon: 'account_circle',
19
+ requiresAuth: true
20
+ },
21
+ { path: '/auth/redirect-google', element: <RedirectGoogle /> },
22
+ { path: '/auth/redirect-microsoft', element: <RedirectMicrosoft /> },
23
+ { path: '/auth/redirect-facebook', element: <RedirectFacebook /> },
24
+ ];
@@ -0,0 +1,84 @@
1
+ .app {
2
+ display: flex;
3
+ flex-flow: column nowrap;
4
+ height: 100%;
5
+ overflow: hidden;
6
+ }
7
+
8
+ .app__navbar {
9
+ display: flex;
10
+ align-items: center;
11
+ flex: 0 0 auto;
12
+ height: 56px;
13
+ padding: 0 16px;
14
+ background: #239ef0;
15
+ box-shadow: 0 2px 4px rgba(0, 0, 0, .24);
16
+ box-sizing: border-box;
17
+ position: relative;
18
+ z-index: 10;
19
+ }
20
+
21
+ .app__navbar-spacer {
22
+ flex: 1 1 auto;
23
+ }
24
+
25
+ .app__title {
26
+ margin: 0 0 0 16px;
27
+ font-size: 1.25rem;
28
+ font-weight: 600;
29
+ line-height: 1;
30
+ color: #000;
31
+ }
32
+
33
+ .app__menu-button {
34
+ display: inline-flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ width: 40px;
38
+ height: 40px;
39
+ padding: 0;
40
+ color: #000;
41
+ border: 0;
42
+ background: transparent;
43
+ cursor: pointer;
44
+ }
45
+
46
+ .app__menu-button igc-icon {
47
+ font-size: 24px;
48
+ }
49
+
50
+ .app__body {
51
+ display: flex;
52
+ flex: 1 1 auto;
53
+ min-height: 0;
54
+ }
55
+
56
+ .app__drawer {
57
+ flex: 0 0 auto;
58
+ height: 100%;
59
+ --menu-full-width: 280px;
60
+ }
61
+
62
+ igc-nav-drawer-item::part(base) {
63
+ min-height: 48px;
64
+ color: #2d2d2d;
65
+ }
66
+
67
+ igc-nav-drawer-item[active]::part(base) {
68
+ background: #e0f2ff;
69
+ color: #0075d2;
70
+ }
71
+
72
+ igc-nav-drawer-item[active] igc-icon {
73
+ color: #0075d2;
74
+ }
75
+
76
+ .app__content {
77
+ flex: 1 1 auto;
78
+ display: flex;
79
+ flex-flow: row nowrap;
80
+ justify-content: center;
81
+ align-items: stretch;
82
+ min-width: 0;
83
+ overflow: auto;
84
+ }
@@ -0,0 +1,124 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { Outlet, useLocation, useNavigate } from "react-router-dom";
3
+ import {
4
+ IgrIcon,
5
+ IgrNavDrawer,
6
+ IgrNavDrawerItem,
7
+ registerIcon,
8
+ } from "igniteui-react";
9
+ import { configureTheme } from "igniteui-webcomponents";
10
+ import { AuthProvider, useAuth } from "./authentication/AuthContext";
11
+ import { LoginBar } from "./authentication/components/LoginBar";
12
+ import { routes } from "./app-routes";
13
+ import "igniteui-webcomponents/themes/light/material.css";
14
+ import "./app.css";
15
+
16
+ configureTheme('material', 'light');
17
+
18
+ const materialIcons = [
19
+ ['home', 'action/svg/production/ic_home_24px.svg'],
20
+ ['menu', 'navigation/svg/production/ic_menu_24px.svg'],
21
+ ['apps', 'navigation/svg/production/ic_apps_24px.svg'],
22
+ ['code', 'action/svg/production/ic_code_24px.svg'],
23
+ ['build', 'action/svg/production/ic_build_24px.svg'],
24
+ ['palette', 'image/svg/production/ic_palette_24px.svg'],
25
+ ['account_circle', 'action/svg/production/ic_account_circle_24px.svg'],
26
+ ['lock', 'action/svg/production/ic_lock_24px.svg'],
27
+ ['assignment_ind', 'action/svg/production/ic_assignment_ind_24px.svg'],
28
+ ] as const;
29
+
30
+ materialIcons.forEach(([name, path]) =>
31
+ registerIcon(name, `https://unpkg.com/material-design-icons@3.0.1/${path}`, "material")
32
+ );
33
+
34
+ function AppContent() {
35
+ const name = "$(name)";
36
+ const location = useLocation();
37
+ const navigate = useNavigate();
38
+ const { currentUser } = useAuth();
39
+ const [drawerOpen, setDrawerOpen] = useState(true);
40
+ const [drawerPosition, setDrawerPosition] = useState<"relative" | "start">("relative");
41
+
42
+ const visibleRoutes = useMemo(() => {
43
+ return routes.filter((route) => {
44
+ if (!route.path || !route.text) return false;
45
+ if ((route as any).requiresAuth && !currentUser) return false;
46
+ return true;
47
+ });
48
+ }, [currentUser]);
49
+
50
+ useEffect(() => {
51
+ const mediaQuery = window.matchMedia("(min-width: 1025px)");
52
+ const updateDrawerState = () => {
53
+ setDrawerOpen(mediaQuery.matches);
54
+ setDrawerPosition(mediaQuery.matches ? "relative" : "start");
55
+ };
56
+
57
+ updateDrawerState();
58
+ mediaQuery.addEventListener("change", updateDrawerState);
59
+
60
+ return () => mediaQuery.removeEventListener("change", updateDrawerState);
61
+ }, []);
62
+
63
+ const handleRouteClick = (path: string) => {
64
+ navigate(path);
65
+
66
+ if (window.matchMedia("(max-width: 1024px)").matches) {
67
+ setDrawerOpen(false);
68
+ }
69
+ };
70
+
71
+ return (
72
+ <div className="app">
73
+ <header className="app__navbar">
74
+ <button
75
+ className="app__menu-button"
76
+ type="button"
77
+ aria-label="Toggle navigation"
78
+ onClick={() => setDrawerOpen((open) => !open)}
79
+ >
80
+ <IgrIcon name="menu" collection="material" />
81
+ </button>
82
+ <h1 className="app__title">{name}</h1>
83
+ <div className="app__navbar-spacer" />
84
+ <LoginBar />
85
+ </header>
86
+ <div className="app__body">
87
+ <IgrNavDrawer
88
+ className="app__drawer"
89
+ open={drawerOpen}
90
+ position={drawerPosition}
91
+ >
92
+ {visibleRoutes.map((route) => (
93
+ <IgrNavDrawerItem
94
+ key={route.path}
95
+ active={location.pathname === route.path}
96
+ onClick={() => handleRouteClick(route.path)}
97
+ >
98
+ <IgrIcon
99
+ slot="icon"
100
+ name={route.icon || "home"}
101
+ collection="material"
102
+ style={{
103
+ color: location.pathname === route.path ? "#0075D2" : "#2d2d2d",
104
+ }}
105
+ />
106
+ <span slot="content">{route.text}</span>
107
+ </IgrNavDrawerItem>
108
+ ))}
109
+ </IgrNavDrawer>
110
+ <main className="app__content">
111
+ <Outlet />
112
+ </main>
113
+ </div>
114
+ </div>
115
+ );
116
+ }
117
+
118
+ export default function App() {
119
+ return (
120
+ <AuthProvider>
121
+ <AppContent />
122
+ </AuthProvider>
123
+ );
124
+ }
@@ -0,0 +1,73 @@
1
+ import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';
2
+ import type { User } from './models/user';
3
+ import type { Login } from './models/login';
4
+ import type { RegisterInfo } from './models/register-info';
5
+ import type { ExternalLogin } from './models/external-login';
6
+ import { Authentication } from './services/authentication';
7
+ import { UserStore } from './services/userStore';
8
+ import { ExternalAuth } from './services/externalAuth';
9
+
10
+ interface AuthContextType {
11
+ currentUser: User | null;
12
+ initials: string | null;
13
+ login: (data: Login) => Promise<string | null>;
14
+ register: (data: RegisterInfo) => Promise<string | null>;
15
+ loginWith: (data: ExternalLogin) => Promise<string | null>;
16
+ logout: () => void;
17
+ }
18
+
19
+ const AuthContext = createContext<AuthContextType | null>(null);
20
+
21
+ export function AuthProvider({ children }: { children: ReactNode }) {
22
+ const [currentUser, setCurrentUser] = useState<User | null>(() => UserStore.getUser());
23
+
24
+ const initials = currentUser ? UserStore.getInitials(currentUser) : null;
25
+
26
+ const login = useCallback(async (data: Login): Promise<string | null> => {
27
+ const result = await Authentication.login(data);
28
+ if (result.user) {
29
+ UserStore.setUser(result.user);
30
+ setCurrentUser(result.user);
31
+ return null;
32
+ }
33
+ return result.error ?? 'Login failed';
34
+ }, []);
35
+
36
+ const register = useCallback(async (data: RegisterInfo): Promise<string | null> => {
37
+ const result = await Authentication.register(data);
38
+ if (result.user) {
39
+ UserStore.setUser(result.user);
40
+ setCurrentUser(result.user);
41
+ return null;
42
+ }
43
+ return result.error ?? 'Registration failed';
44
+ }, []);
45
+
46
+ const loginWith = useCallback(async (data: ExternalLogin): Promise<string | null> => {
47
+ const result = await Authentication.loginWith(data);
48
+ if (result.user) {
49
+ UserStore.setUser(result.user);
50
+ setCurrentUser(result.user);
51
+ return null;
52
+ }
53
+ return result.error ?? 'Social login failed';
54
+ }, []);
55
+
56
+ const logout = useCallback(() => {
57
+ ExternalAuth.logout();
58
+ UserStore.clearUser();
59
+ setCurrentUser(null);
60
+ }, []);
61
+
62
+ return (
63
+ <AuthContext.Provider value={{ currentUser, initials, login, register, loginWith, logout }}>
64
+ {children}
65
+ </AuthContext.Provider>
66
+ );
67
+ }
68
+
69
+ export function useAuth() {
70
+ const ctx = useContext(AuthContext);
71
+ if (!ctx) throw new Error('useAuth must be used within AuthProvider');
72
+ return ctx;
73
+ }
@@ -0,0 +1,14 @@
1
+ import { Navigate, useLocation } from 'react-router-dom';
2
+ import { useAuth } from './AuthContext';
3
+ import type { ReactNode } from 'react';
4
+
5
+ export function AuthGuard({ children }: { children: ReactNode }) {
6
+ const { currentUser } = useAuth();
7
+ const location = useLocation();
8
+
9
+ if (!currentUser) {
10
+ return <Navigate to="/" state={{ returnUrl: location.pathname }} replace />;
11
+ }
12
+
13
+ return <>{children}</>;
14
+ }