Skip to content

Commit be7ddbb

Browse files
committed
Enable darkmode and refactoring
1 parent 53fffa0 commit be7ddbb

12 files changed

+309
-76
lines changed

package-lock.json

Lines changed: 1 addition & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"repository": "csstree/docs",
44
"dependencies": {},
55
"devDependencies": {
6-
"highcharts": "^9.0.0",
76
"@discoveryjs/discovery": "1.0.0-beta.78",
87
"@discoveryjs/cli": "^2.6.0",
98
"css-tree": "^2.3.1",

src/syntax/config.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
module.exports = {
22
name: 'CSS syntax reference (mdn/data & CSSTree)',
33
basedir: __dirname,
4-
darkmode: 'disabled',
54
data: './data',
65
prepare: './prepare',
76
view: {
87
assets: [
98
'ui/sidebar.css',
109
'ui/sidebar.js',
11-
'ui/view/chart.css',
12-
'ui/view/chart.js',
10+
'ui/view/bar-chart.css',
11+
'ui/view/bar-chart.js',
1312
'ui/page/default.css',
1413
'ui/page/default.js',
1514
'ui/page/problems.css',

src/syntax/ui/page/default.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
margin: 0 4px 0 0;
55
background: rgba(130, 195, 11, 0.32);
66
}
7+
.discovery-root-darkmode .page-default .versions .view-badge {
8+
background-color: #446130
9+
}
710

811
.page-default .versions .view-badge .prefix {
912
padding: 5px 8px 6px;

src/syntax/ui/page/default.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ discovery.page.define('default', [
44
{
55
view: 'page-header',
66
content: [
7-
'h1:#.name',
7+
'h1:#.model.name',
88
{
99
view: 'block',
1010
className: 'versions',
@@ -45,7 +45,7 @@ discovery.page.define('default', [
4545
{
4646
title: 'Syntax stat',
4747
query: '[\n { header: \'Types\', data: dict.group(=>type).({ type: key, count: value.size() }) },\n { header: \'Origin\', data: dict.({ type, name, mdn: mdn().syntax, csstree: syntax(), patch: patch() })\n .[type!="Function"]\n .group(=>\n csstree="(generic)" ? "Generic" :\n no mdn ? \'Added (missed in MDN data)\' :\n patch ? \'Patched MDN data\'\n : \'As is from MDN data\'\n )\n .({ type: key, count: value.size() })\n }\n]',
48-
view: '{\n view: \'list\',\n item: [\n \'h2:header\',\n {\n view: \'hstack\',\n data: \'data\',\n content: [\n \'table\',\n \'chart:.({ y: count, name: type })\'\n ]\n }\n ]\n}'
48+
view: '{\n view: \'list\',\n item: [\n \'h2:header\',\n \'bar-chart{ vertical: true, data: data.({ x: type, y: count }) }\'\n ]\n}'
4949
},
5050
// {
5151
// title: 'csstree & mdn-data parity',

src/syntax/ui/page/syntax-page.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const page = {
66
content: [
77
{
88
view: 'page-header',
9-
prelude: 'badge:{ text: type, color: "rgba(237, 177, 9, 0.35)" }',
9+
prelude: 'badge:{ text: type, color: "#ffdc7959" }',
1010
content: 'h1:formatName()'
1111
},
1212
{

src/syntax/ui/view/bar-chart.css

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
.view-bar-chart {
2+
--values-padding: 0 3px;
3+
--fill-bar-direction: top;
4+
--value-line-direction: bottom;
5+
--x-direction: row;
6+
--x-labels-border: 1px 0 0 0;
7+
--x-labels-padding: 4px 3px;
8+
--y-direction: column-reverse;
9+
10+
display: grid;
11+
grid-template-areas:
12+
"y-labels canvas"
13+
"- x-labels";
14+
grid-template-columns: min-content 1fr;
15+
padding-top: 5px;
16+
}
17+
.view-bar-chart.vertical {
18+
--values-padding: 5px 0;
19+
--fill-bar-direction: right;
20+
--value-line-direction: left;
21+
--x-direction: column;
22+
--x-labels-border: 0 1px 0 0;
23+
--x-labels-padding: 5px 4px;
24+
--y-direction: row;
25+
26+
grid-template-areas:
27+
"x-labels canvas"
28+
"- y-labels";
29+
}
30+
.view-bar-chart .canvas {
31+
grid-area: canvas;
32+
display: flex;
33+
flex-direction: var(--x-direction);
34+
align-items: stretch;
35+
gap: 1px;
36+
min-height: 200px;
37+
padding: var(--values-padding);
38+
background-size: calc(100% / (var(--y-label-count) - 1))
39+
calc(100% / (var(--y-label-count) - 1));
40+
background-image: linear-gradient(
41+
to var(--value-line-direction),
42+
#8883 1px,
43+
transparent 0
44+
);
45+
}
46+
.view-bar-chart.vertical .canvas {
47+
min-height: auto;
48+
}
49+
.view-bar-chart .canvas .bar {
50+
flex: 1;
51+
}
52+
.view-bar-chart.vertical .canvas .bar {
53+
position: relative;
54+
min-height: 13px;
55+
}
56+
@keyframes chart-bar-grow {
57+
from,
58+
30% {
59+
--size: 0;
60+
}
61+
}
62+
.view-bar-chart .canvas .bar::before {
63+
content: "";
64+
display: block;
65+
height: 100%;
66+
/* animation: 0.9s ease chart-bar-grow; */
67+
background-image: linear-gradient(
68+
to var(--fill-bar-direction),
69+
var(--color, #54a6eea6)
70+
max(min(1px, var(--size) * 1000000px), calc(var(--size) * 100%)),
71+
transparent 0
72+
);
73+
}
74+
.view-bar-chart .canvas .bar:hover {
75+
background: #fff2;
76+
}
77+
78+
.view-bar-chart .y-labels {
79+
grid-area: y-labels;
80+
display: flex;
81+
flex-direction: var(--y-direction);
82+
justify-content: stretch;
83+
position: relative;
84+
}
85+
.view-bar-chart .y-label {
86+
flex: 1;
87+
min-width: 4ex;
88+
opacity: 0.75;
89+
line-height: 1;
90+
font-size: 10px;
91+
text-align: right;
92+
}
93+
.view-bar-chart:not(.vertical) .y-label {
94+
margin-top: -5px;
95+
margin-right: 6px;
96+
}
97+
.view-bar-chart.vertical .y-label {
98+
writing-mode: vertical-rl;
99+
transform: translate(-10px) rotate(215deg);
100+
transform-origin: right center;
101+
}
102+
.view-bar-chart:not(.vertical) .y-label:first-child {
103+
position: absolute;
104+
right: 0;
105+
margin-bottom: -5px;
106+
}
107+
.view-bar-chart.vertical .y-label:first-child {
108+
position: absolute;
109+
left: 0;
110+
margin-left: -5px;
111+
}
112+
113+
.view-bar-chart .x-labels {
114+
grid-area: x-labels;
115+
position: relative;
116+
display: flex;
117+
flex-direction: var(--x-direction);
118+
justify-content: space-around;
119+
gap: 1px;
120+
border: solid #8883;
121+
border-width: var(--x-labels-border);
122+
padding: var(--x-labels-padding);
123+
cursor: default;
124+
}
125+
.view-bar-chart .x-label {
126+
white-space: nowrap;
127+
line-height: 1;
128+
font-size: 14px;
129+
text-align: right;
130+
opacity: 0.75;
131+
}
132+
.view-bar-chart:not(.vertical) .x-label {
133+
writing-mode: vertical-rl;
134+
transform: translate(calc(-50% - 15px), -5px) rotate(215deg);
135+
transform-origin: right center;
136+
}
137+
.view-bar-chart.vertical .x-label {
138+
padding: 1px 0 2px;
139+
}
140+
141+
.chart-tooltip {
142+
padding: 5px 10px;
143+
min-width: 120px;
144+
border: 0.5px solid #fff5;
145+
border-radius: 3px;
146+
font-size: 12px;
147+
background: rgba(255, 255, 255, 0.75);
148+
-webkit-backdrop-filter: blur(4px);
149+
backdrop-filter: blur(4px);
150+
}
151+
.discovery-root-darkmode .chart-tooltip {
152+
background: rgba(36, 36, 36, 0.8);
153+
}
154+
.chart-tooltip .view-badge {
155+
display: inline-block;
156+
margin: 0 0 3px -5px;
157+
padding-top: 0;
158+
padding-bottom: 1px;
159+
line-height: 19px;
160+
}
161+

src/syntax/ui/view/bar-chart.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* eslint-env browser */
2+
/* global discovery */
3+
4+
const dataByEl = new WeakMap();
5+
6+
new discovery.view.Popup({
7+
className: 'chart-tooltip',
8+
hoverTriggers: '.view-chart .bar',
9+
position: 'pointer',
10+
render(el, triggerEl) {
11+
const { data, context } = dataByEl.get(triggerEl);
12+
13+
discovery.view.render(
14+
el,
15+
[
16+
{ view: 'block', content: 'text:labelText' },
17+
{
18+
view: 'block',
19+
content: "text-numeric:value = undefined ? '–' : value"
20+
}
21+
],
22+
data,
23+
context
24+
);
25+
}
26+
});
27+
28+
// CSS.registerProperty({
29+
// name: "--size",
30+
// initialValue: 0,
31+
// syntax: "<number>",
32+
// inherits: true,
33+
// });
34+
35+
discovery.view.define('bar-chart', (el, config, data, context) => {
36+
function addBar(x, y) {
37+
const barEl = canvasEl.appendChild(document.createElement('div'));
38+
const labelEl = xLabelsEl.appendChild(document.createElement('div'));
39+
const num = xLabelsEl.children.length - 1;
40+
const labelText = labelX(x, num);
41+
42+
barEl.className = y === undefined ? 'bar empty' : 'bar';
43+
barEl.style.setProperty('--size', (y || 0) / roundedMaxY);
44+
labelEl.className = 'x-label';
45+
labelEl.textContent = labelText;
46+
labelEl.style.setProperty('--num', num);
47+
48+
dataByEl.set(barEl, {
49+
context,
50+
data: {
51+
value: y,
52+
labelNum: num,
53+
labelRaw: x,
54+
labelText
55+
}
56+
});
57+
}
58+
59+
const { vertical } = config;
60+
let { nextX, labelX } = config;
61+
const sortedData = data.slice().sort((a, b) => (a.x < b.x ? -1 : 1));
62+
const maxY = sortedData.reduce((maxY, { y }) => Math.max(maxY, y), 0);
63+
let roundedMaxY = maxY;
64+
const minY = sortedData.reduce((minY, { y }) => Math.min(minY, y), Infinity);
65+
66+
if (typeof nextX !== 'function') {
67+
nextX = (_, current) => current;
68+
}
69+
70+
if (typeof labelX !== 'function') {
71+
labelX = value => value;
72+
}
73+
74+
// find better split
75+
76+
const canvasEl = el.appendChild(document.createElement('div'));
77+
const xLabelsEl = el.appendChild(document.createElement('div'));
78+
const yLabelsEl = el.appendChild(document.createElement('div'));
79+
80+
canvasEl.className = 'canvas';
81+
xLabelsEl.className = 'x-labels';
82+
yLabelsEl.className = 'y-labels';
83+
84+
// console.log({ minY, maxY });
85+
// round maxY
86+
if (maxY - minY > 5) {
87+
const allowedGrowth = maxY - minY < 20 ? 1.8 : 1.15;
88+
let base = maxY - minY < 100 ? 5 : 10;
89+
90+
while (true) {
91+
const add = base - (roundedMaxY % base);
92+
93+
if ((roundedMaxY + add) / maxY > allowedGrowth) {
94+
break;
95+
}
96+
97+
roundedMaxY += add;
98+
// console.log({ normMaxY });
99+
base *= 10;
100+
}
101+
} else {
102+
roundedMaxY = 5;
103+
}
104+
105+
for (
106+
let i = 0, n = roundedMaxY % 5 ? 5 : 6, step = roundedMaxY / (n - 1);
107+
i < n;
108+
i++
109+
) {
110+
const labelEl = yLabelsEl.appendChild(document.createElement('div'));
111+
labelEl.textContent = step * i;
112+
labelEl.className = 'y-label';
113+
}
114+
115+
let prev = sortedData[0].x;
116+
for (const { x, y } of sortedData) {
117+
while (prev !== x) {
118+
prev = nextX(prev, x);
119+
if (prev !== x) {
120+
addBar(prev);
121+
}
122+
}
123+
124+
addBar(x, y);
125+
prev = x;
126+
}
127+
128+
el.style.setProperty('--y-label-count', yLabelsEl.children.length);
129+
el.style.setProperty('--x-label-count', xLabelsEl.children.length);
130+
131+
el.classList.toggle('vertical', Boolean(vertical));
132+
el.append(yLabelsEl, canvasEl, xLabelsEl);
133+
});

0 commit comments

Comments
 (0)