Skip to content

Commit b93f994

Browse files
committed
feat(parser): new style parser * 5
1 parent ded64db commit b93f994

File tree

5 files changed

+93
-34
lines changed

5 files changed

+93
-34
lines changed

src/parser/classify.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
VALUE_KEYWORDS,
77
} from './const';
88
import { StyleParser } from './parser';
9-
import { Bucket, ParserOptions, ProcessedStyle, StyleDetails } from './types';
9+
import { Bucket, ParserOptions, ProcessedStyle } from './types';
1010

1111
export function classify(
1212
raw: string,

src/parser/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const VALUE_KEYWORDS = new Set([
44
'max-content',
55
'min-content',
66
'fit-content',
7+
'stretch',
78
]);
89

910
export const COLOR_FUNCS = new Set([

src/parser/parser.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,17 @@ describe('StyleProcessor', () => {
5555

5656
test('parses value modifiers', () => {
5757
const result = parser.process(
58-
'none auto max-content min-content fit-content stretch',
58+
'none auto max-content min-content fit-content stretch space-between',
5959
);
6060
expect(result.groups[0].values).toEqual([
6161
'none',
6262
'auto',
6363
'max-content',
6464
'min-content',
6565
'fit-content',
66+
'stretch',
6667
]);
67-
expect(result.groups[0].mods).toEqual(['stretch']);
68+
expect(result.groups[0].mods).toEqual(['space-between']);
6869
});
6970

7071
test('parses modifiers', () => {

src/tasty/styles/dimension.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { heightStyle } from './height';
2+
import { widthStyle } from './width';
3+
4+
const { parseStyle } = require('../utils/styles');
5+
6+
describe('dimensionStyle – width & height helpers', () => {
7+
test('single value width', () => {
8+
const res = widthStyle({ width: '10x' }) as any;
9+
expect(res.width).toBe('calc(10 * var(--gap))');
10+
expect(res['min-width']).toBe('initial');
11+
expect(res['max-width']).toBe('initial');
12+
});
13+
14+
test('min & max width (two values)', () => {
15+
const res = widthStyle({ width: '1x 10x' }) as any;
16+
expect(res.width).toBe('auto');
17+
expect(res['min-width']).toBe('var(--gap)');
18+
expect(res['max-width']).toBe('calc(10 * var(--gap))');
19+
});
20+
21+
test('min modifier width', () => {
22+
const res = widthStyle({ width: 'min 2x' }) as any;
23+
expect(res.width).toBe('auto');
24+
expect(res['min-width']).toBe('calc(2 * var(--gap))');
25+
expect(res['max-width']).toBe('initial');
26+
});
27+
28+
test('max modifier width', () => {
29+
const res = widthStyle({ width: 'max 2x' }) as any;
30+
expect(res.width).toBe('auto');
31+
expect(res['min-width']).toBe('initial');
32+
expect(res['max-width']).toBe('calc(2 * var(--gap))');
33+
});
34+
35+
test('stretch width keyword', () => {
36+
const res = widthStyle({ width: 'stretch' }) as any;
37+
expect(res.width).toEqual([
38+
'stretch',
39+
'-webkit-fill-available',
40+
'-moz-available',
41+
]);
42+
});
43+
44+
test('boolean true width (auto)', () => {
45+
const res = widthStyle({ width: true }) as any;
46+
expect(res.width).toBe('auto');
47+
});
48+
49+
test('responsive array width', () => {
50+
const res = widthStyle({ width: '1x 2x' }) as any;
51+
expect(res.width).toBe('auto');
52+
expect(res['min-width']).toBe('var(--gap)');
53+
expect(res['max-width']).toBe('calc(2 * var(--gap))');
54+
});
55+
56+
test('single value height', () => {
57+
const res = heightStyle({ height: '100px' }) as any;
58+
expect(res.height).toBe('100px');
59+
expect(res['min-height']).toBe('initial');
60+
expect(res['max-height']).toBe('initial');
61+
});
62+
63+
test('min value height three args', () => {
64+
const res = heightStyle({ height: '1x 5x 10x' }) as any;
65+
expect(res.height).toBe('calc(5 * var(--gap))');
66+
expect(res['min-height']).toBe('var(--gap)');
67+
expect(res['max-height']).toBe('calc(10 * var(--gap))');
68+
});
69+
70+
test('boolean true height (auto)', () => {
71+
const res = heightStyle({ height: true }) as any;
72+
expect(res.height).toBe('auto');
73+
});
74+
});

src/tasty/styles/dimension.ts

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,21 @@
1-
import { parseStyle, transferMods } from '../utils/styles';
1+
import { parseStyle } from '../utils/styles';
22

33
const DEFAULT_MIN_SIZE = 'var(--gap)';
44
const DEFAULT_MAX_SIZE = '100%';
55

6-
function isSizingSupport(val) {
7-
return typeof CSS !== 'undefined' && typeof CSS?.supports === 'function'
8-
? CSS.supports('height', val)
9-
: false;
10-
}
11-
12-
const STRETCH = 'stretch';
13-
const FILL_AVAILABLE = 'fill-available';
14-
const WEBKIT_FILL_AVAILABLE = '-webkit-fill-available';
15-
const MOZ_FILL_AVAILABLE = '-moz-fill-available';
16-
const STRETCH_SIZE = isSizingSupport(STRETCH)
17-
? STRETCH
18-
: isSizingSupport(FILL_AVAILABLE)
19-
? FILL_AVAILABLE
20-
: isSizingSupport(WEBKIT_FILL_AVAILABLE)
21-
? WEBKIT_FILL_AVAILABLE
22-
: isSizingSupport(MOZ_FILL_AVAILABLE)
23-
? MOZ_FILL_AVAILABLE
24-
: null;
25-
const INTRINSIC_MODS = ['max-content', 'min-content', 'fit-content', 'stretch'];
26-
276
export function dimensionStyle(name) {
287
const minStyle = `min-${name}`;
298
const maxStyle = `max-${name}`;
309

3110
return (val) => {
11+
if (val === true) {
12+
return {
13+
[name]: 'auto',
14+
[minStyle]: 'initial',
15+
[maxStyle]: 'initial',
16+
};
17+
}
18+
3219
if (!val) return '';
3320

3421
if (typeof val === 'number') {
@@ -37,7 +24,7 @@ export function dimensionStyle(name) {
3724

3825
val = String(val);
3926

40-
const styles = {
27+
const styles: Record<string, string | string[]> = {
4128
[name]: 'auto',
4229
[minStyle]: 'initial',
4330
[maxStyle]: 'initial',
@@ -47,14 +34,6 @@ export function dimensionStyle(name) {
4734
const { mods, values } =
4835
processed.groups[0] ?? ({ mods: [], values: [] } as any);
4936

50-
transferMods(INTRINSIC_MODS, mods, values);
51-
52-
values.forEach((v, i) => {
53-
if (v === 'stretch') {
54-
values[i] = STRETCH_SIZE || (name === 'height' ? '100vh' : '100vw');
55-
}
56-
});
57-
5837
let flag = false;
5938

6039
for (let mod of mods) {
@@ -85,6 +64,10 @@ export function dimensionStyle(name) {
8564
}
8665
}
8766

67+
if (styles[name] === 'stretch') {
68+
styles[name] = ['stretch', '-webkit-fill-available', '-moz-available'];
69+
}
70+
8871
return styles;
8972
};
9073
}

0 commit comments

Comments
 (0)