Melhor função digitada para gerar consultas de mídia

8

Estou acompanhando este post: https://medium.com/@samuelresua/easy-media-queries-in-styled-components-690b78f50053

Eu criei o seguinte no texto datilografado, mas tive que recorrer a digitar anymais do que eu tenho, tenho certeza:

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, não tenho ajuda no meu IDE quando estou escrevendo estilos nos meus blocos de consulta de mídia:

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

Alguém sabe como posso melhorar minha mediafunção?

Mister Epic
fonte

Respostas:

0

styled-componentspermite usar objetos para propriedades CSS, bem como cadeias de modelo, e os objetos são muito melhor compreendidos pelo compilador TypeScript. Tente o seguinte:

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
fonte
5

Acredito que não seja um problema do TypeScript, mas um problema do plugin IntelliSense.

Da perspectiva do TypeScript, o conteúdo entre os backticks é do tipo TemplateStringsArray. O TypeScript não está ciente das propriedades CSS válidas, pois vê uma matriz de strings.

Acredito que a validação é feita no nível do plug-in pelo typescript-style-plugin .

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

Eu enviaria uma solicitação de recurso ou um relatório de bug aqui .

sunknudsen
fonte
Eu ainda gostaria de melhorar minha consulta de mídia, se possível ... Mas obrigado pela contribuição!
Mister Epic
Vamos esperar e ver se minha suposição está errada e outras pessoas têm uma solução. Enquanto isso, observei que a validação CSS não parece funcionar para estilos dentro das regras CSS do @media, confirmando potencialmente essa limitação do plug-in IntelliSense.
sunknudsen 30/03
1
Acabei de enviar um relatório de bug. github.com/microsoft/typescript-styled-plugin/issues/113
sunknudsen 30/03
1

Se bem entendi, você quer se livrar any.

Veja como você pode fazer isso:

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
fonte