Besser typisierte Funktion zum Generieren von Medienabfragen

8

Ich folge diesem Beitrag: https://medium.com/@samuelresua/easy-media-queries-in-styled-components-690b78f50053

Ich habe Folgendes in Typescript erstellt, musste aber auf anymehr tippen als ich muss, da bin ich mir sicher:

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;
}, {});

Daher habe ich keine Hilfe in meiner IDE, wenn ich Stile in meine Medienabfrageblöcke schreibe:

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

Weiß jemand, wie ich meine mediaFunktion verbessern kann?

Mister Epic
quelle

Antworten:

0

styled-componentsMit dieser Option können Sie Objekte sowohl für CSS-Eigenschaften als auch für Vorlagenzeichenfolgen verwenden. Objekte werden vom TypeScript-Compiler viel besser verstanden. Versuche dies:

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

Ich glaube, das ist kein TypeScript-Problem, sondern ein IntelliSense-Plugin-Problem.

Aus Sicht von TypeScript ist der Inhalt zwischen den Backticks vom Typ TemplateStringsArray. TypeScript kennt keine gültigen CSS-Eigenschaften, da es ein Array von Zeichenfolgen sieht.

Ich glaube, die Validierung erfolgt auf Plugin-Ebene durch das TypScript-Plugin .

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

Ich würde einen Feature - Request oder Fehlerbericht hier .

sunknudsen
quelle
Ich möchte meine Medienabfrage nach Möglichkeit noch verbessern ... Aber danke für die Eingabe!
Mister Epic
Lassen Sie uns abwarten, ob meine Annahme falsch ist und andere eine Lösung haben. In der Zwischenzeit ist mir gerade aufgefallen, dass die CSS-Validierung für Stile innerhalb der @ media CSS-Regeln anscheinend nicht funktioniert, was möglicherweise diese Einschränkung des IntelliSense-Plugins bestätigt.
Sunknudsen
1
Ich habe gerade einen Fehlerbericht eingereicht. github.com/microsoft/typescript-styled-plugin/issues/113
sunknudsen
1

Wenn ich es richtig verstehe, willst du es loswerden any.

So geht's:

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
quelle