css-engine-test-pb 0.1.4 → 0.1.6

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 (59) hide show
  1. package/dist/compiler.d.ts +2 -0
  2. package/dist/compiler.js +40 -4
  3. package/dist/index.d.ts +25 -2
  4. package/dist/index.js +25 -2
  5. package/dist/makeFontFace.d.ts +2 -0
  6. package/dist/makeFontFace.js +70 -0
  7. package/dist/makeStaticStyles.js +35 -2
  8. package/dist/shorthands/border.d.ts +2 -0
  9. package/dist/shorthands/border.js +32 -0
  10. package/dist/shorthands/borderBottom.d.ts +2 -0
  11. package/dist/shorthands/borderBottom.js +29 -0
  12. package/dist/shorthands/borderLeft.d.ts +2 -0
  13. package/dist/shorthands/borderLeft.js +29 -0
  14. package/dist/shorthands/borderRadius.d.ts +2 -0
  15. package/dist/shorthands/borderRadius.js +8 -0
  16. package/dist/shorthands/borderRight.d.ts +2 -0
  17. package/dist/shorthands/borderRight.js +29 -0
  18. package/dist/shorthands/borderStyle.d.ts +2 -0
  19. package/dist/shorthands/borderStyle.js +8 -0
  20. package/dist/shorthands/borderTop.d.ts +2 -0
  21. package/dist/shorthands/borderTop.js +29 -0
  22. package/dist/shorthands/borderWidth.d.ts +2 -0
  23. package/dist/shorthands/borderWidth.js +8 -0
  24. package/dist/shorthands/flex.d.ts +2 -0
  25. package/dist/shorthands/flex.js +49 -0
  26. package/dist/shorthands/gap.d.ts +2 -0
  27. package/dist/shorthands/gap.js +6 -0
  28. package/dist/shorthands/gridArea.d.ts +2 -0
  29. package/dist/shorthands/gridArea.js +8 -0
  30. package/dist/shorthands/index.d.ts +22 -0
  31. package/dist/shorthands/index.js +22 -0
  32. package/dist/shorthands/inset.d.ts +2 -0
  33. package/dist/shorthands/inset.js +8 -0
  34. package/dist/shorthands/margin.d.ts +2 -0
  35. package/dist/shorthands/margin.js +8 -0
  36. package/dist/shorthands/marginBlock.d.ts +2 -0
  37. package/dist/shorthands/marginBlock.js +6 -0
  38. package/dist/shorthands/marginInline.d.ts +2 -0
  39. package/dist/shorthands/marginInline.js +6 -0
  40. package/dist/shorthands/outline.d.ts +2 -0
  41. package/dist/shorthands/outline.js +7 -0
  42. package/dist/shorthands/overflow.d.ts +2 -0
  43. package/dist/shorthands/overflow.js +6 -0
  44. package/dist/shorthands/padding.d.ts +2 -0
  45. package/dist/shorthands/padding.js +8 -0
  46. package/dist/shorthands/paddingBlock.d.ts +2 -0
  47. package/dist/shorthands/paddingBlock.js +6 -0
  48. package/dist/shorthands/paddingInline.d.ts +2 -0
  49. package/dist/shorthands/paddingInline.js +6 -0
  50. package/dist/shorthands/textDecoration.d.ts +2 -0
  51. package/dist/shorthands/textDecoration.js +23 -0
  52. package/dist/shorthands/transition.d.ts +4 -0
  53. package/dist/shorthands/transition.js +37 -0
  54. package/dist/types.d.ts +69 -8
  55. package/dist/utils/css.d.ts +1 -0
  56. package/dist/utils/css.js +3 -0
  57. package/dist/utils/index.d.ts +1 -1
  58. package/dist/utils/index.js +1 -1
  59. package/package.json +1 -1
@@ -11,9 +11,11 @@ export declare class StyleCompiler {
11
11
  private compileMonolithic;
12
12
  private buildCSSBlock;
13
13
  private buildMonolithicPseudos;
14
+ private buildMonolithicCombinators;
14
15
  private buildMonolithicMedia;
15
16
  private processProperties;
16
17
  private processPseudos;
18
+ private processCombinators;
17
19
  private processMediaQueries;
18
20
  }
19
21
  export {};
package/dist/compiler.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { StyleBucket } from './types';
2
2
  import { createClassName, hashString } from './utils/hash';
3
- import { camelToKebab, isPseudoSelector, isMediaQuery, determineBucket } from './utils';
3
+ import { camelToKebab, isPseudoSelector, isMediaQuery, isCombinator, determineBucket } from './utils';
4
4
  export class StyleCompiler {
5
5
  compile(styleDefinition, mode = 'atomic') {
6
6
  if (mode === 'monolithic') {
@@ -12,6 +12,7 @@ export class StyleCompiler {
12
12
  const rules = [];
13
13
  this.processProperties(styleDefinition, rules);
14
14
  this.processPseudos(styleDefinition, rules);
15
+ this.processCombinators(styleDefinition, rules);
15
16
  this.processMediaQueries(styleDefinition, rules);
16
17
  return rules;
17
18
  }
@@ -24,6 +25,7 @@ export class StyleCompiler {
24
25
  cssText += `.${className} { ${mainStyles} }\n`;
25
26
  }
26
27
  cssText += this.buildMonolithicPseudos(styleDefinition, className);
28
+ cssText += this.buildMonolithicCombinators(styleDefinition, className);
27
29
  cssText += this.buildMonolithicMedia(styleDefinition, className);
28
30
  return [{
29
31
  className,
@@ -34,7 +36,7 @@ export class StyleCompiler {
34
36
  buildCSSBlock(styles) {
35
37
  let css = '';
36
38
  for (const [property, value] of Object.entries(styles)) {
37
- if (isPseudoSelector(property) || isMediaQuery(property)) {
39
+ if (isPseudoSelector(property) || isMediaQuery(property) || isCombinator(property)) {
38
40
  continue;
39
41
  }
40
42
  if (value === undefined || value === null) {
@@ -66,6 +68,19 @@ export class StyleCompiler {
66
68
  }
67
69
  return css;
68
70
  }
71
+ buildMonolithicCombinators(styleDefinition, className) {
72
+ let css = '';
73
+ for (const [key, value] of Object.entries(styleDefinition)) {
74
+ if (isCombinator(key) && value) {
75
+ const combinatorStyles = this.buildCSSBlock(value);
76
+ if (combinatorStyles) {
77
+ const selector = key.replace('&', `.${className}`);
78
+ css += `${selector} { ${combinatorStyles} }\n`;
79
+ }
80
+ }
81
+ }
82
+ return css;
83
+ }
69
84
  buildMonolithicMedia(styleDefinition, className) {
70
85
  let css = '';
71
86
  for (const [key, value] of Object.entries(styleDefinition)) {
@@ -92,6 +107,13 @@ export class StyleCompiler {
92
107
  }
93
108
  }
94
109
  }
110
+ else if (isCombinator(nestedKey) && nestedValue) {
111
+ const combinatorStyles = this.buildCSSBlock(nestedValue);
112
+ if (combinatorStyles) {
113
+ const selector = nestedKey.replace('&', `.${className}`);
114
+ mediaCss += `${selector} { ${combinatorStyles} }\n`;
115
+ }
116
+ }
95
117
  }
96
118
  if (mediaCss) {
97
119
  css += `${key} {\n${mediaCss}}\n`;
@@ -102,7 +124,7 @@ export class StyleCompiler {
102
124
  }
103
125
  processProperties(styles, rules, pseudo, media) {
104
126
  Object.entries(styles).forEach(([property, value]) => {
105
- if (isPseudoSelector(property) || isMediaQuery(property)) {
127
+ if (isPseudoSelector(property) || isMediaQuery(property) || isCombinator(property)) {
106
128
  return;
107
129
  }
108
130
  if (value === undefined || value === null) {
@@ -112,7 +134,11 @@ export class StyleCompiler {
112
134
  const hashInput = `${kebabProperty}:${value}${pseudo || ''}${media || ''}`;
113
135
  const className = createClassName(hashInput);
114
136
  let selector;
115
- if (pseudo && pseudo.includes(',')) {
137
+ if (pseudo && pseudo.startsWith('& ')) {
138
+ // It's a combinator - replace & with class
139
+ selector = pseudo.replace('&', `.${className}`);
140
+ }
141
+ else if (pseudo && pseudo.includes(',')) {
116
142
  const selectors = pseudo
117
143
  .split(',')
118
144
  .map(s => `.${className}${s.trim()}`)
@@ -142,6 +168,13 @@ export class StyleCompiler {
142
168
  }
143
169
  });
144
170
  }
171
+ processCombinators(styleDefinition, rules) {
172
+ Object.entries(styleDefinition).forEach(([key, value]) => {
173
+ if (isCombinator(key) && value) {
174
+ this.processProperties(value, rules, key);
175
+ }
176
+ });
177
+ }
145
178
  processMediaQueries(styleDefinition, rules) {
146
179
  Object.entries(styleDefinition).forEach(([key, value]) => {
147
180
  if (isMediaQuery(key) && value) {
@@ -151,6 +184,9 @@ export class StyleCompiler {
151
184
  if (isPseudoSelector(nestedKey) && nestedValue) {
152
185
  this.processProperties(nestedValue, rules, nestedKey, key);
153
186
  }
187
+ else if (isCombinator(nestedKey) && nestedValue) {
188
+ this.processProperties(nestedValue, rules, nestedKey, key);
189
+ }
154
190
  });
155
191
  }
156
192
  });
package/dist/index.d.ts CHANGED
@@ -1,9 +1,32 @@
1
- import { borderColor } from './shorthands';
1
+ import { border, borderTop, borderRight, borderBottom, borderLeft, borderColor, borderStyle, borderWidth, borderRadius, flex, gap, gridArea, inset, margin, marginBlock, marginInline, outline, overflow, padding, paddingBlock, paddingInline, textDecoration, transition } from './shorthands';
2
2
  export declare const shorthands: {
3
+ border: typeof border;
4
+ borderTop: typeof borderTop;
5
+ borderRight: typeof borderRight;
6
+ borderBottom: typeof borderBottom;
7
+ borderLeft: typeof borderLeft;
3
8
  borderColor: typeof borderColor;
9
+ borderStyle: typeof borderStyle;
10
+ borderWidth: typeof borderWidth;
11
+ borderRadius: typeof borderRadius;
12
+ flex: typeof flex;
13
+ gap: typeof gap;
14
+ gridArea: typeof gridArea;
15
+ inset: typeof inset;
16
+ margin: typeof margin;
17
+ marginBlock: typeof marginBlock;
18
+ marginInline: typeof marginInline;
19
+ outline: typeof outline;
20
+ overflow: typeof overflow;
21
+ padding: typeof padding;
22
+ paddingBlock: typeof paddingBlock;
23
+ paddingInline: typeof paddingInline;
24
+ textDecoration: typeof textDecoration;
25
+ transition: typeof transition;
4
26
  };
5
27
  export { makeStyles } from './makeStyles';
6
28
  export { makeResetStyles } from './makeResetStyles';
7
29
  export { mergeClasses } from './mergeClasses';
8
30
  export { makeStaticStyles } from './makeStaticStyles';
9
- export type { StyleRule, CSSProperties, GeneratedClasses, StyleSlots } from './types';
31
+ export { makeFontFace } from './makeFontFace';
32
+ export type { StyleRule, CSSProperties, GeneratedClasses, StyleSlots, FontFaceDefinition } from './types';
package/dist/index.js CHANGED
@@ -1,8 +1,31 @@
1
- import { borderColor } from './shorthands';
1
+ import { border, borderTop, borderRight, borderBottom, borderLeft, borderColor, borderStyle, borderWidth, borderRadius, flex, gap, gridArea, inset, margin, marginBlock, marginInline, outline, overflow, padding, paddingBlock, paddingInline, textDecoration, transition, } from './shorthands';
2
2
  export const shorthands = {
3
- borderColor
3
+ border,
4
+ borderTop,
5
+ borderRight,
6
+ borderBottom,
7
+ borderLeft,
8
+ borderColor,
9
+ borderStyle,
10
+ borderWidth,
11
+ borderRadius,
12
+ flex,
13
+ gap,
14
+ gridArea,
15
+ inset,
16
+ margin,
17
+ marginBlock,
18
+ marginInline,
19
+ outline,
20
+ overflow,
21
+ padding,
22
+ paddingBlock,
23
+ paddingInline,
24
+ textDecoration,
25
+ transition,
4
26
  };
5
27
  export { makeStyles } from './makeStyles';
6
28
  export { makeResetStyles } from './makeResetStyles';
7
29
  export { mergeClasses } from './mergeClasses';
8
30
  export { makeStaticStyles } from './makeStaticStyles';
31
+ export { makeFontFace } from './makeFontFace';
@@ -0,0 +1,2 @@
1
+ import type { FontFaceDefinition } from './types';
2
+ export declare function makeFontFace(fonts: FontFaceDefinition | FontFaceDefinition[]): () => void;
@@ -0,0 +1,70 @@
1
+ import { getGlobalEngine } from './engine';
2
+ import { StyleBucket } from './types';
3
+ export function makeFontFace(fonts) {
4
+ const engine = getGlobalEngine();
5
+ const fontsArray = Array.isArray(fonts) ? fonts : [fonts];
6
+ let inserted = false;
7
+ return function useFontFace() {
8
+ if (inserted) {
9
+ return;
10
+ }
11
+ fontsArray.forEach(font => {
12
+ const properties = [];
13
+ // Required properties
14
+ properties.push(`font-family: ${quoteIfNeeded(font.fontFamily)}`);
15
+ properties.push(`src: ${font.src}`);
16
+ // Optional properties
17
+ if (font.fontWeight !== undefined) {
18
+ properties.push(`font-weight: ${font.fontWeight}`);
19
+ }
20
+ if (font.fontStyle !== undefined) {
21
+ properties.push(`font-style: ${font.fontStyle}`);
22
+ }
23
+ if (font.fontDisplay !== undefined) {
24
+ properties.push(`font-display: ${font.fontDisplay}`);
25
+ }
26
+ if (font.unicodeRange !== undefined) {
27
+ properties.push(`unicode-range: ${font.unicodeRange}`);
28
+ }
29
+ if (font.fontStretch !== undefined) {
30
+ properties.push(`font-stretch: ${font.fontStretch}`);
31
+ }
32
+ if (font.fontVariant !== undefined) {
33
+ properties.push(`font-variant: ${font.fontVariant}`);
34
+ }
35
+ if (font.fontFeatureSettings !== undefined) {
36
+ properties.push(`font-feature-settings: ${font.fontFeatureSettings}`);
37
+ }
38
+ if (font.fontVariationSettings !== undefined) {
39
+ properties.push(`font-variation-settings: ${font.fontVariationSettings}`);
40
+ }
41
+ if (font.ascentOverride !== undefined) {
42
+ properties.push(`ascent-override: ${font.ascentOverride}`);
43
+ }
44
+ if (font.descentOverride !== undefined) {
45
+ properties.push(`descent-override: ${font.descentOverride}`);
46
+ }
47
+ if (font.lineGapOverride !== undefined) {
48
+ properties.push(`line-gap-override: ${font.lineGapOverride}`);
49
+ }
50
+ const cssRule = `@font-face { ${properties.join('; ')}; }`;
51
+ engine['insertion'].insertRule(cssRule, StyleBucket.RESET);
52
+ });
53
+ inserted = true;
54
+ };
55
+ }
56
+ function quoteIfNeeded(fontFamily) {
57
+ // If already quoted or is a generic family, return as-is
58
+ if (fontFamily.startsWith('"') || fontFamily.startsWith("'")) {
59
+ return fontFamily;
60
+ }
61
+ const genericFamilies = ['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy', 'system-ui'];
62
+ if (genericFamilies.includes(fontFamily.toLowerCase())) {
63
+ return fontFamily;
64
+ }
65
+ // Quote font family names with spaces or special characters
66
+ if (/[\s\-]/.test(fontFamily)) {
67
+ return `"${fontFamily}"`;
68
+ }
69
+ return fontFamily;
70
+ }
@@ -10,16 +10,49 @@ export function makeStaticStyles(styles) {
10
10
  }
11
11
  stylesArray.forEach(styleBlock => {
12
12
  Object.entries(styleBlock).forEach(([selector, properties]) => {
13
+ const isFontFace = selector === '@font-face';
13
14
  const cssProperties = Object.entries(properties)
14
15
  .map(([prop, value]) => {
15
16
  const kebabProp = prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);
16
- return `${kebabProp}: ${value};`;
17
+ let cssValue = String(value);
18
+ // Quote font-family values that contain spaces and aren't already quoted
19
+ if (kebabProp === 'font-family' && typeof value === 'string') {
20
+ cssValue = quoteFontFamily(value);
21
+ }
22
+ return `${kebabProp}: ${cssValue};`;
17
23
  })
18
24
  .join(' ');
19
- const cssRule = `${selector} { ${cssProperties} }`;
25
+ let cssRule;
26
+ if (isFontFace) {
27
+ cssRule = `@font-face { ${cssProperties} }`;
28
+ }
29
+ else {
30
+ cssRule = `${selector} { ${cssProperties} }`;
31
+ }
20
32
  engine['insertion'].insertRule(cssRule, StyleBucket.RESET);
21
33
  });
22
34
  });
23
35
  inserted = true;
24
36
  };
25
37
  }
38
+ function quoteFontFamily(value) {
39
+ // Handle comma-separated font stacks
40
+ return value.split(',').map(font => {
41
+ font = font.trim();
42
+ // Already quoted
43
+ if ((font.startsWith('"') && font.endsWith('"')) ||
44
+ (font.startsWith("'") && font.endsWith("'"))) {
45
+ return font;
46
+ }
47
+ // Generic families don't need quotes
48
+ const genericFamilies = ['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy', 'system-ui', 'ui-serif', 'ui-sans-serif', 'ui-monospace', 'ui-rounded', 'inherit', 'initial', 'unset'];
49
+ if (genericFamilies.includes(font.toLowerCase())) {
50
+ return font;
51
+ }
52
+ // Quote if contains spaces or special characters
53
+ if (/[\s\-()]/.test(font)) {
54
+ return `"${font}"`;
55
+ }
56
+ return font;
57
+ }).join(', ');
58
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function border(width: CSSValue, style?: CSSValue, color?: CSSValue): CSSProperties;
@@ -0,0 +1,32 @@
1
+ import { borderWidth } from './borderWidth';
2
+ import { borderStyle } from './borderStyle';
3
+ import { borderColor } from './borderColor';
4
+ const BORDER_STYLES = ['dashed', 'dotted', 'double', 'groove', 'hidden', 'inset', 'none', 'outset', 'ridge', 'solid'];
5
+ function isBorderStyleValue(value) {
6
+ return typeof value === 'string' && BORDER_STYLES.includes(value);
7
+ }
8
+ export function border(width, style, color) {
9
+ if (style === undefined && color === undefined) {
10
+ if (isBorderStyleValue(width)) {
11
+ return borderStyle(width);
12
+ }
13
+ return borderWidth(width);
14
+ }
15
+ if (color === undefined) {
16
+ if (isBorderStyleValue(width)) {
17
+ return {
18
+ ...borderStyle(width),
19
+ ...borderColor(style),
20
+ };
21
+ }
22
+ return {
23
+ ...borderWidth(width),
24
+ ...borderStyle(style),
25
+ };
26
+ }
27
+ return {
28
+ ...borderWidth(width),
29
+ ...borderStyle(style),
30
+ ...borderColor(color),
31
+ };
32
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderBottom(width: CSSValue, style?: CSSValue, color?: CSSValue): CSSProperties;
@@ -0,0 +1,29 @@
1
+ const BORDER_STYLES = ['dashed', 'dotted', 'double', 'groove', 'hidden', 'inset', 'none', 'outset', 'ridge', 'solid'];
2
+ function isBorderStyle(value) {
3
+ return typeof value === 'string' && BORDER_STYLES.includes(value);
4
+ }
5
+ export function borderBottom(width, style, color) {
6
+ if (style === undefined && color === undefined) {
7
+ if (isBorderStyle(width)) {
8
+ return { borderBottomStyle: width };
9
+ }
10
+ return { borderBottomWidth: width };
11
+ }
12
+ if (color === undefined) {
13
+ if (isBorderStyle(width)) {
14
+ return {
15
+ borderBottomStyle: width,
16
+ borderBottomColor: style,
17
+ };
18
+ }
19
+ return {
20
+ borderBottomWidth: width,
21
+ borderBottomStyle: style,
22
+ };
23
+ }
24
+ return {
25
+ borderBottomWidth: width,
26
+ borderBottomStyle: style,
27
+ borderBottomColor: color,
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderLeft(width: CSSValue, style?: CSSValue, color?: CSSValue): CSSProperties;
@@ -0,0 +1,29 @@
1
+ const BORDER_STYLES = ['dashed', 'dotted', 'double', 'groove', 'hidden', 'inset', 'none', 'outset', 'ridge', 'solid'];
2
+ function isBorderStyle(value) {
3
+ return typeof value === 'string' && BORDER_STYLES.includes(value);
4
+ }
5
+ export function borderLeft(width, style, color) {
6
+ if (style === undefined && color === undefined) {
7
+ if (isBorderStyle(width)) {
8
+ return { borderLeftStyle: width };
9
+ }
10
+ return { borderLeftWidth: width };
11
+ }
12
+ if (color === undefined) {
13
+ if (isBorderStyle(width)) {
14
+ return {
15
+ borderLeftStyle: width,
16
+ borderLeftColor: style,
17
+ };
18
+ }
19
+ return {
20
+ borderLeftWidth: width,
21
+ borderLeftStyle: style,
22
+ };
23
+ }
24
+ return {
25
+ borderLeftWidth: width,
26
+ borderLeftStyle: style,
27
+ borderLeftColor: color,
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderRadius(topLeft: CSSValue, topRight?: CSSValue, bottomRight?: CSSValue, bottomLeft?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function borderRadius(topLeft, topRight = topLeft, bottomRight = topLeft, bottomLeft = topRight) {
2
+ return {
3
+ borderTopLeftRadius: topLeft,
4
+ borderTopRightRadius: topRight,
5
+ borderBottomRightRadius: bottomRight,
6
+ borderBottomLeftRadius: bottomLeft,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderRight(width: CSSValue, style?: CSSValue, color?: CSSValue): CSSProperties;
@@ -0,0 +1,29 @@
1
+ const BORDER_STYLES = ['dashed', 'dotted', 'double', 'groove', 'hidden', 'inset', 'none', 'outset', 'ridge', 'solid'];
2
+ function isBorderStyle(value) {
3
+ return typeof value === 'string' && BORDER_STYLES.includes(value);
4
+ }
5
+ export function borderRight(width, style, color) {
6
+ if (style === undefined && color === undefined) {
7
+ if (isBorderStyle(width)) {
8
+ return { borderRightStyle: width };
9
+ }
10
+ return { borderRightWidth: width };
11
+ }
12
+ if (color === undefined) {
13
+ if (isBorderStyle(width)) {
14
+ return {
15
+ borderRightStyle: width,
16
+ borderRightColor: style,
17
+ };
18
+ }
19
+ return {
20
+ borderRightWidth: width,
21
+ borderRightStyle: style,
22
+ };
23
+ }
24
+ return {
25
+ borderRightWidth: width,
26
+ borderRightStyle: style,
27
+ borderRightColor: color,
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderStyle(top: CSSValue, right?: CSSValue, bottom?: CSSValue, left?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function borderStyle(top, right = top, bottom = top, left = right) {
2
+ return {
3
+ borderTopStyle: top,
4
+ borderRightStyle: right,
5
+ borderBottomStyle: bottom,
6
+ borderLeftStyle: left,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderTop(width: CSSValue, style?: CSSValue, color?: CSSValue): CSSProperties;
@@ -0,0 +1,29 @@
1
+ const BORDER_STYLES = ['dashed', 'dotted', 'double', 'groove', 'hidden', 'inset', 'none', 'outset', 'ridge', 'solid'];
2
+ function isBorderStyle(value) {
3
+ return typeof value === 'string' && BORDER_STYLES.includes(value);
4
+ }
5
+ export function borderTop(width, style, color) {
6
+ if (style === undefined && color === undefined) {
7
+ if (isBorderStyle(width)) {
8
+ return { borderTopStyle: width };
9
+ }
10
+ return { borderTopWidth: width };
11
+ }
12
+ if (color === undefined) {
13
+ if (isBorderStyle(width)) {
14
+ return {
15
+ borderTopStyle: width,
16
+ borderTopColor: style,
17
+ };
18
+ }
19
+ return {
20
+ borderTopWidth: width,
21
+ borderTopStyle: style,
22
+ };
23
+ }
24
+ return {
25
+ borderTopWidth: width,
26
+ borderTopStyle: style,
27
+ borderTopColor: color,
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function borderWidth(top: CSSValue, right?: CSSValue, bottom?: CSSValue, left?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function borderWidth(top, right = top, bottom = top, left = right) {
2
+ return {
3
+ borderTopWidth: top,
4
+ borderRightWidth: right,
5
+ borderBottomWidth: bottom,
6
+ borderLeftWidth: left,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function flex(grow: CSSValue, shrinkOrBasis?: CSSValue, basis?: CSSValue): CSSProperties;
@@ -0,0 +1,49 @@
1
+ const WIDTH_KEYWORDS = ['max-content', 'min-content', 'fit-content', 'content'];
2
+ function isUnitless(value) {
3
+ return typeof value === 'number' || (typeof value === 'string' && /^[0-9.]+$/.test(value));
4
+ }
5
+ function isWidth(value) {
6
+ if (typeof value === 'number')
7
+ return false;
8
+ if (typeof value === 'string') {
9
+ if (WIDTH_KEYWORDS.includes(value))
10
+ return true;
11
+ if (/^[0-9.]+(%|px|em|rem|vh|vw|ch|ex|cm|mm|in|pt|pc|vmin|vmax)$/.test(value))
12
+ return true;
13
+ }
14
+ return false;
15
+ }
16
+ export function flex(grow, shrinkOrBasis, basis) {
17
+ // Single value
18
+ if (shrinkOrBasis === undefined && basis === undefined) {
19
+ if (grow === 'initial') {
20
+ return { flexGrow: 0, flexShrink: 1, flexBasis: 'auto' };
21
+ }
22
+ if (grow === 'auto') {
23
+ return { flexGrow: 1, flexShrink: 1, flexBasis: 'auto' };
24
+ }
25
+ if (grow === 'none') {
26
+ return { flexGrow: 0, flexShrink: 0, flexBasis: 'auto' };
27
+ }
28
+ if (isUnitless(grow)) {
29
+ return { flexGrow: grow, flexShrink: 1, flexBasis: 0 };
30
+ }
31
+ if (isWidth(grow)) {
32
+ return { flexGrow: 1, flexShrink: 1, flexBasis: grow };
33
+ }
34
+ return { flexGrow: grow };
35
+ }
36
+ // Two values
37
+ if (basis === undefined) {
38
+ if (isUnitless(shrinkOrBasis)) {
39
+ return { flexGrow: grow, flexShrink: shrinkOrBasis };
40
+ }
41
+ return { flexGrow: grow, flexShrink: 1, flexBasis: shrinkOrBasis };
42
+ }
43
+ // Three values
44
+ return {
45
+ flexGrow: grow,
46
+ flexShrink: shrinkOrBasis,
47
+ flexBasis: basis,
48
+ };
49
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function gap(columnGap: CSSValue, rowGap?: CSSValue): CSSProperties;
@@ -0,0 +1,6 @@
1
+ export function gap(columnGap, rowGap = columnGap) {
2
+ return {
3
+ columnGap,
4
+ rowGap,
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function gridArea(rowStart: CSSValue, columnStart?: CSSValue, rowEnd?: CSSValue, columnEnd?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function gridArea(rowStart, columnStart, rowEnd, columnEnd) {
2
+ return {
3
+ gridRowStart: rowStart,
4
+ gridColumnStart: columnStart ?? rowStart,
5
+ gridRowEnd: rowEnd ?? rowStart,
6
+ gridColumnEnd: columnEnd ?? (columnStart ?? rowStart),
7
+ };
8
+ }
@@ -1 +1,23 @@
1
+ export { border } from './border';
2
+ export { borderTop } from './borderTop';
3
+ export { borderRight } from './borderRight';
4
+ export { borderBottom } from './borderBottom';
5
+ export { borderLeft } from './borderLeft';
1
6
  export { borderColor } from './borderColor';
7
+ export { borderStyle } from './borderStyle';
8
+ export { borderWidth } from './borderWidth';
9
+ export { borderRadius } from './borderRadius';
10
+ export { flex } from './flex';
11
+ export { gap } from './gap';
12
+ export { gridArea } from './gridArea';
13
+ export { inset } from './inset';
14
+ export { margin } from './margin';
15
+ export { marginBlock } from './marginBlock';
16
+ export { marginInline } from './marginInline';
17
+ export { outline } from './outline';
18
+ export { overflow } from './overflow';
19
+ export { padding } from './padding';
20
+ export { paddingBlock } from './paddingBlock';
21
+ export { paddingInline } from './paddingInline';
22
+ export { textDecoration } from './textDecoration';
23
+ export { transition } from './transition';
@@ -1 +1,23 @@
1
+ export { border } from './border';
2
+ export { borderTop } from './borderTop';
3
+ export { borderRight } from './borderRight';
4
+ export { borderBottom } from './borderBottom';
5
+ export { borderLeft } from './borderLeft';
1
6
  export { borderColor } from './borderColor';
7
+ export { borderStyle } from './borderStyle';
8
+ export { borderWidth } from './borderWidth';
9
+ export { borderRadius } from './borderRadius';
10
+ export { flex } from './flex';
11
+ export { gap } from './gap';
12
+ export { gridArea } from './gridArea';
13
+ export { inset } from './inset';
14
+ export { margin } from './margin';
15
+ export { marginBlock } from './marginBlock';
16
+ export { marginInline } from './marginInline';
17
+ export { outline } from './outline';
18
+ export { overflow } from './overflow';
19
+ export { padding } from './padding';
20
+ export { paddingBlock } from './paddingBlock';
21
+ export { paddingInline } from './paddingInline';
22
+ export { textDecoration } from './textDecoration';
23
+ export { transition } from './transition';
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function inset(top: CSSValue, right?: CSSValue, bottom?: CSSValue, left?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function inset(top, right = top, bottom = top, left = right) {
2
+ return {
3
+ top,
4
+ right,
5
+ bottom,
6
+ left,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function margin(top: CSSValue, right?: CSSValue, bottom?: CSSValue, left?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function margin(top, right = top, bottom = top, left = right) {
2
+ return {
3
+ marginTop: top,
4
+ marginRight: right,
5
+ marginBottom: bottom,
6
+ marginLeft: left,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function marginBlock(start: CSSValue, end?: CSSValue): CSSProperties;
@@ -0,0 +1,6 @@
1
+ export function marginBlock(start, end = start) {
2
+ return {
3
+ marginBlockStart: start,
4
+ marginBlockEnd: end,
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function marginInline(start: CSSValue, end?: CSSValue): CSSProperties;
@@ -0,0 +1,6 @@
1
+ export function marginInline(start, end = start) {
2
+ return {
3
+ marginInlineStart: start,
4
+ marginInlineEnd: end,
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function outline(outlineWidth: CSSValue, outlineStyle?: CSSValue, outlineColor?: CSSValue): CSSProperties;
@@ -0,0 +1,7 @@
1
+ export function outline(outlineWidth, outlineStyle, outlineColor) {
2
+ return {
3
+ outlineWidth,
4
+ ...(outlineStyle !== undefined && { outlineStyle }),
5
+ ...(outlineColor !== undefined && { outlineColor }),
6
+ };
7
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function overflow(overflowX: CSSValue, overflowY?: CSSValue): CSSProperties;
@@ -0,0 +1,6 @@
1
+ export function overflow(overflowX, overflowY = overflowX) {
2
+ return {
3
+ overflowX,
4
+ overflowY,
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function padding(top: CSSValue, right?: CSSValue, bottom?: CSSValue, left?: CSSValue): CSSProperties;
@@ -0,0 +1,8 @@
1
+ export function padding(top, right = top, bottom = top, left = right) {
2
+ return {
3
+ paddingTop: top,
4
+ paddingRight: right,
5
+ paddingBottom: bottom,
6
+ paddingLeft: left,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function paddingBlock(start: CSSValue, end?: CSSValue): CSSProperties;
@@ -0,0 +1,6 @@
1
+ export function paddingBlock(start, end = start) {
2
+ return {
3
+ paddingBlockStart: start,
4
+ paddingBlockEnd: end,
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function paddingInline(start: CSSValue, end?: CSSValue): CSSProperties;
@@ -0,0 +1,6 @@
1
+ export function paddingInline(start, end = start) {
2
+ return {
3
+ paddingInlineStart: start,
4
+ paddingInlineEnd: end,
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ export declare function textDecoration(line: CSSValue, style?: CSSValue, color?: CSSValue, thickness?: CSSValue): CSSProperties;
@@ -0,0 +1,23 @@
1
+ const TEXT_DECORATION_STYLES = ['dashed', 'dotted', 'double', 'solid', 'wavy'];
2
+ function isTextDecorationStyle(value) {
3
+ return typeof value === 'string' && TEXT_DECORATION_STYLES.includes(value);
4
+ }
5
+ export function textDecoration(line, style, color, thickness) {
6
+ // Handle case where first arg is a style (for backward compat)
7
+ if (style === undefined && isTextDecorationStyle(line)) {
8
+ return { textDecorationStyle: line };
9
+ }
10
+ const result = {
11
+ textDecorationLine: line,
12
+ };
13
+ if (style !== undefined) {
14
+ result.textDecorationStyle = style;
15
+ }
16
+ if (color !== undefined) {
17
+ result.textDecorationColor = color;
18
+ }
19
+ if (thickness !== undefined) {
20
+ result.textDecorationThickness = thickness;
21
+ }
22
+ return result;
23
+ }
@@ -0,0 +1,4 @@
1
+ import { CSSValue, CSSProperties } from '../types';
2
+ type TransitionInput = [CSSValue, CSSValue?, CSSValue?, CSSValue?];
3
+ export declare function transition(...args: TransitionInput[] | [CSSValue]): CSSProperties;
4
+ export {};
@@ -0,0 +1,37 @@
1
+ const GLOBAL_VALUES = ['inherit', 'initial', 'revert', 'revert-layer', 'unset'];
2
+ function isGlobalValue(value) {
3
+ return typeof value === 'string' && GLOBAL_VALUES.includes(value);
4
+ }
5
+ export function transition(...args) {
6
+ // Handle global values
7
+ if (args.length === 1 && !Array.isArray(args[0]) && isGlobalValue(args[0])) {
8
+ const value = args[0];
9
+ return {
10
+ transitionProperty: value,
11
+ transitionDuration: value,
12
+ transitionDelay: value,
13
+ transitionTimingFunction: value,
14
+ };
15
+ }
16
+ // Normalize inputs
17
+ const transitions = Array.isArray(args[0])
18
+ ? args
19
+ : [args];
20
+ const properties = [];
21
+ const durations = [];
22
+ const delays = [];
23
+ const timings = [];
24
+ for (const t of transitions) {
25
+ const [property, duration = '0s', delay = '0s', timing = 'ease'] = t;
26
+ properties.push(property);
27
+ durations.push(duration);
28
+ delays.push(delay);
29
+ timings.push(timing);
30
+ }
31
+ return {
32
+ transitionProperty: properties.join(', '),
33
+ transitionDuration: durations.join(', '),
34
+ transitionDelay: delays.join(', '),
35
+ transitionTimingFunction: timings.join(', '),
36
+ };
37
+ }
package/dist/types.d.ts CHANGED
@@ -30,16 +30,36 @@ export interface CSSProperties {
30
30
  gridTemplateRows?: CSSValue;
31
31
  gridColumn?: CSSValue;
32
32
  gridRow?: CSSValue;
33
+ gridArea?: CSSValue;
34
+ gridRowStart?: CSSValue;
35
+ gridRowEnd?: CSSValue;
36
+ gridColumnStart?: CSSValue;
37
+ gridColumnEnd?: CSSValue;
38
+ columnGap?: CSSValue;
39
+ rowGap?: CSSValue;
33
40
  margin?: CSSValue;
34
41
  marginTop?: CSSValue;
35
42
  marginRight?: CSSValue;
36
43
  marginBottom?: CSSValue;
37
44
  marginLeft?: CSSValue;
45
+ marginBlock?: CSSValue;
46
+ marginBlockStart?: CSSValue;
47
+ marginBlockEnd?: CSSValue;
48
+ marginInline?: CSSValue;
49
+ marginInlineStart?: CSSValue;
50
+ marginInlineEnd?: CSSValue;
38
51
  padding?: CSSValue;
39
52
  paddingTop?: CSSValue;
40
53
  paddingRight?: CSSValue;
41
54
  paddingBottom?: CSSValue;
42
55
  paddingLeft?: CSSValue;
56
+ paddingBlock?: CSSValue;
57
+ paddingBlockStart?: CSSValue;
58
+ paddingBlockEnd?: CSSValue;
59
+ paddingInline?: CSSValue;
60
+ paddingInlineStart?: CSSValue;
61
+ paddingInlineEnd?: CSSValue;
62
+ inset?: CSSValue;
43
63
  color?: CSSValue;
44
64
  fontSize?: CSSValue;
45
65
  fontWeight?: CSSValue;
@@ -48,6 +68,9 @@ export interface CSSProperties {
48
68
  textAlign?: CSSValue;
49
69
  textDecoration?: CSSValue;
50
70
  textDecorationLine?: CSSValue;
71
+ textDecorationStyle?: CSSValue;
72
+ textDecorationColor?: CSSValue;
73
+ textDecorationThickness?: CSSValue;
51
74
  textTransform?: CSSValue;
52
75
  letterSpacing?: CSSValue;
53
76
  background?: CSSValue;
@@ -69,8 +92,23 @@ export interface CSSProperties {
69
92
  borderRightColor?: CSSValue;
70
93
  borderBottomColor?: CSSValue;
71
94
  borderLeftColor?: CSSValue;
95
+ borderTopWidth?: CSSValue;
96
+ borderRightWidth?: CSSValue;
97
+ borderBottomWidth?: CSSValue;
98
+ borderLeftWidth?: CSSValue;
99
+ borderTopStyle?: CSSValue;
100
+ borderRightStyle?: CSSValue;
101
+ borderBottomStyle?: CSSValue;
102
+ borderLeftStyle?: CSSValue;
103
+ borderTopLeftRadius?: CSSValue;
104
+ borderTopRightRadius?: CSSValue;
105
+ borderBottomRightRadius?: CSSValue;
106
+ borderBottomLeftRadius?: CSSValue;
72
107
  opacity?: CSSValue;
108
+ outline?: CSSValue;
109
+ outlineWidth?: CSSValue;
73
110
  outlineStyle?: CSSValue;
111
+ outlineColor?: CSSValue;
74
112
  boxShadow?: CSSValue;
75
113
  transform?: CSSValue;
76
114
  transition?: CSSValue;
@@ -117,15 +155,23 @@ export interface CSSPseudos {
117
155
  [key: `${':' | '::'}${string}`]: CSSProperties | undefined;
118
156
  }
119
157
  export interface CSSMediaQueries {
120
- '@media (min-width: 480px)'?: CSSProperties & CSSPseudos;
121
- '@media (min-width: 768px)'?: CSSProperties & CSSPseudos;
122
- '@media (min-width: 1024px)'?: CSSProperties & CSSPseudos;
123
- '@media (min-width: 1440px)'?: CSSProperties & CSSPseudos;
124
- '@media (prefers-color-scheme: dark)'?: CSSProperties & CSSPseudos;
125
- '@media (prefers-reduced-motion: reduce)'?: CSSProperties & CSSPseudos;
126
- [key: `@media ${string}`]: (CSSProperties & CSSPseudos) | undefined;
158
+ '@media (min-width: 480px)'?: CSSProperties & CSSPseudos & CSSCombinators;
159
+ '@media (min-width: 768px)'?: CSSProperties & CSSPseudos & CSSCombinators;
160
+ '@media (min-width: 1024px)'?: CSSProperties & CSSPseudos & CSSCombinators;
161
+ '@media (min-width: 1440px)'?: CSSProperties & CSSPseudos & CSSCombinators;
162
+ '@media (prefers-color-scheme: dark)'?: CSSProperties & CSSPseudos & CSSCombinators;
163
+ '@media (prefers-reduced-motion: reduce)'?: CSSProperties & CSSPseudos & CSSCombinators;
164
+ [key: `@media ${string}`]: (CSSProperties & CSSPseudos & CSSCombinators) | undefined;
127
165
  }
128
- export type StyleRule = CSSProperties & CSSPseudos & CSSMediaQueries;
166
+ export interface CSSCombinators {
167
+ '& > *'?: CSSProperties;
168
+ '& > *:first-child'?: CSSProperties;
169
+ '& > *:last-child'?: CSSProperties;
170
+ '& + *'?: CSSProperties;
171
+ '& ~ *'?: CSSProperties;
172
+ [key: `& ${string}`]: CSSProperties | undefined;
173
+ }
174
+ export type StyleRule = CSSProperties & CSSPseudos & CSSMediaQueries & CSSCombinators;
129
175
  export type StyleDefinition = StyleRule | (() => StyleRule);
130
176
  export declare enum StyleBucket {
131
177
  RESET = "d",
@@ -167,3 +213,18 @@ export type MakeStylesFunction = () => GeneratedClasses;
167
213
  export interface StyleSlots {
168
214
  [slotName: string]: StyleDefinition;
169
215
  }
216
+ export interface FontFaceDefinition {
217
+ fontFamily: string;
218
+ src: string;
219
+ fontWeight?: CSSValue;
220
+ fontStyle?: 'normal' | 'italic' | 'oblique' | string;
221
+ fontDisplay?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
222
+ unicodeRange?: string;
223
+ fontStretch?: CSSValue;
224
+ fontVariant?: CSSValue;
225
+ fontFeatureSettings?: string;
226
+ fontVariationSettings?: string;
227
+ ascentOverride?: string;
228
+ descentOverride?: string;
229
+ lineGapOverride?: string;
230
+ }
@@ -1,3 +1,4 @@
1
1
  export declare function camelToKebab(str: string): string;
2
2
  export declare function isPseudoSelector(key: string): boolean;
3
3
  export declare function isMediaQuery(key: string): boolean;
4
+ export declare function isCombinator(key: string): boolean;
package/dist/utils/css.js CHANGED
@@ -7,3 +7,6 @@ export function isPseudoSelector(key) {
7
7
  export function isMediaQuery(key) {
8
8
  return key.startsWith('@media');
9
9
  }
10
+ export function isCombinator(key) {
11
+ return key.startsWith('& ');
12
+ }
@@ -1,3 +1,3 @@
1
1
  export { hashString } from './hash';
2
- export { camelToKebab, isPseudoSelector, isMediaQuery } from './css';
2
+ export { camelToKebab, isPseudoSelector, isMediaQuery, isCombinator } from './css';
3
3
  export { determineBucket } from './bucket';
@@ -1,3 +1,3 @@
1
1
  export { hashString } from './hash';
2
- export { camelToKebab, isPseudoSelector, isMediaQuery } from './css';
2
+ export { camelToKebab, isPseudoSelector, isMediaQuery, isCombinator } from './css';
3
3
  export { determineBucket } from './bucket';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-engine-test-pb",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",