@udixio/theme 1.0.0-beta.15 → 1.0.0-beta.17
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/plugin/plugin.abstract.d.ts +2 -1
- package/dist/plugin/plugin.service.d.ts +3 -1
- package/dist/plugins/font/font.plugin.d.ts +38 -0
- package/dist/plugins/tailwind/index.d.ts +1 -1
- package/dist/plugins/tailwind/plugins-tailwind/font.d.ts +5 -0
- package/dist/plugins/tailwind/{Tailwind.plugin.d.ts → tailwind.plugin.d.ts} +3 -0
- package/dist/theme.cjs.development.js +242 -13
- package/dist/theme.cjs.development.js.map +1 -1
- package/dist/theme.cjs.production.min.js +1 -1
- package/dist/theme.cjs.production.min.js.map +1 -1
- package/dist/theme.esm.js +242 -13
- package/dist/theme.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/config/config.service.ts +7 -1
- package/src/plugin/plugin.abstract.ts +2 -1
- package/src/plugin/plugin.service.ts +23 -5
- package/src/plugins/font/font.plugin.ts +172 -0
- package/src/plugins/tailwind/index.ts +1 -1
- package/src/plugins/tailwind/main.ts +1 -1
- package/src/plugins/tailwind/plugins-tailwind/font.ts +69 -0
- package/src/plugins/tailwind/{Tailwind.plugin.ts → tailwind.plugin.ts} +9 -2
package/package.json
CHANGED
|
@@ -83,7 +83,13 @@ export class ConfigService {
|
|
|
83
83
|
throw new Error('Configuration file not found');
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
let config: unknown;
|
|
87
|
+
if ('default' in configImport) {
|
|
88
|
+
config = configImport.default;
|
|
89
|
+
} else {
|
|
90
|
+
config = configImport;
|
|
91
|
+
}
|
|
92
|
+
|
|
87
93
|
return config as ConfigInterface;
|
|
88
94
|
}
|
|
89
95
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AppService } from '../app.service';
|
|
2
|
+
import { PluginConstructor } from './plugin.service';
|
|
2
3
|
|
|
3
4
|
export abstract class PluginAbstract {
|
|
4
|
-
static dependencies:
|
|
5
|
+
static dependencies: PluginConstructor[] = [];
|
|
5
6
|
|
|
6
7
|
protected abstract appService: AppService;
|
|
7
8
|
protected abstract options: object;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PluginAbstract } from './plugin.abstract';
|
|
2
2
|
import { AppService } from '../app.service';
|
|
3
3
|
|
|
4
|
-
export type PluginConstructor = new (
|
|
4
|
+
export type PluginConstructor = (new (
|
|
5
5
|
appService: AppService,
|
|
6
6
|
options: any
|
|
7
|
-
) => PluginAbstract;
|
|
7
|
+
) => PluginAbstract) & { dependencies: PluginConstructor[] };
|
|
8
8
|
|
|
9
9
|
export class PluginService {
|
|
10
10
|
private pluginInstances = new Map<string, PluginAbstract>();
|
|
@@ -15,9 +15,27 @@ export class PluginService {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
public loadPlugins(appService: AppService) {
|
|
18
|
-
this.pluginConstructors
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const plugins = new Map(this.pluginConstructors);
|
|
19
|
+
|
|
20
|
+
let size = 0;
|
|
21
|
+
do {
|
|
22
|
+
size = plugins.size;
|
|
23
|
+
plugins.forEach(([plugin, option], key) => {
|
|
24
|
+
const deps = plugin.dependencies.filter(
|
|
25
|
+
(dep) => !this.pluginInstances.has(dep.name)
|
|
26
|
+
);
|
|
27
|
+
if (deps.length === 0) {
|
|
28
|
+
this.pluginInstances.set(plugin.name, new plugin(appService, option));
|
|
29
|
+
plugins.delete(key);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
} while (plugins.size != 0 && plugins.size < size);
|
|
33
|
+
|
|
34
|
+
if (plugins.size > 0)
|
|
35
|
+
console.log(
|
|
36
|
+
"Some plugins couldn't be loaded due to missing dependencies: ",
|
|
37
|
+
Array.from(plugins.keys())
|
|
38
|
+
);
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
public getPlugin<T extends PluginAbstract>(
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { PluginAbstract } from '../../plugin';
|
|
2
|
+
import { AppService } from '../../app.service';
|
|
3
|
+
|
|
4
|
+
export enum FontFamily {
|
|
5
|
+
Expressive = 'expressive',
|
|
6
|
+
Neutral = 'neutral',
|
|
7
|
+
}
|
|
8
|
+
export type FontStyle = {
|
|
9
|
+
fontSize: number;
|
|
10
|
+
lineHeight: number;
|
|
11
|
+
fontWeight: number;
|
|
12
|
+
letterSpacing?: number;
|
|
13
|
+
fontFamily: FontFamily;
|
|
14
|
+
};
|
|
15
|
+
export type FontRole = 'display' | 'headline' | 'title' | 'label' | 'body';
|
|
16
|
+
export type FontSize = 'large' | 'medium' | 'small';
|
|
17
|
+
interface FontPluginOptions {
|
|
18
|
+
fontFamily?: {
|
|
19
|
+
expressive?: string[];
|
|
20
|
+
neutral?: string[];
|
|
21
|
+
};
|
|
22
|
+
fontStyles?: Partial<Record<FontRole, Record<FontSize, Partial<FontStyle>>>>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class FontPlugin extends PluginAbstract {
|
|
26
|
+
private readonly fontFamily: { expressive: string[]; neutral: string[] };
|
|
27
|
+
private readonly fontStyles: Record<FontRole, Record<FontSize, FontStyle>>;
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
protected appService: AppService,
|
|
31
|
+
protected options: FontPluginOptions
|
|
32
|
+
) {
|
|
33
|
+
super();
|
|
34
|
+
this.fontFamily = {
|
|
35
|
+
expressive: options?.fontFamily?.expressive ?? ['Roboto', 'sans-serif'],
|
|
36
|
+
neutral: options?.fontFamily?.neutral ?? ['Roboto', 'sans-serif'],
|
|
37
|
+
};
|
|
38
|
+
this.fontStyles = {
|
|
39
|
+
display: {
|
|
40
|
+
large: {
|
|
41
|
+
fontWeight: 400,
|
|
42
|
+
fontSize: 3.5625,
|
|
43
|
+
lineHeight: 4,
|
|
44
|
+
letterSpacing: -0.015625,
|
|
45
|
+
fontFamily: FontFamily.Expressive,
|
|
46
|
+
},
|
|
47
|
+
medium: {
|
|
48
|
+
fontWeight: 400,
|
|
49
|
+
fontSize: 2.8125,
|
|
50
|
+
lineHeight: 3.25,
|
|
51
|
+
fontFamily: FontFamily.Expressive,
|
|
52
|
+
},
|
|
53
|
+
small: {
|
|
54
|
+
fontWeight: 400,
|
|
55
|
+
fontSize: 2.25,
|
|
56
|
+
lineHeight: 2.75,
|
|
57
|
+
fontFamily: FontFamily.Expressive,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
headline: {
|
|
61
|
+
large: {
|
|
62
|
+
fontWeight: 400,
|
|
63
|
+
fontSize: 2,
|
|
64
|
+
lineHeight: 2.5,
|
|
65
|
+
fontFamily: FontFamily.Expressive,
|
|
66
|
+
},
|
|
67
|
+
medium: {
|
|
68
|
+
fontWeight: 400,
|
|
69
|
+
fontSize: 1.75,
|
|
70
|
+
lineHeight: 2.25,
|
|
71
|
+
fontFamily: FontFamily.Expressive,
|
|
72
|
+
},
|
|
73
|
+
small: {
|
|
74
|
+
fontWeight: 400,
|
|
75
|
+
fontSize: 1.5,
|
|
76
|
+
lineHeight: 2,
|
|
77
|
+
fontFamily: FontFamily.Expressive,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
title: {
|
|
81
|
+
large: {
|
|
82
|
+
fontWeight: 400,
|
|
83
|
+
fontSize: 1.375,
|
|
84
|
+
lineHeight: 1.75,
|
|
85
|
+
fontFamily: FontFamily.Neutral,
|
|
86
|
+
},
|
|
87
|
+
medium: {
|
|
88
|
+
fontWeight: 500,
|
|
89
|
+
fontSize: 1,
|
|
90
|
+
lineHeight: 1.5,
|
|
91
|
+
fontFamily: FontFamily.Neutral,
|
|
92
|
+
letterSpacing: 0.009375,
|
|
93
|
+
},
|
|
94
|
+
small: {
|
|
95
|
+
fontWeight: 500,
|
|
96
|
+
fontSize: 0.875,
|
|
97
|
+
lineHeight: 1.25,
|
|
98
|
+
fontFamily: FontFamily.Neutral,
|
|
99
|
+
letterSpacing: 0.00625,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
label: {
|
|
103
|
+
large: {
|
|
104
|
+
fontWeight: 500,
|
|
105
|
+
fontSize: 0.875,
|
|
106
|
+
lineHeight: 1.25,
|
|
107
|
+
fontFamily: FontFamily.Neutral,
|
|
108
|
+
letterSpacing: 0.00625,
|
|
109
|
+
},
|
|
110
|
+
medium: {
|
|
111
|
+
fontWeight: 500,
|
|
112
|
+
fontSize: 0.75,
|
|
113
|
+
lineHeight: 1,
|
|
114
|
+
fontFamily: FontFamily.Neutral,
|
|
115
|
+
letterSpacing: 0.03125,
|
|
116
|
+
},
|
|
117
|
+
small: {
|
|
118
|
+
fontWeight: 500,
|
|
119
|
+
fontSize: 0.6875,
|
|
120
|
+
lineHeight: 1,
|
|
121
|
+
fontFamily: FontFamily.Neutral,
|
|
122
|
+
letterSpacing: 0.03125,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
body: {
|
|
126
|
+
large: {
|
|
127
|
+
fontWeight: 400,
|
|
128
|
+
fontSize: 1,
|
|
129
|
+
lineHeight: 1.5625,
|
|
130
|
+
fontFamily: FontFamily.Neutral,
|
|
131
|
+
letterSpacing: 0.03125,
|
|
132
|
+
},
|
|
133
|
+
medium: {
|
|
134
|
+
fontWeight: 400,
|
|
135
|
+
fontSize: 0.875,
|
|
136
|
+
lineHeight: 1.25,
|
|
137
|
+
fontFamily: FontFamily.Neutral,
|
|
138
|
+
letterSpacing: 0.015625,
|
|
139
|
+
},
|
|
140
|
+
small: {
|
|
141
|
+
fontWeight: 400,
|
|
142
|
+
fontSize: 0.75,
|
|
143
|
+
lineHeight: 1,
|
|
144
|
+
fontFamily: FontFamily.Neutral,
|
|
145
|
+
letterSpacing: 0.025,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
if (options && options.fontStyles)
|
|
150
|
+
Object.entries(options.fontStyles).forEach(([key, fontParam]) => {
|
|
151
|
+
const fontRole: FontRole = key as FontRole;
|
|
152
|
+
Object.entries(fontParam).forEach(([size, fontStyle]) => {
|
|
153
|
+
const fontSize: FontSize = size as FontSize;
|
|
154
|
+
if (fontStyle) {
|
|
155
|
+
this.fontStyles[fontRole][fontSize] = {
|
|
156
|
+
...this.fontStyles[fontRole][fontSize],
|
|
157
|
+
...fontStyle,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
static config(options: FontPluginOptions): FontPluginOptions {
|
|
164
|
+
return options;
|
|
165
|
+
}
|
|
166
|
+
getFonts() {
|
|
167
|
+
return {
|
|
168
|
+
fontStyles: this.fontStyles,
|
|
169
|
+
fontFamily: this.fontFamily,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PluginsConfig } from 'tailwindcss/types/config';
|
|
2
2
|
import { bootstrapFromConfig } from '../../main';
|
|
3
|
-
import { TailwindPlugin } from './
|
|
3
|
+
import { TailwindPlugin } from './tailwind.plugin';
|
|
4
4
|
|
|
5
5
|
export type Theme = {
|
|
6
6
|
colors: Record<string, string>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin';
|
|
2
|
+
import { CSSRuleObject, PluginAPI } from 'tailwindcss/types/config';
|
|
3
|
+
import { FontRole, FontSize, FontStyle } from '../../font/font.plugin';
|
|
4
|
+
|
|
5
|
+
export const font = (
|
|
6
|
+
fontStyles: Record<FontRole, Record<FontSize, FontStyle>>,
|
|
7
|
+
responsiveBreakPoints: Record<string, number>
|
|
8
|
+
) => {
|
|
9
|
+
const createUtilities = ({
|
|
10
|
+
theme,
|
|
11
|
+
}: Pick<PluginAPI, 'theme'>): CSSRuleObject => {
|
|
12
|
+
const pixelUnit = 'rem';
|
|
13
|
+
const newUtilities: any = {};
|
|
14
|
+
|
|
15
|
+
const baseTextStyle = (sizeValue: FontStyle) => ({
|
|
16
|
+
fontSize: sizeValue.fontSize + pixelUnit,
|
|
17
|
+
fontWeight: sizeValue.fontWeight as unknown as CSSRuleObject,
|
|
18
|
+
lineHeight: sizeValue.lineHeight + pixelUnit,
|
|
19
|
+
letterSpacing: sizeValue.letterSpacing
|
|
20
|
+
? sizeValue.letterSpacing + pixelUnit
|
|
21
|
+
: null,
|
|
22
|
+
fontFamily: theme('fontFamily.' + sizeValue.fontFamily),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const responsiveTextStyle = (
|
|
26
|
+
sizeValue: FontStyle,
|
|
27
|
+
breakPointName: string,
|
|
28
|
+
breakPointRatio: number
|
|
29
|
+
) => ({
|
|
30
|
+
[`@media (min-width: ${theme('screens.' + breakPointName, {})})`]: {
|
|
31
|
+
fontSize: sizeValue.fontSize * breakPointRatio + pixelUnit,
|
|
32
|
+
lineHeight: sizeValue.lineHeight * breakPointRatio + pixelUnit,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
for (const [roleName, roleValue] of Object.entries(fontStyles)) {
|
|
37
|
+
for (const [sizeName, sizeValue] of Object.entries(roleValue)) {
|
|
38
|
+
newUtilities['.text-' + roleName + '-' + sizeName] = {
|
|
39
|
+
...baseTextStyle(sizeValue),
|
|
40
|
+
...Object.entries(responsiveBreakPoints).reduce(
|
|
41
|
+
(acc, [breakPointName, breakPointRatio]) => {
|
|
42
|
+
acc = {
|
|
43
|
+
...acc,
|
|
44
|
+
...responsiveTextStyle(
|
|
45
|
+
sizeValue,
|
|
46
|
+
breakPointName,
|
|
47
|
+
breakPointRatio
|
|
48
|
+
),
|
|
49
|
+
};
|
|
50
|
+
return acc;
|
|
51
|
+
},
|
|
52
|
+
{}
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return newUtilities as CSSRuleObject;
|
|
59
|
+
};
|
|
60
|
+
return plugin(
|
|
61
|
+
({
|
|
62
|
+
addUtilities,
|
|
63
|
+
theme,
|
|
64
|
+
}: Pick<PluginAPI, 'theme'> & Pick<PluginAPI, 'addUtilities'>) => {
|
|
65
|
+
const newUtilities = createUtilities({ theme });
|
|
66
|
+
addUtilities(newUtilities);
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
};
|
|
@@ -3,12 +3,16 @@ import { AppService } from '../../app.service';
|
|
|
3
3
|
import { Theme } from './main';
|
|
4
4
|
import { state } from './plugins-tailwind/state';
|
|
5
5
|
import { themer } from './plugins-tailwind/themer';
|
|
6
|
+
import { FontPlugin } from '../font/font.plugin';
|
|
7
|
+
import { font } from './plugins-tailwind/font';
|
|
6
8
|
|
|
7
9
|
interface TailwindPluginOptions {
|
|
8
10
|
darkMode: 'class' | 'media';
|
|
11
|
+
responsiveBreakPoints: Record<string, number>;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
export class TailwindPlugin extends PluginAbstract {
|
|
15
|
+
static dependencies = [FontPlugin];
|
|
12
16
|
constructor(
|
|
13
17
|
protected appService: AppService,
|
|
14
18
|
protected options: TailwindPluginOptions
|
|
@@ -39,14 +43,17 @@ export class TailwindPlugin extends PluginAbstract {
|
|
|
39
43
|
colors[newKey][isDark ? 'dark' : 'light'] = value.getHex();
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
|
-
console.log(colors);
|
|
43
46
|
|
|
47
|
+
const { fontStyles, fontFamily } = this.appService.pluginService
|
|
48
|
+
.getPlugin(FontPlugin)
|
|
49
|
+
.getFonts();
|
|
44
50
|
return {
|
|
45
51
|
colors: {},
|
|
46
|
-
fontFamily:
|
|
52
|
+
fontFamily: fontFamily,
|
|
47
53
|
plugins: [
|
|
48
54
|
state(Object.keys(colors)),
|
|
49
55
|
themer(colors, this.options.darkMode),
|
|
56
|
+
font(fontStyles, this.options.responsiveBreakPoints),
|
|
50
57
|
],
|
|
51
58
|
};
|
|
52
59
|
}
|