@zpress/ui 0.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.
- package/LICENSE +21 -0
- package/dist/index.mjs +75 -0
- package/dist/theme/components/home/feature-card.css +89 -0
- package/dist/theme/components/home/feature-card.tsx +75 -0
- package/dist/theme/components/home/feature.tsx +53 -0
- package/dist/theme/components/home/layout.tsx +36 -0
- package/dist/theme/components/home/workspaces.tsx +53 -0
- package/dist/theme/components/nav/branch-tag.css +54 -0
- package/dist/theme/components/nav/branch-tag.tsx +66 -0
- package/dist/theme/components/shared/card.tsx +27 -0
- package/dist/theme/components/shared/icon.tsx +27 -0
- package/dist/theme/components/shared/section-card.tsx +42 -0
- package/dist/theme/components/shared/section-grid.tsx +12 -0
- package/dist/theme/components/shared/tech-icon-table.tsx +68 -0
- package/dist/theme/components/shared/tech-tag.tsx +28 -0
- package/dist/theme/components/workspaces/card.css +141 -0
- package/dist/theme/components/workspaces/card.tsx +116 -0
- package/dist/theme/components/workspaces/grid.tsx +40 -0
- package/dist/theme/css.d.ts +1 -0
- package/dist/theme/fonts/GeistMono-Variable.woff2 +0 -0
- package/dist/theme/fonts/GeistPixel-Square.woff2 +0 -0
- package/dist/theme/fonts/GeistSans-Variable.woff2 +0 -0
- package/dist/theme/hooks/use-zpress.ts +57 -0
- package/dist/theme/icons/index.ts +2 -0
- package/dist/theme/icons/tech-map.ts +221 -0
- package/dist/theme/index.tsx +46 -0
- package/dist/theme/styles/overrides/details.css +61 -0
- package/dist/theme/styles/overrides/fonts.css +27 -0
- package/dist/theme/styles/overrides/home-card.css +125 -0
- package/dist/theme/styles/overrides/home.css +55 -0
- package/dist/theme/styles/overrides/rspress.css +108 -0
- package/dist/theme/styles/overrides/scrollbar.css +25 -0
- package/dist/theme/styles/overrides/section-card.css +115 -0
- package/dist/theme/styles/overrides/sidebar.css +9 -0
- package/dist/theme/styles/overrides/tokens.css +48 -0
- package/package.json +64 -0
- package/src/theme/components/home/feature-card.css +89 -0
- package/src/theme/components/home/feature-card.tsx +75 -0
- package/src/theme/components/home/feature.tsx +53 -0
- package/src/theme/components/home/layout.tsx +36 -0
- package/src/theme/components/home/workspaces.tsx +53 -0
- package/src/theme/components/nav/branch-tag.css +54 -0
- package/src/theme/components/nav/branch-tag.tsx +66 -0
- package/src/theme/components/shared/card.tsx +27 -0
- package/src/theme/components/shared/icon.tsx +27 -0
- package/src/theme/components/shared/section-card.tsx +42 -0
- package/src/theme/components/shared/section-grid.tsx +12 -0
- package/src/theme/components/shared/tech-icon-table.tsx +68 -0
- package/src/theme/components/shared/tech-tag.tsx +28 -0
- package/src/theme/components/workspaces/card.css +141 -0
- package/src/theme/components/workspaces/card.tsx +116 -0
- package/src/theme/components/workspaces/grid.tsx +40 -0
- package/src/theme/css.d.ts +1 -0
- package/src/theme/fonts/GeistMono-Variable.woff2 +0 -0
- package/src/theme/fonts/GeistPixel-Square.woff2 +0 -0
- package/src/theme/fonts/GeistSans-Variable.woff2 +0 -0
- package/src/theme/hooks/use-zpress.ts +57 -0
- package/src/theme/icons/index.ts +2 -0
- package/src/theme/icons/tech-map.ts +221 -0
- package/src/theme/index.tsx +46 -0
- package/src/theme/styles/overrides/details.css +61 -0
- package/src/theme/styles/overrides/fonts.css +27 -0
- package/src/theme/styles/overrides/home-card.css +125 -0
- package/src/theme/styles/overrides/home.css +55 -0
- package/src/theme/styles/overrides/rspress.css +108 -0
- package/src/theme/styles/overrides/scrollbar.css +25 -0
- package/src/theme/styles/overrides/section-card.css +115 -0
- package/src/theme/styles/overrides/sidebar.css +9 -0
- package/src/theme/styles/overrides/tokens.css +48 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace grid, card layout, deploy badge, and tech tags.
|
|
3
|
+
* Base card styles (container, hover, icons) from home-card.css.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ── Workspace section ───────────────────────────────────── */
|
|
7
|
+
.workspace-section {
|
|
8
|
+
max-width: 1152px;
|
|
9
|
+
margin: 0 auto;
|
|
10
|
+
padding: 0 0 64px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.workspace-section h2 {
|
|
14
|
+
font-size: 18px;
|
|
15
|
+
font-weight: 600;
|
|
16
|
+
letter-spacing: 0.02em;
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
margin-bottom: 4px;
|
|
19
|
+
color: var(--zp-c-text-2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.workspace-group-desc {
|
|
23
|
+
margin: 0 0 16px;
|
|
24
|
+
font-size: 14px;
|
|
25
|
+
color: var(--zp-c-text-3);
|
|
26
|
+
line-height: 1.5;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.workspace-grid {
|
|
30
|
+
display: grid;
|
|
31
|
+
grid-template-columns: repeat(2, 1fr);
|
|
32
|
+
gap: 12px;
|
|
33
|
+
margin-bottom: 40px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* ── Workspace card layout ───────────────────────────────── */
|
|
37
|
+
.workspace-card {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.workspace-header {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
margin-bottom: 10px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.workspace-identity {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
gap: 10px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.workspace-title {
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-direction: column;
|
|
58
|
+
line-height: 1.2;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.workspace-scope {
|
|
62
|
+
font-family: var(--zp-font-family-mono);
|
|
63
|
+
font-size: 11px;
|
|
64
|
+
color: var(--zp-c-text-3);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.workspace-name {
|
|
68
|
+
font-family: var(--zp-font-family-mono);
|
|
69
|
+
font-size: 15px;
|
|
70
|
+
font-weight: 700;
|
|
71
|
+
color: var(--zp-c-text-1);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.workspace-desc {
|
|
75
|
+
font-size: 13px;
|
|
76
|
+
color: var(--zp-c-text-2);
|
|
77
|
+
line-height: 1.5;
|
|
78
|
+
flex: 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ── Deploy badge ────────────────────────────────────────── */
|
|
82
|
+
.deploy-badge {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
padding: 4px 6px;
|
|
87
|
+
border-radius: 6px;
|
|
88
|
+
background: var(--zp-c-bg);
|
|
89
|
+
border: 1px solid var(--zp-c-divider);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.deploy-logo {
|
|
93
|
+
height: 16px;
|
|
94
|
+
width: auto;
|
|
95
|
+
opacity: 0.75;
|
|
96
|
+
transition: opacity 0.2s;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.home-card:hover .deploy-logo {
|
|
100
|
+
opacity: 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* ── Tech tags ───────────────────────────────────────────── */
|
|
104
|
+
.workspace-tags {
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-wrap: wrap;
|
|
107
|
+
gap: 6px;
|
|
108
|
+
margin-top: 10px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.workspace-tag {
|
|
112
|
+
display: inline-flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
gap: 4px;
|
|
115
|
+
font-family: var(--zp-font-family-mono);
|
|
116
|
+
font-size: 11px;
|
|
117
|
+
padding: 2px 8px;
|
|
118
|
+
border-radius: var(--rp-radius-small);
|
|
119
|
+
background: var(--zp-c-bg);
|
|
120
|
+
color: var(--zp-c-text-3);
|
|
121
|
+
border: 1px solid var(--zp-c-divider);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.workspace-tag svg {
|
|
125
|
+
width: 14px;
|
|
126
|
+
height: 14px;
|
|
127
|
+
flex-shrink: 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* ── Responsive ──────────────────────────────────────────── */
|
|
131
|
+
@media (max-width: 768px) {
|
|
132
|
+
.workspace-grid {
|
|
133
|
+
grid-template-columns: 1fr;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@media (min-width: 769px) and (max-width: 1024px) {
|
|
138
|
+
.workspace-grid {
|
|
139
|
+
grid-template-columns: repeat(2, 1fr);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
import { match, P } from 'ts-pattern'
|
|
3
|
+
|
|
4
|
+
import type { IconColor } from '../home/feature-card'
|
|
5
|
+
import { Card } from '../shared/card'
|
|
6
|
+
import { Icon } from '../shared/icon'
|
|
7
|
+
import { TechTag } from '../shared/tech-tag'
|
|
8
|
+
|
|
9
|
+
// ── Types ────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
export interface WorkspaceCardProps {
|
|
12
|
+
/**
|
|
13
|
+
* Display name for the card header.
|
|
14
|
+
*/
|
|
15
|
+
readonly text: string
|
|
16
|
+
/**
|
|
17
|
+
* Link target (e.g. "/apps/api").
|
|
18
|
+
*/
|
|
19
|
+
readonly href: string
|
|
20
|
+
/**
|
|
21
|
+
* Iconify identifier (e.g. "simple-icons:typescript").
|
|
22
|
+
*/
|
|
23
|
+
readonly icon?: string
|
|
24
|
+
/**
|
|
25
|
+
* CSS class suffix for icon background color.
|
|
26
|
+
*/
|
|
27
|
+
readonly iconColor?: IconColor
|
|
28
|
+
/**
|
|
29
|
+
* Scope prefix shown above the name (e.g. "apps/").
|
|
30
|
+
*/
|
|
31
|
+
readonly scope?: string
|
|
32
|
+
/**
|
|
33
|
+
* Short description rendered below the header.
|
|
34
|
+
*/
|
|
35
|
+
readonly description?: string
|
|
36
|
+
/**
|
|
37
|
+
* Technology tag names resolved via the tech map.
|
|
38
|
+
*/
|
|
39
|
+
readonly tags?: readonly string[]
|
|
40
|
+
/**
|
|
41
|
+
* Deploy badge image for the card header.
|
|
42
|
+
*/
|
|
43
|
+
readonly badge?: { readonly src: string; readonly alt: string }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ── Component ────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Workspace card — renders a clickable link card with icon, name,
|
|
50
|
+
* description, tech tags, and optional deploy badge.
|
|
51
|
+
*/
|
|
52
|
+
export function WorkspaceCard({
|
|
53
|
+
text,
|
|
54
|
+
href,
|
|
55
|
+
icon,
|
|
56
|
+
iconColor = 'purple',
|
|
57
|
+
scope,
|
|
58
|
+
description,
|
|
59
|
+
tags,
|
|
60
|
+
badge,
|
|
61
|
+
}: WorkspaceCardProps): React.ReactElement {
|
|
62
|
+
const name = text.toLowerCase()
|
|
63
|
+
|
|
64
|
+
const iconEl = match(icon)
|
|
65
|
+
.with(P.nonNullable, (id) => <Icon icon={id} />)
|
|
66
|
+
.otherwise(() => null)
|
|
67
|
+
|
|
68
|
+
const scopeEl = match(scope)
|
|
69
|
+
.with(
|
|
70
|
+
P.when((s): s is string => s !== undefined && s.length > 0),
|
|
71
|
+
(s) => <span className="workspace-scope">{s}</span>
|
|
72
|
+
)
|
|
73
|
+
.otherwise(() => null)
|
|
74
|
+
|
|
75
|
+
const badgeEl = match(badge)
|
|
76
|
+
.with(P.nonNullable, (b) => (
|
|
77
|
+
<span className="deploy-badge" title={`Deployed on ${b.alt}`}>
|
|
78
|
+
<img src={b.src} alt={b.alt} className="deploy-logo" />
|
|
79
|
+
</span>
|
|
80
|
+
))
|
|
81
|
+
.otherwise(() => null)
|
|
82
|
+
|
|
83
|
+
const descEl = match(description)
|
|
84
|
+
.with(P.nonNullable, (d) => <span className="workspace-desc">{d}</span>)
|
|
85
|
+
.otherwise(() => null)
|
|
86
|
+
|
|
87
|
+
const tagsEl = match(tags)
|
|
88
|
+
.with(
|
|
89
|
+
P.when((t): t is readonly string[] => t !== undefined && t.length > 0),
|
|
90
|
+
(t) => (
|
|
91
|
+
<div className="workspace-tags">
|
|
92
|
+
{t.map((tag) => (
|
|
93
|
+
<TechTag key={tag} name={tag} />
|
|
94
|
+
))}
|
|
95
|
+
</div>
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
.otherwise(() => null)
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<Card href={href} className="workspace-card">
|
|
102
|
+
<div className="workspace-header">
|
|
103
|
+
<div className="workspace-identity">
|
|
104
|
+
<span className={`home-card-icon home-card-icon--${iconColor}`}>{iconEl}</span>
|
|
105
|
+
<div className="workspace-title">
|
|
106
|
+
{scopeEl}
|
|
107
|
+
<span className="workspace-name">{name}</span>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
{badgeEl}
|
|
111
|
+
</div>
|
|
112
|
+
{descEl}
|
|
113
|
+
{tagsEl}
|
|
114
|
+
</Card>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
|
|
3
|
+
import './card.css'
|
|
4
|
+
|
|
5
|
+
// ── Types ────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
export interface WorkspaceGridProps {
|
|
8
|
+
/**
|
|
9
|
+
* Section heading (e.g. "Apps", "Packages").
|
|
10
|
+
*/
|
|
11
|
+
readonly heading: string
|
|
12
|
+
/**
|
|
13
|
+
* Brief description rendered below the heading.
|
|
14
|
+
*/
|
|
15
|
+
readonly description: string
|
|
16
|
+
/**
|
|
17
|
+
* WorkspaceCard elements.
|
|
18
|
+
*/
|
|
19
|
+
readonly children: React.ReactNode
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ── Component ────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Grid container for workspace cards — renders a heading, description,
|
|
26
|
+
* and a CSS grid wrapping its children.
|
|
27
|
+
*/
|
|
28
|
+
export function WorkspaceGrid({
|
|
29
|
+
heading,
|
|
30
|
+
description,
|
|
31
|
+
children,
|
|
32
|
+
}: WorkspaceGridProps): React.ReactElement {
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<h2>{heading}</h2>
|
|
36
|
+
<p className="workspace-group-desc">{description}</p>
|
|
37
|
+
<div className="workspace-grid">{children}</div>
|
|
38
|
+
</>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css' {}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useSite } from '@rspress/core/runtime'
|
|
2
|
+
|
|
3
|
+
import type { IconColor } from '../components/home/feature-card'
|
|
4
|
+
|
|
5
|
+
// ── Sidebar types ───────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
export interface ZpressSidebarItem {
|
|
8
|
+
readonly text?: string
|
|
9
|
+
readonly link?: string
|
|
10
|
+
readonly icon?: string
|
|
11
|
+
readonly items?: readonly ZpressSidebarItem[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ── Workspace types ─────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
export interface WorkspaceCardData {
|
|
17
|
+
readonly text: string
|
|
18
|
+
readonly href: string
|
|
19
|
+
readonly icon: string | undefined
|
|
20
|
+
readonly iconColor: IconColor | undefined
|
|
21
|
+
readonly scope: string | undefined
|
|
22
|
+
readonly description: string | undefined
|
|
23
|
+
readonly tags: readonly string[]
|
|
24
|
+
readonly badge: { readonly src: string; readonly alt: string } | undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface WorkspaceGroupData {
|
|
28
|
+
readonly type: 'apps' | 'packages' | 'workspaces'
|
|
29
|
+
readonly heading: string
|
|
30
|
+
readonly description: string
|
|
31
|
+
readonly cards: readonly WorkspaceCardData[]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ── Theme config ────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
interface ZpressThemeConfig {
|
|
37
|
+
readonly sidebar: Record<string, readonly ZpressSidebarItem[]>
|
|
38
|
+
readonly workspaces: readonly WorkspaceGroupData[] | undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ── Hook ────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Typed wrapper around Rspress `useSite()` that exposes
|
|
45
|
+
* zpress-specific themeConfig fields.
|
|
46
|
+
*
|
|
47
|
+
* The double cast is necessary because Rspress types `themeConfig` as
|
|
48
|
+
* `NormalizedThemeConfig`, but zpress injects custom fields (sidebar,
|
|
49
|
+
* workspaces) via spread at build time. No Zod schema exists for runtime
|
|
50
|
+
* validation yet.
|
|
51
|
+
*
|
|
52
|
+
* @returns zpress theme config with sidebar and workspace data.
|
|
53
|
+
*/
|
|
54
|
+
export function useZpress(): ZpressThemeConfig {
|
|
55
|
+
const { site } = useSite()
|
|
56
|
+
return site.themeConfig as unknown as ZpressThemeConfig
|
|
57
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predefined technology tag to Iconify identifier + display label.
|
|
3
|
+
*
|
|
4
|
+
* Uses `devicon` as the primary source for colored icons, with `logos`,
|
|
5
|
+
* `vscode-icons`, and `material-icon-theme` filling gaps. A small number
|
|
6
|
+
* of entries fall back to `simple-icons` (monochrome) when no colored
|
|
7
|
+
* alternative exists.
|
|
8
|
+
*
|
|
9
|
+
* Add new entries here when new technologies need card support.
|
|
10
|
+
*/
|
|
11
|
+
export const TECH_ICONS = {
|
|
12
|
+
// -- Languages --
|
|
13
|
+
typescript: { icon: 'devicon:typescript', label: 'TypeScript' },
|
|
14
|
+
javascript: { icon: 'devicon:javascript', label: 'JavaScript' },
|
|
15
|
+
python: { icon: 'devicon:python', label: 'Python' },
|
|
16
|
+
go: { icon: 'devicon:go', label: 'Go' },
|
|
17
|
+
rust: { icon: 'devicon:rust', label: 'Rust' },
|
|
18
|
+
java: { icon: 'devicon:java', label: 'Java' },
|
|
19
|
+
csharp: { icon: 'devicon:csharp', label: 'C#' },
|
|
20
|
+
ruby: { icon: 'devicon:ruby', label: 'Ruby' },
|
|
21
|
+
php: { icon: 'devicon:php', label: 'PHP' },
|
|
22
|
+
swift: { icon: 'devicon:swift', label: 'Swift' },
|
|
23
|
+
kotlin: { icon: 'devicon:kotlin', label: 'Kotlin' },
|
|
24
|
+
elixir: { icon: 'devicon:elixir', label: 'Elixir' },
|
|
25
|
+
dart: { icon: 'devicon:dart', label: 'Dart' },
|
|
26
|
+
scala: { icon: 'devicon:scala', label: 'Scala' },
|
|
27
|
+
c: { icon: 'devicon:c', label: 'C' },
|
|
28
|
+
cplusplus: { icon: 'devicon:cplusplus', label: 'C++' },
|
|
29
|
+
r: { icon: 'devicon:r', label: 'R' },
|
|
30
|
+
lua: { icon: 'devicon:lua', label: 'Lua' },
|
|
31
|
+
perl: { icon: 'devicon:perl', label: 'Perl' },
|
|
32
|
+
haskell: { icon: 'devicon:haskell', label: 'Haskell' },
|
|
33
|
+
clojure: { icon: 'devicon:clojure', label: 'Clojure' },
|
|
34
|
+
erlang: { icon: 'devicon:erlang', label: 'Erlang' },
|
|
35
|
+
fsharp: { icon: 'devicon:fsharp', label: 'F#' },
|
|
36
|
+
julia: { icon: 'devicon:julia', label: 'Julia' },
|
|
37
|
+
groovy: { icon: 'devicon:groovy', label: 'Groovy' },
|
|
38
|
+
|
|
39
|
+
// -- Frontend frameworks --
|
|
40
|
+
react: { icon: 'devicon:react', label: 'React' },
|
|
41
|
+
nextjs: { icon: 'devicon:nextjs', label: 'Next.js' },
|
|
42
|
+
vue: { icon: 'devicon:vuejs', label: 'Vue' },
|
|
43
|
+
angular: { icon: 'devicon:angular', label: 'Angular' },
|
|
44
|
+
svelte: { icon: 'devicon:svelte', label: 'Svelte' },
|
|
45
|
+
astro: { icon: 'devicon:astro', label: 'Astro' },
|
|
46
|
+
solid: { icon: 'devicon:solidjs', label: 'Solid' },
|
|
47
|
+
remix: { icon: 'devicon:remix', label: 'Remix' },
|
|
48
|
+
qwik: { icon: 'devicon:qwik', label: 'Qwik' },
|
|
49
|
+
ember: { icon: 'devicon:ember', label: 'Ember' },
|
|
50
|
+
gatsby: { icon: 'devicon:gatsby', label: 'Gatsby' },
|
|
51
|
+
nuxtjs: { icon: 'devicon:nuxtjs', label: 'Nuxt' },
|
|
52
|
+
preact: { icon: 'logos:preact', label: 'Preact' },
|
|
53
|
+
lit: { icon: 'logos:lit', label: 'Lit' },
|
|
54
|
+
|
|
55
|
+
// -- Backend frameworks --
|
|
56
|
+
hono: { icon: 'logos:hono', label: 'Hono' },
|
|
57
|
+
express: { icon: 'devicon:express', label: 'Express' },
|
|
58
|
+
fastify: { icon: 'devicon:fastify', label: 'Fastify' },
|
|
59
|
+
nestjs: { icon: 'devicon:nestjs', label: 'NestJS' },
|
|
60
|
+
django: { icon: 'logos:django-icon', label: 'Django' },
|
|
61
|
+
flask: { icon: 'devicon:flask', label: 'Flask' },
|
|
62
|
+
rails: { icon: 'devicon:rails-wordmark', label: 'Rails' },
|
|
63
|
+
spring: { icon: 'devicon:spring', label: 'Spring' },
|
|
64
|
+
fastapi: { icon: 'devicon:fastapi', label: 'FastAPI' },
|
|
65
|
+
laravel: { icon: 'devicon:laravel', label: 'Laravel' },
|
|
66
|
+
phoenix: { icon: 'devicon:phoenix', label: 'Phoenix' },
|
|
67
|
+
fiber: { icon: 'devicon:fiber', label: 'Fiber' },
|
|
68
|
+
gin: { icon: 'logos:gin', label: 'Gin' },
|
|
69
|
+
akka: { icon: 'devicon:akka', label: 'Akka' },
|
|
70
|
+
|
|
71
|
+
// -- Mobile --
|
|
72
|
+
flutter: { icon: 'devicon:flutter', label: 'Flutter' },
|
|
73
|
+
reactnative: { icon: 'devicon:reactnative', label: 'React Native' },
|
|
74
|
+
ionic: { icon: 'devicon:ionic', label: 'Ionic' },
|
|
75
|
+
|
|
76
|
+
// -- Databases --
|
|
77
|
+
postgresql: { icon: 'devicon:postgresql', label: 'PostgreSQL' },
|
|
78
|
+
mysql: { icon: 'devicon:mysql', label: 'MySQL' },
|
|
79
|
+
mongodb: { icon: 'devicon:mongodb', label: 'MongoDB' },
|
|
80
|
+
redis: { icon: 'devicon:redis', label: 'Redis' },
|
|
81
|
+
sqlite: { icon: 'devicon:sqlite', label: 'SQLite' },
|
|
82
|
+
dynamodb: { icon: 'devicon:dynamodb', label: 'DynamoDB' },
|
|
83
|
+
elasticsearch: { icon: 'devicon:elasticsearch', label: 'Elasticsearch' },
|
|
84
|
+
neo4j: { icon: 'devicon:neo4j', label: 'Neo4j' },
|
|
85
|
+
cassandra: { icon: 'devicon:cassandra', label: 'Cassandra' },
|
|
86
|
+
couchdb: { icon: 'devicon:couchdb', label: 'CouchDB' },
|
|
87
|
+
mariadb: { icon: 'devicon:mariadb', label: 'MariaDB' },
|
|
88
|
+
influxdb: { icon: 'devicon:influxdb', label: 'InfluxDB' },
|
|
89
|
+
cockroachdb: { icon: 'simple-icons:cockroachlabs', label: 'CockroachDB' },
|
|
90
|
+
vitess: { icon: 'devicon:vitess', label: 'Vitess' },
|
|
91
|
+
oracle: { icon: 'devicon:oracle', label: 'Oracle' },
|
|
92
|
+
|
|
93
|
+
// -- ORM / Data tools --
|
|
94
|
+
prisma: { icon: 'devicon:prisma', label: 'Prisma' },
|
|
95
|
+
graphql: { icon: 'logos:graphql', label: 'GraphQL' },
|
|
96
|
+
drizzle: { icon: 'logos:drizzle', label: 'Drizzle' },
|
|
97
|
+
typeorm: { icon: 'logos:typeorm', label: 'TypeORM' },
|
|
98
|
+
sequelize: { icon: 'logos:sequelize', label: 'Sequelize' },
|
|
99
|
+
sqlalchemy: { icon: 'devicon:sqlalchemy', label: 'SQLAlchemy' },
|
|
100
|
+
|
|
101
|
+
// -- Cloud & hosting --
|
|
102
|
+
vercel: { icon: 'devicon:vercel', label: 'Vercel' },
|
|
103
|
+
aws: { icon: 'devicon:amazonwebservices', label: 'AWS' },
|
|
104
|
+
azure: { icon: 'devicon:azure', label: 'Azure' },
|
|
105
|
+
gcp: { icon: 'devicon:googlecloud', label: 'GCP' },
|
|
106
|
+
cloudflare: { icon: 'devicon:cloudflare', label: 'Cloudflare' },
|
|
107
|
+
digitalocean: { icon: 'devicon:digitalocean', label: 'DigitalOcean' },
|
|
108
|
+
heroku: { icon: 'devicon:heroku', label: 'Heroku' },
|
|
109
|
+
netlify: { icon: 'devicon:netlify', label: 'Netlify' },
|
|
110
|
+
firebase: { icon: 'devicon:firebase', label: 'Firebase' },
|
|
111
|
+
supabase: { icon: 'devicon:supabase', label: 'Supabase' },
|
|
112
|
+
railway: { icon: 'devicon:railway', label: 'Railway' },
|
|
113
|
+
pulumi: { icon: 'devicon:pulumi', label: 'Pulumi' },
|
|
114
|
+
fly: { icon: 'logos:fly-icon', label: 'Fly.io' },
|
|
115
|
+
|
|
116
|
+
// -- CI/CD & DevOps --
|
|
117
|
+
docker: { icon: 'devicon:docker', label: 'Docker' },
|
|
118
|
+
kubernetes: { icon: 'devicon:kubernetes', label: 'Kubernetes' },
|
|
119
|
+
github: { icon: 'devicon:github', label: 'GitHub' },
|
|
120
|
+
'github-actions': { icon: 'devicon:githubactions', label: 'GitHub Actions' },
|
|
121
|
+
gitlab: { icon: 'devicon:gitlab', label: 'GitLab' },
|
|
122
|
+
circleci: { icon: 'logos:circleci', label: 'CircleCI' },
|
|
123
|
+
terraform: { icon: 'devicon:terraform', label: 'Terraform' },
|
|
124
|
+
ansible: { icon: 'devicon:ansible', label: 'Ansible' },
|
|
125
|
+
jenkins: { icon: 'devicon:jenkins', label: 'Jenkins' },
|
|
126
|
+
argocd: { icon: 'devicon:argocd', label: 'Argo CD' },
|
|
127
|
+
|
|
128
|
+
// -- Build & package tools --
|
|
129
|
+
vite: { icon: 'devicon:vite', label: 'Vite' },
|
|
130
|
+
webpack: { icon: 'devicon:webpack', label: 'Webpack' },
|
|
131
|
+
npm: { icon: 'devicon:npm', label: 'npm' },
|
|
132
|
+
pnpm: { icon: 'devicon:pnpm', label: 'pnpm' },
|
|
133
|
+
yarn: { icon: 'devicon:yarn', label: 'Yarn' },
|
|
134
|
+
bun: { icon: 'devicon:bun', label: 'Bun' },
|
|
135
|
+
eslint: { icon: 'devicon:eslint', label: 'ESLint' },
|
|
136
|
+
babel: { icon: 'devicon:babel', label: 'Babel' },
|
|
137
|
+
turborepo: { icon: 'logos:turborepo-icon', label: 'Turborepo' },
|
|
138
|
+
biome: { icon: 'devicon:biome', label: 'Biome' },
|
|
139
|
+
prettier: { icon: 'logos:prettier', label: 'Prettier' },
|
|
140
|
+
esbuild: { icon: 'logos:esbuild', label: 'esbuild' },
|
|
141
|
+
rollup: { icon: 'devicon:rollup', label: 'Rollup' },
|
|
142
|
+
swc: { icon: 'logos:swc', label: 'SWC' },
|
|
143
|
+
gradle: { icon: 'devicon:gradle', label: 'Gradle' },
|
|
144
|
+
maven: { icon: 'devicon:maven', label: 'Maven' },
|
|
145
|
+
|
|
146
|
+
// -- UI & styling --
|
|
147
|
+
tailwindcss: { icon: 'devicon:tailwindcss', label: 'Tailwind CSS' },
|
|
148
|
+
css: { icon: 'devicon:css3', label: 'CSS' },
|
|
149
|
+
html: { icon: 'devicon:html5', label: 'HTML' },
|
|
150
|
+
sass: { icon: 'devicon:sass', label: 'Sass' },
|
|
151
|
+
bootstrap: { icon: 'devicon:bootstrap', label: 'Bootstrap' },
|
|
152
|
+
materialui: { icon: 'devicon:materialui', label: 'Material UI' },
|
|
153
|
+
'shadcn-ui': { icon: 'vscode-icons:file-type-shadcn', label: 'shadcn/ui' },
|
|
154
|
+
storybook: { icon: 'devicon:storybook', label: 'Storybook' },
|
|
155
|
+
figma: { icon: 'devicon:figma', label: 'Figma' },
|
|
156
|
+
|
|
157
|
+
// -- Testing --
|
|
158
|
+
jest: { icon: 'logos:jest', label: 'Jest' },
|
|
159
|
+
vitest: { icon: 'devicon:vitest', label: 'Vitest' },
|
|
160
|
+
cypress: { icon: 'devicon:cypressio', label: 'Cypress' },
|
|
161
|
+
playwright: { icon: 'devicon:playwright', label: 'Playwright' },
|
|
162
|
+
selenium: { icon: 'devicon:selenium', label: 'Selenium' },
|
|
163
|
+
mocha: { icon: 'devicon:mocha', label: 'Mocha' },
|
|
164
|
+
puppeteer: { icon: 'devicon:puppeteer', label: 'Puppeteer' },
|
|
165
|
+
cucumber: { icon: 'logos:cucumber', label: 'Cucumber' },
|
|
166
|
+
|
|
167
|
+
// -- Auth & integrations --
|
|
168
|
+
oauth: { icon: 'devicon:oauth', label: 'OAuth' },
|
|
169
|
+
auth0: { icon: 'logos:auth0', label: 'Auth0' },
|
|
170
|
+
stripe: { icon: 'logos:stripe', label: 'Stripe' },
|
|
171
|
+
twilio: { icon: 'devicon:twilio', label: 'Twilio' },
|
|
172
|
+
|
|
173
|
+
// -- AI / ML --
|
|
174
|
+
openai: { icon: 'logos:openai-icon', label: 'OpenAI' },
|
|
175
|
+
tensorflow: { icon: 'devicon:tensorflow', label: 'TensorFlow' },
|
|
176
|
+
pytorch: { icon: 'devicon:pytorch', label: 'PyTorch' },
|
|
177
|
+
huggingface: { icon: 'devicon:huggingface', label: 'Hugging Face' },
|
|
178
|
+
anthropic: { icon: 'logos:anthropic-icon', label: 'Anthropic' },
|
|
179
|
+
jupyter: { icon: 'devicon:jupyter', label: 'Jupyter' },
|
|
180
|
+
numpy: { icon: 'devicon:numpy', label: 'NumPy' },
|
|
181
|
+
pandas: { icon: 'devicon:pandas', label: 'Pandas' },
|
|
182
|
+
scikitlearn: { icon: 'devicon:scikitlearn', label: 'scikit-learn' },
|
|
183
|
+
matplotlib: { icon: 'devicon:matplotlib', label: 'Matplotlib' },
|
|
184
|
+
|
|
185
|
+
// -- Monitoring & observability --
|
|
186
|
+
grafana: { icon: 'devicon:grafana', label: 'Grafana' },
|
|
187
|
+
prometheus: { icon: 'devicon:prometheus', label: 'Prometheus' },
|
|
188
|
+
datadog: { icon: 'devicon:datadog', label: 'Datadog' },
|
|
189
|
+
sentry: { icon: 'devicon:sentry', label: 'Sentry' },
|
|
190
|
+
newrelic: { icon: 'devicon:newrelic', label: 'New Relic' },
|
|
191
|
+
|
|
192
|
+
// -- Message queues --
|
|
193
|
+
kafka: { icon: 'devicon:apachekafka', label: 'Kafka' },
|
|
194
|
+
rabbitmq: { icon: 'devicon:rabbitmq', label: 'RabbitMQ' },
|
|
195
|
+
nats: { icon: 'devicon:nats', label: 'NATS' },
|
|
196
|
+
|
|
197
|
+
// -- CMS --
|
|
198
|
+
strapi: { icon: 'logos:strapi', label: 'Strapi' },
|
|
199
|
+
contentful: { icon: 'logos:contentful', label: 'Contentful' },
|
|
200
|
+
sanity: { icon: 'devicon:sanity', label: 'Sanity' },
|
|
201
|
+
wordpress: { icon: 'devicon:wordpress', label: 'WordPress' },
|
|
202
|
+
shopify: { icon: 'logos:shopify', label: 'Shopify' },
|
|
203
|
+
ghost: { icon: 'devicon:ghost', label: 'Ghost' },
|
|
204
|
+
|
|
205
|
+
// -- Infrastructure --
|
|
206
|
+
nginx: { icon: 'devicon:nginx', label: 'Nginx' },
|
|
207
|
+
apache: { icon: 'devicon:apache', label: 'Apache' },
|
|
208
|
+
linux: { icon: 'devicon:linux', label: 'Linux' },
|
|
209
|
+
|
|
210
|
+
// -- Project-specific (label-only fallback when icon not in any set) --
|
|
211
|
+
'trigger-dev': { icon: 'material-icon-theme:trigger', label: 'Trigger.dev' },
|
|
212
|
+
'ai-sdk': { icon: 'simple-icons:vercel', label: 'AI SDK' },
|
|
213
|
+
openrouter: { icon: 'simple-icons:openrouter', label: 'OpenRouter' },
|
|
214
|
+
liquid: { icon: 'vscode-icons:file-type-liquid', label: 'Liquid' },
|
|
215
|
+
zod: { icon: 'logos:zod', label: 'Zod' },
|
|
216
|
+
} as const satisfies Record<string, { readonly icon: string; readonly label: string }>
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Union of all supported technology tag names.
|
|
220
|
+
*/
|
|
221
|
+
export type TechName = keyof typeof TECH_ICONS
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zpress Rspress theme entry.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the default Rspress theme and extends it with
|
|
5
|
+
* zpress-specific components (branch tag, feature cards).
|
|
6
|
+
*
|
|
7
|
+
* Global styles are imported here so Rspress includes them
|
|
8
|
+
* in the site bundle when this theme entry is loaded.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Global override styles — imported for side-effects
|
|
12
|
+
import './styles/overrides/fonts.css'
|
|
13
|
+
import './styles/overrides/tokens.css'
|
|
14
|
+
import './styles/overrides/rspress.css'
|
|
15
|
+
import './styles/overrides/details.css'
|
|
16
|
+
import './styles/overrides/scrollbar.css'
|
|
17
|
+
import './styles/overrides/sidebar.css'
|
|
18
|
+
import './styles/overrides/home.css'
|
|
19
|
+
import './styles/overrides/home-card.css'
|
|
20
|
+
import './styles/overrides/section-card.css'
|
|
21
|
+
|
|
22
|
+
// Re-export everything from the original Rspress theme
|
|
23
|
+
// (theme-original avoids circular resolution when used inside a themeDir)
|
|
24
|
+
export * from '@rspress/core/theme-original'
|
|
25
|
+
|
|
26
|
+
// zpress components
|
|
27
|
+
export { FeatureCard, FeatureGrid } from './components/home/feature-card'
|
|
28
|
+
export type { FeatureCardProps, FeatureItem, IconColor } from './components/home/feature-card'
|
|
29
|
+
export { WorkspaceCard } from './components/workspaces/card'
|
|
30
|
+
export type { WorkspaceCardProps } from './components/workspaces/card'
|
|
31
|
+
export { WorkspaceGrid } from './components/workspaces/grid'
|
|
32
|
+
export type { WorkspaceGridProps } from './components/workspaces/grid'
|
|
33
|
+
|
|
34
|
+
export { SectionCard } from './components/shared/section-card'
|
|
35
|
+
export type { SectionCardProps } from './components/shared/section-card'
|
|
36
|
+
export { SectionGrid } from './components/shared/section-grid'
|
|
37
|
+
export type { SectionGridProps } from './components/shared/section-grid'
|
|
38
|
+
export { TechTag } from './components/shared/tech-tag'
|
|
39
|
+
export type { TechTagProps } from './components/shared/tech-tag'
|
|
40
|
+
export { TechIconTable } from './components/shared/tech-icon-table'
|
|
41
|
+
export type { TechIconEntry, TechIconTableProps } from './components/shared/tech-icon-table'
|
|
42
|
+
export { Icon } from './components/shared/icon'
|
|
43
|
+
|
|
44
|
+
// Home page overrides — shadow the wildcard re-exports from theme-original
|
|
45
|
+
export { HomeFeature } from './components/home/feature'
|
|
46
|
+
export { HomeLayout } from './components/home/layout'
|