Skip to content

Commit

Permalink
Add @container query support (#437)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkReeder committed Oct 2, 2023
1 parent b552ddc commit 185ef78
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 18 deletions.
Expand Up @@ -232,6 +232,23 @@ function injectFixtureStyles(styletron) {
},
},
});
styletron.renderStyle({
"@container (min-width: 800px)": {
color: "yellow",
},
});
styletron.renderStyle({
"@container (min-width: 600px)": {
color: "blue",
},
});
styletron.renderStyle({
"@container (min-width: 800px)": {
":hover": {
color: "yellow",
},
},
});
styletron.renderStyle({
":hover": {
display: "none",
Expand Down
7 changes: 5 additions & 2 deletions packages/styletron-engine-atomic/src/inject-style-prefixed.ts
Expand Up @@ -77,13 +77,16 @@ export default function injectStylePrefixed(
media,
pseudo + originalKey,
);
} else if (originalKey.substring(0, 6) === "@media") {
} else if (
originalKey.substring(0, 6) === "@media" ||
originalKey.substring(0, 10) === "@container"
) {
classString +=
" " +
injectStylePrefixed(
styleCache,
originalVal as StyleObject,
originalKey.substr(7),
originalKey,
pseudo,
);
}
Expand Down
64 changes: 49 additions & 15 deletions packages/styletron-engine-atomic/src/server/__tests__/tests.node.ts
Expand Up @@ -6,17 +6,17 @@ test("StyletronServer toCss", () => {

injectFixtureStyles(styletron);
expect(styletron.getCss()).toBe(
".ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}@media (min-width: 600px){.ah{color:red}}@media (min-width: 800px){.ag{color:green}.ai:hover{color:green}}",
".ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}@container (min-width: 600px){.ak{color:blue}}@media (min-width: 600px){.ah{color:red}}@container (min-width: 800px){.aj{color:yellow}.al:hover{color:yellow}}@media (min-width: 800px){.ag{color:green}.ai:hover{color:green}}",
);

injectFixtureStyles(styletron);
expect(styletron.getCss()).toBe(
".ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}@media (min-width: 600px){.ah{color:red}}@media (min-width: 800px){.ag{color:green}.ai:hover{color:green}}",
".ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}@container (min-width: 600px){.ak{color:blue}}@media (min-width: 600px){.ah{color:red}}@container (min-width: 800px){.aj{color:yellow}.al:hover{color:yellow}}@media (min-width: 800px){.ag{color:green}.ai:hover{color:green}}",
);

injectFixtureKeyframes(styletron);
expect(styletron.getCss()).toBe(
"@keyframes ae{from{color:purple}50%{color:yellow}to{color:orange}}.ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}@media (min-width: 600px){.ah{color:red}}@media (min-width: 800px){.ag{color:green}.ai:hover{color:green}}",
"@keyframes ae{from{color:purple}50%{color:yellow}to{color:orange}}.ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}@container (min-width: 600px){.ak{color:blue}}@media (min-width: 600px){.ah{color:red}}@container (min-width: 800px){.aj{color:yellow}.al:hover{color:yellow}}@media (min-width: 800px){.ag{color:green}.ai:hover{color:green}}",
);
});

Expand All @@ -27,13 +27,18 @@ test("StyletronServer getStylesheets", () => {
injectFixtureStyles(styletron);
expect(styletron.getStylesheets()).toEqual([
{
css: ".ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}",
css: ".ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}",
attrs: {},
},
{css: ".ah{color:red}", attrs: {media: "(min-width: 600px)"}},
{css: ".ak{color:blue}", attrs: {media: "@container (min-width: 600px)"}},
{css: ".ah{color:red}", attrs: {media: "@media (min-width: 600px)"}},
{
css: ".aj{color:yellow}.al:hover{color:yellow}",
attrs: {media: "@container (min-width: 800px)"},
},
{
css: ".ag{color:green}.ai:hover{color:green}",
attrs: {media: "(min-width: 800px)"},
attrs: {media: "@media (min-width: 800px)"},
},
]);

Expand All @@ -44,13 +49,18 @@ test("StyletronServer getStylesheets", () => {
attrs: {"data-hydrate": "keyframes"},
},
{
css: ".ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}",
css: ".ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}",
attrs: {},
},
{css: ".ah{color:red}", attrs: {media: "(min-width: 600px)"}},
{css: ".ak{color:blue}", attrs: {media: "@container (min-width: 600px)"}},
{css: ".ah{color:red}", attrs: {media: "@media (min-width: 600px)"}},
{
css: ".aj{color:yellow}.al:hover{color:yellow}",
attrs: {media: "@container (min-width: 800px)"},
},
{
css: ".ag{color:green}.ai:hover{color:green}",
attrs: {media: "(min-width: 800px)"},
attrs: {media: "@media (min-width: 800px)"},
},
]);

Expand All @@ -65,13 +75,18 @@ test("StyletronServer getStylesheets", () => {
attrs: {"data-hydrate": "font-face"},
},
{
css: ".ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}",
css: ".ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}",
attrs: {},
},
{css: ".ah{color:red}", attrs: {media: "(min-width: 600px)"}},
{css: ".ak{color:blue}", attrs: {media: "@container (min-width: 600px)"}},
{css: ".ah{color:red}", attrs: {media: "@media (min-width: 600px)"}},
{
css: ".aj{color:yellow}.al:hover{color:yellow}",
attrs: {media: "@container (min-width: 800px)"},
},
{
css: ".ag{color:green}.ai:hover{color:green}",
attrs: {media: "(min-width: 800px)"},
attrs: {media: "@media (min-width: 800px)"},
},
]);
});
Expand All @@ -84,17 +99,17 @@ test("StyletronServer getStylesheetsHtml ", () => {

injectFixtureStyles(styletron);
expect(styletron.getStylesheetsHtml()).toBe(
'<style class="_styletron_hydrate_">.ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}</style><style class="_styletron_hydrate_" media="(min-width: 600px)">.ah{color:red}</style><style class="_styletron_hydrate_" media="(min-width: 800px)">.ag{color:green}.ai:hover{color:green}</style>',
'<style class="_styletron_hydrate_">.ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}</style><style class="_styletron_hydrate_" media="@container (min-width: 600px)">.ak{color:blue}</style><style class="_styletron_hydrate_" media="@media (min-width: 600px)">.ah{color:red}</style><style class="_styletron_hydrate_" media="@container (min-width: 800px)">.aj{color:yellow}.al:hover{color:yellow}</style><style class="_styletron_hydrate_" media="@media (min-width: 800px)">.ag{color:green}.ai:hover{color:green}</style>',
);

injectFixtureKeyframes(styletron);
expect(styletron.getStylesheetsHtml()).toBe(
'<style class="_styletron_hydrate_" data-hydrate="keyframes">@keyframes ae{from{color:purple}50%{color:yellow}to{color:orange}}</style><style class="_styletron_hydrate_">.ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}</style><style class="_styletron_hydrate_" media="(min-width: 600px)">.ah{color:red}</style><style class="_styletron_hydrate_" media="(min-width: 800px)">.ag{color:green}.ai:hover{color:green}</style>',
'<style class="_styletron_hydrate_" data-hydrate="keyframes">@keyframes ae{from{color:purple}50%{color:yellow}to{color:orange}}</style><style class="_styletron_hydrate_">.ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}</style><style class="_styletron_hydrate_" media="@container (min-width: 600px)">.ak{color:blue}</style><style class="_styletron_hydrate_" media="@media (min-width: 600px)">.ah{color:red}</style><style class="_styletron_hydrate_" media="@container (min-width: 800px)">.aj{color:yellow}.al:hover{color:yellow}</style><style class="_styletron_hydrate_" media="@media (min-width: 800px)">.ag{color:green}.ai:hover{color:green}</style>',
);

injectFixtureFontFace(styletron);
expect(styletron.getStylesheetsHtml()).toBe(
'<style class="_styletron_hydrate_" data-hydrate="keyframes">@keyframes ae{from{color:purple}50%{color:yellow}to{color:orange}}</style><style class="_styletron_hydrate_" data-hydrate="font-face">@font-face{font-family:ae;src:local(\'Roboto\')}</style><style class="_styletron_hydrate_">.ae{color:red}.af{color:green}.aj:hover{display:none}.ak{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.al{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}</style><style class="_styletron_hydrate_" media="(min-width: 600px)">.ah{color:red}</style><style class="_styletron_hydrate_" media="(min-width: 800px)">.ag{color:green}.ai:hover{color:green}</style>',
'<style class="_styletron_hydrate_" data-hydrate="keyframes">@keyframes ae{from{color:purple}50%{color:yellow}to{color:orange}}</style><style class="_styletron_hydrate_" data-hydrate="font-face">@font-face{font-family:ae;src:local(\'Roboto\')}</style><style class="_styletron_hydrate_">.ae{color:red}.af{color:green}.am:hover{display:none}.an{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ao{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}</style><style class="_styletron_hydrate_" media="@container (min-width: 600px)">.ak{color:blue}</style><style class="_styletron_hydrate_" media="@media (min-width: 600px)">.ah{color:red}</style><style class="_styletron_hydrate_" media="@container (min-width: 800px)">.aj{color:yellow}.al:hover{color:yellow}</style><style class="_styletron_hydrate_" media="@media (min-width: 800px)">.ag{color:green}.ai:hover{color:green}</style>',
);
});

Expand Down Expand Up @@ -140,6 +155,25 @@ function injectFixtureStyles(styletron) {
},
},
});
styletron.renderStyle({
"@container (min-width: 800px)": {
color: "yellow",
},
});
// should be added before "min-width: 800px" query
// test that Styletron properly sort container queries
styletron.renderStyle({
"@container (min-width: 600px)": {
color: "blue",
},
});
styletron.renderStyle({
"@container (min-width: 800px)": {
":hover": {
color: "yellow",
},
},
});
styletron.renderStyle({
zIndex: void 0, // Should be silently ignored
});
Expand Down
2 changes: 1 addition & 1 deletion packages/styletron-engine-atomic/src/server/server.ts
Expand Up @@ -171,7 +171,7 @@ function stringify(styleRules, sortedCacheKeys) {
sortedCacheKeys.forEach(cacheKey => {
const rules = styleRules[cacheKey];
if (cacheKey !== "") {
result += `@media ${cacheKey}{${rules}}`;
result += `${cacheKey}{${rules}}`;
} else {
result += rules;
}
Expand Down
Expand Up @@ -28,6 +28,14 @@ test("StyletronSnapshotEngine rendering", () => {
"style={\n '@media (min-width: 800px)': {\n color: 'purple',\n },\n}\n",
);

expect(
instance.renderStyle({
"@container (min-width: 600px)": {color: "purple"},
}),
).toBe(
"style={\n '@container (min-width: 600px)': {\n color: 'purple',\n },\n}\n",
);

expect(
instance.renderFontFace({
src: "local('Roboto')",
Expand Down

0 comments on commit 185ef78

Please sign in to comment.