@zpress/ui 0.4.1 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Paths } from '@zpress/core';
2
2
  import type { RspressPlugin } from '@rspress/core';
3
3
  import type { UserConfig } from '@rspress/core';
4
- import type { ZpressConfig } from '@zpress/core';
4
+ import type { ZpressConfig } from '@zpress/config';
5
5
 
6
6
  /**
7
7
  * Translate zpress config + sync engine output into a complete
package/dist/index.mjs CHANGED
@@ -1,7 +1,22 @@
1
1
  import { execSync } from "node:child_process";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import node_path from "node:path";
4
- import { resolveDefaultColorMode } from "@zpress/core";
4
+ import { isBuiltInTheme, resolveDefaultColorMode } from "@zpress/theme";
5
+ const BASE_CRITICAL_CSS = ":root{--zp-c-brand-1:#a78bfa;--zp-c-brand-2:#8b5cf6;--zp-c-brand-3:#7c3aed;--zp-c-brand-soft:rgba(167,139,250,0.14);--zp-c-bg:#ffffff;--zp-c-bg-alt:#f9f9f9;--zp-c-bg-elv:#f5f5f5;--zp-c-bg-soft:#f0f0f0;--zp-c-bg-icon:#cccccc;--zp-c-text-1:#1a1a1a;--zp-c-text-2:rgba(26,26,26,0.72);--zp-c-text-3:rgba(26,26,26,0.48);--zp-c-divider:#e2e2e2;--zp-c-border:#d0d0d0;--zp-c-gutter:#f5f5f5;--zp-code-block-bg:#f5f5f5;--zp-button-brand-bg:#7c3aed;--zp-button-brand-hover-bg:#8b5cf6;--zp-button-brand-active-bg:#6d28d9;--zp-button-brand-text:#ffffff;--rp-c-brand:#a78bfa;--rp-c-brand-light:#c4b5fd;--rp-c-brand-lighter:#ddd6fe;--rp-c-brand-dark:#8b5cf6;--rp-c-brand-darker:#7c3aed;--rp-c-brand-tint:rgba(167,139,250,0.14);--rp-home-background-bg:#fff;--rp-c-bg:#ffffff;--rp-c-bg-soft:#f0f0f0;--rp-c-text-1:#1a1a1a;--rp-c-text-2:rgba(26,26,26,0.72);--rp-c-text-3:rgba(26,26,26,0.48);--rp-c-divider:#e2e2e2}html,body{background-color:var(--zp-c-bg);color:var(--zp-c-text-1)}";
6
+ const MIDNIGHT_CRITICAL_CSS = ":root{--zp-c-brand-1:#60a5fa;--zp-c-brand-2:#3b82f6;--zp-c-brand-3:#2563eb;--zp-c-brand-soft:rgba(96,165,250,0.14);--zp-c-bg:#0a0e1a;--zp-c-bg-alt:#0d1120;--zp-c-bg-elv:#111523;--zp-c-bg-soft:#141829;--zp-c-bg-icon:#2d3548;--zp-c-text-1:#e8edf5;--zp-c-text-2:rgba(232,237,245,0.72);--zp-c-text-3:rgba(232,237,245,0.48);--zp-c-divider:#1a1f2e;--zp-c-border:#252a3a;--zp-c-gutter:#0d1120;--zp-code-block-bg:#0d1120;--zp-button-brand-bg:#2563eb;--zp-button-brand-hover-bg:#3b82f6;--zp-button-brand-active-bg:#1d4ed8;--zp-button-brand-text:#e8edf5;--rp-c-brand:#60a5fa;--rp-c-brand-light:#93c5fd;--rp-c-brand-lighter:#bfdbfe;--rp-c-brand-dark:#3b82f6;--rp-c-brand-darker:#2563eb;--rp-c-brand-tint:rgba(96,165,250,0.14);--rp-home-background-bg:#0a0e1a;--rp-c-bg:#0a0e1a;--rp-c-bg-soft:#141829;--rp-c-text-1:#e8edf5;--rp-c-text-2:rgba(232,237,245,0.72);--rp-c-text-3:rgba(232,237,245,0.48);--rp-c-divider:#1a1f2e}html,body{background-color:var(--zp-c-bg);color:var(--zp-c-text-1)}";
7
+ const ARCADE_CRITICAL_CSS = ":root{--zp-c-brand-1:#f472b6;--zp-c-brand-2:#ec4899;--zp-c-brand-3:#db2777;--zp-c-brand-soft:rgba(244,114,182,0.14);--zp-c-bg:#fef7fb;--zp-c-bg-alt:#fef3f9;--zp-c-bg-elv:#fdeef7;--zp-c-bg-soft:#fce9f4;--zp-c-bg-icon:#f9d5ea;--zp-c-text-1:#1a0a14;--zp-c-text-2:rgba(26,10,20,0.72);--zp-c-text-3:rgba(26,10,20,0.48);--zp-c-divider:#fce0f0;--zp-c-border:#fad0e8;--zp-c-gutter:#fef3f9;--zp-code-block-bg:#fef3f9;--zp-button-brand-bg:#db2777;--zp-button-brand-hover-bg:#ec4899;--zp-button-brand-active-bg:#be185d;--zp-button-brand-text:#fef7fb;--rp-c-brand:#f472b6;--rp-c-brand-light:#f9a8d4;--rp-c-brand-lighter:#fbcfe8;--rp-c-brand-dark:#ec4899;--rp-c-brand-darker:#db2777;--rp-c-brand-tint:rgba(244,114,182,0.14);--rp-home-background-bg:#fef7fb;--rp-c-bg:#fef7fb;--rp-c-bg-soft:#fce9f4;--rp-c-text-1:#1a0a14;--rp-c-text-2:rgba(26,10,20,0.72);--rp-c-text-3:rgba(26,10,20,0.48);--rp-c-divider:#fce0f0}html,body{background-color:var(--zp-c-bg);color:var(--zp-c-text-1)}";
8
+ const CRITICAL_CSS_MAP = {
9
+ base: BASE_CRITICAL_CSS,
10
+ midnight: MIDNIGHT_CRITICAL_CSS,
11
+ arcade: ARCADE_CRITICAL_CSS,
12
+ 'arcade-fx': ARCADE_CRITICAL_CSS
13
+ };
14
+ function getCriticalCss(themeName) {
15
+ const theme = themeName;
16
+ const css = CRITICAL_CSS_MAP[theme];
17
+ if (!css) return '';
18
+ return css;
19
+ }
5
20
  function zpressPlugin() {
6
21
  const componentsDir = node_path.resolve(import.meta.dirname, 'theme', 'components');
7
22
  return {
@@ -35,7 +50,8 @@ function resolveThemeName(config) {
35
50
  }
36
51
  function resolveColorMode(config, themeName) {
37
52
  if (config.theme && config.theme.colorMode) return config.theme.colorMode;
38
- return resolveDefaultColorMode(themeName);
53
+ if (isBuiltInTheme(themeName)) return resolveDefaultColorMode(themeName);
54
+ return 'toggle';
39
55
  }
40
56
  function resolveThemeSwitcher(config) {
41
57
  if (config.theme && config.theme.switcher) return config.theme.switcher;
@@ -60,6 +76,13 @@ function createRspressConfig(options) {
60
76
  const themeSwitcher = resolveThemeSwitcher(config);
61
77
  const themeColors = resolveThemeColors(config);
62
78
  const themeDarkColors = resolveThemeDarkColors(config);
79
+ const criticalCss = getCriticalCss(themeName);
80
+ const headElements = (()=>{
81
+ if (criticalCss) return [
82
+ `<style data-zpress-critical>${criticalCss}</style>`
83
+ ];
84
+ return [];
85
+ })();
63
86
  return {
64
87
  root: paths.contentDir,
65
88
  outDir: paths.distDir,
@@ -76,6 +99,7 @@ function createRspressConfig(options) {
76
99
  plugins: [
77
100
  zpressPlugin()
78
101
  ],
102
+ head: headElements,
79
103
  builderConfig: {
80
104
  ...(()=>{
81
105
  if (logLevel) return {
@@ -1,13 +1,11 @@
1
+ import type { IconColor } from '@zpress/config'
1
2
  import type React from 'react'
2
3
  import { match, P } from 'ts-pattern'
3
4
 
4
5
  import './feature-card.css'
5
6
  import { Card } from '../shared/card'
6
7
 
7
- /**
8
- * Icon color variants matching the design system.
9
- */
10
- export type IconColor = 'purple' | 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'cyan' | 'pink'
8
+ export type { IconColor } from '@zpress/config'
11
9
 
12
10
  export interface FeatureCardProps {
13
11
  readonly title: string
@@ -37,8 +37,8 @@ function renderGroup(group: WorkspaceGroupData): React.ReactElement {
37
37
  <WorkspaceGrid key={group.heading} heading={group.heading} description={group.description}>
38
38
  {group.cards.map((card, i) => (
39
39
  <WorkspaceCard
40
- key={`${card.text}-${i}`}
41
- text={card.text}
40
+ key={`${card.title}-${i}`}
41
+ title={card.title}
42
42
  href={card.href}
43
43
  icon={card.icon}
44
44
  iconColor={card.iconColor}
@@ -6,20 +6,57 @@ import { BranchTag } from './branch-tag'
6
6
  import { ThemeSwitcher } from './theme-switcher'
7
7
  import { VscodeTag } from './vscode-tag'
8
8
 
9
- const VSCODE_OVERRIDES = [
10
- /* Hide left sidebar and its placeholder */
11
- '.rp-doc-layout__sidebar { display: none !important; }',
12
- '.rp-doc-layout__sidebar-placeholder { display: none !important; }',
13
- /* Hide right TOC and its placeholder */
14
- '.rp-doc-layout__outline { display: none !important; }',
15
- '.rp-doc-layout__outline-placeholder { display: none !important; }',
16
- /* Center content at 1200px max */
17
- '.rp-doc-layout__doc { max-width: 1200px !important; margin: 0 auto !important; }',
18
- /* Hide nav items, social links, hamburger */
19
- '.rp-nav-menu__item { display: none !important; }',
20
- '.rp-social-links { display: none !important; }',
21
- '.rp-nav-hamburger { display: none !important; }',
22
- ].join('\n')
9
+ const VSCODE_OVERRIDES = `
10
+ /* Hide left sidebar and its placeholder */
11
+ html[data-zpress-env="vscode"] .rp-doc-layout__sidebar {
12
+ display: none;
13
+ }
14
+ html[data-zpress-env="vscode"] .rp-doc-layout__sidebar-placeholder {
15
+ display: none;
16
+ }
17
+
18
+ /* Hide right TOC and its placeholder */
19
+ html[data-zpress-env="vscode"] .rp-doc-layout__outline {
20
+ display: none;
21
+ }
22
+ html[data-zpress-env="vscode"] .rp-doc-layout__outline-placeholder {
23
+ display: none;
24
+ }
25
+
26
+ /* Center content at 1200px max */
27
+ html[data-zpress-env="vscode"] .rp-doc-layout__doc {
28
+ max-width: 1200px;
29
+ margin: 0 auto;
30
+ }
31
+
32
+ /* Hide nav items, social links, hamburger */
33
+ html[data-zpress-env="vscode"] .rp-nav-menu__item {
34
+ display: none;
35
+ }
36
+ html[data-zpress-env="vscode"] .rp-social-links {
37
+ display: none;
38
+ }
39
+ html[data-zpress-env="vscode"] .rp-nav-hamburger {
40
+ display: none;
41
+ }
42
+
43
+ /* Hide mobile navigation elements */
44
+ html[data-zpress-env="vscode"] .rp-nav-screen {
45
+ display: none;
46
+ }
47
+ html[data-zpress-env="vscode"] .rp-nav-screen-menu {
48
+ display: none;
49
+ }
50
+ html[data-zpress-env="vscode"] .rp-local-nav {
51
+ display: none;
52
+ }
53
+ html[data-zpress-env="vscode"] .rp-appearance {
54
+ display: none;
55
+ }
56
+ html[data-zpress-env="vscode"] .rp-doc-layout__menu {
57
+ display: none;
58
+ }
59
+ `
23
60
 
24
61
  function useVscodeMode(): boolean {
25
62
  const [active, setActive] = useState(false)
@@ -17,6 +17,7 @@ const THEME_OPTIONS: readonly ThemeOption[] = [
17
17
  { name: 'base', label: 'Base', swatch: '#a78bfa', defaultColorMode: 'toggle' },
18
18
  { name: 'midnight', label: 'Midnight', swatch: '#60a5fa', defaultColorMode: 'dark' },
19
19
  { name: 'arcade', label: 'Arcade', swatch: '#00ff88', defaultColorMode: 'dark' },
20
+ { name: 'arcade-fx', label: 'Arcade FX', swatch: '#ff00ff', defaultColorMode: 'dark' },
20
21
  ]
21
22
 
22
23
  /**
@@ -1,7 +1,7 @@
1
+ import type { IconColor } from '@zpress/config'
1
2
  import type React from 'react'
2
3
  import { match, P } from 'ts-pattern'
3
4
 
4
- import type { IconColor } from '../home/feature-card'
5
5
  import { Card } from '../shared/card'
6
6
  import { Icon } from '../shared/icon'
7
7
  import { TechTag } from '../shared/tech-tag'
@@ -12,7 +12,7 @@ export interface WorkspaceCardProps {
12
12
  /**
13
13
  * Display name for the card header.
14
14
  */
15
- readonly text: string
15
+ readonly title: string
16
16
  /**
17
17
  * Link target (e.g. "/apps/api").
18
18
  */
@@ -50,7 +50,7 @@ export interface WorkspaceCardProps {
50
50
  * description, tech tags, and optional deploy badge.
51
51
  */
52
52
  export function WorkspaceCard({
53
- text,
53
+ title,
54
54
  href,
55
55
  icon,
56
56
  iconColor = 'purple',
@@ -59,7 +59,7 @@ export function WorkspaceCard({
59
59
  tags,
60
60
  badge,
61
61
  }: WorkspaceCardProps): React.ReactElement {
62
- const name = text.toLowerCase()
62
+ const name = title.toLowerCase()
63
63
 
64
64
  const iconEl = match(icon)
65
65
  .with(P.nonNullable, (id) => <Icon icon={id} />)
@@ -1,6 +1,5 @@
1
1
  import { useSite } from '@rspress/core/runtime'
2
-
3
- import type { IconColor } from '../components/home/feature-card'
2
+ import type { IconColor } from '@zpress/config'
4
3
 
5
4
  // ── Sidebar types ───────────────────────────────────────────
6
5
 
@@ -14,7 +13,7 @@ export interface ZpressSidebarItem {
14
13
  // ── Workspace types ─────────────────────────────────────────
15
14
 
16
15
  export interface WorkspaceCardData {
17
- readonly text: string
16
+ readonly title: string
18
17
  readonly href: string
19
18
  readonly icon: string | undefined
20
19
  readonly iconColor: IconColor | undefined
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zpress/ui",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Rspress plugin, theme components, and styles for zpress",
5
5
  "keywords": [
6
6
  "react",
@@ -52,7 +52,9 @@
52
52
  "@iconify-json/vscode-icons": "^1.2.45",
53
53
  "@iconify/react": "^6.0.2",
54
54
  "ts-pattern": "^5.9.0",
55
- "@zpress/core": "0.5.0"
55
+ "@zpress/config": "0.2.0",
56
+ "@zpress/core": "0.6.0",
57
+ "@zpress/theme": "0.2.0"
56
58
  },
57
59
  "devDependencies": {
58
60
  "@rslib/core": "^0.20.0",
@@ -1,13 +1,11 @@
1
+ import type { IconColor } from '@zpress/config'
1
2
  import type React from 'react'
2
3
  import { match, P } from 'ts-pattern'
3
4
 
4
5
  import './feature-card.css'
5
6
  import { Card } from '../shared/card'
6
7
 
7
- /**
8
- * Icon color variants matching the design system.
9
- */
10
- export type IconColor = 'purple' | 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'cyan' | 'pink'
8
+ export type { IconColor } from '@zpress/config'
11
9
 
12
10
  export interface FeatureCardProps {
13
11
  readonly title: string
@@ -37,8 +37,8 @@ function renderGroup(group: WorkspaceGroupData): React.ReactElement {
37
37
  <WorkspaceGrid key={group.heading} heading={group.heading} description={group.description}>
38
38
  {group.cards.map((card, i) => (
39
39
  <WorkspaceCard
40
- key={`${card.text}-${i}`}
41
- text={card.text}
40
+ key={`${card.title}-${i}`}
41
+ title={card.title}
42
42
  href={card.href}
43
43
  icon={card.icon}
44
44
  iconColor={card.iconColor}
@@ -6,20 +6,57 @@ import { BranchTag } from './branch-tag'
6
6
  import { ThemeSwitcher } from './theme-switcher'
7
7
  import { VscodeTag } from './vscode-tag'
8
8
 
9
- const VSCODE_OVERRIDES = [
10
- /* Hide left sidebar and its placeholder */
11
- '.rp-doc-layout__sidebar { display: none !important; }',
12
- '.rp-doc-layout__sidebar-placeholder { display: none !important; }',
13
- /* Hide right TOC and its placeholder */
14
- '.rp-doc-layout__outline { display: none !important; }',
15
- '.rp-doc-layout__outline-placeholder { display: none !important; }',
16
- /* Center content at 1200px max */
17
- '.rp-doc-layout__doc { max-width: 1200px !important; margin: 0 auto !important; }',
18
- /* Hide nav items, social links, hamburger */
19
- '.rp-nav-menu__item { display: none !important; }',
20
- '.rp-social-links { display: none !important; }',
21
- '.rp-nav-hamburger { display: none !important; }',
22
- ].join('\n')
9
+ const VSCODE_OVERRIDES = `
10
+ /* Hide left sidebar and its placeholder */
11
+ html[data-zpress-env="vscode"] .rp-doc-layout__sidebar {
12
+ display: none;
13
+ }
14
+ html[data-zpress-env="vscode"] .rp-doc-layout__sidebar-placeholder {
15
+ display: none;
16
+ }
17
+
18
+ /* Hide right TOC and its placeholder */
19
+ html[data-zpress-env="vscode"] .rp-doc-layout__outline {
20
+ display: none;
21
+ }
22
+ html[data-zpress-env="vscode"] .rp-doc-layout__outline-placeholder {
23
+ display: none;
24
+ }
25
+
26
+ /* Center content at 1200px max */
27
+ html[data-zpress-env="vscode"] .rp-doc-layout__doc {
28
+ max-width: 1200px;
29
+ margin: 0 auto;
30
+ }
31
+
32
+ /* Hide nav items, social links, hamburger */
33
+ html[data-zpress-env="vscode"] .rp-nav-menu__item {
34
+ display: none;
35
+ }
36
+ html[data-zpress-env="vscode"] .rp-social-links {
37
+ display: none;
38
+ }
39
+ html[data-zpress-env="vscode"] .rp-nav-hamburger {
40
+ display: none;
41
+ }
42
+
43
+ /* Hide mobile navigation elements */
44
+ html[data-zpress-env="vscode"] .rp-nav-screen {
45
+ display: none;
46
+ }
47
+ html[data-zpress-env="vscode"] .rp-nav-screen-menu {
48
+ display: none;
49
+ }
50
+ html[data-zpress-env="vscode"] .rp-local-nav {
51
+ display: none;
52
+ }
53
+ html[data-zpress-env="vscode"] .rp-appearance {
54
+ display: none;
55
+ }
56
+ html[data-zpress-env="vscode"] .rp-doc-layout__menu {
57
+ display: none;
58
+ }
59
+ `
23
60
 
24
61
  function useVscodeMode(): boolean {
25
62
  const [active, setActive] = useState(false)
@@ -17,6 +17,7 @@ const THEME_OPTIONS: readonly ThemeOption[] = [
17
17
  { name: 'base', label: 'Base', swatch: '#a78bfa', defaultColorMode: 'toggle' },
18
18
  { name: 'midnight', label: 'Midnight', swatch: '#60a5fa', defaultColorMode: 'dark' },
19
19
  { name: 'arcade', label: 'Arcade', swatch: '#00ff88', defaultColorMode: 'dark' },
20
+ { name: 'arcade-fx', label: 'Arcade FX', swatch: '#ff00ff', defaultColorMode: 'dark' },
20
21
  ]
21
22
 
22
23
  /**
@@ -1,7 +1,7 @@
1
+ import type { IconColor } from '@zpress/config'
1
2
  import type React from 'react'
2
3
  import { match, P } from 'ts-pattern'
3
4
 
4
- import type { IconColor } from '../home/feature-card'
5
5
  import { Card } from '../shared/card'
6
6
  import { Icon } from '../shared/icon'
7
7
  import { TechTag } from '../shared/tech-tag'
@@ -12,7 +12,7 @@ export interface WorkspaceCardProps {
12
12
  /**
13
13
  * Display name for the card header.
14
14
  */
15
- readonly text: string
15
+ readonly title: string
16
16
  /**
17
17
  * Link target (e.g. "/apps/api").
18
18
  */
@@ -50,7 +50,7 @@ export interface WorkspaceCardProps {
50
50
  * description, tech tags, and optional deploy badge.
51
51
  */
52
52
  export function WorkspaceCard({
53
- text,
53
+ title,
54
54
  href,
55
55
  icon,
56
56
  iconColor = 'purple',
@@ -59,7 +59,7 @@ export function WorkspaceCard({
59
59
  tags,
60
60
  badge,
61
61
  }: WorkspaceCardProps): React.ReactElement {
62
- const name = text.toLowerCase()
62
+ const name = title.toLowerCase()
63
63
 
64
64
  const iconEl = match(icon)
65
65
  .with(P.nonNullable, (id) => <Icon icon={id} />)
@@ -1,6 +1,5 @@
1
1
  import { useSite } from '@rspress/core/runtime'
2
-
3
- import type { IconColor } from '../components/home/feature-card'
2
+ import type { IconColor } from '@zpress/config'
4
3
 
5
4
  // ── Sidebar types ───────────────────────────────────────────
6
5
 
@@ -14,7 +13,7 @@ export interface ZpressSidebarItem {
14
13
  // ── Workspace types ─────────────────────────────────────────
15
14
 
16
15
  export interface WorkspaceCardData {
17
- readonly text: string
16
+ readonly title: string
18
17
  readonly href: string
19
18
  readonly icon: string | undefined
20
19
  readonly iconColor: IconColor | undefined