Skip to content

Commit 009e122

Browse files
Sprinkles: Add support for container query conditions (#812)
1 parent 2a23ce4 commit 009e122

File tree

6 files changed

+413
-284
lines changed

6 files changed

+413
-284
lines changed

.changeset/fluffy-steaks-yell.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
'@vanilla-extract/sprinkles': minor
3+
---
4+
5+
Add support for container query conditions
6+
7+
**Example usage**
8+
9+
```ts
10+
import {
11+
createContainer,
12+
style
13+
} from '@vanilla-extract/css';
14+
import { defineProperties } from '@vanilla-extract/sprinkles';
15+
16+
const containerName = createContainer();
17+
18+
export const container = style({
19+
containerName,
20+
containerType: 'size'
21+
});
22+
23+
const containerProperties = defineProperties({
24+
conditions: {
25+
small: {},
26+
medium: {
27+
'@container': `${containerName} (min-width: 768px)`
28+
},
29+
large: {
30+
'@container': `${containerName} (min-width: 1024px)`
31+
}
32+
},
33+
defaultCondition: 'small'
34+
// etc.
35+
});
36+
```

fixtures/sprinkles/src/index.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,28 @@ import {
44
normalizeResponsiveValue,
55
preComposedSprinkles,
66
preComposedSprinklesUsedInSelector,
7+
container,
78
} from './styles.css';
89
import testNodes from '../test-nodes.json';
910

1011
function render() {
1112
document.body.innerHTML = `
12-
<div id="${testNodes.root}" class="${sprinkles({
13-
display: normalizeResponsiveValue('block').mobile,
14-
paddingTop: mapResponsiveValue(
15-
{
16-
mobile: 'small',
17-
desktop: 'medium',
18-
} as const,
19-
(x) => x,
20-
),
21-
})}">
22-
Sprinkles
13+
<div id="${testNodes.root}" class="${container}">
14+
<div class="${sprinkles({
15+
display: normalizeResponsiveValue('block').mobile,
16+
paddingTop: mapResponsiveValue(
17+
{
18+
mobile: 'small',
19+
desktop: 'medium',
20+
} as const,
21+
(x) => x,
22+
),
23+
})}">
24+
Sprinkles
25+
</div>
26+
<div class="${preComposedSprinkles}">Precomposed sprinkles</div>
27+
<div class="${preComposedSprinklesUsedInSelector}">Precomposed Sprinkles Used In Selector</div>
2328
</div>
24-
<div class="${preComposedSprinkles}">Precomposed sprinkles</div>
25-
<div class="${preComposedSprinklesUsedInSelector}">Precomposed Sprinkles Used In Selector</div>
2629
`;
2730
}
2831

fixtures/sprinkles/src/styles.css.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { globalStyle, createVar } from '@vanilla-extract/css';
1+
import {
2+
globalStyle,
3+
createVar,
4+
createContainer,
5+
style,
6+
} from '@vanilla-extract/css';
27
import {
38
defineProperties,
49
createSprinkles,
@@ -9,14 +14,23 @@ import {
914
const alpha = createVar();
1015
const textAlpha = createVar();
1116

17+
const containerName = createContainer();
18+
19+
export const container = style({
20+
containerName,
21+
containerType: 'size',
22+
});
23+
1224
const responsiveProperties = defineProperties({
1325
defaultCondition: 'mobile',
1426
conditions: {
1527
mobile: {},
1628
tablet: {
29+
'@container': `${containerName} (min-width: 768px)`,
1730
'@media': 'screen and (min-width: 768px)',
1831
},
1932
desktop: {
33+
'@container': `${containerName} (min-width: 1024px)`,
2034
'@media': 'screen and (min-width: 1024px)',
2135
},
2236
darkDesktop: {
@@ -87,6 +101,10 @@ export const preComposedSprinklesUsedInSelector = sprinkles({
87101
paddingTop: 'medium',
88102
});
89103

90-
globalStyle(`body > ${preComposedSprinklesUsedInSelector}`, {
104+
globalStyle('body', {
105+
margin: 0,
106+
});
107+
108+
globalStyle(`body ${preComposedSprinklesUsedInSelector}`, {
91109
background: 'red',
92110
});

packages/sprinkles/src/index.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,14 @@ import { SprinklesProperties, ResponsiveArrayConfig } from './types';
1616
export { createNormalizeValueFn, createMapValueFn } from './createUtils';
1717
export type { ConditionalValue, RequiredConditionalValue } from './createUtils';
1818

19-
interface Condition {
20-
'@media'?: string;
21-
'@supports'?: string;
22-
selector?: string;
23-
}
19+
type ConditionKey = '@media' | '@supports' | '@container' | 'selector';
20+
type Condition = Partial<Record<ConditionKey, string>>;
2421

2522
type BaseConditions = { [conditionName: string]: Condition };
2623

2724
type AtomicProperties = {
2825
[Property in keyof CSSProperties]?:
29-
| Record<
30-
string,
31-
| CSSProperties[Property]
32-
| Omit<StyleRule, 'selectors' | '@media' | '@supports'>
33-
>
26+
| Record<string, CSSProperties[Property] | Omit<StyleRule, ConditionKey>>
3427
| ReadonlyArray<CSSProperties[Property]>;
3528
};
3629

@@ -262,6 +255,14 @@ export function defineProperties(options: any): any {
262255
};
263256
}
264257

258+
if (condition['@container']) {
259+
styleValue = {
260+
'@container': {
261+
[condition['@container']]: styleValue,
262+
},
263+
};
264+
}
265+
265266
if (condition['@media']) {
266267
styleValue = {
267268
'@media': {

site/docs/packages/sprinkles.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,9 @@ const responsiveProperties = defineProperties({
383383

384384
### conditions
385385

386-
Define a set of media/feature queries for the provided properties.
386+
Define a set of media/feature/container queries for the provided properties.
387+
388+
For example, properties can be scoped to media queries.
387389

388390
```ts
389391
// sprinkles.css.ts
@@ -417,6 +419,40 @@ const properties = defineProperties({
417419
});
418420
```
419421

422+
Properties can also be scoped to container queries.
423+
424+
> 🚧&nbsp;&nbsp;Ensure your target browsers [support container queries]. Vanilla-extract supports the [container query syntax] but does not polyfill the feature in unsupported browsers.
425+
426+
```ts
427+
// sprinkles.css.ts
428+
import {
429+
createContainer,
430+
style
431+
} from '@vanilla-extract/css';
432+
import { defineProperties } from '@vanilla-extract/sprinkles';
433+
434+
const containerName = createContainer();
435+
436+
export const container = style({
437+
containerName,
438+
containerType: 'size'
439+
});
440+
441+
const containerProperties = defineProperties({
442+
conditions: {
443+
small: {},
444+
medium: {
445+
'@container': `${containerName} (min-width: 768px)`
446+
},
447+
large: {
448+
'@container': `${containerName} (min-width: 1024px)`
449+
}
450+
},
451+
defaultCondition: 'small'
452+
// etc.
453+
});
454+
```
455+
420456
### defaultCondition
421457

422458
Defines which condition(s) should be used when a non-conditional value is requested, e.g. `sprinkles({ display: 'flex' })`.
@@ -735,3 +771,5 @@ const e: ResponsiveAlign = { desktop: 'center' };
735771

736772
[tailwind]: https://tailwindcss.com
737773
[styled system]: https://styled-system.com
774+
[support container queries]: https://caniuse.com/css-container-queries
775+
[container query syntax]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries

0 commit comments

Comments
 (0)