@adea-ai/ui 0.105.0 → 0.106.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 +44 -8
- package/dist/components/composites/action-button/action-button.d.ts.map +1 -1
- package/dist/components/composites/action-button/action-button.js +6 -8
- package/dist/components/composites/action-button/action-button.js.map +1 -1
- package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts +16 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.js +151 -0
- package/dist/components/composites/appearance-editor/accent-swatch-groups.js.map +1 -0
- package/dist/components/composites/appearance-editor/appearance-choices.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-choices.js +24 -84
- package/dist/components/composites/appearance-editor/appearance-choices.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts +2 -2
- package/dist/components/composites/appearance-editor/appearance-editor.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-editor.js +25 -7
- package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
- package/dist/components/composites/appearance-editor/appearance-types.d.ts +9 -0
- package/dist/components/composites/appearance-editor/appearance-types.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/font-settings-group.d.ts +10 -0
- package/dist/components/composites/appearance-editor/font-settings-group.d.ts.map +1 -0
- package/dist/components/composites/appearance-editor/font-settings-group.js +310 -0
- package/dist/components/composites/appearance-editor/font-settings-group.js.map +1 -0
- package/dist/components/composites/appearance-editor/index.d.ts +2 -0
- package/dist/components/composites/appearance-editor/index.d.ts.map +1 -1
- package/dist/components/composites/appearance-editor/index.js +3 -1
- package/dist/components/composites/update-dialog/update-dialog.js +2 -2
- package/dist/components/composites/update-dialog/update-dialog.js.map +1 -1
- package/dist/components/conversation/message-row.d.ts.map +1 -1
- package/dist/components/conversation/message-row.js +3 -3
- package/dist/components/conversation/message-row.js.map +1 -1
- package/dist/components/conversation/paste-token-editor.js +1 -1
- package/dist/components/conversation/paste-token-editor.js.map +1 -1
- package/dist/components/layout/side-rail/side-rail.js +2 -2
- package/dist/components/layout/side-rail/side-rail.js.map +1 -1
- package/dist/components/layout/top-bar/top-bar.js +1 -1
- package/dist/components/layout/top-bar/top-bar.js.map +1 -1
- package/dist/components/theme/appearance-panel.d.ts +1 -1
- package/dist/components/theme/appearance-panel.d.ts.map +1 -1
- package/dist/components/theme/appearance-panel.js +45 -105
- package/dist/components/theme/appearance-panel.js.map +1 -1
- package/dist/components/theme/theme-provider.d.ts +5 -2
- package/dist/components/theme/theme-provider.d.ts.map +1 -1
- package/dist/components/theme/theme-provider.js +38 -19
- package/dist/components/theme/theme-provider.js.map +1 -1
- package/dist/components/ui/code-block/code-block.d.ts +3 -3
- package/dist/components/ui/code-block/code-block.js +6 -6
- package/dist/components/ui/code-block/code-block.js.map +1 -1
- package/dist/components/ui/command/command.js +1 -1
- package/dist/components/ui/command/command.js.map +1 -1
- package/dist/components/ui/context-menu/context-menu.js +1 -1
- package/dist/components/ui/context-menu/context-menu.js.map +1 -1
- package/dist/components/ui/diff-block/diff-block.js +5 -5
- package/dist/components/ui/diff-block/diff-block.js.map +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.js +101 -8
- package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/ui/kbd/kbd.js +1 -1
- package/dist/components/ui/kbd/kbd.js.map +1 -1
- package/dist/components/ui/menubar/menubar.js +1 -1
- package/dist/components/ui/menubar/menubar.js.map +1 -1
- package/dist/components/ui/typography/typography.d.ts +3 -5
- package/dist/components/ui/typography/typography.d.ts.map +1 -1
- package/dist/components/ui/typography/typography.js +6 -8
- package/dist/components/ui/typography/typography.js.map +1 -1
- package/dist/index.js +6 -3
- package/dist/lib/appearance-font-settings.d.ts +53 -0
- package/dist/lib/appearance-font-settings.d.ts.map +1 -0
- package/dist/lib/appearance-font-settings.js +160 -0
- package/dist/lib/appearance-font-settings.js.map +1 -0
- package/dist/lib/font-catalog.d.ts +72 -0
- package/dist/lib/font-catalog.d.ts.map +1 -0
- package/dist/lib/font-catalog.js +71 -0
- package/dist/lib/font-catalog.js.map +1 -0
- package/dist/lib/safe-script.d.ts +3 -0
- package/dist/lib/safe-script.d.ts.map +1 -0
- package/dist/lib/safe-script.js +9 -0
- package/dist/lib/safe-script.js.map +1 -0
- package/dist/lib/tokens.d.ts +2 -19
- package/dist/lib/tokens.d.ts.map +1 -1
- package/dist/lib/tokens.js +63 -39
- package/dist/lib/tokens.js.map +1 -1
- package/dist/r/appearance-editor.json +11 -0
- package/dist/r/lib.json +15 -0
- package/dist/r/registry.json +33 -0
- package/dist/r/src/components/composites/action-button/action-button.tsx +2 -1
- package/dist/r/src/components/composites/appearance-editor/accent-swatch-groups.tsx +147 -0
- package/dist/r/src/components/composites/appearance-editor/appearance-choices.tsx +17 -74
- package/dist/r/src/components/composites/appearance-editor/appearance-editor.tsx +19 -6
- package/dist/r/src/components/composites/appearance-editor/appearance-types.ts +9 -0
- package/dist/r/src/components/composites/appearance-editor/font-settings-group.tsx +350 -0
- package/dist/r/src/components/composites/appearance-editor/index.ts +19 -0
- package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +2 -2
- package/dist/r/src/components/conversation/message-row.tsx +7 -3
- package/dist/r/src/components/conversation/paste-token-editor.tsx +1 -1
- package/dist/r/src/components/layout/side-rail/side-rail.tsx +3 -3
- package/dist/r/src/components/layout/top-bar/top-bar.tsx +1 -1
- package/dist/r/src/components/theme/appearance-panel.tsx +34 -83
- package/dist/r/src/components/theme/theme-provider.tsx +50 -20
- package/dist/r/src/components/ui/code-block/code-block.tsx +6 -6
- package/dist/r/src/components/ui/command/command.tsx +1 -1
- package/dist/r/src/components/ui/context-menu/context-menu.tsx +1 -1
- package/dist/r/src/components/ui/diff-block/diff-block.tsx +7 -7
- package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +145 -7
- package/dist/r/src/components/ui/kbd/kbd.tsx +1 -1
- package/dist/r/src/components/ui/menubar/menubar.tsx +1 -1
- package/dist/r/src/components/ui/typography/typography.tsx +6 -8
- package/dist/r/src/lib/appearance-font-settings.ts +233 -0
- package/dist/r/src/lib/font-catalog.ts +80 -0
- package/dist/r/src/lib/safe-script.ts +7 -0
- package/dist/r/src/lib/tokens.ts +64 -59
- package/dist/r/src/styles/appearance-font-settings.css +110 -0
- package/dist/r/src/styles/fonts.css +4 -5
- package/dist/r/src/styles/globals.css +4 -1
- package/dist/r/src/styles/theme.css +14 -0
- package/dist/r/theme.json +5 -0
- package/dist/r/theming.json +2 -0
- package/package.json +2 -1
- package/registry.json +33 -0
- package/src/components/composites/action-button/action-button.tsx +2 -1
- package/src/components/composites/appearance-editor/accent-swatch-groups.tsx +147 -0
- package/src/components/composites/appearance-editor/appearance-choices.tsx +17 -74
- package/src/components/composites/appearance-editor/appearance-editor.tsx +19 -6
- package/src/components/composites/appearance-editor/appearance-types.ts +9 -0
- package/src/components/composites/appearance-editor/font-settings-group.tsx +350 -0
- package/src/components/composites/appearance-editor/index.ts +19 -0
- package/src/components/composites/update-dialog/update-dialog.tsx +2 -2
- package/src/components/conversation/message-row.tsx +7 -3
- package/src/components/conversation/paste-token-editor.tsx +1 -1
- package/src/components/layout/side-rail/side-rail.tsx +3 -3
- package/src/components/layout/top-bar/top-bar.tsx +1 -1
- package/src/components/theme/appearance-panel.tsx +34 -83
- package/src/components/theme/theme-provider.tsx +50 -20
- package/src/components/ui/code-block/code-block.tsx +6 -6
- package/src/components/ui/command/command.tsx +1 -1
- package/src/components/ui/context-menu/context-menu.tsx +1 -1
- package/src/components/ui/diff-block/diff-block.tsx +7 -7
- package/src/components/ui/dropdown-menu/dropdown-menu.tsx +145 -7
- package/src/components/ui/kbd/kbd.tsx +1 -1
- package/src/components/ui/menubar/menubar.tsx +1 -1
- package/src/components/ui/typography/typography.tsx +6 -8
- package/src/lib/appearance-font-settings.ts +233 -0
- package/src/lib/font-catalog.ts +80 -0
- package/src/lib/safe-script.ts +7 -0
- package/src/lib/tokens.ts +64 -59
- package/src/styles/appearance-font-settings.css +110 -0
- package/src/styles/fonts.css +4 -5
- package/src/styles/globals.css +4 -1
- package/src/styles/theme.css +14 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { fontOptions } from "./font-catalog.js";
|
|
2
|
+
import { safeScriptStringLiteral } from "./safe-script.js";
|
|
3
|
+
//#region src/lib/appearance-font-settings.ts
|
|
4
|
+
var APPEARANCE_EDITOR_FONT_AXES = [
|
|
5
|
+
"ui",
|
|
6
|
+
"content",
|
|
7
|
+
"code"
|
|
8
|
+
];
|
|
9
|
+
var APPEARANCE_EDITOR_FONT_SIZE_MIN = 10;
|
|
10
|
+
var APPEARANCE_EDITOR_FONT_SIZE_MAX = 32;
|
|
11
|
+
/** New preferences use the platform face in each text role. */
|
|
12
|
+
var DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS = Object.freeze({
|
|
13
|
+
ui: Object.freeze({
|
|
14
|
+
family: "system",
|
|
15
|
+
size: 14
|
|
16
|
+
}),
|
|
17
|
+
content: Object.freeze({
|
|
18
|
+
family: "system",
|
|
19
|
+
size: 14
|
|
20
|
+
}),
|
|
21
|
+
code: Object.freeze({
|
|
22
|
+
family: "system",
|
|
23
|
+
size: 12
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
var fontFamilyIds = new Set(fontOptions.map((option) => option.id));
|
|
27
|
+
var fontOptionsById = Object.freeze(Object.fromEntries(fontOptions.map((option) => [option.id, option])));
|
|
28
|
+
var fontProjectionById = Object.freeze(Object.fromEntries(fontOptions.map((option) => [option.id, {
|
|
29
|
+
familyVariables: option.familyVariables,
|
|
30
|
+
uiTracking: option.uiTracking,
|
|
31
|
+
uiWordSpacing: option.uiWordSpacing
|
|
32
|
+
}])));
|
|
33
|
+
var fontAxisProjection = Object.freeze({
|
|
34
|
+
ui: Object.freeze({
|
|
35
|
+
familyAttribute: "data-ui-font",
|
|
36
|
+
familyProperty: "--font-ui",
|
|
37
|
+
sizeProperty: "--font-ui-size",
|
|
38
|
+
scaleProperty: "--font-ui-scale",
|
|
39
|
+
defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.ui.size
|
|
40
|
+
}),
|
|
41
|
+
content: Object.freeze({
|
|
42
|
+
familyAttribute: "data-content-font",
|
|
43
|
+
familyProperty: "--font-content",
|
|
44
|
+
sizeProperty: "--font-content-size",
|
|
45
|
+
scaleProperty: "--font-content-scale",
|
|
46
|
+
defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.content.size
|
|
47
|
+
}),
|
|
48
|
+
code: Object.freeze({
|
|
49
|
+
familyAttribute: "data-code-font",
|
|
50
|
+
familyProperty: "--font-code",
|
|
51
|
+
sizeProperty: "--font-code-size",
|
|
52
|
+
scaleProperty: "--font-code-scale",
|
|
53
|
+
defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.code.size
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
function isRecord(value) {
|
|
57
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
58
|
+
}
|
|
59
|
+
function hasOwn(value, key) {
|
|
60
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
61
|
+
}
|
|
62
|
+
function normalizeFamily(value) {
|
|
63
|
+
return typeof value === "string" && fontFamilyIds.has(value) ? value : void 0;
|
|
64
|
+
}
|
|
65
|
+
function clampFontSize(value) {
|
|
66
|
+
return Math.min(32, Math.max(10, Math.round(value)));
|
|
67
|
+
}
|
|
68
|
+
/** Normalize a single number-input value; invalid edits return the current size. */
|
|
69
|
+
function normalizeAppearanceEditorFontSize(value, fallback) {
|
|
70
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : NaN;
|
|
71
|
+
return Number.isFinite(parsed) ? clampFontSize(parsed) : clampFontSize(fallback);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Recover persisted font choices against the shared font catalogue.
|
|
75
|
+
*
|
|
76
|
+
* `legacyUiFamily` lets a host migrate its previous single font field into the
|
|
77
|
+
* UI axis. Content and code remain on the new System defaults during that
|
|
78
|
+
* migration. Missing settings are ordinary defaults; an unknown saved id or an
|
|
79
|
+
* invalid size is reported through `recoveredAxes` for the host's notice.
|
|
80
|
+
*/
|
|
81
|
+
function normalizeAppearanceEditorFontSettings(value, legacyUiFamily) {
|
|
82
|
+
const source = isRecord(value) ? value : void 0;
|
|
83
|
+
const malformedRoot = value !== void 0 && value !== null && source === void 0;
|
|
84
|
+
const recovered = /* @__PURE__ */ new Set();
|
|
85
|
+
const settings = {};
|
|
86
|
+
for (const axis of APPEARANCE_EDITOR_FONT_AXES) {
|
|
87
|
+
const axisPresent = source ? hasOwn(source, axis) : false;
|
|
88
|
+
const axisValue = source?.[axis];
|
|
89
|
+
const axisSource = isRecord(axisValue) ? axisValue : void 0;
|
|
90
|
+
const fallback = DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS[axis];
|
|
91
|
+
if (malformedRoot || axisPresent && axisSource === void 0) recovered.add(axis);
|
|
92
|
+
const hasFamily = axisSource ? hasOwn(axisSource, "family") : false;
|
|
93
|
+
const familyInput = hasFamily ? axisSource?.["family"] : axis === "ui" && legacyUiFamily !== void 0 ? legacyUiFamily : void 0;
|
|
94
|
+
const family = normalizeFamily(familyInput) ?? fallback.family;
|
|
95
|
+
if ((hasFamily || axis === "ui" && legacyUiFamily !== void 0) && !normalizeFamily(familyInput)) recovered.add(axis);
|
|
96
|
+
const hasSize = axisSource ? hasOwn(axisSource, "size") : false;
|
|
97
|
+
const sizeInput = axisSource?.["size"];
|
|
98
|
+
const size = hasSize ? normalizeAppearanceEditorFontSize(sizeInput, fallback.size) : fallback.size;
|
|
99
|
+
if (hasSize && (typeof sizeInput !== "number" || !Number.isFinite(sizeInput) || sizeInput !== size)) recovered.add(axis);
|
|
100
|
+
settings[axis] = Object.freeze({
|
|
101
|
+
family,
|
|
102
|
+
size
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return Object.freeze({
|
|
106
|
+
settings: Object.freeze(settings),
|
|
107
|
+
recoveredAxes: Object.freeze(APPEARANCE_EDITOR_FONT_AXES.filter((axis) => recovered.has(axis)))
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Project normalized font preferences onto a document root.
|
|
112
|
+
*
|
|
113
|
+
* This is shared by `ThemeProvider` and hosts that own their own appearance
|
|
114
|
+
* persistence, so UI/content/code use the same catalogue ids, theme tokens,
|
|
115
|
+
* sizes, and projected CSS variables. The marker activates the optional role
|
|
116
|
+
* stylesheet and survives CSS import reordering.
|
|
117
|
+
*/
|
|
118
|
+
function applyAppearanceFontSettings(root, value) {
|
|
119
|
+
const normalized = normalizeAppearanceEditorFontSettings(value);
|
|
120
|
+
const { settings } = normalized;
|
|
121
|
+
root.removeAttribute("data-font");
|
|
122
|
+
root.setAttribute("data-font-settings", "");
|
|
123
|
+
for (const axis of APPEARANCE_EDITOR_FONT_AXES) {
|
|
124
|
+
const projection = fontAxisProjection[axis];
|
|
125
|
+
const setting = settings[axis];
|
|
126
|
+
const option = fontOptionsById[setting.family];
|
|
127
|
+
if (setting.family === "system") root.removeAttribute(projection.familyAttribute);
|
|
128
|
+
else root.setAttribute(projection.familyAttribute, setting.family);
|
|
129
|
+
root.style.setProperty(projection.familyProperty, `var(${option.familyVariables[axis]})`);
|
|
130
|
+
root.style.setProperty(projection.sizeProperty, String(setting.size) + "px");
|
|
131
|
+
root.style.setProperty(projection.scaleProperty, String(setting.size / projection.defaultSize));
|
|
132
|
+
if (axis === "ui") {
|
|
133
|
+
root.style.setProperty("--ui-tracking", option.uiTracking);
|
|
134
|
+
root.style.setProperty("--ui-word-spacing", option.uiWordSpacing);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return normalized;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Generate a safe inline prepaint script for a host-owned appearance record.
|
|
141
|
+
*
|
|
142
|
+
* The stored object is read from `localStorage[storageKey].fonts`. A legacy
|
|
143
|
+
* top-level `font` family migrates into UI only; content/code use the shared
|
|
144
|
+
* defaults. The script applies the same catalogue whitelist, limits, attributes,
|
|
145
|
+
* and CSS properties as `applyAppearanceFontSettings` before styles paint. When
|
|
146
|
+
* `persistedVersion` is supplied, only a record with that exact top-level version
|
|
147
|
+
* is used; absent or mismatched records receive the System defaults.
|
|
148
|
+
*/
|
|
149
|
+
function fontSettingsBootstrapScript(storageKey, persistedVersion) {
|
|
150
|
+
if (persistedVersion !== void 0 && !Number.isSafeInteger(persistedVersion)) throw new RangeError("persistedVersion must be a safe integer");
|
|
151
|
+
const axisConfig = JSON.stringify(fontAxisProjection);
|
|
152
|
+
const fontProjection = JSON.stringify(fontProjectionById);
|
|
153
|
+
const fontIds = `[${fontOptions.map((option) => safeScriptStringLiteral(option.id)).join(",")}]`;
|
|
154
|
+
const persistedVersionGuard = persistedVersion === void 0 ? "" : `&&parsed.version===Number(${safeScriptStringLiteral(String(persistedVersion))})`;
|
|
155
|
+
return `(function(){var r=document.documentElement;var axes=JSON.parse(${safeScriptStringLiteral(axisConfig)});var projection=JSON.parse(${safeScriptStringLiteral(fontProjection)});var ids=${fontIds};var has=function(v,k){return Object.prototype.hasOwnProperty.call(v,k)};var record=function(v){return typeof v==='object'&&v!==null&&!Array.isArray(v)};var p={};try{var raw=localStorage.getItem(${safeScriptStringLiteral(storageKey)});var parsed=raw?JSON.parse(raw):{};if(record(parsed)${persistedVersionGuard})p=parsed;}catch(e){}var saved=record(p.fonts)?p.fonts:{};var valid=function(v,d){return ids.indexOf(v)!==-1?v:d};var size=function(v,d){var n=typeof v==='number'?v:typeof v==='string'&&v.trim()!==''?Number(v):NaN;return Number.isFinite(n)?Math.min(32,Math.max(10,Math.round(n))):d};r.setAttribute('data-font-settings','');for(var axis in axes){if(!has(axes,axis))continue;var spec=axes[axis];var candidate=saved[axis];var value=record(candidate)?candidate:{};var legacyUi=axis==='ui'&&!has(value,'family');var family=legacyUi?valid(p.font,'system'):valid(value.family,'system');var font=projection[family];if(family==='system')r.removeAttribute(spec.familyAttribute);else r.setAttribute(spec.familyAttribute,family);r.style.setProperty(spec.familyProperty,'var('+font.familyVariables[axis]+')');var px=size(value.size,spec.defaultSize);r.style.setProperty(spec.sizeProperty,px+'px');r.style.setProperty(spec.scaleProperty,String(px/spec.defaultSize));if(axis==='ui'){r.style.setProperty('--ui-tracking',font.uiTracking);r.style.setProperty('--ui-word-spacing',font.uiWordSpacing);}}r.removeAttribute('data-font');})();`;
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
export { APPEARANCE_EDITOR_FONT_AXES, APPEARANCE_EDITOR_FONT_SIZE_MAX, APPEARANCE_EDITOR_FONT_SIZE_MIN, DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS, applyAppearanceFontSettings, fontSettingsBootstrapScript, normalizeAppearanceEditorFontSettings, normalizeAppearanceEditorFontSize };
|
|
159
|
+
|
|
160
|
+
//# sourceMappingURL=appearance-font-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance-font-settings.js","names":[],"sources":["../../src/lib/appearance-font-settings.ts"],"sourcesContent":["import { fontOptions, type FontOption } from '#lib/font-catalog'\nimport { safeScriptStringLiteral } from '#lib/safe-script'\n\nexport const APPEARANCE_EDITOR_FONT_AXES = ['ui', 'content', 'code'] as const\n\nexport type AppearanceEditorFontAxis = (typeof APPEARANCE_EDITOR_FONT_AXES)[number]\nexport type AppearanceEditorFontFamilyId = FontOption['id']\n\nexport type AppearanceEditorFontSetting = Readonly<{\n /** A stable id from the shared font catalogue, never a CSS family string. */\n family: AppearanceEditorFontFamilyId\n /** A pixel size, normalized to the supported range. */\n size: number\n}>\n\n/** The host-owned choices edited by the shared appearance composition. */\nexport type AppearanceEditorFontSettings = Readonly<\n Record<AppearanceEditorFontAxis, AppearanceEditorFontSetting>\n>\n\nexport const APPEARANCE_EDITOR_FONT_SIZE_MIN = 10\nexport const APPEARANCE_EDITOR_FONT_SIZE_MAX = 32\n\n/** New preferences use the platform face in each text role. */\nexport const DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS: AppearanceEditorFontSettings = Object.freeze({\n ui: Object.freeze({ family: 'system', size: 14 }),\n content: Object.freeze({ family: 'system', size: 14 }),\n code: Object.freeze({ family: 'system', size: 12 }),\n})\n\nexport type NormalizedAppearanceEditorFontSettings = Readonly<{\n settings: AppearanceEditorFontSettings\n /** Axes whose persisted family or size was unavailable or outside its limits. */\n recoveredAxes: readonly AppearanceEditorFontAxis[]\n}>\n\nconst fontFamilyIds: ReadonlySet<string> = new Set(fontOptions.map((option) => option.id))\nconst fontOptionsById = Object.freeze(\n Object.fromEntries(fontOptions.map((option) => [option.id, option])) as Record<\n AppearanceEditorFontFamilyId,\n FontOption\n >\n)\nconst fontProjectionById = Object.freeze(\n Object.fromEntries(\n fontOptions.map((option) => [\n option.id,\n {\n familyVariables: option.familyVariables,\n uiTracking: option.uiTracking,\n uiWordSpacing: option.uiWordSpacing,\n },\n ])\n ) as Record<\n AppearanceEditorFontFamilyId,\n Pick<FontOption, 'familyVariables' | 'uiTracking' | 'uiWordSpacing'>\n >\n)\nconst fontAxisProjection = Object.freeze({\n ui: Object.freeze({\n familyAttribute: 'data-ui-font',\n familyProperty: '--font-ui',\n sizeProperty: '--font-ui-size',\n scaleProperty: '--font-ui-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.ui.size,\n }),\n content: Object.freeze({\n familyAttribute: 'data-content-font',\n familyProperty: '--font-content',\n sizeProperty: '--font-content-size',\n scaleProperty: '--font-content-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.content.size,\n }),\n code: Object.freeze({\n familyAttribute: 'data-code-font',\n familyProperty: '--font-code',\n sizeProperty: '--font-code-size',\n scaleProperty: '--font-code-scale',\n defaultSize: DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS.code.size,\n }),\n})\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction normalizeFamily(value: unknown): AppearanceEditorFontFamilyId | undefined {\n return typeof value === 'string' && fontFamilyIds.has(value)\n ? (value as AppearanceEditorFontFamilyId)\n : undefined\n}\n\nfunction clampFontSize(value: number): number {\n return Math.min(\n APPEARANCE_EDITOR_FONT_SIZE_MAX,\n Math.max(APPEARANCE_EDITOR_FONT_SIZE_MIN, Math.round(value))\n )\n}\n\n/** Normalize a single number-input value; invalid edits return the current size. */\nexport function normalizeAppearanceEditorFontSize(value: unknown, fallback: number): number {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string' && value.trim() !== ''\n ? Number(value)\n : Number.NaN\n return Number.isFinite(parsed) ? clampFontSize(parsed) : clampFontSize(fallback)\n}\n\n/**\n * Recover persisted font choices against the shared font catalogue.\n *\n * `legacyUiFamily` lets a host migrate its previous single font field into the\n * UI axis. Content and code remain on the new System defaults during that\n * migration. Missing settings are ordinary defaults; an unknown saved id or an\n * invalid size is reported through `recoveredAxes` for the host's notice.\n */\nexport function normalizeAppearanceEditorFontSettings(\n value: unknown,\n legacyUiFamily?: unknown\n): NormalizedAppearanceEditorFontSettings {\n const source = isRecord(value) ? value : undefined\n const malformedRoot = value !== undefined && value !== null && source === undefined\n const recovered = new Set<AppearanceEditorFontAxis>()\n const settings = {} as Record<AppearanceEditorFontAxis, AppearanceEditorFontSetting>\n\n for (const axis of APPEARANCE_EDITOR_FONT_AXES) {\n const axisPresent = source ? hasOwn(source, axis) : false\n const axisValue = source?.[axis]\n const axisSource = isRecord(axisValue) ? axisValue : undefined\n const fallback = DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS[axis]\n\n if (malformedRoot || (axisPresent && axisSource === undefined)) recovered.add(axis)\n\n const hasFamily = axisSource ? hasOwn(axisSource, 'family') : false\n const familyInput = hasFamily\n ? axisSource?.['family']\n : axis === 'ui' && legacyUiFamily !== undefined\n ? legacyUiFamily\n : undefined\n const family = normalizeFamily(familyInput) ?? fallback.family\n if (\n (hasFamily || (axis === 'ui' && legacyUiFamily !== undefined)) &&\n !normalizeFamily(familyInput)\n ) {\n recovered.add(axis)\n }\n\n const hasSize = axisSource ? hasOwn(axisSource, 'size') : false\n const sizeInput = axisSource?.['size']\n const size = hasSize\n ? normalizeAppearanceEditorFontSize(sizeInput, fallback.size)\n : fallback.size\n if (\n hasSize &&\n (typeof sizeInput !== 'number' || !Number.isFinite(sizeInput) || sizeInput !== size)\n ) {\n recovered.add(axis)\n }\n\n settings[axis] = Object.freeze({ family, size })\n }\n\n return Object.freeze({\n settings: Object.freeze(settings),\n recoveredAxes: Object.freeze(APPEARANCE_EDITOR_FONT_AXES.filter((axis) => recovered.has(axis))),\n })\n}\n\n/**\n * Project normalized font preferences onto a document root.\n *\n * This is shared by `ThemeProvider` and hosts that own their own appearance\n * persistence, so UI/content/code use the same catalogue ids, theme tokens,\n * sizes, and projected CSS variables. The marker activates the optional role\n * stylesheet and survives CSS import reordering.\n */\nexport function applyAppearanceFontSettings(\n root: HTMLElement,\n value: unknown\n): NormalizedAppearanceEditorFontSettings {\n const normalized = normalizeAppearanceEditorFontSettings(value)\n const { settings } = normalized\n\n root.removeAttribute('data-font')\n root.setAttribute('data-font-settings', '')\n for (const axis of APPEARANCE_EDITOR_FONT_AXES) {\n const projection = fontAxisProjection[axis]\n const setting = settings[axis]\n const option = fontOptionsById[setting.family]\n if (setting.family === 'system') root.removeAttribute(projection.familyAttribute)\n else root.setAttribute(projection.familyAttribute, setting.family)\n root.style.setProperty(projection.familyProperty, `var(${option.familyVariables[axis]})`)\n root.style.setProperty(projection.sizeProperty, String(setting.size) + 'px')\n root.style.setProperty(projection.scaleProperty, String(setting.size / projection.defaultSize))\n if (axis === 'ui') {\n root.style.setProperty('--ui-tracking', option.uiTracking)\n root.style.setProperty('--ui-word-spacing', option.uiWordSpacing)\n }\n }\n\n return normalized\n}\n\n/**\n * Generate a safe inline prepaint script for a host-owned appearance record.\n *\n * The stored object is read from `localStorage[storageKey].fonts`. A legacy\n * top-level `font` family migrates into UI only; content/code use the shared\n * defaults. The script applies the same catalogue whitelist, limits, attributes,\n * and CSS properties as `applyAppearanceFontSettings` before styles paint. When\n * `persistedVersion` is supplied, only a record with that exact top-level version\n * is used; absent or mismatched records receive the System defaults.\n */\nexport function fontSettingsBootstrapScript(storageKey: string, persistedVersion?: number): string {\n if (persistedVersion !== undefined && !Number.isSafeInteger(persistedVersion)) {\n throw new RangeError('persistedVersion must be a safe integer')\n }\n const axisConfig = JSON.stringify(fontAxisProjection)\n const fontProjection = JSON.stringify(fontProjectionById)\n const fontIds = `[${fontOptions.map((option) => safeScriptStringLiteral(option.id)).join(',')}]`\n const persistedVersionGuard =\n persistedVersion === undefined\n ? ''\n : `&&parsed.version===Number(${safeScriptStringLiteral(String(persistedVersion))})`\n\n return `(function(){var r=document.documentElement;var axes=JSON.parse(${safeScriptStringLiteral(axisConfig)});var projection=JSON.parse(${safeScriptStringLiteral(fontProjection)});var ids=${fontIds};var has=function(v,k){return Object.prototype.hasOwnProperty.call(v,k)};var record=function(v){return typeof v==='object'&&v!==null&&!Array.isArray(v)};var p={};try{var raw=localStorage.getItem(${safeScriptStringLiteral(storageKey)});var parsed=raw?JSON.parse(raw):{};if(record(parsed)${persistedVersionGuard})p=parsed;}catch(e){}var saved=record(p.fonts)?p.fonts:{};var valid=function(v,d){return ids.indexOf(v)!==-1?v:d};var size=function(v,d){var n=typeof v==='number'?v:typeof v==='string'&&v.trim()!==''?Number(v):NaN;return Number.isFinite(n)?Math.min(${APPEARANCE_EDITOR_FONT_SIZE_MAX},Math.max(${APPEARANCE_EDITOR_FONT_SIZE_MIN},Math.round(n))):d};r.setAttribute('data-font-settings','');for(var axis in axes){if(!has(axes,axis))continue;var spec=axes[axis];var candidate=saved[axis];var value=record(candidate)?candidate:{};var legacyUi=axis==='ui'&&!has(value,'family');var family=legacyUi?valid(p.font,'system'):valid(value.family,'system');var font=projection[family];if(family==='system')r.removeAttribute(spec.familyAttribute);else r.setAttribute(spec.familyAttribute,family);r.style.setProperty(spec.familyProperty,'var('+font.familyVariables[axis]+')');var px=size(value.size,spec.defaultSize);r.style.setProperty(spec.sizeProperty,px+'px');r.style.setProperty(spec.scaleProperty,String(px/spec.defaultSize));if(axis==='ui'){r.style.setProperty('--ui-tracking',font.uiTracking);r.style.setProperty('--ui-word-spacing',font.uiWordSpacing);}}r.removeAttribute('data-font');})();`\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable font-family choices shared by the appearance editor and its host APIs.
|
|
3
|
+
*
|
|
4
|
+
* This stays independent of the theme-token manifest so consumers that need
|
|
5
|
+
* only font settings do not retain the palette catalogue.
|
|
6
|
+
*/
|
|
7
|
+
declare const FONT_OPTIONS: readonly [{
|
|
8
|
+
readonly id: "space-grotesk";
|
|
9
|
+
readonly label: "Space Grotesk";
|
|
10
|
+
readonly description: "The self-hosted Space Grotesk family.";
|
|
11
|
+
readonly familyVariables: {
|
|
12
|
+
readonly ui: "--font-family-space-grotesk";
|
|
13
|
+
readonly content: "--font-family-space-grotesk";
|
|
14
|
+
readonly code: "--font-family-space-grotesk";
|
|
15
|
+
};
|
|
16
|
+
readonly uiTracking: "normal";
|
|
17
|
+
readonly uiWordSpacing: "normal";
|
|
18
|
+
readonly stack: "both";
|
|
19
|
+
}, {
|
|
20
|
+
readonly id: "system";
|
|
21
|
+
readonly label: "System";
|
|
22
|
+
readonly description: "The platform's own interface family and system monospace counterpart.";
|
|
23
|
+
readonly familyVariables: {
|
|
24
|
+
readonly ui: "--font-family-system";
|
|
25
|
+
readonly content: "--font-family-system";
|
|
26
|
+
readonly code: "--font-family-system-mono";
|
|
27
|
+
};
|
|
28
|
+
readonly uiTracking: "normal";
|
|
29
|
+
readonly uiWordSpacing: "normal";
|
|
30
|
+
readonly stack: "both";
|
|
31
|
+
}, {
|
|
32
|
+
readonly id: "geist";
|
|
33
|
+
readonly label: "Geist";
|
|
34
|
+
readonly description: "The face cortana already ships. Neutral and wide.";
|
|
35
|
+
readonly familyVariables: {
|
|
36
|
+
readonly ui: "--font-family-geist";
|
|
37
|
+
readonly content: "--font-family-geist";
|
|
38
|
+
readonly code: "--font-family-geist";
|
|
39
|
+
};
|
|
40
|
+
readonly uiTracking: "normal";
|
|
41
|
+
readonly uiWordSpacing: "normal";
|
|
42
|
+
readonly stack: "both";
|
|
43
|
+
}, {
|
|
44
|
+
readonly id: "geist-mono";
|
|
45
|
+
readonly label: "Geist Mono";
|
|
46
|
+
readonly description: "Monospace throughout, for someone who wants a uniform texture.";
|
|
47
|
+
readonly familyVariables: {
|
|
48
|
+
readonly ui: "--font-family-geist-mono";
|
|
49
|
+
readonly content: "--font-family-geist-mono";
|
|
50
|
+
readonly code: "--font-family-geist-mono";
|
|
51
|
+
};
|
|
52
|
+
readonly uiTracking: "-0.03em";
|
|
53
|
+
readonly uiWordSpacing: "-1.5px";
|
|
54
|
+
readonly stack: "both";
|
|
55
|
+
}, {
|
|
56
|
+
readonly id: "jetbrains-mono";
|
|
57
|
+
readonly label: "JetBrains Mono";
|
|
58
|
+
readonly description: "Monospace throughout, with coding ligatures off.";
|
|
59
|
+
readonly familyVariables: {
|
|
60
|
+
readonly ui: "--font-family-jetbrains-mono";
|
|
61
|
+
readonly content: "--font-family-jetbrains-mono";
|
|
62
|
+
readonly code: "--font-family-jetbrains-mono";
|
|
63
|
+
};
|
|
64
|
+
readonly uiTracking: "-0.04em";
|
|
65
|
+
readonly uiWordSpacing: "-2.5px";
|
|
66
|
+
readonly stack: "both";
|
|
67
|
+
}];
|
|
68
|
+
/** Stable catalogue record type; saved values never contain CSS family strings. */
|
|
69
|
+
export type FontOption = (typeof FONT_OPTIONS)[number];
|
|
70
|
+
export declare const fontOptions: readonly FontOption[];
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=font-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-catalog.d.ts","sourceRoot":"","sources":["../../src/lib/font-catalog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkER,CAAA;AAEV,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,eAAO,MAAM,WAAW,EAAE,SAAS,UAAU,EAAgC,CAAA"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
var fontOptions = Object.freeze([
|
|
2
|
+
{
|
|
3
|
+
id: "space-grotesk",
|
|
4
|
+
label: "Space Grotesk",
|
|
5
|
+
description: "The self-hosted Space Grotesk family.",
|
|
6
|
+
familyVariables: {
|
|
7
|
+
ui: "--font-family-space-grotesk",
|
|
8
|
+
content: "--font-family-space-grotesk",
|
|
9
|
+
code: "--font-family-space-grotesk"
|
|
10
|
+
},
|
|
11
|
+
uiTracking: "normal",
|
|
12
|
+
uiWordSpacing: "normal",
|
|
13
|
+
stack: "both"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "system",
|
|
17
|
+
label: "System",
|
|
18
|
+
description: "The platform's own interface family and system monospace counterpart.",
|
|
19
|
+
familyVariables: {
|
|
20
|
+
ui: "--font-family-system",
|
|
21
|
+
content: "--font-family-system",
|
|
22
|
+
code: "--font-family-system-mono"
|
|
23
|
+
},
|
|
24
|
+
uiTracking: "normal",
|
|
25
|
+
uiWordSpacing: "normal",
|
|
26
|
+
stack: "both"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "geist",
|
|
30
|
+
label: "Geist",
|
|
31
|
+
description: "The face cortana already ships. Neutral and wide.",
|
|
32
|
+
familyVariables: {
|
|
33
|
+
ui: "--font-family-geist",
|
|
34
|
+
content: "--font-family-geist",
|
|
35
|
+
code: "--font-family-geist"
|
|
36
|
+
},
|
|
37
|
+
uiTracking: "normal",
|
|
38
|
+
uiWordSpacing: "normal",
|
|
39
|
+
stack: "both"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "geist-mono",
|
|
43
|
+
label: "Geist Mono",
|
|
44
|
+
description: "Monospace throughout, for someone who wants a uniform texture.",
|
|
45
|
+
familyVariables: {
|
|
46
|
+
ui: "--font-family-geist-mono",
|
|
47
|
+
content: "--font-family-geist-mono",
|
|
48
|
+
code: "--font-family-geist-mono"
|
|
49
|
+
},
|
|
50
|
+
uiTracking: "-0.03em",
|
|
51
|
+
uiWordSpacing: "-1.5px",
|
|
52
|
+
stack: "both"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "jetbrains-mono",
|
|
56
|
+
label: "JetBrains Mono",
|
|
57
|
+
description: "Monospace throughout, with coding ligatures off.",
|
|
58
|
+
familyVariables: {
|
|
59
|
+
ui: "--font-family-jetbrains-mono",
|
|
60
|
+
content: "--font-family-jetbrains-mono",
|
|
61
|
+
code: "--font-family-jetbrains-mono"
|
|
62
|
+
},
|
|
63
|
+
uiTracking: "-0.04em",
|
|
64
|
+
uiWordSpacing: "-2.5px",
|
|
65
|
+
stack: "both"
|
|
66
|
+
}
|
|
67
|
+
]);
|
|
68
|
+
//#endregion
|
|
69
|
+
export { fontOptions };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=font-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-catalog.js","names":[],"sources":["../../src/lib/font-catalog.ts"],"sourcesContent":["/**\n * Stable font-family choices shared by the appearance editor and its host APIs.\n *\n * This stays independent of the theme-token manifest so consumers that need\n * only font settings do not retain the palette catalogue.\n */\n// Explicit catalogue choices resolve to the same named face in every role.\n// System Code is the exception: it resolves to the platform monospace stack.\nconst FONT_OPTIONS = [\n {\n id: 'space-grotesk',\n label: 'Space Grotesk',\n description: 'The self-hosted Space Grotesk family.',\n familyVariables: {\n ui: '--font-family-space-grotesk',\n content: '--font-family-space-grotesk',\n code: '--font-family-space-grotesk',\n },\n uiTracking: 'normal',\n uiWordSpacing: 'normal',\n stack: 'both',\n },\n {\n id: 'system',\n label: 'System',\n description: \"The platform's own interface family and system monospace counterpart.\",\n familyVariables: {\n ui: '--font-family-system',\n content: '--font-family-system',\n code: '--font-family-system-mono',\n },\n uiTracking: 'normal',\n uiWordSpacing: 'normal',\n stack: 'both',\n },\n {\n id: 'geist',\n label: 'Geist',\n description: 'The face cortana already ships. Neutral and wide.',\n familyVariables: {\n ui: '--font-family-geist',\n content: '--font-family-geist',\n code: '--font-family-geist',\n },\n uiTracking: 'normal',\n uiWordSpacing: 'normal',\n stack: 'both',\n },\n {\n id: 'geist-mono',\n label: 'Geist Mono',\n description: 'Monospace throughout, for someone who wants a uniform texture.',\n familyVariables: {\n ui: '--font-family-geist-mono',\n content: '--font-family-geist-mono',\n code: '--font-family-geist-mono',\n },\n uiTracking: '-0.03em',\n uiWordSpacing: '-1.5px',\n stack: 'both',\n },\n {\n id: 'jetbrains-mono',\n label: 'JetBrains Mono',\n description: 'Monospace throughout, with coding ligatures off.',\n familyVariables: {\n ui: '--font-family-jetbrains-mono',\n content: '--font-family-jetbrains-mono',\n code: '--font-family-jetbrains-mono',\n },\n uiTracking: '-0.04em',\n uiWordSpacing: '-2.5px',\n stack: 'both',\n },\n] as const\n\n/** Stable catalogue record type; saved values never contain CSS family strings. */\nexport type FontOption = (typeof FONT_OPTIONS)[number]\n\nexport const fontOptions: readonly FontOption[] = Object.freeze(FONT_OPTIONS)\n"],"mappings":"AA+EA,IAAa,cAAqC,OAAO,OAAO;CAtE9D;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,iBAAiB;GACf,IAAI;GACJ,SAAS;GACT,MAAM;EACR;EACA,YAAY;EACZ,eAAe;EACf,OAAO;CACT;CACA;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,iBAAiB;GACf,IAAI;GACJ,SAAS;GACT,MAAM;EACR;EACA,YAAY;EACZ,eAAe;EACf,OAAO;CACT;CACA;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,iBAAiB;GACf,IAAI;GACJ,SAAS;GACT,MAAM;EACR;EACA,YAAY;EACZ,eAAe;EACf,OAAO;CACT;CACA;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,iBAAiB;GACf,IAAI;GACJ,SAAS;GACT,MAAM;EACR;EACA,YAAY;EACZ,eAAe;EACf,OAAO;CACT;CACA;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,iBAAiB;GACf,IAAI;GACJ,SAAS;GACT,MAAM;EACR;EACA,YAAY;EACZ,eAAe;EACf,OAAO;CACT;AAM8D,CAAY"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-script.d.ts","sourceRoot":"","sources":["../../src/lib/safe-script.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/lib/safe-script.ts
|
|
2
|
+
/** Escape a string literal for an inline script's JavaScript source. */
|
|
3
|
+
function safeScriptStringLiteral(value) {
|
|
4
|
+
return JSON.stringify(value).replace(/[<>\u2028\u2029]/g, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { safeScriptStringLiteral };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=safe-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-script.js","names":[],"sources":["../../src/lib/safe-script.ts"],"sourcesContent":["/** Escape a string literal for an inline script's JavaScript source. */\nexport function safeScriptStringLiteral(value: string): string {\n return JSON.stringify(value).replace(\n /[<>\\u2028\\u2029]/g,\n (character) => `\\\\u${character.charCodeAt(0).toString(16).padStart(4, '0')}`\n )\n}\n"],"mappings":";;AACA,SAAgB,wBAAwB,OAAuB;CAC7D,OAAO,KAAK,UAAU,KAAK,CAAC,CAAC,QAC3B,sBACC,cAAc,MAAM,UAAU,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,GAC3E;AACF"}
|
package/dist/lib/tokens.d.ts
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* That pairing is what makes "every token is documented and every documented
|
|
17
17
|
* token exists" a property the build enforces rather than a promise.
|
|
18
18
|
*/
|
|
19
|
+
export { fontOptions } from './font-catalog';
|
|
20
|
+
export type { FontOption } from './font-catalog';
|
|
19
21
|
export type TokenKind = 'color' | 'dimension' | 'font-family' | 'number' | 'duration' | 'easing' | 'shadow' | 'text';
|
|
20
22
|
export type TokenDefinition = {
|
|
21
23
|
/** The custom property name, without the leading `--`. */
|
|
@@ -66,25 +68,6 @@ export type AccentPreset = {
|
|
|
66
68
|
dark?: string;
|
|
67
69
|
};
|
|
68
70
|
export declare const accentPresets: readonly AccentPreset[];
|
|
69
|
-
/**
|
|
70
|
-
* The font axis.
|
|
71
|
-
*
|
|
72
|
-
* The family is a selection, like the accent: `data-font` sits on the same element
|
|
73
|
-
* and each option swaps the interface face. `space-grotesk` is the default because
|
|
74
|
-
* it is the face the visual language was drawn against, and `system` is a
|
|
75
|
-
* first-class option rather than a fallback — an application that wants the
|
|
76
|
-
* platform's own face should be able to say so without losing the rest of the
|
|
77
|
-
* system.
|
|
78
|
-
*/
|
|
79
|
-
export type FontOption = {
|
|
80
|
-
/** The `data-font` value. `space-grotesk` is the default and needs no attribute. */
|
|
81
|
-
id: string;
|
|
82
|
-
label: string;
|
|
83
|
-
description: string;
|
|
84
|
-
/** Which of the two stacks this option sets. */
|
|
85
|
-
stack: 'sans' | 'mono' | 'both';
|
|
86
|
-
};
|
|
87
|
-
export declare const fontOptions: readonly FontOption[];
|
|
88
71
|
/** Every token, in gallery order. */
|
|
89
72
|
export declare const designTokens: {
|
|
90
73
|
readonly color: TokenDefinition[];
|
package/dist/lib/tokens.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/lib/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/lib/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,WAAW,GACX,aAAa,GACb,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,MAAM,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG;IAC5B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,SAAS,CAAA;IACf,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,eAAe,EAoUxC,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,eAAe,EAezC,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,eAAe,EAgI7C,CAAA;AAED;;+EAE+E;AAC/E,eAAO,MAAM,aAAa,EAAE,eAAe,EAmF1C,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,eAAe,EA2B5C,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,eAAe,EAkBzC,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,eAAe,EAyBzC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAA;IACnB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,SAAS,YAAY,EAQ/C,CAAA;AAEF,qCAAqC;AACrC,eAAO,MAAM,YAAY;;;;;;;;CAQf,CAAA;AAEV,yDAAyD;AACzD,eAAO,MAAM,SAAS,EAAE,eAAe,EAAuC,CAAA;AAE9E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAAe,CAAA"}
|
package/dist/lib/tokens.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fontOptions } from "./font-catalog.js";
|
|
1
2
|
import { ACCENTS } from "@adea-ai/themes";
|
|
2
3
|
//#region src/lib/tokens.ts
|
|
3
4
|
/**
|
|
@@ -446,20 +447,35 @@ var radiusTokens = [
|
|
|
446
447
|
}
|
|
447
448
|
];
|
|
448
449
|
var typographyTokens = [
|
|
450
|
+
{
|
|
451
|
+
name: "font-ui",
|
|
452
|
+
kind: "font-family",
|
|
453
|
+
description: "The selected family for interface controls, labels and headings."
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
name: "font-content",
|
|
457
|
+
kind: "font-family",
|
|
458
|
+
description: "The selected family for prose, transcripts and long-form reading."
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
name: "font-code",
|
|
462
|
+
kind: "font-family",
|
|
463
|
+
description: "The selected family for code, terminals, keyboard keys, ids and paths."
|
|
464
|
+
},
|
|
449
465
|
{
|
|
450
466
|
name: "font-sans",
|
|
451
467
|
kind: "font-family",
|
|
452
|
-
description: "
|
|
468
|
+
description: "Compatibility alias for the selected UI family."
|
|
453
469
|
},
|
|
454
470
|
{
|
|
455
471
|
name: "font-mono",
|
|
456
472
|
kind: "font-family",
|
|
457
|
-
description: "
|
|
473
|
+
description: "Compatibility alias for the selected code family."
|
|
458
474
|
},
|
|
459
475
|
{
|
|
460
476
|
name: "font-family-space-grotesk",
|
|
461
477
|
kind: "font-family",
|
|
462
|
-
description: "The
|
|
478
|
+
description: "The self-hosted Space Grotesk family."
|
|
463
479
|
},
|
|
464
480
|
{
|
|
465
481
|
name: "font-family-jetbrains-mono",
|
|
@@ -486,6 +502,36 @@ var typographyTokens = [
|
|
|
486
502
|
kind: "font-family",
|
|
487
503
|
description: "The platform's own monospace face."
|
|
488
504
|
},
|
|
505
|
+
{
|
|
506
|
+
name: "font-ui-size",
|
|
507
|
+
kind: "dimension",
|
|
508
|
+
description: "Runtime-projected interface size in pixels; scales the shared UI text ladder."
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
name: "font-content-size",
|
|
512
|
+
kind: "dimension",
|
|
513
|
+
description: "Runtime-projected prose and transcript size in pixels."
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
name: "font-code-size",
|
|
517
|
+
kind: "dimension",
|
|
518
|
+
description: "Runtime-projected code, terminal and keyboard-key size in pixels."
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
name: "font-ui-scale",
|
|
522
|
+
kind: "number",
|
|
523
|
+
description: "The UI size ratio applied to the interface text ladder."
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
name: "font-content-scale",
|
|
527
|
+
kind: "number",
|
|
528
|
+
description: "The content size ratio applied to rem-relative prose text."
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
name: "font-code-scale",
|
|
532
|
+
kind: "number",
|
|
533
|
+
description: "The code size ratio applied to rem-relative code text."
|
|
534
|
+
},
|
|
489
535
|
{
|
|
490
536
|
name: "ui-tracking",
|
|
491
537
|
kind: "text",
|
|
@@ -499,17 +545,17 @@ var typographyTokens = [
|
|
|
499
545
|
{
|
|
500
546
|
name: "text-2xs",
|
|
501
547
|
kind: "text",
|
|
502
|
-
description: "
|
|
548
|
+
description: "The smallest UI-scaled label: status bar and compact metadata."
|
|
503
549
|
},
|
|
504
550
|
{
|
|
505
551
|
name: "text-xs",
|
|
506
552
|
kind: "text",
|
|
507
|
-
description: "
|
|
553
|
+
description: "UI-scaled metadata, badges and secondary rows."
|
|
508
554
|
},
|
|
509
555
|
{
|
|
510
556
|
name: "text-sm",
|
|
511
557
|
kind: "text",
|
|
512
|
-
description: "
|
|
558
|
+
description: "The UI-scaled interface default for labels and controls."
|
|
513
559
|
},
|
|
514
560
|
{
|
|
515
561
|
name: "text-base",
|
|
@@ -534,7 +580,17 @@ var typographyTokens = [
|
|
|
534
580
|
{
|
|
535
581
|
name: "text-3xl",
|
|
536
582
|
kind: "text",
|
|
537
|
-
description: "
|
|
583
|
+
description: "The largest UI-scaled rung. Reserved for an empty-state headline."
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
name: "text-content",
|
|
587
|
+
kind: "text",
|
|
588
|
+
description: "The selected content size with the prose line-height."
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
name: "text-code",
|
|
592
|
+
kind: "text",
|
|
593
|
+
description: "The selected code size with the code line-height."
|
|
538
594
|
}
|
|
539
595
|
];
|
|
540
596
|
/** Height tokens also size both axes of icon controls through Tailwind's --size
|
|
@@ -779,38 +835,6 @@ var accentPresets = Object.freeze([{
|
|
|
779
835
|
label: "Theme",
|
|
780
836
|
description: "The variant's own primary. Neutral in adea's palette, so the interface stays monochrome."
|
|
781
837
|
}, ...ACCENTS]);
|
|
782
|
-
var fontOptions = Object.freeze([
|
|
783
|
-
{
|
|
784
|
-
id: "space-grotesk",
|
|
785
|
-
label: "Space Grotesk",
|
|
786
|
-
description: "The default, and the face the visual language was drawn against.",
|
|
787
|
-
stack: "both"
|
|
788
|
-
},
|
|
789
|
-
{
|
|
790
|
-
id: "system",
|
|
791
|
-
label: "System",
|
|
792
|
-
description: "The platform's own face. What a terminal or editor usually wants.",
|
|
793
|
-
stack: "both"
|
|
794
|
-
},
|
|
795
|
-
{
|
|
796
|
-
id: "geist",
|
|
797
|
-
label: "Geist",
|
|
798
|
-
description: "The face cortana already ships. Neutral and wide.",
|
|
799
|
-
stack: "both"
|
|
800
|
-
},
|
|
801
|
-
{
|
|
802
|
-
id: "geist-mono",
|
|
803
|
-
label: "Geist Mono",
|
|
804
|
-
description: "Monospace throughout, for someone who wants a uniform texture.",
|
|
805
|
-
stack: "both"
|
|
806
|
-
},
|
|
807
|
-
{
|
|
808
|
-
id: "jetbrains-mono",
|
|
809
|
-
label: "JetBrains Mono",
|
|
810
|
-
description: "Monospace throughout, with coding ligatures off.",
|
|
811
|
-
stack: "both"
|
|
812
|
-
}
|
|
813
|
-
]);
|
|
814
838
|
/** Every token, in gallery order. */
|
|
815
839
|
var designTokens = {
|
|
816
840
|
color: colorTokens,
|