Skip to content

✨ feat: Support Animation #156

@mauroerta

Description

@mauroerta

🤔 Problem

Currently, Morfeo does not give any additional utilities regarding animations, the property animation is accepted by the resolve method but will be treated as a regular CSS property. Also, there is no way to generate @keyframes.

🚑 Solution

Prosal #1: animations theme's slice

Animations, just like colors, shadows, spacings, and so on... are part of the Design Language of any application, so they should be defined inside the theme.

To do it, we will need a new theme slice called animations, I think that a good way to do it could be the following:

type KeyFrameKey = `${number}%` | 'from' | 'to';

type KeyFrames = {
  [KeyFrameKey]: Style,
};

type Animation = Record<string, {
  delay?: number;
  fillMode?: 'none' | 'forwards' | 'backwards' | 'both' | 'initial' | 'inherit';
  duration?: number;
  direction?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' | 'initial' | 'inherit';
  keyframes: KeyFrames;
  timingFunction?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'step-start' | 'step-end' | `steps(${number}, ${'start' | 'end'})` | `steps(${number})` | `cubic-bezier(${number}, ${number}, ${number}, ${number})` | 'initial' | 'inherit';
  iterationCount?: number;
}>;

Then, of course, we will need a parser to parse the property animation based on theme configuration.
This parser, and also the definition of the slice, should be added to the package @morfeo/web.

Usage

Once defined, they can be probably easily used in the following way:

const classes = morfeo.css({
   container: {
      '&[aria-busy="true"]': {
           animation: 'loading'
       }
   }
})

Prosal #2: animations and keyframes as theme's slices

Similar to the first one but:
Instead of putting the keyframes inside the Animation type, we can create another slice called keyframes instead:

type KeyFrameKey = `${number}%` | 'from' | 'to';

- type KeyFrames = {
+ type KeyFrameConfig = {
  [KeyFrameKey]: Style,
};

+ type KeyFrames = Record<string, KeyFrameConfig>;
+ type KeyFrame = keyof KeyFrames;

type Animation = Record<string, {
  delay?: number;
  fillMode?: 'none' | 'forwards' | 'backwards' | 'both' | 'initial' | 'inherit';
  duration?: number;
  direction?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' | 'initial' | 'inherit';
-  keyframes: KeyFrames;
+  keyframes: KeyFrame;
  timingFunction?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'step-start' | 'step-end' | `steps(${number}, ${'start' | 'end'})` | `steps(${number})` | `cubic-bezier(${number}, ${number}, ${number}, ${number})` | 'initial' | 'inherit';
  iterationCount?: number;
}>;

This way we can also reuse the same keyframe in multiple animations.

Prosal #3: no theme's slice, new API

We can even think to completely change the approach and create a new API like morfeo.keyframes:

morfeo.keyframes({
   loading: {
        '0%': {
          bg: 'gray.dark'
        },
       '100%': {
          bg: 'gray.light'
        }
     } 
   }
});

const classes = morfeo.css({
   loader: {
      animation: 'loading'
   }
})

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions