Skip to content

Commit 630f859

Browse files
authored
Merge pull request #761 from system-ui/docs-graph-illo
Update illustration for docs site
2 parents b29cac1 + 261da16 commit 630f859

File tree

17 files changed

+364
-311
lines changed

17 files changed

+364
-311
lines changed

packages/docs/package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@
1010
"build": "gatsby build",
1111
"serve": "gatsby serve",
1212
"clean": "gatsby clean",
13-
"logo": "npx capture-website-cli 'https://contrast.now.sh/cff/40f?size=32&fontSize=2&baseline=2&fontWeight=900&radius=32&text=UI' --width=32 --height=32 --overwrite static/icon.png",
14-
"card": "npx capture-website-cli 'https://contrast.now.sh/cff/40f?width=1280&height=720&fontWeight=900&fontSize=0.75&text=Theme+UI' --width=1280 --height=720 --overwrite static/card.png",
15-
"now-build": "gatsby build"
13+
"logo": "node ./scripts/svg-logo.js",
14+
"logo:png": "npx repng src/components/logo.js -d static -f logo.png -w=256 -h=256",
15+
"card": "npx repng src/components/og-image.js -d static -f card.png -w=1280 -h=720",
16+
"icon": "npx repng src/components/logo.js -d static -f icon.png -w=32 -h=32 --props='{\"size\":32}'"
1617
},
1718
"dependencies": {
1819
"@emotion/core": "^10.0.10",
1920
"@emotion/styled": "^10.0.10",
2021
"@mdx-js/mdx": "^1.0.0-rc.0",
2122
"@mdx-js/react": "^1.0.0-rc.0",
2223
"@styled-system/edit": "^5.0.15",
23-
"@theme-ui/css": "^0.3.1",
2424
"@theme-ui/color": "^0.3.1",
2525
"@theme-ui/components": "^0.3.1",
26+
"@theme-ui/css": "^0.3.1",
2627
"@theme-ui/editor": "^0.3.1",
2728
"@theme-ui/match-media": "^0.3.1",
2829
"@theme-ui/presets": "^0.3.0",
@@ -90,6 +91,7 @@
9091
"typography-theme-zacklive": "^1.0.2"
9192
},
9293
"devDependencies": {
94+
"@babel/register": "^7.8.6",
9395
"repng": "^3.2.0"
9496
}
9597
}

packages/docs/scripts/svg-logo.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require('@babel/register')({
2+
presets: ['@babel/preset-env', '@babel/preset-react'],
3+
})
4+
5+
const fs = require('fs')
6+
const path = require('path')
7+
const React = require('react')
8+
const { renderToStaticMarkup } = require('react-dom/server')
9+
const Logo = require('../src/components/logo').default
10+
const OGImage = require('../src/components/og-image').default
11+
12+
const h = React.createElement
13+
14+
const dirname = path.join(__dirname, '..', 'static')
15+
const files = {}
16+
const svg = {}
17+
18+
files.logo = path.join(dirname, 'logo.svg')
19+
files.card = path.join(dirname, 'card.svg')
20+
21+
svg.logo = renderToStaticMarkup(h(Logo))
22+
svg.card = renderToStaticMarkup(h(OGImage))
23+
24+
fs.writeFileSync(files.logo, svg.logo)
25+
fs.writeFileSync(files.card, svg.card)
26+
27+
console.log('SVG logo saved')

packages/docs/src/components/banner.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ export default props => (
2323
}}>
2424
<div
2525
sx={{
26-
pb: [5, 6],
26+
pt: 4,
27+
pb: 4,
2728
}}>
2829
<Container>{props.children}</Container>
2930
</div>

packages/docs/src/components/graph.js

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/** @jsx jsx */
2+
import { jsx, get, useThemeUI } from 'theme-ui'
3+
import { useState, useEffect, Fragment } from 'react'
4+
import merge from 'deepmerge'
5+
import Logo from './logo'
6+
7+
const colors = ['background', 'primary', 'secondary', 'accent']
8+
9+
const initialState = {
10+
0: {
11+
0: 0,
12+
1: 1,
13+
2: 1,
14+
3: 2,
15+
4: 2,
16+
5: 0,
17+
6: 0,
18+
7: 1,
19+
8: 3,
20+
9: 2,
21+
},
22+
1: {
23+
0: 1,
24+
1: 1,
25+
2: 1,
26+
3: 0,
27+
4: 1,
28+
5: 1,
29+
6: 1,
30+
7: 3,
31+
8: 3,
32+
9: 2,
33+
},
34+
2: {
35+
0: 0,
36+
1: 1,
37+
2: 0,
38+
3: 1,
39+
4: 1,
40+
5: 1,
41+
6: 1,
42+
7: 3,
43+
8: 0,
44+
9: 2,
45+
},
46+
}
47+
48+
const Node = ({ x, y, color = 0, ...props }) => {
49+
const inset = !!(y % 2)
50+
51+
// adjust for logo position
52+
const isLogo = y === 2 && x === 0
53+
54+
return (
55+
<circle
56+
{...props}
57+
cx={x * 3 + (inset ? 2.5 : 1)}
58+
cy={y * 3 + 1}
59+
r={1}
60+
fill="currentcolor"
61+
strokeWidth={1 / 8}
62+
sx={{
63+
color: isLogo ? 'background' : colors[color] || 'background',
64+
transitionProperty: 'stroke, color',
65+
transitionTimingFunction: 'ease-out',
66+
transitionDuration: '.4s',
67+
'&:hover': {
68+
stroke: t => t.colors.highlight,
69+
},
70+
}}
71+
/>
72+
)
73+
}
74+
75+
const Edges = ({ x, y, state }) => {
76+
const inset = !!(y % 2)
77+
const transform = `translate(${x * 3 + (inset ? 1 : 0)} ${y * 3})`
78+
const angles = []
79+
const active = state[y] && state[y][x]
80+
if (!active) return false
81+
const start = `M ${inset ? 1.5 : 1} 1`
82+
const paths = [`${start} h3`, `${start} l1.5 3`, `${start} l-1.5 3`]
83+
84+
if (state[y][x + 1]) {
85+
angles.push(0)
86+
}
87+
if (inset) {
88+
if (state[y + 1] && state[y + 1][x]) {
89+
angles.push(2)
90+
}
91+
if (state[y + 1] && state[y + 1][x + 1]) {
92+
angles.push(1)
93+
}
94+
} else {
95+
if (state[y + 1] && state[y + 1][x]) {
96+
angles.push(1)
97+
}
98+
if (state[y + 1] && state[y + 1][x - 1]) {
99+
angles.push(2)
100+
}
101+
}
102+
103+
return (
104+
<g transform={transform}>
105+
{angles.map(n => (
106+
<path
107+
key={n}
108+
d={paths[n]}
109+
fill="none"
110+
stroke="currentcolor"
111+
strokeWidth={1 / 4}
112+
sx={{
113+
color: colors[active],
114+
transitionProperty: 'stroke, color',
115+
transitionTimingFunction: 'ease-out',
116+
transitionDuration: '.4s',
117+
}}
118+
/>
119+
))}
120+
</g>
121+
)
122+
}
123+
124+
const rand = l => Math.floor(Math.random() * (l + 1))
125+
const randomizeColors = state => {
126+
const color = rand(colors.length - 1)
127+
return merge(state, {
128+
[rand(2)]: {
129+
[rand(9)]: color,
130+
},
131+
})
132+
}
133+
134+
export default ({ width = 32, height = 9, scale = 32 }) => {
135+
const { theme } = useThemeUI()
136+
const rows = Array.from({ length: height / 3 }).map((n, y) =>
137+
Array.from({
138+
length: Math.floor(width / 3 + (y % 2 ? 0 : 1)),
139+
}).map((o, x) => ({ x, y }))
140+
)
141+
const [state, setState] = useState(initialState)
142+
const viewBox = `0 0 ${width} ${height}`
143+
const dimensions = {
144+
width: width * scale,
145+
height: height * scale,
146+
}
147+
148+
useEffect(() => {
149+
const tick = () => {
150+
setState(randomizeColors)
151+
}
152+
const id = setInterval(tick, 600)
153+
return () => {
154+
clearInterval(id)
155+
}
156+
}, [])
157+
158+
const handleClick = ({ x, y }) => e => {
159+
const i = get(state, [y, x].join('.'), 0)
160+
const n = (i + 1) % colors.length
161+
setState(s =>
162+
merge(s, {
163+
[y]: {
164+
[x]: n,
165+
},
166+
})
167+
)
168+
}
169+
170+
const logo = {}
171+
logo.key = get(colors, get(state, '2.0'))
172+
if (logo.key !== 'background') {
173+
logo.color = get(theme.colors, logo.key)
174+
} else {
175+
logo.color = get(theme.colors, 'text')
176+
}
177+
178+
return (
179+
<svg
180+
xmlns="http://www.w3.org/2000/svg"
181+
viewBox={`0 0 ${width} ${height}`}
182+
width={width * scale}
183+
height={height * scale}
184+
sx={{
185+
maxWidth: '100%',
186+
width: '100%',
187+
height: 'auto',
188+
overflow: 'visible',
189+
userSelect: 'none',
190+
}}>
191+
<rect width={width} height={height} fill="none" />
192+
{rows.map(row =>
193+
row.map(({ x, y }) => (
194+
<g key={x + y}>
195+
<Edges x={x} y={y} state={state} />
196+
<Node
197+
x={x}
198+
y={y}
199+
color={get(state, [y, x].join('.'), 0)}
200+
onClick={handleClick({ x, y })}
201+
/>
202+
</g>
203+
))
204+
)}
205+
<g transform="translate(0 6)">
206+
<Logo size={2} color={logo.color} />
207+
</g>
208+
</svg>
209+
)
210+
}

0 commit comments

Comments
 (0)