Skip to content

Commit be3648f

Browse files
committed
Update ecoystem notes on frontend.
1 parent 7de0e1f commit be3648f

10 files changed

Lines changed: 270 additions & 5 deletions

File tree

‎frontend/components/studioComponents.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import { defineStudioCopyComponent } from './studioCopy'
55
import { defineStudioFaqComponent } from './studioFaq'
66
import { defineStudioFeatureComponent } from './studioFeature'
77
import { defineStudioPackageComponent } from './studioPackage'
8+
import { defineStudioRegorConnectionComponent } from './studioRegorConnection'
89
import { defineStudioWorkbenchComponent } from './studioWorkbench'
910

1011
export function defineStudioComponents() {
1112
return {
1213
studioBrand: defineStudioBrandComponent(),
1314
studioFeature: defineStudioFeatureComponent(),
1415
studioPackage: defineStudioPackageComponent(),
16+
studioRegorConnection: defineStudioRegorConnectionComponent(),
1517
studioCopy: defineStudioCopyComponent(),
1618
studioFaq: defineStudioFaqComponent(),
1719
studioCommand: defineStudioCommandComponent(),
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { defineComponent, html } from 'regor'
2+
3+
export interface StudioRegorConnection {
4+
uiCaption: string
5+
docsCaption: string
6+
}
7+
8+
const studioRegorConnectionTemplate = html`<figure class="regor-connection">
9+
<div class="regor-loop">
10+
<svg class="regor-loop-path" viewBox="0 0 360 220" preserveAspectRatio="none" fill="none" aria-hidden="true">
11+
<path class="regor-loop-ui" d="M80 62 V60 Q80 35 105 35 H255 Q280 35 280 54"/>
12+
<path class="regor-loop-ui" d="M275 48 L280 55 L285 48"/>
13+
<path class="regor-loop-docs" d="M280 160 Q280 185 255 185 H105 Q80 185 80 166"/>
14+
<path class="regor-loop-docs" d="M75 172 L80 165 L85 172"/>
15+
</svg>
16+
<span class="regor-loop-label regor-loop-label--ui">Reactive UI <Icon name="lucide:arrow-right"/></span>
17+
<div class="regor-loop-node regor-loop-node--regor">
18+
<span class="regor-loop-mark"><Icon name="lucide:orbit"/></span>
19+
<strong>Regor</strong>
20+
</div>
21+
<div class="regor-loop-node regor-loop-node--purestack">
22+
<span class="regor-loop-mark"><Icon name="tabler:stack-2"/></span>
23+
<strong>PureStack</strong>
24+
</div>
25+
<span class="regor-loop-label regor-loop-label--docs"><Icon name="lucide:arrow-left"/>Documentation</span>
26+
</div>
27+
<figcaption>{{ uiCaption }}<br/>{{ docsCaption }}</figcaption>
28+
</figure>`
29+
30+
export function defineStudioRegorConnectionComponent() {
31+
return defineComponent<StudioRegorConnection>(studioRegorConnectionTemplate, {
32+
context: () => ({
33+
uiCaption: "Regor powers PureStack's UI.",
34+
docsCaption: "PureStack builds Regor's docs.",
35+
}),
36+
})
37+
}

‎frontend/purestack.studio/components/header.mdx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<a class="topbar__icon" href="https://github.com/PureStackStudio/PureStack" target="_blank" rel="noopener" aria-label="PureStack GitHub repository">
44
<Icon name="tabler:brand-github"/>
55
</a>
6+
<a class="topbar__icon" href="https://regor.purestack.studio" target="_blank" rel="noopener" aria-label="Regor website">
7+
<Icon name="lucide:orbit"/>
8+
</a>
69
<a class="topbar__icon" href="https://x.com/purestackstudio" target="_blank" rel="noopener" aria-label="PureStack Studio on X">
710
<Icon name="tabler:brand-x"/>
811
</a>

‎frontend/purestack.studio/footer.mdx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
<span class="footer-label">EXPLORE</span
1010
><a href="/#framework">The framework</a
1111
><a href="/#ecosystem">The ecosystem</a
12-
><a href="/#getting-started">Get started</a>
12+
><a href="/#getting-started">Get started</a
13+
><a href="https://regor.purestack.studio" target="_blank" rel="noopener"
14+
>Regor ↗</a
15+
>
1316
</div>
1417
<div>
1518
<span class="footer-label">OPEN SOURCE</span

‎frontend/purestack.studio/guides/extending/regor.mdx‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ highlights:
1717

1818
# Regor
1919

20-
<a href="https://github.com/koculu/Regor" target="_blank" rel="noopener">Regor</a> is the component framework PureStack is built on. It runs in two places:
20+
<a href="https://github.com/PureStackStudio/Regor" target="_blank" rel="noopener">Regor</a> is the component framework PureStack is built on. It runs in two places:
2121

2222
<Grid columns="1" columnsSm="2" class="gap-3 mb-4">
2323
<Panel tone="neutral" bodyClass="p-3">
@@ -54,7 +54,16 @@ A PureStack page can load any browser library, including React or Vue, because P
5454

5555
<Flex wrap="true" align="center">
5656
<BtnLink
57-
href="https://github.com/koculu/Regor"
57+
href="https://regor.purestack.studio"
58+
target="_blank"
59+
rel="noopener"
60+
tone="accent"
61+
variant="solid"
62+
icon="lucide:orbit"
63+
>Regor website</BtnLink
64+
>
65+
<BtnLink
66+
href="https://github.com/PureStackStudio/Regor"
5867
target="_blank"
5968
rel="noopener"
6069
tone="neutral"

‎frontend/purestack.studio/guides/header.mdx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<a class="topbar__icon" href="https://github.com/PureStackStudio/PureStack" target="_blank" rel="noopener" aria-label="PureStack GitHub repository">
44
<Icon name="tabler:brand-github"/>
55
</a>
6+
<a class="topbar__icon" href="https://regor.purestack.studio" target="_blank" rel="noopener" aria-label="Regor website">
7+
<Icon name="lucide:orbit"/>
8+
</a>
69
<a class="topbar__icon" href="https://x.com/purestackstudio" target="_blank" rel="noopener" aria-label="PureStack Studio on X">
710
<Icon name="tabler:brand-x"/>
811
</a>

‎frontend/purestack.studio/header.mdx‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@
2020
>
2121
<Icon name="tabler:brand-github"/>
2222
</a>
23+
<a
24+
class="topbar__icon"
25+
href="https://regor.purestack.studio"
26+
target="_blank"
27+
rel="noopener"
28+
aria-label="Regor website"
29+
>
30+
<Icon name="lucide:orbit"/>
31+
</a>
2332
<a
2433
class="topbar__icon"
2534
href="https://x.com/purestackstudio"

‎frontend/purestack.studio/index.mdx‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,43 @@ card.<span class="syntax-blue">toCSS</span>()</code></pre>
426426
pieces that make PureStack work.
427427
</p>
428428
</Flex>
429+
<Grid
430+
container="article"
431+
class="regor-highlight"
432+
columns="1"
433+
columnsLg="1.2fr 0.8fr"
434+
alignItems="center"
435+
aria-labelledby="regor-title"
436+
>
437+
<div>
438+
<span class="eyebrow"><Icon name="lucide:orbit"/>POWERED BY REGOR</span>
439+
<h3 id="regor-title">Small signals. A whole frontend.</h3>
440+
<p class="regor-summary">
441+
Meet the reactive TypeScript library at PureStack's core. Regor connects
442+
state to HTML and SVG, composes components, and updates the DOM directly.
443+
The same component model renders your pages and powers your browser apps.
444+
</p>
445+
<Flex class="regor-actions" wrap="wrap" align="center">
446+
<BtnLink
447+
href="https://regor.purestack.studio"
448+
target="_blank"
449+
rel="noopener"
450+
tone="accent"
451+
variant="solid"
452+
icon="tabler:arrow-up-right"
453+
iconPosition="end"
454+
>Explore Regor</BtnLink
455+
>
456+
<BtnLink
457+
href="/guides/extending/regor/"
458+
tone="accent"
459+
variant="link"
460+
>Regor in PureStack</BtnLink
461+
>
462+
</Flex>
463+
</div>
464+
<StudioRegorConnection/>
465+
</Grid>
429466
<Grid class="package-grid" columns="1" columnsSm="2">
430467
<StudioPackage
431468
href="https://github.com/PureStackStudio/PureStack/tree/main/packages/ts-ssg"

‎frontend/theme/ecosystemStyles.ts‎

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import type { Style } from '@purestack/ts-css'
2-
import type { ThemePalette } from '@purestack/ts-style'
2+
import { BREAKPOINTS, mediaBelow, type ThemePalette } from '@purestack/ts-style'
33
import { studioTypography } from './studioSkin'
44

55
export function registerEcosystemStyles(root: Style, palette: ThemePalette) {
6-
const tone = palette.semanticTone
6+
registerSectionHeadingStyles(root, palette)
7+
registerRegorHighlightStyles(root, palette)
8+
registerPackageStyles(root, palette)
9+
registerEcosystemNoteStyles(root, palette)
10+
}
11+
12+
function registerSectionHeadingStyles(root: Style, palette: ThemePalette) {
713
root.select('.studio .split-heading').css({
814
gap: '40px',
915
})
@@ -12,6 +18,157 @@ export function registerEcosystemStyles(root: Style, palette: ThemePalette) {
1218
fontSize: palette.font.size.sm,
1319
paddingBottom: '3px',
1420
})
21+
}
22+
23+
function registerRegorHighlightStyles(root: Style, palette: ThemePalette) {
24+
const tone = palette.semanticTone
25+
root.select('.studio .regor-highlight').css({
26+
gap: '36px',
27+
padding: '36px',
28+
marginBottom: '24px',
29+
border: `1px solid ${tone.accent.surface.rest.border}`,
30+
borderRadius: palette.radii.lg,
31+
background: tone.accent.surface.rest.bgcolor,
32+
color: tone.accent.surface.rest.text,
33+
})
34+
root.select('.studio .regor-highlight > *').css({ minWidth: '0' })
35+
root.select('.studio .regor-highlight .eyebrow').css({
36+
display: 'flex',
37+
alignItems: 'center',
38+
gap: '8px',
39+
color: tone.accent.surface.rest.text,
40+
})
41+
root.select('.studio .regor-highlight h3').css({
42+
fontSize: palette.font.size.h4,
43+
letterSpacing: '-0.5px',
44+
lineHeight: '1.25',
45+
marginTop: '16px',
46+
})
47+
root.select('.studio .regor-summary').css({
48+
marginTop: '16px',
49+
fontSize: palette.font.size.sm,
50+
lineHeight: '1.8',
51+
})
52+
root.select('.studio .regor-actions').css({
53+
gap: '12px',
54+
marginTop: '24px',
55+
})
56+
registerRegorConnectionStyles(root, palette)
57+
root
58+
.media(mediaBelow(BREAKPOINTS.sm))
59+
.select('.studio .regor-highlight')
60+
.css({
61+
gap: '24px',
62+
padding: '24px',
63+
})
64+
}
65+
66+
function registerRegorConnectionStyles(root: Style, palette: ThemePalette) {
67+
registerRegorLoopPathStyles(root, palette)
68+
registerRegorLoopNodeStyles(root, palette)
69+
registerRegorLoopLabelStyles(root, palette)
70+
root.select('.studio .regor-connection figcaption').css({
71+
fontSize: palette.font.size.xs,
72+
lineHeight: '1.8',
73+
})
74+
}
75+
76+
function registerRegorLoopPathStyles(root: Style, palette: ThemePalette) {
77+
const tone = palette.semanticTone
78+
root.select('.studio .regor-connection').css({
79+
margin: '0',
80+
textAlign: 'center',
81+
})
82+
root.select('.studio .regor-loop').css({
83+
position: 'relative',
84+
height: '220px',
85+
maxWidth: '400px',
86+
marginInline: 'auto',
87+
})
88+
root.select('.studio .regor-loop-path').css({
89+
position: 'absolute',
90+
inset: '0',
91+
width: '100%',
92+
height: '100%',
93+
strokeWidth: '1.5',
94+
strokeLinecap: 'round',
95+
strokeLinejoin: 'round',
96+
})
97+
root
98+
.select('.studio .regor-loop-ui')
99+
.css({ stroke: tone.accent.text.default })
100+
root
101+
.select('.studio .regor-loop-docs')
102+
.css({ stroke: tone.secondary.text.default })
103+
}
104+
105+
function registerRegorLoopNodeStyles(root: Style, palette: ThemePalette) {
106+
const tone = palette.semanticTone
107+
root.select('.studio .regor-loop-node').css({
108+
position: 'absolute',
109+
top: '50%',
110+
transform: 'translate(-50%, -50%)',
111+
display: 'flex',
112+
flexDirection: 'column',
113+
alignItems: 'center',
114+
gap: '10px',
115+
fontSize: palette.font.size.sm,
116+
})
117+
root.select('.studio .regor-loop-node--regor').css({
118+
left: '22.222%',
119+
color: tone.accent.text.default,
120+
})
121+
root.select('.studio .regor-loop-node--purestack').css({
122+
left: '77.778%',
123+
color: tone.secondary.text.default,
124+
})
125+
root.select('.studio .regor-loop-mark').css({
126+
display: 'grid',
127+
placeItems: 'center',
128+
width: '64px',
129+
height: '64px',
130+
border: '1px solid color-mix(in srgb, currentColor 30%, transparent)',
131+
borderRadius: palette.radii.lg,
132+
background: tone.neutral.surface.rest.bgcolor,
133+
boxShadow: '0 8px 24px color-mix(in srgb, currentColor 10%, transparent)',
134+
})
135+
root.select('.studio .regor-loop-mark .icon').css({
136+
width: '32px',
137+
height: '32px',
138+
})
139+
}
140+
141+
function registerRegorLoopLabelStyles(root: Style, palette: ThemePalette) {
142+
const tone = palette.semanticTone
143+
root.select('.studio .regor-loop-label').css({
144+
position: 'absolute',
145+
left: '50%',
146+
transform: 'translate(-50%, -50%)',
147+
display: 'flex',
148+
alignItems: 'center',
149+
gap: '8px',
150+
padding: '5px 10px',
151+
borderRadius: palette.radii.pill,
152+
background: tone.accent.surface.rest.bgcolor,
153+
font: `10px ${studioTypography.mono}`,
154+
whiteSpace: 'nowrap',
155+
})
156+
root.select('.studio .regor-loop-label--ui').css({
157+
top: '35px',
158+
color: tone.accent.text.default,
159+
})
160+
root.select('.studio .regor-loop-label--docs').css({
161+
top: '185px',
162+
color: tone.secondary.text.default,
163+
})
164+
root.select('.studio .regor-loop-label .icon').css({
165+
width: '14px',
166+
height: '14px',
167+
})
168+
}
169+
170+
function registerPackageStyles(root: Style, palette: ThemePalette) {
171+
const tone = palette.semanticTone
15172
root.select('.studio .package-grid').css({
16173
border: `1px solid ${tone.neutral.border.subtle}`,
17174
borderRadius: '7px',
@@ -63,6 +220,10 @@ export function registerEcosystemStyles(root: Style, palette: ThemePalette) {
63220
padding: '0',
64221
border: '0',
65222
})
223+
}
224+
225+
function registerEcosystemNoteStyles(root: Style, palette: ThemePalette) {
226+
const tone = palette.semanticTone
66227
root.select('.studio .ecosystem-note').css({
67228
gap: '20px',
68229
marginTop: '22px',

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"frontend": "yarn tsx --watch packages/purestack/src/cli.ts serve --content frontend/purestack.studio --port 4700",
3636
"frontend:build": "yarn purestack build --content frontend/purestack.studio",
3737
"frontend:publish": "yarn purestack publish --content frontend/purestack.studio",
38+
"frontend:deploy": "pgdeploy deploy --host https://purestack.studio --package ./frontend/out/purestack.studio/web --allow-path 'pagefind/*,.ts-ssg/manifest.json'",
3839
"embed": "yarn tsx scripts/embed.ts && yarn format",
3940
"regor-components": "yarn tsx scripts/regor-components.ts",
4041
"gen-icons": "yarn tsx scripts/generate-icons.ts",

0 commit comments

Comments
 (0)