@alepha/ui 0.18.1 → 0.18.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.
Files changed (187) hide show
  1. package/dist/admin/{AdminApiKeys-C-6_Q-lH.js → AdminApiKeys-BJhIwfD6.js} +17 -38
  2. package/dist/admin/AdminApiKeys-BJhIwfD6.js.map +1 -0
  3. package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-DzD_4cDt.js} +23 -19
  4. package/dist/admin/AdminAudits-DzD_4cDt.js.map +1 -0
  5. package/dist/admin/AdminDashboard-C92tIc6x.js +67 -0
  6. package/dist/admin/AdminDashboard-C92tIc6x.js.map +1 -0
  7. package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DLpfhBkf.js} +3 -7
  8. package/dist/admin/AdminFiles-DLpfhBkf.js.map +1 -0
  9. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-KIOkeMgE.js} +2 -2
  10. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-KIOkeMgE.js.map} +1 -1
  11. package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D0Yo_PU0.js} +24 -36
  12. package/dist/admin/AdminJobExecutions-D0Yo_PU0.js.map +1 -0
  13. package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-PFajqaGK.js} +10 -18
  14. package/dist/admin/AdminJobRegistry-PFajqaGK.js.map +1 -0
  15. package/dist/admin/AdminLayout-B1DXZHDn.js +61 -0
  16. package/dist/admin/AdminLayout-B1DXZHDn.js.map +1 -0
  17. package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-BspPeqp_.js} +2 -2
  18. package/dist/admin/{AdminParameters-DHw9ATgl.js.map → AdminParameters-BspPeqp_.js.map} +1 -1
  19. package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-BnH5CZQl.js} +48 -53
  20. package/dist/admin/AdminSessions-BnH5CZQl.js.map +1 -0
  21. package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-DUbC6-BI.js} +2 -2
  22. package/dist/admin/{AdminUserLayout-BdC4Te8m.js.map → AdminUserLayout-DUbC6-BI.js.map} +1 -1
  23. package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-DuTUnjdG.js} +3 -3
  24. package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-DuTUnjdG.js.map} +1 -1
  25. package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-DvZdAGpL.js} +33 -35
  26. package/dist/admin/AdminUserSessions-DvZdAGpL.js.map +1 -0
  27. package/dist/admin/AdminUsers-CR9z0g_5.js +206 -0
  28. package/dist/admin/AdminUsers-CR9z0g_5.js.map +1 -0
  29. package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-DsUfp9RG.js} +2 -2
  30. package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-DsUfp9RG.js.map} +1 -1
  31. package/dist/admin/{IconGoogle-CSQLPYwX.js → IconGoogle-Ch1m3Uzl.js} +1 -1
  32. package/dist/admin/{IconGoogle-CSQLPYwX.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
  33. package/dist/admin/{Login-BGheURrg.js → Login-DHbYJKwg.js} +3 -3
  34. package/dist/{auth/Login-Denw_UGy.js.map → admin/Login-DHbYJKwg.js.map} +1 -1
  35. package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-B2EcIDB9.js} +2 -2
  36. package/dist/{auth/Profile-BMX_Ar_s.js.map → admin/Profile-B2EcIDB9.js.map} +1 -1
  37. package/dist/admin/{Register-Cs10l8vX.js → Register-Z3fxRbUF.js} +3 -3
  38. package/dist/{demo/Register-a70LPgs2.js.map → admin/Register-Z3fxRbUF.js.map} +1 -1
  39. package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-_Y1qTTKh.js} +2 -2
  40. package/dist/admin/{ResetPassword-BwDdfkGH.js.map → ResetPassword-_Y1qTTKh.js.map} +1 -1
  41. package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-Bg22bwcC.js} +2 -2
  42. package/dist/admin/{VerifyEmail-DfXHAiQl.js.map → VerifyEmail-Bg22bwcC.js.map} +1 -1
  43. package/dist/admin/{core-2xoLiT0o.js → core-BVO_TQxb.js} +1474 -233
  44. package/dist/admin/core-BVO_TQxb.js.map +1 -0
  45. package/dist/admin/index.d.ts +29 -4
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +448 -69
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-C161NeF6.js} +2 -2
  50. package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-C161NeF6.js.map} +1 -1
  51. package/dist/auth/{Login-Denw_UGy.js → Login-C7jIqf00.js} +2 -2
  52. package/dist/{admin/Login-BGheURrg.js.map → auth/Login-C7jIqf00.js.map} +1 -1
  53. package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-BMpXJ0oi.js} +2 -2
  54. package/dist/{demo/Profile-CWqti7FB.js.map → auth/Profile-BMpXJ0oi.js.map} +1 -1
  55. package/dist/auth/{Register-6hi_cpfF.js → Register-2gx8qll-.js} +2 -2
  56. package/dist/auth/{Register-6hi_cpfF.js.map → Register-2gx8qll-.js.map} +1 -1
  57. package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DBxt9hKk.js} +2 -2
  58. package/dist/auth/{ResetPassword-CqfTk1FI.js.map → ResetPassword-DBxt9hKk.js.map} +1 -1
  59. package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-Z80Ubajk.js} +2 -2
  60. package/dist/auth/{VerifyEmail-nWiSTMjF.js.map → VerifyEmail-Z80Ubajk.js.map} +1 -1
  61. package/dist/auth/{core-niW0sFLv.js → core-DyfeVr5c.js} +1002 -38
  62. package/dist/auth/core-DyfeVr5c.js.map +1 -0
  63. package/dist/auth/index.d.ts +12 -1
  64. package/dist/auth/index.d.ts.map +1 -1
  65. package/dist/auth/index.js +12 -13
  66. package/dist/auth/index.js.map +1 -1
  67. package/dist/core/index.d.ts +95 -14
  68. package/dist/core/index.d.ts.map +1 -1
  69. package/dist/core/index.js +1473 -232
  70. package/dist/core/index.js.map +1 -1
  71. package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-DN-ClJQk.js} +2 -2
  72. package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-DN-ClJQk.js.map} +1 -1
  73. package/dist/demo/{DemoButton-BmaWZVwf.js → DemoButton-CGUyR9eM.js} +3 -3
  74. package/dist/demo/{DemoButton-BmaWZVwf.js.map → DemoButton-CGUyR9eM.js.map} +1 -1
  75. package/dist/demo/{DemoDataTable-Z9xyV221.js → DemoDataTable-QFG-xXSx.js} +15 -19
  76. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +1 -0
  77. package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-DW8QEvD1.js} +2 -2
  78. package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-DW8QEvD1.js.map} +1 -1
  79. package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-CAhLUanT.js} +3 -3
  80. package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-CAhLUanT.js.map} +1 -1
  81. package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-yIFmNjHB.js} +3 -3
  82. package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-yIFmNjHB.js.map} +1 -1
  83. package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-BSGuBHus.js} +2 -2
  84. package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-BSGuBHus.js.map} +1 -1
  85. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-DsA2IpgV.js} +3 -3
  86. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-DsA2IpgV.js.map} +1 -1
  87. package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-Cy6xjn6P.js} +2 -2
  88. package/dist/demo/{DemoLayout-C56xb5EE.js.map → DemoLayout-Cy6xjn6P.js.map} +1 -1
  89. package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-vqxgTu4P.js} +8 -8
  90. package/dist/demo/{DemoLogin-BZwpicOS.js.map → DemoLogin-vqxgTu4P.js.map} +1 -1
  91. package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-YHPvPg77.js} +8 -8
  92. package/dist/demo/{DemoRegister-C7_qc4MJ.js.map → DemoRegister-YHPvPg77.js.map} +1 -1
  93. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-mOW18Zlm.js} +8 -8
  94. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js.map → DemoResetPassword-mOW18Zlm.js.map} +1 -1
  95. package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-od7aLjP_.js} +3 -3
  96. package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-od7aLjP_.js.map} +1 -1
  97. package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-DU3JeRS0.js} +3 -3
  98. package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-DU3JeRS0.js.map} +1 -1
  99. package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-CUJEiPRa.js} +2 -2
  100. package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-CUJEiPRa.js.map} +1 -1
  101. package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-C1dNkahD.js} +3 -3
  102. package/dist/demo/{DemoTypeForm-DDzWoMSV.js.map → DemoTypeForm-C1dNkahD.js.map} +1 -1
  103. package/dist/demo/{DemoVerifyEmail-C_Irdnov.js → DemoVerifyEmail-D9EcXZ38.js} +8 -8
  104. package/dist/demo/{DemoVerifyEmail-C_Irdnov.js.map → DemoVerifyEmail-D9EcXZ38.js.map} +1 -1
  105. package/dist/demo/{Login-hSOU3jZc.js → Login-CoYf_P_F.js} +2 -2
  106. package/dist/demo/{Login-hSOU3jZc.js.map → Login-CoYf_P_F.js.map} +1 -1
  107. package/dist/demo/{Profile-CWqti7FB.js → Profile-BE_Y3co2.js} +2 -2
  108. package/dist/{admin/Profile-B-c9pCPf.js.map → demo/Profile-BE_Y3co2.js.map} +1 -1
  109. package/dist/demo/{Register-a70LPgs2.js → Register-fXHmBpr3.js} +2 -2
  110. package/dist/{admin/Register-Cs10l8vX.js.map → demo/Register-fXHmBpr3.js.map} +1 -1
  111. package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-CAPj8MO3.js} +2 -2
  112. package/dist/demo/{ResetPassword-DWN0lzr5.js.map → ResetPassword-CAPj8MO3.js.map} +1 -1
  113. package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-BtEU0pY9.js} +2 -2
  114. package/dist/demo/{Showcase-Dq3MISpd.js.map → Showcase-BtEU0pY9.js.map} +1 -1
  115. package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-DFmdCdYs.js} +2 -2
  116. package/dist/demo/{VerifyEmail-DZWL72K4.js.map → VerifyEmail-DFmdCdYs.js.map} +1 -1
  117. package/dist/demo/{auth-d6n3xbug.js → auth-Djd7SKiw.js} +8 -8
  118. package/dist/demo/{auth-d6n3xbug.js.map → auth-Djd7SKiw.js.map} +1 -1
  119. package/dist/demo/{core-RCUw1Q-a.js → core-B7LNjM78.js} +1484 -226
  120. package/dist/demo/core-B7LNjM78.js.map +1 -0
  121. package/dist/demo/index.js +17 -17
  122. package/package.json +3 -3
  123. package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +128 -19
  124. package/src/admin/components/AdminDashboard.tsx +52 -0
  125. package/src/admin/components/AdminLayout.tsx +32 -40
  126. package/src/admin/components/audits/AdminAudits.tsx +22 -16
  127. package/src/admin/components/files/AdminFiles.tsx +1 -6
  128. package/src/admin/components/jobs/AdminJobExecutions.tsx +33 -39
  129. package/src/admin/components/jobs/AdminJobRegistry.tsx +9 -18
  130. package/src/admin/components/keys/AdminApiKeys.tsx +23 -41
  131. package/src/admin/components/sessions/AdminSessions.tsx +71 -71
  132. package/src/admin/components/users/AdminUserSessions.tsx +33 -31
  133. package/src/admin/components/users/AdminUsers.tsx +184 -72
  134. package/src/admin/index.ts +2 -2
  135. package/src/admin/primitives/$uiAdmin.ts +1 -1
  136. package/src/auth/components/buttons/UserButton.tsx +1 -3
  137. package/src/core/atoms/alephaSidebarAtom.ts +1 -1
  138. package/src/core/atoms/alephaThemeListAtom.ts +14 -1
  139. package/src/core/atoms/alephaThemeOverridesAtom.ts +17 -0
  140. package/src/core/atoms/themes/editorial.ts +184 -0
  141. package/src/core/atoms/themes/monochrome.ts +197 -0
  142. package/src/core/atoms/themes/rosePine.ts +208 -0
  143. package/src/core/atoms/themes/softBrutalism.ts +221 -0
  144. package/src/core/atoms/themes/terminal.ts +186 -0
  145. package/src/core/components/Flex.tsx +91 -1
  146. package/src/core/components/Text.tsx +1 -1
  147. package/src/core/components/buttons/ActionButton.tsx +15 -19
  148. package/src/core/components/buttons/DarkModeButton.tsx +3 -3
  149. package/src/core/components/buttons/LanguageButton.tsx +1 -1
  150. package/src/core/components/buttons/OmnibarButton.tsx +1 -2
  151. package/src/core/components/buttons/ThemeButton.tsx +40 -11
  152. package/src/core/components/buttons/ThemeExpertModal.tsx +184 -0
  153. package/src/core/components/buttons/ToggleSidebarButton.tsx +1 -2
  154. package/src/core/components/layout/AppBar.tsx +10 -0
  155. package/src/core/components/layout/DashboardShell.tsx +10 -7
  156. package/src/core/components/layout/Sidebar.tsx +60 -52
  157. package/src/core/constants/ui.ts +5 -5
  158. package/src/core/hooks/useTheme.ts +26 -3
  159. package/src/core/index.ts +6 -1
  160. package/src/core/interfaces/AlephaTheme.ts +2 -0
  161. package/src/core/providers/ThemeProvider.ts +108 -8
  162. package/src/core/services/DialogService.tsx +24 -3
  163. package/src/core/styles.css +26 -23
  164. package/src/core/table/components/DataTable.tsx +167 -137
  165. package/src/core/table/components/DataTableFilters.tsx +1 -6
  166. package/src/core/table/components/DataTablePagination.tsx +51 -28
  167. package/src/core/table/components/DataTableToolbar.tsx +9 -4
  168. package/src/core/table/index.ts +1 -0
  169. package/src/core/table/interfaces/types.ts +13 -9
  170. package/src/demo/components/core/DemoDataTable.tsx +15 -19
  171. package/dist/admin/AdminApiKeys-C-6_Q-lH.js.map +0 -1
  172. package/dist/admin/AdminAudits-Bgbf04hO.js.map +0 -1
  173. package/dist/admin/AdminFiles-B9a7G3cY.js.map +0 -1
  174. package/dist/admin/AdminJobExecutions-B9cek5dl.js.map +0 -1
  175. package/dist/admin/AdminJobRegistry-DFgV3oqx.js.map +0 -1
  176. package/dist/admin/AdminLayout-DHsvWxVB.js +0 -70
  177. package/dist/admin/AdminLayout-DHsvWxVB.js.map +0 -1
  178. package/dist/admin/AdminSessions-BhGJPI3z.js.map +0 -1
  179. package/dist/admin/AdminUserSessions-1uzcx02z.js.map +0 -1
  180. package/dist/admin/AdminUsers-C85c3eiQ.js +0 -121
  181. package/dist/admin/AdminUsers-C85c3eiQ.js.map +0 -1
  182. package/dist/admin/auth-Dr0Cf8I7.js +0 -319
  183. package/dist/admin/auth-Dr0Cf8I7.js.map +0 -1
  184. package/dist/admin/core-2xoLiT0o.js.map +0 -1
  185. package/dist/auth/core-niW0sFLv.js.map +0 -1
  186. package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
  187. package/dist/demo/core-RCUw1Q-a.js.map +0 -1
@@ -0,0 +1,221 @@
1
+ import {
2
+ ActionIcon,
3
+ Badge,
4
+ Button,
5
+ Card,
6
+ Paper,
7
+ TextInput,
8
+ } from "@mantine/core";
9
+ import type { AlephaTheme } from "../../interfaces/AlephaTheme.ts";
10
+
11
+ /**
12
+ * Soft Brutalism theme.
13
+ *
14
+ * Pastel pop palette with solid offset shadows, rounded corners, and bold borders.
15
+ * A friendlier take on neubrutalism — playful but production-ready.
16
+ */
17
+ export const softBrutalismTheme: AlephaTheme = {
18
+ name: "Soft Brutalism",
19
+ description: "Pastel pop with bold borders and offset shadows",
20
+ head: {
21
+ link: [
22
+ { rel: "preconnect", href: "https://fonts.googleapis.com" },
23
+ {
24
+ rel: "preconnect",
25
+ href: "https://fonts.gstatic.com",
26
+ crossorigin: "",
27
+ },
28
+ {
29
+ rel: "stylesheet",
30
+ href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap",
31
+ },
32
+ ],
33
+ },
34
+ primaryColor: "lavender",
35
+ primaryShade: { light: 5, dark: 7 },
36
+ autoContrast: true,
37
+ cursorType: "pointer",
38
+ fontFamily:
39
+ 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif',
40
+ fontFamilyMonospace:
41
+ 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
42
+ headings: {
43
+ fontFamily:
44
+ 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif',
45
+ fontWeight: "700",
46
+ textWrap: "wrap",
47
+ sizes: {
48
+ h1: { fontSize: "2rem", lineHeight: "1.25" },
49
+ h2: { fontSize: "1.5rem", lineHeight: "1.3" },
50
+ h3: { fontSize: "1.25rem", lineHeight: "1.4" },
51
+ h4: { fontSize: "1rem", lineHeight: "1.5" },
52
+ h5: { fontSize: "0.875rem", lineHeight: "1.5" },
53
+ h6: { fontSize: "0.75rem", lineHeight: "1.5" },
54
+ },
55
+ },
56
+ defaultRadius: "md",
57
+ radius: {
58
+ xs: "6px",
59
+ sm: "8px",
60
+ md: "12px",
61
+ lg: "16px",
62
+ xl: "24px",
63
+ },
64
+ shadows: {
65
+ xs: "2px 2px 0 0 rgba(100, 80, 140, 0.15)",
66
+ sm: "3px 3px 0 0 rgba(100, 80, 140, 0.2)",
67
+ md: "4px 4px 0 0 rgba(100, 80, 140, 0.2)",
68
+ lg: "6px 6px 0 0 rgba(100, 80, 140, 0.25)",
69
+ xl: "8px 8px 0 0 rgba(100, 80, 140, 0.3)",
70
+ },
71
+ colors: {
72
+ // Primary — lavender
73
+ lavender: [
74
+ "#f3f0fa",
75
+ "#e4dcf4",
76
+ "#d1c4e9",
77
+ "#b4a7d6",
78
+ "#9a8bc4",
79
+ "#7f6cb0",
80
+ "#6a549e",
81
+ "#543f87",
82
+ "#3d2d6b",
83
+ "#2a1d52",
84
+ ],
85
+ // Accent — peach
86
+ peach: [
87
+ "#fef3ec",
88
+ "#fce4d0",
89
+ "#f9d0ae",
90
+ "#f4b886",
91
+ "#f4a261",
92
+ "#e68a42",
93
+ "#c67234",
94
+ "#a35a28",
95
+ "#6b3a1a",
96
+ "#4a2710",
97
+ ],
98
+ // Success — mint
99
+ mint: [
100
+ "#ecfaf0",
101
+ "#d4f2dc",
102
+ "#b3e8c2",
103
+ "#8edba4",
104
+ "#81c995",
105
+ "#5ab874",
106
+ "#42a05c",
107
+ "#2e8548",
108
+ "#1a5c2e",
109
+ "#0f3f1e",
110
+ ],
111
+ // Danger — coral
112
+ coral: [
113
+ "#fef0ef",
114
+ "#fcd9d7",
115
+ "#f8b8b4",
116
+ "#f29490",
117
+ "#e97171",
118
+ "#d65454",
119
+ "#b83e3e",
120
+ "#962d2d",
121
+ "#6b1f1f",
122
+ "#4a1414",
123
+ ],
124
+ // Warm grays — cream-shifted
125
+ gray: [
126
+ "#faf8f6",
127
+ "#f0ece8",
128
+ "#ddd7d0",
129
+ "#c4bbb2",
130
+ "#a89e95",
131
+ "#8c8279",
132
+ "#6e655d",
133
+ "#524b44",
134
+ "#3a342f",
135
+ "#24211e",
136
+ ],
137
+ // Warm dark palette — lavender-tinted blacks
138
+ dark: [
139
+ "#d4d0dc",
140
+ "#a9a2b5",
141
+ "#7e7690",
142
+ "#5c546e",
143
+ "#443c56",
144
+ "#342d45",
145
+ "#2a2339",
146
+ "#1e1a2e",
147
+ "#161224",
148
+ "#0f0c1a",
149
+ ],
150
+ },
151
+
152
+ // ---------------------------------------------------------------------------
153
+ // Component overrides
154
+ // ---------------------------------------------------------------------------
155
+
156
+ components: {
157
+ Button: Button.extend({
158
+ defaultProps: {
159
+ fw: 600,
160
+ },
161
+ styles: {
162
+ root: {
163
+ border: "2px solid currentColor",
164
+ boxShadow: "3px 3px 0 0 rgba(100, 80, 140, 0.2)",
165
+ transition: "box-shadow 0.15s ease, transform 0.15s ease",
166
+ },
167
+ },
168
+ }),
169
+
170
+ ActionIcon: ActionIcon.extend({
171
+ styles: {
172
+ root: {
173
+ border: "2px solid currentColor",
174
+ boxShadow: "2px 2px 0 0 rgba(100, 80, 140, 0.15)",
175
+ },
176
+ },
177
+ }),
178
+
179
+ Paper: Paper.extend({
180
+ defaultProps: {
181
+ shadow: "sm",
182
+ },
183
+ styles: {
184
+ root: {
185
+ border: "2px solid var(--mantine-color-default-border)",
186
+ },
187
+ },
188
+ }),
189
+
190
+ Card: Card.extend({
191
+ defaultProps: {
192
+ shadow: "sm",
193
+ },
194
+ styles: {
195
+ root: {
196
+ border: "2px solid var(--mantine-color-default-border)",
197
+ },
198
+ },
199
+ }),
200
+
201
+ TextInput: TextInput.extend({
202
+ styles: {
203
+ input: {
204
+ border: "2px solid var(--mantine-color-default-border)",
205
+ transition: "box-shadow 0.15s ease, border-color 0.15s ease",
206
+ },
207
+ },
208
+ }),
209
+
210
+ Badge: Badge.extend({
211
+ defaultProps: {
212
+ fw: 600,
213
+ },
214
+ styles: {
215
+ root: {
216
+ border: "2px solid currentColor",
217
+ },
218
+ },
219
+ }),
220
+ },
221
+ };
@@ -0,0 +1,186 @@
1
+ import {
2
+ ActionIcon,
3
+ Badge,
4
+ Button,
5
+ Card,
6
+ Paper,
7
+ TextInput,
8
+ } from "@mantine/core";
9
+ import type { AlephaTheme } from "../../interfaces/AlephaTheme.ts";
10
+
11
+ /**
12
+ * Terminal theme.
13
+ *
14
+ * Monospace everything, green-on-black, zero radius.
15
+ * CRT/hacker aesthetic for developer tools and dashboards.
16
+ */
17
+ export const terminalTheme: AlephaTheme = {
18
+ name: "Terminal",
19
+ description: "Green phosphor on black — monospace hacker aesthetic",
20
+ defaultColorScheme: "dark",
21
+ primaryColor: "terminal",
22
+ primaryShade: { light: 5, dark: 4 },
23
+ autoContrast: true,
24
+ fontFamily:
25
+ 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
26
+ fontFamilyMonospace:
27
+ 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
28
+ headings: {
29
+ fontFamily:
30
+ 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
31
+ fontWeight: "700",
32
+ textWrap: "wrap",
33
+ sizes: {
34
+ h1: { fontSize: "1.75rem", lineHeight: "1.3" },
35
+ h2: { fontSize: "1.375rem", lineHeight: "1.35" },
36
+ h3: { fontSize: "1.125rem", lineHeight: "1.4" },
37
+ h4: { fontSize: "1rem", lineHeight: "1.5" },
38
+ h5: { fontSize: "0.875rem", lineHeight: "1.5" },
39
+ h6: { fontSize: "0.75rem", lineHeight: "1.5" },
40
+ },
41
+ },
42
+ defaultRadius: "0",
43
+ radius: {
44
+ xs: "0",
45
+ sm: "0",
46
+ md: "0",
47
+ lg: "2px",
48
+ xl: "4px",
49
+ },
50
+ shadows: {
51
+ xs: "none",
52
+ sm: "none",
53
+ md: "0 0 8px rgba(0, 255, 65, 0.08)",
54
+ lg: "0 0 16px rgba(0, 255, 65, 0.1)",
55
+ xl: "0 0 24px rgba(0, 255, 65, 0.12)",
56
+ },
57
+ colors: {
58
+ // Primary — phosphor green
59
+ terminal: [
60
+ "#e6fff0",
61
+ "#b3ffd1",
62
+ "#80ffb3",
63
+ "#4dff94",
64
+ "#00ff41",
65
+ "#00d636",
66
+ "#00ad2b",
67
+ "#008521",
68
+ "#005c17",
69
+ "#00330d",
70
+ ],
71
+ // Amber accent
72
+ amber: [
73
+ "#fff8e6",
74
+ "#ffecb3",
75
+ "#ffe080",
76
+ "#ffd54d",
77
+ "#ffca28",
78
+ "#d4a520",
79
+ "#aa8418",
80
+ "#806310",
81
+ "#554208",
82
+ "#2b2104",
83
+ ],
84
+ // Danger — red
85
+ red: [
86
+ "#ffe6e6",
87
+ "#ffb3b3",
88
+ "#ff8080",
89
+ "#ff4d4d",
90
+ "#ff1a1a",
91
+ "#d41515",
92
+ "#aa1010",
93
+ "#800c0c",
94
+ "#550808",
95
+ "#2b0404",
96
+ ],
97
+ // Cool grays
98
+ gray: [
99
+ "#e8eaed",
100
+ "#c8cdd3",
101
+ "#a4aab3",
102
+ "#808892",
103
+ "#5f6872",
104
+ "#474f58",
105
+ "#363c44",
106
+ "#282d33",
107
+ "#1c2026",
108
+ "#12151a",
109
+ ],
110
+ // True black darks
111
+ dark: [
112
+ "#c9cdd2",
113
+ "#8b9198",
114
+ "#5c636b",
115
+ "#3d444c",
116
+ "#2b3138",
117
+ "#1e242b",
118
+ "#151a20",
119
+ "#0e1216",
120
+ "#080c0f",
121
+ "#020303",
122
+ ],
123
+ },
124
+
125
+ components: {
126
+ Button: Button.extend({
127
+ defaultProps: {
128
+ fw: 600,
129
+ },
130
+ styles: {
131
+ root: {
132
+ border: "1px solid currentColor",
133
+ textTransform: "uppercase" as const,
134
+ letterSpacing: "0.05em",
135
+ fontSize: "0.8125rem",
136
+ },
137
+ },
138
+ }),
139
+
140
+ ActionIcon: ActionIcon.extend({
141
+ styles: {
142
+ root: {
143
+ border: "1px solid currentColor",
144
+ },
145
+ },
146
+ }),
147
+
148
+ Paper: Paper.extend({
149
+ styles: {
150
+ root: {
151
+ border: "1px solid var(--mantine-color-default-border)",
152
+ },
153
+ },
154
+ }),
155
+
156
+ Card: Card.extend({
157
+ styles: {
158
+ root: {
159
+ border: "1px solid var(--mantine-color-default-border)",
160
+ },
161
+ },
162
+ }),
163
+
164
+ TextInput: TextInput.extend({
165
+ styles: {
166
+ input: {
167
+ border: "1px solid var(--mantine-color-default-border)",
168
+ fontFamily: "inherit",
169
+ },
170
+ },
171
+ }),
172
+
173
+ Badge: Badge.extend({
174
+ defaultProps: {
175
+ fw: 600,
176
+ },
177
+ styles: {
178
+ root: {
179
+ border: "1px solid currentColor",
180
+ textTransform: "uppercase" as const,
181
+ letterSpacing: "0.05em",
182
+ },
183
+ },
184
+ }),
185
+ },
186
+ };
@@ -29,10 +29,65 @@ export interface FlexProps extends MantineFlexProps {
29
29
  * Shorthand for direction="column".
30
30
  */
31
31
  col?: boolean;
32
+
33
+ /**
34
+ * Set ground to `var(--alepha-ground)`.
35
+ */
36
+ ground?: boolean;
37
+
38
+ /**
39
+ * Set ground to `var(--alepha-surface)`.
40
+ */
41
+ surface?: boolean;
42
+
43
+ /**
44
+ * Set ground to `var(--alepha-elevated)`.
45
+ */
46
+ elevated?: boolean;
47
+
48
+ /**
49
+ * Add rounded corners to the container. If `true`, a default border radius will be applied. You can also specify a custom border radius value (e.g., "sm", "md", "lg", or any valid CSS border-radius value).
50
+ */
51
+ rounded?: boolean | number | string;
52
+
53
+ /**
54
+ * Add a border to the container. The color will be determined by the current theme.
55
+ */
56
+ bordered?: boolean;
57
+
58
+ /**
59
+ * Add a top border only.
60
+ */
61
+ borderedTop?: boolean;
62
+
63
+ /**
64
+ * Add a bottom border only.
65
+ */
66
+ borderedBottom?: boolean;
67
+
68
+ /**
69
+ * Add a shadow to the container. The intensity will be determined by the current theme.
70
+ */
71
+ shadowed?: boolean | number | string;
32
72
  }
33
73
 
34
74
  const Flex = forwardRef<HTMLDivElement, FlexProps>((props, ref) => {
35
- const { fill, center, centerX, centerY, col, ...rest } = props;
75
+ const {
76
+ fill,
77
+ center,
78
+ centerX,
79
+ centerY,
80
+ col,
81
+ ground,
82
+ surface,
83
+ elevated,
84
+ rounded,
85
+ bordered,
86
+ borderedTop,
87
+ borderedBottom,
88
+ shadowed,
89
+ ...rest
90
+ } = props;
36
91
 
37
92
  if (fill) {
38
93
  rest.flex ??= 1;
@@ -55,6 +110,41 @@ const Flex = forwardRef<HTMLDivElement, FlexProps>((props, ref) => {
55
110
  rest.align ??= "center";
56
111
  }
57
112
 
113
+ if (ground) {
114
+ rest.bg = "var(--alepha-ground)";
115
+ } else if (surface) {
116
+ rest.bg = "var(--alepha-surface)";
117
+ } else if (elevated) {
118
+ rest.bg = "var(--alepha-elevated)";
119
+ }
120
+
121
+ if (rounded) {
122
+ rest.bdrs = rounded === true ? "md" : rounded;
123
+ }
124
+
125
+ if (bordered) {
126
+ rest.bd = "1px solid var(--alepha-border)";
127
+ }
128
+
129
+ if (borderedTop) {
130
+ rest.style = {
131
+ borderTop: "1px solid var(--alepha-border)",
132
+ ...((rest.style as object) ?? {}),
133
+ };
134
+ }
135
+
136
+ if (borderedBottom) {
137
+ rest.style = {
138
+ borderBottom: "1px solid var(--alepha-border)",
139
+ ...((rest.style as object) ?? {}),
140
+ };
141
+ }
142
+
143
+ if (shadowed) {
144
+ rest.className =
145
+ `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
146
+ }
147
+
58
148
  return <MantineFlex ref={ref} {...rest} />;
59
149
  });
60
150
 
@@ -109,7 +109,7 @@ const Text = forwardRef<HTMLParagraphElement, TextProps>((props, ref) => {
109
109
  }
110
110
 
111
111
  if (small) {
112
- rest.size ??= "sm";
112
+ rest.size ??= "xs";
113
113
  }
114
114
 
115
115
  if (uppercase) {
@@ -8,7 +8,6 @@ import {
8
8
  type MenuItemProps,
9
9
  type MenuProps,
10
10
  type MenuTargetProps,
11
- ThemeIcon,
12
11
  type ThemeIconProps,
13
12
  Tooltip,
14
13
  type TooltipProps,
@@ -140,6 +139,8 @@ export interface ActionCommonProps extends ButtonProps {
140
139
  */
141
140
  icon?: ReactNode | ComponentType;
142
141
 
142
+ iconSize?: number | string;
143
+
143
144
  /**
144
145
  * Additional props to pass to the ThemeIcon wrapping the icon.
145
146
  */
@@ -221,16 +222,16 @@ const ActionMenuItem = (props: {
221
222
  return (
222
223
  <Menu.Item
223
224
  key={index}
224
- leftSection={item.icon}
225
+ leftSection={
226
+ item.icon ??
227
+ (item.active ? (
228
+ <IconCheck size={ui.sizes.icon.sm} />
229
+ ) : (
230
+ <Flex w={ui.sizes.icon.sm} />
231
+ ))
232
+ }
225
233
  onClick={item.onClick}
226
234
  color={item.color}
227
- rightSection={
228
- item.active ? (
229
- <ThemeIcon size={"xs"} variant={"transparent"}>
230
- <IconCheck />
231
- </ThemeIcon>
232
- ) : undefined
233
- }
234
235
  {...menuItemProps}
235
236
  >
236
237
  {item.label}
@@ -241,16 +242,10 @@ const ActionMenuItem = (props: {
241
242
  const ActionButton = (_props: ActionProps) => {
242
243
  const theme = useMantineTheme();
243
244
  const props = { ..._props };
244
- const { tooltip, menu, icon, ...restProps } = props;
245
-
246
- if (props.variant === "subtle" || props.variant === "outline") {
247
- restProps.color ??= "gray";
248
- }
245
+ const { tooltip, menu, icon, iconSize, ...restProps } = props;
249
246
 
250
247
  if (props.intent) {
251
- if (props.intent === "none") {
252
- restProps.color ??= "gray";
253
- } else if (props.intent === "primary") {
248
+ if (props.intent === "primary") {
254
249
  restProps.color ??= theme.primaryColor;
255
250
  } else if (props.intent === "success") {
256
251
  restProps.c ??= "white";
@@ -268,15 +263,16 @@ const ActionButton = (_props: ActionProps) => {
268
263
 
269
264
  if (props.icon) {
270
265
  const sizes = ui.sizes.icon as Record<string, number>;
266
+ const iconSize = props.iconSize ?? sizes[props.size || "sm"];
271
267
  const icon = isComponentType(props.icon) ? (
272
- <props.icon size={sizes[props.size || "md"]} />
268
+ <props.icon size={iconSize} />
273
269
  ) : (
274
270
  <span>{props.icon as ReactNode}</span>
275
271
  );
276
272
 
277
273
  if (!props.children) {
278
274
  restProps.children = Children.only(icon);
279
- restProps.px ??= "xs"; // TODO: change based on props.size ?
275
+ restProps.p ??= 8;
280
276
  } else {
281
277
  restProps.leftSection = icon;
282
278
  }
@@ -20,14 +20,14 @@ const DarkModeButton = (props: Partial<ActionProps>) => {
20
20
  setColorScheme(current === "dark" ? "light" : "dark");
21
21
  };
22
22
 
23
- const size = props.size ?? "md";
23
+ const size = props.size ?? "sm";
24
24
  const iconSize =
25
- (ui.sizes.icon as Record<string, number>)[size] ?? ui.sizes.icon.md;
25
+ (ui.sizes.icon as Record<string, number>)[size] ?? ui.sizes.icon.sm;
26
26
 
27
27
  return (
28
28
  <ActionButton
29
29
  onClick={toggleColorScheme}
30
- variant={props.variant ?? "subtle"}
30
+ variant={props.variant ?? "default"}
31
31
  size={size}
32
32
  aria-label="Toggle color scheme"
33
33
  icon={
@@ -6,7 +6,7 @@ const LanguageButton = (props: Partial<ActionProps>) => {
6
6
  const i18n = useI18n();
7
7
  return (
8
8
  <ActionButton
9
- variant={"subtle"}
9
+ variant={"default"}
10
10
  icon={IconLanguage}
11
11
  menu={{
12
12
  items: i18n.languages.map((lang) => ({
@@ -20,8 +20,7 @@ const OmnibarButton = (props: OmnibarButtonProps) => {
20
20
  <ActionButton
21
21
  variant={"subtle"}
22
22
  onClick={spotlight.open}
23
- radius={"md"}
24
- icon={<IconSearch size={16} />}
23
+ icon={IconSearch}
25
24
  tooltip={{ label: "Search", position: "right" }}
26
25
  {...props.actionProps}
27
26
  />
@@ -1,28 +1,57 @@
1
1
  import { IconPalette } from "@tabler/icons-react";
2
2
  import { useStore } from "alepha/react";
3
3
  import { alephaThemeListAtom } from "../../atoms/alephaThemeListAtom.ts";
4
+ import { useDialog } from "../../hooks/useDialog.ts";
4
5
  import { useTheme } from "../../hooks/useTheme.ts";
6
+ import type { ActionMenuItem } from "./ActionButton.tsx";
5
7
  import ActionButton, { type ActionProps } from "./ActionButton.tsx";
8
+ import ThemeExpertModal from "./ThemeExpertModal.tsx";
6
9
 
7
- const ThemeButton = (props: Partial<ActionProps>) => {
10
+ type ThemeButtonProps = Partial<ActionProps> & {
11
+ /**
12
+ * Enable expert mode with color, radius, and font customization.
13
+ */
14
+ expert?: boolean;
15
+ };
16
+
17
+ const ThemeButton = (props: ThemeButtonProps) => {
18
+ const { expert, ...actionProps } = props;
8
19
  const [theme, setTheme] = useTheme();
9
20
  const themeList = useStore(alephaThemeListAtom)[0];
21
+ const dialog = useDialog();
22
+
23
+ const items: ActionMenuItem[] = themeList.map((it, index) => ({
24
+ label: it.name,
25
+ onClick: () =>
26
+ setTheme({
27
+ index,
28
+ }),
29
+ active: theme.name === it.name,
30
+ }));
31
+
32
+ if (expert) {
33
+ items.push(
34
+ { type: "divider" },
35
+ {
36
+ label: "Customize...",
37
+ onClick: () => {
38
+ dialog.open({
39
+ title: "Customize Theme",
40
+ content: <ThemeExpertModal />,
41
+ });
42
+ },
43
+ },
44
+ );
45
+ }
10
46
 
11
47
  return (
12
48
  <ActionButton
13
- variant="subtle"
49
+ variant="default"
14
50
  icon={IconPalette}
15
51
  menu={{
16
- items: themeList.map((it, index) => ({
17
- label: it.name,
18
- onClick: () =>
19
- setTheme({
20
- index,
21
- }),
22
- active: theme.name === it.name,
23
- })),
52
+ items,
24
53
  }}
25
- {...props}
54
+ {...actionProps}
26
55
  />
27
56
  );
28
57
  };