Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for style module media query variations #73

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Initial support for style module media query variations",
"packageName": "@adaptive-web/adaptive-ui",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Initial support for style module media query variations",
"packageName": "@adaptive-web/adaptive-web-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/adaptive-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"dependencies": {
"@microsoft/fast-element": "2.0.0-beta.26",
"@microsoft/fast-foundation": "3.0.0-alpha.31",
"@microsoft/fast-web-utilities": "^6.0.0",
"culori": "^3.2.0"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/adaptive-ui/src/design-tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export * from "./density.js";
export * from "./elevation.js";
export * from "./layer.js";
export * from "./modules.js";
export * from "./modules.forced-colors.js";
export * from "./palette.js";
export * from "./type.js";
60 changes: 60 additions & 0 deletions packages/adaptive-ui/src/design-tokens/modules.forced-colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { SystemColors } from "@microsoft/fast-web-utilities";
import { InteractiveSet } from "../types.js";
import { Styles } from "../modules/styles.js";

/**
* Convenience function for styles that share rest/focus and hover/active states.
*
* @param restAndFocus - The value to use for rest and focus states.
* @param hoverAndActive - The value to use for hover and active states.
* @returns A full interactive color set.
*/
function set(
restAndFocus: string,
hoverAndActive: string,
): InteractiveSet<string> {
return {
rest: restAndFocus,
hover: hoverAndActive,
active: hoverAndActive,
focus: restAndFocus,
disabled: SystemColors.GrayText,
};
}

/**
* @public
*/
export const forcedColorsButtonStyles: Styles = Styles.fromProperties({
backgroundFill: {
...set(SystemColors.ButtonFace, SystemColors.HighlightText),
},
foregroundFill: {
...set(SystemColors.ButtonText, SystemColors.Highlight),
},
borderFill: {
...set(SystemColors.ButtonText, SystemColors.Highlight),
},
});

/**
* @public
*/
export const forcedColorsHighlightStyles: Styles = Styles.fromProperties({
backgroundFill: {
...set(SystemColors.Highlight, SystemColors.ButtonFace),
},
foregroundFill: {
...set(SystemColors.HighlightText, SystemColors.ButtonText),
},
borderFill: {
...set(SystemColors.Highlight, SystemColors.ButtonText),
},
});

/**
* @public
*/
export const forcedColorsTextStyles: Styles = Styles.fromProperties({
foregroundFill: SystemColors.CanvasText,
});
11 changes: 11 additions & 0 deletions packages/adaptive-ui/src/design-tokens/modules.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { MediaQuery } from "../modules/css.js";
import { BorderFill, BorderStyle, BorderThickness, CornerRadius, Fill, Padding, Styles, StyleValue } from "../modules/styles.js";
import { cornerRadiusControl, cornerRadiusLayer, focusStrokeThickness, strokeThickness } from "./appearance.js";
import {
Expand Down Expand Up @@ -101,6 +102,7 @@ import {
typeRampPlus6FontVariations,
typeRampPlus6LineHeight,
} from "./type.js";
import { forcedColorsButtonStyles, forcedColorsHighlightStyles, forcedColorsTextStyles } from "./modules.forced-colors.js";

/**
* Style module for the shape of a control.
Expand Down Expand Up @@ -1330,6 +1332,9 @@ export const selectableSelectedStyles: Styles = Styles.compose(
],
undefined,
"styles.selectable-control-selected",
).withMediaQuery(
MediaQuery.ForcedColors,
forcedColorsHighlightStyles,
);

/**
Expand All @@ -1343,6 +1348,9 @@ export const selectableUnselectedStyles: Styles = Styles.compose(
],
undefined,
"styles.selectable-control-unselected",
).withMediaQuery(
MediaQuery.ForcedColors,
forcedColorsButtonStyles,
);

/**
Expand All @@ -1369,6 +1377,9 @@ export const plainTextStyles: Styles = Styles.compose(
],
undefined,
"styles.text-plain",
).withMediaQuery(
MediaQuery.ForcedColors,
forcedColorsTextStyles,
);

/**
Expand Down
9 changes: 9 additions & 0 deletions packages/adaptive-ui/src/modules/css.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { StyleProperty } from "./types.js";

/**
* Convenience media queries for {@link Styles} variations.
*/
export const MediaQuery = {
ForcedColors: "(forced-colors)",
ColorsDark: "(prefers-color-scheme: dark)",
ColorsLight: "(prefers-color-scheme: light)",
} as const;

/**
* Converts a {@link StyleProperty} to a css property name.
*
Expand Down
13 changes: 11 additions & 2 deletions packages/adaptive-ui/src/modules/element-styles-renderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComposableStyles, css, HostBehavior } from "@microsoft/fast-element";
import { type CSSDirective, ElementStyles } from "@microsoft/fast-element";
import { CSSDesignToken } from "@microsoft/fast-foundation";
import { CSSDesignToken, MatchMediaStyleSheetBehavior } from "@microsoft/fast-foundation";
import { Interactivity, type InteractivityDefinition, type StyleModuleTarget, StyleProperty } from "../modules/types.js";
import type { InteractiveSet } from "../types.js";
import { makeSelector } from "./selector.js";
Expand Down Expand Up @@ -184,8 +184,17 @@ export class ElementStylesRenderer {
*/
public static renderStyleRules(baseStyles: ComposableStyles[] = [], styleRules: StyleRules, anatomy?: ComponentAnatomy<any, any>) {
for (const rule of styleRules) {
const target = rule.target || {};
const styles = Styles.fromDeclaration(rule);
const renderedStyles = new ElementStylesRenderer(styles).render(rule.target || {}, anatomy?.interactivity);
const renderedStyles = new ElementStylesRenderer(styles).render(target, anatomy?.interactivity);

styles.getMediaQueryStyles()?.forEach((queryStyles, query) => {
const queryRenderedStyles = new ElementStylesRenderer(queryStyles).render(target, anatomy?.interactivity);
renderedStyles.withBehaviors(
MatchMediaStyleSheetBehavior.with(
window.matchMedia(query))(queryRenderedStyles))
});

baseStyles.push(renderedStyles);
}

Expand Down
26 changes: 26 additions & 0 deletions packages/adaptive-ui/src/modules/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ export class Styles {
private _properties?: StylePropertiesMap;
// Effective properties from composed styles and additional properties
private _composedProperties?: StylePropertiesMap;
// Style overrides for a media query
private _mediaQueryVariations: Map<string, Styles>;

private constructor(
/**
Expand Down Expand Up @@ -266,6 +268,30 @@ export class Styles {
this.createEffectiveProperties();
}

/**
* Adds a style variation for a media query like `forced-colors`.
*
* @param query - The media query, see {@link MediaQuery}.
* @param styles - The styles to apply for the provided media query
* @returns The `Styles` definition with media query variation.
*/
public withMediaQuery(query: string, styles: Styles): this {
if (!this._mediaQueryVariations) {
this._mediaQueryVariations = new Map();
}
this._mediaQueryVariations.set(query, styles);
return this;
}

/**
* Gets the media query variations for this style.
*
* @returns The defined media query variations.
*/
public getMediaQueryStyles(): ReadonlyMap<string, Styles> | undefined {
return this._mediaQueryVariations;
}

/**
* Gets the full effective set of properties, from composed styles and local properties as applicable.
*/
Expand Down