Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "minor",
"comment": "makeStyles: finish up keyframes implementation",
"packageName": "@fluentui/make-styles",
"email": "xgao@microsoft.com",
"dependentChangeType": "patch",
"date": "2021-02-02T04:10:06.714Z"
}
21 changes: 21 additions & 0 deletions packages/make-styles/src/makeStyles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,25 @@ describe('makeStyles', () => {
const computeClasses = makeStyles([[null, { color: 'red', position: 'absolute' }]]);
expect(computeClasses({}, { renderer, tokens: {} })).toBe('__1fslksb fe3e8s90 f1euv43f');
});

it('handles RTL for keyframes', () => {
const computeClasses = makeStyles([
[
null,
{
animationName: {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
animationIterationCount: 'infinite',
animationDuration: '5s',
},
],
]);
expect(computeClasses({}, { renderer, tokens: {}, rtl: true })).toBe('__la4fka0 rfkf6eed0 f1cpbl36 f1t9cprh');
});
});
13 changes: 8 additions & 5 deletions packages/make-styles/src/renderer/createDOMRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,22 @@ export function createDOMRenderer(targetDocument: Document = document): MakeStyl
const className = definition[0];
const rtlCSS = definition[2];

const ruleClassName = rtl ? (rtlCSS ? RTL_PREFIX + className : className) : className;
const ruleClassName = className && (rtl && rtlCSS ? RTL_PREFIX + className : className);

// Should be done always to return classes
classes += ruleClassName + ' ';
if (ruleClassName) {
// Should be done always to return classes even if they have been already inserted to DOM
classes += ruleClassName + ' ';
}

if (renderer.insertionCache[ruleClassName]) {
const cacheKey = ruleClassName || propName;
if (renderer.insertionCache[cacheKey]) {
continue;
}

const css = definition[1];
const ruleCSS = rtl ? rtlCSS || css : css;

renderer.insertionCache[ruleClassName] = true;
renderer.insertionCache[cacheKey] = true;

(renderer.styleElement.sheet as CSSStyleSheet).insertRule(ruleCSS, renderer.index);
renderer.index++;
Expand Down
6 changes: 6 additions & 0 deletions packages/make-styles/src/runtime/compileKeyframeRule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { hyphenateProperty } from './utils/hyphenateProperty';
import { MakeStyles } from '../types';
import { compile, middleware, serialize, stringify, prefixer } from 'stylis';

/* eslint-disable guard-for-in */

Expand Down Expand Up @@ -34,3 +35,8 @@ export function compileKeyframeRule(frames: MakeStyles): string {

return css;
}

export function compileKeyframesCSS(animationName: string, framesCSS: string): string {
const cssRule = `@keyframes ${animationName} {${framesCSS}}`;
return serialize(compile(cssRule), middleware([prefixer, stringify]));
}
227 changes: 206 additions & 21 deletions packages/make-styles/src/runtime/resolveStyleRules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ expect.addSnapshotSerializer({
});

function getFirstClassName(resolvedStyles: Record<string, MakeStylesResolvedRule>): string {
return resolvedStyles[Object.keys(resolvedStyles)[0]][0];
return resolvedStyles[Object.keys(resolvedStyles)[0]][0] as string;
}

describe('resolveStyleRules', () => {
Expand Down Expand Up @@ -367,32 +367,17 @@ describe('resolveStyleRules', () => {
});
});

describe('experimental', () => {
it('allows to define keyframes', () => {
describe('keyframes', () => {
it('allows to define string as animationName', () => {
expect(
resolveStyleRules({
animationName: {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
animationName: 'fade-in slide-out',
animationIterationCount: 'infinite',
animationDuration: '5s',
}),
).toMatchInlineSnapshot(`
@keyframes f13owpa8 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.fkf6eed0 {
animation-name: f13owpa8;
.fc59ano0 {
animation-name: fade-in slide-out;
}
.f1cpbl36 {
animation-iteration-count: infinite;
Expand All @@ -403,6 +388,206 @@ describe('resolveStyleRules', () => {
`);
});

it('allows to define object as animationName', () => {
expect(
resolveStyleRules({
animationName: {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
animationIterationCount: 'infinite',
animationDuration: '5s',
}),
).toMatchInlineSnapshot(`
@-webkit-keyframes f13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes f13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes rf13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(-360deg);
-moz-transform: rotate(-360deg);
-ms-transform: rotate(-360deg);
transform: rotate(-360deg);
}
}
@keyframes rf13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(-360deg);
-moz-transform: rotate(-360deg);
-ms-transform: rotate(-360deg);
transform: rotate(-360deg);
}
}
.fkf6eed0 {
animation-name: f13owpa8;
}
.rfkf6eed0 {
animation-name: rf13owpa8;
}
.f1cpbl36 {
animation-iteration-count: infinite;
}
.f1t9cprh {
animation-duration: 5s;
}
`);
});

it('allows to define array as animationName', () => {
expect(
resolveStyleRules({
animationName: [
{
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
{
from: {
opacity: 0,
},
to: {
opacity: 1,
},
},
],
animationIterationCount: 'infinite',
animationDuration: '5s',
}),
).toMatchInlineSnapshot(`
@-webkit-keyframes f13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes f13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes f1qa61cu {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes f1qa61cu {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes rf13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(-360deg);
-moz-transform: rotate(-360deg);
-ms-transform: rotate(-360deg);
transform: rotate(-360deg);
}
}
@keyframes rf13owpa8 {
from {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(-360deg);
-moz-transform: rotate(-360deg);
-ms-transform: rotate(-360deg);
transform: rotate(-360deg);
}
}
.f18gdskf {
animation-name: f13owpa8 f1qa61cu;
}
.rf18gdskf {
animation-name: rf13owpa8 f1qa61cu;
}
.f1cpbl36 {
animation-iteration-count: infinite;
}
.f1t9cprh {
animation-duration: 5s;
}
`);
});
});

describe('experimental', () => {
it('allows to increase specificity', () => {
expect(resolveStyleRules({ color: 'red' }, 1)).toMatchInlineSnapshot(`
.fe3e8s901.fe3e8s901 {
Expand Down
Loading