@master/css 2.0.0-rc.24 → 2.0.0-rc.26

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 (47) hide show
  1. package/dist/config/index.cjs +4 -4
  2. package/dist/config/index.d.ts +4 -4
  3. package/dist/config/index.mjs +4 -4
  4. package/dist/config/queries.cjs +13 -0
  5. package/dist/config/queries.d.ts +18 -0
  6. package/dist/config/queries.mjs +11 -0
  7. package/dist/config/variables.d.ts +0 -12
  8. package/dist/config/variables.mjs +2 -2
  9. package/dist/core.cjs +80 -75
  10. package/dist/core.d.ts +4 -4
  11. package/dist/core.mjs +76 -71
  12. package/dist/functions/are-rule-modes-equal.cjs +7 -0
  13. package/dist/functions/are-rule-modes-equal.d.ts +2 -0
  14. package/dist/functions/are-rule-modes-equal.mjs +5 -0
  15. package/dist/functions/are-rule-queries-equal.cjs +22 -0
  16. package/dist/functions/are-rule-queries-equal.d.ts +2 -0
  17. package/dist/functions/are-rule-queries-equal.mjs +20 -0
  18. package/dist/functions/are-rule-selectors-equal.cjs +29 -0
  19. package/dist/functions/are-rule-selectors-equal.d.ts +2 -0
  20. package/dist/functions/are-rule-selectors-equal.mjs +27 -0
  21. package/dist/functions/are-rule-states-equal.cjs +11 -0
  22. package/dist/functions/are-rule-states-equal.d.ts +2 -0
  23. package/dist/functions/are-rule-states-equal.mjs +9 -0
  24. package/dist/functions/are-rules-duplicated.cjs +17 -0
  25. package/dist/functions/are-rules-duplicated.d.ts +2 -0
  26. package/dist/functions/are-rules-duplicated.mjs +15 -0
  27. package/dist/{utils → functions}/extend-config.cjs +27 -14
  28. package/dist/functions/extend-config.d.ts +2 -0
  29. package/dist/{utils → functions}/extend-config.mjs +27 -14
  30. package/dist/functions/reorder-for-readable-classes.cjs +7 -7
  31. package/dist/functions/reorder-for-readable-classes.mjs +7 -7
  32. package/dist/index.cjs +16 -6
  33. package/dist/index.d.ts +7 -2
  34. package/dist/index.mjs +8 -3
  35. package/dist/rule.cjs +118 -90
  36. package/dist/rule.d.ts +28 -3
  37. package/dist/rule.mjs +118 -90
  38. package/dist/tokens/screen-sizes.cjs +2 -2
  39. package/dist/tokens/screen-sizes.mjs +2 -2
  40. package/package.json +1 -1
  41. package/dist/config/media-queries.cjs +0 -7
  42. package/dist/config/media-queries.d.ts +0 -1
  43. package/dist/config/media-queries.mjs +0 -1
  44. package/dist/functions/transform-color-with-opacity.cjs +0 -9
  45. package/dist/functions/transform-color-with-opacity.d.ts +0 -1
  46. package/dist/functions/transform-color-with-opacity.mjs +0 -7
  47. package/dist/utils/extend-config.d.ts +0 -2
package/dist/rule.mjs CHANGED
@@ -3,7 +3,6 @@ import cssEscape from './shared/utils/css-escape.mjs';
3
3
  import { Layer } from './layer.mjs';
4
4
  import { BASE_UNIT_REGEX } from './constants/base-unit-regex.mjs';
5
5
 
6
- const atRuleRegExp = /^(media|supports|page|font-face|keyframes|counter-style|font-feature-values|property|layer|container)(?=\||{|\(|$)/;
7
6
  class Rule {
8
7
  className;
9
8
  css;
@@ -12,6 +11,7 @@ class Rule {
12
11
  natives;
13
12
  order;
14
13
  layer;
14
+ atToken;
15
15
  stateToken;
16
16
  declarations;
17
17
  animationNames;
@@ -24,6 +24,7 @@ class Rule {
24
24
  this.natives = [];
25
25
  this.order = 0;
26
26
  this.layer = 0;
27
+ this.atToken = '';
27
28
  this.resolveValue = (valueComponents, unit, bypassVariableNames, bypassParsing)=>{
28
29
  const { functions } = this.css.config;
29
30
  let currentValue = '';
@@ -45,9 +46,9 @@ class Rule {
45
46
  const variable = this.css.variables[eachValueComponent.name];
46
47
  if (variable) {
47
48
  const handleVariable = (normalHandler, varHandler)=>{
48
- if (variable.themes) {
49
- if (this.theme) {
50
- const themeVariable = variable.themes[this.theme] ?? variable;
49
+ if (variable.modes) {
50
+ if (this.mode) {
51
+ const themeVariable = variable.modes[this.mode] ?? variable;
51
52
  if (themeVariable?.value) {
52
53
  normalHandler(themeVariable);
53
54
  }
@@ -262,8 +263,8 @@ class Rule {
262
263
  if (!definition.separators) definition.separators = [
263
264
  ','
264
265
  ];
265
- const { scope, important, themeDriver } = css.config;
266
- const { selectors, mediaQueries, stylesBy, animations } = css;
266
+ const { scope, important, modeDriver } = css.config;
267
+ const { selectors, queries, stylesBy, animations } = css;
267
268
  const classNames = stylesBy[className];
268
269
  if (create) create.call(this, className);
269
270
  // 1. value / selectorToken
@@ -449,109 +450,124 @@ class Rule {
449
450
  for(let i = 1; i < stateTokens.length; i++){
450
451
  const atToken = stateTokens[i];
451
452
  if (atToken) {
453
+ this.atToken += '@' + atToken;
452
454
  if (atToken === 'rtl' || atToken === 'ltr') {
453
455
  this.direction = atToken;
454
456
  } else {
455
- let type = '';
456
- let queryText;
457
- const atRuleResult = atRuleRegExp.exec(atToken);
457
+ let queryType;
458
+ const atComponents = [];
459
+ // x font-face, counter-style, keyframes, font-feature-values, property, layer
460
+ const queryTypeRegExp = /^(media|supports|container)/;
461
+ const atRuleResult = queryTypeRegExp.exec(atToken);
458
462
  if (atRuleResult) {
459
- type = atRuleResult[1];
460
- queryText = atToken.slice(type.length);
461
- } else {
462
- this.media = {
463
+ queryType = atRuleResult[1];
464
+ atComponents.push({
465
+ type: 'arbitrary',
463
466
  token: atToken,
464
- features: {}
465
- };
466
- const queryTexts = [];
467
- const analyzeToken = (typeOrFeatureToken)=>{
468
- if (typeOrFeatureToken === 'all' || typeOrFeatureToken === 'print' || typeOrFeatureToken === 'screen' || typeOrFeatureToken === 'speech') {
469
- this.media.type = typeOrFeatureToken;
470
- } else if (typeOrFeatureToken.startsWith('')) {
471
- if (typeOrFeatureToken === 'landscape' || typeOrFeatureToken === 'portrait') {
472
- queryTexts.push('(orientation:' + typeOrFeatureToken + ')');
473
- } else if (typeOrFeatureToken === 'motion' || typeOrFeatureToken === 'reduced-motion') {
474
- queryTexts.push('(prefers-reduced-motion:' + (typeOrFeatureToken === 'motion' ? 'no-preference' : 'reduce') + ')');
467
+ value: atToken.slice(queryType.length).replace(/\|/g, ' ')
468
+ });
469
+ } else {
470
+ const analyzeToken = (atComponentToken)=>{
471
+ if (atComponentToken === 'all' || atComponentToken === 'print' || atComponentToken === 'screen' || atComponentToken === 'speech') {
472
+ queryType = 'media';
473
+ atComponents.push({
474
+ type: 'media-type',
475
+ token: atComponentToken,
476
+ value: atComponentToken
477
+ });
478
+ } else if (atComponentToken === '&') {
479
+ atComponents.push({
480
+ type: 'operator',
481
+ token: atComponentToken,
482
+ value: 'and'
483
+ });
484
+ } else if (atComponentToken.startsWith('')) {
485
+ const targetQuery = queries[atComponentToken];
486
+ if (targetQuery && typeof targetQuery === 'string') {
487
+ const match = targetQuery.match(queryTypeRegExp);
488
+ queryType = match ? match[1] : '';
489
+ if (!queryType) throw new Error(`Invalid query '${atComponentToken}': '${targetQuery}'`);
490
+ atComponents.push({
491
+ type: 'arbitrary',
492
+ value: targetQuery.slice(match ? match[1].length + 1 : 0)
493
+ });
475
494
  } else {
476
- const targetMediaQuery = mediaQueries[typeOrFeatureToken];
477
- if (targetMediaQuery && typeof targetMediaQuery === 'string') {
478
- queryTexts.push(targetMediaQuery);
479
- } else {
480
- let featureName = '';
481
- let extremumOperator = '';
482
- let correction = 0;
483
- if (typeOrFeatureToken.startsWith('<=')) {
484
- extremumOperator = '<=';
485
- featureName = 'max-width';
486
- } else if (typeOrFeatureToken.startsWith('>=') || targetMediaQuery) {
487
- extremumOperator = '>=';
488
- featureName = 'min-width';
489
- } else if (typeOrFeatureToken.startsWith('>')) {
490
- extremumOperator = '>';
491
- featureName = 'min-width';
492
- correction = .02;
493
- } else if (typeOrFeatureToken.startsWith('<')) {
494
- extremumOperator = '<';
495
- featureName = 'max-width';
496
- correction = -.02;
497
- }
498
- const token = extremumOperator ? typeOrFeatureToken.replace(extremumOperator, '') : typeOrFeatureToken;
499
- const viewport = mediaQueries[token];
500
- switch(featureName){
501
- case 'max-width':
502
- case 'min-width':
503
- // eslint-disable-next-line no-case-declarations
504
- let featureComponent = {};
505
- if (typeof viewport === 'number') {
506
- featureComponent = {
507
- type: 'number',
508
- value: viewport + correction,
509
- unit: 'px'
510
- };
511
- } else {
512
- featureComponent = this.parseValueComponent(token, 'px');
513
- if (featureComponent.type === 'number' && featureComponent.unit === 'px') {
514
- featureComponent.value += correction;
515
- }
516
- }
517
- this.media.features[featureName] = featureComponent;
518
- if (featureComponent.type === 'number') {
519
- queryTexts.push('(' + featureName + ':' + (featureComponent.value + featureComponent.unit) + ')');
495
+ // todo: container queries
496
+ queryType = 'media';
497
+ let featureName = '';
498
+ let extremumOperator = '';
499
+ let correction = 0;
500
+ if (atComponentToken.startsWith('<=')) {
501
+ extremumOperator = '<=';
502
+ featureName = 'max-width';
503
+ } else if (atComponentToken.startsWith('>=') || targetQuery) {
504
+ extremumOperator = '>=';
505
+ featureName = 'min-width';
506
+ } else if (atComponentToken.startsWith('>')) {
507
+ extremumOperator = '>';
508
+ featureName = 'min-width';
509
+ correction = .02;
510
+ } else if (atComponentToken.startsWith('<')) {
511
+ extremumOperator = '<';
512
+ featureName = 'max-width';
513
+ correction = -.02;
514
+ }
515
+ const token = extremumOperator ? atComponentToken.replace(extremumOperator, '') : atComponentToken;
516
+ const viewport = queries[token];
517
+ switch(featureName){
518
+ case 'max-width':
519
+ case 'min-width':
520
+ // eslint-disable-next-line no-case-declarations
521
+ if (typeof viewport === 'number') {
522
+ atComponents.push({
523
+ type: 'feature',
524
+ name: featureName,
525
+ valueType: 'number',
526
+ value: viewport + correction,
527
+ unit: 'px'
528
+ });
529
+ } else {
530
+ const valueComponent = this.parseValueComponent(token, 'px');
531
+ if (valueComponent.type === 'number') {
532
+ atComponents.push({
533
+ type: 'feature',
534
+ name: featureName,
535
+ valueType: 'number',
536
+ value: valueComponent.value + correction,
537
+ unit: valueComponent.unit
538
+ });
520
539
  } else {
521
- queryTexts.push('(' + featureName + ':' + featureComponent.value + ')');
540
+ atComponents.push({
541
+ type: 'feature',
542
+ name: featureName,
543
+ valueType: 'string',
544
+ value: token
545
+ });
522
546
  }
523
- break;
524
- }
547
+ }
548
+ break;
525
549
  }
526
550
  }
527
551
  }
528
552
  };
529
553
  const isAmpersandIncluded = atToken.includes('&');
530
554
  if (isAmpersandIncluded) {
531
- const typeOrFeatureTokens = atToken.split('&');
532
- for (const typeOrFeatureToken of typeOrFeatureTokens){
533
- analyzeToken(typeOrFeatureToken);
555
+ const typeOrFeatureTokens = atToken.split(/(&|,)/);
556
+ for (const atComponentToken of typeOrFeatureTokens){
557
+ analyzeToken(atComponentToken);
534
558
  }
535
559
  } else {
536
560
  analyzeToken(atToken);
537
561
  }
538
- if (this.media.type) {
539
- queryText = this.media.type;
540
- }
541
- if (queryTexts.length) {
542
- queryText = queryTexts.join(' and ');
543
- }
544
- if (!queryText) {
562
+ if (!atComponents.length) {
545
563
  if (!isAmpersandIncluded) {
546
- this.theme = atToken;
564
+ this.mode = atToken;
547
565
  continue;
548
566
  }
549
- } else {
550
- type = 'media';
551
567
  }
552
568
  }
553
- if (queryText) {
554
- this.at[type] = (type in this.at ? this.at[type] + ' and ' : '') + queryText.replace(/\|/g, ' ');
569
+ if (queryType) {
570
+ this.at[queryType] = atComponents;
555
571
  }
556
572
  }
557
573
  }
@@ -610,7 +626,7 @@ class Rule {
610
626
  const prefixSelectors = this.vendorPrefixSelectors[prefixSelectorVendor];
611
627
  const suffixSelectors = this.vendorSuffixSelectors[eachSuffixSelectorVendor];
612
628
  const prefixTexts = prefixSelectors.map((eachPrefixSelector)=>eachPrefixSelector + prefixText);
613
- const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>(this.theme && themeDriver !== 'media' ? themeDriver === 'host' ? `:host(.${this.theme}) ` : `.${this.theme} ` : '') + (scope ? scope + ' ' : '') + eachPrefixText).reduce((arr, eachPrefixText)=>{
629
+ const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>(this.mode && modeDriver !== 'media' ? modeDriver === 'host' ? `:host(.${this.mode}) ` : `.${this.mode} ` : '') + (scope ? scope + ' ' : '') + eachPrefixText).reduce((arr, eachPrefixText)=>{
614
630
  arr.push(suffixSelectors.reduce((_arr, eachSuffixSelector)=>{
615
631
  _arr.push(eachPrefixText + '.' + cssEscape(name) + eachSuffixSelector);
616
632
  return _arr;
@@ -619,10 +635,10 @@ class Rule {
619
635
  }, []).join(',');
620
636
  let cssText = getCssText(className) + (classNames ? classNames.reduce((str, className)=>str + ',' + getCssText(className), '') : '') + '{' + propertiesText.join(';') + '}';
621
637
  for (const key of Object.keys(this.at).sort((_a, b)=>b === 'supports' ? -1 : 1)){
622
- cssText = '@' + key + (key.includes(' ') ? '' : ' ') + this.at[key] + '{' + cssText + '}';
638
+ cssText = '@' + key + (key.includes(' ') ? '' : ' ') + this.at[key].map((eachAtComponent)=>this.resolveAtComponent(eachAtComponent)).join(' ') + '{' + cssText + '}';
623
639
  }
624
- if (this.theme && themeDriver === 'media') {
625
- cssText = `@media(prefers-color-scheme:${this.theme}){` + cssText + '}';
640
+ if (this.mode && modeDriver === 'media') {
641
+ cssText = `@media(prefers-color-scheme:${this.mode}){` + cssText + '}';
626
642
  }
627
643
  this.natives.push({
628
644
  text: cssText
@@ -631,6 +647,18 @@ class Rule {
631
647
  }
632
648
  }
633
649
  }
650
+ resolveAtComponent(atComponent) {
651
+ switch(atComponent.type){
652
+ case 'arbitrary':
653
+ return atComponent.value;
654
+ case 'media-type':
655
+ return atComponent.value;
656
+ case 'feature':
657
+ return '(' + atComponent.name + ':' + atComponent.value + (atComponent.unit || '') + ')';
658
+ case 'operator':
659
+ return atComponent.value;
660
+ }
661
+ }
634
662
  resolveValue;
635
663
  get text() {
636
664
  return this.natives.map((eachNative)=>eachNative.text).join('');
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var mediaQueries = {
3
+ var screenSizes = {
4
4
  '4xs': 360,
5
5
  '3xs': 480,
6
6
  '2xs': 600,
@@ -14,4 +14,4 @@ var mediaQueries = {
14
14
  '4xl': 2560
15
15
  };
16
16
 
17
- module.exports = mediaQueries;
17
+ module.exports = screenSizes;
@@ -1,4 +1,4 @@
1
- var mediaQueries = {
1
+ var screenSizes = {
2
2
  '4xs': 360,
3
3
  '3xs': 480,
4
4
  '2xs': 600,
@@ -12,4 +12,4 @@ var mediaQueries = {
12
12
  '4xl': 2560
13
13
  };
14
14
 
15
- export { mediaQueries as default };
15
+ export { screenSizes as default };
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@master/css","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","test":"jest","type-check":"tsc --noEmit","lint":"eslint src"},"license":"MIT","description":"The CSS language and framework for rapidly building modern and high-performance websites","author":"Aoyue Design LLC.","funding":"https://css.master.co/docs/donate","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/css"},"keywords":["style","styles","html","variants","virtual","virtual-css","utility","css","ui","lightweight","class","webpack","plugin","integration","vite","parcel","build-tools","mastercss"],"sideEffects":false,"main":"./dist/index.cjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"require":"./dist/index.cjs","import":"./dist/index.mjs","types":"./dist/index.d.ts"}},"bin":"./dist/bin/index.mjs","files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/colors":"rc","@master/normal.css":"^2.0.0","@techor/extend":"^3.0.16"},"devDependencies":{"css-shared":"^2.0.0-rc.24","csstype":"^3.1.3"},"version":"2.0.0-rc.24"}
1
+ {"name":"@master/css","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","test":"jest","type-check":"tsc --noEmit","lint":"eslint src"},"license":"MIT","description":"The CSS language and framework for rapidly building modern and high-performance websites","author":"Aoyue Design LLC.","funding":"https://css.master.co/docs/donate","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/css"},"keywords":["style","styles","html","variants","virtual","virtual-css","utility","css","ui","lightweight","class","webpack","plugin","integration","vite","parcel","build-tools","mastercss"],"sideEffects":false,"main":"./dist/index.cjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"require":"./dist/index.cjs","import":"./dist/index.mjs","types":"./dist/index.d.ts"}},"bin":"./dist/bin/index.mjs","files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/colors":"^2.0.0","@master/normal.css":"^2.1.0","@techor/extend":"^3.0.18"},"devDependencies":{"css-shared":"^2.0.0-rc.26","csstype":"^3.1.3"},"version":"2.0.0-rc.26"}
@@ -1,7 +0,0 @@
1
- 'use strict';
2
-
3
- var screenSizes = require('../tokens/screen-sizes.cjs');
4
-
5
-
6
-
7
- module.exports = screenSizes;
@@ -1 +0,0 @@
1
- export { default } from '../tokens/screen-sizes';
@@ -1 +0,0 @@
1
- export { default } from '../tokens/screen-sizes.mjs';
@@ -1,9 +0,0 @@
1
- 'use strict';
2
-
3
- function transformColorWithOpacity(color, opacityStr) {
4
- let opacity = opacityStr.endsWith('%') ? parseFloat(opacityStr) / 100.0 : +opacityStr;
5
- opacity = isNaN(opacity) ? 1 : Math.min(Math.max(opacity, 0), 1);
6
- return color + Math.round(opacity * 255).toString(16).toUpperCase().padStart(2, '0');
7
- }
8
-
9
- exports.transformColorWithOpacity = transformColorWithOpacity;
@@ -1 +0,0 @@
1
- export declare function transformColorWithOpacity(color: string, opacityStr: string): string;
@@ -1,7 +0,0 @@
1
- function transformColorWithOpacity(color, opacityStr) {
2
- let opacity = opacityStr.endsWith('%') ? parseFloat(opacityStr) / 100.0 : +opacityStr;
3
- opacity = isNaN(opacity) ? 1 : Math.min(Math.max(opacity, 0), 1);
4
- return color + Math.round(opacity * 255).toString(16).toUpperCase().padStart(2, '0');
5
- }
6
-
7
- export { transformColorWithOpacity };
@@ -1,2 +0,0 @@
1
- import type { Config } from '../config';
2
- export declare function extendConfig(...configs: Config[]): Config;