@code-coaching/vuetiful 0.26.0 → 0.27.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 (262) hide show
  1. package/README.md +47 -55
  2. package/dist/css/animations.css +2 -0
  3. package/{src → dist}/css/overrides/quasar.css +73 -58
  4. package/{src/styles → dist/css}/transitions/slide.css +6 -0
  5. package/dist/favicon.ico +0 -0
  6. package/dist/types/components/atoms/VAvatar.vue.d.ts +39 -90
  7. package/dist/types/components/atoms/VBadge.vue.d.ts +34 -21
  8. package/dist/types/components/atoms/VButton.vue.d.ts +42 -48
  9. package/dist/types/components/atoms/VChip.vue.d.ts +33 -21
  10. package/dist/types/components/atoms/VLightSwitch.vue.d.ts +5 -5
  11. package/dist/types/components/atoms/VRadio/VRadioDescription.vue.d.ts +7 -12
  12. package/dist/types/components/atoms/VRadio/VRadioGroup.vue.d.ts +53 -83
  13. package/dist/types/components/atoms/VRadio/VRadioItem.vue.d.ts +46 -12
  14. package/dist/types/components/atoms/VRadio/VRadioLabel.vue.d.ts +7 -12
  15. package/dist/types/components/atoms/VSwitch/VSwitch.vue.d.ts +51 -72
  16. package/dist/types/components/atoms/VSwitch/VSwitchDescription.vue.d.ts +32 -11
  17. package/dist/types/components/atoms/VSwitch/VSwitchGroup.vue.d.ts +32 -11
  18. package/dist/types/components/atoms/VSwitch/VSwitchLabel.vue.d.ts +33 -20
  19. package/dist/types/components/molecules/VAccordion/VAccordion.vue.d.ts +39 -28
  20. package/dist/types/components/molecules/VAccordion/VAccordionItem.vue.d.ts +35 -19
  21. package/dist/types/components/molecules/VAlert.vue.d.ts +50 -73
  22. package/dist/types/components/molecules/VCard/VCard.vue.d.ts +37 -48
  23. package/dist/types/components/molecules/VCard/VCardBody.vue.d.ts +33 -12
  24. package/dist/types/components/molecules/VCard/VCardFooter.vue.d.ts +36 -20
  25. package/dist/types/components/molecules/VCard/VCardHeader.vue.d.ts +36 -20
  26. package/dist/types/components/molecules/VCodeBlock.vue.d.ts +15 -16
  27. package/dist/types/components/molecules/VDrawer.vue.d.ts +13 -7
  28. package/dist/types/components/molecules/VListbox/VListbox.vue.d.ts +54 -132
  29. package/dist/types/components/molecules/VListbox/VListboxButton.vue.d.ts +22 -21
  30. package/dist/types/components/molecules/VListbox/VListboxItem.vue.d.ts +22 -19
  31. package/dist/types/components/molecules/VListbox/VListboxItems.vue.d.ts +19 -30
  32. package/dist/types/components/molecules/VListbox/VListboxLabel.vue.d.ts +7 -12
  33. package/dist/types/components/molecules/VPreview.vue.d.ts +57 -74
  34. package/dist/types/components/molecules/VRail/VRail.vue.d.ts +28 -13
  35. package/dist/types/components/molecules/VRail/VRailTile.vue.d.ts +49 -16
  36. package/dist/types/components/molecules/VShell.vue.d.ts +76 -44
  37. package/dist/types/components/molecules/VShellConfigurator.vue.d.ts +99 -0
  38. package/dist/types/components/molecules/VTabs/VTab.vue.d.ts +52 -20
  39. package/dist/types/components/molecules/VTabs/VTabPanel.vue.d.ts +8 -1
  40. package/dist/types/components/molecules/VTabs/VTabs.vue.d.ts +43 -101
  41. package/dist/types/components/molecules/Vuetiful.vue.d.ts +22 -0
  42. package/dist/types/components/molecules/index.d.ts +3 -4
  43. package/dist/types/directives/click-outside-group.d.ts +1 -1
  44. package/dist/types/directives/click-outside.d.ts +1 -1
  45. package/dist/types/directives/clipboard.d.ts +1 -1
  46. package/dist/types/index.d.ts +1 -8
  47. package/dist/types/props/props.d.ts +1 -14
  48. package/dist/types/services/dark-mode.service.d.ts +1 -1
  49. package/dist/types/services/drawer.service.d.ts +3 -3
  50. package/dist/types/services/index.d.ts +2 -2
  51. package/dist/types/utils/id-generator.d.ts +1 -0
  52. package/dist/types/utils/index.d.ts +3 -4
  53. package/dist/types/utils/tailwind-merge.d.ts +1 -0
  54. package/dist/types/utils/theme/rocket.theme.d.ts +223 -0
  55. package/dist/types/utils/theme/theme-switcher.vue.d.ts +14 -5
  56. package/dist/types/utils/theme/theme.service.d.ts +6 -9
  57. package/dist/types/utils/theme/themes.d.ts +3 -39
  58. package/dist/types/utils/theme/vuetiful.theme.d.ts +224 -0
  59. package/dist/vuetiful.es.mjs +54831 -49535
  60. package/dist/vuetiful.umd.cjs +189 -0
  61. package/package.json +53 -37
  62. package/dist/style.css +0 -10
  63. package/dist/types/components/VBootstrap.vue.d.ts +0 -15
  64. package/dist/types/components/atoms/VAvatar.test.d.ts +0 -1
  65. package/dist/types/components/atoms/VBadge.test.d.ts +0 -1
  66. package/dist/types/components/atoms/VButton.test.d.ts +0 -1
  67. package/dist/types/components/atoms/VChip.test.d.ts +0 -1
  68. package/dist/types/components/atoms/VLightSwitch.test.d.ts +0 -1
  69. package/dist/types/components/atoms/VRadio/VRadioDescription.test.d.ts +0 -1
  70. package/dist/types/components/atoms/VRadio/VRadioGroup.test.d.ts +0 -1
  71. package/dist/types/components/atoms/VRadio/VRadioItem.test.d.ts +0 -1
  72. package/dist/types/components/atoms/VRadio/VRadioLabel.test.d.ts +0 -1
  73. package/dist/types/components/atoms/VSwitch/VSwitch.test.d.ts +0 -1
  74. package/dist/types/components/atoms/VSwitch/VSwitchDescription.test.d.ts +0 -1
  75. package/dist/types/components/atoms/VSwitch/VSwitchGroup.test.d.ts +0 -1
  76. package/dist/types/components/atoms/VSwitch/VSwitchLabel.test.d.ts +0 -1
  77. package/dist/types/components/molecules/VAccordion/VAccordion.test.d.ts +0 -1
  78. package/dist/types/components/molecules/VAccordion/VAccordionItem.test.d.ts +0 -1
  79. package/dist/types/components/molecules/VAlert.test.d.ts +0 -1
  80. package/dist/types/components/molecules/VCard/VCard.test.d.ts +0 -1
  81. package/dist/types/components/molecules/VCard/VCardBody.test.d.ts +0 -1
  82. package/dist/types/components/molecules/VCard/VCardFooter.test.d.ts +0 -1
  83. package/dist/types/components/molecules/VCard/VCardHeader.test.d.ts +0 -1
  84. package/dist/types/components/molecules/VCodeBlock.test.d.ts +0 -1
  85. package/dist/types/components/molecules/VDrawer.test.d.ts +0 -1
  86. package/dist/types/components/molecules/VListbox/VListbox.test.d.ts +0 -1
  87. package/dist/types/components/molecules/VListbox/VListboxButton.test.d.ts +0 -1
  88. package/dist/types/components/molecules/VListbox/VListboxItem.test.d.ts +0 -1
  89. package/dist/types/components/molecules/VListbox/VListboxItems.test.d.ts +0 -1
  90. package/dist/types/components/molecules/VListbox/VListboxLabel.test.d.ts +0 -1
  91. package/dist/types/components/molecules/VPreview.test.d.ts +0 -1
  92. package/dist/types/components/molecules/VRail/VRail.test.d.ts +0 -1
  93. package/dist/types/components/molecules/VRail/VRailTile.test.d.ts +0 -1
  94. package/dist/types/components/molecules/VShell.test.d.ts +0 -1
  95. package/dist/types/components/molecules/VTabs/VTab.test.d.ts +0 -1
  96. package/dist/types/components/molecules/VTabs/VTabPanel.test.d.ts +0 -1
  97. package/dist/types/components/molecules/VTabs/VTabs.test.d.ts +0 -1
  98. package/dist/types/directives/click-outside-group.test.d.ts +0 -1
  99. package/dist/types/directives/click-outside.test.d.ts +0 -1
  100. package/dist/types/directives/clipboard.test.d.ts +0 -1
  101. package/dist/types/services/dark-mode.service.test.d.ts +0 -1
  102. package/dist/types/services/drawer.service.test.d.ts +0 -1
  103. package/dist/types/services/highlight.service.test.d.ts +0 -1
  104. package/dist/types/services/rail.service.test.d.ts +0 -1
  105. package/dist/types/services/settings.service.test.d.ts +0 -1
  106. package/dist/types/types/index.d.ts +0 -54
  107. package/dist/types/types/tailwind.d.ts +0 -4
  108. package/dist/types/utils/colors/colors.service.d.ts +0 -69
  109. package/dist/types/utils/platform/platform.service.test.d.ts +0 -1
  110. package/dist/types/utils/theme/callback.test.d.ts +0 -1
  111. package/dist/types/utils/theme/remove.test.d.ts +0 -1
  112. package/dist/types/utils/theme/theme.service.test.d.ts +0 -1
  113. package/dist/vuetiful.umd.js +0 -99
  114. package/src/assets/fonts/myfont.woff +0 -0
  115. package/src/assets/main.css +0 -17
  116. package/src/components/VBootstrap.vue +0 -62
  117. package/src/components/atoms/VAvatar.test.ts +0 -175
  118. package/src/components/atoms/VAvatar.vue +0 -89
  119. package/src/components/atoms/VBadge.test.ts +0 -28
  120. package/src/components/atoms/VBadge.vue +0 -17
  121. package/src/components/atoms/VButton.test.ts +0 -180
  122. package/src/components/atoms/VButton.vue +0 -76
  123. package/src/components/atoms/VChip.test.ts +0 -33
  124. package/src/components/atoms/VChip.vue +0 -17
  125. package/src/components/atoms/VLightSwitch.test.ts +0 -69
  126. package/src/components/atoms/VLightSwitch.vue +0 -121
  127. package/src/components/atoms/VRadio/VRadioDescription.test.ts +0 -55
  128. package/src/components/atoms/VRadio/VRadioDescription.vue +0 -14
  129. package/src/components/atoms/VRadio/VRadioGroup.test.ts +0 -81
  130. package/src/components/atoms/VRadio/VRadioGroup.vue +0 -88
  131. package/src/components/atoms/VRadio/VRadioItem.test.ts +0 -183
  132. package/src/components/atoms/VRadio/VRadioItem.vue +0 -36
  133. package/src/components/atoms/VRadio/VRadioLabel.test.ts +0 -55
  134. package/src/components/atoms/VRadio/VRadioLabel.vue +0 -16
  135. package/src/components/atoms/VSwitch/VSwitch.test.ts +0 -100
  136. package/src/components/atoms/VSwitch/VSwitch.vue +0 -106
  137. package/src/components/atoms/VSwitch/VSwitchDescription.test.ts +0 -55
  138. package/src/components/atoms/VSwitch/VSwitchDescription.vue +0 -16
  139. package/src/components/atoms/VSwitch/VSwitchGroup.test.ts +0 -26
  140. package/src/components/atoms/VSwitch/VSwitchGroup.vue +0 -16
  141. package/src/components/atoms/VSwitch/VSwitchLabel.test.ts +0 -89
  142. package/src/components/atoms/VSwitch/VSwitchLabel.vue +0 -20
  143. package/src/components/atoms/index.ts +0 -31
  144. package/src/components/index.ts +0 -2
  145. package/src/components/molecules/VAccordion/VAccordion.test.ts +0 -27
  146. package/src/components/molecules/VAccordion/VAccordion.vue +0 -32
  147. package/src/components/molecules/VAccordion/VAccordionItem.test.ts +0 -134
  148. package/src/components/molecules/VAccordion/VAccordionItem.vue +0 -68
  149. package/src/components/molecules/VAlert.test.ts +0 -100
  150. package/src/components/molecules/VAlert.vue +0 -137
  151. package/src/components/molecules/VCard/VCard.test.ts +0 -47
  152. package/src/components/molecules/VCard/VCard.vue +0 -74
  153. package/src/components/molecules/VCard/VCardBody.test.ts +0 -39
  154. package/src/components/molecules/VCard/VCardBody.vue +0 -16
  155. package/src/components/molecules/VCard/VCardFooter.test.ts +0 -63
  156. package/src/components/molecules/VCard/VCardFooter.vue +0 -31
  157. package/src/components/molecules/VCard/VCardHeader.test.ts +0 -86
  158. package/src/components/molecules/VCard/VCardHeader.vue +0 -53
  159. package/src/components/molecules/VCodeBlock.test.ts +0 -133
  160. package/src/components/molecules/VCodeBlock.vue +0 -113
  161. package/src/components/molecules/VDrawer.test.ts +0 -14
  162. package/src/components/molecules/VDrawer.vue +0 -87
  163. package/src/components/molecules/VListbox/VListbox.test.ts +0 -146
  164. package/src/components/molecules/VListbox/VListbox.vue +0 -149
  165. package/src/components/molecules/VListbox/VListboxButton.test.ts +0 -66
  166. package/src/components/molecules/VListbox/VListboxButton.vue +0 -57
  167. package/src/components/molecules/VListbox/VListboxItem.test.ts +0 -51
  168. package/src/components/molecules/VListbox/VListboxItem.vue +0 -39
  169. package/src/components/molecules/VListbox/VListboxItems.test.ts +0 -44
  170. package/src/components/molecules/VListbox/VListboxItems.vue +0 -42
  171. package/src/components/molecules/VListbox/VListboxLabel.test.ts +0 -30
  172. package/src/components/molecules/VListbox/VListboxLabel.vue +0 -14
  173. package/src/components/molecules/VPreview.test.ts +0 -73
  174. package/src/components/molecules/VPreview.vue +0 -230
  175. package/src/components/molecules/VRail/VRail.test.ts +0 -14
  176. package/src/components/molecules/VRail/VRail.vue +0 -33
  177. package/src/components/molecules/VRail/VRailTile.test.ts +0 -97
  178. package/src/components/molecules/VRail/VRailTile.vue +0 -49
  179. package/src/components/molecules/VShell.test.ts +0 -14
  180. package/src/components/molecules/VShell.vue +0 -63
  181. package/src/components/molecules/VTabs/VTab.test.ts +0 -143
  182. package/src/components/molecules/VTabs/VTab.vue +0 -50
  183. package/src/components/molecules/VTabs/VTabPanel.test.ts +0 -24
  184. package/src/components/molecules/VTabs/VTabPanel.vue +0 -9
  185. package/src/components/molecules/VTabs/VTabs.test.ts +0 -92
  186. package/src/components/molecules/VTabs/VTabs.vue +0 -104
  187. package/src/components/molecules/index.ts +0 -51
  188. package/src/directives/click-outside-group.test.ts +0 -44
  189. package/src/directives/click-outside-group.ts +0 -39
  190. package/src/directives/click-outside.test.ts +0 -38
  191. package/src/directives/click-outside.ts +0 -28
  192. package/src/directives/clipboard.test.ts +0 -26
  193. package/src/directives/clipboard.ts +0 -9
  194. package/src/directives/index.ts +0 -5
  195. package/src/env.d.ts +0 -8
  196. package/src/index.ts +0 -21
  197. package/src/props/index.ts +0 -1
  198. package/src/props/props.ts +0 -62
  199. package/src/services/dark-mode.service.test.ts +0 -104
  200. package/src/services/dark-mode.service.ts +0 -75
  201. package/src/services/drawer.service.test.ts +0 -45
  202. package/src/services/drawer.service.ts +0 -46
  203. package/src/services/highlight.service.test.ts +0 -24
  204. package/src/services/highlight.service.ts +0 -19
  205. package/src/services/index.ts +0 -8
  206. package/src/services/rail.service.test.ts +0 -13
  207. package/src/services/rail.service.ts +0 -11
  208. package/src/services/settings.service.test.ts +0 -17
  209. package/src/services/settings.service.ts +0 -136
  210. package/src/styles/all.css +0 -24
  211. package/src/styles/core.css +0 -66
  212. package/src/styles/elements/alerts.css +0 -17
  213. package/src/styles/elements/badges.css +0 -31
  214. package/src/styles/elements/breadcrumbs.css +0 -26
  215. package/src/styles/elements/buttons.css +0 -103
  216. package/src/styles/elements/cards.css +0 -32
  217. package/src/styles/elements/chips.css +0 -22
  218. package/src/styles/elements/forms.css +0 -269
  219. package/src/styles/elements/lists.css +0 -48
  220. package/src/styles/elements/logo-clouds.css +0 -29
  221. package/src/styles/elements/modals.css +0 -15
  222. package/src/styles/elements/placeholders.css +0 -17
  223. package/src/styles/elements/popups.css +0 -16
  224. package/src/styles/elements/tables.css +0 -102
  225. package/src/styles/elements.css +0 -19
  226. package/src/styles/highlight-js.css +0 -116
  227. package/src/styles/tailwind.css +0 -16
  228. package/src/styles/transitions.css +0 -2
  229. package/src/styles/typography.css +0 -101
  230. package/src/styles/variants.css +0 -156
  231. package/src/tailwind/core.cjs +0 -37
  232. package/src/tailwind/generated/intellisense-classes.cjs +0 -558
  233. package/src/tailwind/intellisense.cjs +0 -21
  234. package/src/tailwind/settings.cjs +0 -20
  235. package/src/tailwind/theme/colors.cjs +0 -20
  236. package/src/tailwind/tokens/backgrounds.cjs +0 -48
  237. package/src/tailwind/tokens/border-radius.cjs +0 -21
  238. package/src/tailwind/tokens/borders.cjs +0 -24
  239. package/src/tailwind/tokens/fills.cjs +0 -20
  240. package/src/tailwind/tokens/rings.cjs +0 -50
  241. package/src/tailwind/tokens/text.cjs +0 -35
  242. package/src/tailwind/vuetiful.cjs +0 -19
  243. package/src/themes/theme-rocket.css +0 -119
  244. package/src/themes/theme-sahara.css +0 -128
  245. package/src/themes/theme-seafoam.css +0 -120
  246. package/src/themes/theme-seasonal.css +0 -115
  247. package/src/themes/theme-skeleton.css +0 -115
  248. package/src/themes/theme-vintage.css +0 -125
  249. package/src/themes/theme-vuetiful.css +0 -136
  250. package/src/types/index.ts +0 -59
  251. package/src/types/tailwind.ts +0 -7
  252. package/src/utils/colors/colors.service.ts +0 -293
  253. package/src/utils/index.ts +0 -8
  254. package/src/utils/platform/platform.service.test.ts +0 -19
  255. package/src/utils/platform/platform.service.ts +0 -8
  256. package/src/utils/theme/callback.test.ts +0 -28
  257. package/src/utils/theme/remove.test.ts +0 -27
  258. package/src/utils/theme/theme-switcher.vue +0 -78
  259. package/src/utils/theme/theme.service.test.ts +0 -269
  260. package/src/utils/theme/theme.service.ts +0 -173
  261. package/src/utils/theme/themes.ts +0 -282
  262. /package/{src/styles → dist/css}/transitions/fade.css +0 -0
@@ -1,269 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
2
-
3
- const localStorageMock = {
4
- getItem: vi.fn(),
5
- setItem: vi.fn(),
6
- };
7
-
8
- describe('useTheme', () => {
9
- afterEach(() => {
10
- vi.resetModules();
11
- });
12
- describe('initializetheme', () => {
13
- describe('given not in browser', () => {
14
- test('should set the theme to the default theme if no theme is stored', async () => {
15
- const platform = await import('../platform/platform.service');
16
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
17
- isBrowser: false,
18
- });
19
-
20
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
21
-
22
- const { useTheme } = await import('./theme.service');
23
- const { initializeTheme } = useTheme();
24
-
25
- initializeTheme();
26
-
27
- expect(localStorageSpy).not.toHaveBeenCalled();
28
- });
29
- });
30
-
31
- describe('given in browser', () => {
32
- beforeEach(() => {
33
- window.localStorage = localStorageMock as any;
34
- });
35
-
36
- describe('given no theme is stored', () => {
37
- test('should set the theme to the default theme', async () => {
38
- const platform = await import('../platform/platform.service');
39
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
40
- isBrowser: true,
41
- });
42
-
43
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
44
-
45
- const { useTheme } = await import('./theme.service');
46
- const { initializeTheme, themes, chosenTheme } = useTheme();
47
-
48
- initializeTheme();
49
-
50
- expect(localStorageSpy).not.toHaveBeenCalled();
51
- expect(chosenTheme.value.name).toBe(themes[0].name);
52
- });
53
- });
54
-
55
- describe('given a theme is stored', () => {
56
- test('should set the theme to the stored theme', async () => {
57
- const platform = await import('../platform/platform.service');
58
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
59
- isBrowser: true,
60
- });
61
-
62
- const { useTheme } = await import('./theme.service');
63
- const { initializeTheme, themes, chosenTheme } = useTheme();
64
-
65
- const customTheme = JSON.parse(JSON.stringify(themes[1]));
66
- customTheme.name = 'rocket';
67
-
68
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
69
-
70
- document.cookie = 'vuetiful-theme=rocket';
71
- initializeTheme();
72
-
73
- expect(localStorageSpy).not.toHaveBeenCalled();
74
- expect(chosenTheme.value).toEqual(customTheme);
75
- });
76
- });
77
-
78
- describe('given the theme cookie is not a known theme', () => {
79
- test('should set the theme to the default theme', async () => {
80
- const platform = await import('../platform/platform.service');
81
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
82
- isBrowser: true,
83
- });
84
-
85
- const { useTheme } = await import('./theme.service');
86
- const { initializeTheme, themes, chosenTheme } = useTheme();
87
-
88
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
89
-
90
- document.cookie = 'vuetiful-theme=not-a-theme';
91
- initializeTheme();
92
-
93
- expect(localStorageSpy).not.toHaveBeenCalled();
94
- expect(chosenTheme.value).toEqual(themes[0]);
95
- });
96
- });
97
-
98
- describe('given the theme is set to custom', () => {
99
- test('should set the custom theme from local storage', async () => {
100
- const platform = await import('../platform/platform.service');
101
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
102
- isBrowser: true,
103
- });
104
-
105
- const { useTheme } = await import('./theme.service');
106
- const { initializeTheme, themes, chosenTheme } = useTheme();
107
-
108
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
109
- const customTheme = JSON.parse(JSON.stringify(themes[0]));
110
- customTheme.name = 'custom';
111
- localStorageSpy.mockReturnValueOnce(JSON.stringify(customTheme));
112
-
113
- document.cookie = 'vuetiful-theme=custom';
114
- initializeTheme();
115
-
116
- expect(localStorageSpy).toHaveBeenCalledWith('vuetiful-custom-theme');
117
- expect(chosenTheme.value).toEqual(customTheme);
118
- });
119
-
120
- test('should set the default theme if an invalid theme is stored', async () => {
121
- const platform = await import('../platform/platform.service');
122
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
123
- isBrowser: true,
124
- });
125
-
126
- const { useTheme } = await import('./theme.service');
127
- const { initializeTheme, themes, chosenTheme } = useTheme();
128
-
129
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
130
- localStorageSpy.mockReturnValueOnce('not-a-theme');
131
-
132
- document.cookie = 'vuetiful-theme=custom';
133
- initializeTheme();
134
-
135
- expect(localStorageSpy).toHaveBeenCalledWith('vuetiful-custom-theme');
136
- expect(chosenTheme.value).toEqual(themes[0]);
137
- })
138
-
139
- test('should set the default theme if no theme is stored', async () => {
140
- const platform = await import('../platform/platform.service');
141
- vi.spyOn(platform, 'usePlatform').mockReturnValueOnce({
142
- isBrowser: true,
143
- });
144
-
145
- const { useTheme } = await import('./theme.service');
146
- const { initializeTheme, themes, chosenTheme } = useTheme();
147
-
148
- const localStorageSpy = vi.spyOn(window.localStorage, 'getItem');
149
- localStorageSpy.mockReturnValueOnce(null);
150
-
151
- document.cookie = 'vuetiful-theme=custom';
152
- initializeTheme();
153
-
154
- expect(localStorageSpy).toHaveBeenCalledWith('vuetiful-custom-theme');
155
- expect(chosenTheme.value).toEqual(themes[0]);
156
- })
157
- });
158
-
159
- });
160
- });
161
-
162
- describe('registerTheme', () => {
163
- test('should register a theme', async () => {
164
- const { useTheme } = await import('./theme.service');
165
- const { registerTheme, themes } = useTheme();
166
-
167
- const newTheme = JSON.parse(JSON.stringify(themes[0]));
168
- newTheme.name = 'new-theme';
169
-
170
- registerTheme(newTheme);
171
- expect(themes).toContain(newTheme);
172
- });
173
-
174
- describe('given the theme is already registered', () => {
175
- test('should update the theme', async () => {
176
- const { useTheme } = await import('./theme.service');
177
- const { registerTheme, themes } = useTheme();
178
-
179
- const newTheme = JSON.parse(JSON.stringify(themes[0]));
180
- newTheme.customCss = 'new-custom-css';
181
-
182
- registerTheme(newTheme);
183
-
184
- expect(themes.find((theme) => theme.name === newTheme.name)).toEqual(newTheme);
185
- });
186
- });
187
- });
188
-
189
- describe('getThemeFromCookie', () => {
190
- describe('given there is no cookie', () => {
191
- test('should return default theme', async () => {
192
- const { useTheme } = await import('./theme.service');
193
- const { getThemeFromCookie, themes } = useTheme();
194
-
195
- const cookie = '';
196
- const theme = getThemeFromCookie(cookie);
197
-
198
- expect(theme).toEqual(themes[0]);
199
- });
200
- });
201
-
202
- describe('given there is a cookie', () => {
203
- test('should return the theme', async () => {
204
- const { useTheme } = await import('./theme.service');
205
- const { getThemeFromCookie, themes } = useTheme();
206
-
207
- const cookie = 'vuetiful-theme=rocket';
208
-
209
- const theme = getThemeFromCookie(cookie);
210
-
211
- const rocketTheme = themes.find((theme) => theme.name === 'rocket');
212
- expect(theme).toEqual(rocketTheme);
213
- });
214
- });
215
- });
216
-
217
- describe('applyThemeSSR', () => {
218
- test('should apply the theme', async () => {
219
- const { useTheme } = await import('./theme.service');
220
- const { applyThemeSSR, themes } = useTheme();
221
-
222
- const theme = themes[0];
223
-
224
- const preHtml = '<html><head></head><body></body></html>';
225
- const html = applyThemeSSR(preHtml, theme);
226
-
227
- const style = html.includes('id="vuetiful-theme"');
228
- expect(style).toBe(true);
229
- const body = html.includes('data-theme="vuetiful"');
230
- expect(body).toBe(true);
231
- });
232
-
233
- test('no customBase, no customHeadings, no gradients, no custom css', async () => {
234
- const { useTheme } = await import('./theme.service');
235
- const { applyThemeSSR, themes } = useTheme();
236
-
237
- const theme = JSON.parse(JSON.stringify(themes[0]));
238
- theme.fonts.customBase = '';
239
- theme.fonts.customHeadings = '';
240
- theme.gradients.light = '';
241
- theme.gradients.dark = '';
242
- theme.customCss = '';
243
-
244
- const preHtml = '<html><head></head><body></body></html>';
245
- const html = applyThemeSSR(preHtml, theme);
246
-
247
- const style = html.includes('id="vuetiful-theme"');
248
- expect(style).toBe(true);
249
- const body = html.includes('data-theme="vuetiful"');
250
- expect(body).toBe(true);
251
- });
252
-
253
- test('invalid hex colors', async () => {
254
- const { useTheme } = await import('./theme.service');
255
- const { applyThemeSSR, themes } = useTheme();
256
-
257
- const theme = JSON.parse(JSON.stringify(themes[0]));
258
- theme.colors.primary = 'invalid';
259
-
260
- const preHtml = '<html><head></head><body></body></html>';
261
- const html = applyThemeSSR(preHtml, theme);
262
-
263
- const style = html.includes('id="vuetiful-theme"');
264
- expect(style).toBe(true);
265
- const body = html.includes('data-theme="vuetiful"');
266
- expect(body).toBe(true);
267
- });
268
- });
269
- });
@@ -1,173 +0,0 @@
1
- import { Ref, ref } from 'vue';
2
- import { usePlatform } from '../platform/platform.service';
3
- import { ColorSettings, Palette, useColors } from '../colors/colors.service';
4
- import { Theme, themes, THEME } from './themes';
5
-
6
- const { isBrowser } = usePlatform();
7
- const chosenTheme: Ref<Theme> = ref(themes[0]);
8
- const { generatePalette, hexValuesAreValid } = useColors();
9
-
10
- const generateColorCSS = (theme: Theme): string => {
11
- let newCSS = '';
12
- const newPalette: Record<string, Palette> = {};
13
- Object.values(theme.colors).forEach((color: ColorSettings) => {
14
- const colorKey = color.key;
15
- newPalette[color.key] = generatePalette(color.hex);
16
- newCSS += '\n\t';
17
- newCSS += `/* ${colorKey} | ${newPalette[colorKey][500].hex} */\n\t`;
18
- for (let [k, v] of Object.entries(newPalette[colorKey])) {
19
- newCSS += `--color-${colorKey}-${k}: ${v.rgb}; /* ⬅ ${v.hex} */\n\t`;
20
- }
21
- });
22
- return newCSS;
23
- };
24
-
25
- const useTheme = () => {
26
- const changeDataTheme = (name: string) => document.body.setAttribute('data-theme', name);
27
-
28
- const getThemeFromCookie = (cookies: string): Theme => {
29
- const themeName = getThemeNameFromCookie(cookies);
30
- const theme = themes.find((t) => t.name === themeName);
31
- if (theme) return theme;
32
- return themes[0];
33
- };
34
-
35
- const getThemeNameFromCookie = (cookies: string): string => {
36
- const cookie = cookies.split(';').find((c) => c.trim().startsWith(`vuetiful-theme=`));
37
- const value = cookie?.split('=')[1];
38
- return value || '';
39
- };
40
-
41
- const applyThemeSSR = (html: string, theme: Theme): string => {
42
- chosenTheme.value = theme;
43
- const css = generateCss(theme);
44
- html = html.replace('</head>', `<style type="text/css" id="vuetiful-theme">${css}</style></head>`);
45
- html = html.replace('<body', `<body data-theme="${theme.name}"`);
46
- return html;
47
- };
48
-
49
- const generateCss = (theme: Theme): string => {
50
- if (hexValuesAreValid(Object.values(theme.colors))) {
51
- return `${theme.fonts.baseImports}
52
- ${theme.fonts.headingImports}
53
- :root {
54
- /* =~= Theme Properties =~= */
55
- --theme-font-family-base: ${theme.fonts.customBase ? `"${theme.fonts.customBase}", ` : ''}${theme.fonts.base};
56
- --theme-font-family-heading: ${theme.fonts.customHeadings ? `"${theme.fonts.customHeadings}", ` : ''}${
57
- theme.fonts.headings
58
- };
59
- --theme-font-color-base: ${theme.textColorLight};
60
- --theme-font-color-dark: ${theme.textColorDark};
61
- --theme-rounded-base: ${theme.roundedBase};
62
- --theme-rounded-container: ${theme.roundedContainer};
63
- --theme-border-base: ${theme.borderBase};
64
-
65
- /* =~= Theme On-X Colors =~= */
66
- --on-primary: ${theme.colors.primary.on};
67
- --on-secondary: ${theme.colors.secondary.on};
68
- --on-tertiary: ${theme.colors.tertiary.on};
69
- --on-success: ${theme.colors.success.on};
70
- --on-warning: ${theme.colors.warning.on};
71
- --on-error: ${theme.colors.error.on};
72
- --on-surface: ${theme.colors.surface.on};
73
-
74
- /* =~= Theme Colors =~= */
75
- ${generateColorCSS(theme)}
76
- }
77
-
78
- ${
79
- theme.gradients.light.length
80
- ? `[data-theme="${theme.name}"] {
81
- background-image:
82
- ${theme.gradients.light};
83
- }`
84
- : ''
85
- }
86
- ${
87
- theme.gradients.dark.length
88
- ? `.dark [data-theme="${theme.name}"] {
89
- background-image:
90
- ${theme.gradients.dark};
91
- }`
92
- : ''
93
- }
94
- ${theme.customCss}
95
- `;
96
- }
97
- return '';
98
- };
99
-
100
- const applyTheme = (theme: Theme, callback?: Function) => {
101
- const existingStyle = document.getElementById('vuetiful-theme');
102
- const themeCss = generateCss(theme);
103
-
104
- const style = document.createElement('style');
105
- style.innerHTML = themeCss;
106
- style.id = 'vuetiful-theme';
107
- style.onload = () => {
108
- if (existingStyle) existingStyle.remove();
109
- if (callback) callback();
110
- };
111
-
112
- const head = document.querySelector('head');
113
- if (head) head.appendChild(style);
114
-
115
- chosenTheme.value = theme;
116
- if (isBrowser) {
117
- document.cookie = `vuetiful-theme=${theme.name};path=/;max-age=31536000;SameSite=Lax`;
118
- changeDataTheme(theme.name);
119
- }
120
- };
121
-
122
- const initializeTheme = (callback?: Function): void => {
123
- if (isBrowser) {
124
- const themeName = getThemeNameFromCookie(document.cookie);
125
-
126
- if (themeName === 'custom') {
127
- const storedThemeJson = localStorage.getItem('vuetiful-custom-theme');
128
- let storedTheme: Theme | null = null;
129
-
130
- try {
131
- storedTheme = storedThemeJson ? JSON.parse(storedThemeJson) : null;
132
- if (storedTheme) {
133
- applyTheme(storedTheme, callback);
134
- registerTheme(storedTheme);
135
- }
136
- } catch (e) {
137
- applyTheme(themes[0], callback);
138
- }
139
- } else {
140
- const theme = themes.find((t) => t.name === themeName);
141
- if (theme) {
142
- applyTheme(theme, callback);
143
- } else {
144
- applyTheme(themes[0], callback);
145
- }
146
- }
147
- }
148
- };
149
-
150
- const registerTheme = (theme: Theme): void => {
151
- const existingTheme = themes.find((t) => t.name === theme.name);
152
- if (existingTheme) {
153
- const index = themes.indexOf(existingTheme);
154
- themes[index] = theme;
155
- } else {
156
- themes.push(theme);
157
- }
158
- };
159
-
160
- return {
161
- chosenTheme,
162
- themes,
163
- THEME,
164
- applyThemeSSR,
165
- applyTheme,
166
- getThemeFromCookie,
167
- initializeTheme,
168
- changeDataTheme,
169
- registerTheme,
170
- };
171
- };
172
-
173
- export { useTheme };