Giter Site home page Giter Site logo

csstype's Introduction

CSSType

npm

TypeScript and Flow definitions for CSS, generated by data from MDN. It provides autocompletion and type checking for CSS properties and values.

TypeScript

import type * as CSS from 'csstype';

const style: CSS.Properties = {
  colour: 'white', // Type error on property
  textAlign: 'middle', // Type error on value
};

Flow

// @flow strict
import * as CSS from 'csstype';

const style: CSS.Properties<> = {
  colour: 'white', // Type error on property
  textAlign: 'middle', // Type error on value
};

Further examples below will be in TypeScript!

Getting started

$ npm install csstype

Table of content

Style types

Properties are categorized in different uses and in several technical variations to provide typings that suits as many as possible.

Default Hyphen Fallback HyphenFallback
All Properties PropertiesHyphen PropertiesFallback PropertiesHyphenFallback
Standard StandardProperties StandardPropertiesHyphen StandardPropertiesFallback StandardPropertiesHyphenFallback
Vendor VendorProperties VendorPropertiesHyphen VendorPropertiesFallback VendorPropertiesHyphenFallback
Obsolete ObsoleteProperties ObsoletePropertiesHyphen ObsoletePropertiesFallback ObsoletePropertiesHyphenFallback
Svg SvgProperties SvgPropertiesHyphen SvgPropertiesFallback SvgPropertiesHyphenFallback

Categories:

  • All - Includes Standard, Vendor, Obsolete and Svg
  • Standard - Current properties and extends subcategories StandardLonghand and StandardShorthand (e.g. StandardShorthandProperties)
  • Vendor - Vendor prefixed properties and extends subcategories VendorLonghand and VendorShorthand (e.g. VendorShorthandProperties)
  • Obsolete - Removed or deprecated properties
  • Svg - SVG-specific properties

Variations:

  • Default - JavaScript (camel) cased property names
  • Hyphen - CSS (kebab) cased property names
  • Fallback - Also accepts array of values e.g. string | string[]

At-rule types

At-rule interfaces with descriptors.

TypeScript: These will be found in the AtRule namespace, e.g. AtRule.Viewport.
Flow: These will be prefixed with AtRule$, e.g. AtRule$Viewport.

Default Hyphen Fallback HyphenFallback
@counter-style CounterStyle CounterStyleHyphen CounterStyleFallback CounterStyleHyphenFallback
@font-face FontFace FontFaceHyphen FontFaceFallback FontFaceHyphenFallback
@viewport Viewport ViewportHyphen ViewportFallback ViewportHyphenFallback

Pseudo types

String literals of pseudo classes and pseudo elements

  • Pseudos

    Extends:

    • AdvancedPseudos

      Function-like pseudos e.g. :not(:first-child). The string literal contains the value excluding the parenthesis: :not. These are separated because they require an argument that results in infinite number of variations.

    • SimplePseudos

      Plain pseudos e.g. :hover that can only be one variation.

Generics

All interfaces has two optional generic argument to define length and time: CSS.Properties<TLength = string | 0, TTime = string>

  • Length is the first generic parameter and defaults to string | 0 because 0 is the only length where the unit identifier is optional. You can specify this, e.g. string | number, for platforms and libraries that accepts any numeric value as length with a specific unit.
    const style: CSS.Properties<string | number> = {
      width: 100,
    };
  • Time is the second generic argument and defaults to string. You can specify this, e.g. string | number, for platforms and libraries that accepts any numeric value as length with a specific unit.
    const style: CSS.Properties<string | number, number> = {
      transitionDuration: 1000,
    };

Usage

import type * as CSS from 'csstype';

const style: CSS.Properties = {
  width: '10px',
  margin: '1em',
};

In some cases, like for CSS-in-JS libraries, an array of values is a way to provide fallback values in CSS. Using CSS.PropertiesFallback instead of CSS.Properties will add the possibility to use any property value as an array of values.

import type * as CSS from 'csstype';

const style: CSS.PropertiesFallback = {
  display: ['-webkit-flex', 'flex'],
  color: 'white',
};

There's even string literals for pseudo selectors and elements.

import type * as CSS from 'csstype';

const pseudos: { [P in CSS.SimplePseudos]?: CSS.Properties } = {
  ':hover': {
    display: 'flex',
  },
};

Hyphen cased (kebab cased) properties are provided in CSS.PropertiesHyphen and CSS.PropertiesHyphenFallback. It's not not added by default in CSS.Properties. To allow both of them, you can simply extend with CSS.PropertiesHyphen or/and CSS.PropertiesHyphenFallback.

import type * as CSS from 'csstype';

interface Style extends CSS.Properties, CSS.PropertiesHyphen {}

const style: Style = {
  'flex-grow': 1,
  'flex-shrink': 0,
  'font-weight': 'normal',
  backgroundColor: 'white',
};

Adding type checked CSS properties to a HTMLElement.

import type * as CSS from 'csstype';

const style: CSS.Properties = {
  color: 'red',
  margin: '1em',
};

let button = document.createElement('button');

Object.assign(button.style, style);

What should I do when I get type errors?

The goal is to have as perfect types as possible and we're trying to do our best. But with CSS Custom Properties, the CSS specification changing frequently and vendors implementing their own specifications with new releases sometimes causes type errors even if it should work. Here's some steps you could take to get it fixed:

If you're using CSS Custom Properties you can step directly to step 3.

  1. First of all, make sure you're doing it right. A type error could also indicate that you're not 😉

    • Some CSS specs that some vendors has implemented could have been officially rejected or haven't yet received any official acceptance and are therefor not included
    • If you're using TypeScript, type widening could be the reason you get Type 'string' is not assignable to... errors
  2. Have a look in issues to see if an issue already has been filed. If not, create a new one. To help us out, please refer to any information you have found.

  3. Fix the issue locally with TypeScript (Flow further down):

    • The recommended way is to use module augmentation. Here's a few examples:

      // My css.d.ts file
      import type * as CSS from 'csstype';
      
      declare module 'csstype' {
        interface Properties {
          // Add a missing property
          WebkitRocketLauncher?: string;
      
          // Add a CSS Custom Property
          '--theme-color'?: 'black' | 'white';
      
          // Allow namespaced CSS Custom Properties
          [index: `--theme-${string}`]: any;
          
          // Allow any CSS Custom Properties
          [index: `--${string}`]: any;
      
          // ...or allow any other property
          [index: string]: any;
        }
      }
    • The alternative way is to use type assertion. Here's a few examples:

      const style: CSS.Properties = {
        // Add a missing property
        ['WebkitRocketLauncher' as any]: 'launching',
      
        // Add a CSS Custom Property
        ['--theme-color' as any]: 'black',
      };

    Fix the issue locally with Flow:

    • Use type assertion. Here's a few examples:

      const style: $Exact<CSS.Properties<*>> = {
        // Add a missing property
        [('WebkitRocketLauncher': any)]: 'launching',
      
        // Add a CSS Custom Property
        [('--theme-color': any)]: 'black',
      };

Version 3.0

  • All property types are exposed with namespace
    TypeScript: Property.AlignContent (was AlignContentProperty before)
    Flow: Property$AlignContent
  • All at-rules are exposed with namespace
    TypeScript: AtRule.FontFace (was FontFace before)
    Flow: AtRule$FontFace
  • Data types are NOT exposed
    E.g. Color and Box. Because the generation of data types may suddenly be removed or renamed.
  • TypeScript hack for autocompletion
    Uses (string & {}) for literal string unions and (number & {}) for literal number unions (related issue). Utilize PropertyValue<T> to unpack types from e.g. (string & {}) to string.
  • New generic for time
    Read more on the "Generics" section.
  • Flow types improvements
    Flow Strict enabled and exact types are used.

Contributing

Never modify index.d.ts and index.js.flow directly. They are generated automatically and committed so that we can easily follow any change it results in. Therefor it's important that you run $ git config merge.ours.driver true after you've forked and cloned. That setting prevents merge conflicts when doing rebase.

Commands

  • npm run build Generates typings and type checks them
  • npm run watch Runs build on each save
  • npm run test Runs the tests
  • npm run lazy Type checks, lints and formats everything

csstype's People

Contributors

arnfaldur avatar dependabot[bot] avatar frenic avatar keyz avatar milesj avatar nojvek avatar notoriousb1t avatar notwoods avatar rtsao avatar schonert avatar sgrishchenko avatar superquadratic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csstype's Issues

How can I get only the type of properties strings?

I want to check if a key is valid property key, such as 'font-size', 'font-family', which is string type. Is there some exported type in csstype can implement that? I tried to view source code but I'm a beginner of ts... If you could be so kind to give me some advices, I would be grateful!

Missing WebkitAppRegion property

Currently working around this with via module augmentation:

declare module 'csstype' {
  interface Properties {
    WebkitAppRegion?: 'drag' | 'inherit' | 'initial' | 'no-drag' | 'none' | 'unset',
  }
}

There is some official documentation for this property, and you can see it mentioned in the Electron docs; if you look in the Chrome dev tools you'll see that autocomplete offers the possible property values listed above.

Missing a couple IE11 grid vendor rules

I'm not exactly sure how much control you have over missing css properties, but I ran into a few that are sometimes needed when working with IE11 and CSS Grids. I believe the following are some of the missing CSS properties:

  • -ms-grid-row
  • -ms-grid-row-span
  • -ms-grid-column
  • -ms-grid-column-span

I can probably dig up some more references if that'd be helpful.

Generic for properties with time

Just like <length>, it should be possible to customize the type for <time>.

The only properties that has <time> are:

  • animationDelay
  • animationDuration
  • transitionDelay
  • transitionDuration

Manual patches pending MDN data updates

Particularly now that React is using CSSType's Properties without a string index fallback, we're discovering more cases where the MDN data is missing properties and it's more pressing to have the typings be complete (sorry if I jumped the gun in creating this pressure!). It might be nice to have a release valve in the form of an interface of manual patches that we mix in to Properties, so we don't have to wait on MDN to merge PRs in order to be responsive to these missing properties. Then once the MDN PRs do get merged and the properties can be generated, we can delete them from the manual patches interface. This is essentially the approach taken with the SVG properties; would it make sense to generalize it?

Also if we take this approach I'm happy to volunteer to start creating PRs to patch the known missing properties!

Using Flow `$Exact` type utility with `Properties` doesn't work

The $Exact type utility in Flow could be useful to fail when an unknown (possibly misspelled) style property is used. But this fails for some reason when a known vendor property is used.

const css: $Exact<CSS.Properties<*>> = {
  height: '1px',           // <- OK
  MozAppearance: 'button', // <- Error
};

// All branches are incompatible:
//  - Either cannot assign object literal to `css` because property `MozAppearance` is missing in
//   `StandardLonghandProperties` [1] but exists in object literal [2].
//  - Or cannot assign object literal to `css` because property `MozAppearance` is missing in
//   `StandardShorthandProperties` [3] but exists in object literal [2].

This however works:

const css: CSS.Properties<*> & $Shape<CSS.Properties<*>> = {
  height: '1px',           // <- Ok
  MozAppearance: 'button', // <- Ok
  someUnknown: 'abc'       // <- Error
};

All I could find was this bug when $Exact is used along with spread. But it doesn't really cover this problem.

I'm trying to understand what's happening but I'm not that familiar with Flow.

type def might be missing 'overlay' for OverflowXProperty

export type OverflowXProperty = Globals | "auto" | "clip" | "hidden" | "scroll" | "visible";

I think its not the only one that should have the 'overlay' property. With material UI when assigning style using JS for overflowX: "overlay" I would get a type error.

Manually did this fix my issue in csstype/index.d.ts:
export type OverflowXProperty = Globals | "auto" | "clip" | "hidden" | "scroll" | "visible" | "overlay";

Hyphen-separated property names

Hi, this project looks awesome! I’m trying to improve the typings for JSS and these typings look very promising in that effort. However, there’s a need in that library for both camel cased and hyphen-separated CSS property names. Would it be possible to generate a kebab-cased version of the Properties interface?

Change license to MPL

It occurs that any new files containing MPL covered data (like MDN data) must also be distributed under MPL (see discussion).

Our options:

  1. Change from MIT to MPL
  2. Generate typings as a install script with MDN data as a dependency to keep the MIT license

Option 1 seems preferable. But I don't know what impact that would have and don't know how a process like that works.

cc @chrisdavidmills @pelotom

Missing css property: -webkit-text-decoration

According to MDN, text-decoration requires no browser prefixes except for when used with a shorthand property in Safari browsers, when it needs the -webkit- prefix.

From what I can tell, the current types don't allow for the -webkit- prefix for text-decoration.

Prefix keywords are never removed

CSS properties are deprecated as they are marked as deprecated by the spec or are removed by vendor. But CSS keywords lives on forever at the moment (#36). Maybe this won't ever be a problem. But I'm a bit worried if old prefixed keywords results in too many combined keywords in the future. But lets see if that happens. This issue is for now just a friendly reminder to my self. 👴

Should we remove the string type at the end of `DisplayProperty`?

export type DisplayProperty = Globals | DisplayOutside | DisplayInside | DisplayInternal | DisplayLegacy | "contents" | "list-item" | "none" | string;

The extra string in the end simply disable the feature of type checking, now the display could be anything like foo or bar.

Furthermore, in Typescript, you can't get intellisense, because it could be anything.
Should we remove it? Or I miss something?

Thanks :)

Intellisense not working (TS)

import * as CSS from 'csstype';

const style: CSS.Properties = {
  alignSelf: 'stretsh', // Type error on value
  colour: 'white', // Type error on property
};

alignSelf from the frontpage does not throw an error because string is allowed:

type AlignSelfProperty = Globals | SelfPosition | "auto" | "baseline" | "normal" | "stretch" | string;

Also with the latest typescript 2.8.1 and csstype 2.2.0 and the latest VSCode I do not get any intellisense for alignSelf. Does it work for you?

Move to an Organization

Over in TypeStyle we are discussing possibly moving to csstype instead of maintaining types in our repository. typestyle/typestyle#245

One of my biggest fears with this move is that csstype has one maintainer. Since we have many of the same goals, I think it could make sense for csstype to join the TypeStyle organization if you are open to that. I think many of the members of TypeStyle may be open to that.

If not, I would love to help out with this project. At the very least, I think we can combine efforts to making CSS type safe.

Interface vs intersection types w/ Flow

It'd be nice to allow for some customization of properties. A use case would be custom fontFace or animationName property name values for declarative @keyframes or @font-face rules.

For example:

const animation = {
  from: {color: "red"},
  to: {color: "blue"}
};

const style = {
  animationName: animation
};

Unfortunately, types can't be easily extended in Flow.

So when using Flow, there's two possible options:

  1. Make add parameterized types for animationName and fontFace values.
  2. Use Flow utility types as a means of composition and override mechanism.

Option 1 seems a bit clunky, because the parameterization is overly specific to a particular implementation/use case that may not be generically applicable. Adding generics for all the things is probably not sustainable, as folks may want to add more and more things.

Option 2 seems much more sustainable, as this customization can simply happen outside of this library. However, this doesn't work well with interface types and Flow.

Here's a simple reproduction case in the Flow playground.

Other than keeping the code generation the same between Flow and Typescript, was there any other reason to use interface types in the Flow case?

I propose changing the Flow generation code in this library to use object intersection types instead of interfaces and extends, which I think will make customization/composition much easier. I'm temporarily using a forked version of this library in Styletron to get around this, but this change should solve the problem. Happy to put up a PR for this, just figured I'd make an issue first.

Thanks for making a such an awesome library 😄

No autocompletition on property value

Hi there,

I found your awesome style definitions for typescript an I am emused to have this BUT the autocompletition does not work on values because they are always string | undefined.
The property "color" normaly should display valid color names but it doesn't.
I am using VS Code and at the moment there are no @types installed except typescript and its types Of course. It would be nice if you can fix this =)

Another thing is, that I need sometimes just a list of properties instead of an interface. For example PropertiesList = "background" | "backgroundPosition" | "color" and so on. This would be a very nice feature.

Split literal strings from base types

Properties like vertical-align allow literals but also the very wide string type. The issue with this is that TypeScript will widen the type to string, losing the ability to offer auto-completion hints for literal values and allowing any string value to pass type-checking. Would it be possible to define types which allow a very wide type like this:

type VerticalAlignPropertyBase<TLength> = Globals | TLength | "baseline" | "bottom" | "middle" | "sub" | "super" | "text-bottom" | "text-top" | "top";
type VerticalAlignProperty<TLength> = VerticalAlignPropertyBase<TLength> | string;

Auto-completion without split-out types
screen shot 2018-08-16 at 4 14 32 pm

Auto-completion with split-out types
screen shot 2018-08-16 at 4 14 40 pm

It's possible that I'm missing an obvious way to remove string from the union and be left only with the literal types and Globals/TLength, but so far I've been unlucky with my attempts.

[Help wanted] How to apply csstype on an interface

I have an object that must only contain specific css properties:

export interface InterfaceTypeElementProperties {
  fontFamily?: string;
  fontSize?: [string, number];
  fontWeight?: number;
  letterSpacing?: number;
  textTransform?: string;
  lineHeight?: number | number[];
  marginTop?: number | number[];
  marginBottom?: number | number[];
}

I'm hoping to apply csstypes on top of those properties - for instance fontWeight shouldn't just accept any number, but those recognised by csstype.

What's the right way to do this?
Thank you!

CSS custom properties

I am writing an app in React and Typescript and will be making heavy use of CSS custom properties.

Could you idiot-proof the documentation a bit more please? Is css.d.ts a file I need to create and does it matter what directory it is in?

// My css.d.ts file
import * as CSS from 'csstype';

declare module 'csstype' {
  interface Properties {
    // Add a missing property
    WebkitRocketLauncher?: string;

    // Add a CSS Custom Property
    '--theme-color'?: 'black' | 'white';

    // ...or allow any other property
    [index: string]: any;
  }
}

Supporting attributes?

Might be out of scope for this project, but thought I'd give it a try. I'm adding types to a CSS-in-JS library, which relies on attributes like [disabled]. I generated a union using https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes and https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute, which resulted in:

export type HTMLAttributes =
  | '[accept]'
  | '[accept-charset]'
  | '[accesskey]'
  | '[action]'
  | '[align]'
  | '[allow]'
  | '[alt]'
  | '[async]'
  | '[autocapitalize]'
  | '[autofocus]'
  | '[autoplay]'
  | '[bgcolor]'
  | '[border]'
  | '[buffered]'
  | '[challenge]'
  | '[charset]'
  | '[checked]'
  | '[cite]'
  | '[class]'
  | '[code]'
  | '[codebase]'
  | '[color]'
  | '[cols]'
  | '[colspan]'
  | '[content]'
  | '[contenteditable]'
  | '[contextmenu]'
  | '[controls]'
  | '[coords]'
  | '[data]'
  | '[datetime]'
  | '[decoding]'
  | '[default]'
  | '[defer]'
  | '[dir]'
  | '[dirname]'
  | '[disabled]'
  | '[download]'
  | '[draggable]'
  | '[dropzone]'
  | '[enctype]'
  | '[for]'
  | '[form]'
  | '[formaction]'
  | '[headers]'
  | '[height]'
  | '[hidden]'
  | '[high]'
  | '[href]'
  | '[hreflang]'
  | '[http-equiv]'
  | '[icon]'
  | '[id]'
  | '[importance]'
  | '[integrity]'
  | '[ismap]'
  | '[itemprop]'
  | '[keytype]'
  | '[kind]'
  | '[label]'
  | '[lang]'
  | '[language]'
  | '[lazyload]'
  | '[list]'
  | '[loop]'
  | '[low]'
  | '[manifest]'
  | '[max]'
  | '[maxlength]'
  | '[minlength]'
  | '[media]'
  | '[method]'
  | '[min]'
  | '[multiple]'
  | '[muted]'
  | '[name]'
  | '[novalidate]'
  | '[open]'
  | '[optimum]'
  | '[pattern]'
  | '[ping]'
  | '[placeholder]'
  | '[poster]'
  | '[preload]'
  | '[radiogroup]'
  | '[readonly]'
  | '[rel]'
  | '[required]'
  | '[reversed]'
  | '[rows]'
  | '[rowspan]'
  | '[sandbox]'
  | '[scope]'
  | '[scoped]'
  | '[selected]'
  | '[shape]'
  | '[size]'
  | '[sizes]'
  | '[slot]'
  | '[span]'
  | '[spellcheck]'
  | '[src]'
  | '[srcdoc]'
  | '[srclang]'
  | '[srcset]'
  | '[start]'
  | '[step]'
  | '[style]'
  | '[summary]'
  | '[tabindex]'
  | '[target]'
  | '[title]'
  | '[translate]'
  | '[type]'
  | '[usemap]'
  | '[value]'
  | '[width]'
  | '[wrap]';

export type SVGAttributes =
  | '[accent-height]'
  | '[accumulate]'
  | '[additive]'
  | '[alignment-baseline]'
  | '[allowReorder]'
  | '[alphabetic]'
  | '[amplitude]'
  | '[arabic-form]'
  | '[ascent]'
  | '[attributeName]'
  | '[attributeType]'
  | '[autoReverse]'
  | '[azimuth]'
  | '[baseFrequency]'
  | '[baseline-shift]'
  | '[baseProfile]'
  | '[bbox]'
  | '[begin]'
  | '[bias]'
  | '[by]'
  | '[calcMode]'
  | '[cap-height]'
  | '[class]'
  | '[clip]'
  | '[clipPathUnits]'
  | '[clip-path]'
  | '[clip-rule]'
  | '[color]'
  | '[color-interpolation]'
  | '[color-interpolation-filters]'
  | '[color-profile]'
  | '[color-rendering]'
  | '[contentScriptType]'
  | '[contentStyleType]'
  | '[cursor]'
  | '[cx]'
  | '[cy]'
  | '[d]'
  | '[decelerate]'
  | '[descent]'
  | '[diffuseConstant]'
  | '[direction]'
  | '[display]'
  | '[divisor]'
  | '[dominant-baseline]'
  | '[dur]'
  | '[dx]'
  | '[dy]'
  | '[edgeMode]'
  | '[elevation]'
  | '[enable-background]'
  | '[end]'
  | '[exponent]'
  | '[externalResourcesRequired]'
  | '[fill]'
  | '[fill-opacity]'
  | '[fill-rule]'
  | '[filter]'
  | '[filterRes]'
  | '[filterUnits]'
  | '[flood-color]'
  | '[flood-opacity]'
  | '[font-family]'
  | '[font-size]'
  | '[font-size-adjust]'
  | '[font-stretch]'
  | '[font-style]'
  | '[font-variant]'
  | '[font-weight]'
  | '[format]'
  | '[from]'
  | '[fr]'
  | '[fx]'
  | '[fy]'
  | '[g1]'
  | '[g2]'
  | '[glyph-name]'
  | '[glyph-orientation-horizontal]'
  | '[glyph-orientation-vertical]'
  | '[glyphRef]'
  | '[gradientTransform]'
  | '[gradientUnits]'
  | '[hanging]'
  | '[height]'
  | '[href]'
  | '[hreflang]'
  | '[horiz-adv-x]'
  | '[horiz-origin-x]'
  | '[id]'
  | '[ideographic]'
  | '[image-rendering]'
  | '[in]'
  | '[in2]'
  | '[intercept]'
  | '[k]'
  | '[k1]'
  | '[k2]'
  | '[k3]'
  | '[k4]'
  | '[kernelMatrix]'
  | '[kernelUnitLength]'
  | '[kerning]'
  | '[keyPoints]'
  | '[keySplines]'
  | '[keyTimes]'
  | '[lang]'
  | '[lengthAdjust]'
  | '[letter-spacing]'
  | '[lighting-color]'
  | '[limitingConeAngle]'
  | '[local]'
  | '[marker-end]'
  | '[marker-mid]'
  | '[marker-start]'
  | '[markerHeight]'
  | '[markerUnits]'
  | '[markerWidth]'
  | '[mask]'
  | '[maskContentUnits]'
  | '[maskUnits]'
  | '[mathematical]'
  | '[max]'
  | '[media]'
  | '[method]'
  | '[min]'
  | '[mode]'
  | '[name]'
  | '[numOctaves]'
  | '[offset]'
  | '[opacity]'
  | '[operator]'
  | '[order]'
  | '[orient]'
  | '[orientation]'
  | '[origin]'
  | '[overflow]'
  | '[overline-position]'
  | '[overline-thickness]'
  | '[panose-1]'
  | '[paint-order]'
  | '[path]'
  | '[pathLength]'
  | '[patternContentUnits]'
  | '[patternTransform]'
  | '[patternUnits]'
  | '[ping]'
  | '[pointer-events]'
  | '[points]'
  | '[pointsAtX]'
  | '[pointsAtY]'
  | '[pointsAtZ]'
  | '[preserveAlpha]'
  | '[preserveAspectRatio]'
  | '[primitiveUnits]'
  | '[r]'
  | '[radius]'
  | '[referrerPolicy]'
  | '[refX]'
  | '[refY]'
  | '[rel]'
  | '[rendering-intent]'
  | '[repeatCount]'
  | '[repeatDur]'
  | '[requiredExtensions]'
  | '[requiredFeatures]'
  | '[restart]'
  | '[result]'
  | '[rotate]'
  | '[rx]'
  | '[ry]'
  | '[scale]'
  | '[seed]'
  | '[shape-rendering]'
  | '[slope]'
  | '[spacing]'
  | '[specularConstant]'
  | '[specularExponent]'
  | '[speed]'
  | '[spreadMethod]'
  | '[startOffset]'
  | '[stdDeviation]'
  | '[stemh]'
  | '[stemv]'
  | '[stitchTiles]'
  | '[stop-color]'
  | '[stop-opacity]'
  | '[strikethrough-position]'
  | '[strikethrough-thickness]'
  | '[string]'
  | '[stroke]'
  | '[stroke-dasharray]'
  | '[stroke-dashoffset]'
  | '[stroke-linecap]'
  | '[stroke-linejoin]'
  | '[stroke-miterlimit]'
  | '[stroke-opacity]'
  | '[stroke-width]'
  | '[style]'
  | '[surfaceScale]'
  | '[systemLanguage]'
  | '[tabindex]'
  | '[tableValues]'
  | '[target]'
  | '[targetX]'
  | '[targetY]'
  | '[text-anchor]'
  | '[text-decoration]'
  | '[text-rendering]'
  | '[textLength]'
  | '[to]'
  | '[transform]'
  | '[type]'
  | '[u1]'
  | '[u2]'
  | '[underline-position]'
  | '[underline-thickness]'
  | '[unicode]'
  | '[unicode-bidi]'
  | '[unicode-range]'
  | '[units-per-em]'
  | '[v-alphabetic]'
  | '[v-hanging]'
  | '[v-ideographic]'
  | '[v-mathematical]'
  | '[values]'
  | '[vector-effect]'
  | '[version]'
  | '[vert-adv-y]'
  | '[vert-origin-x]'
  | '[vert-origin-y]'
  | '[viewBox]'
  | '[viewTarget]'
  | '[visibility]'
  | '[width]'
  | '[widths]'
  | '[word-spacing]'
  | '[writing-mode]'
  | '[x]'
  | '[x-height]'
  | '[x1]'
  | '[x2]'
  | '[xChannelSelector]'
  | '[xlink:actuate]'
  | '[xlink:arcrole]'
  | '[xlink:href]'
  | '[xlink:role]'
  | '[xlink:show]'
  | '[xlink:title]'
  | '[xlink:type]'
  | '[xml:base]'
  | '[xml:lang]'
  | '[xml:space]'
  | '[y]'
  | '[y1]'
  | '[y2]'
  | '[yChannelSelector]'
  | '[z]'
  | '[zoomAndPan]';

While this works, it doesn't support all attributes, especially ones that use patterns like [target="_blank"], but I don't see this as a big issue because: 1) Pseudos have the same problem with functions like :not() and 2) Attribute usage in CSS-in-JS isn't that common.

Let me know your thoughts and I'll submit a PR if need be.

Expose property types for each property, e.g. `BackgroundColorProperty`

import { BackgroundColorProperty } from 'csstype';
const bgColor: BackgroundColorProperty = 'white';

Many users are using this instead of

import { Properties } from 'csstype';
const bgColor: Properties['backgroundColor'] = 'white';

But only some property types that doesn't only include type string or number are exposed. Should all properties have an equivalent property type?

Test against third-party libraries

Even small changes may have impact on third-party libraries that uses CSSType (like JSS, Styletron and Glitz) and tests against these would provide safety when publishing new releases. Not sure about the best approach to keep it quite general for both TypeScript/Flow and when API/definitions/tests changes on these libraries? It shouldn't fail unless a change in CSSType is the cause of the failure.

Incompatibilities with @types/react

I was taking a look at what it would take to get @types/react to use csstype instead of its own internal definition for CSSProperties. So far I've run into the following issues:

  1. CSSProperties uses numeric literals for fontWeight:

    fontWeight?: CSSWideKeyword | "normal" | "bold" | "bolder" | "lighter" | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
    

    whereas csstype uses all string literals:

    type FontWeightProperty = All | "900" | "bold" | "bolder" | "lighter" | "100" | "200" | "normal" | "400" | "500" | "600" | "700" | "800" | "300";
    

    Could this be changed to use numeric literals?

  2. SVG properties such as fillOpacity, strokeOpacity and strokeWidth appear to be missing.

EOL characters and build artifacts

Because output.ts is implemented using os.EOL, building the libdefs on a different operating system than Windows produces an enormous diff in the build artifacts.

This raises a few questions:

  1. Should index.d.ts (and Flow equivalent) be checked into git?
  2. If so, should a particular line ending be chosen?

string "none" not assignable to text-transform or user-select

As far as I can tell, React's TypeScript types via DefinitelyTyped (https://github.com/DefinitelyTyped/DefinitelyTyped/commits/master/types/react) recently began using this library for CSS types / stopped allowing a string fallback. Since updating my @types/react dependency, I've been getting the following errors for this (example) piece of code:

<span
  style={{
    userSelect: 'none',
    textTransform: 'none',
  }}
/>

Type '<style object>' is not assigning to type 'CSSProperties'. Types of property '[userSelect / textTransform]' are incompatible. Type 'string' is not assignable to type '[UserSelectProperty / TextTransformProperty]'.

Sorry if this repo isn't the right place to bring this up, it's hard to tell. Cheers!

JSDOC Property Descriptions

Having compatibility and initial values for each property in the jsdocs is great! One thing that would make these definitions stronger is if they had short descriptions for each. There are way too many css properties for any one developer/designer to memorize, so in TypeStyle we put a short little blurb about the property to give it some context:

  /**
   * Background-size specifies the size of a background image
   * @see https://developer.mozilla.org/en-US/docs/Web/CSS/background-size
   */
  backgroundSize?: 'auto' | 'cover' | 'contain' | CSSLength | CSSPercentage | CSSGlobalValues;

The short description lets the developer know that backgroundSize controls the background image.

Since the underlying types are from MDN's browser compat tables, I realize this information is not readily available from that datasource. I propose adding a json file to store the description or finding a datasource for it and then adding it to the output.

I can take a swing at creating a PR for it.

typestyle/typestyle#245

Type-checking performance

I’ve been working on improving our TypeScript check time at work this week. Over the past month our check time has gone from around 15 seconds to almost two minutes (!!!). The major slowdown happened to coincide with me updating jsxstyle—the CSS in JS library I maintain—to use csstype.

The main issue I encountered was not related to csstype. I was intersecting the Properties interface with { [key: string]: any } instead of extending it. Big mistake. After I replaced the intersection with an extends, check time dropped down to about one minute.

I ran tsc with the diagnostics flag and got the following check times:

CSS types Check time
{ [key: string]: any } 22 seconds
Old CSSProperties from @types/react 32 seconds
Properties<string | number> 56 seconds

I started messing with a few things to see if I could improve that number. Inlining TLength in Properties drops check time to 47 seconds. I’m currently looking at inlining other things (unexported types that are only used once or twice). My general feeling right now is that a single interface with everything inlined is going to be the fastest option. It’ll be super verbose and lots of things will be duplicated, but since it’s all codegen’d that doesn’t seem like a big issue to me. TypeScript seems to deal better with large type definition files that it does with smaller files that dynamically generate lots of types.

I feel like it should be possible to get check times fairly close to the old check time (pre-csstype). My main issue right now is that I haven’t figured out a good way to profile TypeScript type checking. Seems like a bit of a black box.

I’m still looking into other ways of speeding things up. Will update this issue when I find something interesting.

Discrepancies with TypeStyle

Hi, I've started a very preliminary PR to integrate csstype with TypeStyle at typestyle/typestyle#245. TypeStyle has some of the highest fidelity CSS typings I've seen outside of this library, and I want to make sure to capture and work through the differences that exist. To kick things off, here are the properties that TypeStyle has but csstype doesn't currently:

Properties in typestyle but not csstype:

-apple-trailing-word
-epub-text-emphasis
-epub-text-emphasis-color
-epub-text-emphasis-style
-internal-marquee-direction
-internal-marquee-increment
-internal-marquee-repetition
-internal-marquee-speed
-internal-marquee-style
-moz-min-font-size-ratio
-moz-text-align-last
-moz-text-decoration-color
-moz-text-decoration-line
-moz-text-decoration-style
-moz-top-layer
-ms-align-items
-ms-backface-visibility
-ms-background-position-x
-ms-background-position-y
-ms-behavior
-ms-flex-flow
-ms-flex-grow
-ms-flex-shrink
-ms-flex-wrap
-ms-grid-column
-ms-grid-column-align
-ms-grid-column-span
-ms-grid-row
-ms-grid-row-align
-ms-grid-row-span
-ms-ime-mode
-ms-layout-flow
-ms-layout-grid
-ms-layout-grid-char
-ms-layout-grid-line
-ms-layout-grid-mode
-ms-layout-grid-type
-ms-perspective
-ms-perspective-origin
-ms-perspective-origin-x
-ms-perspective-origin-y
-ms-text-align-last
-ms-text-justify
-ms-text-kashida-space
-ms-text-underline-position
-ms-transform-origin-x
-ms-transform-origin-y
-ms-transform-origin-z
-ms-transform-style
-ms-word-wrap
-ms-zoom
-webkit-animation-trigger
-webkit-appearance
-webkit-color-correction
-webkit-column-fill
-webkit-cursor-visibility
-webkit-flex-align
-webkit-flex-negative
-webkit-flex-positive
-webkit-flex-wrap
-webkit-flow-from
-webkit-flow-into
-webkit-font-size-delta
-webkit-grid
-webkit-grid-area
-webkit-grid-auto-columns
-webkit-grid-auto-flow
-webkit-grid-auto-rows
-webkit-grid-column
-webkit-grid-column-end
-webkit-grid-column-gap
-webkit-grid-column-start
-webkit-grid-gap
-webkit-grid-row
-webkit-grid-row-end
-webkit-grid-row-gap
-webkit-grid-row-start
-webkit-grid-template
-webkit-grid-template-areas
-webkit-grid-template-columns
-webkit-grid-template-rows
-webkit-hyphenate-limit-after
-webkit-hyphenate-limit-before
-webkit-hyphenate-limit-lines
-webkit-initial-letter
-webkit-justify-items
-webkit-justify-self
-webkit-line-align
-webkit-line-grid
-webkit-line-snap
-webkit-mask-size
-webkit-nbsp-mode
-webkit-region-fragment
-webkit-ruby-position
-webkit-text-align-last
-webkit-text-justify
-webkit-text-underline-position
-webkit-text-zoom
alignmentAdjust
backgroundComposite
behavior
borderCornerShape
cue
cueAfter
flexNegative
flexOrder
flexPositive
flowFrom
gridRowPosition
gridRowSpan
hyphenateLimitChars
hyphenateLimitLines
hyphenateLimitZone
layoutGrid
layoutGridChar
layoutGridLine
layoutGridMode
layoutGridType
marqueeDirection
marqueeStyle
overflowStyle
pause
pauseAfter
pauseBefore
regionFragment
restAfter
restBefore
shapeInside
speak
speakAs
textDecorationLineThrough
textDecorationNone
textDecorationOverline
textDecorationUnderline
textHeight
textJustifyTrim
textKashidaSpace
textLineThrough
textLineThroughWidth
textOverline
textOverlineColor
textOverlineMode
textOverlineStyle
textOverlineWidth
transformOriginZ
userFocus
userInput
voiceBalance
voiceDuration
voiceFamily
voicePitch
voiceRange
voiceRate
voiceStress
voiceVolume
wrapFlow
wrapMargin

Where csstype's properties overlap with typestyle but it's missing some allowed values:

-moz-appearance: string | number;
-moz-binding: number;
-moz-border-bottom-colors: number;
-moz-border-end-color: number;
-moz-border-end-style: number;
-moz-border-left-colors: number;
-moz-border-right-colors: number;
-moz-border-start-color: number;
-moz-border-start-style: number;
-moz-border-top-colors: number;
-moz-column-count: string;
-moz-column-fill: string | number;
-moz-column-rule-color: number;
-moz-column-rule-style: number;
-moz-float-edge: string | number;
-moz-force-broken-image-icon: string;
-moz-hyphens: string | number;
-moz-image-region: number;
-moz-orient: string | number;
-moz-stack-sizing: string | number;
-moz-text-size-adjust: number;
-moz-user-focus: string | number;
-moz-user-input: string | number;
-moz-user-modify: string | number;
-moz-window-dragging: string | number;
-moz-window-shadow: string | number;
-ms-accelerator: string | number;
-ms-block-progression: string | number;
-ms-content-zoom-chaining: string | number;
-ms-content-zoom-limit-max: number;
-ms-content-zoom-limit-min: number;
-ms-content-zoom-limit: number;
-ms-content-zoom-snap-points: number;
-ms-content-zoom-snap-type: string | number;
-ms-content-zoom-snap: number;
-ms-content-zooming: string | number;
-ms-filter: number;
-ms-flow-from: number;
-ms-flow-into: number;
-ms-high-contrast-adjust: string | number;
-ms-hyphenate-limit-lines: string;
-ms-hyphens: string | number;
-ms-ime-align: string | number;
-ms-line-break: string | number;
-ms-overflow-style: string | number;
-ms-overflow-x: string | number;
-ms-overflow-y: string | number;
-ms-scroll-chaining: string | number;
-ms-scroll-limit: number;
-ms-scroll-rails: string | number;
-ms-scroll-snap-points-x: number;
-ms-scroll-snap-points-y: number;
-ms-scroll-snap-type: string | number;
-ms-scroll-snap-x: number;
-ms-scroll-snap-y: number;
-ms-scroll-translation: string | number;
-ms-scrollbar-3dlight-color: number;
-ms-scrollbar-arrow-color: number;
-ms-scrollbar-base-color: number;
-ms-scrollbar-darkshadow-color: number;
-ms-scrollbar-face-color: number;
-ms-scrollbar-highlight-color: number;
-ms-scrollbar-shadow-color: number;
-ms-scrollbar-track-color: number;
-ms-text-autospace: string | number;
-ms-text-combine-horizontal: number;
-ms-text-overflow: number;
-ms-text-size-adjust: number;
-ms-touch-action: number;
-ms-touch-select: string | number;
-ms-transform: number;
-ms-user-select: contain | all | auto;
-ms-word-break: string | number;
-ms-wrap-flow: string | number;
-ms-wrap-through: string | number;
-ms-writing-mode: string | number;
-webkit-align-content: number;
-webkit-animation-delay: number;
-webkit-animation-direction: number;
-webkit-animation-duration: number;
-webkit-animation-fill-mode: number;
-webkit-animation-name: number;
-webkit-animation-play-state: number;
-webkit-animation-timing-function: number;
-webkit-backdrop-filter: number;
-webkit-backface-visibility: string | number;
-webkit-border-before-color: number;
-webkit-border-before-style: number;
-webkit-box-decoration-break: string | number;
-webkit-box-shadow: number;
-webkit-clip-path: number;
-webkit-column-count: string;
-webkit-column-rule-color: number;
-webkit-column-rule-style: number;
-webkit-column-span: string | number;
-webkit-filter: number;
-webkit-flex-flow: number;
-webkit-font-feature-settings: number;
-webkit-font-kerning: string | number;
-webkit-font-variant-ligatures: number;
-webkit-hyphens: string | number;
-webkit-line-break: string | number;
-webkit-line-clamp: string;
-webkit-mask-clip: number;
-webkit-mask-composite: number;
-webkit-mask-image: number;
-webkit-mask-origin: number;
-webkit-mask-repeat-x: string | number;
-webkit-mask-repeat-y: string | number;
-webkit-mask-repeat: number;
-webkit-mask: number;
-webkit-order: string;
-webkit-scroll-snap-type: string | number;
-webkit-shape-image-threshold: string;
-webkit-shape-outside: number;
-webkit-tap-highlight-color: number;
-webkit-text-combine: number;
-webkit-text-decoration-color: number;
-webkit-text-decoration-line: number;
-webkit-text-decoration-skip: number;
-webkit-text-decoration-style: string | number;
-webkit-text-emphasis-color: number;
-webkit-text-emphasis-position: number;
-webkit-text-emphasis-style: number;
-webkit-text-emphasis: number;
-webkit-text-fill-color: number;
-webkit-text-orientation: string | number;
-webkit-text-size-adjust: number;
-webkit-text-stroke-color: number;
-webkit-touch-callout: string | number;
-webkit-transform-style: string | number;
-webkit-transform: number;
-webkit-transition-delay: number;
-webkit-transition-duration: number;
-webkit-transition-property: number;
-webkit-transition-timing-function: number;
-webkit-transition: number;
-webkit-user-modify: string | number;
-webkit-writing-mode: string | number;
borderBottomStyle: string;
borderLeftStyle: string;
borderRightStyle: string;
borderTopStyle: string;
boxShadow: number;
fontWeight: number;
hyphens: string;
strokeDasharray: number[];
textAlign: justify-all;

Can't combine overflowX with !important

I'm trying to override styles from a 3rd party library, the only way being to use overflowX: scroll !important
However, type definitions doesn't allow that, although for simple overflow does allow (any) string.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.