Skip to content

Commit f7c4534

Browse files
committed
feat: opacity shorthand
1 parent 75121f8 commit f7c4534

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

packages/typewind/src/babel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ try {
5353
throw new Error(\`Error in evaluating typewind expression: ${code.replace(
5454
'`',
5555
'\\`'
56-
)}\`)
56+
)}. \${error}\`)
5757
}
5858
`,
5959
true

packages/typewind/src/cli.ts

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function createDoc(doc: string) {
3333
}
3434
}
3535

36-
const fmtToTypewind = (s: string) => s.replace(/-/g, '_').replace(/\@/, '$');
36+
const fmtToTypewind = (s: string) => s.replace(/-/g, '_').replace(/^\@/, '$');
3737

3838
const objectTemplate = (
3939
props: [prop: string, type: string, doc?: string][]
@@ -62,10 +62,15 @@ const rootTypeTemplate = (
6262
6363
${others.join('\n')}
6464
65+
type OpacityMap = {
66+
[K in Opacity]: Property;
67+
} & Record<string, Property>;
68+
type Colors = {
69+
[K in {} as \`\${_Colors}\`]: OpacityMap
70+
}
71+
6572
type Typewind = ${types.join(' & ')} & {
66-
${modifiers
67-
.map((variant) => `${variant}(style: Property): Property`)
68-
.join(';')}
73+
${modifiers.map(variant => `${variant}(style: Property): Property`).join(';')}
6974
} & {
7075
[arbitraryVariant: string]: (style: Property) => Property;
7176
} & {
@@ -103,18 +108,40 @@ export async function generateTypes() {
103108
s => !s.startsWith('-')
104109
);
105110

111+
const opacityMap = ctx.tailwindConfig.theme.opacity;
112+
106113
const classesWithStandardSyntax = classList.filter(s => !/\.|\//.test(s));
114+
const classesWithCandidateItem = classesWithStandardSyntax.map(s => {
115+
return [s, getCandidateItem(ctx.candidateRuleMap, s)] as const;
116+
});
117+
118+
const colorSet = new Set<string>();
107119
const standard = typeTemplate(
108120
'Standard',
109-
classesWithStandardSyntax.map(s => {
110-
let { rule: rules, rest } = getCandidateItem(ctx.candidateRuleMap, s);
121+
classesWithCandidateItem.map(([s, { rule: rules, rest }]) => {
111122
let css = '';
112123

113124
if (rules) {
114125
for (const rule of rules) {
115-
const [_info, ruleOrFn] = rule;
126+
const [info, ruleOrFn] = rule;
116127

117128
if (typeof ruleOrFn === 'function') {
129+
const types = info.options.types;
130+
const isColor = types.some(
131+
(t: Record<string, string>) => t.type == 'color'
132+
);
133+
134+
if (isColor) {
135+
if (rest) {
136+
const key = fmtToTypewind(s) + '$';
137+
138+
colorSet.add(key);
139+
for (const opacity in opacityMap) {
140+
// colorSet.add(key + opacity);
141+
}
142+
}
143+
}
144+
118145
const [ruleSet] = ruleOrFn(rest ?? 'DEFAULT', {});
119146
if (ruleSet) {
120147
css += fmtRuleToCss(ruleSet);
@@ -129,6 +156,10 @@ export async function generateTypes() {
129156
return [fmtToTypewind(s), 'Property', css];
130157
})
131158
);
159+
// const colorTemplate = typeTemplate(
160+
// '_Colors',
161+
// [...colorSet].map(color => [color, 'Property'])
162+
// );
132163
const candidates = [...ctx.candidateRuleMap.entries()];
133164
const arbitraryStyles: [string, string, string?][] = [];
134165
for (const [name, rules] of candidates) {
@@ -158,18 +189,26 @@ export async function generateTypes() {
158189
const arbitrary = typeTemplate('Arbitrary', arbitraryStyles);
159190

160191
const variants = `type Variants = ${[...ctx.variantMap.keys()]
161-
.map((variant) => `'${variant}'`)
192+
.map(variant => `'${variant}'`)
162193
.join(' | ')};`;
163194
164-
const modifiers = [...ctx.variantMap.keys(), 'important'].map((s) => {
195+
const modifiers = [...ctx.variantMap.keys(), 'important'].map(s => {
165196
s = /^\d/.test(s) ? `_${s}` : s;
166197
167198
return fmtToTypewind(s);
168199
});
169200
170201
const root = rootTypeTemplate(
171-
[variants, standard, arbitrary],
172-
['Standard', 'Arbitrary'],
202+
[
203+
variants,
204+
standard,
205+
arbitrary,
206+
`type _Colors = ${[...colorSet].map(k => JSON.stringify(k)).join(' | ')}`,
207+
`type Opacity = ${Object.keys(opacityMap)
208+
.map(k => JSON.stringify(k))
209+
.join(' | ')}`,
210+
],
211+
['Standard', 'Arbitrary', 'Variants', 'Colors'],
173212
modifiers
174213
);
175214

packages/typewind/src/evaluate.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ function fmtArbitraryRule(name: string, value: string, candidateRuleMap: any) {
1919
return classes.join(' ');
2020
}
2121

22-
const fmtToTailwind = (s: string) => s.replace(/_/g, '-').replace(/\$/, '@');
22+
const fmtToTailwind = (s: string) =>
23+
s.replace(/_/g, '-').replace(/^\$/, '@').replace(/\$/, '/');
2324

2425
export const createTw: any = () => {
2526
const twUsed = (classes = new Set<string>()) => {
@@ -50,7 +51,9 @@ export const createTw: any = () => {
5051
target.classes.add(
5152
fmtArbitraryRule(target.prevProp.slice(0, -1), p, candidateRuleMap)
5253
);
53-
} else if (!name.endsWith('-')) {
54+
} else if (target.prevProp?.endsWith('/')) {
55+
target.classes.add(`${target.prevProp}${name}`);
56+
} else if (!name.endsWith('-') && !name.endsWith('/')) {
5457
if (!classList.includes(name)) {
5558
const prefix =
5659
name === 'important'

0 commit comments

Comments
 (0)