@maple-design/cli-vue 0.0.0-stage → 1.1.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 (228) hide show
  1. package/README.md +305 -2
  2. package/README.zh-CN.md +305 -0
  3. package/bin/cli.mjs +5 -0
  4. package/client.d.ts +1 -0
  5. package/client.js +1 -0
  6. package/lib/client/appType.d.ts +4 -0
  7. package/lib/client/appType.js +7 -0
  8. package/lib/client/index.d.ts +29 -0
  9. package/lib/client/index.js +170 -0
  10. package/lib/client/language.d.ts +11 -0
  11. package/lib/client/language.js +52 -0
  12. package/lib/client/theme-state.d.ts +3 -0
  13. package/lib/client/theme-state.js +6 -0
  14. package/lib/node/bin.d.ts +2 -0
  15. package/lib/node/bin.js +154 -0
  16. package/lib/node/commands/build.d.ts +1 -0
  17. package/lib/node/commands/build.js +15 -0
  18. package/lib/node/commands/checklist.d.ts +6 -0
  19. package/lib/node/commands/checklist.js +59 -0
  20. package/lib/node/commands/compile.d.ts +3 -0
  21. package/lib/node/commands/compile.js +41 -0
  22. package/lib/node/commands/create.d.ts +8 -0
  23. package/lib/node/commands/create.js +91 -0
  24. package/lib/node/commands/dev.d.ts +6 -0
  25. package/lib/node/commands/dev.js +58 -0
  26. package/lib/node/commands/extension.d.ts +3 -0
  27. package/lib/node/commands/extension.js +5 -0
  28. package/lib/node/commands/gen.d.ts +24 -0
  29. package/lib/node/commands/gen.js +91 -0
  30. package/lib/node/commands/icons.d.ts +4 -0
  31. package/lib/node/commands/icons.js +15 -0
  32. package/lib/node/commands/preview.d.ts +4 -0
  33. package/lib/node/commands/preview.js +18 -0
  34. package/lib/node/commands/styleVars.d.ts +1 -0
  35. package/lib/node/commands/styleVars.js +6 -0
  36. package/lib/node/commands/test.d.ts +7 -0
  37. package/lib/node/commands/test.js +16 -0
  38. package/lib/node/commands/vite.d.ts +2 -0
  39. package/lib/node/commands/vite.js +14 -0
  40. package/lib/node/compiler/compileModule.d.ts +4 -0
  41. package/lib/node/compiler/compileModule.js +78 -0
  42. package/lib/node/compiler/compileSFC.d.ts +6 -0
  43. package/lib/node/compiler/compileSFC.js +119 -0
  44. package/lib/node/compiler/compileScript.d.ts +27 -0
  45. package/lib/node/compiler/compileScript.js +221 -0
  46. package/lib/node/compiler/compileSiteEntry.d.ts +19 -0
  47. package/lib/node/compiler/compileSiteEntry.js +164 -0
  48. package/lib/node/compiler/compileStyle.d.ts +14 -0
  49. package/lib/node/compiler/compileStyle.js +55 -0
  50. package/lib/node/compiler/compileStyleVars.d.ts +3 -0
  51. package/lib/node/compiler/compileStyleVars.js +46 -0
  52. package/lib/node/compiler/compileTemplateHighlight.d.ts +18 -0
  53. package/lib/node/compiler/compileTemplateHighlight.js +133 -0
  54. package/lib/node/compiler/compileTypes.d.ts +2 -0
  55. package/lib/node/compiler/compileTypes.js +58 -0
  56. package/lib/node/compiler/generateLibraryEntry.d.ts +3 -0
  57. package/lib/node/compiler/generateLibraryEntry.js +152 -0
  58. package/lib/node/compiler/siteRoutes.d.ts +4 -0
  59. package/lib/node/compiler/siteRoutes.js +9 -0
  60. package/lib/node/config/maple.config.d.ts +215 -0
  61. package/lib/node/config/maple.config.js +32 -0
  62. package/lib/node/config/maple.default.config.d.ts +2 -0
  63. package/lib/node/config/maple.default.config.js +386 -0
  64. package/lib/node/config/site-resolver.d.ts +25 -0
  65. package/lib/node/config/site-resolver.js +138 -0
  66. package/lib/node/config/vite.config.d.ts +28 -0
  67. package/lib/node/config/vite.config.js +209 -0
  68. package/lib/node/config/vitest.config.d.ts +2 -0
  69. package/lib/node/config/vitest.config.js +54 -0
  70. package/lib/node/config/vitest.setup.d.ts +1 -0
  71. package/lib/node/config/vitest.setup.js +8 -0
  72. package/lib/node/index.d.ts +13 -0
  73. package/lib/node/index.js +13 -0
  74. package/lib/node/release/index.d.ts +20 -0
  75. package/lib/node/release/index.js +147 -0
  76. package/lib/node/shared/constant.d.ts +47 -0
  77. package/lib/node/shared/constant.js +53 -0
  78. package/lib/node/shared/fsUtils.d.ts +18 -0
  79. package/lib/node/shared/fsUtils.js +57 -0
  80. package/lib/node/shared/logger.d.ts +8 -0
  81. package/lib/node/shared/logger.js +18 -0
  82. package/lib/node/shared/serial-task.d.ts +2 -0
  83. package/lib/node/shared/serial-task.js +9 -0
  84. package/package.json +111 -3
  85. package/site/documentation-sections.spec.ts +45 -0
  86. package/site/documentation-sections.ts +48 -0
  87. package/site/index.html +89 -0
  88. package/site/mobile/App.vue +437 -0
  89. package/site/mobile/AppHome.vue +154 -0
  90. package/site/mobile/main.ts +99 -0
  91. package/site/mobile/route-sync.spec.ts +34 -0
  92. package/site/mobile/route-sync.ts +10 -0
  93. package/site/mobile.html +70 -0
  94. package/site/module.d.ts +5 -0
  95. package/site/pc/App.vue +44 -0
  96. package/site/pc/Layout.vue +641 -0
  97. package/site/pc/components/AppAd.vue +117 -0
  98. package/site/pc/components/AppHeader.vue +459 -0
  99. package/site/pc/components/AppMobile.spec.ts +204 -0
  100. package/site/pc/components/AppMobile.vue +201 -0
  101. package/site/pc/components/AppOutline.spec.ts +89 -0
  102. package/site/pc/components/AppOutline.vue +161 -0
  103. package/site/pc/components/AppSidebar.vue +144 -0
  104. package/site/pc/components/code-example/CodeExample.spec.ts +36 -0
  105. package/site/pc/components/code-example/CodeExample.vue +164 -0
  106. package/site/pc/components/code-example/codeExample.less +88 -0
  107. package/site/pc/components/code-example/index.ts +10 -0
  108. package/site/pc/components/demo-preview/DemoPreview.vue +92 -0
  109. package/site/pc/components/demo-preview/index.ts +8 -0
  110. package/site/pc/components/mobile-preview-url.ts +17 -0
  111. package/site/pc/components/preview-section.spec.ts +24 -0
  112. package/site/pc/components/preview-section.ts +23 -0
  113. package/site/pc/main.ts +108 -0
  114. package/site/pc/pages/index/index.vue +421 -0
  115. package/site/pc/pages/index/locale/en-US.ts +1 -0
  116. package/site/pc/pages/index/locale/zh-CN.ts +1 -0
  117. package/site/pc/responsive-layout.spec.ts +40 -0
  118. package/site/pc/route-state.spec.ts +34 -0
  119. package/site/pc/route-state.ts +25 -0
  120. package/site/pc/scroll-hash.spec.ts +49 -0
  121. package/site/pc/scroll-hash.ts +25 -0
  122. package/site/route-recovery.spec.ts +51 -0
  123. package/site/route-recovery.ts +38 -0
  124. package/site/tsconfig.json +16 -0
  125. package/site/types.ts +6 -0
  126. package/site/utils.ts +45 -0
  127. package/template/create/[ComponentName].tsx.ejs +16 -0
  128. package/template/create/[ComponentName].vue.ejs +21 -0
  129. package/template/create/[componentName].d.ts.ejs +13 -0
  130. package/template/create/__tests__/index.spec.js.ejs +10 -0
  131. package/template/create/docs/en-US.md +0 -0
  132. package/template/create/docs/zh-CN.md +0 -0
  133. package/template/create/example/index.vue.ejs +17 -0
  134. package/template/create/example/locale/_index.ts +17 -0
  135. package/template/create/example/locale/en-US.ts +3 -0
  136. package/template/create/example/locale/index.ts +24 -0
  137. package/template/create/example/locale/zh-CN.ts +3 -0
  138. package/template/create/index.ts.ejs +12 -0
  139. package/template/create/props.ts +1 -0
  140. package/template/create/style/[componentName].less.ejs +5 -0
  141. package/template/create/style/index.less.ejs +1 -0
  142. package/template/create/style/index.ts.ejs +1 -0
  143. package/template/generators/base/.browserslistrc +2 -0
  144. package/template/generators/base/.prettierignore +14 -0
  145. package/template/generators/base/README.md +90 -0
  146. package/template/generators/base/_gitignore +19 -0
  147. package/template/generators/base/eslint.config.js +15 -0
  148. package/template/generators/base/package.json +97 -0
  149. package/template/generators/base/prettier.config.js +3 -0
  150. package/template/generators/base/public/logo.svg +30 -0
  151. package/template/generators/base/shims/shims-md.d.ts +4 -0
  152. package/template/generators/base/shims/shims-vue.d.ts +6 -0
  153. package/template/generators/base/tsconfig.declaration.json +21 -0
  154. package/template/generators/base/tsconfig.json +28 -0
  155. package/template/generators/base/ui-build.config.mjs +16 -0
  156. package/template/generators/config/default/base/docs/home.zh-CN.md +3 -0
  157. package/template/generators/config/default/base/maple.config.mjs +49 -0
  158. package/template/generators/config/default/sfc/src/button/Button.vue +34 -0
  159. package/template/generators/config/default/sfc/src/button/__tests__/index.spec.js +8 -0
  160. package/template/generators/config/default/sfc/src/button/docs/zh-CN.md +39 -0
  161. package/template/generators/config/default/sfc/src/button/example/BasicUse.vue +7 -0
  162. package/template/generators/config/default/sfc/src/button/example/ModifyColor.vue +7 -0
  163. package/template/generators/config/default/sfc/src/button/example/index.vue +12 -0
  164. package/template/generators/config/default/sfc/src/button/index.ts +8 -0
  165. package/template/generators/config/default/sfc/src/button/style/button.less +14 -0
  166. package/template/generators/config/default/sfc/src/button/style/index.less +1 -0
  167. package/template/generators/config/default/sfc/src/button/style/index.ts +1 -0
  168. package/template/generators/config/default/sfc/src/utils/components.ts +20 -0
  169. package/template/generators/config/default/tsx/src/button/Button.tsx +30 -0
  170. package/template/generators/config/default/tsx/src/button/__tests__/index.spec.js +8 -0
  171. package/template/generators/config/default/tsx/src/button/docs/zh-CN.md +39 -0
  172. package/template/generators/config/default/tsx/src/button/example/BasicUse.vue +7 -0
  173. package/template/generators/config/default/tsx/src/button/example/ModifyColor.vue +7 -0
  174. package/template/generators/config/default/tsx/src/button/example/index.vue +12 -0
  175. package/template/generators/config/default/tsx/src/button/index.ts +8 -0
  176. package/template/generators/config/default/tsx/src/button/style/button.less +14 -0
  177. package/template/generators/config/default/tsx/src/button/style/index.less +1 -0
  178. package/template/generators/config/default/tsx/src/button/style/index.ts +1 -0
  179. package/template/generators/config/default/tsx/src/utils/components.ts +20 -0
  180. package/template/generators/config/i18n/base/docs/home.en-US.md +3 -0
  181. package/template/generators/config/i18n/base/docs/home.zh-CN.md +3 -0
  182. package/template/generators/config/i18n/base/maple.config.mjs +51 -0
  183. package/template/generators/config/i18n/sfc/src/button/Button.vue +38 -0
  184. package/template/generators/config/i18n/sfc/src/button/__tests__/index.spec.js +8 -0
  185. package/template/generators/config/i18n/sfc/src/button/docs/en-US.md +39 -0
  186. package/template/generators/config/i18n/sfc/src/button/docs/zh-CN.md +39 -0
  187. package/template/generators/config/i18n/sfc/src/button/example/BasicUse.vue +11 -0
  188. package/template/generators/config/i18n/sfc/src/button/example/ModifyColor.vue +11 -0
  189. package/template/generators/config/i18n/sfc/src/button/example/index.vue +15 -0
  190. package/template/generators/config/i18n/sfc/src/button/example/locale/en-US.ts +5 -0
  191. package/template/generators/config/i18n/sfc/src/button/example/locale/index.ts +23 -0
  192. package/template/generators/config/i18n/sfc/src/button/example/locale/zh-CN.ts +5 -0
  193. package/template/generators/config/i18n/sfc/src/button/index.ts +8 -0
  194. package/template/generators/config/i18n/sfc/src/button/style/button.less +14 -0
  195. package/template/generators/config/i18n/sfc/src/button/style/index.less +1 -0
  196. package/template/generators/config/i18n/sfc/src/button/style/index.ts +1 -0
  197. package/template/generators/config/i18n/sfc/src/locale/__tests__/index.spec.js +52 -0
  198. package/template/generators/config/i18n/sfc/src/locale/docs/en-US.md +26 -0
  199. package/template/generators/config/i18n/sfc/src/locale/docs/zh-CN.md +25 -0
  200. package/template/generators/config/i18n/sfc/src/locale/en-US.d.ts +5 -0
  201. package/template/generators/config/i18n/sfc/src/locale/en-US.ts +7 -0
  202. package/template/generators/config/i18n/sfc/src/locale/index.ts +82 -0
  203. package/template/generators/config/i18n/sfc/src/locale/zh-CN.d.ts +5 -0
  204. package/template/generators/config/i18n/sfc/src/locale/zh-CN.ts +7 -0
  205. package/template/generators/config/i18n/sfc/src/utils/components.ts +20 -0
  206. package/template/generators/config/i18n/tsx/src/button/Button.tsx +35 -0
  207. package/template/generators/config/i18n/tsx/src/button/__tests__/index.spec.js +8 -0
  208. package/template/generators/config/i18n/tsx/src/button/docs/en-US.md +39 -0
  209. package/template/generators/config/i18n/tsx/src/button/docs/zh-CN.md +39 -0
  210. package/template/generators/config/i18n/tsx/src/button/example/BasicUse.vue +11 -0
  211. package/template/generators/config/i18n/tsx/src/button/example/ModifyColor.vue +11 -0
  212. package/template/generators/config/i18n/tsx/src/button/example/index.vue +15 -0
  213. package/template/generators/config/i18n/tsx/src/button/example/locale/en-US.ts +5 -0
  214. package/template/generators/config/i18n/tsx/src/button/example/locale/index.ts +23 -0
  215. package/template/generators/config/i18n/tsx/src/button/example/locale/zh-CN.ts +5 -0
  216. package/template/generators/config/i18n/tsx/src/button/index.ts +8 -0
  217. package/template/generators/config/i18n/tsx/src/button/style/button.less +14 -0
  218. package/template/generators/config/i18n/tsx/src/button/style/index.less +1 -0
  219. package/template/generators/config/i18n/tsx/src/button/style/index.ts +1 -0
  220. package/template/generators/config/i18n/tsx/src/locale/__tests__/index.spec.js +52 -0
  221. package/template/generators/config/i18n/tsx/src/locale/docs/en-US.md +26 -0
  222. package/template/generators/config/i18n/tsx/src/locale/docs/zh-CN.md +25 -0
  223. package/template/generators/config/i18n/tsx/src/locale/en-US.d.ts +5 -0
  224. package/template/generators/config/i18n/tsx/src/locale/en-US.ts +7 -0
  225. package/template/generators/config/i18n/tsx/src/locale/index.ts +82 -0
  226. package/template/generators/config/i18n/tsx/src/locale/zh-CN.d.ts +5 -0
  227. package/template/generators/config/i18n/tsx/src/locale/zh-CN.ts +7 -0
  228. package/template/generators/config/i18n/tsx/src/utils/components.ts +20 -0
@@ -0,0 +1,170 @@
1
+ import { onMounted, onUnmounted, shallowRef } from 'vue';
2
+ import config from '@config';
3
+ import { ThemeProvider, Themes } from '@maple-design/ui-vue';
4
+ import AppType from './appType';
5
+ import { resolveDemoLanguage } from './language';
6
+ import { currentTheme, observeTheme } from './theme-state';
7
+ const themes = [
8
+ 'lightTheme',
9
+ 'darkTheme',
10
+ 'mapleLightTheme',
11
+ 'mapleDarkTheme',
12
+ 'alpsLightTheme',
13
+ 'fireflyLightTheme',
14
+ 'alpsDarkTheme',
15
+ 'fireflyDarkTheme',
16
+ ];
17
+ function isTheme(value) {
18
+ return value !== null && themes.includes(value);
19
+ }
20
+ export function getPCLocationInfo() {
21
+ const [, language, path] = window.location.hash.split('/');
22
+ const [menuName, hash = ''] = path?.split('#') ?? [];
23
+ return {
24
+ language,
25
+ menuName,
26
+ hash,
27
+ };
28
+ }
29
+ function getHashSearch() {
30
+ const { href } = window.location;
31
+ const hashSearch = href.slice(href.indexOf('?'));
32
+ return new URLSearchParams(hashSearch);
33
+ }
34
+ function getSiteThemeKey() {
35
+ return config?.themeKey;
36
+ }
37
+ function getDemoThemeKey() {
38
+ return config?.demoThemeKey ?? `${getSiteThemeKey()}_DEMO`;
39
+ }
40
+ function getThemeStorageKey(scope) {
41
+ return scope === 'demo' ? getDemoThemeKey() : getSiteThemeKey();
42
+ }
43
+ function getPreferredTheme() {
44
+ const defaultLightTheme = config?.defaultLightTheme;
45
+ const defaultDarkTheme = config?.defaultDarkTheme;
46
+ return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? defaultDarkTheme : defaultLightTheme;
47
+ }
48
+ /** Site docs chrome theme (`themeKey`) vs mobile demo theme (`demoThemeKey`). */
49
+ export function getBrowserTheme(scope = 'site') {
50
+ const themeKey = getThemeStorageKey(scope);
51
+ const storageTheme = window.localStorage.getItem(themeKey);
52
+ if (isTheme(storageTheme)) {
53
+ return storageTheme;
54
+ }
55
+ // First visit for demo: seed from site theme so existing users keep the same look until they diverge.
56
+ if (scope === 'demo') {
57
+ const siteTheme = window.localStorage.getItem(getSiteThemeKey());
58
+ const theme = isTheme(siteTheme) ? siteTheme : getPreferredTheme();
59
+ window.localStorage.setItem(themeKey, theme);
60
+ return theme;
61
+ }
62
+ const theme = getPreferredTheme();
63
+ window.localStorage.setItem(themeKey, theme);
64
+ return theme;
65
+ }
66
+ export function persistTheme(theme, scope = 'site') {
67
+ window.localStorage.setItem(getThemeStorageKey(scope), theme);
68
+ }
69
+ export function watchLang(cb, platform) {
70
+ const handleHashchange = () => {
71
+ cb(resolveDemoLanguage(window.location.hash, platform));
72
+ };
73
+ useRouteListener(handleHashchange);
74
+ handleHashchange();
75
+ }
76
+ export function withSiteConfigNamespace(styleVars) {
77
+ return Object.entries(styleVars).reduce((styleVars, [key, value]) => {
78
+ styleVars[`--site-config-${key}`] = value;
79
+ return styleVars;
80
+ }, {});
81
+ }
82
+ export function watchPlatform(cb) {
83
+ const handleHashchange = () => {
84
+ const platform = getHashSearch().get('platform') ?? 'mobile';
85
+ cb(platform);
86
+ };
87
+ useRouteListener(handleHashchange);
88
+ handleHashchange();
89
+ }
90
+ export function useRouteListener(cb) {
91
+ onMounted(() => {
92
+ window.addEventListener('hashchange', cb);
93
+ window.addEventListener('popstate', cb);
94
+ });
95
+ onUnmounted(() => {
96
+ window.removeEventListener('hashchange', cb);
97
+ window.removeEventListener('popstate', cb);
98
+ });
99
+ }
100
+ export const currentThemePreset = shallowRef(Themes.default.light);
101
+ export const currentStyleVars = shallowRef({});
102
+ export { currentTheme } from './theme-state';
103
+ const themeMap = {
104
+ lightTheme: Themes.default.light,
105
+ darkTheme: Themes.default.dark,
106
+ mapleLightTheme: Themes.maple.light,
107
+ mapleDarkTheme: Themes.maple.dark,
108
+ alpsLightTheme: Themes.alps.light,
109
+ fireflyLightTheme: Themes.firefly.light,
110
+ alpsDarkTheme: Themes.alps.dark,
111
+ fireflyDarkTheme: Themes.firefly.dark,
112
+ };
113
+ export function setTheme(theme) {
114
+ const siteStyleVars = withSiteConfigNamespace(config[theme] ||
115
+ (theme === 'alpsLightTheme' || theme === 'fireflyLightTheme'
116
+ ? config.lightTheme
117
+ : theme === 'alpsDarkTheme' || theme === 'fireflyDarkTheme'
118
+ ? config.darkTheme
119
+ : {}) ||
120
+ {});
121
+ currentThemePreset.value = themeMap[theme] ?? Themes.default.light;
122
+ currentStyleVars.value = siteStyleVars;
123
+ setColorScheme(theme);
124
+ currentTheme.value = theme;
125
+ }
126
+ export function onThemeChange(cb, scope = 'site') {
127
+ const theme = currentTheme.value ?? getBrowserTheme(scope);
128
+ setTheme(theme);
129
+ if (cb) {
130
+ observeTheme(cb);
131
+ }
132
+ }
133
+ export function getSiteStyleVars(theme) {
134
+ return withSiteConfigNamespace(config[theme] ||
135
+ (theme === 'alpsLightTheme' || theme === 'fireflyLightTheme'
136
+ ? config.lightTheme
137
+ : theme === 'alpsDarkTheme' || theme === 'fireflyDarkTheme'
138
+ ? config.darkTheme
139
+ : {}) ||
140
+ {});
141
+ }
142
+ export function setColorScheme(theme) {
143
+ document.documentElement.style.setProperty('color-scheme', theme.toLowerCase().includes('dark') ? 'dark' : 'light');
144
+ }
145
+ export function watchTheme(cb, shouldUnmount = true) {
146
+ const handleThemeChange = (event) => {
147
+ const { data } = event;
148
+ if (data?.action === 'theme-change') {
149
+ cb(data.data, data.from);
150
+ }
151
+ };
152
+ window.addEventListener('message', handleThemeChange);
153
+ if (shouldUnmount) {
154
+ onUnmounted(() => {
155
+ window.removeEventListener('message', handleThemeChange);
156
+ });
157
+ }
158
+ cb(getBrowserTheme('site'), 'default');
159
+ }
160
+ export function getMobileIndex() {
161
+ // Vite's dev server serves mobile.html from its root, even when the PC
162
+ // document was opened through a nested history-fallback URL.
163
+ if (import.meta.env.DEV) {
164
+ return '/mobile.html';
165
+ }
166
+ const isCf = config._cf.some((path) => window.location.origin.includes(path));
167
+ return isCf ? './mobile' : './mobile.html';
168
+ }
169
+ export { AppType, ThemeProvider };
170
+ export { normalizeLanguage, getSavedLanguage, saveLanguage, createDemoMessages } from './language';
@@ -0,0 +1,11 @@
1
+ export declare const siteLanguages: readonly ["zh-CN", "en-US"];
2
+ export type SiteLanguage = (typeof siteLanguages)[number];
3
+ export declare function normalizeLanguage(value: unknown, fallback?: SiteLanguage): SiteLanguage;
4
+ export declare function getSavedLanguage(fallback?: SiteLanguage): SiteLanguage;
5
+ export declare function saveLanguage(value: unknown): SiteLanguage;
6
+ export declare function createDemoMessages(messages: Record<string, Record<string, string>>): {
7
+ use: (value: string) => void;
8
+ t: (key: string) => string;
9
+ };
10
+ /** Both the desktop docs route and the mobile demo route carry the site language. */
11
+ export declare function resolveDemoLanguage(hash: string, platform?: 'pc' | 'mobile'): string;
@@ -0,0 +1,52 @@
1
+ import { computed, ref } from 'vue';
2
+ export const siteLanguages = ['zh-CN', 'en-US'];
3
+ const storageKey = 'maple-site-language';
4
+ export function normalizeLanguage(value, fallback = 'zh-CN') {
5
+ return siteLanguages.includes(value) ? value : fallback;
6
+ }
7
+ export function getSavedLanguage(fallback = 'zh-CN') {
8
+ try {
9
+ return normalizeLanguage(window.localStorage.getItem(storageKey), fallback);
10
+ }
11
+ catch {
12
+ return fallback;
13
+ }
14
+ }
15
+ export function saveLanguage(value) {
16
+ const language = normalizeLanguage(value);
17
+ if (typeof document !== 'undefined') {
18
+ document.documentElement.lang = language;
19
+ }
20
+ try {
21
+ window.localStorage.setItem(storageKey, language);
22
+ }
23
+ catch {
24
+ /* Storage may be unavailable. */
25
+ }
26
+ return language;
27
+ }
28
+ // Demo titles are site metadata; demo SFCs do not need translation imports.
29
+ export function createDemoMessages(messages) {
30
+ const language = ref('zh-CN');
31
+ const current = computed(() => messages[language.value] ?? messages['zh-CN'] ?? {});
32
+ return {
33
+ use: (value) => {
34
+ language.value = normalizeLanguage(value);
35
+ },
36
+ t: (key) => current.value[key] ?? messages['zh-CN']?.[key] ?? key,
37
+ };
38
+ }
39
+ /** Both the desktop docs route and the mobile demo route carry the site language. */
40
+ export function resolveDemoLanguage(hash, platform) {
41
+ const queryIndex = hash.indexOf('?');
42
+ const query = new URLSearchParams(queryIndex < 0 ? '' : hash.slice(queryIndex + 1));
43
+ const [, routeLanguage, page] = hash.slice(0, queryIndex < 0 ? undefined : queryIndex).split('/');
44
+ if (platform === 'mobile') {
45
+ return query.get('language') || 'zh-CN';
46
+ }
47
+ if (platform === 'pc') {
48
+ return routeLanguage || 'zh-CN';
49
+ }
50
+ // Desktop: #/en-US/input; mobile/iframe: #/input?language=en-US.
51
+ return query.get('language') || (page ? routeLanguage : undefined) || 'zh-CN';
52
+ }
@@ -0,0 +1,3 @@
1
+ import type { Theme } from './index';
2
+ export declare const currentTheme: import("vue").ShallowRef<Theme | undefined, Theme | undefined>;
3
+ export declare function observeTheme(callback: (theme: Theme) => void): import("vue").WatchHandle;
@@ -0,0 +1,6 @@
1
+ import { shallowRef, watch } from 'vue';
2
+ // The mounted app owns its theme; demos must not reapply another storage scope.
3
+ export const currentTheme = shallowRef();
4
+ export function observeTheme(callback) {
5
+ return watch(currentTheme, (theme) => theme && callback(theme), { immediate: true, flush: 'sync' });
6
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { getCliVersion } from './shared/fsUtils.js';
4
+ const program = new Command();
5
+ program.version(`maple-cli ${getCliVersion()}`).usage('<command> [options]');
6
+ program
7
+ .command('dev')
8
+ .option('-f --force', 'Force dep pre-optimization regardless of whether deps have changed')
9
+ .option('-d --draft', 'Start the service in draft mode')
10
+ .description('Run maple development environment')
11
+ .action(async (options) => {
12
+ const { dev } = await import('./commands/dev.js');
13
+ return dev(options);
14
+ });
15
+ program
16
+ .command('build')
17
+ .description('Build maple site for production')
18
+ .action(async () => {
19
+ const { build } = await import('./commands/build.js');
20
+ return build();
21
+ });
22
+ program
23
+ .command('dev:vite')
24
+ .description('Use vite start server for development')
25
+ .action(async () => {
26
+ const { vite } = await import('./commands/vite.js');
27
+ return vite('dev');
28
+ });
29
+ program
30
+ .command('build:vite')
31
+ .description('Use vite build app for production')
32
+ .action(async () => {
33
+ const { vite } = await import('./commands/vite.js');
34
+ return vite('build');
35
+ });
36
+ program
37
+ .command('dev:extension')
38
+ .description('Run VSCode extension development environment')
39
+ .action(async () => {
40
+ const { extension } = await import('./commands/extension.js');
41
+ return extension('dev');
42
+ });
43
+ program
44
+ .command('build:extension')
45
+ .description('Build VSCode extension for production')
46
+ .action(async () => {
47
+ const { extension } = await import('./commands/extension.js');
48
+ return extension('build');
49
+ });
50
+ program
51
+ .command('build:icons')
52
+ .option('-w --watch', 'Watch icons for changes and rebuild')
53
+ .description('Build icons')
54
+ .action(async (options) => {
55
+ const { icons } = await import('./commands/icons.js');
56
+ return icons(options);
57
+ });
58
+ program
59
+ .command('preview')
60
+ .description('Preview maple site for production')
61
+ .option('-p, --port <port>', 'port number')
62
+ .action(async (options) => {
63
+ const { preview } = await import('./commands/preview.js');
64
+ return preview(options);
65
+ });
66
+ program
67
+ .command('compile')
68
+ .description('Compile maple components library code')
69
+ .action(async () => {
70
+ const { compile } = await import('./commands/compile.js');
71
+ return compile();
72
+ });
73
+ program
74
+ .command('compile:style-vars')
75
+ .description('Compile maple style vars')
76
+ .action(async () => {
77
+ const { styleVars } = await import('./commands/styleVars.js');
78
+ return styleVars();
79
+ });
80
+ program
81
+ .command('create')
82
+ .description('Create a component directory')
83
+ .option('-i, --internal', 'maple internal mode')
84
+ .option('-n, --name <componentName>', 'Component name')
85
+ .option('-s, --sfc', 'Generate files in sfc format')
86
+ .option('-t, --tsx', 'Generate files in tsx format')
87
+ .option('-l, --locale', 'Generator internationalized files')
88
+ .action(async (options) => {
89
+ const { create } = await import('./commands/create.js');
90
+ return create(options);
91
+ });
92
+ program
93
+ .command('test')
94
+ .description('Run test in work directory')
95
+ .option('-w, --watch', 'Watch files for changes and rerun tests related to changed files')
96
+ .option('-c, --component <componentName>', 'Test a specific component')
97
+ .option('-cov, --coverage', 'Generate the coverage')
98
+ .action(async (options) => {
99
+ const { test } = await import('./commands/test.js');
100
+ return test(options);
101
+ });
102
+ program
103
+ .command('gen')
104
+ .description('Generate cli application')
105
+ .option('-n, --name <applicationName>', 'Application name')
106
+ .option('-s, --sfc', 'Generate files in sfc format')
107
+ .option('-t, --tsx', 'Generate files in tsx format')
108
+ .option('-l, --locale', 'Generator internationalized files')
109
+ .action(async (options) => {
110
+ const { gen } = await import('./commands/gen.js');
111
+ return gen(options);
112
+ });
113
+ program
114
+ .command('changelog')
115
+ .option('-rc --releaseCount <releaseCount>', 'Release count')
116
+ .option('-f --file <file>', 'Changelog filename')
117
+ .description('Generate changelog')
118
+ .action(async (options) => {
119
+ const { changelog } = await import('./release/index.js');
120
+ return changelog(options);
121
+ });
122
+ program
123
+ .command('release')
124
+ .option('-r --remote <remote>', 'Remote name')
125
+ .description('Release all packages and generate changelogs')
126
+ .action(async (options) => {
127
+ const { release } = await import('./release/index.js');
128
+ return release(options);
129
+ });
130
+ program
131
+ .command('commit-lint')
132
+ .option('-p --commitMessagePath <path>', 'Git commit message path')
133
+ .option('-r --commitMessageRe <reg>', 'Validate the regular of whether the commit message passes')
134
+ .option('-e --errorMessage <message>', 'Validation failed to display error messages')
135
+ .option('-w --warningMessage <message>', 'Validation failed to display warning messages')
136
+ .description('Lint commit message')
137
+ .action(async (options) => {
138
+ const { commitLint } = await import('./release/index.js');
139
+ return commitLint(options);
140
+ });
141
+ program
142
+ .command('checklist <gitParams>')
143
+ .description('Display a checklist for confirmation')
144
+ .action(async (options) => {
145
+ const { checklist } = await import('./commands/checklist.js');
146
+ return checklist(options);
147
+ });
148
+ program.on('command:*', async ([cmd]) => {
149
+ const { default: logger } = await import('./shared/logger.js');
150
+ program.outputHelp();
151
+ logger.error(`\nUnknown command ${cmd}.\n`);
152
+ process.exitCode = 1;
153
+ });
154
+ program.parse();
@@ -0,0 +1 @@
1
+ export declare function build(): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import fse from 'fs-extra';
2
+ import { build as buildVite } from 'vite';
3
+ import { buildSiteEntry } from '../compiler/compileSiteEntry.js';
4
+ import { getMapleConfig } from '../config/maple.config.js';
5
+ import { getBuildConfig } from '../config/vite.config.js';
6
+ import { SRC_DIR } from '../shared/constant.js';
7
+ const { ensureDirSync } = fse;
8
+ export async function build() {
9
+ process.env.NODE_ENV = 'production';
10
+ ensureDirSync(SRC_DIR);
11
+ await buildSiteEntry(false);
12
+ const mapleConfig = await getMapleConfig();
13
+ const buildConfig = getBuildConfig(mapleConfig);
14
+ await buildVite(buildConfig);
15
+ }
@@ -0,0 +1,6 @@
1
+ export interface CheckBlock {
2
+ type: string;
3
+ list: string[];
4
+ }
5
+ export declare function getCheckBlocks(html: string): CheckBlock[];
6
+ export declare function checklist(gitParams: string): void;
@@ -0,0 +1,59 @@
1
+ import fse from 'fs-extra';
2
+ import markdownIt from 'markdown-it';
3
+ import { COMMIT_MESSAGE_RE, getCommitMessage, isVersionCommitMessage } from '../release/index.js';
4
+ import { CHECKLIST_FILE } from '../shared/constant.js';
5
+ import logger from '../shared/logger.js';
6
+ const { readFileSync, existsSync } = fse;
7
+ const blockRE = /<h3>(.|\n|\r)+?<\/ul>/g;
8
+ const typeRE = /<h3>(.+)<\/h3>/;
9
+ const childrenRE = /<ul>(.|\n|\r)+<\/ul>/;
10
+ const childRE = /<li>(.|\n|\r)+?<\/li>/g;
11
+ export function getCheckBlocks(html) {
12
+ const blocks = html.match(blockRE) ?? [];
13
+ const checkBlocks = [];
14
+ blocks.forEach((block) => {
15
+ const type = block.match(typeRE)?.[1];
16
+ const childrenBlock = block.match(childrenRE)?.[0];
17
+ if (!type || !childrenBlock) {
18
+ return;
19
+ }
20
+ const children = childrenBlock.match(childRE);
21
+ if (!children) {
22
+ return;
23
+ }
24
+ const list = children.map((child) => child
25
+ .replaceAll('<li>', '')
26
+ .replaceAll('</li>', '')
27
+ .replaceAll('<p>', '')
28
+ .replaceAll('</p>', '')
29
+ .replaceAll('\n', ''));
30
+ checkBlocks.push({
31
+ type,
32
+ list,
33
+ });
34
+ });
35
+ return checkBlocks;
36
+ }
37
+ export function checklist(gitParams) {
38
+ const commitMessage = getCommitMessage(gitParams);
39
+ if (isVersionCommitMessage(commitMessage) || !existsSync(CHECKLIST_FILE)) {
40
+ return;
41
+ }
42
+ const content = readFileSync(CHECKLIST_FILE, 'utf-8');
43
+ const html = markdownIt().render(content);
44
+ const checkBlocks = getCheckBlocks(html);
45
+ if (!checkBlocks.length) {
46
+ logger.warning('Cannot find anything need to checked');
47
+ return;
48
+ }
49
+ const type = commitMessage.match(COMMIT_MESSAGE_RE)?.[1];
50
+ const typeChildren = checkBlocks.find((checkBlock) => checkBlock.type === type)?.list ?? [];
51
+ const commonChildren = checkBlocks.find((checkBlock) => checkBlock.type === 'common')?.list ?? [];
52
+ const list = [...commonChildren, ...typeChildren];
53
+ if (!list.length) {
54
+ return;
55
+ }
56
+ logger.title('\nIt is recommended that you check the following information before pushing:\n');
57
+ logger.warning(`${list.map((item) => `šŸ”” ${item}`).join('\n')}\n`);
58
+ logger.title('If there are changes that need to be amended, please use git commit --amend to resolve.');
59
+ }
@@ -0,0 +1,3 @@
1
+ export declare function removeDir(): Promise<[void, void, void, void]>;
2
+ export declare function runTask(taskName: string, task: () => any): Promise<void>;
3
+ export declare function compile(): Promise<void>;
@@ -0,0 +1,41 @@
1
+ import { resolve } from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { buildLibrary } from '@sparknest/ui-build-vue';
4
+ import fse from 'fs-extra';
5
+ import { createSpinner } from 'nanospinner';
6
+ import { compileTemplateHighlight } from '../compiler/compileTemplateHighlight.js';
7
+ import { compileTypes, generateReference } from '../compiler/compileTypes.js';
8
+ import { generateLibraryEntry } from '../compiler/generateLibraryEntry.js';
9
+ import { ES_DIR, HL_DIR, LIB_DIR, UMD_DIR } from '../shared/constant.js';
10
+ import logger from '../shared/logger.js';
11
+ const { remove } = fse;
12
+ export function removeDir() {
13
+ return Promise.all([remove(ES_DIR), remove(LIB_DIR), remove(HL_DIR), remove(UMD_DIR)]);
14
+ }
15
+ export async function runTask(taskName, task) {
16
+ const s = createSpinner().start({ text: `Compiling ${taskName}` });
17
+ try {
18
+ const start = performance.now();
19
+ await task();
20
+ s.success({ text: `Compilation ${taskName} completed! (${Math.ceil(performance.now() - start)}ms)` });
21
+ }
22
+ catch (e) {
23
+ s.error({ text: `Compilation ${taskName} failed!` });
24
+ logger.error(e.toString());
25
+ process.exitCode = 1;
26
+ }
27
+ }
28
+ export async function compile() {
29
+ process.env.NODE_ENV = 'production';
30
+ await removeDir();
31
+ await runTask('library entry', generateLibraryEntry);
32
+ await Promise.all([runTask('types', compileTypes), runTask('template highlight', compileTemplateHighlight)]);
33
+ const configUrl = pathToFileURL(resolve(process.cwd(), 'ui-build.config.mjs')).href;
34
+ const configModule = await import(`${configUrl}?t=${Date.now()}`);
35
+ await runTask('module', () => buildLibrary(configModule.default));
36
+ if (process.exitCode && process.exitCode !== 0) {
37
+ return;
38
+ }
39
+ generateReference(ES_DIR);
40
+ generateReference(LIB_DIR);
41
+ }
@@ -0,0 +1,8 @@
1
+ export interface CreateCommandOptions {
2
+ internal?: boolean;
3
+ name?: string;
4
+ locale?: boolean;
5
+ sfc?: boolean;
6
+ tsx?: boolean;
7
+ }
8
+ export declare function create(options: CreateCommandOptions): Promise<void>;
@@ -0,0 +1,91 @@
1
+ import { resolve } from 'path';
2
+ import { confirm, input, select } from '@inquirer/prompts';
3
+ import { camelize, kebabCase, pascalCase } from '@maple-design/shared-vue';
4
+ import ejs from 'ejs';
5
+ import fse from 'fs-extra';
6
+ import { getMapleConfig } from '../config/maple.config.js';
7
+ import { dirname, SRC_DIR } from '../shared/constant.js';
8
+ import { glob } from '../shared/fsUtils.js';
9
+ import logger from '../shared/logger.js';
10
+ const { removeSync, readFileSync, copySync, pathExistsSync, writeFileSync, renameSync } = fse;
11
+ async function renderTemplates(componentFolder, componentFolderName, renderData) {
12
+ const templates = await glob(`${componentFolder}/**/*.ejs`);
13
+ templates.forEach((template) => {
14
+ const templateCode = readFileSync(template, { encoding: 'utf-8' });
15
+ const code = ejs.render(templateCode, renderData);
16
+ const file = template
17
+ .replace('[componentName]', camelize(componentFolderName))
18
+ .replace('[ComponentName]', pascalCase(componentFolderName))
19
+ .replace('.ejs', '');
20
+ writeFileSync(file, code);
21
+ removeSync(template);
22
+ });
23
+ }
24
+ export async function create(options) {
25
+ logger.title('\nšŸ“¦šŸ“¦ Create a component ! \n');
26
+ const { namespace } = await getMapleConfig();
27
+ const renderData = {
28
+ namespace,
29
+ bigCamelizeNamespace: pascalCase(namespace),
30
+ kebabCaseName: 'component-name',
31
+ bigCamelizeName: 'ComponentName',
32
+ camelizeName: 'componentName',
33
+ style: 'vue',
34
+ };
35
+ const name = options.name
36
+ ? options.name
37
+ : await input({
38
+ message: 'Name of the component created: ',
39
+ default: renderData.kebabCaseName,
40
+ });
41
+ renderData.kebabCaseName = kebabCase(name);
42
+ renderData.camelizeName = camelize(name);
43
+ renderData.bigCamelizeName = pascalCase(name);
44
+ const componentFolder = resolve(SRC_DIR, renderData.kebabCaseName);
45
+ const componentFolderName = renderData.kebabCaseName;
46
+ if (pathExistsSync(componentFolder)) {
47
+ logger.warning(`${componentFolderName} already exist and cannot be recreated...`);
48
+ return;
49
+ }
50
+ const locale = options.locale
51
+ ? options.locale
52
+ : await confirm({
53
+ message: 'Whether to use i18n?',
54
+ default: false,
55
+ });
56
+ renderData.locale = locale;
57
+ // Determine whether the parameter carries a component style
58
+ if (options.sfc || options.tsx) {
59
+ renderData.style = options.sfc ? 'vue' : 'tsx';
60
+ }
61
+ else {
62
+ const style = await select({
63
+ message: 'Which style do you use to write your component ?',
64
+ choices: [
65
+ { name: 'sfc', value: 'vue' },
66
+ { name: 'tsx', value: 'tsx' },
67
+ ],
68
+ default: 'vue',
69
+ });
70
+ renderData.style = style;
71
+ }
72
+ copySync(resolve(dirname, '../../../template/create'), componentFolder);
73
+ await renderTemplates(componentFolder, componentFolderName, renderData);
74
+ if (options.internal) {
75
+ removeSync(resolve(componentFolder, './example/locale/index.ts'));
76
+ renameSync(resolve(componentFolder, './example/locale/_index.ts'), resolve(componentFolder, './example/locale/index.ts'));
77
+ }
78
+ else {
79
+ removeSync(resolve(componentFolder, './example/locale/_index.ts'));
80
+ }
81
+ if (!renderData.locale) {
82
+ removeSync(resolve(componentFolder, '/example/locale'));
83
+ }
84
+ if (renderData.style !== 'vue') {
85
+ removeSync(resolve(componentFolder, `${renderData.bigCamelizeName}.vue`));
86
+ }
87
+ if (renderData.style !== 'tsx') {
88
+ removeSync(resolve(componentFolder, `${renderData.bigCamelizeName}.tsx`));
89
+ }
90
+ logger.success(`Create ${componentFolderName} component success!`);
91
+ }
@@ -0,0 +1,6 @@
1
+ interface DevCommandOptions {
2
+ force?: boolean;
3
+ draft?: boolean;
4
+ }
5
+ export declare function dev(options: DevCommandOptions): Promise<void>;
6
+ export {};