forked from microsoft/fast
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adding directional stylesheet behavior (microsoft#3559)
* adding directional stylesheet behavior * fixing documentation * Update packages/web-components/fast-components/docs/design/localization.md Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com> * align imports and doc links Co-authored-by: nicholasrice <nicholasrice@users.noreply.github.com> Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>
- Loading branch information
1 parent
6c6ec43
commit 74c19af
Showing
6 changed files
with
197 additions
and
1 deletion.
There are no files selected for viewing
53 changes: 53 additions & 0 deletions
53
packages/web-components/fast-components/docs/design/localization.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
--- | ||
id: localization | ||
title: Localization | ||
custom_edit_url: https://github.com/microsoft/fast/edit/master/packages/web-components/fast-components/docs/design/localization.md | ||
--- | ||
|
||
## Document Direction | ||
Many CSS layout properties like [flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) and [CSS grid](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout) automatically handle reflow depending on the [document's primary direction](https://www.w3.org/International/questions/qa-html-dir). There are also CSS [logical properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties/Basic_concepts) that can be used as well to apply localized margins, paddings, borders and positioning. Unfortunately, browser support for these properties is limited and there are still styling cases not covered by these properties (directional glyphs, transforms, etc). That is why FAST provides several mechanisms to apply direction-based styles. | ||
|
||
### DesignSystemProvider | ||
The [`FASTDesignSystemProvider`](/docs/api/fast-components.fastdesignsystemprovider/) exposes a `direction` property. This should be set to the primary document direction and defaults to `ltr`. This value will be used to inform the stylesheet behaviors described below. | ||
|
||
### `inlineStartBehavior` and `inlineEndBehavior` | ||
[inlineStartBehavior](/docs/api/fast-components.inlinestartbehavior/) and [inlineEndBehavior](/docs/api/fast-components.inlineendbehavior/) can be used to apply localized [float](https://developer.mozilla.org/en-US/docs/Web/CSS/float) properties. These are drop-in replacements for the browsers `inline-start` and `inline-end` float values and should be used when the native values are not supported. If your browser-matrix supports `inline-start` and `inline-end` float values, please use the native values. | ||
|
||
**Example: Using `inlineStartBehavior` and `inlineEndBehavior`** | ||
```ts | ||
import { css } from "@microsoft/fast-element"; | ||
import { inlineStartBehavior } from "@microsoft/fast-components"; | ||
|
||
const styles = css` | ||
:host { | ||
float: ${inlineStartBehavior.var} | ||
} | ||
`.withBehaviors(inlineStartBehavior) | ||
``` | ||
|
||
### DirectionalStyleSheetBehavior | ||
[`DirectionalStyleSheetBehavior`](/docs/api/fast-foundation.directionalstylesheetbehavior/) can be used to apply arbitrary LTR and RTL stylesheets, depending on the nearest [`FASTDesignSystemProvider`s direction](/docs/api/fast-components.fastdesignsystemprovider.direction/) property. | ||
|
||
**Example: Using `DirectionalStyleSheetBehavior`** | ||
```ts | ||
import { css } from "@microsoft/fast-element"; | ||
import { DirectionalStyleSheetBehavior } from "@microsoft/fast-components"; | ||
|
||
const ltr = css` | ||
:host { | ||
left: 20px; | ||
} | ||
`; | ||
|
||
const rtl = css` | ||
:host { | ||
right: 20px; | ||
} | ||
`; | ||
|
||
const styles = css` | ||
.host { | ||
position: relative | ||
} | ||
`.withBehaviors(new DirectionalStyleSheetBehavior(ltr, rtl)) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
packages/web-components/fast-foundation/src/utilities/style/direction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { | ||
ElementStyles, | ||
Behavior, | ||
FASTElement, | ||
Subscriber, | ||
Observable, | ||
} from "@microsoft/fast-element"; | ||
import { DesignSystemProvider } from "../../design-system-provider"; | ||
import { Direction } from "@microsoft/fast-web-utilities"; | ||
|
||
/** | ||
* Behavior to conditionally apply LTR and RTL stylesheets. To determine which to apply, | ||
* the behavior will use the nearest DesignSystemProvider's 'direction' design system value. | ||
* | ||
* @public | ||
* @example | ||
* ```ts | ||
* import { css } from "@microsoft/fast-element"; | ||
* import { DirectionalStyleSheetBehavior } from "@microsoft/fast-foundation"; | ||
* | ||
* css` | ||
* // ... | ||
* `.withBehaviors(new DirectionalStyleSheetBehavior( | ||
* css`:host { content: "ltr"}`), | ||
* css`:host { content: "rtl"}`), | ||
* ) | ||
* ``` | ||
*/ | ||
export class DirectionalStyleSheetBehavior implements Behavior { | ||
private ltr: ElementStyles | null; | ||
private rtl: ElementStyles | null; | ||
private cache: WeakMap< | ||
HTMLElement, | ||
[DesignSystemProvider, DirectionalStyleSheetBehaviorSubscription] | ||
> = new WeakMap(); | ||
|
||
constructor(ltr: ElementStyles | null, rtl: ElementStyles | null) { | ||
this.ltr = ltr; | ||
this.rtl = rtl; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
public bind(source: typeof FASTElement & HTMLElement) { | ||
const provider = DesignSystemProvider.findProvider(source); | ||
|
||
if (provider !== null) { | ||
if (provider.$fastController && provider.$fastController.isConnected) { | ||
this.attach(source, provider); | ||
} else { | ||
if (!Array.isArray(provider.disconnectedRegistry)) { | ||
provider.disconnectedRegistry = []; | ||
} | ||
|
||
provider.disconnectedRegistry.push(this.attach.bind(this, source)); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
public unbind(source: typeof FASTElement & HTMLElement) { | ||
const cache = this.cache.get(source); | ||
|
||
if (cache) { | ||
Observable.getNotifier(cache[0].designSystem).unsubscribe(cache[1]); | ||
} | ||
} | ||
|
||
private attach( | ||
source: typeof FASTElement & HTMLElement, | ||
provider: DesignSystemProvider | ||
) { | ||
const subscriber = new DirectionalStyleSheetBehaviorSubscription( | ||
this.ltr, | ||
this.rtl, | ||
source | ||
); | ||
Observable.getNotifier(provider.designSystem).subscribe(subscriber, "direction"); | ||
subscriber.attach(provider.designSystem["direction"]); | ||
|
||
this.cache.set(source, [provider, subscriber]); | ||
} | ||
} | ||
|
||
/** | ||
* Subscription for {@link DirectionalStyleSheetBehavior} | ||
*/ | ||
class DirectionalStyleSheetBehaviorSubscription implements Subscriber { | ||
private attached: ElementStyles | null = null; | ||
|
||
constructor( | ||
private ltr: ElementStyles | null, | ||
private rtl: ElementStyles | null, | ||
private source: HTMLElement | ||
) {} | ||
|
||
public handleChange(source: any) { | ||
this.attach(source.direction); | ||
} | ||
|
||
public attach(direction: Direction) { | ||
if (this.attached !== this[direction] && this.source?.shadowRoot) { | ||
this.attached?.removeStylesFrom(this.source.shadowRoot); | ||
this[direction]?.addStylesTo(this.source.shadowRoot); | ||
this.attached = this[direction]; | ||
} | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
packages/web-components/fast-foundation/src/utilities/style/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from "./disabled"; | ||
export * from "./display"; | ||
export * from "./focus"; | ||
export * from "./direction"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters