Función mejor escrita para generar consultas de medios

8

Estoy siguiendo junto con esta publicación: https://medium.com/@samuelresua/easy-media-queries-in-styled-components-690b78f50053

He creado lo siguiente en Typecript, pero he tenido que recurrir a escribir anymás de lo que tengo que estar seguro:

const breakpoints: ObjectMap<number> = {
  small: 767,
  medium: 992,
  large: 1200,
  extraLarge: 1240
};

export const media = Object.keys(breakpoints).reduce((acc: { [key: string]: (...args: any) => any }, label) => {
  acc[label] = (...args) => css`
     @media (min-width: ${breakpoints[label]}px) {
        ${css(...args as [any])};
     }
  `;
  return acc;
}, {});

Como resultado, no tengo ayuda en mi IDE cuando escribo estilos en mis bloques de consulta de medios:

styled.button<Props>`
  background: red; /* this must be a valid style */
  ${({ theme }) => theme.media.large`
      background: blue;
      foo: bar; /* this isn't caught */
   `

¿Alguien sabe cómo puedo mejorar mi mediafunción?

Señor épico
fuente

Respuestas:

0

styled-componentsle permite usar objetos para propiedades CSS, así como cadenas de plantillas, y el compilador TypeScript comprende mucho mejor los objetos. Prueba esto:

const breakpoints: ObjectMap<number> = {
  small: 767,
  medium: 992,
  large: 1200,
  extraLarge: 1240
};

export const media = (size: keyof typeof breakpoints, properties: CSSObject) => ({[`@media (min-width: ${breakpoints[size]})`]: properties});

const MyButton = styled.button<Props>(({ theme }) => ({
  background: red, // this must be a valid style
  ...theme.media('large', {
    background: blue // this is also validated :)
  })
}));
Robert Moore
fuente
5

Creo que no es un problema de TypeScript, sino un problema del complemento IntelliSense.

Desde la perspectiva de TypeScript, el contenido entre los backticks es de tipo TemplateStringsArray. TypeScript no conoce las propiedades válidas de CSS, ya que ve una serie de cadenas.

Creo que la validación se realiza a nivel de plugin por typecript-styled-plugin .

Ver https://github.com/styled-components/vscode-styled-components/pull/41

Enviaría una solicitud de función o informe de error aquí .

sunknudsen
fuente
Todavía me gustaría mejorar mi consulta de medios si es posible ... ¡Pero gracias por el aporte!
Señor Epic
Esperemos y veamos si mi suposición es incorrecta y otros tienen una solución. Mientras tanto, acabo de notar que la validación de CSS no parece funcionar para los estilos dentro de las reglas at @media CSS que potencialmente confirman esta limitación del complemento IntelliSense.
sunknudsen
1
Acabo de enviar un informe de error. github.com/microsoft/typescript-styled-plugin/issues/113
sunknudsen
1

Si entiendo correctamente, quieres deshacerte de él any.

Así es como puedes hacerlo:

import {
  css,
  CSSObject,
  SimpleInterpolation,
  FlattenSimpleInterpolation,
} from 'styled-components';

type ObjectMap<T> = {[key: string]: T};

const breakpoints: ObjectMap<number> = {
  small: 767,
  medium: 992,
  large: 1200,
  extraLarge: 1240,
};

export const media = Object.keys(breakpoints).reduce(
  (
    acc: {
      [key: string]: (
        first: TemplateStringsArray | CSSObject,
        ...interpolations: SimpleInterpolation[]
      ) => FlattenSimpleInterpolation;
      // ^^^ this is the first implementation of  `BaseThemedCssFunction`
    },
    label
  ) => {
    acc[label] = (...args) => css`
      @media (min-width: ${breakpoints[label]}px) {
        ${css(...args)};
      }
    `;
    return acc;
  },
  {}
);
Maxim Mazurok
fuente