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