Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass variables to keyframes #289

Open
paulm17 opened this issue Oct 27, 2024 · 1 comment
Open

Pass variables to keyframes #289

paulm17 opened this issue Oct 27, 2024 · 1 comment
Assignees
Labels
customization: theme Centered around the theming features status: waiting for maintainer These issues haven't been looked at yet by a maintainer

Comments

@paulm17
Copy link

paulm17 commented Oct 27, 2024

Summary

I have the following example.

import { css, keyframes } from "@pigment-css/react";

const thickness = "calc(var(--hash-size) / 5)";
const lat = `calc((var(--hash-size) - ${thickness}) / 2)`;
const offset = `calc(${lat} - ${thickness})`;

const hashLoaderBeforeAnimation = keyframes({
  "0%": {
    width: thickness,
    boxShadow: `${lat} ${-offset} var(--hash-color), ${-lat} ${offset} var(--hash-color)`,
  },
  "35%": {
    width: "var(--hash-size)",
    boxShadow: `0 ${-offset} var(--hash-color), 0 ${offset} var(--hash-color)`,
  },
  "70%": {
    width: "calc(var(--hash-size) / 5)",
    boxShadow: `${-lat} ${-offset} var(--hash-color), ${lat} ${offset} var(--hash-color)`,
  },
  "100%": {
    boxShadow: `${lat} ${-offset} var(--hash-color), ${-lat} ${offset} var(--hash-color)`,
  },
});

const hashLoaderAfterAnimation = keyframes({
  "0%": {
    width: thickness,
    boxShadow: `${offset}px ${lat}px var(--hash-color), ${-offset}px ${-lat}px var(--hash-color)`,
  },
  "35%": {
    width: "var(--hash-size)",
    boxShadow: `${offset}px 0 var(--hash-color), ${-offset}px 0 var(--hash-color)`,
  },
  "70%": {
    width: thickness,
    boxShadow: `${offset}px ${-lat}px var(--hash-color), ${-offset}px ${lat}px var(--hash-color)`,
  },
  "100%": {
    boxShadow: `${offset}px ${lat}px var(--hash-color), ${-offset}px ${-lat}px var(--hash-color)`,
  },
});

export const LoaderHashLoaderStyle = css({
  "--hash-size-xs": "18px",
  "--hash-size-sm": "22px",
  "--hash-size-md": "36px",
  "--hash-size-lg": "44px",
  "--hash-size-xl": "58px",
  "--hash-size": "var(--hash-size-md)",
  "--hash-color": "var(--raikou-primary-color-filled)",
  display: "inherit",
  position: "relative",
  width: "var(--hash-size)",
  height: "var(--hash-size)",
  transform: "rotate(165deg)",
});

const LoaderHashStyle = {
  position: "absolute",
  top: "50%",
  left: "50%",
  display: "block",
  width: "calc(var(--hash-size) / 5)",
  height: "calc(var(--hash-size) / 5)",
  borderRadius: "100%",
  transform: "translate(-50%, -50%)",
};

export const LoaderHash1Style = css({
  ...LoaderHashStyle,
  animation: `${hashLoaderBeforeAnimation} calc(2.1s / var(--hash-speed-multiplier)) infinite`,
});

export const LoaderHash2Style = css({
  ...LoaderHashStyle,
  animation: `${hashLoaderAfterAnimation} calc(2.1s / var(--hash-speed-multiplier)) infinite`,
});

When I view in devtools, none of the variables are defined. They are defined, but are styled to a parent div. Even putting the variables in a style on where the animation is defined. Still no joy.

Image

I have tried to use "variations" globalcss to define them:

globalCss`
  :root {
    --hash-size: 50;
  }
`;

Not sure how to solve this to tbh. How to marry a component creating a variable and having it accessible via the keyframes function? 🤔

Examples

No response

Motivation

I'm moving over react-spinners: react-spinners

I appreciate that this is a clientside app and some parts won't be as trivial to move over.

const thickness = value / 5;

const lat = (value - thickness) / 2;

const offset = lat - thickness;

const colorValue = calculateRgba(color, 0.75);

const before = createAnimation(
    "HashLoader",
    `0% {width: ${thickness}px; box-shadow: ${lat}px ${-offset}px ${colorValue}, ${-lat}px ${offset}px ${colorValue}}
    35% {width: ${cssValue(size)}; box-shadow: 0 ${-offset}px ${colorValue}, 0 ${offset}px ${colorValue}}
    70% {width: ${thickness}px; box-shadow: ${-lat}px ${-offset}px ${colorValue}, ${lat}px ${offset}px ${colorValue}}
    100% {box-shadow: ${lat}px ${-offset}px ${colorValue}, ${-lat}px ${offset}px ${colorValue}}`,
    "before"
  );

Search keywords: keyframes

@paulm17 paulm17 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 27, 2024
@zannager zannager added the customization: theme Centered around the theming features label Oct 28, 2024
@paulm17
Copy link
Author

paulm17 commented Oct 28, 2024

My issue here. Is that I am not colocating the keyframes and css with the main code. For readability, I'm putting all styles into it's own css.ts file. As this is a UI lib, I don't want too much code on the page.

That said, to resolve this fully. I found this SO answer.

Doing the following (in the required component) works:

const rawHTML = `
    <style scoped>
      @keyframes whisper-loader {
        0% { transform: scale(1, 1); opacity: 1; background-color: var(--whisper-color); }
        100% { transform: scale(0, 0); opacity: 0; background-color: var(--whisper-color); }
      }
    </style>
  `;

return (
    <Box ref={ref} {...others}>
      <div dangerouslySetInnerHTML={{ __html: rawHTML }} />
      ...
    </Box>
  );

This also means the above example where variables are interpolated like in the above example will be solved.

I'll leave the closing to a maintainer. I don't know if in future you'll want to do extend this functionality or not...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
customization: theme Centered around the theming features status: waiting for maintainer These issues haven't been looked at yet by a maintainer
Projects
None yet
Development

No branches or pull requests

3 participants