@navita/css 0.0.0-main-20230917201540

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.
Files changed (4) hide show
  1. package/index.d.ts +39 -0
  2. package/index.js +237 -0
  3. package/index.mjs +222 -0
  4. package/package.json +22 -0
package/index.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { StyleRule, GlobalStyleRule, CSSKeyframes, FontFaceRule, NullableTokens, ThemeVars, Tokens, Contract, MapLeafNodes, CSSVarFunction } from '@navita/types';
2
+
3
+ declare function style(rule: StyleRule): string;
4
+
5
+ declare function globalStyle(selector: string, rule: GlobalStyleRule): void;
6
+
7
+ declare function merge(...classNames: (string | false | void | null | 0 | '')[]): string;
8
+
9
+ declare function keyframes(rule: CSSKeyframes): string;
10
+
11
+ declare function fontFace(rule: FontFaceRule | FontFaceRule[]): string;
12
+
13
+ declare function createThemeContract<ThemeTokens extends NullableTokens>(tokens: ThemeTokens): ThemeVars<ThemeTokens>;
14
+ declare function createGlobalThemeContract<ThemeTokens extends Tokens>(tokens: ThemeTokens): ThemeVars<ThemeTokens>;
15
+ declare function createGlobalThemeContract<ThemeTokens extends NullableTokens>(tokens: ThemeTokens, mapFn: (value: string | null, path: Array<string>) => string): ThemeVars<ThemeTokens>;
16
+ declare function createGlobalTheme<ThemeTokens extends Tokens>(selector: string, tokens: ThemeTokens): ThemeVars<ThemeTokens>;
17
+ declare function createGlobalTheme<ThemeContract extends Contract>(selector: string, themeContract: ThemeContract, tokens: MapLeafNodes<ThemeContract, string>): void;
18
+ declare function createTheme<ThemeTokens extends Tokens>(tokens: ThemeTokens, debugId?: string): [className: string, vars: ThemeVars<ThemeTokens>];
19
+ declare function createTheme<ThemeContract extends Contract>(themeContract: ThemeContract, tokens: MapLeafNodes<ThemeContract, string>): string;
20
+
21
+ declare function createVar(name: string): string;
22
+ declare function fallbackVar(...values: [string, ...Array<string>]): CSSVarFunction;
23
+ declare function assignVars<VarContract extends Contract>(varContract: VarContract, tokens: MapLeafNodes<VarContract, string>): Record<CSSVarFunction, string>;
24
+
25
+ declare class ClassList extends String {
26
+ classList: {
27
+ [key: string]: string[];
28
+ };
29
+ constructor(str: string, classList: {
30
+ [key: string]: string[];
31
+ });
32
+ }
33
+
34
+ declare const importMap: {
35
+ callee: string;
36
+ source: string;
37
+ }[];
38
+
39
+ export { ClassList, assignVars, createGlobalTheme, createGlobalThemeContract, createTheme, createThemeContract, createVar, fallbackVar, fontFace, globalStyle, importMap, keyframes, merge, style };
package/index.js ADDED
@@ -0,0 +1,237 @@
1
+ 'use strict';
2
+
3
+ var adapter = require('@navita/adapter');
4
+ var cssesc = require('cssesc');
5
+ var chalk = require('chalk');
6
+ var deepObjectDiff = require('deep-object-diff');
7
+
8
+ function style(rule) {
9
+ return adapter.addCss(rule);
10
+ }
11
+
12
+ function globalStyle(selector, rule) {
13
+ adapter.addStaticCss(selector, rule);
14
+ }
15
+
16
+ function merge(...classNames) {
17
+ const input = classNames.filter(Boolean).join(' ').split(' ');
18
+ const output = {};
19
+ for (const className of input){
20
+ const [property] = className.split(/\d+$/);
21
+ output[property] = className;
22
+ }
23
+ return Object.values(output).join(' ');
24
+ }
25
+
26
+ function keyframes(rule) {
27
+ return adapter.addKeyframe(rule);
28
+ }
29
+
30
+ function fontFace(rule) {
31
+ return adapter.addFontFace(rule);
32
+ }
33
+
34
+ function walkObject(objectToWalk, transformFn, currentPath = []) {
35
+ const clonedObject = objectToWalk.constructor();
36
+ for(const key in objectToWalk){
37
+ const value = objectToWalk[key];
38
+ const newPath = [
39
+ ...currentPath,
40
+ key
41
+ ];
42
+ if (typeof value === 'string' || typeof value === 'number' || value == null) {
43
+ clonedObject[key] = transformFn(value, newPath);
44
+ } else if (typeof value === 'object' && !Array.isArray(value)) {
45
+ clonedObject[key] = walkObject(value, transformFn, newPath);
46
+ }
47
+ }
48
+ return clonedObject;
49
+ }
50
+
51
+ const normaliseObject = (obj)=>walkObject(obj, ()=>'');
52
+ function validateContract(contract, tokens) {
53
+ const theDiff = deepObjectDiff.diff(normaliseObject(contract), normaliseObject(tokens));
54
+ const valid = Object.keys(theDiff).length === 0;
55
+ return {
56
+ valid,
57
+ diffString: valid ? '' : renderDiff(contract, theDiff)
58
+ };
59
+ }
60
+ function diffLine(value, nesting, type) {
61
+ const whitespace = [
62
+ ...Array(nesting).keys()
63
+ ].map(()=>' ').join('');
64
+ const line = `${type ? type : ' '}${whitespace}${value}`;
65
+ {
66
+ if (type === '-') {
67
+ return chalk.red(line);
68
+ }
69
+ if (type === '+') {
70
+ return chalk.green(line);
71
+ }
72
+ }
73
+ return line;
74
+ }
75
+ function renderDiff(orig, diff, nesting = 0) {
76
+ const lines = [];
77
+ if (nesting === 0) {
78
+ lines.push(diffLine('{', 0));
79
+ }
80
+ const innerNesting = nesting + 1;
81
+ const keys = Object.keys(diff).sort();
82
+ for (const key of keys){
83
+ const value = diff[key];
84
+ if (!(key in orig)) {
85
+ lines.push(diffLine(`${key}: ...,`, innerNesting, '+'));
86
+ } else if (typeof value === 'object') {
87
+ lines.push(diffLine(`${key}: {`, innerNesting));
88
+ lines.push(renderDiff(orig[key], diff[key], innerNesting));
89
+ lines.push(diffLine('}', innerNesting));
90
+ } else {
91
+ lines.push(diffLine(`${key}: ...,`, innerNesting, '-'));
92
+ }
93
+ }
94
+ if (nesting === 0) {
95
+ lines.push(diffLine('}', 0));
96
+ }
97
+ return lines.join('\n');
98
+ }
99
+
100
+ function createVar(name) {
101
+ if (!name) {
102
+ return `var(--${adapter.generateIdentifier(undefined)})`;
103
+ }
104
+ return `var(--${cssesc(name, {
105
+ isIdentifier: true
106
+ })})`;
107
+ }
108
+ function fallbackVar(...values) {
109
+ let finalValue = '';
110
+ values.reverse().forEach((value)=>{
111
+ if (finalValue === '') {
112
+ finalValue = String(value);
113
+ } else {
114
+ if (typeof value !== 'string' || !/^var\(--.*\)$/.test(value)) {
115
+ throw new Error(`Invalid variable name: ${value}`);
116
+ }
117
+ finalValue = value.replace(/\)$/, `, ${finalValue})`);
118
+ }
119
+ });
120
+ return finalValue;
121
+ }
122
+ function assignVars(varContract, tokens) {
123
+ const varSetters = {};
124
+ const { valid , diffString } = validateContract(varContract, tokens);
125
+ if (!valid) {
126
+ throw new Error(`Tokens don't match contract.\n${diffString}`);
127
+ }
128
+ walkObject(tokens, (value, path)=>{
129
+ const cssVarWithoutVar = `--${cssesc(path.join('-').toLowerCase(), {
130
+ isIdentifier: true
131
+ })}`;
132
+ varSetters[cssVarWithoutVar] = String(value);
133
+ });
134
+ return varSetters;
135
+ }
136
+
137
+ function createThemeContract(tokens) {
138
+ return walkObject(tokens, (_value, path)=>{
139
+ return createVar(path.join('-').toLowerCase());
140
+ });
141
+ }
142
+ function createGlobalThemeContract(tokens, mapFn) {
143
+ return walkObject(tokens, (value, path)=>{
144
+ const rawVarName = typeof mapFn === 'function' ? mapFn(value, path) : value;
145
+ const varName = typeof rawVarName === 'string' ? rawVarName.replace(/^\-\-/, '') : null;
146
+ if (typeof varName !== 'string' || varName !== cssesc(varName, {
147
+ isIdentifier: true
148
+ })) {
149
+ throw new Error(`Invalid variable name for "${path.join('.')}": ${varName}`);
150
+ }
151
+ return `var(--${varName})`;
152
+ });
153
+ }
154
+ function createGlobalTheme(selector, arg2, arg3) {
155
+ const shouldCreateVars = Boolean(!arg3);
156
+ const themeVars = shouldCreateVars ? createThemeContract(arg2) : arg2;
157
+ const tokens = shouldCreateVars ? arg2 : arg3;
158
+ const temp = assignVars(themeVars, tokens);
159
+ adapter.addStaticCss(selector, temp);
160
+ if (shouldCreateVars) {
161
+ return themeVars;
162
+ }
163
+ }
164
+ function createTheme(arg1, arg2) {
165
+ const themeClassName = `.${adapter.generateIdentifier(typeof arg2 === 'object' ? arg2 : arg1)}`;
166
+ const vars = typeof arg2 === 'object' ? createGlobalTheme(themeClassName, arg1, arg2) : createGlobalTheme(themeClassName, arg1);
167
+ return vars ? [
168
+ themeClassName,
169
+ vars
170
+ ] : themeClassName;
171
+ }
172
+
173
+ class ClassList extends String {
174
+ constructor(str, classList){
175
+ super(str);
176
+ this.classList = classList;
177
+ }
178
+ }
179
+
180
+ const source = '@navita/css';
181
+ const importMap = [
182
+ {
183
+ callee: "style",
184
+ source
185
+ },
186
+ {
187
+ callee: "globalStyle",
188
+ source
189
+ },
190
+ {
191
+ callee: "keyframes",
192
+ source
193
+ },
194
+ {
195
+ callee: "fontFace",
196
+ source
197
+ },
198
+ {
199
+ callee: "createThemeContract",
200
+ source
201
+ },
202
+ {
203
+ callee: "createGlobalThemeContract",
204
+ source
205
+ },
206
+ {
207
+ callee: "createGlobalTheme",
208
+ source
209
+ },
210
+ {
211
+ callee: "createTheme",
212
+ source
213
+ },
214
+ {
215
+ callee: "createVar",
216
+ source
217
+ },
218
+ {
219
+ callee: "fallbackVar",
220
+ source
221
+ }
222
+ ];
223
+
224
+ exports.ClassList = ClassList;
225
+ exports.assignVars = assignVars;
226
+ exports.createGlobalTheme = createGlobalTheme;
227
+ exports.createGlobalThemeContract = createGlobalThemeContract;
228
+ exports.createTheme = createTheme;
229
+ exports.createThemeContract = createThemeContract;
230
+ exports.createVar = createVar;
231
+ exports.fallbackVar = fallbackVar;
232
+ exports.fontFace = fontFace;
233
+ exports.globalStyle = globalStyle;
234
+ exports.importMap = importMap;
235
+ exports.keyframes = keyframes;
236
+ exports.merge = merge;
237
+ exports.style = style;
package/index.mjs ADDED
@@ -0,0 +1,222 @@
1
+ import { addCss, addStaticCss, addKeyframe, addFontFace, generateIdentifier } from '@navita/adapter';
2
+ import cssesc from 'cssesc';
3
+ import chalk from 'chalk';
4
+ import { diff } from 'deep-object-diff';
5
+
6
+ function style(rule) {
7
+ return addCss(rule);
8
+ }
9
+
10
+ function globalStyle(selector, rule) {
11
+ addStaticCss(selector, rule);
12
+ }
13
+
14
+ function merge(...classNames) {
15
+ const input = classNames.filter(Boolean).join(' ').split(' ');
16
+ const output = {};
17
+ for (const className of input){
18
+ const [property] = className.split(/\d+$/);
19
+ output[property] = className;
20
+ }
21
+ return Object.values(output).join(' ');
22
+ }
23
+
24
+ function keyframes(rule) {
25
+ return addKeyframe(rule);
26
+ }
27
+
28
+ function fontFace(rule) {
29
+ return addFontFace(rule);
30
+ }
31
+
32
+ function walkObject(objectToWalk, transformFn, currentPath = []) {
33
+ const clonedObject = objectToWalk.constructor();
34
+ for(const key in objectToWalk){
35
+ const value = objectToWalk[key];
36
+ const newPath = [
37
+ ...currentPath,
38
+ key
39
+ ];
40
+ if (typeof value === 'string' || typeof value === 'number' || value == null) {
41
+ clonedObject[key] = transformFn(value, newPath);
42
+ } else if (typeof value === 'object' && !Array.isArray(value)) {
43
+ clonedObject[key] = walkObject(value, transformFn, newPath);
44
+ }
45
+ }
46
+ return clonedObject;
47
+ }
48
+
49
+ const normaliseObject = (obj)=>walkObject(obj, ()=>'');
50
+ function validateContract(contract, tokens) {
51
+ const theDiff = diff(normaliseObject(contract), normaliseObject(tokens));
52
+ const valid = Object.keys(theDiff).length === 0;
53
+ return {
54
+ valid,
55
+ diffString: valid ? '' : renderDiff(contract, theDiff)
56
+ };
57
+ }
58
+ function diffLine(value, nesting, type) {
59
+ const whitespace = [
60
+ ...Array(nesting).keys()
61
+ ].map(()=>' ').join('');
62
+ const line = `${type ? type : ' '}${whitespace}${value}`;
63
+ {
64
+ if (type === '-') {
65
+ return chalk.red(line);
66
+ }
67
+ if (type === '+') {
68
+ return chalk.green(line);
69
+ }
70
+ }
71
+ return line;
72
+ }
73
+ function renderDiff(orig, diff, nesting = 0) {
74
+ const lines = [];
75
+ if (nesting === 0) {
76
+ lines.push(diffLine('{', 0));
77
+ }
78
+ const innerNesting = nesting + 1;
79
+ const keys = Object.keys(diff).sort();
80
+ for (const key of keys){
81
+ const value = diff[key];
82
+ if (!(key in orig)) {
83
+ lines.push(diffLine(`${key}: ...,`, innerNesting, '+'));
84
+ } else if (typeof value === 'object') {
85
+ lines.push(diffLine(`${key}: {`, innerNesting));
86
+ lines.push(renderDiff(orig[key], diff[key], innerNesting));
87
+ lines.push(diffLine('}', innerNesting));
88
+ } else {
89
+ lines.push(diffLine(`${key}: ...,`, innerNesting, '-'));
90
+ }
91
+ }
92
+ if (nesting === 0) {
93
+ lines.push(diffLine('}', 0));
94
+ }
95
+ return lines.join('\n');
96
+ }
97
+
98
+ function createVar(name) {
99
+ if (!name) {
100
+ return `var(--${generateIdentifier(undefined)})`;
101
+ }
102
+ return `var(--${cssesc(name, {
103
+ isIdentifier: true
104
+ })})`;
105
+ }
106
+ function fallbackVar(...values) {
107
+ let finalValue = '';
108
+ values.reverse().forEach((value)=>{
109
+ if (finalValue === '') {
110
+ finalValue = String(value);
111
+ } else {
112
+ if (typeof value !== 'string' || !/^var\(--.*\)$/.test(value)) {
113
+ throw new Error(`Invalid variable name: ${value}`);
114
+ }
115
+ finalValue = value.replace(/\)$/, `, ${finalValue})`);
116
+ }
117
+ });
118
+ return finalValue;
119
+ }
120
+ function assignVars(varContract, tokens) {
121
+ const varSetters = {};
122
+ const { valid , diffString } = validateContract(varContract, tokens);
123
+ if (!valid) {
124
+ throw new Error(`Tokens don't match contract.\n${diffString}`);
125
+ }
126
+ walkObject(tokens, (value, path)=>{
127
+ const cssVarWithoutVar = `--${cssesc(path.join('-').toLowerCase(), {
128
+ isIdentifier: true
129
+ })}`;
130
+ varSetters[cssVarWithoutVar] = String(value);
131
+ });
132
+ return varSetters;
133
+ }
134
+
135
+ function createThemeContract(tokens) {
136
+ return walkObject(tokens, (_value, path)=>{
137
+ return createVar(path.join('-').toLowerCase());
138
+ });
139
+ }
140
+ function createGlobalThemeContract(tokens, mapFn) {
141
+ return walkObject(tokens, (value, path)=>{
142
+ const rawVarName = typeof mapFn === 'function' ? mapFn(value, path) : value;
143
+ const varName = typeof rawVarName === 'string' ? rawVarName.replace(/^\-\-/, '') : null;
144
+ if (typeof varName !== 'string' || varName !== cssesc(varName, {
145
+ isIdentifier: true
146
+ })) {
147
+ throw new Error(`Invalid variable name for "${path.join('.')}": ${varName}`);
148
+ }
149
+ return `var(--${varName})`;
150
+ });
151
+ }
152
+ function createGlobalTheme(selector, arg2, arg3) {
153
+ const shouldCreateVars = Boolean(!arg3);
154
+ const themeVars = shouldCreateVars ? createThemeContract(arg2) : arg2;
155
+ const tokens = shouldCreateVars ? arg2 : arg3;
156
+ const temp = assignVars(themeVars, tokens);
157
+ addStaticCss(selector, temp);
158
+ if (shouldCreateVars) {
159
+ return themeVars;
160
+ }
161
+ }
162
+ function createTheme(arg1, arg2) {
163
+ const themeClassName = `.${generateIdentifier(typeof arg2 === 'object' ? arg2 : arg1)}`;
164
+ const vars = typeof arg2 === 'object' ? createGlobalTheme(themeClassName, arg1, arg2) : createGlobalTheme(themeClassName, arg1);
165
+ return vars ? [
166
+ themeClassName,
167
+ vars
168
+ ] : themeClassName;
169
+ }
170
+
171
+ class ClassList extends String {
172
+ constructor(str, classList){
173
+ super(str);
174
+ this.classList = classList;
175
+ }
176
+ }
177
+
178
+ const source = '@navita/css';
179
+ const importMap = [
180
+ {
181
+ callee: "style",
182
+ source
183
+ },
184
+ {
185
+ callee: "globalStyle",
186
+ source
187
+ },
188
+ {
189
+ callee: "keyframes",
190
+ source
191
+ },
192
+ {
193
+ callee: "fontFace",
194
+ source
195
+ },
196
+ {
197
+ callee: "createThemeContract",
198
+ source
199
+ },
200
+ {
201
+ callee: "createGlobalThemeContract",
202
+ source
203
+ },
204
+ {
205
+ callee: "createGlobalTheme",
206
+ source
207
+ },
208
+ {
209
+ callee: "createTheme",
210
+ source
211
+ },
212
+ {
213
+ callee: "createVar",
214
+ source
215
+ },
216
+ {
217
+ callee: "fallbackVar",
218
+ source
219
+ }
220
+ ];
221
+
222
+ export { ClassList, assignVars, createGlobalTheme, createGlobalThemeContract, createTheme, createThemeContract, createVar, fallbackVar, fontFace, globalStyle, importMap, keyframes, merge, style };
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@navita/css",
3
+ "version": "0.0.0-main-20230917201540",
4
+ "license": "MIT",
5
+ "private": false,
6
+ "sideEffects": false,
7
+ "types": "src/index.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./index.mjs",
11
+ "require": "./index.js",
12
+ "types": "./index.d.ts"
13
+ }
14
+ },
15
+ "dependencies": {
16
+ "@navita/adapter": "0.0.0-main-20230917201540",
17
+ "@navita/types": "0.0.0-main-20230917201540",
18
+ "deep-object-diff": "^1.1.9",
19
+ "cssesc": "^3.0.0",
20
+ "chalk": "^4.1.2"
21
+ }
22
+ }