docpensieve 0.1.0 → 0.1.2
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/README.md +5 -2
- package/bin/docpensieve.js +1 -0
- package/package.json +8 -6
- package/src/commands/dev.js +1 -1
- package/src/commands/init.js +214 -39
- package/starter/01-guide/01-installation.md +79 -0
- package/starter/01-guide/02-first-site.md +97 -0
- package/starter/01-guide/03-writing-pages.md +138 -0
- package/starter/01-guide/04-versions.md +179 -0
- package/starter/01-guide/05-themes.md +116 -0
- package/starter/01-guide/06-deployment.md +124 -0
- package/starter/01-guide/index.md +38 -0
- package/starter/02-components/01-card.mdx +195 -0
- package/starter/02-components/02-columns.mdx +193 -0
- package/starter/02-components/03-time-timer.mdx +120 -0
- package/starter/02-components/04-tooltip.mdx +100 -0
- package/starter/02-components/05-tree.mdx +163 -0
- package/starter/02-components/06-scroll-to-top.mdx +103 -0
- package/starter/02-components/07-skill.mdx +214 -0
- package/starter/02-components/08-logo-icon.mdx +122 -0
- package/starter/02-components/icons/banner.svg +15 -0
- package/starter/02-components/icons/book.svg +4 -0
- package/starter/02-components/icons/lightning.svg +3 -0
- package/starter/02-components/icons/shield.svg +4 -0
- package/starter/02-components/icons/star.svg +3 -0
- package/starter/02-components/index.md +41 -0
- package/starter/03-reference/01-cli.md +134 -0
- package/starter/03-reference/02-configuration.md +132 -0
- package/starter/03-reference/03-frontmatter.md +110 -0
- package/starter/03-reference/04-theme.md +149 -0
- package/starter/03-reference/index.md +32 -0
- package/starter/04-architecture.md +106 -0
- package/starter/icons/blocks.svg +6 -0
- package/starter/icons/book.svg +4 -0
- package/starter/icons/branch.svg +6 -0
- package/starter/icons/compass.svg +4 -0
- package/starter/icons/lightning.svg +3 -0
- package/starter/icons/list.svg +4 -0
- package/starter/icons/shield.svg +4 -0
- package/starter/icons/star.svg +3 -0
- package/starter/index.mdx +244 -0
- package/types/commands/init.d.ts +7 -4
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tree
|
|
3
|
+
description: Collapsible tree, built on native elements.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tree
|
|
7
|
+
|
|
8
|
+
Expanding is done by `<details>`: it works from the keyboard, survives
|
|
9
|
+
printing, and costs not a line of JavaScript.
|
|
10
|
+
|
|
11
|
+
## A file tree
|
|
12
|
+
|
|
13
|
+
Click a folder to expand it.
|
|
14
|
+
|
|
15
|
+
<Tree>
|
|
16
|
+
<TreeItem label="docpensieve.config.mjs" />
|
|
17
|
+
<TreeItem label="docs" open>
|
|
18
|
+
<TreeItem label="v1.0" open>
|
|
19
|
+
<TreeItem label="index.md" />
|
|
20
|
+
<TreeItem label="guide">
|
|
21
|
+
<TreeItem label="installation.md" />
|
|
22
|
+
<TreeItem label="configuration.md" />
|
|
23
|
+
</TreeItem>
|
|
24
|
+
<TreeItem label="components">
|
|
25
|
+
<TreeItem label="card.mdx" />
|
|
26
|
+
<TreeItem label="tree.mdx" />
|
|
27
|
+
</TreeItem>
|
|
28
|
+
</TreeItem>
|
|
29
|
+
</TreeItem>
|
|
30
|
+
<TreeItem label="dist" />
|
|
31
|
+
</Tree>
|
|
32
|
+
|
|
33
|
+
```mdx
|
|
34
|
+
<Tree>
|
|
35
|
+
<TreeItem label="docs" open>
|
|
36
|
+
<TreeItem label="index.md" />
|
|
37
|
+
</TreeItem>
|
|
38
|
+
</Tree>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Branch or leaf
|
|
42
|
+
|
|
43
|
+
The difference is read from the writing, with no prop to set: an entry **with
|
|
44
|
+
children** is a collapsible branch, an entry **without children** is a leaf.
|
|
45
|
+
`open` expands the branch as soon as the page opens.
|
|
46
|
+
|
|
47
|
+
<Columns>
|
|
48
|
+
<Column span={6}>
|
|
49
|
+
<Card className="h-full">
|
|
50
|
+
<CardHeader>Closed by default</CardHeader>
|
|
51
|
+
<CardBody>
|
|
52
|
+
<Tree>
|
|
53
|
+
<TreeItem label="package">
|
|
54
|
+
<TreeItem label="index.js" />
|
|
55
|
+
</TreeItem>
|
|
56
|
+
</Tree>
|
|
57
|
+
</CardBody>
|
|
58
|
+
</Card>
|
|
59
|
+
</Column>
|
|
60
|
+
<Column span={6}>
|
|
61
|
+
<Card className="h-full">
|
|
62
|
+
<CardHeader>Opened by `open`</CardHeader>
|
|
63
|
+
<CardBody>
|
|
64
|
+
<Tree>
|
|
65
|
+
<TreeItem label="package" open>
|
|
66
|
+
<TreeItem label="index.js" />
|
|
67
|
+
</TreeItem>
|
|
68
|
+
</Tree>
|
|
69
|
+
</CardBody>
|
|
70
|
+
</Card>
|
|
71
|
+
</Column>
|
|
72
|
+
</Columns>
|
|
73
|
+
|
|
74
|
+
## A plain list
|
|
75
|
+
|
|
76
|
+
Without any branch, the tree becomes a monospaced list — useful to list
|
|
77
|
+
produced files.
|
|
78
|
+
|
|
79
|
+
<Tree>
|
|
80
|
+
<TreeItem label="index.html" />
|
|
81
|
+
<TreeItem label="versions.json" />
|
|
82
|
+
<TreeItem label="assets/docpensieve.css" />
|
|
83
|
+
</Tree>
|
|
84
|
+
|
|
85
|
+
## Something that is not a file
|
|
86
|
+
|
|
87
|
+
Nothing forces you to describe a file tree. A data structure reads just as
|
|
88
|
+
well.
|
|
89
|
+
|
|
90
|
+
<Tree>
|
|
91
|
+
<TreeItem label="config" open>
|
|
92
|
+
<TreeItem label="projectName : string" />
|
|
93
|
+
<TreeItem label="siteUrl : string" />
|
|
94
|
+
<TreeItem label="versions" open>
|
|
95
|
+
<TreeItem label="slug : string" />
|
|
96
|
+
<TreeItem label="current : boolean" />
|
|
97
|
+
<TreeItem label="prerelease : boolean" />
|
|
98
|
+
</TreeItem>
|
|
99
|
+
<TreeItem label="theme">
|
|
100
|
+
<TreeItem label="framework : 'tailwind' | 'custom'" />
|
|
101
|
+
<TreeItem label="tokens : Record<string, string>" />
|
|
102
|
+
</TreeItem>
|
|
103
|
+
</TreeItem>
|
|
104
|
+
</Tree>
|
|
105
|
+
|
|
106
|
+
## A composite label
|
|
107
|
+
|
|
108
|
+
`label` accepts content, not just text.
|
|
109
|
+
|
|
110
|
+
<Tree>
|
|
111
|
+
<TreeItem
|
|
112
|
+
label={
|
|
113
|
+
<span>
|
|
114
|
+
📦 <strong>package</strong>
|
|
115
|
+
</span>
|
|
116
|
+
}
|
|
117
|
+
open
|
|
118
|
+
>
|
|
119
|
+
<TreeItem label={<code>index.js</code>} />
|
|
120
|
+
<TreeItem
|
|
121
|
+
label={
|
|
122
|
+
<span>
|
|
123
|
+
<em>types</em> — generated
|
|
124
|
+
</span>
|
|
125
|
+
}
|
|
126
|
+
/>
|
|
127
|
+
</TreeItem>
|
|
128
|
+
</Tree>
|
|
129
|
+
|
|
130
|
+
```mdx
|
|
131
|
+
<TreeItem
|
|
132
|
+
label={
|
|
133
|
+
<span>
|
|
134
|
+
📦 <strong>package</strong>
|
|
135
|
+
</span>
|
|
136
|
+
}
|
|
137
|
+
>
|
|
138
|
+
…
|
|
139
|
+
</TreeItem>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
> One caveat: what is written between braces is an **expression**, and the
|
|
143
|
+
> compiler does not read it — its result only exists at render time. A URL
|
|
144
|
+
> placed there is therefore not rewritten and will ignore the deployment
|
|
145
|
+
> prefix. For a link in a label, write the full URL.
|
|
146
|
+
|
|
147
|
+
## Styling the tree
|
|
148
|
+
|
|
149
|
+
<Tree className="text-indigo-700 dark:text-indigo-300">
|
|
150
|
+
<TreeItem label="in colour" open>
|
|
151
|
+
<TreeItem label="the children inherit" />
|
|
152
|
+
</TreeItem>
|
|
153
|
+
</Tree>
|
|
154
|
+
|
|
155
|
+
## What it does not announce
|
|
156
|
+
|
|
157
|
+
The structure is a nested list, not a `role="tree"`. That role promises a
|
|
158
|
+
screen reader arrow-key navigation that nothing here would implement:
|
|
159
|
+
announcing it would lie about what the page can do.
|
|
160
|
+
|
|
161
|
+
A `TreeItem` written outside a `Tree` is refused — it would produce an `<li>`
|
|
162
|
+
outside any list, invalid HTML that no browser reports. An entry without a
|
|
163
|
+
label is refused too.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ScrollToTop
|
|
3
|
+
description: Back to the top of the page, set by the shell or by hand.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ScrollToTop
|
|
7
|
+
|
|
8
|
+
A link to the `top` fragment, which the HTML specification reserves for the
|
|
9
|
+
top of the document when no element carries that identifier. Nothing to add to
|
|
10
|
+
the template, nothing to load.
|
|
11
|
+
|
|
12
|
+
## It is already there
|
|
13
|
+
|
|
14
|
+
**The button is set on every page**, by the shell. Back-to-top is page
|
|
15
|
+
furniture, not content: writing it in every file would mean repeating it
|
|
16
|
+
everywhere, and forgetting it somewhere.
|
|
17
|
+
|
|
18
|
+
Look at the bottom right of this page while scrolling: it is there without
|
|
19
|
+
anything having asked for it.
|
|
20
|
+
|
|
21
|
+
To remove it from the whole site:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
// docpensieve.config.mjs
|
|
25
|
+
scrollToTop: false,
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## The component, for special cases
|
|
29
|
+
|
|
30
|
+
`ScrollToTop` stays available when you want a button **in the flow of the
|
|
31
|
+
text**, with its own content — a pointer at the end of a chapter, for
|
|
32
|
+
instance.
|
|
33
|
+
|
|
34
|
+
<div className="flex flex-wrap items-center gap-3">
|
|
35
|
+
<ScrollToTop className="!static !inline-flex !w-auto !shadow-none px-4" label="Top of page">
|
|
36
|
+
Top
|
|
37
|
+
</ScrollToTop>
|
|
38
|
+
<ScrollToTop
|
|
39
|
+
className="!static !inline-flex !w-auto !shadow-none px-4"
|
|
40
|
+
label="Back to the summit"
|
|
41
|
+
>
|
|
42
|
+
↑ Summit
|
|
43
|
+
</ScrollToTop>
|
|
44
|
+
<ScrollToTop
|
|
45
|
+
className="!static !inline-flex !w-auto !shadow-none px-4 border-indigo-400 text-indigo-700"
|
|
46
|
+
label="Start reading again"
|
|
47
|
+
>
|
|
48
|
+
Start again
|
|
49
|
+
</ScrollToTop>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
```mdx
|
|
53
|
+
<ScrollToTop className="!static !inline-flex !w-auto" label="Top of page">
|
|
54
|
+
Top
|
|
55
|
+
</ScrollToTop>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
All three carry `!static`: that is what takes them out of the corner of the
|
|
59
|
+
screen to set them in the text. **Without this class, they would stack** on
|
|
60
|
+
top of the shell's button, all in the same place.
|
|
61
|
+
|
|
62
|
+
The accessible name stays set by `label`: without it, the link would announce
|
|
63
|
+
itself by its appearance alone.
|
|
64
|
+
|
|
65
|
+
## Appearing
|
|
66
|
+
|
|
67
|
+
It is driven by `animation-timeline: scroll()`: scrolling drives the
|
|
68
|
+
animation, with no event listener. Where the browser does not know that
|
|
69
|
+
property yet, the button simply stays visible — always there is better than
|
|
70
|
+
never there.
|
|
71
|
+
|
|
72
|
+
Smooth scrolling follows the same caution: it only applies to the pages that
|
|
73
|
+
carry this button, and only if the system does not ask for less motion.
|
|
74
|
+
|
|
75
|
+
## Room to breathe
|
|
76
|
+
|
|
77
|
+
Some text, so that the page is long enough to scroll and the appearance of the
|
|
78
|
+
button is noticeable.
|
|
79
|
+
|
|
80
|
+
The generator produces a static site: each page is a complete HTML file,
|
|
81
|
+
served as is. No hydration step, no bundle to download before reading. That is
|
|
82
|
+
what lets a component like this one be nothing but a link and two style rules.
|
|
83
|
+
|
|
84
|
+
A version lives on its own branch. The working branch keeps the sources, the
|
|
85
|
+
version branch keeps the output. The two never mix, and going back to an old
|
|
86
|
+
version does not require rebuilding anything.
|
|
87
|
+
|
|
88
|
+
The shipped components all follow the same rule: they provide the structure,
|
|
89
|
+
and the look is set at use. None of them embeds a hard-coded colour; all of
|
|
90
|
+
them read the tokens of the active theme.
|
|
91
|
+
|
|
92
|
+
When a page needs interaction, the answer is first sought in native elements —
|
|
93
|
+
`details` for expanding, a link for moving, a CSS transition for appearing.
|
|
94
|
+
Only after that, and rarely, would a script be justified.
|
|
95
|
+
|
|
96
|
+
This constraint has a happy side effect: a page stays readable in ten years,
|
|
97
|
+
because there is nothing that can stop working. No dependency to update, no
|
|
98
|
+
interface that breaks with the next browser.
|
|
99
|
+
|
|
100
|
+
And a less happy side effect, better known in advance: what depends on the
|
|
101
|
+
moment is frozen at build time. A page that shows “the offer ends tomorrow”
|
|
102
|
+
will still say so in six months if the site has not been rebuilt. A scheduled
|
|
103
|
+
build is enough to keep it right.
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Skill
|
|
3
|
+
description: Level gauge, filled in CSS.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill
|
|
7
|
+
|
|
8
|
+
A measure within a known range: that is exactly what the `meter` role
|
|
9
|
+
describes, which the gauge carries. The value is therefore announced, whether it
|
|
10
|
+
is shown as a figure or not.
|
|
11
|
+
|
|
12
|
+
## A gauge
|
|
13
|
+
|
|
14
|
+
<Skill name="Accessibility" level={85} />
|
|
15
|
+
<Skill name="Performance" level={92} />
|
|
16
|
+
<Skill name="Test coverage" level={64}>
|
|
17
|
+
Target: 90% on the shipped modules.
|
|
18
|
+
</Skill>
|
|
19
|
+
|
|
20
|
+
```mdx
|
|
21
|
+
<Skill name="Accessibility" level={85} />
|
|
22
|
+
<Skill name="Test coverage" level={64}>
|
|
23
|
+
Target: 90%.
|
|
24
|
+
</Skill>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Content passed as a child becomes a comment under the bar.
|
|
28
|
+
|
|
29
|
+
## As a circle
|
|
30
|
+
|
|
31
|
+
`shape="circle"` draws a dial rather than a bar. Useful when the gauges are
|
|
32
|
+
few and you want them to stand out.
|
|
33
|
+
|
|
34
|
+
<div className="flex flex-wrap">
|
|
35
|
+
<Skill name="Accessibility" level={85} shape="circle" />
|
|
36
|
+
<Skill name="Performance" level={92} shape="circle" />
|
|
37
|
+
<Skill name="Coverage" level={64} shape="circle" />
|
|
38
|
+
<Skill name="Types" level={100} shape="circle" />
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
```mdx
|
|
42
|
+
<Skill name="Accessibility" level={85} shape="circle" />
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The circle is a decorative SVG: its wrapper carries the role and the value, so
|
|
46
|
+
what is announced does not depend on what is drawn.
|
|
47
|
+
|
|
48
|
+
Its radius gives it a circumference of exactly a hundred units. The level then
|
|
49
|
+
goes as is into `stroke-dasharray`, with no multiplication or rounding — and
|
|
50
|
+
the entry animation only has to start from zero.
|
|
51
|
+
|
|
52
|
+
### Size
|
|
53
|
+
|
|
54
|
+
It is set through `--dp-skill-size`, on the gauge or on what surrounds it.
|
|
55
|
+
|
|
56
|
+
<div className="flex flex-wrap items-end" style={{ '--dp-skill-size': '4rem' }}>
|
|
57
|
+
<Skill name="Smaller" level={70} shape="circle" />
|
|
58
|
+
<Skill name="Also smaller" level={45} shape="circle" />
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
```mdx
|
|
62
|
+
<div style={{ '--dp-skill-size': '4rem' }}>
|
|
63
|
+
<Skill name="Smaller" level={70} shape="circle" />
|
|
64
|
+
</div>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### With a comment
|
|
68
|
+
|
|
69
|
+
<Skill name="Translations" level={40} shape="circle">
|
|
70
|
+
Two languages out of five.
|
|
71
|
+
</Skill>
|
|
72
|
+
|
|
73
|
+
### Without the figure
|
|
74
|
+
|
|
75
|
+
<div className="flex flex-wrap">
|
|
76
|
+
<Skill name="Silent" level={55} shape="circle" showValue={false} />
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
There again, the figure leaves the screen but not what the gauge announces.
|
|
80
|
+
|
|
81
|
+
## With an icon and a colour
|
|
82
|
+
|
|
83
|
+
`icon` goes before the name — a [LogoIcon](./logo-icon/) fits there.
|
|
84
|
+
`color` tints the fill **and** the icon: both designate the same thing, and
|
|
85
|
+
seeing them match helps read a column of gauges at a glance.
|
|
86
|
+
|
|
87
|
+
<Skill name="Speed" level={92} color="#f59e0b" icon={<LogoIcon src="./icons/lightning.svg" />} />
|
|
88
|
+
<Skill name="Safety" level={78} color="#10b981" icon={<LogoIcon src="./icons/shield.svg" />} />
|
|
89
|
+
<Skill name="Documentation" level={64} color="#6366f1" icon={<LogoIcon src="./icons/book.svg" />} />
|
|
90
|
+
|
|
91
|
+
```mdx
|
|
92
|
+
<Skill name="Speed" level={92} color="#f59e0b" icon={<LogoIcon src="./icons/lightning.svg" />} />
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`color` accepts any CSS colour. Without it, the theme's accent colour applies.
|
|
96
|
+
|
|
97
|
+
### As a circle too
|
|
98
|
+
|
|
99
|
+
<div className="flex flex-wrap">
|
|
100
|
+
<Skill
|
|
101
|
+
name="Speed"
|
|
102
|
+
level={92}
|
|
103
|
+
shape="circle"
|
|
104
|
+
color="#f59e0b"
|
|
105
|
+
icon={<LogoIcon src="./icons/lightning.svg" />}
|
|
106
|
+
/>
|
|
107
|
+
<Skill
|
|
108
|
+
name="Safety"
|
|
109
|
+
level={78}
|
|
110
|
+
shape="circle"
|
|
111
|
+
color="#10b981"
|
|
112
|
+
icon={<LogoIcon src="./icons/shield.svg" />}
|
|
113
|
+
/>
|
|
114
|
+
<Skill
|
|
115
|
+
name="Favourite"
|
|
116
|
+
level={55}
|
|
117
|
+
shape="circle"
|
|
118
|
+
color="#ec4899"
|
|
119
|
+
icon={<LogoIcon src="./icons/star.svg" />}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
### Tinting a whole group
|
|
124
|
+
|
|
125
|
+
The tint goes through `--dp-skill-color`: setting it on a container applies to
|
|
126
|
+
every gauge it holds.
|
|
127
|
+
|
|
128
|
+
<div style={{ '--dp-skill-color': '#0ea5e9' }}>
|
|
129
|
+
<Skill name="First" level={70} />
|
|
130
|
+
<Skill name="Second" level={45} />
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
```mdx
|
|
134
|
+
<div style={{ '--dp-skill-color': '#0ea5e9' }}>
|
|
135
|
+
<Skill name="First" level={70} />
|
|
136
|
+
</div>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## The bounds
|
|
140
|
+
|
|
141
|
+
`level` goes from 0 to 100. Both extremes render with no special case.
|
|
142
|
+
|
|
143
|
+
<Skill name="Not started" level={0} />
|
|
144
|
+
<Skill name="Done" level={100} />
|
|
145
|
+
|
|
146
|
+
## Without the figure
|
|
147
|
+
|
|
148
|
+
<Skill name="Restraint" level={70} showValue={false} />
|
|
149
|
+
|
|
150
|
+
```mdx
|
|
151
|
+
<Skill name="Restraint" level={70} showValue={false} />
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`showValue={false}` removes the percentage **from the screen only**: the gauge
|
|
155
|
+
keeps announcing it to screen readers. Hiding a piece of information is not
|
|
156
|
+
deleting it.
|
|
157
|
+
|
|
158
|
+
## A dashboard
|
|
159
|
+
|
|
160
|
+
Several gauges in columns, each in its card.
|
|
161
|
+
|
|
162
|
+
<Columns>
|
|
163
|
+
<Column span={6}>
|
|
164
|
+
<Card className="h-full">
|
|
165
|
+
<CardHeader>Quality</CardHeader>
|
|
166
|
+
<CardBody>
|
|
167
|
+
<Skill name="Tests" level={88} />
|
|
168
|
+
<Skill name="Types" level={95} />
|
|
169
|
+
<Skill name="Documentation" level={72} />
|
|
170
|
+
</CardBody>
|
|
171
|
+
</Card>
|
|
172
|
+
</Column>
|
|
173
|
+
<Column span={6}>
|
|
174
|
+
<Card className="h-full">
|
|
175
|
+
<CardHeader>Delivery</CardHeader>
|
|
176
|
+
<CardBody>
|
|
177
|
+
<Skill name="Continuous integration" level={100} />
|
|
178
|
+
<Skill name="Translations" level={40}>
|
|
179
|
+
Two languages out of five.
|
|
180
|
+
</Skill>
|
|
181
|
+
<Skill name="Site online" level={100} />
|
|
182
|
+
</CardBody>
|
|
183
|
+
</Card>
|
|
184
|
+
</Column>
|
|
185
|
+
</Columns>
|
|
186
|
+
|
|
187
|
+
## Styling the gauge
|
|
188
|
+
|
|
189
|
+
The component classes live below the utilities: a `className` set at use wins.
|
|
190
|
+
|
|
191
|
+
<Skill className="max-w-sm" name="Reduced width" level={55} />
|
|
192
|
+
|
|
193
|
+
<div className="[&_.dp-skill-fill]:bg-emerald-500">
|
|
194
|
+
<Skill name="Green fill" level={78} />
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
```mdx
|
|
198
|
+
<div className="[&_.dp-skill-fill]:bg-emerald-500">
|
|
199
|
+
<Skill name="Green fill" level={78} />
|
|
200
|
+
</div>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## The fill
|
|
204
|
+
|
|
205
|
+
It animates as it enters the viewport, through `animation-timeline: view()`,
|
|
206
|
+
over a range wide enough for the movement to be seen rather than flicker.
|
|
207
|
+
Where that property is missing, or if the system asks for less motion, the bar
|
|
208
|
+
is full from the start — the value stays readable, which is what matters.
|
|
209
|
+
|
|
210
|
+
## What it refuses
|
|
211
|
+
|
|
212
|
+
A level outside 0–100 stops the build, as does a gauge without a name, a level
|
|
213
|
+
that is not a number, or an unknown `shape`. A silent or overflowing bar goes
|
|
214
|
+
unnoticed on review.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: LogoIcon
|
|
3
|
+
description: SVG icon inlined in the page at build time.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# LogoIcon
|
|
7
|
+
|
|
8
|
+
The file is read at build time and its content placed in the page. That is
|
|
9
|
+
what lets it take its colour from `currentColor` and be sized like the rest of
|
|
10
|
+
the text — impossible through an `img` tag, which isolates the document.
|
|
11
|
+
|
|
12
|
+
## An icon
|
|
13
|
+
|
|
14
|
+
<LogoIcon src="./icons/book.svg" label="Documentation" />
|
|
15
|
+
<LogoIcon src="./icons/star.svg" label="Favourite" />
|
|
16
|
+
<LogoIcon src="./icons/lightning.svg" label="Fast" />
|
|
17
|
+
<LogoIcon src="./icons/shield.svg" label="Verified" />
|
|
18
|
+
|
|
19
|
+
```mdx
|
|
20
|
+
<LogoIcon src="./icons/book.svg" label="Documentation" />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
A relative path starts from the page, an absolute path from the version
|
|
24
|
+
folder. Nothing can leave it: a page does not read the rest of the machine.
|
|
25
|
+
|
|
26
|
+
## It follows the text
|
|
27
|
+
|
|
28
|
+
Placed in a text, the icon takes its size and colour.
|
|
29
|
+
|
|
30
|
+
<div className="text-indigo-600 text-2xl">
|
|
31
|
+
<LogoIcon src="./icons/star.svg" /> at the size and colour of the text
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div className="text-sm text-slate-500">
|
|
35
|
+
<LogoIcon src="./icons/star.svg" /> and here, smaller and greyer
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
## Sizes
|
|
39
|
+
|
|
40
|
+
`size` accepts any CSS length.
|
|
41
|
+
|
|
42
|
+
<div className="flex items-end gap-4 text-emerald-600">
|
|
43
|
+
<LogoIcon src="./icons/shield.svg" size="1rem" />
|
|
44
|
+
<LogoIcon src="./icons/shield.svg" size="2rem" />
|
|
45
|
+
<LogoIcon src="./icons/shield.svg" size="3rem" />
|
|
46
|
+
<LogoIcon src="./icons/shield.svg" size="4rem" />
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
```mdx
|
|
50
|
+
<LogoIcon src="./icons/shield.svg" size="3rem" className="text-emerald-600" />
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The colour only follows if the file relies on `currentColor` rather than on a
|
|
54
|
+
fixed colour.
|
|
55
|
+
|
|
56
|
+
## In a list
|
|
57
|
+
|
|
58
|
+
<ul className="list-none pl-0 space-y-2">
|
|
59
|
+
<li className="flex items-center gap-2">
|
|
60
|
+
<LogoIcon src="./icons/lightning.svg" size="1.1rem" className="text-amber-500" /> No script to
|
|
61
|
+
load
|
|
62
|
+
</li>
|
|
63
|
+
<li className="flex items-center gap-2">
|
|
64
|
+
<LogoIcon src="./icons/shield.svg" size="1.1rem" className="text-emerald-600" /> Links are read
|
|
65
|
+
back before publishing
|
|
66
|
+
</li>
|
|
67
|
+
<li className="flex items-center gap-2">
|
|
68
|
+
<LogoIcon src="./icons/book.svg" size="1.1rem" className="text-indigo-600" /> One version per
|
|
69
|
+
branch
|
|
70
|
+
</li>
|
|
71
|
+
</ul>
|
|
72
|
+
|
|
73
|
+
## At the head of a card
|
|
74
|
+
|
|
75
|
+
<Columns>
|
|
76
|
+
<Column span={6}>
|
|
77
|
+
<Card className="h-full">
|
|
78
|
+
<CardBody>
|
|
79
|
+
<LogoIcon src="./icons/lightning.svg" size="1.6rem" className="text-amber-500" />
|
|
80
|
+
<strong className="block mt-2 mb-1 text-base font-semibold">Fast</strong>
|
|
81
|
+
|
|
82
|
+
No hydration, no bundle to download before reading.
|
|
83
|
+
</CardBody>
|
|
84
|
+
</Card>
|
|
85
|
+
|
|
86
|
+
</Column>
|
|
87
|
+
<Column span={6}>
|
|
88
|
+
<Card className="h-full">
|
|
89
|
+
<CardBody>
|
|
90
|
+
<LogoIcon src="./icons/shield.svg" size="1.6rem" className="text-emerald-600" />
|
|
91
|
+
<strong className="block mt-2 mb-1 text-base font-semibold">Verified</strong>
|
|
92
|
+
|
|
93
|
+
Dead links and invalid markup stop the publication.
|
|
94
|
+
</CardBody>
|
|
95
|
+
</Card>
|
|
96
|
+
|
|
97
|
+
</Column>
|
|
98
|
+
</Columns>
|
|
99
|
+
|
|
100
|
+
## Decorative or meaningful
|
|
101
|
+
|
|
102
|
+
Without `label`, the icon is treated as decorative and hidden from screen
|
|
103
|
+
readers — which is right when nearby text already says the same thing. With
|
|
104
|
+
`label`, it becomes a described image.
|
|
105
|
+
|
|
106
|
+
```mdx
|
|
107
|
+
<LogoIcon src="./icons/star.svg" />
|
|
108
|
+
<LogoIcon src="./icons/star.svg" label="Favourite" />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
In the list above, the icons have no `label`: the text next to them already
|
|
112
|
+
carries the meaning, and announcing it twice would tell nothing.
|
|
113
|
+
|
|
114
|
+
## What it refuses
|
|
115
|
+
|
|
116
|
+
A missing file, a file without an `svg` tag, a target leaving the version
|
|
117
|
+
folder: each one stops the build, naming the expected path. A missing icon
|
|
118
|
+
would otherwise leave an empty box that nobody notices.
|
|
119
|
+
|
|
120
|
+
The scripts and event handlers present in a file are removed before inlining.
|
|
121
|
+
The produced site loads no JavaScript, and a component is not going to
|
|
122
|
+
introduce any.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 120" role="img" aria-label="Decorative banner">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="dp-b" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#6366f1" />
|
|
5
|
+
<stop offset="1" stop-color="#0ea5e9" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="320" height="120" fill="url(#dp-b)" />
|
|
9
|
+
<g fill="none" stroke="#ffffff" stroke-opacity="0.45" stroke-width="2">
|
|
10
|
+
<circle cx="62" cy="60" r="26" />
|
|
11
|
+
<circle cx="160" cy="60" r="40" />
|
|
12
|
+
<circle cx="258" cy="60" r="26" />
|
|
13
|
+
<path d="M0 92h320M0 28h320" />
|
|
14
|
+
</g>
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" />
|
|
3
|
+
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Components
|
|
3
|
+
description: The components available in every page, without an import.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Components
|
|
7
|
+
|
|
8
|
+
These components can be used in any `.mdx` page **without an import**.
|
|
9
|
+
|
|
10
|
+
They provide the **structure** — wrappers, separators, spacing. The look is set
|
|
11
|
+
with `className`, in utilities of the active theme:
|
|
12
|
+
|
|
13
|
+
```mdx
|
|
14
|
+
<Card className="max-w-sm">
|
|
15
|
+
<CardHeader className="text-center font-bold">Title</CardHeader>
|
|
16
|
+
</Card>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The component classes live in the `components` layer, below the utilities: a
|
|
20
|
+
`className` set at use always wins.
|
|
21
|
+
|
|
22
|
+
## Available
|
|
23
|
+
|
|
24
|
+
- [Card](./card/) — card, with header, body, footer and image
|
|
25
|
+
- [Columns](./columns/) — column grid
|
|
26
|
+
- [TimeTimer](./time-timer/) — display depending on a date
|
|
27
|
+
- [Tooltip](./tooltip/) — tooltip on hover and from the keyboard
|
|
28
|
+
- [Tree](./tree/) — collapsible tree
|
|
29
|
+
- [ScrollToTop](./scroll-to-top/) — back to the top of the page
|
|
30
|
+
- [Skill](./skill/) — level gauge
|
|
31
|
+
- [LogoIcon](./logo-icon/) — SVG icon inlined in the page
|
|
32
|
+
|
|
33
|
+
## Without JavaScript
|
|
34
|
+
|
|
35
|
+
The produced site loads no script. Whatever needs interaction therefore goes
|
|
36
|
+
through native elements or through CSS: `details` for expanding, a link for
|
|
37
|
+
moving, `animation-timeline` for appearing on scroll.
|
|
38
|
+
|
|
39
|
+
When the browser does not know one of these properties yet, the component stays
|
|
40
|
+
usable in its simplest state — visible, full, expanded. None of them waits for
|
|
41
|
+
a capability to work.
|