Skip to content

Commit

Permalink
feat: Added support of fallback properties in makeStaticStyles (#558)
Browse files Browse the repository at this point in the history
* added fallback values support in makeStaticStyles

* Change files

* added the section for docs

* Change files

* PR review

---------

Co-authored-by: Oleksandr Fediashov <olfedias@microsoft.com>
  • Loading branch information
Shubhdeep12 and layershifter committed May 21, 2024
1 parent 1a56464 commit f545363
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 6 deletions.
32 changes: 32 additions & 0 deletions apps/website/docs/react/api/make-static-styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,35 @@ export default function App(props) {
return <p className={props.primaryText}>Hello world</p>;
}
```

## CSS Fallback Properties

Griffel supports CSS fallback properties in order to support older browsers.

Any CSS property accepts an array of values which are all added to the styles.
Every browser will use the latest valid value (which might be a different one in different browsers, based on supported CSS in that browser):

```js
import { makeStaticStyles } from '@griffel/react';

const useClasses = makeStaticStyles({
body: {
overflowY: ['scroll', 'overlay'],
},
});

function App() {
useStaticStyles();

return <div />;
}
```

<OutputTitle>Produces following CSS...</OutputTitle>

```css
body {
overflow-y: scroll; /* Fallback for browsers which do not support overflow: overlay */
overflow-y: overlay; /* Used by browsers which support overflow: overlay */
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "feat: add fallback values support in makeStaticStyles",
"packageName": "@griffel/core",
"email": "chhabrashubhdeep@gmail.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "feat: add support for fallback values in GriffelStaticStyle",
"packageName": "@griffel/style-types",
"email": "chhabrashubhdeep@gmail.com",
"dependentChangeType": "patch"
}
31 changes: 31 additions & 0 deletions e2e/typescript/src/assets/fixture-static.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { GriffelStaticStyles } from '@griffel/style-types';

function assertType(styles: GriffelStaticStyles): GriffelStaticStyles {
return styles;
}

// Basic styles
//

assertType('html { line-height: 20px; }');

assertType({
body: {
color: 'red',
},
});
assertType({
'@font-face': {
fontFamily: 'My Font',
src: `url(my_font.woff)`,
},
});

// Styles with fallbacks
//

assertType({
body: {
display: ['flex', '-webkit-flex'],
},
});
19 changes: 19 additions & 0 deletions packages/core/src/makeStaticStyles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,23 @@ describe('makeStaticStyles', () => {
}
`);
});

it('fallback values', () => {
const useStyles = makeStaticStyles({
body: {
background: 'blue',
overflowY: ['scroll', 'hidden'],
},
});

useStyles({ renderer });

expect(renderer).toMatchInlineSnapshot(`
/** bucket "d" {"data-priority":"0"} **/
body {
background: blue;
overflow-y: hidden;
}
`);
});
});
16 changes: 16 additions & 0 deletions packages/core/src/runtime/resolveStaticStyleRules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,20 @@ describe('resolveStaticStyleRules', () => {
]
`);
});

it('handles fallbacks', () => {
expect(
resolveStaticStyleRules([
{
body: {
display: ['flex', '-webkit-flex'],
},
},
]),
).toMatchInlineSnapshot(`
Array [
"body{display:flex;display:-webkit-flex;}",
]
`);
});
});
11 changes: 7 additions & 4 deletions packages/core/src/runtime/utils/cssifyObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ export function cssifyObject(style: GriffelStyle | GriffelStaticStyle) {
// eslint-disable-next-line guard-for-in
for (const property in style) {
const value = style[property as keyof GriffelStyle];

if (typeof value !== 'string' && typeof value !== 'number') {
if (typeof value === 'string' || typeof value === 'number') {
css += hyphenateProperty(property) + ':' + value + ';';
continue;
}

css += hyphenateProperty(property) + ':' + value + ';';
if (Array.isArray(value)) {
for (const arrValue of value) {
css += hyphenateProperty(property) + ':' + arrValue + ';';
}
}
}

return css;
Expand Down
3 changes: 2 additions & 1 deletion packages/style-types/src/legacy/makeStaticStyles.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type * as CSS from 'csstype';
import type { Fallback, GriffelStylesCSSValue } from '../shared';

//
// Types for makeStaticStyles()
// ---
//

export type GriffelStaticStyle = {
[key: string]: CSS.Properties &
[key: string]: (CSS.Properties | Fallback<CSS.Properties<GriffelStylesCSSValue>>) &
// TODO Questionable: how else would users target their own children?
Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
} & {
Expand Down
3 changes: 2 additions & 1 deletion packages/style-types/src/makeStaticStyles.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type * as CSS from 'csstype';
import type { GriffelStylesCSSValue, Fallback } from './shared';

//
// Types for makeStaticStyles()
// ---
//

export type GriffelStaticStyle = {
[key: string]: CSS.Properties &
[key: string]: (CSS.Properties | Fallback<CSS.Properties<GriffelStylesCSSValue>>) &
// TODO Questionable: how else would users target their own children?
Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
} & {
Expand Down

0 comments on commit f545363

Please sign in to comment.