Skip to content

Commit

Permalink
feat(layout): add hover and any-hover predefined media queries
Browse files Browse the repository at this point in the history
  • Loading branch information
smalluban committed Jul 5, 2024
1 parent 8b1f308 commit b3dc67c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
67 changes: 31 additions & 36 deletions docs/component-model/layout-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ It focuses on "invisible" CSS rules, like display types, alignments, positioning

## Usage

Add `<template layout></template>` element wrapper with at least one empty `layout` attribute to the root template of the component. The `<template>` element represents the host element, which also can be styled:
You must add `<template layout></template>` element wrapper with at least one empty `layout` attribute to the root template of the component. The `<template>` element represents the host element, which also can be styled:

```js
define({
Expand All @@ -19,26 +19,11 @@ define({
});
```

When the template is compiled, a group of attributes (`layout*="..."`) containing the layout rules compiles to single unique class selector added to the element. Generated selectors are shared between all of the component instances, regardless if the Shadow DOM is used or not. If the browser supports Constructable Stylesheets, the generated CSS is added to the global single shared stylesheet, which makes the styling the fastest possible.
While the template compiles, a group of attributes (`layout*="..."`) containing the layout rules resolve to a single unique class selector added to the element. Generated selectors are shared between all of the component instances (regardless if the Shadow DOM is used or not). If the browser supports Constructable Stylesheets, the generated CSS is added to the global single shared stylesheet, which makes the styling the fastest possible.

## Targets
### Other Styles

The feature supports both `content` and `render` properties of the component's definition. Styling `content` is especially useful for creating layouts in app views, which don't require Shadow DOM:

```js
define({
tag: "my-app-view",
render: () => html`
<template layout="column">
...
</template>
`,
});
```

### Mixing

If it is required, or preferred to use layout engine inside of the UI components, you can mix the approach with other styling technics. Styles generated by template helpers are addded after the layout engine generated styles.
When using layout engine inside of the UI components, you can still mix the approach with other styling technics. Styles generated by the template helpers are added after the layout engine styles:

```js
define({
Expand All @@ -57,7 +42,13 @@ define({

## Compound Selectors

The `layout` attribute does not support expressions as the value, because the process takes place when the template is compiled (before it runs for the first time with arguments). However, the attribute can be extended with compound selector. The rules will apply only if the conditions are met:
```html
<div layout.selector=""></div>
```

The `layout` attribute name can be extended with any correct CSS selector, which does not contain space character.

Value of the attribute does not support expressions, as the compilation process takes place before the function runs for the first time with arguments. However, the selector is added to the generated class selector, so the rules will apply only if the conditions are met:

```js
define({
Expand All @@ -82,7 +73,7 @@ define({
});
```

The compound selector is place as-is into the generated class selector, so any supported CSS selector can be used, like pseudo-classes, etc:
Any supported CSS selector can be used, like pseudo-classes, etc:

```html
<div layout:first-child="margin:0"></div>
Expand All @@ -91,21 +82,25 @@ The compound selector is place as-is into the generated class selector, so any s

## Media Queries

In the similar way to the compound selector, the layout supports media queries with the value followed by `@` character. Not predefined values maps to `min-width` media query:

```html
<div layout="row gap" layout@768px="column gap:2"></div>
```

The layout engine comes with `portrait` and `landscape` built-in queries:
The media queries are supported by the part of the `layout` attribute followed by `@` character. For the convenience, the engine defaults to `min-width` media query, but it also supports predefined values:

* `portrait` - `@media screen and (orientation: portrait)`
* `landscape` - `@media screen and (orientation: landscape)`
* `hover` - `@media screen and (hover: hover)`
* `any-hover` - `@media screen and (any-hover: hover)`
* `[value]` - `@media screen and (min-width: [value])`

```html
<div layout="row" layout@portrait="column gap:2" layout@landscape="row gap:3"></div>
```

## Arguments

The attribute value contains space-separated list of rules. The rules are applied in the order they are added to the attribute. The rules comes with useful predefined arguments, but depending on the rule, they can take a list of arguments separated by `:` character (without the whitespace):
The attribute value contains space-separated list of rules. The rules are applied in the order they appear in the attribute. The rules comes with useful predefined arguments, but depending on the rule, they can take a list of arguments separated by `:` character (without the whitespace):

```html
<div layout="column gap:3 items:center width:full:100px"></div>
Expand All @@ -122,17 +117,17 @@ If the rule supports more than one argument, you can skip it by omitting the val
If the argument type is dimension, the engine maps it with the following order:

1. Predefined strings maps to corresponding values:
* `min` -> `min-content`
* `max` -> `max-content`
* `fit` -> `fit-content`
* `full` -> `100%`
* `min` -> `min-content`
* `max` -> `max-content`
* `fit` -> `fit-content`
* `full` -> `100%`
2. A number without the type suffix maps to the multiplication of `8px`:
* `0` -> `0px`
* `0.5` -> `4px`
* `1` -> `8px`
* `2` -> `16px`
* `3` -> `24px`
* ...
* `0` -> `0px`
* `0.5` -> `4px`
* `1` -> `8px`
* `2` -> `16px`
* `3` -> `24px`
* ...
3. Provided value is used as is.

## CSS Variables
Expand Down Expand Up @@ -249,7 +244,7 @@ Use following examples as a reference:

## Generic Values

You can extend ruleset supported by the layout engine by using special empty rule `::`. It generates a CSS property with a value set to CSS variable based on its name. In another words, it allows to use predefined design tokens, which points any CSS properties.
You can extend ruleset supported by the layout engine by using special empty rule `::`. It generates a CSS property with a value set to CSS variable based on its name. In another words, it allows to use predefined design tokens, which points to any CSS properties.

| Rule | Arguments | Properties |
|--------|--------------------------------|--------------------------------|
Expand Down
2 changes: 2 additions & 0 deletions src/template/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ const dimensions = {
const queries = {
portrait: "orientation: portrait",
landscape: "orientation: landscape",
hover: "hover: hover",
"any-hover": "any-hover: hover",
};

function dimension(value) {
Expand Down

0 comments on commit b3dc67c

Please sign in to comment.