Skip to content

Commit

Permalink
Foundation: Update Horizontal Scroll component template
Browse files Browse the repository at this point in the history
  • Loading branch information
bheston committed Mar 10, 2024
1 parent 0d592e2 commit 2484fd1
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Foundation: Updated Horizontal Scroll template",
"packageName": "@microsoft/fast-foundation",
"email": "[email protected]",
"dependentChangeType": "prerelease"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Fix tests for related foundation template changes",
"packageName": "@microsoft/fast-ssr",
"email": "[email protected]",
"dependentChangeType": "prerelease"
}
4 changes: 3 additions & 1 deletion packages/web-components/fast-foundation/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -2383,10 +2383,11 @@ export type HorizontalPosition = ValuesOf<typeof HorizontalPosition>;
export type HorizontalScrollOptions = StartEndOptions<FASTHorizontalScroll> & {
nextFlipper?: StaticallyComposableHTML<FASTHorizontalScroll>;
previousFlipper?: StaticallyComposableHTML<FASTHorizontalScroll>;
flipper: TemplateElementDependency;
};

// @public (undocumented)
export function horizontalScrollTemplate<T extends FASTHorizontalScroll>(options?: HorizontalScrollOptions): ElementViewTemplate<T>;
export function horizontalScrollTemplate<T extends FASTHorizontalScroll>(options: HorizontalScrollOptions): ElementViewTemplate<T>;

// @public
export const HorizontalScrollView: {
Expand Down Expand Up @@ -2900,6 +2901,7 @@ export type YearFormat = ValuesOf<typeof YearFormat>;
// dist/dts/calendar/calendar.d.ts:53:5 - (ae-incompatible-release-tags) The symbol "dataGrid" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
// dist/dts/data-grid/data-grid-row.template.d.ts:9:5 - (ae-incompatible-release-tags) The symbol "dataGridCell" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
// dist/dts/data-grid/data-grid.template.d.ts:9:5 - (ae-incompatible-release-tags) The symbol "dataGridRow" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
// dist/dts/horizontal-scroll/horizontal-scroll.options.d.ts:39:5 - (ae-incompatible-release-tags) The symbol "flipper" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
// dist/dts/picker/picker.template.d.ts:9:5 - (ae-incompatible-release-tags) The symbol "anchoredRegion" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
// dist/dts/picker/picker.template.d.ts:10:5 - (ae-incompatible-release-tags) The symbol "pickerMenu" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
// dist/dts/picker/picker.template.d.ts:11:5 - (ae-incompatible-release-tags) The symbol "pickerMenuOption" is marked as @public, but its signature references "TemplateElementDependency" which is marked as @beta
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function flipperTemplate<T extends FASTFlipper>(
let existing = templateCache[direction];

if (!existing) {
templateCache[direction] = existing = html`
templateCache[direction] = existing = html<T>`
<span part="${direction}" class="${direction}">
<slot name="${direction}">
${staticallyCompose(options[direction])}
Expand All @@ -31,7 +31,7 @@ export function flipperTemplate<T extends FASTFlipper>(
return existing;
}

return html`
return html<T>`
<template
role="button"
aria-disabled="${x => (x.disabled ? true : void 0)}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const styles = css`
position: relative;
width: var(--size);
}
:host::before {
background: var(--accent-fill-rest);
border-radius: 50%;
Expand All @@ -37,9 +38,7 @@ const styles = css`
.next,
.previous {
display: grid;
height: 16px;
position: relative;
width: 16px;
}
:host([disabled]) {
Expand All @@ -49,36 +48,44 @@ const styles = css`
color: var(--neutral-foreground-rest);
pointer-events: none;
}
:host([disabled])::before,
:host([disabled]:hover)::before,
:host([disabled]:active)::before {
background: var(--neutral-fill-stealth-rest);
border-color: var(--neutral-stroke-rest);
}
:host(:hover) {
color: var(--foreground-on-accent-hover);
}
:host(:hover)::before {
background: var(--accent-fill-hover);
border-color: var(--accent-fill-hover);
}
:host(:active) {
color: var(--foreground-on-accent-active);
}
:host(:active)::before {
background: var(--accent-fill-active);
border-color: var(--accent-fill-active);
}
:host(:focus-visible) {
outline: none;
}
:host(:focus-visible)::before {
border-color: var(--focus-stroke-outer);
box-shadow: 0 0 0 calc((var(--focus-stroke-width) - var(--stroke-width)) * 1px)
var(--focus-stroke-outer) inset,
0 0 0 calc((var(--focus-stroke-width) + var(--stroke-width)) * 1px)
var(--focus-stroke-inner) inset;
}
:host::-moz-focus-inner {
border: 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,25 @@ export const myHorizontalScroll = HorizontalScroll.compose<HorizontalScrollOptio

#### CSS Parts

| Name | Description |
| ------------------------ | ----------------------------------------- |
| `scroll-area` | Wraps the entire scrollable region |
| `scroll-view` | The visible scroll area |
| `content-container` | The container for the content |
| `scroll-prev` | The previous flipper container |
| `scroll-action-previous` | The element wrapping the previous flipper |
| `scroll-next` | The next flipper container |
| `scroll-action-next` | The element wrapping the next flipper |
| Name | Description |
| ------------------ | ---------------------------------- |
| `scroll-area` | Wraps the entire scrollable region |
| `scroll-view` | The visible scroll area |
| `content` | The container for the content |
| `scroll-previous` | The previous flipper container |
| `previous-flipper` | The previous flipper |
| `scroll-next` | The next flipper container |
| `next-flipper` | The next flipper |

#### Slots

| Name | Description |
| ------- | ---------------------------------------------------- |
| `start` | Content which can be provided before the scroll area |
| `end` | Content which can be provided after the scroll area |
| Name | Description |
| ------------------ | ---------------------------------------------------- |
| `start` | Content which can be provided before the scroll area |
| `end` | Content which can be provided after the scroll area |
| | Content in the scroll area |
| `previous-flipper` | The component for scrolling previous |
| `next-flipper` | The component for scrolling next |

<hr/>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { StartEndOptions, TemplateElementDependency } from "../patterns/index.js";
import type { StaticallyComposableHTML, ValuesOf } from "../utilities/index.js";
import type { StartEndOptions } from "../patterns/index.js";
import type { FASTHorizontalScroll } from "./horizontal-scroll.js";

/**
Expand Down Expand Up @@ -41,4 +41,5 @@ export type ScrollEasing = ValuesOf<typeof ScrollEasing>;
export type HorizontalScrollOptions = StartEndOptions<FASTHorizontalScroll> & {
nextFlipper?: StaticallyComposableHTML<FASTHorizontalScroll>;
previousFlipper?: StaticallyComposableHTML<FASTHorizontalScroll>;
flipper: TemplateElementDependency;
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test.describe("HorizontalScroll", () => {

scrollNext = element.locator(".scroll-next");

scrollPrevious = element.locator(".scroll-prev");
scrollPrevious = element.locator(".scroll-previous");

scrollView = element.locator(".scroll-view");

Expand Down Expand Up @@ -59,7 +59,7 @@ test.describe("HorizontalScroll", () => {
node.scrollToNext();
});

await expect(scrollView).toHaveJSProperty("scrollLeft", 375);
await expect(scrollView).toHaveJSProperty("scrollLeft", 379);
});

test("should not scroll past the beginning", async () => {
Expand Down Expand Up @@ -165,7 +165,7 @@ test.describe("HorizontalScroll", () => {

await nextFlipper.click();

await expect(scrollView).toHaveJSProperty("scrollLeft", 375);
await expect(scrollView).toHaveJSProperty("scrollLeft", 379);

await previousFlipper.click();

Expand All @@ -175,7 +175,7 @@ test.describe("HorizontalScroll", () => {

await nextFlipper.click();

await expect(scrollView).toHaveJSProperty("scrollLeft", 250);
await expect(scrollView).toHaveJSProperty("scrollLeft", 254);
});

test("should scroll to previous when only 2 items wide", async ({ page }) => {
Expand All @@ -193,7 +193,7 @@ test.describe("HorizontalScroll", () => {
node.scrollToNext();
});

await expect(scrollView).toHaveJSProperty("scrollLeft", 125);
await expect(scrollView).toHaveJSProperty("scrollLeft", 129);

await element.evaluate((node: FASTHorizontalScroll) => {
node.scrollToPrevious();
Expand Down Expand Up @@ -221,9 +221,9 @@ test.describe("HorizontalScroll", () => {
node.scrollInView(card as HTMLElement, 0);
}, await lastCard.elementHandle());

await expect(scrollView).toHaveJSProperty("scrollLeft", 1375);
await expect(scrollView).toHaveJSProperty("scrollLeft", 1383);

await expect(lastCard).toHaveJSProperty("offsetLeft", 1875);
await expect(lastCard).toHaveJSProperty("offsetLeft", 1879);

await expect(lastCard).toHaveJSProperty("offsetWidth", 120);

Expand All @@ -249,9 +249,9 @@ test.describe("HorizontalScroll", () => {
node.scrollInView(cardsCount - 1, 0);
}, await cards.count());

await expect(scrollView).toHaveJSProperty("scrollLeft", 1375);
await expect(scrollView).toHaveJSProperty("scrollLeft", 1383);

await expect(lastCard).toHaveJSProperty("offsetLeft", 1875);
await expect(lastCard).toHaveJSProperty("offsetLeft", 1879);

await expect(lastCard).toHaveJSProperty("offsetWidth", 120);

Expand All @@ -277,9 +277,9 @@ test.describe("HorizontalScroll", () => {
node.scrollInView(12, 0);
});

await expect(scrollView).toHaveJSProperty("scrollLeft", 1125);
await expect(scrollView).toHaveJSProperty("scrollLeft", 1129);

await expect(thirdLastCard).toHaveJSProperty("offsetLeft", 1500);
await expect(thirdLastCard).toHaveJSProperty("offsetLeft", 1504);

await expect(thirdLastCard).toHaveJSProperty("offsetWidth", 120);

Expand All @@ -289,19 +289,19 @@ test.describe("HorizontalScroll", () => {
node.scrollInView(12, 80);
});

await expect(scrollView).toHaveJSProperty("scrollLeft", 1125);
await expect(scrollView).toHaveJSProperty("scrollLeft", 1129);

await element.evaluate((node: FASTHorizontalScroll) => {
node.scrollInView(12, 0, 200);
});

await expect(scrollView).toHaveJSProperty("scrollLeft", 1250);
await expect(scrollView).toHaveJSProperty("scrollLeft", 1254);

await element.evaluate((node: FASTHorizontalScroll) => {
node.scrollInView(2, 20);
});

await expect(scrollView).toHaveJSProperty("scrollLeft", 125);
await expect(scrollView).toHaveJSProperty("scrollLeft", 129);
});

test("Should not scroll with `scrollInView()` when the item is in view", async ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import type { ElementViewTemplate } from "@microsoft/fast-element";
import { elements, html, ref, slotted, when } from "@microsoft/fast-element";
import { endSlotTemplate, startSlotTemplate, tagFor } from "../patterns/index.js";
import { staticallyCompose } from "../utilities/template-helpers.js";
import { endSlotTemplate, startSlotTemplate } from "../patterns/start-end.js";
import type { FASTHorizontalScroll } from "./horizontal-scroll.js";
import type { HorizontalScrollOptions } from "./horizontal-scroll.options.js";

/**
* @public
*/
export function horizontalScrollTemplate<T extends FASTHorizontalScroll>(
options: HorizontalScrollOptions = {}
options: HorizontalScrollOptions
): ElementViewTemplate<T> {
const flipperTag = html.partial(tagFor(options.flipper));
return html<T>`
<template @keyup="${(x, c) => x.keyupHandler(c.event as KeyboardEvent)}">
${startSlotTemplate(options)}
Expand All @@ -21,11 +22,7 @@ export function horizontalScrollTemplate<T extends FASTHorizontalScroll>(
@scroll="${x => x.scrolled()}"
${ref("scrollContainer")}
>
<div
class="content-container"
part="content-container"
${ref("content")}
>
<div class="content" part="content" ${ref("content")}>
<slot
${slotted({
property: "scrollItems",
Expand All @@ -38,26 +35,43 @@ export function horizontalScrollTemplate<T extends FASTHorizontalScroll>(
x => x.view !== "mobile",
html<T>`
<div
class="scroll scroll-prev"
part="scroll-prev"
class="scroll-previous"
part="scroll-previous"
${ref("previousFlipperContainer")}
>
<div class="scroll-action" part="scroll-action-previous">
<slot name="previous-flipper">
${staticallyCompose(options.previousFlipper)}
</slot>
</div>
<slot name="previous-flipper">
${staticallyCompose(
options.previousFlipper ??
html<T>`
<${flipperTag}
part="previous-flipper"
@click="${x => x.scrollToPrevious()}"
direction="previous"
aria-hidden="${x =>
x.flippersHiddenFromAT}"
></${flipperTag}>
`
)}
</slot>
</div>
<div
class="scroll scroll-next"
class="scroll-next"
part="scroll-next"
${ref("nextFlipperContainer")}
>
<div class="scroll-action" part="scroll-action-next">
<slot name="next-flipper">
${staticallyCompose(options.nextFlipper)}
</slot>
</div>
<slot name="next-flipper">
${staticallyCompose(
options.nextFlipper ??
html<T>`
<${flipperTag}
part="next-flipper"
@click="${x => x.scrollToNext()}"
aria-hidden="${x =>
x.flippersHiddenFromAT}"
></${flipperTag}>
`
)}
</slot>
</div>
`
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ import { ScrollEasing } from "./horizontal-scroll.options.js";
*
* @slot start - Content which can be provided before the scroll area
* @slot end - Content which can be provided after the scroll area
* @slot - Content in the scroll area
* @slot previous-flipper - The component for scrolling previous
* @slot next-flipper - The component for scrolling next
* @csspart scroll-area - Wraps the entire scrollable region
* @csspart scroll-view - The visible scroll area
* @csspart content-container - The container for the content
* @csspart scroll-prev - The previous flipper container
* @csspart scroll-action-previous - The element wrapping the previous flipper
* @csspart content - The container for the content
* @csspart scroll-previous - The previous flipper container
* @csspart previous-flipper - The previous flipper
* @csspart scroll-next - The next flipper container
* @csspart scroll-action-next - The element wrapping the next flipper
* @csspart next-flipper - The next flipper
* @fires scrollstart - Fires a custom 'scrollstart' event when scrolling
* @fires scrollend - Fires a custom 'scrollend' event when scrolling stops
*
Expand Down
Loading

0 comments on commit 2484fd1

Please sign in to comment.