@konce-pt/theme 0.9.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/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/audit.d.ts +59 -0
- package/dist/audit.js +102 -0
- package/dist/dtcg.d.ts +80 -0
- package/dist/dtcg.js +624 -0
- package/dist/emit.d.ts +76 -0
- package/dist/emit.js +276 -0
- package/dist/generated/tokens.d.ts +24 -0
- package/dist/generated/tokens.js +348 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +9 -0
- package/dist/ramp.d.ts +41 -0
- package/dist/ramp.js +66 -0
- package/dist/resolve.d.ts +56 -0
- package/dist/resolve.js +192 -0
- package/dist/roles.d.ts +28 -0
- package/dist/roles.js +77 -0
- package/dist/runtime.d.ts +32 -0
- package/dist/runtime.js +41 -0
- package/dist/schema.d.ts +128 -0
- package/dist/schema.js +129 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 konce.pt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://ui.konce.pt/images/koncept_ui_lib.png" alt="Koncept UI — Angular component library" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# @konce-pt/theme
|
|
6
|
+
|
|
7
|
+
Rdzeń motywu [Koncept UI](https://gitlab.com/konce-pt/koncept-ui): format dokumentu
|
|
8
|
+
`kpt-theme.json`, rampa OKLCH z jednego koloru marki, derywacja kompletu ról semantycznych, audyt
|
|
9
|
+
kontrastu i emitery do CSS, SCSS, TS oraz W3C DTCG. Czysty TypeScript bez wiązania z frameworkiem;
|
|
10
|
+
jedyna zależność to [`@konce-pt/color`](https://www.npmjs.com/package/@konce-pt/color).
|
|
11
|
+
|
|
12
|
+
Motyw dla tej biblioteki to zestaw wartości `--kpt-*` — a policzenie tego zestawu jest arytmetyką,
|
|
13
|
+
nie znacznikami. Ta sama arytmetyka musi chodzić w przeglądarce (podgląd na żywo) i w Node (eksport,
|
|
14
|
+
testy), więc mieszka osobno od aplikacji, która ją renderuje.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm i @konce-pt/theme
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { emitCss, auditTheme } from '@konce-pt/theme';
|
|
22
|
+
|
|
23
|
+
const theme = {
|
|
24
|
+
kptTheme: 1,
|
|
25
|
+
meta: { name: 'Acme' },
|
|
26
|
+
recipe: { color: { seed: { primary: '#3b82f6' } }, radius: { base: '0.75rem' } },
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
emitCss(theme); // :root { … } + [data-theme="dark"] { … } — plik do wklejenia w aplikacji
|
|
30
|
+
auditTheme(theme); // pary o zbyt niskim kontraście, w obu motywach, WCAG 2.1 + APCA
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Różnica, nie zrzut
|
|
34
|
+
|
|
35
|
+
Dokument zapisuje wyłącznie to, co odbiega od stocku. Motyw waży kilka kilobajtów zamiast
|
|
36
|
+
kilkudziesięciu, czyta się go w code review, a nowe tokeny w kolejnej wersji biblioteki dziedziczą
|
|
37
|
+
się same, zamiast zamarzać na wartościach sprzed aktualizacji. Osobno trzymane są wejścia generatora
|
|
38
|
+
(`recipe`) i ręczne poprawki (`overrides`): dzięki temu „przelicz paletę od nowa" nie kasuje ręcznej
|
|
39
|
+
pracy, a suwaki dają się ponownie otworzyć.
|
|
40
|
+
|
|
41
|
+
## Rampa czytana z palety, nie wymyślona
|
|
42
|
+
|
|
43
|
+
Jasność każdego stopnia pochodzi z rampy neutralnej biblioteki, kształt nasycenia — z uśrednienia
|
|
44
|
+
czterech ramp akcentowych. Który stopień trafia na `primary`, `-hover`, `-subtle` i `-border`, też
|
|
45
|
+
jest odczytane: cztery rodziny chromatyczne biblioteki mają identyczny układ i to on jest wzorcem.
|
|
46
|
+
Generator pęka głośno, gdyby kiedykolwiek się rozjechały.
|
|
47
|
+
|
|
48
|
+
## Audyt, który nie krzyczy bez powodu
|
|
49
|
+
|
|
50
|
+
Każdy wynik niesie `inherited` — czy ta sama para nie zdaje już w stockowym motywie biblioteki.
|
|
51
|
+
Użytkownik widzi to, co **on** popsuł, zamiast dziedziczyć listę, na którą nie ma wpływu. Ukrywać
|
|
52
|
+
ich zupełnie jednak nie wolno: część z nich to prawdziwe problemy.
|
|
53
|
+
|
|
54
|
+
Pełny opis: [`llms.txt`](https://ui.konce.pt/llms/theme/llms.txt) (EN)
|
|
55
|
+
i [`llms-pl.txt`](https://ui.konce.pt/llms/theme/llms-pl.txt) (PL).
|
|
56
|
+
|
|
57
|
+
## Testy
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pnpm --filter @konce-pt/theme exec node --test "src/**/*.test.ts"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Licencja
|
|
64
|
+
|
|
65
|
+
MIT © [konce.pt](https://konce.pt)
|
package/dist/audit.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audyt kontrastu.
|
|
3
|
+
*
|
|
4
|
+
* Mierzymy pary, które realnie występują w bibliotece — tekst na powierzchni, treść na wypełnieniu
|
|
5
|
+
* akcentowym, kreska na tle — a nie iloczyn kartezjański wszystkich tokenów. Lista jest krótka
|
|
6
|
+
* i konkretna, bo audyt ma wskazać miejsce do poprawienia, a nie wysypać sto liczb.
|
|
7
|
+
*
|
|
8
|
+
* Obie miary idą obok siebie: WCAG 2.1, bo na nim stoją wymagania formalne, i APCA, bo lepiej
|
|
9
|
+
* odpowiada temu, co widać, i uwzględnia biegunowość. Para może zdać jedną i oblać drugą — wtedy
|
|
10
|
+
* warto to zobaczyć, a nie uśredniać.
|
|
11
|
+
*/
|
|
12
|
+
import type { KptThemeDoc, KptThemeMode } from './schema.ts';
|
|
13
|
+
/**
|
|
14
|
+
* Poziom wymagania: tekst podstawowy, tekst duży, element interfejsu, element dekoracyjny.
|
|
15
|
+
*
|
|
16
|
+
* `decorative` **nie jest** progiem WCAG i celowo nie udaje, że jest. Zwykła kreska rozdzielająca
|
|
17
|
+
* nie jest „komponentem interfejsu" w rozumieniu 1.4.11 i praktycznie żaden system projektowy nie
|
|
18
|
+
* trzyma jej na 3:1 — wymaganie tego produkowałoby ostrzeżenie, które każdy nauczy się ignorować,
|
|
19
|
+
* a razem z nim ignorować całą resztę. Pytanie jest tu inne i węższe: czy kreska w ogóle widać.
|
|
20
|
+
*/
|
|
21
|
+
export type KptContrastLevel = 'body' | 'large' | 'ui' | 'decorative';
|
|
22
|
+
export interface KptContrastPair {
|
|
23
|
+
text: string;
|
|
24
|
+
background: string;
|
|
25
|
+
level: KptContrastLevel;
|
|
26
|
+
/** Po czym poznać tę parę w interfejsie — co to jest na ekranie. */
|
|
27
|
+
label: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pary sprawdzane w obu motywach. `text` nie zawsze jest literami: dla `ui` to bywa kreska albo
|
|
31
|
+
* pierścień focus, czyli rzecz, która ma się odciąć od tła.
|
|
32
|
+
*/
|
|
33
|
+
export declare const KPT_CONTRAST_PAIRS: readonly KptContrastPair[];
|
|
34
|
+
export interface KptContrastFinding extends KptContrastPair {
|
|
35
|
+
mode: KptThemeMode;
|
|
36
|
+
/** Wartości po rozwiązaniu — żeby interfejs mógł pokazać, co dokładnie zmierzono. */
|
|
37
|
+
textValue: string;
|
|
38
|
+
backgroundValue: string;
|
|
39
|
+
ratio: number;
|
|
40
|
+
lc: number;
|
|
41
|
+
requiredRatio: number;
|
|
42
|
+
requiredLc: number;
|
|
43
|
+
passesWcag: boolean;
|
|
44
|
+
passesApca: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Czy ta sama para nie zdaje już w motywie stockowym biblioteki. Edytor domyślnie chowa takie
|
|
47
|
+
* wyniki: użytkownik ma zobaczyć, co **on** popsuł, a nie odziedziczyć listy, na którą nie ma
|
|
48
|
+
* wpływu — ale ukryć to zupełnie też nie wolno, bo część z tych par to prawdziwe problemy
|
|
49
|
+
* (biały tekst na wypełnieniu ostrzeżenia trzyma 3,19 przy wymaganych 4,5).
|
|
50
|
+
*/
|
|
51
|
+
inherited: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface KptAuditOptions {
|
|
54
|
+
/** Zwróć także pary, które zdały. Domyślnie wracają same problemy. */
|
|
55
|
+
all?: boolean;
|
|
56
|
+
/** Ogranicz do jednego motywu. Domyślnie sprawdzane są oba. */
|
|
57
|
+
mode?: KptThemeMode;
|
|
58
|
+
}
|
|
59
|
+
export declare function auditTheme(doc?: KptThemeDoc, options?: KptAuditOptions): KptContrastFinding[];
|
package/dist/audit.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audyt kontrastu.
|
|
3
|
+
*
|
|
4
|
+
* Mierzymy pary, które realnie występują w bibliotece — tekst na powierzchni, treść na wypełnieniu
|
|
5
|
+
* akcentowym, kreska na tle — a nie iloczyn kartezjański wszystkich tokenów. Lista jest krótka
|
|
6
|
+
* i konkretna, bo audyt ma wskazać miejsce do poprawienia, a nie wysypać sto liczb.
|
|
7
|
+
*
|
|
8
|
+
* Obie miary idą obok siebie: WCAG 2.1, bo na nim stoją wymagania formalne, i APCA, bo lepiej
|
|
9
|
+
* odpowiada temu, co widać, i uwzględnia biegunowość. Para może zdać jedną i oblać drugą — wtedy
|
|
10
|
+
* warto to zobaczyć, a nie uśredniać.
|
|
11
|
+
*/
|
|
12
|
+
import { apcaLc, contrastRatio, oklchToSrgb, parseOklch } from '@konce-pt/color';
|
|
13
|
+
import { resolveTheme } from "./resolve.js";
|
|
14
|
+
const THRESHOLDS = {
|
|
15
|
+
body: { ratio: 4.5, lc: 75 },
|
|
16
|
+
large: { ratio: 3, lc: 60 },
|
|
17
|
+
ui: { ratio: 3, lc: 45 },
|
|
18
|
+
decorative: { ratio: 1.2, lc: 8 },
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Pary sprawdzane w obu motywach. `text` nie zawsze jest literami: dla `ui` to bywa kreska albo
|
|
22
|
+
* pierścień focus, czyli rzecz, która ma się odciąć od tła.
|
|
23
|
+
*/
|
|
24
|
+
export const KPT_CONTRAST_PAIRS = [
|
|
25
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-surface', level: 'body', label: 'Tekst główny na stronie' },
|
|
26
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-surface-raised', level: 'body', label: 'Tekst na karcie' },
|
|
27
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-surface-variant', level: 'body', label: 'Tekst w nagłówku tabeli' },
|
|
28
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-surface-sunken', level: 'body', label: 'Tekst w sekcji zagłębionej' },
|
|
29
|
+
{ text: '--kpt-color-on-surface-muted', background: '--kpt-color-surface', level: 'body', label: 'Tekst drugorzędny' },
|
|
30
|
+
{ text: '--kpt-color-text-subtle', background: '--kpt-color-surface', level: 'ui', label: 'Placeholder i tekst wyłączony' },
|
|
31
|
+
{ text: '--kpt-color-on-primary', background: '--kpt-color-primary', level: 'body', label: 'Etykieta przycisku głównego' },
|
|
32
|
+
{ text: '--kpt-color-on-muted', background: '--kpt-color-muted', level: 'body', label: 'Etykieta przycisku tonalnego' },
|
|
33
|
+
{ text: '--kpt-color-danger-contrast', background: '--kpt-color-danger', level: 'body', label: 'Treść na wypełnieniu błędu' },
|
|
34
|
+
{ text: '--kpt-color-success-contrast', background: '--kpt-color-success', level: 'body', label: 'Treść na wypełnieniu powodzenia' },
|
|
35
|
+
{ text: '--kpt-color-warning-contrast', background: '--kpt-color-warning', level: 'body', label: 'Treść na wypełnieniu ostrzeżenia' },
|
|
36
|
+
{ text: '--kpt-color-info-contrast', background: '--kpt-color-info', level: 'body', label: 'Treść na wypełnieniu informacji' },
|
|
37
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-primary-subtle', level: 'body', label: 'Tekst na badge akcentu' },
|
|
38
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-danger-subtle', level: 'body', label: 'Tekst w alercie błędu' },
|
|
39
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-success-subtle', level: 'body', label: 'Tekst w alercie powodzenia' },
|
|
40
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-warning-subtle', level: 'body', label: 'Tekst w alercie ostrzeżenia' },
|
|
41
|
+
{ text: '--kpt-color-on-surface', background: '--kpt-color-info-subtle', level: 'body', label: 'Tekst w alercie informacji' },
|
|
42
|
+
{ text: '--kpt-color-border', background: '--kpt-color-surface', level: 'decorative', label: 'Kreska rozdzielająca' },
|
|
43
|
+
{ text: '--kpt-color-border-strong', background: '--kpt-color-surface', level: 'ui', label: 'Obrys pola formularza' },
|
|
44
|
+
{ text: '--kpt-color-focus-ring', background: '--kpt-color-surface', level: 'ui', label: 'Pierścień focus' },
|
|
45
|
+
{ text: '--kpt-color-primary', background: '--kpt-color-surface', level: 'ui', label: 'Ikona i tekst akcentowy' },
|
|
46
|
+
];
|
|
47
|
+
const toRgb = (value) => {
|
|
48
|
+
const oklch = parseOklch(value);
|
|
49
|
+
return oklch ? oklchToSrgb(oklch) : null;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Pary o zbyt niskim kontraście, posortowane od najgorszej.
|
|
53
|
+
*
|
|
54
|
+
* Pary, których nie da się zmierzyć — bo wartość jest półprzezroczysta, jest `color-mix()` albo
|
|
55
|
+
* czymś, czego nie umiemy sprowadzić do składowych — są **pomijane**, nie zaliczane. Liczba
|
|
56
|
+
* wzięta z niepewnej wartości byłaby gorsza niż jej brak: audyt mówiłby „zdane" tam, gdzie nic
|
|
57
|
+
* nie sprawdził.
|
|
58
|
+
*/
|
|
59
|
+
const keyOf = (mode, pair) => `${mode}|${pair.text}|${pair.background}`;
|
|
60
|
+
/** Pary nie zdające już w stocku. Liczone raz i bez flagi `inherited`, żeby nie zapętlić audytu. */
|
|
61
|
+
let stockFailures;
|
|
62
|
+
const inheritedFailures = () => (stockFailures ??= new Set(measure(undefined).filter((f) => !f.passesWcag || !f.passesApca).map((f) => f.key)));
|
|
63
|
+
export function auditTheme(doc, options = {}) {
|
|
64
|
+
const baseline = inheritedFailures();
|
|
65
|
+
return measure(doc, options)
|
|
66
|
+
.map(({ key, ...finding }) => ({ ...finding, inherited: baseline.has(key) }))
|
|
67
|
+
.filter((finding) => options.all || !finding.passesWcag || !finding.passesApca)
|
|
68
|
+
.sort((a, b) => a.ratio - b.ratio);
|
|
69
|
+
}
|
|
70
|
+
function measure(doc, options = {}) {
|
|
71
|
+
const resolved = resolveTheme(doc);
|
|
72
|
+
const modes = options.mode ? [options.mode] : ['light', 'dark'];
|
|
73
|
+
const findings = [];
|
|
74
|
+
for (const mode of modes) {
|
|
75
|
+
const values = resolved[mode];
|
|
76
|
+
for (const pair of KPT_CONTRAST_PAIRS) {
|
|
77
|
+
const textValue = values[pair.text];
|
|
78
|
+
const backgroundValue = values[pair.background];
|
|
79
|
+
const text = textValue ? toRgb(textValue) : null;
|
|
80
|
+
const background = backgroundValue ? toRgb(backgroundValue) : null;
|
|
81
|
+
if (!text || !background)
|
|
82
|
+
continue;
|
|
83
|
+
const threshold = THRESHOLDS[pair.level];
|
|
84
|
+
const ratio = contrastRatio(text, background);
|
|
85
|
+
const lc = apcaLc(text, background);
|
|
86
|
+
findings.push({
|
|
87
|
+
...pair,
|
|
88
|
+
key: keyOf(mode, pair),
|
|
89
|
+
mode,
|
|
90
|
+
textValue,
|
|
91
|
+
backgroundValue,
|
|
92
|
+
ratio: Number(ratio.toFixed(2)),
|
|
93
|
+
lc: Number(lc.toFixed(1)),
|
|
94
|
+
requiredRatio: threshold.ratio,
|
|
95
|
+
requiredLc: threshold.lc,
|
|
96
|
+
passesWcag: ratio >= threshold.ratio,
|
|
97
|
+
passesApca: Math.abs(lc) >= threshold.lc,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return findings;
|
|
102
|
+
}
|
package/dist/dtcg.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import z formatu W3C Design Tokens (DTCG) — jednokierunkowy, plikowy.
|
|
3
|
+
*
|
|
4
|
+
* To jest import, nie synchronizacja, i tak trzeba go nazywać. Odczyt zmiennych z narzędzia
|
|
5
|
+
* projektowego przez API bywa zarezerwowany dla planów firmowych, więc realną drogą jest plik
|
|
6
|
+
* wyeksportowany wtyczką. Nie ma tu OAuth, nie ma odpytywania, nie ma śledzenia zmian.
|
|
7
|
+
*
|
|
8
|
+
* Najtrudniejsze nie jest samo czytanie tokenów, tylko **tryby**: DTCG ich nie standaryzuje.
|
|
9
|
+
* Eksportery kodują je na trzy sposoby i każdy trzeba obsłużyć osobno — patrz `splitModes`.
|
|
10
|
+
*
|
|
11
|
+
* Zasada, od której nie ma odstępstwa: **importer nigdy niczego nie gubi po cichu.** Token, którego
|
|
12
|
+
* nie umiemy przypisać, trafia do raportu z powodem. Lepiej pokazać listę stu niedopasowań niż
|
|
13
|
+
* wczytać trzydzieści i nie powiedzieć o siedemdziesięciu.
|
|
14
|
+
*/
|
|
15
|
+
import type { KptThemeDoc, KptThemeMode } from './schema.ts';
|
|
16
|
+
/** Jeden plik wejściowy. Nazwa bywa jedyną informacją o trybie, więc idzie razem z treścią. */
|
|
17
|
+
export interface KptDtcgSource {
|
|
18
|
+
name: string;
|
|
19
|
+
content: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface KptDtcgOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Ręczne wskazanie, co jest którym trybem — nazwa pliku albo grupy najwyższego poziomu.
|
|
24
|
+
* Podane, wygrywa z heurystyką; to jest wyjście awaryjne dla eksporterów, których nie znamy.
|
|
25
|
+
*/
|
|
26
|
+
modes?: {
|
|
27
|
+
light?: string;
|
|
28
|
+
dark?: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Utrwalone mapowanie ze ścieżki DTCG na nazwę tokenu (`meta.importMap`). To ono zamienia
|
|
32
|
+
* jednorazowy import w element procesu pracy: po zmianie brandbooka wystarczy wczytać plik.
|
|
33
|
+
*/
|
|
34
|
+
map?: Readonly<Record<string, string>>;
|
|
35
|
+
}
|
|
36
|
+
export type KptDtcgConfidence = 'exact' | 'synonym' | 'manual';
|
|
37
|
+
export interface KptDtcgReport {
|
|
38
|
+
/** Dopasowane tokeny — `from` to ścieżka DTCG, `to` nazwa custom property. */
|
|
39
|
+
matched: {
|
|
40
|
+
from: string;
|
|
41
|
+
to: string;
|
|
42
|
+
mode: KptThemeMode;
|
|
43
|
+
confidence: KptDtcgConfidence;
|
|
44
|
+
}[];
|
|
45
|
+
/** Tokeny, których nie przypisaliśmy. Każdy z powodem — to jest sedno raportu. */
|
|
46
|
+
unmapped: {
|
|
47
|
+
path: string;
|
|
48
|
+
type: string;
|
|
49
|
+
value: string;
|
|
50
|
+
reason: KptDtcgReason;
|
|
51
|
+
}[];
|
|
52
|
+
/** Role biblioteki, których plik nie pokrył. Zostają na wartościach stockowych. */
|
|
53
|
+
missing: string[];
|
|
54
|
+
warnings: {
|
|
55
|
+
code: KptDtcgWarning;
|
|
56
|
+
detail: string;
|
|
57
|
+
}[];
|
|
58
|
+
/** Rampy rozpoznane w pliku — z nich bierze się ziarno koloru wiodącego. */
|
|
59
|
+
ramps: {
|
|
60
|
+
path: string;
|
|
61
|
+
steps: number;
|
|
62
|
+
seed?: string;
|
|
63
|
+
}[];
|
|
64
|
+
}
|
|
65
|
+
export type KptDtcgReason = 'no-target' | 'unsupported-type' | 'composite' | 'unreadable-value'
|
|
66
|
+
/** Token nasz, ale **pochodny** — podąża za semantyką, więc nadpisanie zamroziłoby go. */
|
|
67
|
+
| 'derived';
|
|
68
|
+
export type KptDtcgWarning = 'mode-guess' | 'no-modes' | 'alias-broken' | 'legacy-format' | 'empty';
|
|
69
|
+
/** Nazwa ze ścieżki DTCG w kształcie, w którym da się ją porównać z nazwą roli. */
|
|
70
|
+
export declare function normalizeDtcgPath(path: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Czyta pliki DTCG i buduje z nich dokument motywu.
|
|
73
|
+
*
|
|
74
|
+
* Zwraca **parę**: motyw i raport. Raport nie jest dodatkiem — to on decyduje, czy import da się
|
|
75
|
+
* przyjąć, i to on pokazuje, czego plik nie pokrył. Interfejs ma go wyświetlić, a nie schować.
|
|
76
|
+
*/
|
|
77
|
+
export declare function fromDtcg(sources: readonly KptDtcgSource[], options?: KptDtcgOptions): {
|
|
78
|
+
theme: KptThemeDoc;
|
|
79
|
+
report: KptDtcgReport;
|
|
80
|
+
};
|