Skip to content

Commit

Permalink
fix: creating keyframes inside defineVars (#315)
Browse files Browse the repository at this point in the history
* Docs: Fix code example typo (#290)

* Handle `keyframe` within `defineVars`

* Add test

* Format

* Fix grammar

* Update stylex-validation-define-vars-test.js

---------

Co-authored-by: k14lb3 <[email protected]>
  • Loading branch information
nedjulius and k14lb3 authored Jan 7, 2024
1 parent 68efd8d commit 80ef282
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
2 changes: 1 addition & 1 deletion apps/docs/docs/api/javascript/createTheme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function createTheme(

```ts
import * as stylex from '@stylexjs/stylex';
import {colors} from './vars.stylex.js';
import { colors } from './vars.stylex.js';

const theme = stylex.createTheme(colors, {
accentColor: 'red',
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/docs/api/javascript/defineVars.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ You must define your variables as named exports in a `.stylex.js` (or
```tsx title="vars.stylex.js"
import * as stylex from '@stylexjs/stylex';

const colors = stylex.defineVars({
export const colors = stylex.defineVars({
accent: 'blue',
background: 'white',
line: 'gray',
Expand All @@ -38,7 +38,7 @@ You can then import and use these variables in any `stylex.create` call.

```tsx
import * as stylex from '@stylexjs/stylex';
import {colors} from './vars.stylex.js';
import { colors } from './vars.stylex.js';

const styles = stylex.create({
container: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('@stylexjs/babel-plugin', () => {

/* Values */

test('values must be static number or string in stylex.defineVars()', () => {
test('values must be static number or string, or keyframes in stylex.defineVars()', () => {
// number
expect(() => {
transform(`
Expand All @@ -120,6 +120,18 @@ describe('@stylexjs/babel-plugin', () => {
});
`);
}).not.toThrow();
// keyframes
expect(() => {
transform(`
import stylex from 'stylex';
export const styles = stylex.defineVars({
fadeIn: stylex.keyframes({
'0%': { opacity: 0 },
'100%': { opacity: 1}
}),
});
`);
}).not.toThrow();
// not static
expect(() => {
transform(`
Expand Down
44 changes: 40 additions & 4 deletions packages/babel-plugin/src/visitors/stylex-define-vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
defineVars as stylexDefineVars,
messages,
utils,
keyframes as stylexKeyframes,
type InjectableStyle,
} from '@stylexjs/shared';
import { convertObjectToAST } from '../utils/js-to-ast';
import { evaluate, type FunctionConfig } from '../utils/evaluate-path';
Expand Down Expand Up @@ -71,8 +73,34 @@ export default function transformStyleXDefineVars(
> = callExpressionPath.get('arguments');
const firstArg = args[0];

const injectedKeyframes: { [animationName: string]: InjectableStyle } = {};

// eslint-disable-next-line no-inner-declarations
function keyframes<
Obj: {
+[key: string]: { +[k: string]: string | number },
},
>(animation: Obj): string {
const [animationName, injectedStyle] = stylexKeyframes(
animation,
state.options,
);
injectedKeyframes[animationName] = injectedStyle;
return animationName;
}

const identifiers: FunctionConfig['identifiers'] = {};
const memberExpressions: FunctionConfig['memberExpressions'] = {};
state.stylexKeyframesImport.forEach((name) => {
identifiers[name] = { fn: keyframes };
});
state.stylexImport.forEach((name) => {
if (memberExpressions[name] === undefined) {
memberExpressions[name] = {};
}

memberExpressions[name].keyframes = { fn: keyframes };
});

const { confident, value } = evaluate(firstArg, state, {
identifiers,
Expand All @@ -92,10 +120,18 @@ export default function transformStyleXDefineVars(

const exportName = varId.name;

const [variablesObj, injectedStyles] = stylexDefineVars(value, {
...state.options,
themeName: utils.genFileBasedIdentifier({ fileName, exportName }),
});
const [variablesObj, injectedStylesSansKeyframes] = stylexDefineVars(
value,
{
...state.options,
themeName: utils.genFileBasedIdentifier({ fileName, exportName }),
},
);

const injectedStyles = {
...injectedKeyframes,
...injectedStylesSansKeyframes,
};

// This should be a transformed variables object
callExpressionPath.replaceWith(convertObjectToAST(variablesObj));
Expand Down

0 comments on commit 80ef282

Please sign in to comment.