From 2ba8729473156176840521f1332e98032b3114b0 Mon Sep 17 00:00:00 2001 From: Brian Heston <47367562+bheston@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:16:24 -0800 Subject: [PATCH] Foundation: Update Slider templates (#6800) --- ...-eadfb2dc-2d02-48d8-9106-739f0c3e80d2.json | 7 ++ .../fast-foundation/docs/api-report.md | 6 +- .../src/slider-label/slider-label.template.ts | 27 ++++--- .../src/slider-label/slider-label.ts | 6 +- .../stories/slider-label.register.ts | 20 +++-- .../fast-foundation/src/slider/README.md | 21 ++--- .../src/slider/slider.template.ts | 9 ++- .../fast-foundation/src/slider/slider.ts | 11 +-- .../src/slider/stories/slider.register.ts | 77 ++++++++++--------- .../src/slider/stories/slider.stories.ts | 17 ++++ 10 files changed, 123 insertions(+), 78 deletions(-) create mode 100644 change/@microsoft-fast-foundation-eadfb2dc-2d02-48d8-9106-739f0c3e80d2.json diff --git a/change/@microsoft-fast-foundation-eadfb2dc-2d02-48d8-9106-739f0c3e80d2.json b/change/@microsoft-fast-foundation-eadfb2dc-2d02-48d8-9106-739f0c3e80d2.json new file mode 100644 index 00000000000..eba2d4d9e02 --- /dev/null +++ b/change/@microsoft-fast-foundation-eadfb2dc-2d02-48d8-9106-739f0c3e80d2.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Foundation: Update Slider templates (https://github.com/microsoft/fast/pull/6800)", + "packageName": "@microsoft/fast-foundation", + "email": "47367562+bheston@users.noreply.github.com", + "dependentChangeType": "prerelease" +} diff --git a/packages/web-components/fast-foundation/docs/api-report.md b/packages/web-components/fast-foundation/docs/api-report.md index 03c8ffc9bdf..ebe96754c7a 100644 --- a/packages/web-components/fast-foundation/docs/api-report.md +++ b/packages/web-components/fast-foundation/docs/api-report.md @@ -1887,7 +1887,7 @@ export class FASTSlider extends FormAssociatedSlider implements SliderConfigurat // @internal (undocumented) stepMultiplier: number; // @internal (undocumented) - thumb: HTMLDivElement; + thumbContainer: HTMLDivElement; // @internal (undocumented) track: HTMLDivElement; // @internal (undocumented) @@ -1911,6 +1911,8 @@ export class FASTSlider extends FormAssociatedSlider implements SliderConfigurat export class FASTSliderLabel extends FASTElement { // @internal (undocumented) connectedCallback(): void; + // @internal (undocumented) + container: HTMLDivElement; disabled: boolean; // @internal (undocumented) disconnectedCallback(): void; @@ -1927,8 +1929,6 @@ export class FASTSliderLabel extends FASTElement { // @internal (undocumented) positionStyle: string; // @internal (undocumented) - root: HTMLDivElement; - // @internal (undocumented) sliderDirection: Direction; // @internal (undocumented) sliderMaxPosition: number; diff --git a/packages/web-components/fast-foundation/src/slider-label/slider-label.template.ts b/packages/web-components/fast-foundation/src/slider-label/slider-label.template.ts index facfa9b84c5..bf030caecdb 100644 --- a/packages/web-components/fast-foundation/src/slider-label/slider-label.template.ts +++ b/packages/web-components/fast-foundation/src/slider-label/slider-label.template.ts @@ -8,18 +8,21 @@ import type { FASTSliderLabel } from "./slider-label.js"; export function sliderLabelTemplate(): ElementViewTemplate { return html` `; diff --git a/packages/web-components/fast-foundation/src/slider-label/slider-label.ts b/packages/web-components/fast-foundation/src/slider-label/slider-label.ts index bc559c03efd..aecdc48cb6b 100644 --- a/packages/web-components/fast-foundation/src/slider-label/slider-label.ts +++ b/packages/web-components/fast-foundation/src/slider-label/slider-label.ts @@ -21,7 +21,9 @@ const defaultConfig: SliderConfiguration = { * A label element intended to be used with the {@link @microsoft/fast-foundation#(FASTSlider:class)} component. * * @slot - The default slot for the label content - * @csspart root - The element wrapping the label mark and text + * @csspart container - The element wrapping the label mark and content + * @csspart mark - The element wrapping the label mark + * @csspart content - The element wrapping the label content * * @public */ @@ -35,7 +37,7 @@ export class FASTSliderLabel extends FASTElement { /** * @internal */ - public root: HTMLDivElement; + public container: HTMLDivElement; /** * The position of the label relative to the min and max value of the parent {@link @microsoft/fast-foundation#(FASTSlider:class)}. diff --git a/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.register.ts b/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.register.ts index a598a1c428d..99ddee2d8b9 100644 --- a/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.register.ts +++ b/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.register.ts @@ -9,26 +9,27 @@ const styles = css` color: var(--neutral-foreground-rest); fill: currentcolor; } - .root { - position: absolute; - display: grid; - } + .container { + position: absolute; display: grid; justify-self: center; } - .label { + + .content { justify-self: center; align-self: center; white-space: nowrap; max-width: 30px; } + .mark { width: calc((var(--design-unit) / 4) * 1px); height: calc(var(--height-number) * 0.25 * 1px); background: var(--neutral-stroke-rest); justify-self: center; } + :host([aria-disabled="true"]) { opacity: var(--disabled-opacity); } @@ -42,11 +43,13 @@ const horizontalSliderLabelStyles = css` height: calc((var(--height-number) / 2 + var(--design-unit)) * 1px); width: auto; } + .container { grid-template-rows: auto auto; grid-template-columns: 0; } - .label { + + .content { margin: 2px 0; } `; @@ -59,17 +62,20 @@ const verticalSliderLabelStyles = css` height: auto; width: calc((var(--height-number) / 2 + var(--design-unit)) * 1px); } + .container { grid-template-columns: auto auto; grid-template-rows: 0; min-width: calc(var(--thumb-size) * 1px); height: calc(var(--thumb-size) * 1px); } + .mark { transform: rotate(90deg); align-self: center; } - .label { + + .content { margin-left: calc((var(--design-unit) / 2) * 3px); align-self: center; } diff --git a/packages/web-components/fast-foundation/src/slider/README.md b/packages/web-components/fast-foundation/src/slider/README.md index c59c21a3263..aade9fd14b9 100644 --- a/packages/web-components/fast-foundation/src/slider/README.md +++ b/packages/web-components/fast-foundation/src/slider/README.md @@ -211,12 +211,13 @@ export const mySliderLabel = SliderLabel.compose({ #### CSS Parts -| Name | Description | -| -------------------- | --------------------------------------------------------------- | -| `positioning-region` | The region used to position the elements of the slider | -| `track-container` | The region containing the track elements | -| `track-start` | The element wrapping the track start slot | -| `thumb-container` | The thumb container element which is programatically positioned | +| Name | Description | +| -------------------- | ---------------------------------------------------------------- | +| `positioning-region` | The region used to position the elements of the slider | +| `track` | The region containing the track elements | +| `track-start` | The element wrapping the track start slot | +| `thumb-container` | The thumb container element which is programmatically positioned | +| `thumb` | The thumb element | #### Slots @@ -265,9 +266,11 @@ export const mySliderLabel = SliderLabel.compose({ #### CSS Parts -| Name | Description | -| ------ | -------------------------------------------- | -| `root` | The element wrapping the label mark and text | +| Name | Description | +| ----------- | ----------------------------------------------- | +| `container` | The element wrapping the label mark and content | +| `mark` | The element wrapping the label mark | +| `content` | The element wrapping the label content | #### Slots diff --git a/packages/web-components/fast-foundation/src/slider/slider.template.ts b/packages/web-components/fast-foundation/src/slider/slider.template.ts index ae7654ff7ee..bddcfdb0854 100644 --- a/packages/web-components/fast-foundation/src/slider/slider.template.ts +++ b/packages/web-components/fast-foundation/src/slider/slider.template.ts @@ -21,10 +21,9 @@ export function sliderTemplate( aria-disabled="${x => (x.disabled ? true : void 0)}" aria-readonly="${x => (x.readOnly ? true : void 0)}" aria-orientation="${x => x.orientation}" - class="${x => x.orientation}" >
-
+
(
- ${staticallyCompose(options.thumb)} +
+ ${staticallyCompose(options.thumb)} +
diff --git a/packages/web-components/fast-foundation/src/slider/slider.ts b/packages/web-components/fast-foundation/src/slider/slider.ts index 1bc0b1250a9..b5f7e2660ff 100644 --- a/packages/web-components/fast-foundation/src/slider/slider.ts +++ b/packages/web-components/fast-foundation/src/slider/slider.ts @@ -24,9 +24,10 @@ import { SliderConfiguration, SliderMode } from "./slider.options.js"; * @slot thumb - The slider thumb * @slot - The default slot for labels * @csspart positioning-region - The region used to position the elements of the slider - * @csspart track-container - The region containing the track elements + * @csspart track - The region containing the track elements * @csspart track-start - The element wrapping the track start slot - * @csspart thumb-container - The thumb container element which is programatically positioned + * @csspart thumb-container - The thumb container element which is programmatically positioned + * @csspart thumb - The thumb element * @fires change - Fires a custom 'change' event when the slider value changes * * @public @@ -55,7 +56,7 @@ export class FASTSlider extends FormAssociatedSlider implements SliderConfigurat /** * @internal */ - public thumb: HTMLDivElement; + public thumbContainer: HTMLDivElement; /** * @internal @@ -381,10 +382,10 @@ export class FASTSlider extends FormAssociatedSlider implements SliderConfigurat const eventAction = `${remove ? "remove" : "add"}EventListener`; this[eventAction]("keydown", this.keypressHandler); this[eventAction]("mousedown", this.handleMouseDown); - this.thumb[eventAction]("mousedown", this.handleThumbMouseDown, { + this.thumbContainer[eventAction]("mousedown", this.handleThumbMouseDown, { passive: true, }); - this.thumb[eventAction]("touchstart", this.handleThumbMouseDown, { + this.thumbContainer[eventAction]("touchstart", this.handleThumbMouseDown, { passive: true, }); // removes handlers attached by mousedown handlers diff --git a/packages/web-components/fast-foundation/src/slider/stories/slider.register.ts b/packages/web-components/fast-foundation/src/slider/stories/slider.register.ts index fa8c85c998f..abc2b8ed66b 100644 --- a/packages/web-components/fast-foundation/src/slider/stories/slider.register.ts +++ b/packages/web-components/fast-foundation/src/slider/stories/slider.register.ts @@ -1,4 +1,3 @@ -import { html } from "@microsoft/fast-element"; import { css } from "@microsoft/fast-element"; import { FASTSlider } from "../slider.js"; import { sliderTemplate } from "../slider.template.js"; @@ -12,11 +11,8 @@ const styles = css` display: inline-grid; --thumb-size: calc(var(--height-number) * 0.5 - var(--design-unit)); --thumb-translate: calc(var(--thumb-size) * -0.5 + var(--track-width) / 2); - --track-overhang: calc((var(--design-unit) / 2) * -1); --track-width: var(--design-unit); --fast-slider-height: calc(var(--thumb-size) * 10); - align-items: center; - margin: calc(var(--design-unit) * 1px) 0; user-select: none; box-sizing: border-box; border-radius: calc(var(--control-corner-radius) * 1px); @@ -24,47 +20,58 @@ const styles = css` cursor: pointer; } - :host([orientation="horizontal"]) .positioning-region { + .positioning-region { position: relative; - margin: 0 8px; display: grid; + } + + :host([orientation="horizontal"]) .positioning-region { grid-template-rows: calc(var(--thumb-size) * 1px) 1fr; } :host([orientation="vertical"]) .positioning-region { - position: relative; - margin: 0 8px; - display: grid; height: 100%; grid-template-columns: calc(var(--thumb-size) * 1px) 1fr; } - :host(:focus) .thumb-cursor { - box-shadow: 0 0 0 2px var(--fill-color), 0 0 0 4px var(--focus-stroke-outer); - } - .thumb-container { position: absolute; height: calc(var(--thumb-size) * 1px); width: calc(var(--thumb-size) * 1px); transition: all 0.2s ease; - color: var(--neutral-foreground-rest); - fill: currentcolor; } - .thumb-cursor { + + :host([orientation="horizontal"]) .thumb-container { + transform: translateX(calc(var(--thumb-size) * 0.5px)); + } + + :host([orientation="vertical"]) .thumb-container { + transform: translateY(calc(var(--thumb-size) * -0.5px)); + } + + .thumb { border: none; width: calc(var(--thumb-size) * 1px); height: calc(var(--thumb-size) * 1px); background: var(--neutral-foreground-rest); border-radius: calc(var(--control-corner-radius) * 1px); + color: var(--neutral-foreground-rest); + fill: currentcolor; } - .thumb-cursor:hover { + + .thumb:hover { background: var(--neutral-foreground-rest); border-color: var(--neutral-stroke-hover); } - .thumb-cursor:active { + + .thumb:active { background: var(--neutral-foreground-rest); } + + :host(:focus-visible) .thumb { + box-shadow: 0 0 0 2px var(--fill-color), 0 0 0 4px var(--focus-stroke-outer); + } + .track-start { background: var(--accent-foreground-rest); position: absolute; @@ -72,53 +79,55 @@ const styles = css` left: 0; border-radius: calc(var(--control-corner-radius) * 1px); } + .track-start { left: 0; } - :host([orientation="horizontal"]) .thumb-container { - transform: translateX(calc(var(--thumb-size) * 0.5px)) - translateY(calc(var(--thumb-translate) * 1px)); - } - :host([orientation="vertical"]) .thumb-container { - transform: translateX(calc(var(--thumb-translate) * 1px)) - translateY(calc(var(--thumb-size) * -0.5px)); - } + :host([orientation="horizontal"]) { touch-action: pan-y; min-width: calc(var(--thumb-size) * 1px); width: 100%; } + :host([orientation="horizontal"]) .track { - right: calc(var(--track-overhang) * 1px); - left: calc(var(--track-overhang) * 1px); - align-self: start; + top: calc(((var(--thumb-size) - var(--track-width)) / 2) * 1px); + right: 0; + left: 0; height: calc(var(--track-width) * 1px); } + :host([orientation="vertical"]) .track { - top: calc(var(--track-overhang) * 1px); - bottom: calc(var(--track-overhang) * 1px); + left: calc(((var(--thumb-size) - var(--track-width)) / 2) * 1px); + top: 0; + bottom: 0; width: calc(var(--track-width) * 1px); height: 100%; } + .track { background: var(--neutral-stroke-rest); position: absolute; border-radius: calc(var(--control-corner-radius) * 1px); } + :host([orientation="vertical"]) { height: calc(var(--fast-slider-height) * 1px); min-height: calc(var(--thumb-size) * 1px); touch-action: pan-x; } + :host([orientation="vertical"]) .track-start { height: auto; width: 100%; bottom: 0; } + :host([disabled]), :host([readonly]) { cursor: var(--disabled-cursor); } + :host([disabled]) { opacity: var(--disabled-opacity); } @@ -126,10 +135,6 @@ const styles = css` FASTSlider.define({ name: "fast-slider", - template: sliderTemplate({ - thumb: /* html */ html` -
- `, - }), + template: sliderTemplate(), styles, }); diff --git a/packages/web-components/fast-foundation/src/slider/stories/slider.stories.ts b/packages/web-components/fast-foundation/src/slider/stories/slider.stories.ts index a707c7f5dc6..c99842e35c8 100644 --- a/packages/web-components/fast-foundation/src/slider/stories/slider.stories.ts +++ b/packages/web-components/fast-foundation/src/slider/stories/slider.stories.ts @@ -78,6 +78,23 @@ SliderVerticalOrientation.args = { orientation: SliderOrientation.vertical, }; +export const SliderVerticalOrientationWithLabels: Story = Slider.bind({}); +SliderVerticalOrientationWithLabels.args = { + orientation: SliderOrientation.vertical, + min: 0, + max: 100, + step: 10, + storyContent: html` + ${repeat(x => x.storyItems, sliderLabelStoryTemplate)} + `, + storyItems: [ + { position: 0, storyContent: "0℃" }, + { position: 10, storyContent: "10℃" }, + { position: 90, storyContent: "90℃" }, + { position: 100, storyContent: "100℃" }, + ], +}; + export const SliderInForm: Story = renderComponent( html>`