@codecademy/variance 1.0.0-alpha.f43515.0 → 1.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 (65) hide show
  1. package/dist/core.d.ts +5 -5
  2. package/dist/core.js +152 -163
  3. package/dist/createTheme/createTheme.d.ts +7 -0
  4. package/dist/createTheme/createTheme.js +118 -150
  5. package/dist/createTheme/createTheme.test.js +50 -62
  6. package/dist/createTheme/types.d.ts +7 -7
  7. package/dist/createTheme/types.js +1 -0
  8. package/dist/getPropertyMode/getPropertyMode.d.ts +2 -0
  9. package/dist/getPropertyMode/getPropertyMode.js +3 -0
  10. package/dist/getPropertyMode/getPropertyMode.test.js +15 -0
  11. package/dist/getPropertyMode/index.d.ts +1 -0
  12. package/dist/getPropertyMode/index.js +1 -0
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +2 -1
  15. package/dist/scales/createScale.js +1 -3
  16. package/dist/scales/createScaleLookup.d.ts +2 -2
  17. package/dist/scales/createScaleLookup.js +9 -17
  18. package/dist/transforms/transformSize.js +9 -31
  19. package/dist/types/config.d.ts +18 -14
  20. package/dist/types/config.js +1 -0
  21. package/dist/types/properties.d.ts +14 -5
  22. package/dist/types/properties.js +1 -0
  23. package/dist/types/props.d.ts +27 -8
  24. package/dist/types/props.js +1 -0
  25. package/dist/types/theme.d.ts +6 -0
  26. package/dist/types/theme.js +1 -0
  27. package/dist/types/utils.d.ts +3 -3
  28. package/dist/types/utils.js +1 -0
  29. package/dist/utils/flattenScale.d.ts +5 -5
  30. package/dist/utils/flattenScale.js +24 -13
  31. package/dist/utils/getStaticProperties.js +3 -6
  32. package/dist/utils/propNames.js +42 -39
  33. package/dist/utils/responsive.d.ts +5 -5
  34. package/dist/utils/responsive.js +60 -69
  35. package/dist/utils/serializeTokens.d.ts +2 -2
  36. package/dist/utils/serializeTokens.js +34 -26
  37. package/package.json +19 -31
  38. package/CHANGELOG.md +0 -325
  39. package/LICENSE +0 -21
  40. package/babel.config.js +0 -5
  41. package/dist/core.js.map +0 -1
  42. package/dist/createTheme/createTheme.js.map +0 -1
  43. package/dist/createTheme/createTheme.test.d.ts +0 -1
  44. package/dist/createTheme/createTheme.test.js.map +0 -1
  45. package/dist/createTheme/index.js.map +0 -1
  46. package/dist/createTheme/types.js.map +0 -1
  47. package/dist/index.js.map +0 -1
  48. package/dist/scales/createScale.js.map +0 -1
  49. package/dist/scales/createScaleLookup.js.map +0 -1
  50. package/dist/transforms/index.js.map +0 -1
  51. package/dist/transforms/transformSize.js.map +0 -1
  52. package/dist/types/config.js.map +0 -1
  53. package/dist/types/properties.js.map +0 -1
  54. package/dist/types/props.js.map +0 -1
  55. package/dist/types/theme.js.map +0 -1
  56. package/dist/types/utils.js.map +0 -1
  57. package/dist/utils/__fixtures__/testConfig.js +0 -153
  58. package/dist/utils/__fixtures__/testConfig.js.map +0 -1
  59. package/dist/utils/flattenScale.js.map +0 -1
  60. package/dist/utils/getStaticProperties.js.map +0 -1
  61. package/dist/utils/propNames.js.map +0 -1
  62. package/dist/utils/responsive.js.map +0 -1
  63. package/dist/utils/serializeTokens.js.map +0 -1
  64. package/jest.config.js +0 -1
  65. package/tsconfig.base.json +0 -3
package/dist/core.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { AbstractParser, AbstractPropTransformer, Compose, CSS, Parser, Prop, PropTransformer, States, TransformerMap, Variant } from './types/config';
2
2
  export declare const variance: {
3
3
  createParser<Config extends Record<string, AbstractPropTransformer>>(config: Config): Parser<Config>;
4
- createTransform<P extends string, Config_1 extends Prop>(prop: P, config: Config_1): PropTransformer<P, Config_1>;
4
+ createTransform<P extends string, Config extends Prop>(prop: P, config: Config): PropTransformer<P, Config>;
5
5
  compose<Args extends AbstractParser[]>(...parsers: Args): Parser<Compose<Args>>;
6
- createCss<Config_2 extends Record<string, Prop>, P_1 extends Parser<TransformerMap<Config_2>>>(config: Config_2): CSS<P_1>;
7
- createVariant<Config_3 extends Record<string, Prop>, P_2 extends Parser<TransformerMap<Config_3>>>(config: Config_3): Variant<P_2>;
8
- createStates<Config_4 extends Record<string, Prop>, P_3 extends Parser<TransformerMap<Config_4>>>(config: Config_4): States<P_3>;
9
- create<Config_5 extends Record<string, Prop>>(config: Config_5): Parser<TransformerMap<Config_5>>;
6
+ createCss<Config extends Record<string, Prop>, P extends Parser<TransformerMap<Config>>>(config: Config): CSS<P>;
7
+ createVariant<Config extends Record<string, Prop>, P extends Parser<TransformerMap<Config>>>(config: Config): Variant<P>;
8
+ createStates<Config extends Record<string, Prop>, P extends Parser<TransformerMap<Config>>>(config: Config): States<P>;
9
+ create<Config extends Record<string, Prop>>(config: Config): Parser<TransformerMap<Config>>;
10
10
  };
package/dist/core.js CHANGED
@@ -1,251 +1,240 @@
1
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
-
3
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
-
5
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
-
7
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
8
-
9
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
10
-
11
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
12
-
13
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
14
-
15
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
16
-
17
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
18
-
19
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
20
-
21
- import { get, identity, isArray, isObject, isUndefined, merge } from 'lodash';
1
+ import get from 'lodash/get';
2
+ import identity from 'lodash/identity';
3
+ import isArray from 'lodash/isArray';
4
+ import isObject from 'lodash/isObject';
5
+ import isUndefined from 'lodash/isUndefined';
6
+ import merge from 'lodash/merge';
22
7
  import { createScaleLookup } from './scales/createScaleLookup';
23
8
  import { getStaticCss } from './utils/getStaticProperties';
24
9
  import { orderPropNames } from './utils/propNames';
25
10
  import { arrayParser, isMediaArray, isMediaMap, objectParser, orderBreakpoints, parseBreakpoints } from './utils/responsive';
26
- export var variance = {
11
+ export const variance = {
27
12
  // Parser to handle any set of configured props
28
- createParser: function createParser(config) {
29
- var propNames = orderPropNames(config);
30
- var breakpoints;
31
-
32
- var parser = function parser(props) {
33
- var styles = {};
34
- var theme = props.theme; // Attempt to cache the breakpoints if we have not yet or if theme has become available.
35
-
36
- if (breakpoints === undefined || breakpoints === null && theme !== null && theme !== void 0 && theme.breakpoints) {
13
+ createParser(config) {
14
+ const propNames = orderPropNames(config);
15
+ let breakpoints;
16
+ const parser = props => {
17
+ const styles = {};
18
+ const {
19
+ theme
20
+ } = props;
21
+ // Attempt to cache the breakpoints if we have not yet or if theme has become available.
22
+ if (breakpoints === undefined || breakpoints === null && theme?.breakpoints) {
37
23
  // Save the breakpoints if we can
38
- breakpoints = parseBreakpoints(theme === null || theme === void 0 ? void 0 : theme.breakpoints);
39
- } // Loops over all prop names on the configured config to check for configured styles
40
-
41
-
42
- propNames.forEach(function (prop) {
43
- var property = config[prop];
44
- var value = get(props, prop);
24
+ breakpoints = parseBreakpoints(theme?.breakpoints);
25
+ }
45
26
 
46
- switch (_typeof(value)) {
27
+ // Loops over all prop names on the configured config to check for configured styles
28
+ propNames.forEach(prop => {
29
+ const property = config[prop];
30
+ const value = get(props, prop);
31
+ switch (typeof value) {
47
32
  case 'string':
48
33
  case 'number':
49
34
  case 'function':
50
35
  return Object.assign(styles, property.styleFn(value, prop, props));
51
36
  // handle any props configured with the responsive notation
52
-
53
37
  case 'object':
54
38
  if (!breakpoints) {
55
39
  return;
56
- } // If it is an array the order of values is smallest to largest: [_, xs, ...]
57
-
58
-
40
+ }
41
+ // If it is an array the order of values is smallest to largest: [_, xs, ...]
59
42
  if (isMediaArray(value)) {
60
43
  return merge(styles, arrayParser(value, props, property, breakpoints.array));
61
- } // Check to see if value is an object matching the responsive syntax and generate the styles.
62
-
63
-
44
+ }
45
+ // Check to see if value is an object matching the responsive syntax and generate the styles.
64
46
  if (isMediaMap(value)) {
65
47
  return merge(styles, objectParser(value, props, property, breakpoints.map));
66
48
  }
67
-
68
49
  }
69
50
  });
70
51
  return breakpoints ? orderBreakpoints(styles, breakpoints.array) : styles;
71
- }; // return the parser function with the resulting meta information for further composition
72
-
73
-
52
+ };
53
+ // return the parser function with the resulting meta information for further composition
74
54
  return Object.assign(parser, {
75
- propNames: propNames,
76
- config: config
55
+ propNames,
56
+ config
77
57
  });
78
58
  },
79
59
  // Given a single property configuration enrich the config with a transform function
80
60
  // that traverses the properties the function is responsible for.
81
- createTransform: function createTransform(prop, config) {
82
- var _config$transform = config.transform,
83
- transform = _config$transform === void 0 ? identity : _config$transform,
84
- property = config.property,
85
- _config$properties = config.properties,
86
- properties = _config$properties === void 0 ? [property] : _config$properties,
87
- scale = config.scale;
88
- var getScaleValue = createScaleLookup(scale);
89
- var alwaysTransform = scale === undefined || isArray(scale);
90
- return _objectSpread(_objectSpread({}, config), {}, {
91
- prop: prop,
92
- styleFn: function styleFn(value, prop, props) {
93
- var _scaleValue;
94
-
95
- var styles = {};
96
-
61
+ createTransform(prop, config) {
62
+ const {
63
+ transform = identity,
64
+ property,
65
+ properties: configProperties,
66
+ scale,
67
+ resolveProperty
68
+ } = config;
69
+ const getScaleValue = createScaleLookup(scale);
70
+ const alwaysTransform = scale === undefined || isArray(scale);
71
+ const isDirectionalProperties = props => props !== undefined && !isArray(props) && 'physical' in props && 'logical' in props;
72
+ return {
73
+ ...config,
74
+ prop,
75
+ styleFn: (value, prop, props) => {
76
+ const styles = {};
97
77
  if (isUndefined(value)) {
98
78
  return styles;
99
79
  }
100
-
101
- var useTransform = false;
102
- var intermediateValue;
103
- var scaleValue;
104
-
105
- switch (_typeof(value)) {
80
+ let useTransform = false;
81
+ let intermediateValue;
82
+ let scaleValue;
83
+ switch (typeof value) {
106
84
  case 'number':
107
85
  case 'string':
108
86
  scaleValue = getScaleValue(value, props);
109
87
  useTransform = scaleValue !== undefined || alwaysTransform;
110
- intermediateValue = (_scaleValue = scaleValue) !== null && _scaleValue !== void 0 ? _scaleValue : value;
88
+ intermediateValue = scaleValue ?? value;
111
89
  break;
112
-
113
90
  case 'function':
114
91
  if (props.theme) {
115
92
  intermediateValue = value(props.theme);
116
93
  }
117
-
118
94
  break;
119
-
120
95
  default:
121
96
  return styles;
122
- } // for each property look up the scale value from theme if passed and apply any
123
- // final transforms to the value
124
-
125
-
126
- properties.forEach(function (property) {
127
- var styleValue = intermediateValue;
97
+ }
98
+ const useLogicalProperties = props.theme?.useLogicalProperties ?? true;
99
+ let resolvedProperties;
100
+ if (isDirectionalProperties(configProperties)) {
101
+ const mode = resolveProperty ? resolveProperty(useLogicalProperties) : useLogicalProperties ? 'logical' : 'physical';
102
+ resolvedProperties = configProperties[mode];
103
+ } else {
104
+ resolvedProperties = configProperties ?? [property];
105
+ }
128
106
 
107
+ // for each property look up the scale value from theme if passed and apply any
108
+ // final transforms to the value
109
+ resolvedProperties.forEach(property => {
110
+ let resolvedProperty;
111
+ if (resolveProperty && typeof property === 'object') {
112
+ const mode = resolveProperty(useLogicalProperties);
113
+ resolvedProperty = property[mode];
114
+ } else {
115
+ resolvedProperty = property;
116
+ }
117
+ let styleValue = intermediateValue;
129
118
  if (useTransform && !isUndefined(styleValue)) {
130
- styleValue = transform(styleValue, property, props);
119
+ styleValue = transform(styleValue, resolvedProperty, props);
131
120
  }
132
-
133
- switch (_typeof(styleValue)) {
121
+ switch (typeof styleValue) {
134
122
  case 'number':
135
123
  case 'string':
136
- return styles[property] = styleValue;
137
-
124
+ return styles[resolvedProperty] = styleValue;
138
125
  case 'object':
139
126
  return Object.assign(styles, styleValue);
140
-
141
127
  default:
142
128
  }
143
- }); // return the resulting styles object
144
-
129
+ });
130
+ // return the resulting styles object
145
131
  return styles;
146
132
  }
147
- });
133
+ };
148
134
  },
149
- compose: function compose() {
150
- for (var _len = arguments.length, parsers = new Array(_len), _key = 0; _key < _len; _key++) {
151
- parsers[_key] = arguments[_key];
152
- }
153
-
154
- return this.createParser(parsers.reduce(function (carry, parser) {
155
- return _objectSpread(_objectSpread({}, carry), parser.config);
156
- }, {}));
135
+ compose(...parsers) {
136
+ return this.createParser(parsers.reduce((carry, parser) => ({
137
+ ...carry,
138
+ ...parser.config
139
+ }), {}));
157
140
  },
158
- createCss: function createCss(config) {
159
- var parser = this.create(config);
160
- var filteredProps = parser.propNames;
161
- return function (cssProps) {
162
- var cache;
163
- var allKeys = Object.keys(cssProps);
141
+ createCss(config) {
142
+ const parser = this.create(config);
143
+ const filteredProps = parser.propNames;
144
+ return cssProps => {
145
+ let cache;
146
+ const allKeys = Object.keys(cssProps);
147
+
164
148
  /** Any key of the CSSProps that is not a System Prop or a Static CSS Property is treated as a nested selector */
149
+ const selectors = allKeys.filter(key => !filteredProps.includes(key) && isObject(cssProps[key]));
165
150
 
166
- var selectors = allKeys.filter(function (key) {
167
- return !filteredProps.includes(key) && isObject(cssProps[key]);
168
- });
169
151
  /** Static CSS Properties get extracted if they match neither syntax */
170
-
171
- var staticCss = getStaticCss(cssProps, ['theme'].concat(_toConsumableArray(selectors), _toConsumableArray(filteredProps)));
172
- return function (_ref) {
173
- var theme = _ref.theme;
152
+ const staticCss = getStaticCss(cssProps, ['theme',
153
+ // Just in case this gets passed somehow
154
+ ...selectors, ...filteredProps]);
155
+ return ({
156
+ theme
157
+ }) => {
174
158
  if (cache) return cache;
175
- var css = parser(_objectSpread(_objectSpread({}, cssProps), {}, {
176
- theme: theme
177
- }));
178
- selectors.forEach(function (selector) {
179
- var _cssProps$selector;
180
-
181
- var selectorConfig = (_cssProps$selector = cssProps[selector]) !== null && _cssProps$selector !== void 0 ? _cssProps$selector : {};
182
- css[selector] = _objectSpread(_objectSpread({}, getStaticCss(selectorConfig, filteredProps)), parser(_objectSpread(_objectSpread({}, selectorConfig), {}, {
183
- theme: theme
184
- })));
159
+ const css = parser({
160
+ ...cssProps,
161
+ theme
162
+ });
163
+ selectors.forEach(selector => {
164
+ const selectorConfig = cssProps[selector] ?? {};
165
+ css[selector] = {
166
+ ...getStaticCss(selectorConfig, filteredProps),
167
+ ...parser({
168
+ ...selectorConfig,
169
+ theme
170
+ })
171
+ };
185
172
  });
186
- /** Merge the static and generated css and save it to the cache */
187
173
 
188
- cache = _objectSpread(_objectSpread({}, staticCss), css);
174
+ /** Merge the static and generated css and save it to the cache */
175
+ cache = {
176
+ ...staticCss,
177
+ ...css
178
+ };
189
179
  return cache;
190
180
  };
191
181
  };
192
182
  },
193
- createVariant: function createVariant(config) {
194
- var css = this.createCss(config);
195
- return function (_ref2) {
196
- var _ref2$prop = _ref2.prop,
197
- prop = _ref2$prop === void 0 ? 'variant' : _ref2$prop,
198
- defaultVariant = _ref2.defaultVariant,
199
- _ref2$base = _ref2.base,
200
- base = _ref2$base === void 0 ? {} : _ref2$base,
201
- variants = _ref2.variants;
202
- var baseFn = css(base);
203
- var variantFns = {};
204
- Object.keys(variants).forEach(function (key) {
205
- var variantKey = key;
206
- var cssProps = variants[variantKey];
183
+ createVariant(config) {
184
+ const css = this.createCss(config);
185
+ return ({
186
+ prop = 'variant',
187
+ defaultVariant,
188
+ base = {},
189
+ variants
190
+ }) => {
191
+ const baseFn = css(base);
192
+ const variantFns = {};
193
+ Object.keys(variants).forEach(key => {
194
+ const variantKey = key;
195
+ const cssProps = variants[variantKey];
207
196
  variantFns[variantKey] = css(cssProps);
208
197
  });
209
- return function (props) {
210
- var _variantFns;
211
-
212
- var _props$prop = props[prop],
213
- selected = _props$prop === void 0 ? defaultVariant : _props$prop;
214
- var styles = {};
198
+ return props => {
199
+ const {
200
+ [prop]: selected = defaultVariant
201
+ } = props;
202
+ const styles = {};
215
203
  if (!selected) return styles;
216
- return merge(styles, baseFn(props), variantFns === null || variantFns === void 0 ? void 0 : (_variantFns = variantFns[selected]) === null || _variantFns === void 0 ? void 0 : _variantFns.call(variantFns, props));
204
+ return merge(styles, baseFn(props), variantFns?.[selected]?.(props));
217
205
  };
218
206
  };
219
207
  },
220
- createStates: function createStates(config) {
221
- var css = this.createCss(config);
222
- return function (states) {
223
- var orderedStates = Object.keys(states);
224
- var stateFns = {};
225
- orderedStates.forEach(function (key) {
226
- var stateKey = key;
227
- var cssProps = states[stateKey];
208
+ createStates(config) {
209
+ const css = this.createCss(config);
210
+ return states => {
211
+ const orderedStates = Object.keys(states);
212
+ const stateFns = {};
213
+ orderedStates.forEach(key => {
214
+ const stateKey = key;
215
+ const cssProps = states[stateKey];
228
216
  stateFns[stateKey] = css(cssProps);
229
217
  });
230
- return function (props) {
231
- var styles = {};
232
- orderedStates.forEach(function (state) {
218
+ return props => {
219
+ const styles = {};
220
+ orderedStates.forEach(state => {
233
221
  merge(styles, props[state] && stateFns[state](props));
234
222
  });
235
223
  return styles;
236
224
  };
237
225
  };
238
226
  },
239
- create: function create(config) {
240
- var transforms = {}; // Create a transform function for each of the props
227
+ create(config) {
228
+ const transforms = {};
241
229
 
242
- for (var prop in config) {
230
+ // Create a transform function for each of the props
231
+ for (const prop in config) {
243
232
  if (typeof prop === 'string') {
244
233
  transforms[prop] = this.createTransform(prop, config[prop]);
245
234
  }
246
- } // Create a parser that handles all the props within the config
247
-
235
+ }
248
236
 
237
+ // Create a parser that handles all the props within the config
249
238
  return this.createParser(transforms);
250
239
  }
251
240
  };
@@ -46,6 +46,13 @@ declare class ThemeBuilder<T extends AbstractTheme> {
46
46
  * @example .updateScale('fonts', ({ basic }) => ({ basicFallback: `{basic}, Montserrat` }))
47
47
  */
48
48
  updateScale<Key extends keyof T, Fn extends (tokens: T[Key]) => Record<string | number, unknown>>(key: Key, updateFn: Fn): ThemeBuilder<T & Record<Key, T[Key] & ReturnType<Fn>>>;
49
+ /**
50
+ *
51
+ * @param name Adds a name to the theme
52
+ * This is used for referencing the theme for replacing default fonts.
53
+ * @example .addName('core')
54
+ */
55
+ addName(name: string): ThemeBuilder<MergeTheme<T & PrivateThemeKeys, Record<'name', string>>>;
49
56
  /**
50
57
  * This finalizes the theme build and returns the final theme and variables to be provided.
51
58
  */