@xyd-js/themes 0.0.0-build
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.
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/decorators/atlas-vars.css +29 -0
- package/dist/decorators/header-sketch.css +23 -0
- package/dist/decorators/page-layout.css +11 -0
- package/dist/decorators/page-leftpad.css +46 -0
- package/dist/decorators/page-sketch.css +52 -0
- package/dist/decorators/sidebar-pad.css +24 -0
- package/dist/decorators/sidebar-scroll.css +51 -0
- package/dist/index.css +1259 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.js +669 -0
- package/dist/index.js.map +1 -0
- package/dist/reset.css +56 -0
- package/dist/rollup.d.ts +28 -0
- package/dist/rollup.js +139 -0
- package/dist/rollup.js.map +1 -0
- package/package.json +60 -0
- package/postcss.config.cjs +7 -0
- package/scripts/build-css.js +73 -0
- package/src/BaseTheme.tsx +471 -0
- package/src/Theme.tsx +363 -0
- package/src/context.tsx +9 -0
- package/src/copyPresetsPlugin.ts +124 -0
- package/src/index.ts +11 -0
- package/src/rollup.ts +91 -0
- package/src/styles/decorators/atlas-vars.css +32 -0
- package/src/styles/decorators/header-sketch.css +23 -0
- package/src/styles/decorators/page-layout.css +11 -0
- package/src/styles/decorators/page-leftpad.css +46 -0
- package/src/styles/decorators/page-sketch.css +30 -0
- package/src/styles/decorators/sidebar-pad.css +24 -0
- package/src/styles/decorators/sidebar-scroll.css +51 -0
- package/src/styles/index.css +26 -0
- package/src/styles/reset.css +56 -0
- package/src/styles/styles.css +156 -0
- package/src/styles/tokens.css +472 -0
- package/tsconfig.json +51 -0
- package/tsup.config.ts +38 -0
- package/types.d.ts +13 -0
package/src/Theme.tsx
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import type { Appearance, Navigation, Theme as ThemeSettings, UserPreferences, WebEditor, WebEditorNavigationItem } from "@xyd-js/core"
|
|
4
|
+
import { ReactContent } from "@xyd-js/components/content"
|
|
5
|
+
import { IconSocial } from "@xyd-js/components/writer"
|
|
6
|
+
import { Surfaces } from "@xyd-js/framework"
|
|
7
|
+
import { useMetadata } from "@xyd-js/framework/react"
|
|
8
|
+
|
|
9
|
+
// ─── Theme Class ──────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
// TODO: still issues with double settings on dev changing
|
|
12
|
+
// TODO: refactor
|
|
13
|
+
export abstract class Theme {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.settings = globalThis.__xydThemeSettings
|
|
16
|
+
|
|
17
|
+
this.useHideToc = this.useHideToc.bind(this)
|
|
18
|
+
this.useHideSidebar = this.useHideSidebar.bind(this)
|
|
19
|
+
this.appearanceWebEditor = this.appearanceWebEditor.bind(this)
|
|
20
|
+
this.headerPrepend = this.headerPrepend.bind(this)
|
|
21
|
+
this.mergeUserAppearance = this.mergeUserAppearance.bind(this)
|
|
22
|
+
this.resetWebeditor = this.resetWebeditor.bind(this)
|
|
23
|
+
|
|
24
|
+
globalThis.__xydThemeSettings.Update = this.update.bind(this) // TODO: in the future better solution cuz we modify original object
|
|
25
|
+
globalThis.__xydThemeSettings.UpdatePreset = this.updateThemePreset.bind(this)
|
|
26
|
+
|
|
27
|
+
this.theme = globalThis.__xydThemeSettings
|
|
28
|
+
this.surfaces = globalThis.__xydSurfaces
|
|
29
|
+
this.reactContent = globalThis.__xydReactContent
|
|
30
|
+
this.navigation = globalThis.__xydNavigation as Navigation
|
|
31
|
+
this.webeditor = globalThis.__xydWebeditor as WebEditor
|
|
32
|
+
this.userPreferences = globalThis.__xydUserPreferences as UserPreferences
|
|
33
|
+
|
|
34
|
+
this.userAppearance = JSON.parse(JSON.stringify(this.theme.appearance || {}))
|
|
35
|
+
|
|
36
|
+
this.appearanceWebEditor()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private webeditor: WebEditor
|
|
40
|
+
private navigation: Navigation
|
|
41
|
+
|
|
42
|
+
private userAppearance: Appearance
|
|
43
|
+
protected settings: ThemeSettings
|
|
44
|
+
protected theme: CustomTheme<ThemeSettings>
|
|
45
|
+
protected readonly reactContent: ReactContent
|
|
46
|
+
protected readonly surfaces: Surfaces
|
|
47
|
+
private readonly userPreferences: UserPreferences
|
|
48
|
+
|
|
49
|
+
private get originalTheme(): ThemeSettings {
|
|
50
|
+
return JSON.parse(JSON.stringify(globalThis.__xydSettingsClone?.theme))
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private get originalWebeditor(): WebEditor {
|
|
54
|
+
return JSON.parse(JSON.stringify(globalThis.__xydSettingsClone?.webeditor))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private get originalNavigation(): Navigation {
|
|
58
|
+
return JSON.parse(JSON.stringify(globalThis.__xydSettingsClone?.navigation))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public abstract Page({ children }: { children: React.ReactNode }): React.ReactElement
|
|
62
|
+
|
|
63
|
+
public abstract Layout({ children }: { children: React.ReactNode }): React.ReactElement
|
|
64
|
+
|
|
65
|
+
public abstract reactContentComponents(): { [component: string]: (props: any) => React.JSX.Element | null }
|
|
66
|
+
|
|
67
|
+
public abstract reactFileComponents(): { [component: string]: (props: any) => React.JSX.Element | null } | false
|
|
68
|
+
|
|
69
|
+
protected useHideToc() {
|
|
70
|
+
const meta = useMetadata()
|
|
71
|
+
return meta?.layout === "wide" || meta?.layout === "reader" || meta?.layout === "page"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected useHideSidebar() {
|
|
75
|
+
const meta = useMetadata()
|
|
76
|
+
return meta?.layout === "page" || meta?.layout === "reader"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private headerPrepend(searchItem: any, float: string) {
|
|
80
|
+
const header = this.webeditor.header || []
|
|
81
|
+
const insertIndex = header.findIndex(item => item.float === float)
|
|
82
|
+
return insertIndex === -1
|
|
83
|
+
? [...header, searchItem]
|
|
84
|
+
: [...header.slice(0, insertIndex), searchItem, ...header.slice(insertIndex)]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private headerAppend(searchItem: any, float: string = "") {
|
|
88
|
+
const header = this.webeditor.header || []
|
|
89
|
+
const insertIndex = header.findIndex(item => item.float === float)
|
|
90
|
+
return insertIndex === -1
|
|
91
|
+
? [...header, searchItem]
|
|
92
|
+
: [...header.slice(0, insertIndex + 1), searchItem, ...header.slice(insertIndex + 1)]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private update(patch: DeepPartial<ThemeSettings>) {
|
|
96
|
+
deepMerge(this.theme, patch)
|
|
97
|
+
this.appearanceWebEditor()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private updateThemePreset(patch: string[]) {
|
|
101
|
+
this.update({
|
|
102
|
+
appearance: {
|
|
103
|
+
presets: [
|
|
104
|
+
...(this.settings.appearance?.presets || []),
|
|
105
|
+
...(patch || [])
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private appearanceWebEditor() {
|
|
112
|
+
if (!this.theme.appearance) {
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.resetWebeditor()
|
|
117
|
+
this.resetNavigation()
|
|
118
|
+
|
|
119
|
+
const searchAppearance = this.theme.appearance?.search?.sidebar || this.theme.appearance?.search?.middle
|
|
120
|
+
if (searchAppearance) {
|
|
121
|
+
const hasSearch = this.webeditor.header?.find(item => item.component === "Search")
|
|
122
|
+
|
|
123
|
+
if (hasSearch) {
|
|
124
|
+
console.warn("Search already exists in webeditor.header")
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (this.theme.appearance?.search?.sidebar) {
|
|
129
|
+
const search: WebEditorNavigationItem = {
|
|
130
|
+
component: "Search",
|
|
131
|
+
mobile: this.theme.appearance?.search?.sidebar === "mobile" || undefined,
|
|
132
|
+
desktop: this.theme.appearance?.search?.sidebar === "desktop" || undefined
|
|
133
|
+
}
|
|
134
|
+
if (!this.webeditor.sidebarTop) {
|
|
135
|
+
this.webeditor.sidebarTop = []
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this.webeditor.sidebarTop?.unshift({
|
|
139
|
+
...search,
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (this.theme.appearance?.search?.middle) {
|
|
144
|
+
const search: WebEditorNavigationItem = {
|
|
145
|
+
component: "Search",
|
|
146
|
+
mobile: this.theme.appearance?.search?.middle === "mobile" || undefined,
|
|
147
|
+
desktop: this.theme.appearance?.search?.middle === "desktop" || undefined
|
|
148
|
+
}
|
|
149
|
+
const searchItem = {
|
|
150
|
+
...search,
|
|
151
|
+
float: "center" as const
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.webeditor.header = this.headerPrepend(searchItem, "center")
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (
|
|
159
|
+
this.theme.appearance?.sidebar?.scrollbarColor &&
|
|
160
|
+
!this.theme.appearance?.sidebar?.scrollbar
|
|
161
|
+
) {
|
|
162
|
+
this.theme.appearance.sidebar.scrollbar = "secondary"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (this.theme.appearance?.logo?.sidebar) {
|
|
166
|
+
const logo: WebEditorNavigationItem = {
|
|
167
|
+
component: "Logo",
|
|
168
|
+
mobile: this.theme.appearance?.logo?.sidebar === "mobile" || undefined,
|
|
169
|
+
desktop: this.theme.appearance?.logo?.sidebar === "desktop" || undefined
|
|
170
|
+
}
|
|
171
|
+
if (!this.webeditor.sidebarTop) {
|
|
172
|
+
this.webeditor.sidebarTop = []
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// this.webeditor.sidebarTop = [
|
|
176
|
+
// logo,
|
|
177
|
+
// ...(this.originalWebeditor.sidebarTop || []),
|
|
178
|
+
// ]
|
|
179
|
+
|
|
180
|
+
this.webeditor.sidebarTop?.unshift(logo)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (
|
|
184
|
+
this.theme.appearance?.tabs?.surface === "center" &&
|
|
185
|
+
this.navigation?.tabs?.length
|
|
186
|
+
) {
|
|
187
|
+
this.insertCenterHeaderTabs()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (
|
|
191
|
+
this.navigation?.tabs?.length &&
|
|
192
|
+
this.navigation?.segments?.length && // cuz segments defaults are inside subnav
|
|
193
|
+
this.theme.appearance?.tabs?.surface !== "center") {
|
|
194
|
+
|
|
195
|
+
this.navigation.segments = this.navigation.segments.map(segment => {
|
|
196
|
+
if (segment.appearance !== "sidebarDropdown") {
|
|
197
|
+
segment.appearance = "sidebarDropdown"
|
|
198
|
+
}
|
|
199
|
+
return segment
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (this.navigation?.anchors?.header?.length) {
|
|
204
|
+
this.navigation?.anchors?.header.forEach(item => {
|
|
205
|
+
const button = {
|
|
206
|
+
...item,
|
|
207
|
+
component: "Button",
|
|
208
|
+
props: {},
|
|
209
|
+
float: "right" as const,
|
|
210
|
+
desktop: true,
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if ("button" in item) {
|
|
214
|
+
this.webeditor.header = this.headerAppend({
|
|
215
|
+
...button,
|
|
216
|
+
props: {
|
|
217
|
+
kind: item.button,
|
|
218
|
+
children: item.title,
|
|
219
|
+
size: this.theme.appearance?.header?.buttonSize || "md"
|
|
220
|
+
},
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if ("social" in item) {
|
|
227
|
+
this.webeditor.header = this.headerAppend({
|
|
228
|
+
...button,
|
|
229
|
+
icon: <IconSocial kind={item.social as any} />,
|
|
230
|
+
props: {
|
|
231
|
+
theme: "ghost",
|
|
232
|
+
icon: <IconSocial kind={item.social as any} />,
|
|
233
|
+
},
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (item.icon) {
|
|
240
|
+
this.webeditor.header = this.headerAppend({
|
|
241
|
+
...button,
|
|
242
|
+
props: {
|
|
243
|
+
theme: "ghost",
|
|
244
|
+
icon: item.icon,
|
|
245
|
+
},
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
return
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
this.webeditor.header = this.headerAppend({
|
|
252
|
+
...item,
|
|
253
|
+
float: "right" as const,
|
|
254
|
+
desktop: true,
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// TODO: in the future it should be in theme level
|
|
260
|
+
if (this.theme.name === "gusto") {
|
|
261
|
+
if (this.navigation?.tabs?.length) {
|
|
262
|
+
this.navigation.sidebarDropdown = this.navigation.tabs
|
|
263
|
+
|
|
264
|
+
// this.navigation.tabs.map(tab => {
|
|
265
|
+
// this.webeditor.sidebarTop = this.headerAppend({
|
|
266
|
+
// ...tab,
|
|
267
|
+
// })
|
|
268
|
+
// })
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private mergeUserAppearance() {
|
|
274
|
+
const update: DeepPartial<ThemeSettings> = {
|
|
275
|
+
appearance: this.userAppearance
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (this.originalTheme.coder) {
|
|
279
|
+
update.coder = this.originalTheme.coder
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
this.update(update)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private resetWebeditor() {
|
|
286
|
+
for (const key in this.webeditor) {
|
|
287
|
+
this.webeditor[key] = this.originalWebeditor[key] || []
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private resetNavigation() {
|
|
292
|
+
for (const key in this.navigation) {
|
|
293
|
+
this.navigation[key] = this.originalNavigation[key] || []
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
private insertCenterHeaderTabs() {
|
|
298
|
+
const tabsWithFloat = this.navigation?.tabs?.map(item => ({
|
|
299
|
+
...item,
|
|
300
|
+
float: "center" as const
|
|
301
|
+
})) ?? []
|
|
302
|
+
|
|
303
|
+
const searchIndex = this.webeditor.header?.findIndex(item => item.component === "Search") ?? -1
|
|
304
|
+
const currentHeader = this.webeditor.header ?? []
|
|
305
|
+
|
|
306
|
+
if (searchIndex !== -1) {
|
|
307
|
+
// Insert tabs after Search component
|
|
308
|
+
this.webeditor.header = [
|
|
309
|
+
...currentHeader.slice(0, searchIndex + 1),
|
|
310
|
+
...tabsWithFloat,
|
|
311
|
+
...currentHeader.slice(searchIndex + 1)
|
|
312
|
+
]
|
|
313
|
+
} else {
|
|
314
|
+
// If no Search component, insert at the beginning
|
|
315
|
+
this.webeditor.header = [
|
|
316
|
+
...tabsWithFloat,
|
|
317
|
+
...currentHeader
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// ─── DeepPartial Type ─────────────────────────────────────────
|
|
324
|
+
|
|
325
|
+
type DeepPartial<T> = {
|
|
326
|
+
[P in keyof T]?: T[P] extends object
|
|
327
|
+
? T[P] extends Function
|
|
328
|
+
? T[P]
|
|
329
|
+
: T[P] extends Array<infer U>
|
|
330
|
+
? Array<DeepPartial<U>>
|
|
331
|
+
: DeepPartial<T[P]>
|
|
332
|
+
: T[P]
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ─── CustomTheme Type ─────────────────────────────────────────
|
|
336
|
+
|
|
337
|
+
type CustomTheme<T> = T & {
|
|
338
|
+
Update: (value: DeepPartial<T>) => void
|
|
339
|
+
UpdatePreset: (value: string[]) => void
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// ─── Deep Merge Helper ────────────────────────────────────────
|
|
343
|
+
|
|
344
|
+
function deepMerge<T>(target: T, source: DeepPartial<T>): T {
|
|
345
|
+
for (const key in source) {
|
|
346
|
+
const sourceVal = source[key]
|
|
347
|
+
const targetVal = target[key]
|
|
348
|
+
|
|
349
|
+
if (
|
|
350
|
+
sourceVal &&
|
|
351
|
+
typeof sourceVal === "object" &&
|
|
352
|
+
!Array.isArray(sourceVal) &&
|
|
353
|
+
typeof targetVal === "object" &&
|
|
354
|
+
targetVal !== null
|
|
355
|
+
) {
|
|
356
|
+
target[key] = deepMerge(targetVal, sourceVal)
|
|
357
|
+
} else if (sourceVal !== undefined) {
|
|
358
|
+
target[key] = sourceVal as any
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return target
|
|
363
|
+
}
|
package/src/context.tsx
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a Rollup plugin to copy presets directory from src to dist
|
|
6
|
+
* @param options - Plugin options
|
|
7
|
+
* @param options.srcDir - Source directory (default: 'src/presets')
|
|
8
|
+
* @param options.distDir - Destination directory (default: 'dist/presets')
|
|
9
|
+
* @param options.packageRoot - Package root directory (default: process.cwd())
|
|
10
|
+
* @returns Rollup plugin
|
|
11
|
+
*/
|
|
12
|
+
export function copyPresetsPlugin(options: {
|
|
13
|
+
srcDir?: string;
|
|
14
|
+
distDir?: string;
|
|
15
|
+
packageRoot?: string;
|
|
16
|
+
} = {}) {
|
|
17
|
+
const {
|
|
18
|
+
srcDir = 'src/presets',
|
|
19
|
+
distDir = 'dist/presets',
|
|
20
|
+
packageRoot = process.cwd()
|
|
21
|
+
} = options;
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
name: 'copy-presets',
|
|
25
|
+
writeBundle() {
|
|
26
|
+
const srcPresetsPath = path.join(packageRoot, srcDir);
|
|
27
|
+
const distPresetsPath = path.join(packageRoot, distDir);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Check if src/presets exists
|
|
31
|
+
if (!fs.existsSync(srcPresetsPath)) {
|
|
32
|
+
console.log(`${srcDir} directory does not exist, skipping copy`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Copy presets directory recursively
|
|
37
|
+
function copyDir(src: string, dest: string) {
|
|
38
|
+
if (!fs.existsSync(dest)) {
|
|
39
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const items = fs.readdirSync(src);
|
|
43
|
+
for (const item of items) {
|
|
44
|
+
const srcPath = path.join(src, item);
|
|
45
|
+
const destPath = path.join(dest, item);
|
|
46
|
+
|
|
47
|
+
const stat = fs.statSync(srcPath);
|
|
48
|
+
if (stat.isDirectory()) {
|
|
49
|
+
copyDir(srcPath, destPath);
|
|
50
|
+
} else {
|
|
51
|
+
fs.copyFileSync(srcPath, destPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
copyDir(srcPresetsPath, distPresetsPath);
|
|
57
|
+
console.log(`✅ Successfully copied ${srcDir} to ${distDir}`);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error(`❌ Error copying presets:`, error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates a tsup plugin to copy presets directory
|
|
67
|
+
* @param options - Plugin options
|
|
68
|
+
* @param options.srcDir - Source directory (default: 'src/presets')
|
|
69
|
+
* @param options.distDir - Destination directory (default: 'dist/presets')
|
|
70
|
+
* @param options.packageRoot - Package root directory (default: process.cwd())
|
|
71
|
+
* @returns tsup plugin function
|
|
72
|
+
*/
|
|
73
|
+
export function tsupCopyPresetsPlugin(options: {
|
|
74
|
+
srcDir?: string;
|
|
75
|
+
distDir?: string;
|
|
76
|
+
packageRoot?: string;
|
|
77
|
+
} = {}) {
|
|
78
|
+
const {
|
|
79
|
+
srcDir = 'src/presets',
|
|
80
|
+
distDir = 'dist/presets',
|
|
81
|
+
packageRoot = process.cwd()
|
|
82
|
+
} = options;
|
|
83
|
+
|
|
84
|
+
return () => ({
|
|
85
|
+
name: 'copy-presets',
|
|
86
|
+
closeBundle() {
|
|
87
|
+
const srcPresetsPath = path.join(packageRoot, srcDir);
|
|
88
|
+
const distPresetsPath = path.join(packageRoot, distDir);
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
// Check if src/presets exists
|
|
92
|
+
if (!fs.existsSync(srcPresetsPath)) {
|
|
93
|
+
console.log(`${srcDir} directory does not exist, skipping copy`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Copy presets directory recursively
|
|
98
|
+
function copyDir(src: string, dest: string) {
|
|
99
|
+
if (!fs.existsSync(dest)) {
|
|
100
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const items = fs.readdirSync(src);
|
|
104
|
+
for (const item of items) {
|
|
105
|
+
const srcPath = path.join(src, item);
|
|
106
|
+
const destPath = path.join(dest, item);
|
|
107
|
+
|
|
108
|
+
const stat = fs.statSync(srcPath);
|
|
109
|
+
if (stat.isDirectory()) {
|
|
110
|
+
copyDir(srcPath, destPath);
|
|
111
|
+
} else {
|
|
112
|
+
fs.copyFileSync(srcPath, destPath);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
copyDir(srcPresetsPath, distPresetsPath);
|
|
118
|
+
console.log(`✅ Successfully copied ${srcDir} to ${distDir}`);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error(`❌ Error copying presets:`, error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
package/src/index.ts
ADDED
package/src/rollup.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {createRequire} from "module";
|
|
2
|
+
|
|
3
|
+
import resolve from '@rollup/plugin-node-resolve';
|
|
4
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
5
|
+
import typescript from '@rollup/plugin-typescript';
|
|
6
|
+
import dts from 'rollup-plugin-dts';
|
|
7
|
+
import postcss from 'rollup-plugin-postcss';
|
|
8
|
+
import postcssImport from 'postcss-import';
|
|
9
|
+
import postcssMixins from 'postcss-mixins';
|
|
10
|
+
import wyw from '@wyw-in-js/rollup';
|
|
11
|
+
|
|
12
|
+
import {copyPresetsPlugin} from './copyPresetsPlugin';
|
|
13
|
+
|
|
14
|
+
export default function (importPath: string) {
|
|
15
|
+
const require = createRequire(importPath);
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
dependencies,
|
|
19
|
+
peerDependencies,
|
|
20
|
+
devDependencies
|
|
21
|
+
} = require('./package.json');
|
|
22
|
+
|
|
23
|
+
const external = [
|
|
24
|
+
...Object.keys(dependencies),
|
|
25
|
+
...Object.keys(peerDependencies),
|
|
26
|
+
...Object.keys(devDependencies),
|
|
27
|
+
"@xyd-js/framework/react",
|
|
28
|
+
"@xyd-js/components/brand",
|
|
29
|
+
"@xyd-js/components/coder",
|
|
30
|
+
"@xyd-js/components/content",
|
|
31
|
+
"@xyd-js/components/layouts",
|
|
32
|
+
"@xyd-js/components/pages",
|
|
33
|
+
"@xyd-js/components/views",
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
return [
|
|
37
|
+
{
|
|
38
|
+
input: {
|
|
39
|
+
index: './src/index.ts'
|
|
40
|
+
},
|
|
41
|
+
output: [
|
|
42
|
+
{
|
|
43
|
+
dir: 'dist',
|
|
44
|
+
format: 'esm',
|
|
45
|
+
sourcemap: true,
|
|
46
|
+
entryFileNames: '[name].js'
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
plugins: [
|
|
50
|
+
wyw({
|
|
51
|
+
include: ['**/*.{ts,tsx}'],
|
|
52
|
+
babelOptions: {
|
|
53
|
+
presets: [
|
|
54
|
+
'@babel/preset-typescript',
|
|
55
|
+
'@babel/preset-react'
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
resolve(),
|
|
60
|
+
commonjs(),
|
|
61
|
+
typescript({
|
|
62
|
+
tsconfig: './tsconfig.json',
|
|
63
|
+
}),
|
|
64
|
+
postcss({
|
|
65
|
+
extensions: ['.css'],
|
|
66
|
+
plugins: [postcssImport(), postcssMixins()],
|
|
67
|
+
extract: true, // Extract CSS into a separate file
|
|
68
|
+
minimize: true, // Minify the CSS
|
|
69
|
+
}),
|
|
70
|
+
copyPresetsPlugin(),
|
|
71
|
+
],
|
|
72
|
+
external
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
input: './src/index.ts',
|
|
76
|
+
output: {
|
|
77
|
+
file: 'dist/index.d.ts',
|
|
78
|
+
format: 'es',
|
|
79
|
+
},
|
|
80
|
+
plugins: [
|
|
81
|
+
dts({
|
|
82
|
+
respectExternal: true, // Ignore unresolved imports
|
|
83
|
+
}),
|
|
84
|
+
],
|
|
85
|
+
external: [
|
|
86
|
+
...external,
|
|
87
|
+
/\.css$/ // Mark CSS imports as external
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* Atlas */
|
|
2
|
+
:root {
|
|
3
|
+
--XydAtlas-Ref-Palette-White: var(--white);
|
|
4
|
+
--XydAtlas-Ref-Palette-Primary-60: var(--color-primary);
|
|
5
|
+
--XydAtlas-Ref-Palette-Primary-70: var(--color-primary--active);
|
|
6
|
+
--XydAtlas-Ref-Palette-Primary-80: var(--color-primary--active);
|
|
7
|
+
|
|
8
|
+
--XydAtlas-Ref-Palette-Neutral-10: var(--dark8);
|
|
9
|
+
--XydAtlas-Ref-Palette-Neutral-20: var(--dark16);
|
|
10
|
+
--XydAtlas-Ref-Palette-Neutral-30: var(--dark32);
|
|
11
|
+
--XydAtlas-Ref-Palette-Neutral-40: var(--dark40);
|
|
12
|
+
--XydAtlas-Ref-Palette-Neutral-70: var(--dark48);
|
|
13
|
+
--XydAtlas-Ref-Palette-Neutral-80: var(--dark60);
|
|
14
|
+
--XydAtlas-Ref-Palette-Neutral-100: var(--dark80);
|
|
15
|
+
|
|
16
|
+
--XydAtlas-Sys-Color-Text-Primary: var(--color-text);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@define-mixin dark-theme {
|
|
20
|
+
--XydAtlas-Ref-Palette-Primary-60: var(--color-text);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[data-color-scheme="dark"] {
|
|
24
|
+
@mixin dark-theme;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* System dark mode support for sidebar - only when OS preference is enabled */
|
|
28
|
+
@media (prefers-color-scheme: dark) {
|
|
29
|
+
:root:not([data-color-scheme="light"]):not([data-color-scheme="dark"]) {
|
|
30
|
+
@mixin dark-theme;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@layer decorators {
|
|
2
|
+
xyd-layout-primary {
|
|
3
|
+
/* tag: Header */
|
|
4
|
+
header {
|
|
5
|
+
[part="header-content"] {
|
|
6
|
+
border-bottom: 1px solid var(--decorator-sketch-border-color);
|
|
7
|
+
border-top: 1px solid var(--decorator-sketch-border-color);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* component: Sidebar */
|
|
12
|
+
xyd-sidebar {
|
|
13
|
+
border-radius: 0;
|
|
14
|
+
border-right: 0.5px solid var(--decorator-sketch-border-color);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* component: SubNav */
|
|
18
|
+
xyd-subnav {
|
|
19
|
+
border-bottom: 1px solid var(--decorator-sketch-border-color);
|
|
20
|
+
border-radius: 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|