diff --git a/.changeset/long-trees-listen.md b/.changeset/long-trees-listen.md new file mode 100644 index 000000000..3778873ae --- /dev/null +++ b/.changeset/long-trees-listen.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +Add types for the object syntax for `style` (ex: `style={{color: 'red'}}`) diff --git a/packages/astro/astro-jsx.d.ts b/packages/astro/astro-jsx.d.ts index b82de9388..3e8a86889 100644 --- a/packages/astro/astro-jsx.d.ts +++ b/packages/astro/astro-jsx.d.ts @@ -471,6 +471,33 @@ declare namespace astroHTML.JSX { | 'treegrid' | 'treeitem'; + type CssProperty = keyof Omit< + CSSStyleDeclaration, + | 'item' + | 'setProperty' + | 'removeProperty' + | 'getPropertyValue' + | 'getPropertyPriority' + | 'parentRule' + | 'length' + | 'cssFloat' + | 'cssText' + | typeof Symbol.iterator + | number + >; + + type KebabCSSDOMProperties = import('./dist/type-utils.js').KebabKeys; + + type DOMCSSProperties = { + [key in CssProperty]?: string | number | null | undefined; + }; + type AllCSSProperties = { + [key: string]: string | number | null | undefined; + }; + type StyleObject = import('./dist/type-utils.js').Simplify< + KebabCSSDOMProperties & DOMCSSProperties & AllCSSProperties + >; + interface HTMLAttributes extends AriaAttributes, DOMAttributes, AstroBuiltinAttributes { // Standard HTML Attributes accesskey?: string | undefined | null; @@ -513,7 +540,7 @@ declare namespace astroHTML.JSX { lang?: string | undefined | null; slot?: string | undefined | null; spellcheck?: 'true' | 'false' | boolean | undefined | null; - style?: string | Record | undefined | null; + style?: string | StyleObject | undefined | null; tabindex?: number | string | undefined | null; title?: string | undefined | null; translate?: 'yes' | 'no' | undefined | null; diff --git a/packages/astro/src/type-utils.ts b/packages/astro/src/type-utils.ts index 926b0349d..96970f7c4 100644 --- a/packages/astro/src/type-utils.ts +++ b/packages/astro/src/type-utils.ts @@ -17,5 +17,13 @@ export type OmitIndexSignature = { : KeyType]: ObjectType[KeyType]; }; +// Transform a string into its kebab case equivalent (camelCase -> kebab-case). Useful for CSS-in-JS to CSS. +export type Kebab = T extends `${infer F}${infer R}` + ? Kebab ? '' : '-'}${Lowercase}`> + : A; + +// Transform every key of an object to its kebab case equivalent using the above utility +export type KebabKeys = { [K in keyof T as K extends string ? Kebab : K]: T[K] }; + // Similar to `keyof`, gets the type of all the values of an object export type ValueOf = T[keyof T]; diff --git a/packages/astro/types.d.ts b/packages/astro/types.d.ts index da48b5e1b..638ad762e 100644 --- a/packages/astro/types.d.ts +++ b/packages/astro/types.d.ts @@ -9,6 +9,11 @@ export type HTMLAttributes = Omit< keyof Omit >; +/** + * All the CSS properties available, as defined by the CSS specification + */ +export type CSSProperty = keyof astroHTML.JSX.KebabCSSDOMProperties; + type PolymorphicAttributes

= Omit

, 'as'> & { as?: P['as']; };