@d0nj/dsh-ui-custom 0.2.1 → 0.3.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 +1 -1
- package/dist/client/client.js +44 -8
- package/dist/client/hosted-fonts.d.ts +17 -4
- package/dist/client/hosted-fonts.js +24 -5
- package/dist/client/panel.js +2 -2
- package/dist/resolve.js +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ The Harness ships one palette per mode. Restyling it otherwise means editing CSS
|
|
|
10
10
|
|
|
11
11
|
- **15 presets**, each defined for both light and dark: Midnight, Paper, High contrast, Dracula, Nord, Catppuccin Mocha, Gruvbox, One Dark, Solarized, Rosé Pine, Tokyo Night, Ayu Dark, GitHub Dark, Monokai, Mono.
|
|
12
12
|
- **14 colour tokens** — surfaces, borders, text, brand, and state colours — each overridable per mode.
|
|
13
|
-
- **Typography** per role: interface/body, code, and the sidebar terminal, including font
|
|
13
|
+
- **Typography** per role: interface/body, code, and the sidebar terminal, including 40 font families and separate sizes. Families load from our own mirror, not Google Fonts.
|
|
14
14
|
- **Geometry**: corner radius (0–24 px) and spacing density (compact, comfortable, spacious).
|
|
15
15
|
- **Theme Studio** panel with live preview, so changes apply without a restart.
|
|
16
16
|
|
package/dist/client/client.js
CHANGED
|
@@ -881,6 +881,11 @@ window.__ModuleLoader__.load({
|
|
|
881
881
|
'fangsong', '-apple-system', 'blinkmacsystemfont',
|
|
882
882
|
'inherit', 'initial', 'unset',
|
|
883
883
|
]);
|
|
884
|
+
/** Tokens the Client paints with that no preset names; each follows a documented token. */
|
|
885
|
+
const RUNTIME_ALIASES = [
|
|
886
|
+
['--dsw-specific-input-major', '--dsw-alias-bg-layer-1'],
|
|
887
|
+
['--dsw-alias-button-info-fill', '--dsw-alias-brand-primary'],
|
|
888
|
+
];
|
|
884
889
|
/**
|
|
885
890
|
* Whether a value is a plausible CSS colour.
|
|
886
891
|
*
|
|
@@ -1002,6 +1007,18 @@ window.__ModuleLoader__.load({
|
|
|
1002
1007
|
}
|
|
1003
1008
|
tokens[name] = { light, dark };
|
|
1004
1009
|
}
|
|
1010
|
+
for (const [alias, source] of RUNTIME_ALIASES) {
|
|
1011
|
+
const modes = tokens[source];
|
|
1012
|
+
if (modes !== undefined)
|
|
1013
|
+
tokens[alias] = modes;
|
|
1014
|
+
}
|
|
1015
|
+
const accent = tokens['--dsw-alias-button-info-fill'];
|
|
1016
|
+
if (accent !== undefined) {
|
|
1017
|
+
tokens['--dsw-alias-button-info-hover'] = {
|
|
1018
|
+
light: `color-mix(in srgb, ${accent.light} 85%, black)`,
|
|
1019
|
+
dark: `color-mix(in srgb, ${accent.dark} 85%, white)`,
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1005
1022
|
for (const [name, modes] of Object.entries(geometryTokens(document.geometry))) {
|
|
1006
1023
|
tokens[name] = modes;
|
|
1007
1024
|
}
|
|
@@ -1277,10 +1294,10 @@ window.__ModuleLoader__.load({
|
|
|
1277
1294
|
const matches = () => {
|
|
1278
1295
|
const query = combo.query.trim().toLowerCase();
|
|
1279
1296
|
if (query === '')
|
|
1280
|
-
return [DEFAULT_CHOICE, ...choices
|
|
1297
|
+
return [DEFAULT_CHOICE, ...choices];
|
|
1281
1298
|
const filtered = choices.filter((choice) => choice.toLowerCase().includes(query));
|
|
1282
1299
|
const keepDefault = 'default (built-in)'.includes(query) || 'built-in'.includes(query);
|
|
1283
|
-
return
|
|
1300
|
+
return keepDefault ? [DEFAULT_CHOICE, ...filtered] : filtered;
|
|
1284
1301
|
};
|
|
1285
1302
|
const commit = (value) => {
|
|
1286
1303
|
combo.open = false;
|
|
@@ -1518,10 +1535,20 @@ window.__ModuleLoader__.load({
|
|
|
1518
1535
|
},
|
|
1519
1536
|
"./client/hosted-fonts.js": (module, exports, __require) => {
|
|
1520
1537
|
/**
|
|
1521
|
-
* Families
|
|
1538
|
+
* Families loaded on demand from our own font mirror.
|
|
1539
|
+
*
|
|
1540
|
+
* The mirror keeps every family out of Google's hands: the plugin loads one
|
|
1541
|
+
* stylesheet per pick, and the stylesheet's `unicode-range` rules make the
|
|
1542
|
+
* browser download only the subsets the page needs.
|
|
1522
1543
|
*
|
|
1523
1544
|
* @module @d0nj/dsh-ui-custom/hosted-fonts
|
|
1524
1545
|
*/
|
|
1546
|
+
/**
|
|
1547
|
+
* The catalog.
|
|
1548
|
+
*
|
|
1549
|
+
* A family added here is not loadable until the mirror carries it, so a new
|
|
1550
|
+
* family means a new mirror tag and a new version of this package.
|
|
1551
|
+
*/
|
|
1525
1552
|
const HOSTED_FONTS = [
|
|
1526
1553
|
{ family: 'Inter', category: 'sans' },
|
|
1527
1554
|
{ family: 'IBM Plex Sans', category: 'sans' },
|
|
@@ -1542,6 +1569,10 @@ window.__ModuleLoader__.load({
|
|
|
1542
1569
|
{ family: 'Sora', category: 'sans' },
|
|
1543
1570
|
{ family: 'Space Grotesk', category: 'sans' },
|
|
1544
1571
|
{ family: 'JetBrains Mono', category: 'mono' },
|
|
1572
|
+
{ family: 'Geist Mono', category: 'mono' },
|
|
1573
|
+
{ family: 'Victor Mono', category: 'mono' },
|
|
1574
|
+
{ family: 'MonoLisa', category: 'mono' },
|
|
1575
|
+
{ family: 'SF Mono', category: 'mono' },
|
|
1545
1576
|
{ family: 'Fira Code', category: 'mono' },
|
|
1546
1577
|
{ family: 'Source Code Pro', category: 'mono' },
|
|
1547
1578
|
{ family: 'IBM Plex Mono', category: 'mono' },
|
|
@@ -1560,17 +1591,22 @@ window.__ModuleLoader__.load({
|
|
|
1560
1591
|
{ family: 'Bricolage Grotesque', category: 'display' },
|
|
1561
1592
|
{ family: 'Instrument Serif', category: 'display' },
|
|
1562
1593
|
];
|
|
1563
|
-
const CDN_BASE = 'https://fonts.
|
|
1594
|
+
const CDN_BASE = 'https://cdn.jsdelivr.net/gh/d0nj/dsh-fonts@v1.0.0/fonts';
|
|
1564
1595
|
/** Stylesheets outlive any one render, and a repeat request is a wasted round-trip. */
|
|
1565
1596
|
const requested = new Set();
|
|
1597
|
+
/**
|
|
1598
|
+
* @param family - the family to address.
|
|
1599
|
+
* @returns its directory name in the mirror.
|
|
1600
|
+
*/
|
|
1601
|
+
function fontSlug(family) {
|
|
1602
|
+
return family.toLowerCase().replaceAll(' ', '-').replaceAll(/[^a-z0-9-]/gu, '');
|
|
1603
|
+
}
|
|
1566
1604
|
/**
|
|
1567
1605
|
* @param font - the family to request.
|
|
1568
1606
|
* @returns an absolute stylesheet URL.
|
|
1569
1607
|
*/
|
|
1570
1608
|
function hostedFontUrl(font) {
|
|
1571
|
-
|
|
1572
|
-
const weights = (font.weights ?? [400]).join(';');
|
|
1573
|
-
return `${CDN_BASE}?family=${name}:wght@${weights}&display=swap`;
|
|
1609
|
+
return `${CDN_BASE}/${fontSlug(font.family)}/font.css`;
|
|
1574
1610
|
}
|
|
1575
1611
|
/**
|
|
1576
1612
|
* Load one family into the page; resolves on failure too, because a font that
|
|
@@ -1615,7 +1651,7 @@ window.__ModuleLoader__.load({
|
|
|
1615
1651
|
return fonts.find((font) => font.family.toLowerCase() === key);
|
|
1616
1652
|
}
|
|
1617
1653
|
//# sourceMappingURL=hosted-fonts.js.map
|
|
1618
|
-
Object.assign(exports, { hostedFontUrl: hostedFontUrl, loadHostedFont: loadHostedFont, hostedFamilies: hostedFamilies, findHostedFont: findHostedFont, HOSTED_FONTS: HOSTED_FONTS });
|
|
1654
|
+
Object.assign(exports, { fontSlug: fontSlug, hostedFontUrl: hostedFontUrl, loadHostedFont: loadHostedFont, hostedFamilies: hostedFamilies, findHostedFont: findHostedFont, HOSTED_FONTS: HOSTED_FONTS });
|
|
1619
1655
|
|
|
1620
1656
|
},
|
|
1621
1657
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Families
|
|
2
|
+
* Families loaded on demand from our own font mirror.
|
|
3
|
+
*
|
|
4
|
+
* The mirror keeps every family out of Google's hands: the plugin loads one
|
|
5
|
+
* stylesheet per pick, and the stylesheet's `unicode-range` rules make the
|
|
6
|
+
* browser download only the subsets the page needs.
|
|
3
7
|
*
|
|
4
8
|
* @module @d0nj/dsh-ui-custom/hosted-fonts
|
|
5
9
|
*/
|
|
@@ -7,14 +11,23 @@
|
|
|
7
11
|
export type FontCategory = 'sans' | 'serif' | 'mono' | 'display';
|
|
8
12
|
/** One hosted family this package can load. */
|
|
9
13
|
export interface HostedFont {
|
|
10
|
-
/** CSS family name, exactly as the stylesheet declares it. */
|
|
14
|
+
/** CSS family name, exactly as the mirrored stylesheet declares it. */
|
|
11
15
|
readonly family: string;
|
|
12
16
|
/** Grouping in the picker. */
|
|
13
17
|
readonly category: FontCategory;
|
|
14
|
-
/** Weights requested from the CDN; 400 is enough for body text. */
|
|
15
|
-
readonly weights?: readonly number[];
|
|
16
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* The catalog.
|
|
21
|
+
*
|
|
22
|
+
* A family added here is not loadable until the mirror carries it, so a new
|
|
23
|
+
* family means a new mirror tag and a new version of this package.
|
|
24
|
+
*/
|
|
17
25
|
export declare const HOSTED_FONTS: readonly HostedFont[];
|
|
26
|
+
/**
|
|
27
|
+
* @param family - the family to address.
|
|
28
|
+
* @returns its directory name in the mirror.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fontSlug(family: string): string;
|
|
18
31
|
/**
|
|
19
32
|
* @param font - the family to request.
|
|
20
33
|
* @returns an absolute stylesheet URL.
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Families
|
|
2
|
+
* Families loaded on demand from our own font mirror.
|
|
3
|
+
*
|
|
4
|
+
* The mirror keeps every family out of Google's hands: the plugin loads one
|
|
5
|
+
* stylesheet per pick, and the stylesheet's `unicode-range` rules make the
|
|
6
|
+
* browser download only the subsets the page needs.
|
|
3
7
|
*
|
|
4
8
|
* @module @d0nj/dsh-ui-custom/hosted-fonts
|
|
5
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* The catalog.
|
|
12
|
+
*
|
|
13
|
+
* A family added here is not loadable until the mirror carries it, so a new
|
|
14
|
+
* family means a new mirror tag and a new version of this package.
|
|
15
|
+
*/
|
|
6
16
|
export const HOSTED_FONTS = [
|
|
7
17
|
{ family: 'Inter', category: 'sans' },
|
|
8
18
|
{ family: 'IBM Plex Sans', category: 'sans' },
|
|
@@ -23,6 +33,10 @@ export const HOSTED_FONTS = [
|
|
|
23
33
|
{ family: 'Sora', category: 'sans' },
|
|
24
34
|
{ family: 'Space Grotesk', category: 'sans' },
|
|
25
35
|
{ family: 'JetBrains Mono', category: 'mono' },
|
|
36
|
+
{ family: 'Geist Mono', category: 'mono' },
|
|
37
|
+
{ family: 'Victor Mono', category: 'mono' },
|
|
38
|
+
{ family: 'MonoLisa', category: 'mono' },
|
|
39
|
+
{ family: 'SF Mono', category: 'mono' },
|
|
26
40
|
{ family: 'Fira Code', category: 'mono' },
|
|
27
41
|
{ family: 'Source Code Pro', category: 'mono' },
|
|
28
42
|
{ family: 'IBM Plex Mono', category: 'mono' },
|
|
@@ -41,17 +55,22 @@ export const HOSTED_FONTS = [
|
|
|
41
55
|
{ family: 'Bricolage Grotesque', category: 'display' },
|
|
42
56
|
{ family: 'Instrument Serif', category: 'display' },
|
|
43
57
|
];
|
|
44
|
-
const CDN_BASE = 'https://fonts.
|
|
58
|
+
const CDN_BASE = 'https://cdn.jsdelivr.net/gh/d0nj/dsh-fonts@v1.0.0/fonts';
|
|
45
59
|
/** Stylesheets outlive any one render, and a repeat request is a wasted round-trip. */
|
|
46
60
|
const requested = new Set();
|
|
61
|
+
/**
|
|
62
|
+
* @param family - the family to address.
|
|
63
|
+
* @returns its directory name in the mirror.
|
|
64
|
+
*/
|
|
65
|
+
export function fontSlug(family) {
|
|
66
|
+
return family.toLowerCase().replaceAll(' ', '-').replaceAll(/[^a-z0-9-]/gu, '');
|
|
67
|
+
}
|
|
47
68
|
/**
|
|
48
69
|
* @param font - the family to request.
|
|
49
70
|
* @returns an absolute stylesheet URL.
|
|
50
71
|
*/
|
|
51
72
|
export function hostedFontUrl(font) {
|
|
52
|
-
|
|
53
|
-
const weights = (font.weights ?? [400]).join(';');
|
|
54
|
-
return `${CDN_BASE}?family=${name}:wght@${weights}&display=swap`;
|
|
73
|
+
return `${CDN_BASE}/${fontSlug(font.family)}/font.css`;
|
|
55
74
|
}
|
|
56
75
|
/**
|
|
57
76
|
* Load one family into the page; resolves on failure too, because a font that
|
package/dist/client/panel.js
CHANGED
|
@@ -250,10 +250,10 @@ export function ThemeStudio(React, props) {
|
|
|
250
250
|
const matches = () => {
|
|
251
251
|
const query = combo.query.trim().toLowerCase();
|
|
252
252
|
if (query === '')
|
|
253
|
-
return [DEFAULT_CHOICE, ...choices
|
|
253
|
+
return [DEFAULT_CHOICE, ...choices];
|
|
254
254
|
const filtered = choices.filter((choice) => choice.toLowerCase().includes(query));
|
|
255
255
|
const keepDefault = 'default (built-in)'.includes(query) || 'built-in'.includes(query);
|
|
256
|
-
return
|
|
256
|
+
return keepDefault ? [DEFAULT_CHOICE, ...filtered] : filtered;
|
|
257
257
|
};
|
|
258
258
|
const commit = (value) => {
|
|
259
259
|
combo.open = false;
|
package/dist/resolve.js
CHANGED
|
@@ -24,6 +24,11 @@ const GENERIC_FAMILIES = new Set([
|
|
|
24
24
|
'fangsong', '-apple-system', 'blinkmacsystemfont',
|
|
25
25
|
'inherit', 'initial', 'unset',
|
|
26
26
|
]);
|
|
27
|
+
/** Tokens the Client paints with that no preset names; each follows a documented token. */
|
|
28
|
+
const RUNTIME_ALIASES = [
|
|
29
|
+
['--dsw-specific-input-major', '--dsw-alias-bg-layer-1'],
|
|
30
|
+
['--dsw-alias-button-info-fill', '--dsw-alias-brand-primary'],
|
|
31
|
+
];
|
|
27
32
|
/**
|
|
28
33
|
* Whether a value is a plausible CSS colour.
|
|
29
34
|
*
|
|
@@ -145,6 +150,18 @@ export function resolveCustomization(document) {
|
|
|
145
150
|
}
|
|
146
151
|
tokens[name] = { light, dark };
|
|
147
152
|
}
|
|
153
|
+
for (const [alias, source] of RUNTIME_ALIASES) {
|
|
154
|
+
const modes = tokens[source];
|
|
155
|
+
if (modes !== undefined)
|
|
156
|
+
tokens[alias] = modes;
|
|
157
|
+
}
|
|
158
|
+
const accent = tokens['--dsw-alias-button-info-fill'];
|
|
159
|
+
if (accent !== undefined) {
|
|
160
|
+
tokens['--dsw-alias-button-info-hover'] = {
|
|
161
|
+
light: `color-mix(in srgb, ${accent.light} 85%, black)`,
|
|
162
|
+
dark: `color-mix(in srgb, ${accent.dark} 85%, white)`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
148
165
|
for (const [name, modes] of Object.entries(geometryTokens(document.geometry))) {
|
|
149
166
|
tokens[name] = modes;
|
|
150
167
|
}
|
package/package.json
CHANGED