@zpress/ui 0.2.1 → 0.3.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
@@ -19,8 +19,8 @@ declare interface CreateRspressConfigOptions {
19
19
  *
20
20
  * Global styles are loaded via the theme entry (theme/index.tsx)
21
21
  * CSS import — not through the plugin globalStyles property.
22
- * Custom UI components are registered here as globalUIComponents so
23
- * Rspress renders them on every page.
22
+ * Nav-level components (e.g. BranchTag) are injected via layout
23
+ * slot props in the custom Layout component, not globalUIComponents.
24
24
  */
25
25
  export declare function zpressPlugin(): RspressPlugin;
26
26
 
package/dist/index.mjs CHANGED
@@ -2,12 +2,8 @@ import { execSync } from "node:child_process";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import node_path from "node:path";
4
4
  function zpressPlugin() {
5
- const componentsDir = node_path.resolve(import.meta.dirname, 'theme', 'components');
6
5
  return {
7
- name: 'zpress',
8
- globalUIComponents: [
9
- node_path.resolve(componentsDir, 'nav', 'branch-tag.tsx')
10
- ]
6
+ name: 'zpress'
11
7
  };
12
8
  }
13
9
  function loadGenerated(contentDir, name, fallback) {
@@ -37,6 +33,9 @@ function createRspressConfig(options) {
37
33
  return {
38
34
  root: paths.contentDir,
39
35
  outDir: paths.distDir,
36
+ route: {
37
+ cleanUrls: true
38
+ },
40
39
  llms: true,
41
40
  title: config.title ?? 'zpress',
42
41
  description: config.description ?? 'Documentation',
@@ -10,7 +10,7 @@
10
10
  gap: var(--feature-grid-gap);
11
11
  max-width: 1152px;
12
12
  margin: 0 auto;
13
- padding: 0 0 64px;
13
+ padding: 0 16px 64px;
14
14
  }
15
15
 
16
16
  /* ── Grid item + span system ────────────────────────────────── */
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef } from 'react'
1
+ import type React from 'react'
2
2
 
3
3
  import './branch-tag.css'
4
4
  import { Icon } from '../shared/icon.tsx'
@@ -17,32 +17,12 @@ function resolveBranch(): string {
17
17
  }
18
18
 
19
19
  /**
20
- * Git branch tag — pill-shaped badge positioned in the nav bar.
21
- * Hidden when on `main` (production). Uses the pixelarticons:git-branch icon.
20
+ * Git branch tag — pill-shaped badge rendered via the `beforeNavMenu`
21
+ * layout slot. Hidden when on `main` (production).
22
+ * Uses the pixelarticons:git-branch icon.
22
23
  */
23
24
  export function BranchTag(): React.ReactElement | null {
24
25
  const branch = resolveBranch()
25
- const rootRef = useRef<HTMLAnchorElement>(null)
26
-
27
- useEffect(() => {
28
- if (!branch || branch === 'main' || !rootRef.current) {
29
- return
30
- }
31
-
32
- const node = rootRef.current
33
-
34
- // Relocate into the search container so it sits beside the search button.
35
- // No Rspress API exists for injecting into the nav bar, so direct DOM
36
- // manipulation is the only option for this placement.
37
- const searchContainer = document.querySelector('.rspress-nav-search')
38
- if (searchContainer) {
39
- searchContainer.append(node)
40
- }
41
-
42
- return () => {
43
- node.remove()
44
- }
45
- }, [branch])
46
26
 
47
27
  if (!branch || branch === 'main') {
48
28
  return null
@@ -51,7 +31,6 @@ export function BranchTag(): React.ReactElement | null {
51
31
  return (
52
32
  <a
53
33
  className="branch-tag"
54
- ref={rootRef}
55
34
  href={`https://github.com/joggrdocs/zpress/tree/${branch}`}
56
35
  target="_blank"
57
36
  rel="noopener noreferrer"
@@ -0,0 +1,14 @@
1
+ import { Layout as OriginalLayout } from '@rspress/core/theme-original'
2
+ import type React from 'react'
3
+
4
+ import { BranchTag } from './branch-tag'
5
+
6
+ /**
7
+ * Custom Layout override for zpress.
8
+ * Wraps the original Rspress Layout and injects the BranchTag
9
+ * into the `beforeNavMenu` slot so it renders before the search
10
+ * bar in the navbar on all page types.
11
+ */
12
+ export function Layout(): React.ReactElement {
13
+ return <OriginalLayout beforeNavMenu={<BranchTag />} />
14
+ }
@@ -7,7 +7,7 @@
7
7
  .workspace-section {
8
8
  max-width: 1152px;
9
9
  margin: 0 auto;
10
- padding: 0 0 64px;
10
+ padding: 0 16px 64px;
11
11
  }
12
12
 
13
13
  .workspace-section h2 {
@@ -23,6 +23,9 @@ import './styles/overrides/section-card.css'
23
23
  // (theme-original avoids circular resolution when used inside a themeDir)
24
24
  export * from '@rspress/core/theme-original'
25
25
 
26
+ // Layout override — inject zpress nav components via layout slots
27
+ export { Layout } from './components/nav/layout'
28
+
26
29
  // zpress components
27
30
  export { FeatureCard, FeatureGrid } from './components/home/feature-card'
28
31
  export type { FeatureCardProps, FeatureItem, IconColor } from './components/home/feature-card'
@@ -120,6 +120,7 @@
120
120
  .home-card-divider {
121
121
  max-width: 1152px;
122
122
  margin: 0 auto 48px;
123
+ padding: 0 16px;
123
124
  border: none;
124
125
  border-top: 1px solid var(--zp-c-divider);
125
126
  }
@@ -15,7 +15,7 @@ html .rp-home-hero__image-img {
15
15
  }
16
16
 
17
17
  /* ── Rspress home hero container ────────────────────────── */
18
- html .rp-home-hero {
18
+ html .rp-home-hero__container {
19
19
  gap: 16px !important;
20
20
  }
21
21
 
@@ -33,7 +33,15 @@ html .rp-home-hero__tagline {
33
33
  padding-bottom: 16px !important;
34
34
  }
35
35
 
36
+ html .rp-home-hero__actions {
37
+ gap: 1.25rem !important;
38
+ }
39
+
36
40
  @media (max-width: 1000px) {
41
+ html .rp-home-hero {
42
+ padding-bottom: 24px !important;
43
+ }
44
+
37
45
  html .rp-home-hero__image {
38
46
  width: 400px;
39
47
  margin-left: 0;
@@ -45,6 +53,42 @@ html .rp-home-hero__tagline {
45
53
  }
46
54
  }
47
55
 
56
+ /* ── Mobile overrides ────────────────────────────────────── */
57
+ @media (max-width: 768px) {
58
+ html .rp-home-hero__container {
59
+ gap: 8px !important;
60
+ }
61
+
62
+ html .rp-home-hero__image {
63
+ width: 100%;
64
+ max-width: 90vw !important;
65
+ margin-left: 0;
66
+ margin-top: 24px;
67
+ }
68
+
69
+ html .rp-home-hero__image-img {
70
+ width: 100%;
71
+ max-width: 90vw !important;
72
+ }
73
+
74
+ html .rp-home-hero__content {
75
+ padding: 0 8px;
76
+ }
77
+
78
+ html .rp-home-hero__name {
79
+ font-size: 1.125rem !important;
80
+ }
81
+
82
+ html .rp-home-hero__text {
83
+ font-size: 2rem !important;
84
+ }
85
+
86
+ html .rp-home-hero__tagline {
87
+ font-size: 1rem !important;
88
+ line-height: 1.5 !important;
89
+ }
90
+ }
91
+
48
92
  /* ── Code blocks ─────────────────────────────────────────── */
49
93
  div[class*='language-'] {
50
94
  border-radius: var(--rp-radius) !important;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zpress/ui",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Rspress plugin, theme components, and styles for zpress",
5
5
  "keywords": [
6
6
  "react",
@@ -43,18 +43,18 @@
43
43
  "dependencies": {
44
44
  "@iconify-json/catppuccin": "^1.2.17",
45
45
  "@iconify-json/devicon": "^1.2.59",
46
+ "@iconify-json/logos": "^1.2.10",
47
+ "@iconify-json/material-icon-theme": "^1.2.55",
46
48
  "@iconify-json/mdi": "^1.2.3",
47
49
  "@iconify-json/pixelarticons": "^1.2.4",
48
50
  "@iconify-json/simple-icons": "^1.2.73",
49
51
  "@iconify-json/skill-icons": "^1.2.4",
52
+ "@iconify-json/vscode-icons": "^1.2.45",
50
53
  "@iconify/react": "^6.0.2",
51
54
  "ts-pattern": "^5.9.0",
52
- "@zpress/core": "0.2.1"
55
+ "@zpress/core": "0.3.0"
53
56
  },
54
57
  "devDependencies": {
55
- "@iconify-json/logos": "^1.2.10",
56
- "@iconify-json/material-icon-theme": "^1.2.55",
57
- "@iconify-json/vscode-icons": "^1.2.45",
58
58
  "@rslib/core": "^0.20.0",
59
59
  "@rspress/core": "^2.0.5",
60
60
  "@types/react": "^19.2.14",
@@ -10,7 +10,7 @@
10
10
  gap: var(--feature-grid-gap);
11
11
  max-width: 1152px;
12
12
  margin: 0 auto;
13
- padding: 0 0 64px;
13
+ padding: 0 16px 64px;
14
14
  }
15
15
 
16
16
  /* ── Grid item + span system ────────────────────────────────── */
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef } from 'react'
1
+ import type React from 'react'
2
2
 
3
3
  import './branch-tag.css'
4
4
  import { Icon } from '../shared/icon.tsx'
@@ -17,32 +17,12 @@ function resolveBranch(): string {
17
17
  }
18
18
 
19
19
  /**
20
- * Git branch tag — pill-shaped badge positioned in the nav bar.
21
- * Hidden when on `main` (production). Uses the pixelarticons:git-branch icon.
20
+ * Git branch tag — pill-shaped badge rendered via the `beforeNavMenu`
21
+ * layout slot. Hidden when on `main` (production).
22
+ * Uses the pixelarticons:git-branch icon.
22
23
  */
23
24
  export function BranchTag(): React.ReactElement | null {
24
25
  const branch = resolveBranch()
25
- const rootRef = useRef<HTMLAnchorElement>(null)
26
-
27
- useEffect(() => {
28
- if (!branch || branch === 'main' || !rootRef.current) {
29
- return
30
- }
31
-
32
- const node = rootRef.current
33
-
34
- // Relocate into the search container so it sits beside the search button.
35
- // No Rspress API exists for injecting into the nav bar, so direct DOM
36
- // manipulation is the only option for this placement.
37
- const searchContainer = document.querySelector('.rspress-nav-search')
38
- if (searchContainer) {
39
- searchContainer.append(node)
40
- }
41
-
42
- return () => {
43
- node.remove()
44
- }
45
- }, [branch])
46
26
 
47
27
  if (!branch || branch === 'main') {
48
28
  return null
@@ -51,7 +31,6 @@ export function BranchTag(): React.ReactElement | null {
51
31
  return (
52
32
  <a
53
33
  className="branch-tag"
54
- ref={rootRef}
55
34
  href={`https://github.com/joggrdocs/zpress/tree/${branch}`}
56
35
  target="_blank"
57
36
  rel="noopener noreferrer"
@@ -0,0 +1,14 @@
1
+ import { Layout as OriginalLayout } from '@rspress/core/theme-original'
2
+ import type React from 'react'
3
+
4
+ import { BranchTag } from './branch-tag'
5
+
6
+ /**
7
+ * Custom Layout override for zpress.
8
+ * Wraps the original Rspress Layout and injects the BranchTag
9
+ * into the `beforeNavMenu` slot so it renders before the search
10
+ * bar in the navbar on all page types.
11
+ */
12
+ export function Layout(): React.ReactElement {
13
+ return <OriginalLayout beforeNavMenu={<BranchTag />} />
14
+ }
@@ -7,7 +7,7 @@
7
7
  .workspace-section {
8
8
  max-width: 1152px;
9
9
  margin: 0 auto;
10
- padding: 0 0 64px;
10
+ padding: 0 16px 64px;
11
11
  }
12
12
 
13
13
  .workspace-section h2 {
@@ -23,6 +23,9 @@ import './styles/overrides/section-card.css'
23
23
  // (theme-original avoids circular resolution when used inside a themeDir)
24
24
  export * from '@rspress/core/theme-original'
25
25
 
26
+ // Layout override — inject zpress nav components via layout slots
27
+ export { Layout } from './components/nav/layout'
28
+
26
29
  // zpress components
27
30
  export { FeatureCard, FeatureGrid } from './components/home/feature-card'
28
31
  export type { FeatureCardProps, FeatureItem, IconColor } from './components/home/feature-card'
@@ -120,6 +120,7 @@
120
120
  .home-card-divider {
121
121
  max-width: 1152px;
122
122
  margin: 0 auto 48px;
123
+ padding: 0 16px;
123
124
  border: none;
124
125
  border-top: 1px solid var(--zp-c-divider);
125
126
  }
@@ -15,7 +15,7 @@ html .rp-home-hero__image-img {
15
15
  }
16
16
 
17
17
  /* ── Rspress home hero container ────────────────────────── */
18
- html .rp-home-hero {
18
+ html .rp-home-hero__container {
19
19
  gap: 16px !important;
20
20
  }
21
21
 
@@ -33,7 +33,15 @@ html .rp-home-hero__tagline {
33
33
  padding-bottom: 16px !important;
34
34
  }
35
35
 
36
+ html .rp-home-hero__actions {
37
+ gap: 1.25rem !important;
38
+ }
39
+
36
40
  @media (max-width: 1000px) {
41
+ html .rp-home-hero {
42
+ padding-bottom: 24px !important;
43
+ }
44
+
37
45
  html .rp-home-hero__image {
38
46
  width: 400px;
39
47
  margin-left: 0;
@@ -45,6 +53,42 @@ html .rp-home-hero__tagline {
45
53
  }
46
54
  }
47
55
 
56
+ /* ── Mobile overrides ────────────────────────────────────── */
57
+ @media (max-width: 768px) {
58
+ html .rp-home-hero__container {
59
+ gap: 8px !important;
60
+ }
61
+
62
+ html .rp-home-hero__image {
63
+ width: 100%;
64
+ max-width: 90vw !important;
65
+ margin-left: 0;
66
+ margin-top: 24px;
67
+ }
68
+
69
+ html .rp-home-hero__image-img {
70
+ width: 100%;
71
+ max-width: 90vw !important;
72
+ }
73
+
74
+ html .rp-home-hero__content {
75
+ padding: 0 8px;
76
+ }
77
+
78
+ html .rp-home-hero__name {
79
+ font-size: 1.125rem !important;
80
+ }
81
+
82
+ html .rp-home-hero__text {
83
+ font-size: 2rem !important;
84
+ }
85
+
86
+ html .rp-home-hero__tagline {
87
+ font-size: 1rem !important;
88
+ line-height: 1.5 !important;
89
+ }
90
+ }
91
+
48
92
  /* ── Code blocks ─────────────────────────────────────────── */
49
93
  div[class*='language-'] {
50
94
  border-radius: var(--rp-radius) !important;