@pokela/components 1.1.0 → 1.2.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/README.md +3 -2
- package/ThemeScript.d.ts +12 -0
- package/ThemeScript.js +16 -0
- package/ThemeToggle.d.ts +15 -0
- package/ThemeToggle.js +49 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +2 -2
- package/styles/base.css +21 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @pokela/components
|
|
2
2
|
|
|
3
|
-
React-komponentit: **Pokela Design System**, versio 1.
|
|
3
|
+
React-komponentit: **Pokela Design System**, versio 1.2.0.
|
|
4
4
|
|
|
5
5
|
> Generoitu hakemistosta `components/` — samoista tiedostoista joita sivusto
|
|
6
6
|
> ajaa. Älä muokkaa käsin: muutokset tehdään lähteeseen ja paketti
|
|
@@ -23,6 +23,8 @@ tarvita.
|
|
|
23
23
|
- `Accordion`
|
|
24
24
|
- `Grid`
|
|
25
25
|
- `Reveal`
|
|
26
|
+
- `ThemeScript`
|
|
27
|
+
- `ThemeToggle`
|
|
26
28
|
|
|
27
29
|
### Linkit
|
|
28
30
|
|
|
@@ -41,7 +43,6 @@ import Link from 'next/link';
|
|
|
41
43
|
- **Nav, Footer** — tarvitsevat sivuston sanakirjan ja reitityksen
|
|
42
44
|
- **BeforeAfter** — rakentuu Median varaan, ja Media lukee kuvamanifestia
|
|
43
45
|
- **ComponentView, PrintCv** — ovat riippumattomia mutta sivuston ominaisuuksia — lähdekoodinäkymä ja CV:n tulostusasu — eivät design systemin osia
|
|
44
|
-
- **ThemeToggle, ThemeScript** — teemanvaihto käyttää luokkaa `.nav__toggle`, joka on määritelty Navin tyyleissä. Kytkentä on lähteessä eikä paketoinnissa, joten se korjataan CSS:ää siistimällä eikä tätä listaa muuttamalla
|
|
45
46
|
|
|
46
47
|
## Tyylit
|
|
47
48
|
|
package/ThemeScript.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teeman palautus ennen ensimmäistä maalausta.
|
|
3
|
+
*
|
|
4
|
+
* Ilman tätä sivu välähtäisi vaaleana ennen kuin tallennettu tumma
|
|
5
|
+
* teema ehtii päälle. Skripti on tarkoituksella pieni ja synkroninen,
|
|
6
|
+
* ja se ajetaan <head>issä ennen tyylejä.
|
|
7
|
+
*
|
|
8
|
+
* Ilman tallennettua valintaa data-themeä ei aseteta lainkaan, jolloin
|
|
9
|
+
* tokens.css:n `color-scheme: light dark` seuraa käyttöjärjestelmää.
|
|
10
|
+
*/
|
|
11
|
+
export declare const THEME_STORAGE_KEY = "pokela-theme";
|
|
12
|
+
export default function ThemeScript(): import("react/jsx-runtime").JSX.Element;
|
package/ThemeScript.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Teeman palautus ennen ensimmäistä maalausta.
|
|
4
|
+
*
|
|
5
|
+
* Ilman tätä sivu välähtäisi vaaleana ennen kuin tallennettu tumma
|
|
6
|
+
* teema ehtii päälle. Skripti on tarkoituksella pieni ja synkroninen,
|
|
7
|
+
* ja se ajetaan <head>issä ennen tyylejä.
|
|
8
|
+
*
|
|
9
|
+
* Ilman tallennettua valintaa data-themeä ei aseteta lainkaan, jolloin
|
|
10
|
+
* tokens.css:n `color-scheme: light dark` seuraa käyttöjärjestelmää.
|
|
11
|
+
*/
|
|
12
|
+
export const THEME_STORAGE_KEY = 'pokela-theme';
|
|
13
|
+
const script = `(function(){try{var t=localStorage.getItem(${JSON.stringify(THEME_STORAGE_KEY)});if(t==='light'||t==='dark'){document.documentElement.setAttribute('data-theme',t)}}catch(e){}})()`;
|
|
14
|
+
export default function ThemeScript() {
|
|
15
|
+
return _jsx("script", { dangerouslySetInnerHTML: { __html: script } });
|
|
16
|
+
}
|
package/ThemeToggle.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teemanvaihto tekstinappina — ei ikonia, ei väriä.
|
|
3
|
+
* Kierto: järjestelmä → vaalea → tumma → järjestelmä.
|
|
4
|
+
*
|
|
5
|
+
* `data-theme` puuttuu kun valinta on "järjestelmä", jolloin
|
|
6
|
+
* tokens.css:n light-dark() seuraa prefers-color-schemeä.
|
|
7
|
+
*/
|
|
8
|
+
export default function ThemeToggle({ labels, }: {
|
|
9
|
+
labels: {
|
|
10
|
+
theme: string;
|
|
11
|
+
light: string;
|
|
12
|
+
dark: string;
|
|
13
|
+
system: string;
|
|
14
|
+
};
|
|
15
|
+
}): import("react/jsx-runtime").JSX.Element;
|
package/ThemeToggle.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { THEME_STORAGE_KEY } from './ThemeScript';
|
|
5
|
+
/**
|
|
6
|
+
* Teemanvaihto tekstinappina — ei ikonia, ei väriä.
|
|
7
|
+
* Kierto: järjestelmä → vaalea → tumma → järjestelmä.
|
|
8
|
+
*
|
|
9
|
+
* `data-theme` puuttuu kun valinta on "järjestelmä", jolloin
|
|
10
|
+
* tokens.css:n light-dark() seuraa prefers-color-schemeä.
|
|
11
|
+
*/
|
|
12
|
+
export default function ThemeToggle({ labels, }) {
|
|
13
|
+
const [theme, setTheme] = useState('system');
|
|
14
|
+
const [mounted, setMounted] = useState(false);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
setMounted(true);
|
|
17
|
+
try {
|
|
18
|
+
const stored = localStorage.getItem(THEME_STORAGE_KEY);
|
|
19
|
+
if (stored === 'light' || stored === 'dark')
|
|
20
|
+
setTheme(stored);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
/* private mode — pidetään järjestelmän teema */
|
|
24
|
+
}
|
|
25
|
+
}, []);
|
|
26
|
+
function apply(next) {
|
|
27
|
+
setTheme(next);
|
|
28
|
+
const root = document.documentElement;
|
|
29
|
+
if (next === 'system')
|
|
30
|
+
root.removeAttribute('data-theme');
|
|
31
|
+
else
|
|
32
|
+
root.setAttribute('data-theme', next);
|
|
33
|
+
try {
|
|
34
|
+
if (next === 'system')
|
|
35
|
+
localStorage.removeItem(THEME_STORAGE_KEY);
|
|
36
|
+
else
|
|
37
|
+
localStorage.setItem(THEME_STORAGE_KEY, next);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* valinta jää tälle sivulataukselle */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const order = ['system', 'light', 'dark'];
|
|
44
|
+
const label = { system: labels.system, light: labels.light, dark: labels.dark }[theme];
|
|
45
|
+
return (_jsx("button", { type: "button", className: "meta meta--s toggle", onClick: () => apply(order[(order.indexOf(theme) + 1) % order.length]), "aria-label": `${labels.theme}: ${label}`,
|
|
46
|
+
/* Ennen hydraatiota näytetään neutraali merkintä, jottei
|
|
47
|
+
palvelimen ja selaimen tila eroa toisistaan. */
|
|
48
|
+
suppressHydrationWarning: true, children: mounted ? label : labels.theme }));
|
|
49
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -6,3 +6,5 @@ export { Accordion, useAccordionGroup } from './Accordion.js';
|
|
|
6
6
|
export type { AccordionProps } from './Accordion.js';
|
|
7
7
|
export { Grid, Col } from './Grid.js';
|
|
8
8
|
export { default as Reveal } from './Reveal.js';
|
|
9
|
+
export { default as ThemeScript, THEME_STORAGE_KEY } from './ThemeScript.js';
|
|
10
|
+
export { default as ThemeToggle } from './ThemeToggle.js';
|
package/index.js
CHANGED
|
@@ -4,3 +4,5 @@ export { default as ListRow } from './ListRow.js';
|
|
|
4
4
|
export { Accordion, useAccordionGroup } from './Accordion.js';
|
|
5
5
|
export { Grid, Col } from './Grid.js';
|
|
6
6
|
export { default as Reveal } from './Reveal.js';
|
|
7
|
+
export { default as ThemeScript, THEME_STORAGE_KEY } from './ThemeScript.js';
|
|
8
|
+
export { default as ThemeToggle } from './ThemeToggle.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pokela/components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "React-komponentit: Pokela Design System. Generoitu tiedostoista components/, ei käsin ylläpidetty.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Veli-Matti Pokela",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"LICENSE"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@pokela/tokens": "^1.
|
|
28
|
+
"@pokela/tokens": "^1.2.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"react": ">=18"
|
package/styles/base.css
CHANGED
|
@@ -165,6 +165,27 @@ a:hover { text-decoration: underline; text-underline-offset: var(--space-4); }
|
|
|
165
165
|
border-bottom: var(--hairline) solid currentColor;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
/* Hiljainen kytkin: teemanvaihto ja vastaavat. Ei .btn-perheen jäsen —
|
|
169
|
+
typografia tulee .meta:sta ja nappimaisuus riisutaan kokonaan, joten
|
|
170
|
+
se ei kilpaile sivun oikeiden toimintojen kanssa. Kosketusalue on
|
|
171
|
+
silti täysi: padding kasvattaa sen ja yhtä suuri negatiivinen margin
|
|
172
|
+
kumoaa vaikutuksen taittoon.
|
|
173
|
+
|
|
174
|
+
Ei ollut navigaatiokohtainen, vaikka asui aiemmin nav.css:ssä nimellä
|
|
175
|
+
.nav__toggle. Nimi esti ThemeTogglen viennin komponenttipakettiin,
|
|
176
|
+
koska komponentti olisi tarvinnut Navin tyylit. */
|
|
177
|
+
.toggle {
|
|
178
|
+
background: none;
|
|
179
|
+
border: 0;
|
|
180
|
+
padding: var(--space-12);
|
|
181
|
+
margin: calc(var(--space-12) * -1);
|
|
182
|
+
min-width: var(--tap-min);
|
|
183
|
+
min-height: var(--tap-min);
|
|
184
|
+
cursor: pointer;
|
|
185
|
+
transition: color var(--dur-fast) var(--ease-standard);
|
|
186
|
+
}
|
|
187
|
+
.toggle:hover { color: var(--ink); }
|
|
188
|
+
|
|
168
189
|
/* Tekstinapilla ei ole pintaa jota kääntää, joten hover on sama liike
|
|
169
190
|
kuin .case-linkillä: viiva paksunee. Padding kevenee saman verran
|
|
170
191
|
kuin viiva kasvaa, jotta napin korkeus ei muutu eikä ympärillä oleva
|