theme-vir 28.25.2 → 29.0.0-beta.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/dist/index.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export * from './color-theme/apply-color-theme.js';
2
2
  export * from './color-theme/build-color-theme.js';
3
- export * from './color-theme/color-palette-book-pages.js';
4
- export * from './color-theme/color-theme-book-pages.js';
5
3
  export * from './color-theme/color-theme-code.js';
6
4
  export * from './color-theme/color-theme-init.js';
7
5
  export * from './color-theme/color-theme-override.js';
package/dist/index.js CHANGED
@@ -1,7 +1,5 @@
1
1
  export * from './color-theme/apply-color-theme.js';
2
2
  export * from './color-theme/build-color-theme.js';
3
- export * from './color-theme/color-palette-book-pages.js';
4
- export * from './color-theme/color-theme-book-pages.js';
5
3
  export * from './color-theme/color-theme-code.js';
6
4
  export * from './color-theme/color-theme-init.js';
7
5
  export * from './color-theme/color-theme-override.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "theme-vir",
3
- "version": "28.25.2",
3
+ "version": "29.0.0-beta.0",
4
4
  "description": "Create an entire web theme.",
5
5
  "keywords": [
6
6
  "design",
@@ -36,43 +36,36 @@
36
36
  "build": "npm run docs",
37
37
  "compile": "virmator compile",
38
38
  "docs": "virmator docs",
39
- "start": "npm run compile && virmator frontend",
40
39
  "test": "virmator test web",
41
40
  "test:coverage": "npm run test coverage",
42
41
  "test:docs": "virmator docs check",
43
42
  "test:update": "virmator test web update"
44
43
  },
45
44
  "dependencies": {
46
- "@augment-vir/assert": "^32.2.3",
47
- "@augment-vir/common": "^32.2.3",
45
+ "@augment-vir/assert": "^32.3.0-beta.0",
46
+ "@augment-vir/common": "^32.3.0-beta.0",
48
47
  "@electrovir/color": "^1.7.11",
49
48
  "apca-w3": "^0.1.9",
50
49
  "lit-css-vars": "^3.6.3",
51
50
  "type-fest": "^5.8.0"
52
51
  },
53
52
  "devDependencies": {
54
- "@augment-vir/test": "^32.2.3",
53
+ "@augment-vir/test": "^32.3.0-beta.0",
55
54
  "@types/apca-w3": "^0.1.3",
56
55
  "@web/dev-server-esbuild": "^2.0.0",
57
56
  "@web/test-runner": "^1.0.0",
58
57
  "@web/test-runner-commands": "^1.0.1",
59
58
  "@web/test-runner-playwright": "^1.0.0",
60
59
  "@web/test-runner-visual-regression": "^1.0.1",
61
- "element-book": "^26.17.4",
62
- "element-vir": "^26.17.3",
60
+ "element-vir": "^27.0.0-beta.3",
63
61
  "esbuild": "^0.28.2",
64
62
  "istanbul-smart-text-reporter": "^1.1.5",
65
63
  "markdown-code-example-inserter": "^3.0.6",
66
64
  "typedoc": "^0.28.20",
67
- "typescript": "5.9.3",
68
- "vira": "^31.31.6",
69
- "vite": "^8.2.2",
70
- "vite-tsconfig-paths": "^6.1.1"
65
+ "typescript": "5.9.3"
71
66
  },
72
67
  "peerDependencies": {
73
- "element-book": ">=17",
74
- "element-vir": "^26",
75
- "vira": ">=28"
68
+ "element-vir": "^27.0.0-beta.3"
76
69
  },
77
70
  "engines": {
78
71
  "node": ">=22"
@@ -1,19 +0,0 @@
1
- import { type PartialWithUndefined } from '@augment-vir/common';
2
- import { type BookPage } from 'element-book';
3
- import { type BuildLowLevelColorThemeOptions, type ColorPaletteVars } from './build-color-theme.js';
4
- /**
5
- * Create multiple element-book pages to showcase a bunch of color CSS variables.
6
- *
7
- * @category Color Theme
8
- * @see `createColorThemeBookPages` for creating full color theme pages.
9
- */
10
- export declare function createColorPaletteBookPages({ colors, parent, title, includeContrast, includeTheme, useVerticalTheme, options, }: {
11
- title: string;
12
- colors: Readonly<ColorPaletteVars>;
13
- } & PartialWithUndefined<{
14
- parent: Readonly<BookPage>;
15
- includeContrast: boolean;
16
- includeTheme: boolean;
17
- useVerticalTheme: boolean;
18
- options: Readonly<BuildLowLevelColorThemeOptions>;
19
- }>): BookPage[];
@@ -1,275 +0,0 @@
1
- import { check } from '@augment-vir/assert';
2
- import { VirColorPair } from '@electrovir/color';
3
- import { defineBookPage } from 'element-book';
4
- import { css, html, listen, unsafeCSS } from 'element-vir';
5
- import { noNativeSpacing, viraTheme } from 'vira';
6
- import { buildColorTheme, groupColors, } from './build-color-theme.js';
7
- import { createColorThemeBookPages } from './color-theme-book-pages.js';
8
- import { themeDefaultKey } from './color-theme.js';
9
- const blackWhiteCells = [
10
- {
11
- title: 'Black',
12
- fontWeight: 400,
13
- foreground: viraTheme.colors[themeDefaultKey].foreground,
14
- },
15
- {
16
- title: 'Black',
17
- fontWeight: 700,
18
- foreground: viraTheme.colors[themeDefaultKey].foreground,
19
- },
20
- {
21
- title: 'White',
22
- fontWeight: 400,
23
- foreground: viraTheme.colors[themeDefaultKey].background,
24
- },
25
- {
26
- title: 'White',
27
- fontWeight: 700,
28
- foreground: viraTheme.colors[themeDefaultKey].background,
29
- },
30
- {
31
- title: 'Black',
32
- fontWeight: 400,
33
- background: viraTheme.colors[themeDefaultKey].foreground,
34
- },
35
- {
36
- title: 'Black',
37
- fontWeight: 700,
38
- background: viraTheme.colors[themeDefaultKey].foreground,
39
- },
40
- {
41
- title: 'White',
42
- fontWeight: 400,
43
- background: viraTheme.colors[themeDefaultKey].background,
44
- },
45
- {
46
- title: 'White',
47
- fontWeight: 700,
48
- background: viraTheme.colors[themeDefaultKey].background,
49
- },
50
- ];
51
- /**
52
- * Create multiple element-book pages to showcase a bunch of color CSS variables.
53
- *
54
- * @category Color Theme
55
- * @see `createColorThemeBookPages` for creating full color theme pages.
56
- */
57
- export function createColorPaletteBookPages({ colors, parent, title, includeContrast, includeTheme, useVerticalTheme, options, }) {
58
- const colorGroups = groupColors(colors);
59
- const topColorsPage = defineBookPage({
60
- parent,
61
- title,
62
- });
63
- const colorPalettePage = defineBookPage({
64
- parent: topColorsPage,
65
- title: 'Palette',
66
- defineExamples({ defineExample }) {
67
- defineExample({
68
- title: 'All Colors',
69
- styles: css `
70
- :host {
71
- display: flex;
72
- flex-direction: row;
73
- }
74
-
75
- p {
76
- ${noNativeSpacing}
77
- }
78
-
79
- .color-column {
80
- display: flex;
81
- flex-direction: column;
82
- }
83
-
84
- .column-title {
85
- text-align: center;
86
- font-size: 12px;
87
- padding-bottom: 4px;
88
- border-bottom: 1px solid
89
- ${viraTheme.colors['vira-grey-foreground-decoration'].foreground.value};
90
- margin-bottom: 4px;
91
- color: ${viraTheme.colors['vira-grey-foreground-non-body'].foreground
92
- .value};
93
- }
94
-
95
- .swatch-wrapper {
96
- display: flex;
97
- gap: 4px;
98
- align-items: center;
99
-
100
- & .swatch {
101
- width: 50px;
102
- height: 50px;
103
- cursor: pointer;
104
- }
105
-
106
- & .color-details {
107
- display: none;
108
- font-family: monospace;
109
- font-size: 12px;
110
- color: ${viraTheme.colors['vira-grey-foreground-non-body'].foreground
111
- .value};
112
- }
113
-
114
- &.expanded .color-details {
115
- display: block;
116
- }
117
-
118
- & .color-value {
119
- margin-left: 1ch;
120
- }
121
- }
122
- `,
123
- render() {
124
- return Object.entries(colorGroups).map(([groupName, colors,]) => {
125
- return html `
126
- <div class="color-column">
127
- <p class="column-title">${groupName}</p>
128
- ${colors.map((color) => {
129
- return html `
130
- <div class="swatch-wrapper">
131
- <div
132
- class="swatch"
133
- style=${css `
134
- background-color: ${unsafeCSS(color.definition.default)};
135
- `}
136
- ${listen('click', (event) => {
137
- const wrapper = event.currentTarget.parentElement;
138
- wrapper?.classList.toggle('expanded');
139
- })}
140
- ></div>
141
- <p class="color-details">
142
- <span>${color.cssVarName}</span>
143
- <br />
144
- <span class="color-value">
145
- ${color.definition.default}
146
- </span>
147
- </p>
148
- </div>
149
- `;
150
- })}
151
- </div>
152
- `;
153
- });
154
- },
155
- });
156
- },
157
- });
158
- const contrastsPage = defineBookPage({
159
- parent: topColorsPage,
160
- title: 'Palette Contrast',
161
- });
162
- function createContrastPage(contrastPageTitle, contrastCellsInput) {
163
- return defineBookPage({
164
- parent: contrastsPage,
165
- title: `${title} ${contrastPageTitle}`,
166
- defineExamples({ defineExample }) {
167
- Object.entries(colorGroups).forEach(([groupName, colors,]) => {
168
- const contrastCells = check.isArray(contrastCellsInput)
169
- ? contrastCellsInput
170
- : contrastCellsInput(colors);
171
- defineExample({
172
- title: groupName,
173
- styles: css `
174
- :host {
175
- display: flex;
176
- flex-direction: column;
177
- gap: 24px;
178
- }
179
-
180
- p {
181
- ${noNativeSpacing}
182
- }
183
-
184
- .darkness-level {
185
- text-align: center;
186
- font-size: 12px;
187
- color: ${viraTheme.colors['vira-grey-foreground-header']
188
- .foreground.value};
189
- }
190
-
191
- td {
192
- padding: 4px;
193
- min-width: 170px;
194
- }
195
- `,
196
- render() {
197
- const colorRowTemplates = colors.map((color) => {
198
- const cellTemplates = contrastCells.map((cell) => {
199
- return html `
200
- <td>
201
- <p class="darkness-level">${color.suffix}</p>
202
- <${VirColorPair.assign({
203
- color: {
204
- background: cell.background || color.definition,
205
- foreground: cell.foreground || color.definition,
206
- },
207
- showVarValues: true,
208
- showVarNames: false,
209
- showContrast: true,
210
- fontWeight: cell.fontWeight,
211
- })}></${VirColorPair}>
212
- </td>
213
- `;
214
- });
215
- return html `
216
- <tr>${cellTemplates}</tr>
217
- `;
218
- });
219
- const headerCells = contrastCells.map((cell) => {
220
- const layerText = cell.background ? 'in back' : 'in front';
221
- const title = [
222
- cell.title,
223
- `(${layerText})`,
224
- `(${cell.fontWeight})`,
225
- ].join(' ');
226
- return html `
227
- <th>${title}</th>
228
- `;
229
- });
230
- return html `
231
- <table cellspacing="0" cellpadding="0">
232
- <thead><tr>${headerCells}</tr></thead>
233
- <tbody>${colorRowTemplates}</tbody>
234
- </table>
235
- `;
236
- },
237
- });
238
- });
239
- },
240
- });
241
- }
242
- const blackWhiteContrastPage = createContrastPage('Contrast Black White', blackWhiteCells);
243
- function createSelfContrastPage(fontWeight) {
244
- return createContrastPage(`Contrast Self ${fontWeight}`, (colors) => {
245
- return colors.map((color) => {
246
- return {
247
- fontWeight,
248
- title: color.suffix || '',
249
- foreground: color.definition,
250
- };
251
- });
252
- });
253
- }
254
- function createThemePages() {
255
- const generatedTheme = buildColorTheme(colors, options);
256
- return createColorThemeBookPages({
257
- parent: topColorsPage,
258
- title: 'Theme (auto)',
259
- theme: generatedTheme.defaultLight,
260
- hideInverseColors: true,
261
- useVerticalLayout: useVerticalTheme,
262
- prefixGroupByCount: 2,
263
- overrides: [generatedTheme.darkOverride],
264
- });
265
- }
266
- return [
267
- topColorsPage,
268
- colorPalettePage,
269
- includeContrast ? contrastsPage : undefined,
270
- includeContrast ? blackWhiteContrastPage : undefined,
271
- includeContrast ? createSelfContrastPage(400) : undefined,
272
- includeContrast ? createSelfContrastPage(700) : undefined,
273
- ...(includeTheme ? createThemePages() : []),
274
- ].filter(check.isTruthy);
275
- }
@@ -1,31 +0,0 @@
1
- import { type PartialWithUndefined } from '@augment-vir/common';
2
- import { BookPageControlType, type BookPage } from 'element-book';
3
- import { type ColorThemeOverride } from './color-theme-init.js';
4
- import { type ColorTheme } from './color-theme.js';
5
- /**
6
- * Create multiple element-book pages to showcase a theme its overrides (if any).
7
- *
8
- * @category Color Theme
9
- */
10
- export declare function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, useVerticalLayout, prefixGroupByCount, hideCopyCode, }: {
11
- title: string;
12
- theme: Readonly<ColorTheme>;
13
- } & PartialWithUndefined<{
14
- hideCopyCode: boolean;
15
- parent: Readonly<BookPage>;
16
- hideInverseColors: boolean;
17
- overrides: ReadonlyArray<Readonly<ColorThemeOverride>>;
18
- useVerticalLayout: boolean;
19
- /**
20
- * The number of CSS variable name prefixes to group colors by.
21
- *
22
- * @default 0
23
- */
24
- prefixGroupByCount: number;
25
- }>): (BookPage<{}, Readonly<BookPage> | undefined, {
26
- 'Show Var Names': import("element-book").BookPageControlInit<BookPageControlType.Checkbox>;
27
- 'Show Contrast Tips': import("element-book").BookPageControlInit<BookPageControlType.Checkbox>;
28
- }> | BookPage<{}, BookPage<{}, Readonly<BookPage> | undefined, {
29
- 'Show Var Names': import("element-book").BookPageControlInit<BookPageControlType.Checkbox>;
30
- 'Show Contrast Tips': import("element-book").BookPageControlInit<BookPageControlType.Checkbox>;
31
- }>, {}>)[];
@@ -1,183 +0,0 @@
1
- import { check } from '@augment-vir/assert';
2
- import { groupArrayBy } from '@augment-vir/common';
3
- import { VirColorPair } from '@electrovir/color';
4
- import { BookPageControlType, defineBookPage, definePageControl, } from 'element-book';
5
- import { css, html, listen, nothing } from 'element-vir';
6
- import { generateThemeCode } from './color-theme-code.js';
7
- const noneOverridesSelectionValue = 'None';
8
- /**
9
- * Create multiple element-book pages to showcase a theme its overrides (if any).
10
- *
11
- * @category Color Theme
12
- */
13
- export function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, useVerticalLayout, prefixGroupByCount = 2, hideCopyCode, }) {
14
- const themeControls = {
15
- 'Show Var Names': definePageControl({
16
- controlType: BookPageControlType.Checkbox,
17
- initValue: false,
18
- }),
19
- 'Show Contrast Tips': definePageControl({
20
- controlType: BookPageControlType.Checkbox,
21
- initValue: true,
22
- }),
23
- };
24
- const defaultThemeControls = {
25
- 'Theme Override': definePageControl({
26
- controlType: BookPageControlType.Dropdown,
27
- initValue: noneOverridesSelectionValue,
28
- options: [
29
- noneOverridesSelectionValue,
30
- ...(overrides || []).map((override) => {
31
- if (override.name === noneOverridesSelectionValue) {
32
- throw new Error(`Cannot have theme override named '${noneOverridesSelectionValue}'`);
33
- }
34
- return override.name;
35
- }),
36
- ],
37
- }),
38
- };
39
- const themeParentPage = defineBookPage({
40
- parent,
41
- title,
42
- controls: themeControls,
43
- });
44
- function buildThemeColorTemplate({ controls, theme, themeColorName, }) {
45
- const themeColor = check.isKeyOf(themeColorName, theme.colors)
46
- ? theme.colors[themeColorName]
47
- : undefined;
48
- const inverseThemeColor = check.isKeyOf(themeColorName, theme.inverse)
49
- ? theme.inverse[themeColorName]
50
- : undefined;
51
- if (!themeColor || !inverseThemeColor) {
52
- throw new Error(`No theme color found by name '${themeColorName}'`);
53
- }
54
- const normalTemplate = html `
55
- <${VirColorPair.assign({
56
- color: themeColor,
57
- showVarValues: true,
58
- showVarNames: controls['Show Var Names'],
59
- showContrast: controls['Show Contrast Tips'],
60
- fontWeight: 400,
61
- })}></${VirColorPair}>
62
- `;
63
- const inverseColor = hideInverseColors ? undefined : inverseThemeColor;
64
- const inverseTemplate = inverseColor
65
- ? html `
66
- <${VirColorPair.assign({
67
- color: inverseColor,
68
- showVarValues: false,
69
- showVarNames: controls['Show Var Names'],
70
- showContrast: controls['Show Contrast Tips'],
71
- fontWeight: 400,
72
- })}></${VirColorPair}>
73
- `
74
- : nothing;
75
- return html `
76
- <div class="with-inverse">${normalTemplate}${inverseTemplate}</div>
77
- `;
78
- }
79
- function createThemePageExamples(defineExample, defaultTheme, overrides) {
80
- const groups = groupArrayBy(Object.keys(defaultTheme.colors), (value) => {
81
- if (prefixGroupByCount) {
82
- return value.split('-').slice(0, prefixGroupByCount).join('-');
83
- }
84
- else {
85
- return value;
86
- }
87
- });
88
- Object.entries(groups).forEach(([groupName, group,]) => {
89
- if (!group) {
90
- return;
91
- }
92
- defineExample({
93
- title: groupName,
94
- styles: css `
95
- :host {
96
- display: flex;
97
- flex-direction: column;
98
- gap: 4px;
99
- }
100
-
101
- .theme-wrapper {
102
- display: contents;
103
- }
104
-
105
- .with-inverse {
106
- display: flex;
107
- flex-direction: column;
108
- gap: 4px;
109
- }
110
- `,
111
- render({ controls }) {
112
- const selectedOverride = ('Theme Override' in controls &&
113
- controls['Theme Override'] &&
114
- overrides?.find((override) => override.name === controls['Theme Override'])) ||
115
- undefined;
116
- const currentTheme = selectedOverride?.asTheme || defaultTheme;
117
- return html `
118
- <div class="theme-wrapper">
119
- ${group.map((entry) => {
120
- return buildThemeColorTemplate({
121
- controls,
122
- theme: currentTheme,
123
- themeColorName: entry,
124
- });
125
- })}
126
- </div>
127
- `;
128
- },
129
- });
130
- });
131
- }
132
- const descriptionParagraphs = [
133
- 'Click a color preview to show CSS var names and values.',
134
- ];
135
- const defaultThemePage = defineBookPage({
136
- parent: themeParentPage,
137
- title: 'Default',
138
- descriptionParagraphs,
139
- useVerticalExamples: useVerticalLayout,
140
- controls: {
141
- ...(hideCopyCode
142
- ? {}
143
- : {
144
- copy: definePageControl({
145
- controlType: BookPageControlType.Custom,
146
- content: html `
147
- <button
148
- ${listen('click', async () => {
149
- const code = generateThemeCode(theme, {
150
- paletteVarName: 'viraColorPalette',
151
- overrides,
152
- });
153
- await navigator.clipboard.writeText(code);
154
- })}
155
- >
156
- Copy Code
157
- </button>
158
- `,
159
- }),
160
- }),
161
- ...defaultThemeControls,
162
- },
163
- defineExamples({ defineExample }) {
164
- createThemePageExamples(defineExample, theme, overrides);
165
- },
166
- });
167
- const overridePages = (overrides || []).map((override) => {
168
- return defineBookPage({
169
- parent: themeParentPage,
170
- title: override.name,
171
- useVerticalExamples: useVerticalLayout,
172
- descriptionParagraphs,
173
- defineExamples({ defineExample }) {
174
- createThemePageExamples(defineExample, override.asTheme, undefined);
175
- },
176
- });
177
- });
178
- return [
179
- themeParentPage,
180
- defaultThemePage,
181
- ...overridePages,
182
- ];
183
- }
@@ -1,3 +0,0 @@
1
- import { type ThemeOptions } from './theme-options.js';
2
- import { type Theme } from './theme.js';
3
- export declare function createTheme<TagPrefix extends string>(options: ThemeOptions<TagPrefix>): Theme<TagPrefix>;
@@ -1,9 +0,0 @@
1
- import { mergeDeep } from '@augment-vir/common';
2
- import { defineThemeElements } from './define-theme-elements.js';
3
- import { createDefaultThemeOptions, } from './theme-options.js';
4
- export function createTheme(options) {
5
- const fullOptions = mergeDeep(createDefaultThemeOptions(), options);
6
- return {
7
- elements: defineThemeElements(fullOptions),
8
- };
9
- }
@@ -1,3 +0,0 @@
1
- import { type AllThemeOptions } from './theme-options.js';
2
- import { type Theme } from './theme.js';
3
- export declare function defineThemeElements<TagPrefix extends string>(options: Pick<AllThemeOptions<TagPrefix>, 'elementTagPrefix' | 'font'>): Theme<TagPrefix>['elements'];
@@ -1,125 +0,0 @@
1
- import { getEnumValues, getObjectTypedValues, typedObjectFromEntries } from '@augment-vir/common';
2
- import { css, defineElement, html, unsafeCSS } from 'element-vir';
3
- import { createFontStyleCss } from './font-css.js';
4
- import { HeadingLevel } from './theme-options.js';
5
- export function defineThemeElements(options) {
6
- const themeElements = {
7
- bold: defineElement()({
8
- tagName: `${options.elementTagPrefix}-b`,
9
- styles: css `
10
- :host {
11
- display: inline;
12
- ${createFontStyleCss(options.font.bold)}
13
- }
14
-
15
- b {
16
- all: inherit;
17
- }
18
- `,
19
- render() {
20
- return html `
21
- <b><slot></slot></b>
22
- `;
23
- },
24
- }),
25
- monospace: defineElement()({
26
- tagName: `${options.elementTagPrefix}-monospace`,
27
- styles: css `
28
- :host {
29
- display: inline;
30
- ${createFontStyleCss(options.font.monospace)}
31
- }
32
- `,
33
- render() {
34
- return html `
35
- <slot></slot>
36
- `;
37
- },
38
- }),
39
- code: defineElement()({
40
- tagName: `${options.elementTagPrefix}-code`,
41
- styles: css `
42
- :host {
43
- display: inline;
44
- ${createFontStyleCss(options.font.monospace)}
45
- }
46
- `,
47
- render() {
48
- return html `
49
- <code><slot></slot></code>
50
- `;
51
- },
52
- }),
53
- paragraph: defineElement()({
54
- tagName: `${options.elementTagPrefix}-p`,
55
- styles: css `
56
- :host {
57
- display: block;
58
- ${createFontStyleCss(options.font.bold)}
59
- }
60
-
61
- p {
62
- all: inherit;
63
- }
64
- `,
65
- render() {
66
- return html `
67
- <p><slot></slot></p>
68
- `;
69
- },
70
- }),
71
- heading: defineHeadingElement(options),
72
- };
73
- return themeElements;
74
- }
75
- function defineHeadingElement(options) {
76
- const headingTag = `${options.elementTagPrefix}-heading`;
77
- const headingSelectors = unsafeCSS(getEnumValues(HeadingLevel).join(', '));
78
- return defineElement()({
79
- tagName: headingTag,
80
- hostClasses: typedObjectFromEntries(
81
- /**
82
- * `mapEnumToObject` cannot be used here: host class keys must be prefixed with the
83
- * element's tag name, not the bare enum values.
84
- */
85
- // eslint-disable-next-line @virmator/prefer-map-enum-to-object
86
- getEnumValues(HeadingLevel).map((headingLevel) => {
87
- return [
88
- `${headingTag}-${headingLevel}`,
89
- ({ inputs }) => inputs.headingLevel === headingLevel,
90
- ];
91
- })),
92
- styles: ({ hostClasses }) => {
93
- const hostClassValues = getObjectTypedValues(hostClasses);
94
- return css `
95
- :host {
96
- display: block;
97
- }
98
-
99
- ${unsafeCSS(hostClassValues
100
- .map((hostClass) => {
101
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
102
- const headingLevel = String(hostClass.name)
103
- .split('-')
104
- .slice(-1)[0];
105
- return css `
106
- ${hostClass.selector} {
107
- ${createFontStyleCss(options.font.headings[headingLevel])}
108
- }
109
- `;
110
- })
111
- .join('\n'))}
112
-
113
- ${headingSelectors} {
114
- all: inherit;
115
- }
116
- `;
117
- },
118
- render({ inputs }) {
119
- const headingTag = inputs.headingLevel;
120
- return html `
121
- <${headingTag}><slot></slot></${headingTag}>
122
- `;
123
- },
124
- });
125
- }
@@ -1,4 +0,0 @@
1
- import { type CSSResult } from 'element-vir';
2
- import { type FontSize, type FontStyle } from './theme-options.js';
3
- export declare function createFontSizeCssValue(fontSize: Readonly<FontSize>): CSSResult;
4
- export declare function createFontStyleCss(fontStyle: Readonly<FontStyle>): CSSResult;
@@ -1,20 +0,0 @@
1
- import { css, unsafeCSS } from 'element-vir';
2
- export function createFontSizeCssValue(fontSize) {
3
- if ('pixels' in fontSize) {
4
- return unsafeCSS(`${fontSize.pixels}px`);
5
- }
6
- else if ('ratio' in fontSize) {
7
- return unsafeCSS(`${fontSize.ratio}em`);
8
- }
9
- else {
10
- throw new Error(`Invalid fontSize given: '${JSON.stringify(fontSize)}'`);
11
- }
12
- }
13
- export function createFontStyleCss(fontStyle) {
14
- return css `
15
- font-family: ${unsafeCSS(fontStyle.family)};
16
- font-size: ${createFontSizeCssValue(fontStyle.size)};
17
- line-height: ${createFontSizeCssValue(fontStyle.lineHeight)};
18
- font-weight: ${fontStyle.weight};
19
- `;
20
- }
@@ -1,3 +0,0 @@
1
- import { type ThemeOptions } from './theme-options.js';
2
- export type InternalTheme = {};
3
- export declare function createInternalTheme<TagPrefix extends string>(options: ThemeOptions<TagPrefix>): InternalTheme;
@@ -1,5 +0,0 @@
1
- export function createInternalTheme(
2
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
3
- options) {
4
- return {};
5
- }
@@ -1,36 +0,0 @@
1
- export declare enum HeadingLevel {
2
- H1 = "h1",
3
- H2 = "h2",
4
- H3 = "h3",
5
- H4 = "h4",
6
- H5 = "h5",
7
- H6 = "h6"
8
- }
9
- export type FontSize = {
10
- pixels: number;
11
- } | {
12
- ratio: number;
13
- };
14
- export type FontStyle = {
15
- weight: number;
16
- family: string;
17
- lineHeight: FontSize;
18
- size: FontSize;
19
- };
20
- export type RequiredThemeOptions<TagPrefix extends string> = {
21
- elementTagPrefix: TagPrefix;
22
- };
23
- export type OptionalThemeOptions = {
24
- font?: {
25
- default: FontStyle;
26
- bold: FontStyle;
27
- monospace: FontStyle;
28
- headings: Record<HeadingLevel, FontStyle>;
29
- };
30
- colors?: {
31
- error: string;
32
- };
33
- };
34
- export type ThemeOptions<TagPrefix extends string> = Required<RequiredThemeOptions<TagPrefix>> & Partial<OptionalThemeOptions>;
35
- export type AllThemeOptions<TagPrefix extends string> = Required<RequiredThemeOptions<TagPrefix>> & Required<OptionalThemeOptions>;
36
- export declare function createDefaultThemeOptions(): AllThemeOptions<any>;
@@ -1,78 +0,0 @@
1
- export var HeadingLevel;
2
- (function (HeadingLevel) {
3
- HeadingLevel["H1"] = "h1";
4
- HeadingLevel["H2"] = "h2";
5
- HeadingLevel["H3"] = "h3";
6
- HeadingLevel["H4"] = "h4";
7
- HeadingLevel["H5"] = "h5";
8
- HeadingLevel["H6"] = "h6";
9
- })(HeadingLevel || (HeadingLevel = {}));
10
- export function createDefaultThemeOptions() {
11
- const defaultFont = {
12
- family: 'sans-serif',
13
- lineHeight: {
14
- ratio: 1.1,
15
- },
16
- size: {
17
- pixels: 14,
18
- },
19
- weight: 400,
20
- };
21
- const bold = {
22
- ...defaultFont,
23
- weight: 700,
24
- };
25
- const allThemeOptions = {
26
- elementTagPrefix: 'vir',
27
- colors: {
28
- error: 'red',
29
- },
30
- font: {
31
- default: defaultFont,
32
- bold,
33
- monospace: {
34
- ...defaultFont,
35
- family: 'monospace',
36
- size: {
37
- ratio: 1.2,
38
- },
39
- },
40
- headings: {
41
- h1: {
42
- ...bold,
43
- size: {
44
- ratio: 2,
45
- },
46
- },
47
- h2: {
48
- ...bold,
49
- size: {
50
- ratio: 1.5,
51
- },
52
- },
53
- h3: {
54
- ...bold,
55
- size: {
56
- ratio: 1.17,
57
- },
58
- },
59
- h4: {
60
- ...bold,
61
- },
62
- h5: {
63
- ...bold,
64
- size: {
65
- ratio: 0.83,
66
- },
67
- },
68
- h6: {
69
- ...bold,
70
- size: {
71
- ratio: 0.67,
72
- },
73
- },
74
- },
75
- },
76
- };
77
- return allThemeOptions;
78
- }
@@ -1,13 +0,0 @@
1
- import { type DeclarativeElementDefinition } from 'element-vir';
2
- import { type HeadingLevel } from './theme-options.js';
3
- export type Theme<TagPrefix extends string> = {
4
- elements: {
5
- bold: DeclarativeElementDefinition<`${TagPrefix}-b`>;
6
- monospace: DeclarativeElementDefinition<`${TagPrefix}-monospace`>;
7
- paragraph: DeclarativeElementDefinition<`${TagPrefix}-p`>;
8
- code: DeclarativeElementDefinition<`${TagPrefix}-code`>;
9
- heading: DeclarativeElementDefinition<`${TagPrefix}-heading`, {
10
- headingLevel: HeadingLevel;
11
- }>;
12
- };
13
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,3 +0,0 @@
1
- import { type BookPage } from 'element-book';
2
- import { type Theme } from '../create-theme/theme.js';
3
- export declare function createThemeBookPages<TagName extends string>(theme: Readonly<Theme<TagName>>): ReadonlyArray<Readonly<BookPage>>;
@@ -1,56 +0,0 @@
1
- import { check } from '@augment-vir/assert';
2
- import { getEnumValues, getObjectTypedKeys } from '@augment-vir/common';
3
- import { defineBookPage } from 'element-book';
4
- import { html } from 'element-vir';
5
- import { HeadingLevel } from '../create-theme/theme-options.js';
6
- export function createThemeBookPages(theme) {
7
- const elementsBookPage = defineBookPage({
8
- title: 'elements',
9
- parent: undefined,
10
- });
11
- const fontEntries = getObjectTypedKeys(theme.elements)
12
- .map((elementKey) => {
13
- if (elementKey === 'heading') {
14
- return undefined;
15
- }
16
- const themeElement = theme.elements[elementKey];
17
- return defineBookPage({
18
- title: themeElement.tagName,
19
- parent: elementsBookPage,
20
- defineExamples({ defineExample }) {
21
- defineExample({
22
- title: 'basic',
23
- render() {
24
- return html `
25
- <${themeElement}>This is ${elementKey}</${themeElement}>
26
- `;
27
- },
28
- });
29
- },
30
- });
31
- })
32
- .filter(check.isTruthy);
33
- return [
34
- defineBookPage({
35
- title: theme.elements.heading.tagName,
36
- parent: elementsBookPage,
37
- defineExamples({ defineExample }) {
38
- getEnumValues(HeadingLevel).forEach((headingLevel) => {
39
- defineExample({
40
- title: headingLevel,
41
- render() {
42
- return html `
43
- <${theme.elements.heading.assign({
44
- headingLevel,
45
- })}>
46
- This is heading ${headingLevel}
47
- </${theme.elements.heading}>
48
- `;
49
- },
50
- });
51
- });
52
- },
53
- }),
54
- ...fontEntries,
55
- ].sort((a, b) => a.title.localeCompare(b.title));
56
- }