diff --git a/change/@microsoft-fast-foundation-6f10b9c9-3154-4b85-a95c-f22a452e7d7a.json b/change/@microsoft-fast-foundation-6f10b9c9-3154-4b85-a95c-f22a452e7d7a.json new file mode 100644 index 00000000000..745c5efebf2 --- /dev/null +++ b/change/@microsoft-fast-foundation-6f10b9c9-3154-4b85-a95c-f22a452e7d7a.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "normalize storybook stories", + "packageName": "@microsoft/fast-foundation", + "email": "863023+radium-v@users.noreply.github.com", + "dependentChangeType": "prerelease" +} diff --git a/packages/web-components/fast-foundation/.eslintrc.json b/packages/web-components/fast-foundation/.eslintrc.json index a39f5e35842..a26a6f9df3f 100644 --- a/packages/web-components/fast-foundation/.eslintrc.json +++ b/packages/web-components/fast-foundation/.eslintrc.json @@ -20,12 +20,20 @@ }, "extendDefaults": true } - ], - "no-restricted-imports": [ - "error", - { - "patterns": ["**/stories/**"] - } ] - } + }, + "overrides": [ + { + "files": ["**/*.ts"], + "excludedFiles": ["**/*.stories.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": ["**/stories/**"] + } + ] + } + } + ] } diff --git a/packages/web-components/fast-foundation/.storybook/debug.stories.ts b/packages/web-components/fast-foundation/.storybook/debug.stories.ts new file mode 100644 index 00000000000..05352662f9a --- /dev/null +++ b/packages/web-components/fast-foundation/.storybook/debug.stories.ts @@ -0,0 +1,13 @@ +/** + * This is a special story that allows us to load a blank preview page for + * playwright tests which need to generate elements and insert them directly, + * rather than start with a pre-determined element. + */ + +import type { Meta } from "@storybook/html"; + +export default { + title: "Debug", +} as Meta; + +export const Blank = () => ""; diff --git a/packages/web-components/fast-foundation/.storybook/main.cjs b/packages/web-components/fast-foundation/.storybook/main.cjs index 5b25bdf576e..25dbc387df0 100644 --- a/packages/web-components/fast-foundation/.storybook/main.cjs +++ b/packages/web-components/fast-foundation/.storybook/main.cjs @@ -3,7 +3,7 @@ const path = require("path"); module.exports = { addons: ["@storybook/addon-links", "@storybook/addon-essentials"], - stories: ["../src/**/stories/*.stories.ts"], + stories: ["../src/**/stories/*.stories.ts", "debug.stories.ts"], framework: "@storybook/html", features: { babelModeV7: true, diff --git a/packages/web-components/fast-foundation/.storybook/manager-head.html b/packages/web-components/fast-foundation/.storybook/manager-head.html new file mode 100644 index 00000000000..3baaa1af068 --- /dev/null +++ b/packages/web-components/fast-foundation/.storybook/manager-head.html @@ -0,0 +1,6 @@ + diff --git a/packages/web-components/fast-foundation/.storybook/preview-head.html b/packages/web-components/fast-foundation/.storybook/preview-head.html index 7ea6a412083..e8f9154b1a6 100644 --- a/packages/web-components/fast-foundation/.storybook/preview-head.html +++ b/packages/web-components/fast-foundation/.storybook/preview-head.html @@ -98,8 +98,10 @@ --type-ramp-plus-6-line-height: 72px; } - html { + html, + .docs-story { background-color: var(--fill-color); + color: var(--neutral-foreground-rest); min-height: 100%; } diff --git a/packages/web-components/fast-foundation/.storybook/preview.js b/packages/web-components/fast-foundation/.storybook/preview.js index 70fc3b041d6..cbf38bb3638 100644 --- a/packages/web-components/fast-foundation/.storybook/preview.js +++ b/packages/web-components/fast-foundation/.storybook/preview.js @@ -1,3 +1,4 @@ +import "@microsoft/fast-element/polyfills"; import "../src/anchor/stories/anchor.register.js"; import "../src/anchored-region/stories/anchored-region.register.js"; import "../src/avatar/stories/avatar.register.js"; diff --git a/packages/web-components/fast-foundation/docs/api-report.md b/packages/web-components/fast-foundation/docs/api-report.md index 9a5e327ddb9..684747398e6 100644 --- a/packages/web-components/fast-foundation/docs/api-report.md +++ b/packages/web-components/fast-foundation/docs/api-report.md @@ -59,7 +59,16 @@ export interface AnchoredRegionConfig { } // @public -export type AnchoredRegionPositionLabel = "start" | "insetStart" | "insetEnd" | "end" | "center"; +export const AnchoredRegionPositionLabel: { + readonly start: "start"; + readonly insetStart: "insetStart"; + readonly insetEnd: "insetEnd"; + readonly end: "end"; + readonly center: "center"; +}; + +// @public +export type AnchoredRegionPositionLabel = typeof AnchoredRegionPositionLabel[keyof typeof AnchoredRegionPositionLabel]; // @public export function anchoredRegionTemplate(): ElementViewTemplate; @@ -67,6 +76,17 @@ export function anchoredRegionTemplate(): ElementViewTemplate; @@ -102,7 +122,7 @@ export const AutoUpdateMode: { readonly auto: "auto"; }; -// @public (undocumented) +// @public export type AutoUpdateMode = typeof AutoUpdateMode[keyof typeof AutoUpdateMode]; // @public @@ -114,10 +134,24 @@ export type AvatarOptions = { export function avatarTemplate(options?: AvatarOptions): ElementViewTemplate; // @public -export type AxisPositioningMode = "uncontrolled" | "locktodefault" | "dynamic"; +export const AxisPositioningMode: { + readonly uncontrolled: "uncontrolled"; + readonly locktodefault: "locktodefault"; + readonly dynamic: "dynamic"; +}; // @public -export type AxisScalingMode = "anchor" | "fill" | "content"; +export type AxisPositioningMode = typeof AxisPositioningMode[keyof typeof AxisPositioningMode]; + +// @public +export const AxisScalingMode: { + readonly anchor: "anchor"; + readonly content: "content"; + readonly fill: "fill"; +}; + +// @public +export type AxisScalingMode = typeof AxisScalingMode[keyof typeof AxisScalingMode]; // @public export function badgeTemplate(): ElementViewTemplate; @@ -139,6 +173,16 @@ export type ButtonOptions = StartEndOptions; // @public export function buttonTemplate(options?: ButtonOptions): ElementViewTemplate; +// @public +export const ButtonType: { + readonly submit: "submit"; + readonly reset: "reset"; + readonly button: "button"; +}; + +// @public +export type ButtonType = typeof ButtonType[keyof typeof ButtonType]; + // @public export function calendarCellTemplate(options: CalendarOptions, todayString: string): ViewTemplate; @@ -534,6 +578,16 @@ export interface DesignTokenSubscriber> { // @public export function dialogTemplate(): ElementViewTemplate; +// Warning: (ae-internal-missing-underscore) The name "Dimension" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export interface Dimension { + // (undocumented) + height: number; + // (undocumented) + width: number; +} + // @public @deprecated export const disabledCursor = "not-allowed"; @@ -606,7 +660,7 @@ export class FASTAnchor extends FASTElement { ping: string; referrerpolicy: string; rel: string; - target: "_self" | "_blank" | "_parent" | "_top"; + target: AnchorTarget; type: string; } @@ -761,9 +815,9 @@ export class FASTButton extends FormAssociatedButton { formtarget: "_self" | "_blank" | "_parent" | "_top"; // (undocumented) protected formtargetChanged(): void; - type: "submit" | "reset" | "button"; + type: ButtonType; // (undocumented) - protected typeChanged(previous: "submit" | "reset" | "button" | void, next: "submit" | "reset" | "button"): void; + protected typeChanged(previous: ButtonType | undefined, next: ButtonType): void; validate(): void; } @@ -1057,7 +1111,7 @@ export class FASTHorizontalScroll extends FASTElement { // (undocumented) disconnectedCallback(): void; duration: string; - easing: ScrollEasing; + easing: ScrollEasing | string; flippersHiddenFromAT: boolean; keyupHandler(e: Event & KeyboardEvent): void; nextFlipperContainer: HTMLDivElement; @@ -1430,7 +1484,7 @@ export class FASTPicker extends FormAssociatedPicker { menuOptionTemplate: ViewTemplate; // (undocumented) protected menuOptionTemplateChanged(): void; - menuPlacement: menuConfigs; + menuPlacement: MenuPlacement; // (undocumented) protected menuPlacementChanged(): void; // @internal @@ -2236,7 +2290,17 @@ export const getDirection: (rootNode: HTMLElement) => Direction; export const hidden = ":host([hidden]){display:none}"; // @public -export type HorizontalPosition = "start" | "end" | "left" | "right" | "center" | "unset"; +export const HorizontalPosition: { + readonly start: "start"; + readonly end: "end"; + readonly left: "left"; + readonly right: "right"; + readonly center: "center"; + readonly unset: "unset"; +}; + +// @public +export type HorizontalPosition = typeof HorizontalPosition[keyof typeof HorizontalPosition]; // @public export type HorizontalScrollOptions = StartEndOptions & { @@ -2248,7 +2312,13 @@ export type HorizontalScrollOptions = StartEndOptions & { export function horizontalScrollTemplate(options?: HorizontalScrollOptions): ElementViewTemplate; // @public -export type HorizontalScrollView = "default" | "mobile"; +export const HorizontalScrollView: { + readonly default: "default"; + readonly mobile: "mobile"; +}; + +// @public +export type HorizontalScrollView = typeof HorizontalScrollView[keyof typeof HorizontalScrollView]; // Warning: (ae-internal-missing-underscore) The name "interactiveCalendarGridTemplate" should be prefixed with an underscore because the declaration is marked as @internal // @@ -2296,9 +2366,6 @@ export class MatchMediaStyleSheetBehavior extends MatchMediaBehavior { // @public export type MediaQueryListListener = (this: MediaQueryList, ev?: MediaQueryListEvent) => void; -// @beta -export type menuConfigs = "bottom" | "bottom-fill" | "tallest" | "tallest-fill" | "top" | "top-fill"; - // @public export type MenuItemColumnCount = 0 | 1 | 2; @@ -2323,6 +2390,19 @@ export type MenuItemRole = typeof MenuItemRole[keyof typeof MenuItemRole]; // @public export function menuItemTemplate(options: MenuItemOptions): ElementViewTemplate; +// @beta +export const MenuPlacement: { + readonly bottom: "bottom"; + readonly bottomFill: "bottom-fill"; + readonly tallest: "tallest"; + readonly tallestFill: "tallest-fill"; + readonly top: "top"; + readonly topFill: "top-fill"; +}; + +// @beta +export type MenuPlacement = typeof MenuPlacement[keyof typeof MenuPlacement]; + // @public export function menuTemplate(): ElementViewTemplate; @@ -2457,7 +2537,15 @@ export const roleForMenuItem: { }; // @public -export type ScrollEasing = "linear" | "ease-in" | "ease-out" | "ease-in-out" | string; +export const ScrollEasing: { + readonly linear: "linear"; + readonly easeIn: "ease-in"; + readonly easeOut: "ease-out"; + readonly easeInOut: "ease-in-out"; +}; + +// @public +export type ScrollEasing = typeof ScrollEasing[keyof typeof ScrollEasing]; // @public export type SearchOptions = StartEndOptions; @@ -2639,11 +2727,14 @@ export const TooltipPosition: { readonly right: "right"; readonly bottom: "bottom"; readonly left: "left"; + readonly center: "center"; readonly start: "start"; readonly end: "end"; readonly topLeft: "top-left"; + readonly topCenter: "top-center"; readonly topRight: "top-right"; readonly bottomLeft: "bottom-left"; + readonly bottomCenter: "bottom-center"; readonly bottomRight: "bottom-right"; readonly topStart: "top-start"; readonly topEnd: "top-end"; @@ -2669,7 +2760,15 @@ export function treeItemTemplate(options?: TreeItemOptions): ElementViewTemplate export function treeViewTemplate(): ElementViewTemplate; // @public -export type VerticalPosition = "top" | "bottom" | "center" | "unset"; +export const VerticalPosition: { + readonly top: "top"; + readonly bottom: "bottom"; + readonly center: "center"; + readonly unset: "unset"; +}; + +// @public +export type VerticalPosition = typeof VerticalPosition[keyof typeof VerticalPosition]; // @public export const WeekdayFormat: { diff --git a/packages/web-components/fast-foundation/src/__test__/helpers.ts b/packages/web-components/fast-foundation/src/__test__/helpers.ts new file mode 100644 index 00000000000..6bda31ea8af --- /dev/null +++ b/packages/web-components/fast-foundation/src/__test__/helpers.ts @@ -0,0 +1,64 @@ +import type { FASTElement, ViewTemplate } from "@microsoft/fast-element"; +import type { + AnnotatedStoryFn, + Args, + ComponentAnnotations, + StoryAnnotations, +} from "@storybook/csf"; + +/** + * A helper that returns a function to bind a Storybook story to a ViewTemplate. + * + * @param template - The ViewTemplate to render + * @returns - a function to bind a Storybook story + */ +export function renderComponent( + template: ViewTemplate +): (args: TArgs) => Element | DocumentFragment | null { + return function (args) { + const storyFragment = new DocumentFragment(); + template.render(args, storyFragment); + if (storyFragment.childElementCount === 1) { + return storyFragment.firstElementChild; + } + return storyFragment; + }; +} + +/** + * A helper that returns a function to bind a Storybook story to a ViewTemplate. + */ +export type FASTFramework = { + component: typeof FASTElement; + storyResult: FASTElement | Element | DocumentFragment; +}; + +/** + * Metadata to configure the stories for a component. + */ +export type Meta = ComponentAnnotations< + FASTFramework, + Omit +>; + +/** + * Story function that represents a CSFv3 component example. + */ +export declare type StoryObj = StoryAnnotations; + +/** + * Story function that represents a CSFv2 component example. + */ +export declare type StoryFn = AnnotatedStoryFn; + +/** + * Story function that represents a CSFv2 component example. + * + * NOTE that in Storybook 7.0, this type will be renamed to `StoryFn` and replaced by the current `StoryObj` type. + */ +export declare type Story = StoryFn>; + +/** + * Combined Storybook story args. + */ +export type StoryArgs = Partial> & Args; diff --git a/packages/web-components/fast-foundation/src/accordion-item/stories/accordion-item.stories.ts b/packages/web-components/fast-foundation/src/accordion-item/stories/accordion-item.stories.ts index 77d59808202..d0240d85c20 100644 --- a/packages/web-components/fast-foundation/src/accordion-item/stories/accordion-item.stories.ts +++ b/packages/web-components/fast-foundation/src/accordion-item/stories/accordion-item.stories.ts @@ -1,30 +1,37 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTAccordionItem } from "../accordion-item.js"; -type AccordionItemArgs = Args & FASTAccordionItem; -type AccordionItemMeta = Meta; - -const storyTemplate = html` - - ${x => x?.content} +const storyTemplate = html>` + + ${x => x.storyContent} `; export default { - title: "Accordion/Accordion Item", - includeStories: ["AccordionItem"], + title: "Accordion Item", args: { - content: html` - Accordion Item Content -
Accordion Item Heading
- `, - expanded: true, + expanded: false, + }, + argTypes: { + expanded: { control: "boolean" }, + headinglevel: { control: { type: "number", max: 6, min: 1 } }, + id: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as AccordionItemMeta; +} as Meta; -export const AccordionItem = (args: AccordionItemArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const AccordionItem: Story = renderComponent( + storyTemplate +).bind({}); +AccordionItem.args = { + storyContent: html` + Accordion Item Content +
Accordion Item Heading
+ `, }; diff --git a/packages/web-components/fast-foundation/src/accordion/README.md b/packages/web-components/fast-foundation/src/accordion/README.md index 36029bc7afa..b98f16d7248 100644 --- a/packages/web-components/fast-foundation/src/accordion/README.md +++ b/packages/web-components/fast-foundation/src/accordion/README.md @@ -104,6 +104,16 @@ export const myAccordionItem = AccordionItem.compose({ +### Variables + +| Name | Description | Type | +| --------------------- | ----------------------------- | --------------------------------------- | +| `AccordionExpandMode` | Expand mode for FASTAccordion | `{ single: "single", multi: "multi", }` | + +
+ + + ### class: `FASTAccordion` #### Superclass @@ -138,14 +148,6 @@ export const myAccordionItem = AccordionItem.compose({
-### Variables - -| Name | Description | Type | -| --------------------- | ----------------------------- | --------------------------------------- | -| `AccordionExpandMode` | Expand mode for FASTAccordion | `{ single: "single", multi: "multi", }` | - -
- ### class: `FASTAccordionItem` diff --git a/packages/web-components/fast-foundation/src/accordion/accordion.options.ts b/packages/web-components/fast-foundation/src/accordion/accordion.options.ts new file mode 100644 index 00000000000..65430ab7737 --- /dev/null +++ b/packages/web-components/fast-foundation/src/accordion/accordion.options.ts @@ -0,0 +1,21 @@ +/** + * Expand mode for {@link FASTAccordion} + * @public + */ +export const AccordionExpandMode = { + /** + * Designates only a single {@link @microsoft/fast-foundation#(FASTAccordionItem:class) } can be open a time. + */ + single: "single", + + /** + * Designates multiple {@link @microsoft/fast-foundation#(FASTAccordionItem:class) | FASTAccordionItemItems} can be open simultaneously. + */ + multi: "multi", +} as const; + +/** + * Type for the {@link FASTAccordion} Expand Mode + * @public + */ +export type AccordionExpandMode = typeof AccordionExpandMode[keyof typeof AccordionExpandMode]; diff --git a/packages/web-components/fast-foundation/src/accordion/accordion.ts b/packages/web-components/fast-foundation/src/accordion/accordion.ts index bdf7aea98e8..1b192037667 100644 --- a/packages/web-components/fast-foundation/src/accordion/accordion.ts +++ b/packages/web-components/fast-foundation/src/accordion/accordion.ts @@ -7,28 +7,7 @@ import { wrapInBounds, } from "@microsoft/fast-web-utilities"; import { FASTAccordionItem } from "../accordion-item/accordion-item.js"; - -/** - * Expand mode for {@link FASTAccordion} - * @public - */ -export const AccordionExpandMode = { - /** - * Designates only a single {@link @microsoft/fast-foundation#(FASTAccordionItem:class) } can be open a time. - */ - single: "single", - - /** - * Designates multiple {@link @microsoft/fast-foundation#(FASTAccordionItem:class) | FASTAccordionItemItems} can be open simultaneously. - */ - multi: "multi", -} as const; - -/** - * Type for the {@link FASTAccordion} Expand Mode - * @public - */ -export type AccordionExpandMode = typeof AccordionExpandMode[keyof typeof AccordionExpandMode]; +import { AccordionExpandMode } from "./accordion.options.js"; /** * An Accordion Custom HTML Element diff --git a/packages/web-components/fast-foundation/src/accordion/index.ts b/packages/web-components/fast-foundation/src/accordion/index.ts index ad2c4085329..dc8f7f0aa86 100644 --- a/packages/web-components/fast-foundation/src/accordion/index.ts +++ b/packages/web-components/fast-foundation/src/accordion/index.ts @@ -1,2 +1,3 @@ -export * from "./accordion.template.js"; export * from "./accordion.js"; +export * from "./accordion.options.js"; +export * from "./accordion.template.js"; diff --git a/packages/web-components/fast-foundation/src/accordion/stories/accordion.stories.ts b/packages/web-components/fast-foundation/src/accordion/stories/accordion.stories.ts index f89243dea60..a4750abd9b8 100644 --- a/packages/web-components/fast-foundation/src/accordion/stories/accordion.stories.ts +++ b/packages/web-components/fast-foundation/src/accordion/stories/accordion.stories.ts @@ -1,44 +1,37 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; -import type { FASTAccordion } from "../accordion.js"; -import { AccordionExpandMode } from "../accordion.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; +import { FASTAccordion } from "../accordion.js"; +import { AccordionExpandMode } from "../accordion.options.js"; -type AccordionArgs = Args & FASTAccordion; -type AccordionMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` - ${x => x?.content} + ${x => x.storyContent} `; export default { title: "Accordion", + component: FASTAccordion, args: { - content: html` - -
Accordion Item 1 Heading
- Accordion Item 1 Content -
- -
Accordion Item 2 Heading
- A checkbox as content - `, + expandmode: AccordionExpandMode.multi, }, - argTypes: { - expandmode: { - options: Object.values(AccordionExpandMode), - control: { - type: "select", - }, - }, + expandmode: { control: "select", options: Object.values(AccordionExpandMode) }, + storyContent: { table: { disable: true } }, }, -} as AccordionMeta; +} as Meta; -export const Accordion = (args: AccordionArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Accordion: Story = renderComponent(storyTemplate).bind({}); +Accordion.args = { + storyContent: html` + +
Accordion Item 1 Heading
+ Accordion Item 1 Content +
+ +
Accordion Item 2 Heading
+ A checkbox as content +
+ `, }; diff --git a/packages/web-components/fast-foundation/src/anchor/README.md b/packages/web-components/fast-foundation/src/anchor/README.md index 8d9c8a115ae..a960150e000 100644 --- a/packages/web-components/fast-foundation/src/anchor/README.md +++ b/packages/web-components/fast-foundation/src/anchor/README.md @@ -59,6 +59,16 @@ This component is built with the expectation that focus is delegated to the anch +### Variables + +| Name | Description | Type | +| -------------- | --------------------- | ------------------------------------------------------------------------- | +| `AnchorTarget` | Anchor target values. | `{ _self: "_self", _blank: "_blank", _parent: "_parent", _top: "_top", }` | + +
+ + + ### class: `FASTAnchor` #### Superclass @@ -69,17 +79,17 @@ This component is built with the expectation that focus is delegated to the anch #### Fields -| Name | Privacy | Type | Default | Description | Inherited From | -| ---------------- | ------- | -------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `download` | public | `string` | | Prompts the user to save the linked URL. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `href` | public | `string` | | The URL the hyperlink references. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `ping` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `referrerpolicy` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `rel` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `target` | public | `"_self" or "_blank" or "_parent" or "_top"` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `type` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | -| `control` | public | `HTMLAnchorElement` | | References the root element | | +| Name | Privacy | Type | Default | Description | Inherited From | +| ---------------- | ------- | ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `download` | public | `string` | | Prompts the user to save the linked URL. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `href` | public | `string` | | The URL the hyperlink references. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `ping` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `referrerpolicy` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `rel` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `target` | public | `AnchorTarget` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `type` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | | +| `control` | public | `HTMLAnchorElement` | | References the root element | | #### Attributes diff --git a/packages/web-components/fast-foundation/src/anchor/anchor.options.ts b/packages/web-components/fast-foundation/src/anchor/anchor.options.ts new file mode 100644 index 00000000000..bee40f4c585 --- /dev/null +++ b/packages/web-components/fast-foundation/src/anchor/anchor.options.ts @@ -0,0 +1,18 @@ +/** + * Anchor target values. + * + * @public + */ +export const AnchorTarget = { + _self: "_self", + _blank: "_blank", + _parent: "_parent", + _top: "_top", +} as const; + +/** + * Type for anchor target values. + * + * @public + */ +export type AnchorTarget = typeof AnchorTarget[keyof typeof AnchorTarget]; diff --git a/packages/web-components/fast-foundation/src/anchor/anchor.ts b/packages/web-components/fast-foundation/src/anchor/anchor.ts index 8730147b4c1..781230fc73e 100644 --- a/packages/web-components/fast-foundation/src/anchor/anchor.ts +++ b/packages/web-components/fast-foundation/src/anchor/anchor.ts @@ -5,6 +5,7 @@ import { StartEndOptions, } from "../patterns/index.js"; import { applyMixins } from "../utilities/apply-mixins.js"; +import type { AnchorTarget } from "./anchor.options.js"; /** * Anchor configuration options @@ -86,7 +87,7 @@ export class FASTAnchor extends FASTElement { * HTML Attribute: target */ @attr - public target: "_self" | "_blank" | "_parent" | "_top"; + public target: AnchorTarget; /** * See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. diff --git a/packages/web-components/fast-foundation/src/anchor/index.ts b/packages/web-components/fast-foundation/src/anchor/index.ts index 3249312b46f..9ca2f50053d 100644 --- a/packages/web-components/fast-foundation/src/anchor/index.ts +++ b/packages/web-components/fast-foundation/src/anchor/index.ts @@ -1,2 +1,3 @@ -export * from "./anchor.template.js"; export * from "./anchor.js"; +export * from "./anchor.options.js"; +export * from "./anchor.template.js"; diff --git a/packages/web-components/fast-foundation/src/anchor/stories/anchor.stories.ts b/packages/web-components/fast-foundation/src/anchor/stories/anchor.stories.ts index a39c54cc5f7..a273bfddf84 100644 --- a/packages/web-components/fast-foundation/src/anchor/stories/anchor.stories.ts +++ b/packages/web-components/fast-foundation/src/anchor/stories/anchor.stories.ts @@ -1,44 +1,81 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; -import type { FASTAnchor as FoundationAnchor } from "../anchor.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; +import type { FASTAnchor } from "../anchor.js"; +import { AnchorTarget } from "../anchor.options.js"; -type AnchorArgs = Args & FoundationAnchor; -type AnchorMeta = Meta; - -export const storyTemplate = html` +const storyTemplate = html>` - ${x => x?.content} + ${x => x.storyContent} `; export default { title: "Anchor", - includeStories: ["Anchor"], - args: { - content: "Anchor", - href: "#", - }, argTypes: { - download: { control: { type: "text" } }, - href: { control: { type: "text" } }, - hreflang: { control: { type: "text" } }, - ping: { control: { type: "text" } }, - referrerpolicy: { control: { type: "text" } }, - rel: { control: { type: "text" } }, - target: { - options: ["_self", "_blank", "_parent", "_top"], - control: { type: "select" }, - }, - type: { control: { type: "text" } }, + download: { control: "text" }, + href: { control: "text" }, + hreflang: { control: "text" }, + ping: { control: "text" }, + referrerpolicy: { control: "text" }, + rel: { control: "text" }, + target: { control: "select", options: Object.values(AnchorTarget) }, + type: { control: "text" }, + ariaAtomic: { control: "boolean" }, + ariaBusy: { control: "boolean" }, + ariaCurrent: { control: "text" }, + ariaControls: { control: "text" }, + ariaDescribedby: { control: "text" }, + ariaDisabled: { control: "text" }, + ariaDetails: { control: "text" }, + ariaErrormessage: { control: "text" }, + ariaExpanded: { control: "text" }, + ariaFlowto: { control: "text" }, + ariaHaspopup: { control: "boolean" }, + ariaHidden: { control: "boolean" }, + ariaInvalid: { control: "text" }, + ariaKeyshortcuts: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + ariaLive: { control: "text" }, + ariaOwns: { control: "text" }, + ariaRelevant: { control: "text" }, + ariaRoledescription: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as AnchorMeta; +} as Meta; -export const Anchor = (args: AnchorArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Anchor: Story = renderComponent(storyTemplate).bind({}); +Anchor.args = { + href: "https://www.fast.design/", + storyContent: "Anchor", }; diff --git a/packages/web-components/fast-foundation/src/anchored-region/README.md b/packages/web-components/fast-foundation/src/anchored-region/README.md index 00d1bce7faa..8113edce8aa 100644 --- a/packages/web-components/fast-foundation/src/anchored-region/README.md +++ b/packages/web-components/fast-foundation/src/anchored-region/README.md @@ -75,6 +75,21 @@ export const myAnchoredRegion = AnchoredRegion.compose({ +### Variables + +| Name | Description | Type | +| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `AxisPositioningMode` | Values to define the base behavior of an anchored region on a particular axis | `{ uncontrolled: "uncontrolled", locktodefault: "locktodefault", dynamic: "dynamic", }` | +| `AxisScalingMode` | Values to define the scaling behavior of an anchored region on a particular axis | `{ anchor: "anchor", content: "content", fill: "fill", }` | +| `HorizontalPosition` | Values for the horizontal positioning options for an anchored region | `{ start: "start", end: "end", left: "left", right: "right", center: "center", unset: "unset", }` | +| `VerticalPosition` | Values for the vertical positioning options for an anchored region | `{ top: "top", bottom: "bottom", center: "center", unset: "unset", }` | +| `AutoUpdateMode` | Defines if the component updates its position automatically. Calling update() always provokes an update. anchor - the component only updates its position when the anchor resizes (default) auto - the component updates its position when: - update() is called - the anchor resizes - the window resizes - the viewport resizes - any scroll event in the document | `{ anchor: "anchor", auto: "auto", }` | +| `AnchoredRegionPositionLabel` | Values to describe the possible positions of the region relative to its anchor. Depending on the axis start = left/top, end = right/bottom | `{ start: "start", insetStart: "insetStart", insetEnd: "insetEnd", end: "end", center: "center", }` | + +
+ + + ### class: `FASTAnchoredRegion` #### Superclass @@ -168,14 +183,6 @@ export const myAnchoredRegion = AnchoredRegion.compose({
-### Variables - -| Name | Description | Type | -| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| `AutoUpdateMode` | Defines if the component updates its position automatically. Calling update() always provokes an update. anchor - the component only updates its position when the anchor resizes (default) auto - the component updates its position when: - update() is called - the anchor resizes - the window resizes - the viewport resizes - any scroll event in the document | `{ anchor: "anchor", auto: "auto", }` | - -
- ## Additional resources diff --git a/packages/web-components/fast-foundation/src/anchored-region/anchored-region-config.ts b/packages/web-components/fast-foundation/src/anchored-region/anchored-region-config.ts index 17a3fa770ce..378f70ffccb 100644 --- a/packages/web-components/fast-foundation/src/anchored-region/anchored-region-config.ts +++ b/packages/web-components/fast-foundation/src/anchored-region/anchored-region-config.ts @@ -4,7 +4,7 @@ import type { AxisScalingMode, HorizontalPosition, VerticalPosition, -} from "./anchored-region.js"; +} from "./anchored-region.options.js"; /** * A utility interface to store anchored region diff --git a/packages/web-components/fast-foundation/src/anchored-region/anchored-region.options.ts b/packages/web-components/fast-foundation/src/anchored-region/anchored-region.options.ts new file mode 100644 index 00000000000..0a818297c5e --- /dev/null +++ b/packages/web-components/fast-foundation/src/anchored-region/anchored-region.options.ts @@ -0,0 +1,122 @@ +/** + * Values to define the base behavior of an anchored region on a particular axis + * @public + */ +export const AxisPositioningMode = { + uncontrolled: "uncontrolled", + locktodefault: "locktodefault", + dynamic: "dynamic", +} as const; + +/** + * Type to define the base behavior of an anchored region on a particular axis + * @public + */ +export type AxisPositioningMode = typeof AxisPositioningMode[keyof typeof AxisPositioningMode]; + +/** + * Values to define the scaling behavior of an anchored region on a particular axis + * @public + */ +export const AxisScalingMode = { + anchor: "anchor", + content: "content", + fill: "fill", +} as const; + +/** + * Type to define the scaling behavior of an anchored region on a particular axis + * + * @public + */ +export type AxisScalingMode = typeof AxisScalingMode[keyof typeof AxisScalingMode]; + +/** + * Values for the horizontal positioning options for an anchored region + * @public + */ +export const HorizontalPosition = { + start: "start", + end: "end", + left: "left", + right: "right", + center: "center", + unset: "unset", +} as const; + +/** + * Type for the horizontal positioning options for an anchored region + * + * @public + */ +export type HorizontalPosition = typeof HorizontalPosition[keyof typeof HorizontalPosition]; + +/** + * Values for the vertical positioning options for an anchored region + * @public + */ +export const VerticalPosition = { + top: "top", + bottom: "bottom", + center: "center", + unset: "unset", +} as const; + +/** + * Type for the vertical positioning options for an anchored region + * + * @public + */ +export type VerticalPosition = typeof VerticalPosition[keyof typeof VerticalPosition]; + +/** + * Defines if the component updates its position automatically. Calling update() always provokes an update. + * anchor - the component only updates its position when the anchor resizes (default) + * auto - the component updates its position when: + * - update() is called + * - the anchor resizes + * - the window resizes + * - the viewport resizes + * - any scroll event in the document + * + * @public + */ +export const AutoUpdateMode = { + anchor: "anchor", + auto: "auto", +} as const; + +/** + * Type for the auto update mode values + * @public + */ +export type AutoUpdateMode = typeof AutoUpdateMode[keyof typeof AutoUpdateMode]; + +/** + * Values to describe the possible positions of the region relative to its anchor. + * Depending on the axis start = left/top, end = right/bottom + * @public + */ +export const AnchoredRegionPositionLabel = { + start: "start", + insetStart: "insetStart", + insetEnd: "insetEnd", + end: "end", + center: "center", +} as const; + +/** + * Describes the possible positions of the region relative + * to its anchor. Depending on the axis start = left/top, end = right/bottom + * + * @public + */ +export type AnchoredRegionPositionLabel = typeof AnchoredRegionPositionLabel[keyof typeof AnchoredRegionPositionLabel]; + +/** + * @internal + */ +export interface Dimension { + height: number; + width: number; +} diff --git a/packages/web-components/fast-foundation/src/anchored-region/anchored-region.ts b/packages/web-components/fast-foundation/src/anchored-region/anchored-region.ts index 2bdf4d1821f..f68bf6a9345 100644 --- a/packages/web-components/fast-foundation/src/anchored-region/anchored-region.ts +++ b/packages/web-components/fast-foundation/src/anchored-region/anchored-region.ts @@ -6,77 +6,15 @@ import type { ResizeObserverClassDefinition, ResizeObserverEntry, } from "../utilities/resize-observer.js"; - -/** - * Defines the base behavior of an anchored region on a particular axis - * - * @public - */ -export type AxisPositioningMode = "uncontrolled" | "locktodefault" | "dynamic"; - -/** - * Defines the scaling behavior of an anchored region on a particular axis - * - * @public - */ -export type AxisScalingMode = "anchor" | "fill" | "content"; - -/** - * Defines the horizontal positioning options for an anchored region - * - * @public - */ -export type HorizontalPosition = "start" | "end" | "left" | "right" | "center" | "unset"; - -/** - * Defines the vertical positioning options for an anchored region - * - * @public - */ -export type VerticalPosition = "top" | "bottom" | "center" | "unset"; - -/** - * Defines if the component updates its position automatically. Calling update() always provokes an update. - * anchor - the component only updates its position when the anchor resizes (default) - * auto - the component updates its position when: - * - update() is called - * - the anchor resizes - * - the window resizes - * - the viewport resizes - * - any scroll event in the document - * - * @public - */ -export const AutoUpdateMode = { - anchor: "anchor", - auto: "auto", -} as const; - -/** - * @public - */ -export type AutoUpdateMode = typeof AutoUpdateMode[keyof typeof AutoUpdateMode]; - -/** - * Describes the possible positions of the region relative - * to its anchor. Depending on the axis start = left/top, end = right/bottom - * - * @public - */ -export type AnchoredRegionPositionLabel = - | "start" - | "insetStart" - | "insetEnd" - | "end" - | "center"; - -/** - * @internal - */ -interface Dimension { - height: number; - width: number; -} +import type { + AnchoredRegionPositionLabel, + AutoUpdateMode, + AxisPositioningMode, + AxisScalingMode, + Dimension, + HorizontalPosition, + VerticalPosition, +} from "./anchored-region.options.js"; /** * An anchored region Custom HTML Element. diff --git a/packages/web-components/fast-foundation/src/anchored-region/index.ts b/packages/web-components/fast-foundation/src/anchored-region/index.ts index 31e0379e3fb..5ec59157ebb 100644 --- a/packages/web-components/fast-foundation/src/anchored-region/index.ts +++ b/packages/web-components/fast-foundation/src/anchored-region/index.ts @@ -1,3 +1,4 @@ -export * from "./anchored-region.template.js"; -export * from "./anchored-region.js"; export * from "./anchored-region-config.js"; +export * from "./anchored-region.js"; +export * from "./anchored-region.options.js"; +export * from "./anchored-region.template.js"; diff --git a/packages/web-components/fast-foundation/src/anchored-region/stories/anchored-region.stories.ts b/packages/web-components/fast-foundation/src/anchored-region/stories/anchored-region.stories.ts index 30433ef648e..e6e655c8a87 100644 --- a/packages/web-components/fast-foundation/src/anchored-region/stories/anchored-region.stories.ts +++ b/packages/web-components/fast-foundation/src/anchored-region/stories/anchored-region.stories.ts @@ -1,38 +1,39 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { uniqueId } from "@microsoft/fast-web-utilities"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTAnchoredRegion } from "../anchored-region.js"; +import { + AutoUpdateMode, + AxisPositioningMode, + AxisScalingMode, + HorizontalPosition, + VerticalPosition, +} from "../anchored-region.options.js"; -type AnchoredRegionArgs = Args & FASTAnchoredRegion; -type AnchoredRegionMeta = Meta; - -const storyTemplate = html` -
- - Anchor - +const storyTemplate = html>` +
+ Anchor - ${x => x?.content} + ${x => x.storyContent}
`; @@ -40,56 +41,83 @@ const storyTemplate = html` export default { title: "Anchored Region", args: { - autoUpdateMode: "auto", - verticalPositioningMode: "locktodefault", - horizontalPositioningMode: "locktodefault", - verticalDefaultPosition: "top", - horizontalDefaultPosition: "left", - content: html` -
- anchored-region + storyContent: html` +
+ anchored region
`, + fixedPlacement: false, + horizontalInset: false, + horizontalViewportLock: false, + verticalInset: false, + verticalViewportLock: false, }, argTypes: { - fixedPlacement: { control: { type: "boolean" } }, - verticalPositioningMode: { - options: ["uncontrolled", "locktodefault", "dynamic"], - control: { type: "select" }, - }, - verticalDefaultPosition: { - options: ["top", "bottom", "center", "unset"], - control: { type: "select" }, + anchor: { control: "text" }, + anchorId: { table: { disable: true } }, + autoUpdateMode: { + control: "select", + options: Object.values(AutoUpdateMode), }, - verticalInset: { control: { type: "boolean" } }, - verticalScaling: { - options: ["anchor", "fill", "content"], - control: { type: "select" }, + fixedPlacement: { control: "boolean" }, + horizontalDefaultPosition: { + control: "select", + options: Object.values(HorizontalPosition), }, - verticalViewportLock: { control: { type: "boolean" } }, + horizontalInset: { control: "boolean" }, horizontalPositioningMode: { - options: ["uncontrolled", "locktodefault", "dynamic"], - control: { type: "select" }, - }, - horizontalDefaultPosition: { - options: ["start", "end", "left", "right", "center", "unset"], - control: { type: "select" }, + control: "select", + options: Object.values(AxisPositioningMode), }, horizontalScaling: { - options: ["anchor", "fill", "content"], - control: { type: "select" }, + control: "select", + options: Object.values(AxisScalingMode), }, - horizontalInset: { control: { type: "boolean" } }, - horizontalViewportLock: { control: { type: "boolean" } }, - autoUpdateMode: { - options: ["anchor", "auto"], - control: { type: "select" }, + horizontalThreshold: { control: "number" }, + horizontalViewportLock: { control: "boolean" }, + storyContent: { table: { disable: true } }, + verticalDefaultPosition: { + control: "select", + options: Object.values(VerticalPosition), }, + verticalInset: { control: "boolean" }, + verticalPositioningMode: { + control: "select", + options: Object.values(AxisPositioningMode), + }, + verticalScaling: { + control: "select", + options: Object.values(AxisScalingMode), + }, + verticalThreshold: { control: "number" }, + verticalViewportLock: { control: "boolean" }, + viewport: { control: "text" }, }, -} as AnchoredRegionMeta; + decorators: [ + (Story, { args }) => { + // IDs are generated to ensure that they're unique for the docs page + const renderedStory = Story() as DocumentFragment; + const anchor = renderedStory.querySelector(".anchor") as HTMLElement; + const region = renderedStory.querySelector(".region") as HTMLElement; + + const anchorId = args.anchorId ?? uniqueId("anchor"); + + anchor.id = anchorId; + region.id = uniqueId("region"); + region.setAttribute("anchor", anchorId); + return renderedStory; + }, + ], +} as Meta; + +export const AnchoredRegion: Story = renderComponent( + storyTemplate +).bind({}); -export const AnchoredRegion = (args: AnchoredRegionArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const LockToDefault: Story = AnchoredRegion.bind({}); +LockToDefault.args = { + horizontalDefaultPosition: HorizontalPosition.right, + horizontalPositioningMode: AxisPositioningMode.locktodefault, + verticalDefaultPosition: VerticalPosition.bottom, + verticalPositioningMode: AxisPositioningMode.locktodefault, }; diff --git a/packages/web-components/fast-foundation/src/avatar/stories/avatar.stories.ts b/packages/web-components/fast-foundation/src/avatar/stories/avatar.stories.ts index 16a02442856..a59c9891a5f 100644 --- a/packages/web-components/fast-foundation/src/avatar/stories/avatar.stories.ts +++ b/packages/web-components/fast-foundation/src/avatar/stories/avatar.stories.ts @@ -1,30 +1,25 @@ import { css, html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTAvatar } from "../avatar.js"; -type AvatarStoryArgs = Args & FASTAvatar; -type AvatarStoryMeta = Meta; - -const storyTemplate = html` - - ${x => x.content} +const storyTemplate = html>` + + ${x => x.storyContent} `; export default { title: "Avatar", - args: { - content: html` - - `, - alt: "Annie's profile image", - link: "#", + argTypes: { + link: { control: "text" }, + storyContent: { table: { disable: true } }, }, decorators: [ Story => { const renderedStory = Story() as FASTAvatar; - const storyStyles = css` + renderedStory.$fastController.addStyles(css` ::slotted(fast-badge) { bottom: 0; right: 0; @@ -38,26 +33,26 @@ export default { ::slotted(.container) { padding: 1em; } - `; - - renderedStory.$fastController.addStyles(storyStyles); + `); return renderedStory; }, ], -} as AvatarStoryMeta; - -export const Avatar = (args: AvatarStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +} as Meta; + +export const Avatar: Story = renderComponent(storyTemplate).bind({}); +Avatar.args = { + storyContent: html` + Annie's profile image + `, }; -export const CircleWithTextContent: AvatarStoryMeta = Avatar.bind({}); -CircleWithTextContent.args = { - alt: "Carlos's profile image", - content: html` - CR - `, - link: "#", +export const AvatarCircleWithTextContent: Story = Avatar.bind({}); +AvatarCircleWithTextContent.args = { + storyContent: "CR", }; diff --git a/packages/web-components/fast-foundation/src/badge/stories/badge.stories.ts b/packages/web-components/fast-foundation/src/badge/stories/badge.stories.ts index 83c9d095aa3..dc1acb44b75 100644 --- a/packages/web-components/fast-foundation/src/badge/stories/badge.stories.ts +++ b/packages/web-components/fast-foundation/src/badge/stories/badge.stories.ts @@ -1,23 +1,20 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTBadge } from "../badge.js"; -type BadgeStoryArgs = Args & FASTBadge; -type BadgeStoryMeta = Meta; - -const storyTemplate = html` - ${x => x.content} +const storyTemplate = html>` + ${x => x.storyContent} `; export default { title: "Badge", args: { - content: "Badge", + storyContent: "Badge", + }, + argTypes: { + storyContent: { table: { disable: true } }, }, -} as BadgeStoryMeta; +} as Meta; -export const Badge = (args: BadgeStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const Badge: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/fast-foundation/src/breadcrumb-item/stories/breadcrumb-item.stories.ts b/packages/web-components/fast-foundation/src/breadcrumb-item/stories/breadcrumb-item.stories.ts index 05c2028689e..ed7b161826c 100644 --- a/packages/web-components/fast-foundation/src/breadcrumb-item/stories/breadcrumb-item.stories.ts +++ b/packages/web-components/fast-foundation/src/breadcrumb-item/stories/breadcrumb-item.stories.ts @@ -1,57 +1,118 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTBreadcrumbItem } from "../breadcrumb-item.js"; -type BreadcrumbItemStoryArgs = Args & FASTBreadcrumbItem; -type BreadcrumbItemStoryMeta = Meta; - -const storyTemplate = html` - - ${x => x.content} +const storyTemplate = html>` + + ${x => x.storyContent} `; export default { - title: "Breadcrumb/Breadcrumb Item", - args: { - content: "Breadcrumb item", - }, + title: "Breadcrumb Item", argTypes: { - href: { control: { type: "text" } }, + download: { control: "text" }, + href: { control: "text" }, + hreflang: { control: "text" }, + ping: { control: "text" }, + referrerpolicy: { control: "text" }, + rel: { control: "text" }, + separator: { control: "boolean" }, + target: { control: "text" }, + type: { control: "text" }, + ariaAtomic: { control: "boolean" }, + ariaBusy: { control: "boolean" }, + ariaControls: { control: "text" }, + ariaCurrent: { control: "text" }, + ariaDescribedby: { control: "text" }, + ariaDetails: { control: "text" }, + ariaDisabled: { control: "boolean" }, + ariaErrormessage: { control: "text" }, + ariaExpanded: { control: "boolean" }, + ariaFlowto: { control: "text" }, + ariaHaspopup: { control: "boolean" }, + ariaHidden: { control: "boolean" }, + ariaInvalid: { control: "text" }, + ariaKeyshortcuts: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + ariaLive: { control: "text" }, + ariaOwns: { control: "text" }, + ariaRelevant: { control: "text" }, + ariaRoledescription: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as BreadcrumbItemStoryMeta; +} as Meta; -export const BreadcrumbItem = (args: BreadcrumbItemStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const BreadcrumbItem: Story = renderComponent( + storyTemplate +).bind({}); +BreadcrumbItem.args = { + storyContent: "Breadcrumb Item", }; -export const WithHref: BreadcrumbItemStoryMeta = BreadcrumbItem.bind({}); -WithHref.args = { - content: "Breadcrumb item with href attribute", +export const BreadcrumbItemWithHref: Story = BreadcrumbItem.bind({}); +BreadcrumbItemWithHref.args = { + storyContent: "Breadcrumb item with href attribute", href: "https://www.fast.design/", }; -export const WithSlottedStart: BreadcrumbItemStoryMeta = BreadcrumbItem.bind({}); -WithSlottedStart.args = { - content: html` +export const BreadcrumbItemWithSlottedStart: Story = BreadcrumbItem.bind( + {} +); +BreadcrumbItemWithSlottedStart.args = { + storyContent: html` Breadcrumb Item with slotted start icon `, }; -export const WithSlottedEnd: BreadcrumbItemStoryMeta = BreadcrumbItem.bind({}); -WithSlottedEnd.args = { - content: html` +export const BreadcrumbItemWithSlottedEnd: Story = BreadcrumbItem.bind( + {} +); +BreadcrumbItemWithSlottedEnd.args = { + storyContent: html` Breadcrumb item with slotted end icon `, }; -export const WithSlottedSeparator: BreadcrumbItemStoryMeta = BreadcrumbItem.bind({}); -WithSlottedSeparator.args = { - content: html` +export const BreadcrumbItemWithSlottedSeparator: Story = BreadcrumbItem.bind( + {} +); +BreadcrumbItemWithSlottedSeparator.args = { + storyContent: html` Breadcrumb item with slotted separator icon `, diff --git a/packages/web-components/fast-foundation/src/breadcrumb/README.md b/packages/web-components/fast-foundation/src/breadcrumb/README.md index 822ffd923ef..ae4e58d3257 100644 --- a/packages/web-components/fast-foundation/src/breadcrumb/README.md +++ b/packages/web-components/fast-foundation/src/breadcrumb/README.md @@ -140,17 +140,17 @@ This component is built with the expectation that focus is delegated to the anch #### Fields -| Name | Privacy | Type | Default | Description | Inherited From | -| ---------------- | ------- | -------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| `download` | public | `string` | | Prompts the user to save the linked URL. See [`
` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `href` | public | `string` | | The URL the hyperlink references. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `ping` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `referrerpolicy` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `rel` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `target` | public | `"_self" or "_blank" or "_parent" or "_top"` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `type` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | -| `control` | public | `HTMLAnchorElement` | | References the root element | FASTAnchor | +| Name | Privacy | Type | Default | Description | Inherited From | +| ---------------- | ------- | ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| `download` | public | `string` | | Prompts the user to save the linked URL. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `href` | public | `string` | | The URL the hyperlink references. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `ping` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `referrerpolicy` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `rel` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `target` | public | `AnchorTarget` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `type` | public | `string` | | See [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | FASTAnchor | +| `control` | public | `HTMLAnchorElement` | | References the root element | FASTAnchor | #### Attributes diff --git a/packages/web-components/fast-foundation/src/breadcrumb/stories/breadcrumb.stories.ts b/packages/web-components/fast-foundation/src/breadcrumb/stories/breadcrumb.stories.ts index 96239078475..6ac2df76b8b 100644 --- a/packages/web-components/fast-foundation/src/breadcrumb/stories/breadcrumb.stories.ts +++ b/packages/web-components/fast-foundation/src/breadcrumb/stories/breadcrumb.stories.ts @@ -1,36 +1,31 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTBreadcrumb } from "../breadcrumb.js"; -type BreadcrumbStoryArgs = Args & FASTBreadcrumb; -type BreadcrumbStoryMeta = Meta; - -const storyTemplate = html` - - ${x => x.content} - +const storyTemplate = html>` + ${x => x.storyContent} `; export default { title: "Breadcrumb", - args: { - content: html` - Breadcrumb Item 1 - Breadcrumb Item 2 - Breadcrumb Item 3 - `, + argTypes: { + storyContent: { table: { disable: true } }, }, -} as BreadcrumbStoryMeta; +} as Meta; -export const Breadcrumb = (args: BreadcrumbStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Breadcrumb: Story = renderComponent(storyTemplate).bind({}); +Breadcrumb.args = { + storyContent: html` + Breadcrumb Item 1 + Breadcrumb Item 2 + Breadcrumb Item 3 + `, }; -export const BreadcrumbsWithSeparators: BreadcrumbStoryMeta = Breadcrumb.bind({}); -BreadcrumbsWithSeparators.args = { - content: html` +export const BreadcrumbWithSeparators: Story = Breadcrumb.bind({}); +BreadcrumbWithSeparators.args = { + storyContent: html` Breadcrumb Item 1 @@ -39,18 +34,18 @@ BreadcrumbsWithSeparators.args = { Breadcrumb Item 2 - + Breadcrumb Item 3 `, }; -export const BreadcrumbsWithAnchors: BreadcrumbStoryMeta = Breadcrumb.bind({}); -BreadcrumbsWithAnchors.args = { - content: html` - Breadcrumb Item 1 - Breadcrumb Item 2 - Breadcrumb Item 3 +export const BreadcrumbWithAnchors: Story = Breadcrumb.bind({}); +BreadcrumbWithAnchors.args = { + storyContent: html` + Anchor 1 + Anchor 2 + Anchor 3 `, }; diff --git a/packages/web-components/fast-foundation/src/button/README.md b/packages/web-components/fast-foundation/src/button/README.md index ab297d5a818..f216240816c 100644 --- a/packages/web-components/fast-foundation/src/button/README.md +++ b/packages/web-components/fast-foundation/src/button/README.md @@ -83,6 +83,16 @@ This component is built with the expectation that focus is delegated to the butt +### Variables + +| Name | Description | Type | +| ------------ | ------------------- | --------------------------------------------------------- | +| `ButtonType` | Button type values. | `{ submit: "submit", reset: "reset", button: "button", }` | + +
+ + + ### class: `FASTButton` #### Superclass @@ -102,22 +112,22 @@ This component is built with the expectation that focus is delegated to the butt | `formmethod` | public | `string` | | See [` - A checkbox - - One - Three - - `, + hidden: false, + modal: false, + noFocusTrap: false, }, argTypes: { - content: { - table: { disable: true }, - }, + hidden: { control: "boolean" }, + modal: { control: "boolean" }, + noFocusTrap: { control: "boolean" }, + ariaDescribedby: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + storyContent: { table: { disable: true } }, }, // docs are disabled since the modals would all load at once on the docs page - parameters: { - docs: { disable: true }, - }, -} as DialogStoryMeta; + parameters: { docs: { disable: true } }, +} as Meta; -export const Dialog = (args: DialogStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Dialog: Story = renderComponent(storyTemplate).bind({}); +Dialog.args = { + storyContent: html` + Button A + + A checkbox + + One + Three + + `, }; -export const DialogModal = Dialog.bind({}); +export const DialogModal: Story = Dialog.bind({}); DialogModal.args = { modal: true, - content: "A modal dialog element", + storyContent: "A modal dialog element", }; -export const DialogDismiss = (args: DialogStoryArgs) => { - const componentTemplate = html` +export const DialogWithDismiss: Story = renderComponent( + html>`
- - toggle dialog + + show dialog
- `; - - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; -DialogDismiss.args = { + ` +).bind({}); +DialogWithDismiss.args = { modal: true, - content: html` -

press Escape to close

+ storyContent: html` +

press Escape or click the button below to close

+ + dismiss dialog + `, }; diff --git a/packages/web-components/fast-foundation/src/disclosure/stories/disclosure.stories.ts b/packages/web-components/fast-foundation/src/disclosure/stories/disclosure.stories.ts index b0193e489f4..48b1b0ce122 100644 --- a/packages/web-components/fast-foundation/src/disclosure/stories/disclosure.stories.ts +++ b/packages/web-components/fast-foundation/src/disclosure/stories/disclosure.stories.ts @@ -1,39 +1,38 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTDisclosure } from "../disclosure.js"; -type DisclosureStoryArgs = Args & FASTDisclosure; -type DisclosureStoryMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` - ${x => x.detail} + ${x => x.storyContent} `; export default { title: "Disclosure", args: { - summary: "More about Flash", - detail: html` - ⚡️ -
- Created by writer Gardner Fox and artist Harry Lampert, the original Flash - first appeared in Flash Comics #1 (cover date January 1940/release month - November 1939). Nicknamed the "Scarlet Speedster", all incarnations of the - Flash possess "super speed", which includes the ability to run, move, and - think extremely fast, use superhuman reflexes, and seemingly violate - certain laws of physics. -
- `, + expanded: false, }, argTypes: { - expanded: { control: { type: "boolean" } }, + expanded: { control: "boolean" }, + storyContent: { table: { disable: true } }, + summary: { control: "text" }, }, -} as DisclosureStoryMeta; +} as Meta; -export const Disclosure = (args: DisclosureStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Disclosure: Story = renderComponent(storyTemplate).bind({}); +Disclosure.args = { + storyContent: html` + ⚡️ +
+ Created by writer Gardner Fox and artist Harry Lampert, the original Flash + first appeared in Flash Comics #1 (cover date January 1940/release month + November 1939). Nicknamed the "Scarlet Speedster", all incarnations of the + Flash possess "super speed", which includes the ability to run, move, and + think extremely fast, use superhuman reflexes, and seemingly violate certain + laws of physics. +
+ `, + summary: "More about Flash", }; diff --git a/packages/web-components/fast-foundation/src/divider/stories/divider.stories.ts b/packages/web-components/fast-foundation/src/divider/stories/divider.stories.ts index 34d677351f2..668b3571e93 100644 --- a/packages/web-components/fast-foundation/src/divider/stories/divider.stories.ts +++ b/packages/web-components/fast-foundation/src/divider/stories/divider.stories.ts @@ -1,13 +1,11 @@ import { html } from "@microsoft/fast-element"; import { Orientation } from "@microsoft/fast-web-utilities"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTDivider } from "../divider.js"; import { DividerRole } from "../divider.options.js"; -type DividerStoryArgs = Args & FASTDivider; -type DividerStoryMeta = Meta; - -const componentTemplate = html` +export const storyTemplate = html>` ` export default { title: "Divider", + excludeStories: ["storyTemplate"], argTypes: { - orientation: { - options: Object.values(Orientation), - control: { type: "select" }, - }, - role: { - options: Object.values(DividerRole), - control: { type: "select" }, - }, + orientation: { control: "radio", options: Object.values(Orientation) }, + role: { control: "select", options: Object.values(DividerRole) }, }, -} as DividerStoryMeta; - -export const Divider = (args: DividerStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; - -export const DividerPresentation = Divider.bind({}); -DividerPresentation.storyName = "Divider (presentation role)"; -DividerPresentation.args = { - role: DividerRole.presentation, -}; +} as Meta; -export const DividerVertical = Divider.bind({}); -DividerVertical.args = { - orientation: Orientation.vertical, -}; +export const Divider: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/fast-foundation/src/flipper/stories/flipper.stories.ts b/packages/web-components/fast-foundation/src/flipper/stories/flipper.stories.ts index 1efe444cb73..a96a6657bc3 100644 --- a/packages/web-components/fast-foundation/src/flipper/stories/flipper.stories.ts +++ b/packages/web-components/fast-foundation/src/flipper/stories/flipper.stories.ts @@ -1,60 +1,28 @@ -import { html, repeat } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { html } from "@microsoft/fast-element"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTFlipper } from "../flipper.js"; import { FlipperDirection } from "../flipper.options.js"; -type FlipperStoryArgs = Args & FASTFlipper; -type FlipperStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` `; export default { title: "Flipper", + args: { + disabled: false, + hiddenFromAT: true, + }, argTypes: { - direction: { - options: Object.values(FlipperDirection), - control: { type: "select" }, - }, - disabled: { - control: { type: "boolean" }, - }, + direction: { control: "select", options: Object.values(FlipperDirection) }, + disabled: { control: "boolean" }, + hiddenFromAT: { control: "boolean" }, }, -} as FlipperStoryMeta; - -export const Flipper = (args: FlipperStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; - -export const FlipperPrevious = Flipper.bind({}); -FlipperPrevious.storyName = "Previous Flipper"; -FlipperPrevious.args = { - direction: FlipperDirection.previous, -}; - -export const FlipperDisabled = (args: FlipperStoryArgs) => { - const storyFragment = new DocumentFragment(); - - html` - ${repeat(x => x.items, componentTemplate)} - `.render(args, storyFragment); +} as Meta; - return storyFragment; -}; -FlipperDisabled.storyName = "Disabled Flippers"; -FlipperDisabled.args = { - items: [ - { direction: FlipperDirection.previous, disabled: true }, - { direction: FlipperDirection.next, disabled: true }, - ], - direction: FlipperDirection.previous, -}; -FlipperDisabled.argTypes = { - items: { table: { disable: true } }, -}; +export const Flipper: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/fast-foundation/src/horizontal-scroll/README.md b/packages/web-components/fast-foundation/src/horizontal-scroll/README.md index 3d061328c08..435ae8f6366 100644 --- a/packages/web-components/fast-foundation/src/horizontal-scroll/README.md +++ b/packages/web-components/fast-foundation/src/horizontal-scroll/README.md @@ -129,6 +129,17 @@ export const myHorizontalScroll = HorizontalScroll.compose + + + ### class: `FASTHorizontalScroll` #### Superclass @@ -139,18 +150,18 @@ export const myHorizontalScroll = HorizontalScroll.compose; - -const componentTemplate = html` - - ${repeat( - x => x.items, - html` - ${x => x} - `, - { - positioning: true, - } - )} +const storyTemplate = html>` + + ${x => x.storyContent} `; export default { title: "Horizontal Scroll", args: { - items: new Array(16).fill(html` - A button - `), + flippersHiddenFromAT: false, + storyContent: html` + ${repeat(x => x.storyItems, cardStoryTemplate)} + `, + storyItems: new Array(16).fill(null).map((_, i) => ({ + storyContent: html` +
Card ${i + 1}
+ button + `, + })), }, argTypes: { - items: { table: { disable: true } }, + duration: { control: "text" }, + flippersHiddenFromAT: { control: "boolean" }, + easing: { control: "text", options: Object.values(ScrollEasing) }, + speed: { control: { type: "number", min: 0 } }, + storyContent: { table: { disable: true } }, + storyItems: { table: { disable: true } }, + view: { control: "radio", options: Object.values(HorizontalScrollView) }, }, decorators: [ Story => { const renderedStory = Story() as FASTHorizontalScroll; - const styles = document.createElement("style"); - styles.innerHTML = /* css */ ` - fast-card { - width: 120px; - height: 200px; + renderedStory.$fastController.addStyles(css` + ::slotted(fast-card) { color: var(--neutral-foreground-rest); + height: 200px; + width: 120px; } - fast-horizontal-scroll { + :host { max-width: 620px; margin: 20px; } - - .right-gradient { - --scroll-fade-next: var(--fill-color); - } - - .both-gradient { - --scroll-fade-next: var(--fill-color); - --scroll-fade-previous: var(--fill-color); - } - - .top-align { - --scroll-align: flex-start; - } - - .bottom-align { - --scroll-align: flex-end; - } - - .full-width, - .full-width fast-card { - width: 600px; - height: 300px; - } - .window-resize { - max-width: unset; - } - `; - - renderedStory.append(styles); + `); return renderedStory; }, ], -} as HorizontalScrollStoryMeta; +} as Meta; -export const HorizontalScroll = (args: HorizontalScrollStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const HorizontalScroll: Story = renderComponent( + storyTemplate +).bind({}); diff --git a/packages/web-components/fast-foundation/src/listbox-option/listbox-option.ts b/packages/web-components/fast-foundation/src/listbox-option/listbox-option.ts index aa2ad20368e..891cb5f198d 100644 --- a/packages/web-components/fast-foundation/src/listbox-option/listbox-option.ts +++ b/packages/web-components/fast-foundation/src/listbox-option/listbox-option.ts @@ -282,7 +282,7 @@ export class DelegatesARIAListboxOption { * HTML Attribute: `aria-posinset` */ @observable - ariaPosInSet: string | null; + public ariaPosInSet: string | null; /** * See {@link https://www.w3.org/TR/wai-aria-1.2/#option} for more information. @@ -291,7 +291,7 @@ export class DelegatesARIAListboxOption { * HTML Attribute: `aria-selected` */ @observable - ariaSelected: "true" | "false" | string | null; + public ariaSelected: "true" | "false" | string | null; /** * See {@link https://www.w3.org/TR/wai-aria-1.2/#option} for more information. @@ -300,7 +300,7 @@ export class DelegatesARIAListboxOption { * HTML Attribute: `aria-setsize` */ @observable - ariaSetSize: string | null; + public ariaSetSize: string | null; } /** diff --git a/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.register.ts b/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.register.ts index c1dc7d1529b..433c455ba63 100644 --- a/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.register.ts +++ b/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.register.ts @@ -27,6 +27,10 @@ const styles = css` white-space: nowrap; } + :host([hidden]) { + display: none; + } + :host(:focus-visible) { background: var(--accent-fill-focus); border-color: var(--focus-stroke-outer); diff --git a/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.stories.ts b/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.stories.ts index 31ebf7f3114..aa1851e45e3 100644 --- a/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.stories.ts +++ b/packages/web-components/fast-foundation/src/listbox-option/stories/listbox-option.stories.ts @@ -1,79 +1,40 @@ -import { html, repeat } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { html } from "@microsoft/fast-element"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTListboxOption } from "../listbox-option.js"; -type ListboxOptionStoryArgs = Args & FASTListboxOption; -type ListboxOptionStoryMeta = Meta; - -const storyTemplate = html` +export const storyTemplate = html>` - ${x => x.text} + ${x => x.storyContent} `; export default { - title: "Listbox/Listbox Option", + title: "Listbox Option", + excludeStories: ["storyTemplate"], args: { - text: "Listbox option", + selected: false, + disabled: false, + storyContent: "Listbox option", value: "listbox-value", }, argTypes: { - selected: { - control: { - type: "boolean", - }, - }, + disabled: { control: "boolean" }, + items: { table: { disable: true } }, + selected: { control: "boolean" }, + value: { control: "text" }, + ariaChecked: { control: "text" }, + ariaPosInSet: { control: "text" }, + ariaSelected: { control: "text" }, + ariaSetSize: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as ListboxOptionStoryMeta; - -export const ListboxOption = (args: ListboxOptionStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; - -export const ListboxOptionSelected = ListboxOption.bind({}); -ListboxOptionSelected.storyName = "Selected Listbox Option"; -ListboxOptionSelected.args = { - selected: true, -}; - -export const ListboxOptionDisabled = (args: ListboxOptionStoryArgs) => { - const disabledStoryTemplate = html` - ${repeat(x => x.items, storyTemplate)} - `; +} as Meta; - const storyFragment = new DocumentFragment(); - disabledStoryTemplate.render(args, storyFragment); - return storyFragment; -}; -ListboxOptionDisabled.storyName = "Disabled Listbox Option"; -ListboxOptionDisabled.args = { - items: [ - { - disabled: true, - text: "disabled (unselected)", - }, - { - disabled: true, - text: "disabled (selected)", - }, - { - checked: false, - disabled: true, - selected: true, - text: "disabled (unselected, checked)", - }, - { - checked: true, - disabled: true, - selected: true, - text: "disabled (selected, checked)", - }, - ], -}; +export const ListboxOption: Story = renderComponent( + storyTemplate +).bind({}); diff --git a/packages/web-components/fast-foundation/src/listbox/stories/listbox.register.ts b/packages/web-components/fast-foundation/src/listbox/stories/listbox.register.ts index 23d82201e9c..b5a1e2d791b 100644 --- a/packages/web-components/fast-foundation/src/listbox/stories/listbox.register.ts +++ b/packages/web-components/fast-foundation/src/listbox/stories/listbox.register.ts @@ -14,6 +14,10 @@ const styles = css` padding: calc(var(--design-unit) * 1px) 0; } + :host([hidden]) { + display: none !important; + } + :host(:focus-within:not([disabled])) { border-color: var(--focus-stroke-outer); box-shadow: 0 0 0 calc((var(--focus-stroke-width) - var(--stroke-width)) * 1px) diff --git a/packages/web-components/fast-foundation/src/listbox/stories/listbox.stories.ts b/packages/web-components/fast-foundation/src/listbox/stories/listbox.stories.ts index c0c6709a1a2..4eb1201a7d3 100644 --- a/packages/web-components/fast-foundation/src/listbox/stories/listbox.stories.ts +++ b/packages/web-components/fast-foundation/src/listbox/stories/listbox.stories.ts @@ -1,77 +1,57 @@ import { html, repeat } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { storyTemplate as listboxOptionStoryTemplate } from "../../listbox-option/stories/listbox-option.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTListboxElement } from "../listbox.element.js"; -type ListboxStoryArgs = Args & FASTListboxElement; -type ListboxStoryMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` - ${repeat( - x => x.items, - html` - ${x => x.text} - ` - )} + ${x => x.storyContent} `; export default { title: "Listbox", args: { - items: [ - { text: "William Hartnell" }, - { text: "Patrick Troughton" }, - { text: "Jon Pertwee" }, - { text: "Tom Baker" }, - { text: "Peter Davidson" }, - { text: "Colin Baker" }, - { text: "Sylvester McCoy" }, - { text: "Paul McGann" }, - { text: "Christopher Eccleston" }, - { text: "David Tenant" }, - { text: "Matt Smith" }, - { text: "Peter Capaldi" }, - { text: "Jodie Whittaker" }, + disabled: false, + multiple: false, + storyContent: html>` + ${repeat(x => x.storyItems, listboxOptionStoryTemplate)} + `, + storyItems: [ + { storyContent: "William Hartnell" }, + { storyContent: "Patrick Troughton" }, + { storyContent: "Jon Pertwee" }, + { storyContent: "Tom Baker" }, + { storyContent: "Peter Davidson" }, + { storyContent: "Colin Baker" }, + { storyContent: "Sylvester McCoy" }, + { storyContent: "Paul McGann" }, + { storyContent: "Christopher Eccleston" }, + { storyContent: "David Tenant" }, + { storyContent: "Matt Smith" }, + { storyContent: "Peter Capaldi" }, + { storyContent: "Jodie Whittaker" }, + { storyContent: "Ncuti Gatwa" }, ], }, argTypes: { - disabled: { - control: { - type: "boolean", - }, - }, - items: { - table: { - disable: true, - }, - }, - size: { - control: { - type: "number", - }, - }, + disabled: { control: "boolean" }, + multiple: { control: "boolean" }, + size: { control: "number" }, + storyContent: { table: { disable: true } }, + storyItems: { table: { disable: true } }, }, -} as ListboxStoryMeta; +} as Meta; -export const Listbox = (args: ListboxStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const Listbox: Story = renderComponent(storyTemplate).bind({}); -export const ListboxMultiple = Listbox.bind({}); +export const ListboxMultiple: Story = Listbox.bind({}); ListboxMultiple.storyName = "Listbox in multiple-selection mode"; ListboxMultiple.args = { multiple: true, }; - -export const ListboxDisabled = Listbox.bind({}); -ListboxDisabled.storyName = "Disabled Listbox"; -ListboxDisabled.args = { - disabled: true, -}; diff --git a/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.register.ts b/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.register.ts index 91fbcb5d538..d4207aca432 100644 --- a/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.register.ts +++ b/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.register.ts @@ -4,7 +4,7 @@ import { menuItemTemplate } from "../menu-item.template.js"; const styles = css` :host([hidden]) { - display: none; + display: none !important; } :host { diff --git a/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.stories.ts b/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.stories.ts index 1f99036243d..f7ef082652d 100644 --- a/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.stories.ts +++ b/packages/web-components/fast-foundation/src/menu-item/stories/menu-item.stories.ts @@ -1,128 +1,123 @@ import { css, html, repeat } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTMenuItem } from "../menu-item.js"; import { MenuItemRole } from "../menu-item.options.js"; -type MenuItemStoryArgs = Args & FASTMenuItem; -type MenuItemStoryMeta = Meta; - -const componentTemplate = html` +export const storyTemplate = html>` - ${x => x.content} + ${x => x.storyContent} `; export default { - title: "Menu/Menu Item", + title: "Menu Item", + excludeStories: ["storyTemplate"], args: { - content: "Menu Item", + checked: false, + disabled: false, + expanded: false, }, argTypes: { - checked: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, - expanded: { control: { type: "boolean" } }, - role: { options: Object.values(MenuItemRole), control: { type: "select" } }, + checked: { control: "boolean", if: { arg: "role", neq: MenuItemRole.menuitem } }, + disabled: { control: "boolean" }, + expanded: { control: "boolean" }, + role: { control: "select", options: Object.values(MenuItemRole) }, }, -} as MenuItemStoryMeta; +} as Meta; -export const MenuItem = (args: MenuItemStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const MenuItem: Story = renderComponent(storyTemplate).bind({}); +MenuItem.args = { + storyContent: "Menu Item", }; -export const WithSlottedStart = MenuItem.bind({}); -WithSlottedStart.args = { - content: html` +export const MenuItemWithSlottedStart: Story = MenuItem.bind({}); +MenuItemWithSlottedStart.args = { + storyContent: html` Menu item with slotted start icon `, }; -export const WithSlottedEnd = MenuItem.bind({}); -WithSlottedEnd.args = { - content: html` +export const MenuItemWithSlottedEnd: Story = MenuItem.bind({}); +MenuItemWithSlottedEnd.args = { + storyContent: html` Menu item with slotted end icon `, }; -export const MenuItemCheckbox = (args: MenuItemStoryArgs) => { - const menuItemCheckboxTemplate = html` -
${repeat(x => x.items, componentTemplate)}
- `; - const storyFragment = new DocumentFragment(); - menuItemCheckboxTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const MenuItemCheckbox: Story = renderComponent( + html>` +
${repeat(x => x.items, storyTemplate)}
+ ` +).bind({}); MenuItemCheckbox.args = { items: [ { - content: "Menu item checkbox (unchecked)", role: MenuItemRole.menuitemcheckbox, + storyContent: "Menu item checkbox (unchecked)", }, { - content: "Menu item checkbox (checked)", - role: MenuItemRole.menuitemcheckbox, checked: true, + role: MenuItemRole.menuitemcheckbox, + storyContent: "Menu item checkbox (checked)", }, { - content: "Menu item checkbox (unchecked, disabled)", - role: MenuItemRole.menuitemcheckbox, checked: false, disabled: true, + role: MenuItemRole.menuitemcheckbox, + storyContent: "Menu item checkbox (unchecked, disabled)", }, { - content: "Menu item checkbox (checked, disabled)", - role: MenuItemRole.menuitemcheckbox, - disabled: true, checked: true, + disabled: true, + role: MenuItemRole.menuitemcheckbox, + storyContent: "Menu item checkbox (checked, disabled)", }, ], }; -export const MenuItemRadio = (args: MenuItemStoryArgs) => { - const MenuItemRadioTemplate = html` - ${repeat(x => x.items, componentTemplate)} - `; - const storyFragment = new DocumentFragment(); - MenuItemRadioTemplate.render(args, storyFragment); - return storyFragment; -}; +export const MenuItemRadio: Story = renderComponent( + html>` + ${repeat(x => x.items, storyTemplate)} + ` +).bind({}); MenuItemRadio.args = { items: [ { - content: "Menu item radio (unchecked)", role: MenuItemRole.menuitemradio, + storyContent: "Menu item radio (unchecked)", }, { - content: "Menu item radio (checked)", - role: MenuItemRole.menuitemradio, checked: true, + role: MenuItemRole.menuitemradio, + storyContent: "Menu item radio (checked)", }, { - content: "Menu item radio (unchecked, disabled)", - role: MenuItemRole.menuitemradio, checked: false, disabled: true, + role: MenuItemRole.menuitemradio, + storyContent: "Menu item radio (unchecked, disabled)", }, { - content: "Menu item radio (checked, disabled)", - role: MenuItemRole.menuitemradio, - disabled: true, checked: true, + disabled: true, + role: MenuItemRole.menuitemradio, + storyContent: "Menu item radio (checked, disabled)", }, ], }; -export const MenuItemExpanded: MenuItemStoryMeta = MenuItem.bind({}); +export const MenuItemExpanded: Story = MenuItem.bind({}); MenuItemExpanded.args = { - content: html` + storyContent: html` Expanded
submenu slot
`, diff --git a/packages/web-components/fast-foundation/src/menu/stories/menu.stories.ts b/packages/web-components/fast-foundation/src/menu/stories/menu.stories.ts index 18b3e47a3b2..ceeb8c7b287 100644 --- a/packages/web-components/fast-foundation/src/menu/stories/menu.stories.ts +++ b/packages/web-components/fast-foundation/src/menu/stories/menu.stories.ts @@ -1,109 +1,169 @@ -import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { html, repeat } from "@microsoft/fast-element"; +import { storyTemplate as dividerStoryTemplate } from "../../divider/stories/divider.stories.js"; +import type { FASTMenuItem } from "../../menu-item/menu-item.js"; +import { storyTemplate as menuItemStoryTemplate } from "../../menu-item/stories/menu-item.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTMenu } from "../menu.js"; -type MenuStoryArgs = Args & FASTMenu; -type MenuStoryMeta = Meta; +const storyTemplate = html>` + ${x => x.storyContent} +`; -const storyTemplate = html` - ${x => x.content} +const storyContentTemplate = html` + ${repeat( + x => x.storyItems, + html>` + ${x => x.template ?? menuItemStoryTemplate} + ` + )} `; export default { title: "Menu", args: { - content: html` - Menu item 1 - Menu item 2 - Menu item 3 - `, + storyContent: storyContentTemplate, + storyItems: [ + { storyContent: "Menu Item 1" }, + { storyContent: "Menu Item 2" }, + { storyContent: "Menu Item 3" }, + ], }, argTypes: { - content: { table: { disable: true } }, + storyContent: { table: { disable: true } }, }, -} as MenuStoryMeta; +} as Meta; -export const Menu = (args: MenuStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Menu: Story = renderComponent(storyTemplate).bind({}); +Menu.args = { + storyContent: html` + ${repeat( + x => x.storyItems, + html>` + ${x => x.template ?? menuItemStoryTemplate} + ` + )} + `, }; -export const MenuWithDivider = Menu.bind({}); +export const MenuWithDivider: Story = Menu.bind({}); MenuWithDivider.args = { - content: html` - Menu item 1 - Menu item 2 - - Menu item 3 - Menu item 4 - `, + storyItems: [ + { storyContent: "Menu Item 1" }, + { storyContent: "Menu Item 2" }, + { template: dividerStoryTemplate }, + { storyContent: "Menu Item 3" }, + { storyContent: "Menu Item 4" }, + ], }; -export const MenuWithFormControls = Menu.bind({}); +export const MenuWithFormControls: Story = Menu.bind({}); MenuWithFormControls.args = { - content: html` - Menu item 1 - Menu item 2 - - Checkbox 1 - Checkbox 2 - - Radio 1.1 - Radio 1.2 - - Radio 2.1 - Radio 2.2 - `, + storyItems: [ + { storyContent: "Menu Item 1" }, + { storyContent: "Menu Item 2" }, + { template: dividerStoryTemplate }, + { storyContent: "Checkbox 1", role: "menuitemcheckbox" }, + { storyContent: "Checkbox 2", role: "menuitemcheckbox" }, + { template: dividerStoryTemplate }, + { storyContent: "Radio 1.1", role: "menuitemradio" }, + { storyContent: "Radio 1.2", role: "menuitemradio" }, + { template: dividerStoryTemplate }, + { storyContent: "Radio 2.1", role: "menuitemradio" }, + { storyContent: "Radio 2.2", role: "menuitemradio" }, + ], }; -export const MenuWithNestedItems = Menu.bind({}); +export const MenuWithNestedItems: Story = Menu.bind({}); MenuWithNestedItems.args = { - content: html` - - Menu item 1 - - Menu item 1.1 - Menu item 1.2 - Menu item 1.3 - - - - Menu item 2 - - Menu item 2.1 - Menu item 2.2 - Menu item 2.3 - - - - Menu item 3 - - Menu item 3.1 - Menu item 3.2 - Menu item 3.3 - - - `, + storyItems: [ + { + storyContent: html` + Menu Item 1 ${repeat(x => x.storyItems, storyTemplate)} + `, + storyItems: [ + { + slot: "submenu", + storyContent: storyContentTemplate, + storyItems: [ + { storyContent: "Menu Item 1.1" }, + { storyContent: "Menu Item 1.2" }, + { storyContent: "Menu Item 1.3" }, + ], + }, + ], + }, + { + storyContent: html` + Menu Item 2 ${repeat(x => x.storyItems, storyTemplate)} + `, + storyItems: [ + { + slot: "submenu", + storyContent: storyContentTemplate, + storyItems: [ + { + storyContent: html` + Menu Item 2.1 ${repeat(x => x.storyItems, storyTemplate)} + `, + storyItems: [ + { + slot: "submenu", + storyContent: storyContentTemplate, + storyItems: [ + { storyContent: "Menu Item 2.1.1" }, + { storyContent: "Menu Item 2.1.2" }, + { storyContent: "Menu Item 2.1.3" }, + ], + }, + ], + }, + { storyContent: "Menu Item 2.2" }, + { storyContent: "Menu Item 2.3" }, + ], + }, + ], + }, + { + storyContent: html` + Menu Item 3 ${repeat(x => x.storyItems, storyTemplate)} + `, + storyItems: [ + { + slot: "submenu", + storyContent: storyContentTemplate, + storyItems: [ + { storyContent: "Menu Item 3.1" }, + { storyContent: "Menu Item 3.2" }, + { storyContent: "Menu Item 3.3" }, + ], + }, + ], + }, + ], }; -export const WithIcons = Menu.bind({}); -WithIcons.args = { - content: html` - - - - Menu item 1 - - - - - Menu item 2 - - - - - Menu item 3 - - `, +export const MenuWithItemsWithIcons: Story = Menu.bind({}); +MenuWithItemsWithIcons.args = { + storyItems: [ + { + storyContent: html` + + Slotted start icon + `, + }, + { + storyContent: html` + + Slotted end icon + `, + }, + { + storyContent: html` + + + Slotted start and end icons + `, + }, + ], }; diff --git a/packages/web-components/fast-foundation/src/number-field/stories/number-field.stories.ts b/packages/web-components/fast-foundation/src/number-field/stories/number-field.stories.ts index 49e1df3c266..48422cf64ef 100644 --- a/packages/web-components/fast-foundation/src/number-field/stories/number-field.stories.ts +++ b/packages/web-components/fast-foundation/src/number-field/stories/number-field.stories.ts @@ -1,17 +1,17 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTNumberField } from "../number-field.js"; -type NumberFieldStoryArgs = Args & FASTNumberField; -type NumberFieldStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` ` placeholder="${x => x.placeholder}" size="${x => x.size}" value="${x => x.value}" + :ariaAtomic="${x => x.ariaAtomic}" + :ariaBusy="${x => x.ariaBusy}" + :ariaControls="${x => x.ariaControls}" + :ariaCurrent="${x => x.ariaCurrent}" + :ariaDescribedby="${x => x.ariaDescribedby}" + :ariaDetails="${x => x.ariaDetails}" + :ariaDisabled="${x => x.ariaDisabled}" + :ariaErrormessage="${x => x.ariaErrormessage}" + :ariaFlowto="${x => x.ariaFlowto}" + :ariaHaspopup="${x => x.ariaHaspopup}" + :ariaHidden="${x => x.ariaHidden}" + :ariaInvalid="${x => x.ariaInvalid}" + :ariaKeyshortcuts="${x => x.ariaKeyshortcuts}" + :ariaLabel="${x => x.ariaLabel}" + :ariaLabelledby="${x => x.ariaLabelledby}" + :ariaLive="${x => x.ariaLive}" + :ariaOwns="${x => x.ariaOwns}" + :ariaRelevant="${x => x.ariaRelevant}" + :ariaRoledescription="${x => x.ariaRoledescription}" > - ${x => x.label} + ${x => x.storyContent} `; export default { title: "Number Field", args: { - label: "Number Field", - placeholder: "number", + readOnly: false, + required: false, + autofocus: false, + disabled: false, + hideStep: false, + storyContent: "Number Field", }, argTypes: { - autofocus: { control: { type: "boolean" } }, - label: { control: { type: "text" } }, - disabled: { control: { type: "boolean" } }, - hideStep: { control: { type: "boolean " } }, - list: { control: { type: "text" } }, - max: { control: { type: "number" } }, - maxlength: { control: { type: "number" } }, - min: { control: { type: "number" } }, - minlength: { control: { type: "number" } }, - placeholder: { control: { type: "text" } }, - readOnly: { control: { type: "boolean" } }, - required: { control: { type: "boolean" } }, - size: { control: { type: "number" } }, - value: { control: { type: "number" } }, + autofocus: { control: "boolean" }, + disabled: { control: "boolean" }, + hideStep: { control: "boolean" }, + step: { control: "number" }, + list: { control: "text" }, + max: { control: "number" }, + maxlength: { control: "number" }, + min: { control: "number" }, + minlength: { control: "number" }, + placeholder: { control: "text" }, + readOnly: { control: "boolean" }, + required: { control: "boolean" }, + size: { control: "number" }, + value: { control: "number" }, + valueAsNumber: { control: "number" }, + ariaAtomic: { control: "text" }, + ariaBusy: { control: "text" }, + ariaControls: { control: "text" }, + ariaCurrent: { control: "text" }, + ariaDescribedby: { control: "text" }, + ariaDetails: { control: "text" }, + ariaDisabled: { control: "text" }, + ariaErrormessage: { control: "text" }, + ariaFlowto: { control: "text" }, + ariaHaspopup: { control: "text" }, + ariaHidden: { control: "text" }, + ariaInvalid: { control: "text" }, + ariaKeyshortcuts: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + ariaLive: { control: "text" }, + ariaOwns: { control: "text" }, + ariaRelevant: { control: "text" }, + ariaRoledescription: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as NumberFieldStoryMeta; +} as Meta; + +export const NumberField: Story = renderComponent(storyTemplate).bind( + {} +); -export const NumberField = (args: NumberFieldStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const NumberFieldInForm: Story = renderComponent(html` +
+ ${storyTemplate} + Submit +
+`).bind({}); diff --git a/packages/web-components/fast-foundation/src/picker/README.md b/packages/web-components/fast-foundation/src/picker/README.md index 60ffbab81d1..0be5da500c9 100644 --- a/packages/web-components/fast-foundation/src/picker/README.md +++ b/packages/web-components/fast-foundation/src/picker/README.md @@ -169,6 +169,16 @@ export class FASTTextField extends TextField {} +### Variables + +| Name | Description | Type | +| --------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `MenuPlacement` | vertical positioning values for an anchored region | `{ bottom: "bottom", bottomFill: "bottom-fill", tallest: "tallest", tallestFill: "tallest-fill", top: "top", topFill: "top-fill", }` | + +
+ + + ### class: `FASTPicker` #### Superclass @@ -192,7 +202,7 @@ export class FASTTextField extends TextField {} | `label` | public | `string` | | Applied to the aria-label attribute of the input element | | | `labelledBy` | public | `string` | | Applied to the aria-labelledby attribute of the input element | | | `placeholder` | public | `string` | | Applied to the placeholder attribute of the input element | | -| `menuPlacement` | public | `menuConfigs` | `"bottom-fill"` | Controls menu placement | | +| `menuPlacement` | public | `MenuPlacement` | | Controls menu placement | | | `showLoading` | public | `boolean` | `false` | Whether to display a loading state if the menu is opened. | | | `listItemTemplate` | public | `ViewTemplate` | | Template used to generate selected items. This is used in a repeat directive. | | | `defaultListItemTemplate` | public | `ViewTemplate or undefined` | | Default template to use for selected items (usually specified in the component template). This is used in a repeat directive. | | diff --git a/packages/web-components/fast-foundation/src/picker/index.ts b/packages/web-components/fast-foundation/src/picker/index.ts index a0663d95289..815c5233273 100644 --- a/packages/web-components/fast-foundation/src/picker/index.ts +++ b/packages/web-components/fast-foundation/src/picker/index.ts @@ -1,10 +1,11 @@ -export * from "./picker.template.js"; -export * from "./picker.js"; -export * from "./picker-menu.template.js"; -export * from "./picker-menu.js"; -export * from "./picker-menu-option.template.js"; -export * from "./picker-menu-option.js"; -export * from "./picker-list.template.js"; -export * from "./picker-list.js"; -export * from "./picker-list-item.template.js"; export * from "./picker-list-item.js"; +export * from "./picker-list-item.template.js"; +export * from "./picker-list.js"; +export * from "./picker-list.template.js"; +export * from "./picker-menu-option.js"; +export * from "./picker-menu-option.template.js"; +export * from "./picker-menu.js"; +export * from "./picker-menu.template.js"; +export * from "./picker.js"; +export * from "./picker.options.js"; +export * from "./picker.template.js"; diff --git a/packages/web-components/fast-foundation/src/picker/picker.options.ts b/packages/web-components/fast-foundation/src/picker/picker.options.ts new file mode 100644 index 00000000000..aa4cb403419 --- /dev/null +++ b/packages/web-components/fast-foundation/src/picker/picker.options.ts @@ -0,0 +1,18 @@ +/** + * vertical positioning values for an anchored region + * @beta + */ +export const MenuPlacement = { + bottom: "bottom", + bottomFill: "bottom-fill", + tallest: "tallest", + tallestFill: "tallest-fill", + top: "top", + topFill: "top-fill", +} as const; + +/** + * Type for vertical positioning values for an anchored region + * @beta + */ +export type MenuPlacement = typeof MenuPlacement[keyof typeof MenuPlacement]; diff --git a/packages/web-components/fast-foundation/src/picker/picker.ts b/packages/web-components/fast-foundation/src/picker/picker.ts index f013fc65a27..801462e2430 100644 --- a/packages/web-components/fast-foundation/src/picker/picker.ts +++ b/packages/web-components/fast-foundation/src/picker/picker.ts @@ -31,11 +31,12 @@ import { FlyoutPosTop, FlyoutPosTopFill, } from "../anchored-region/index.js"; -import type { FASTPickerMenu } from "./picker-menu.js"; -import { FASTPickerMenuOption } from "./picker-menu-option.js"; import { FASTPickerListItem } from "./picker-list-item.js"; -import { FormAssociatedPicker } from "./picker.form-associated.js"; import type { FASTPickerList } from "./picker-list.js"; +import { FASTPickerMenuOption } from "./picker-menu-option.js"; +import type { FASTPickerMenu } from "./picker-menu.js"; +import { FormAssociatedPicker } from "./picker.form-associated.js"; +import { MenuPlacement } from "./picker.options.js"; const pickerInputTemplate: ViewTemplate = html` ` /> `; -/** - * Defines the vertical positioning options for an anchored region - * - * @beta - */ -export type menuConfigs = - | "bottom" - | "bottom-fill" - | "tallest" - | "tallest-fill" - | "top" - | "top-fill"; - /** * A Picker Custom HTML Element. This is an early "alpha" version of the component. * Developers should expect the api to evolve, breaking changes are possible. @@ -193,7 +181,7 @@ export class FASTPicker extends FormAssociatedPicker { * HTML Attribute: menu-placement */ @attr({ attribute: "menu-placement" }) - public menuPlacement: menuConfigs = "bottom-fill"; + public menuPlacement: MenuPlacement = MenuPlacement.bottomFill; protected menuPlacementChanged(): void { if (this.$fastController.isConnected) { this.updateMenuConfig(); diff --git a/packages/web-components/fast-foundation/src/picker/stories/picker.stories.ts b/packages/web-components/fast-foundation/src/picker/stories/picker.stories.ts index 786bd9a3c1a..bc132c4b1e7 100644 --- a/packages/web-components/fast-foundation/src/picker/stories/picker.stories.ts +++ b/packages/web-components/fast-foundation/src/picker/stories/picker.stories.ts @@ -1,16 +1,15 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTPicker } from "../picker.js"; +import { MenuPlacement } from "../picker.options.js"; -type PickerArgs = Args & FASTPicker; -type PickerMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` ` export default { title: "Picker", args: { - selection: "apple", - options: "apple, orange, banana, mango, strawberry, raspberry, blueberry", - placeholder: "Choose fruit", - noSuggestionsText: "No such fruit", - suggestionsAvailableText: "Found some fruit", - loadingText: "Loading", - label: "Fruit picker", + // TODO: These are always true https://github.com/microsoft/fast/issues/6311 + filterQuery: true, + filterSelected: true, }, argTypes: { - filterSelected: { control: { type: "boolean" } }, - filterQuery: { control: { type: "boolean" } }, - maxSelected: { control: { type: "number" } }, - noSuggestionsText: { control: { type: "text" } }, - suggestionsAvailableText: { control: { type: "text" } }, - loadingText: { control: { type: "text" } }, - label: { control: { type: "text" } }, - labelledBy: { control: { type: "text" } }, - placeholder: { control: { type: "text" } }, - menuPlacement: { - options: [ - "bottom", - "bottom-fill", - "tallest", - "tallest-fill", - "top", - "top-fill", - ], - control: { type: "select" }, - }, + filterQuery: { control: "boolean" }, + filterSelected: { control: "boolean" }, + label: { control: "text" }, + labelledBy: { control: "text" }, + loadingText: { control: "text" }, + maxSelected: { control: "number" }, + menuPlacement: { control: "select", options: Object.values(MenuPlacement) }, + noSuggestionsText: { control: "text" }, + placeholder: { control: "text" }, + suggestionsAvailableText: { control: "text" }, }, -} as PickerMeta; +} as Meta; -export const Picker = (args: PickerArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const Picker: Story = renderComponent(storyTemplate).bind({}); +Picker.args = { + label: "Fruit picker", + loadingText: "Loading", + noSuggestionsText: "No such fruit", + options: "apple, orange, banana, mango, strawberry, raspberry, blueberry", + placeholder: "Choose fruit", + selection: "apple", + suggestionsAvailableText: "Found some fruit", }; diff --git a/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.stories.ts b/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.stories.ts index 80cebad0dad..312d182dfd4 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.stories.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.stories.ts @@ -1,43 +1,36 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTProgressRing } from "../progress-ring.js"; -type ProgressRingStoryArgs = Args & FASTProgressRing; -type ProgressRingStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` + > + ${x => x.storyContent} + `; export default { title: "Progress/Progress Ring", args: { - min: 0, - max: 100, + paused: false, + indeterminate: false, value: 75, }, argTypes: { - paused: { control: { type: "boolean" } }, + indeterminate: { control: "boolean" }, + min: { control: "number" }, + max: { control: "number" }, + paused: { control: "boolean" }, + storyContent: { table: { disable: true } }, + value: { control: "number", if: { arg: "indeterminate", truthy: false } }, }, -} as ProgressRingStoryMeta; - -export const ProgressRing = (args: ProgressRingStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; - -export const ProgressRingIndeterminate = ProgressRing.bind({}); -ProgressRingIndeterminate.args = { - value: null, -}; +} as Meta; -export const ProgressRingPaused = ProgressRing.bind({}); -ProgressRingPaused.args = { - paused: true, -}; +export const ProgressRing: Story = renderComponent(storyTemplate).bind( + {} +); diff --git a/packages/web-components/fast-foundation/src/progress/base-progress.ts b/packages/web-components/fast-foundation/src/progress/base-progress.ts index efc56e7c00d..52cd0760eb5 100644 --- a/packages/web-components/fast-foundation/src/progress/base-progress.ts +++ b/packages/web-components/fast-foundation/src/progress/base-progress.ts @@ -19,9 +19,7 @@ export class FASTBaseProgress extends FASTElement { @attr({ converter: nullableNumberConverter }) public value: number | null; protected valueChanged(): void { - if (this.$fastController.isConnected) { - this.updatePercentComplete(); - } + this.updatePercentComplete(); } /** diff --git a/packages/web-components/fast-foundation/src/progress/stories/progress.stories.ts b/packages/web-components/fast-foundation/src/progress/stories/progress.stories.ts index e22e1bd854d..e512fa8b5d1 100644 --- a/packages/web-components/fast-foundation/src/progress/stories/progress.stories.ts +++ b/packages/web-components/fast-foundation/src/progress/stories/progress.stories.ts @@ -1,43 +1,34 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTProgress } from "../progress.js"; -type ProgressStoryArgs = Args & FASTProgress; -type ProgressStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` + > + ${x => x.storyContent} + `; export default { title: "Progress", args: { - min: 0, - max: 100, + paused: false, + indeterminate: false, value: 75, }, argTypes: { - paused: { control: { type: "boolean" } }, + indeterminate: { control: "boolean" }, + min: { control: "number" }, + max: { control: "number" }, + paused: { control: "boolean" }, + storyContent: { table: { disable: true } }, + value: { control: "number", if: { arg: "indeterminate", truthy: false } }, }, -} as ProgressStoryMeta; - -export const Progress = (args: ProgressStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; - -export const ProgressIndeterminate = Progress.bind({}); -ProgressIndeterminate.args = { - value: null, -}; +} as Meta; -export const ProgressPaused = Progress.bind({}); -ProgressPaused.args = { - paused: true, -}; +export const Progress: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/fast-foundation/src/radio-group/stories/radio-group.stories.ts b/packages/web-components/fast-foundation/src/radio-group/stories/radio-group.stories.ts index 57b660212e6..af383aa5f4b 100644 --- a/packages/web-components/fast-foundation/src/radio-group/stories/radio-group.stories.ts +++ b/packages/web-components/fast-foundation/src/radio-group/stories/radio-group.stories.ts @@ -1,66 +1,67 @@ -import { html, repeat, when } from "@microsoft/fast-element"; +import { html, repeat } from "@microsoft/fast-element"; import { Orientation } from "@microsoft/fast-web-utilities"; -import type { Args, Meta } from "@storybook/html"; +import { storyTemplate as radioStoryTemplate } from "../../radio/stories/radio.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTRadioGroup } from "../radio-group.js"; -type RadioGroupStoryArgs = Args & FASTRadioGroup; -type RadioGroupStoryMeta = Meta; - -const storyTemplate = html` - - ${when( - x => x.label, - html` - - ` - )} - ${repeat( - x => x.items, - html` - - ${x => x.label} - - ` - )} +const storyTemplate = html>` + + ${x => x.storyContent} `; export default { - title: "Radio/Radio Group", + title: "Radio Group", args: { - label: "Fruits", + disabled: false, name: "fruits", - items: [ - { value: "apples", label: "Apples" }, - { value: "bananas", label: "Bananas" }, - { value: "blueberries", label: "Blueberries" }, - { value: "grapefruit", label: "Grapefruit" }, - { value: "kiwi", label: "Kiwi" }, - { value: "mango", label: "Mango" }, - { value: "oranges", label: "Oranges" }, - { value: "pineapple", label: "Pineapple" }, - { value: "strawberries", label: "Strawberries" }, + readOnly: false, + storyContent: html>` + + ${repeat(x => x.storyItems, radioStoryTemplate)} + `, + storyItems: [ + { storyContent: "Apples", value: "apples" }, + { storyContent: "Bananas", value: "bananas" }, + { storyContent: "Blueberries", value: "blueberries" }, + { storyContent: "Grapefruit", value: "grapefruit" }, + { storyContent: "Kiwi", value: "kiwi" }, + { storyContent: "Mango", value: "mango" }, + { storyContent: "Oranges", value: "oranges" }, + { storyContent: "Pineapple", value: "pineapple" }, + { storyContent: "Strawberries", value: "strawberries" }, ], }, argTypes: { - orientation: { - options: Object.values(Orientation), - control: { - type: "select", - }, - }, + disabled: { control: "boolean" }, + name: { control: "text" }, + orientation: { control: "radio", options: Object.values(Orientation) }, + readOnly: { control: "boolean" }, + storyContent: { table: { disable: true } }, + storyItems: { control: "object" }, + value: { control: "text" }, }, -} as RadioGroupStoryMeta; +} as Meta; -export const RadioGroup = (args: RadioGroupStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const RadioGroup: Story = renderComponent(storyTemplate).bind({}); -export const RadioGroupVertical = RadioGroup.bind({}); +export const RadioGroupVertical: Story = RadioGroup.bind({}); RadioGroupVertical.args = { orientation: Orientation.vertical, }; + +export const RadioGroupInForm: Story = renderComponent( + html>` +
+ ${storyTemplate} + Submit +
+ ` +).bind({}); diff --git a/packages/web-components/fast-foundation/src/radio/stories/radio.register.ts b/packages/web-components/fast-foundation/src/radio/stories/radio.register.ts index d8eb90d2803..23cffbbcf98 100644 --- a/packages/web-components/fast-foundation/src/radio/stories/radio.register.ts +++ b/packages/web-components/fast-foundation/src/radio/stories/radio.register.ts @@ -19,7 +19,6 @@ const styles = css` the radio is clicked. Maybe there is a better solution here? */ outline: none; position: relative; - transition: all 0.2s ease-in-out; user-select: none; } diff --git a/packages/web-components/fast-foundation/src/radio/stories/radio.stories.ts b/packages/web-components/fast-foundation/src/radio/stories/radio.stories.ts index 788c61796e3..a81aabe3d71 100644 --- a/packages/web-components/fast-foundation/src/radio/stories/radio.stories.ts +++ b/packages/web-components/fast-foundation/src/radio/stories/radio.stories.ts @@ -1,37 +1,48 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTRadio } from "../radio.js"; -type RadioStoryArgs = Args & FASTRadio; -type RadioStoryMeta = Meta; - -const storyTemplate = html` +export const storyTemplate = html>` - ${x => x.label} + ${x => x.storyContent} `; export default { title: "Radio", + excludeStories: ["storyTemplate"], args: { - label: "Label", checked: false, disabled: false, required: false, + readOnly: false, + storyContent: "Label", }, argTypes: { - checked: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, - required: { control: { type: "boolean" } }, + checked: { control: "boolean" }, + disabled: { control: "boolean" }, + name: { control: "text" }, + required: { control: "boolean" }, + storyContent: { table: { disable: true } }, + value: { control: "text" }, }, -} as RadioStoryMeta; +} as Meta; + +export const Radio: Story = renderComponent(storyTemplate).bind({}); -export const Radio = (args: RadioStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const RadioInForm: Story = renderComponent( + html>` +
+ ${storyTemplate} + Submit +
+ ` +).bind({}); diff --git a/packages/web-components/fast-foundation/src/search/stories/search.stories.ts b/packages/web-components/fast-foundation/src/search/stories/search.stories.ts index 2c4d72d31a3..c36e02d4ce4 100644 --- a/packages/web-components/fast-foundation/src/search/stories/search.stories.ts +++ b/packages/web-components/fast-foundation/src/search/stories/search.stories.ts @@ -1,51 +1,99 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTSearch } from "../search.js"; -type SearchStoryArgs = Args & FASTSearch; -type SearchStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` - ${x => x.label} + ${x => x.storyContent} `; export default { title: "Search", args: { - label: "Search", + autofocus: false, + disabled: false, + readonly: false, + required: false, + spellcheck: false, + storyContent: "Search", }, argTypes: { - autofocus: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, - label: { control: { type: "text" } }, - list: { control: { type: "text" } }, - maxlength: { control: { type: "number" } }, - minlength: { control: { type: "number" } }, - pattern: { control: { type: "text" } }, - placeholder: { control: { type: "text" } }, - readOnly: { control: { type: "boolean" } }, - size: { control: { type: "number" } }, - spellcheck: { control: { type: "boolean" } }, - value: { control: { type: "text" } }, + autofocus: { control: "boolean" }, + disabled: { control: "boolean" }, + list: { control: "text" }, + maxlength: { control: "number" }, + minlength: { control: "number" }, + pattern: { control: "text" }, + placeholder: { control: "text" }, + readonly: { control: "boolean" }, + required: { control: "boolean" }, + size: { control: "number" }, + spellcheck: { control: "boolean" }, + value: { control: "text" }, + ariaAtomic: { control: "text" }, + ariaBusy: { control: "text" }, + ariaControls: { control: "text" }, + ariaCurrent: { control: "text" }, + ariaDescribedby: { control: "text" }, + ariaDetails: { control: "text" }, + ariaDisabled: { control: "text" }, + ariaErrormessage: { control: "text" }, + ariaFlowto: { control: "text" }, + ariaHaspopup: { control: "text" }, + ariaHidden: { control: "text" }, + ariaInvalid: { control: "text" }, + ariaKeyshortcuts: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + ariaLive: { control: "text" }, + ariaOwns: { control: "text" }, + ariaRelevant: { control: "text" }, + ariaRoledescription: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as SearchStoryMeta; +} as Meta; + +export const Search: Story = renderComponent(storyTemplate).bind({}); -export const Search = (args: SearchStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const SearchInForm: Story = renderComponent( + html` +
+ ${storyTemplate} + Submit +
+ ` +).bind({}); diff --git a/packages/web-components/fast-foundation/src/select/stories/select.register.ts b/packages/web-components/fast-foundation/src/select/stories/select.register.ts index d6b7e5fd8b4..866cfe391f3 100644 --- a/packages/web-components/fast-foundation/src/select/stories/select.register.ts +++ b/packages/web-components/fast-foundation/src/select/stories/select.register.ts @@ -91,7 +91,7 @@ const styles = css` box-shadow: 0 0 0 calc(var(--focus-stroke-width) * 1px) var(--focus-stroke-outer); } :host(:not([multiple]):not([size]):focus-visible) - ::slotted(fast-option}[aria-selected="true"]:not([disabled])) { + ::slotted(fast-option[aria-selected="true"]:not([disabled])) { box-shadow: 0 0 0 calc(var(--focus-stroke-width) * 1px) inset var(--focus-stroke-inner); border-color: var(--focus-stroke-outer); @@ -251,8 +251,6 @@ export class Select extends FASTSelect { } `; - console.log(this.selectSize); - this.$fastController.addStyles(this.computedStylesheet); } } diff --git a/packages/web-components/fast-foundation/src/select/stories/select.stories.ts b/packages/web-components/fast-foundation/src/select/stories/select.stories.ts index 9fb9f8bf46d..d1c25f75f96 100644 --- a/packages/web-components/fast-foundation/src/select/stories/select.stories.ts +++ b/packages/web-components/fast-foundation/src/select/stories/select.stories.ts @@ -1,75 +1,85 @@ import { html, repeat } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { storyTemplate as ListboxOptionTemplate } from "../../listbox-option/stories/listbox-option.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTSelect } from "../select.js"; import { SelectPosition } from "../select.options.js"; -type SelectStoryArgs = Args & FASTSelect; -type SelectStoryMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` - ${repeat( - x => x.items, - html` - ${x => x.text} - ` - )} + ${x => x.storyContent} `; export default { title: "Select", args: { - items: [ - { text: "William Hartnell" }, - { text: "Patrick Troughton" }, - { text: "Jon Pertwee" }, - { text: "Tom Baker" }, - { text: "Peter Davidson" }, - { text: "Colin Baker" }, - { text: "Sylvester McCoy" }, - { text: "Paul McGann" }, - { text: "Christopher Eccleston" }, - { text: "David Tenant" }, - { text: "Matt Smith" }, - { text: "Peter Capaldi" }, - { text: "Jodie Whittaker" }, + disabled: false, + multiple: false, + open: false, + storyContent: html>` + ${repeat(x => x.storyItems, ListboxOptionTemplate)} + `, + storyItems: [ + { storyContent: "William Hartnell" }, + { storyContent: "Patrick Troughton" }, + { storyContent: "Jon Pertwee" }, + { storyContent: "Tom Baker" }, + { storyContent: "Peter Davidson" }, + { storyContent: "Colin Baker" }, + { storyContent: "Sylvester McCoy" }, + { storyContent: "Paul McGann" }, + { storyContent: "Christopher Eccleston" }, + { storyContent: "David Tenant" }, + { storyContent: "Matt Smith" }, + { storyContent: "Peter Capaldi" }, + { storyContent: "Jodie Whittaker" }, + { storyContent: "Ncuti Gatwa" }, ], }, argTypes: { - disabled: { control: { type: "boolean" } }, - items: { table: { disable: true } }, - name: { control: { type: "text" } }, - multiple: { control: { type: "boolean" } }, - open: { control: { type: "boolean" } }, - position: { options: Object.values(SelectPosition), control: { type: "select" } }, - size: { control: { type: "number" } }, + disabled: { control: "boolean" }, + name: { control: "text" }, + multiple: { control: "boolean" }, + open: { control: "boolean" }, + position: { + control: "select", + options: [undefined, ...Object.values(SelectPosition)], + }, + size: { control: "number" }, + storyContent: { table: { disable: true } }, + storyItems: { control: "object" }, + value: { control: "text" }, }, -} as SelectStoryMeta; +} as Meta; -export const Select = (args: SelectStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const Select: Story = renderComponent(storyTemplate).bind({}); -export const SelectMultiple = Select.bind({}); +export const SelectMultiple: Story = Select.bind({}); SelectMultiple.args = { multiple: true, }; -export const SelectWithSize = Select.bind({}); +export const SelectWithSize: Story = Select.bind({}); SelectWithSize.args = { size: 5, }; -export const SelectDisabled = Select.bind({}); +export const SelectDisabled: Story = Select.bind({}); SelectDisabled.args = { disabled: true, }; + +export const SelectInForm: Story = renderComponent(html>` +
+ ${storyTemplate} + Submit +
+`).bind({}); diff --git a/packages/web-components/fast-foundation/src/skeleton/stories/skeleton.stories.ts b/packages/web-components/fast-foundation/src/skeleton/stories/skeleton.stories.ts index 42433d55dcc..19dfd6563a1 100644 --- a/packages/web-components/fast-foundation/src/skeleton/stories/skeleton.stories.ts +++ b/packages/web-components/fast-foundation/src/skeleton/stories/skeleton.stories.ts @@ -1,104 +1,95 @@ -import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { css, html, repeat } from "@microsoft/fast-element"; import type { FASTCard } from "../../card/card.js"; +import { storyTemplate as cardStoryTemplate } from "../../card/stories/card.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import { FASTSkeleton, SkeletonShape } from "../skeleton.js"; -type SkeletonStoryArgs = Args & FASTSkeleton; -type SkeletonStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` + > + ${x => x.storyContent} + `; export default { title: "Skeleton", args: { - shape: "rect", shimmer: true, }, argTypes: { - fill: { control: { type: "text" } }, - pattern: { control: { type: "text" } }, - shape: { - options: Object.values(SkeletonShape), - control: { type: "radio" }, - }, - shimmer: { control: { type: "boolean" } }, + fill: { control: "text" }, + pattern: { control: "text" }, + shape: { control: "radio", options: Object.values(SkeletonShape) }, + shimmer: { control: "boolean" }, + storyContent: { table: { disable: true } }, + storyItems: { table: { disable: true } }, }, -} as SkeletonStoryMeta; +} as Meta; -export const Skeleton: SkeletonStoryMeta = (args: SkeletonStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const Skeleton: Story = renderComponent(storyTemplate).bind({}); Skeleton.decorators = [ - (Story, { id }) => { + Story => { const renderedStory = Story() as FASTSkeleton; - renderedStory.id = id; - - const styles = document.createElement("style"); - styles.innerHTML = /* css */ ` - #${id} { + renderedStory.$fastController.addStyles(css` + :host(fast-skeleton) { height: 100px; width: 100px; } - `; - renderedStory.append(styles); + `); return renderedStory; }, ]; -export const SkeletonExample: SkeletonStoryMeta = (args: SkeletonStoryArgs) => { - const componentTemplate = html` - - - - - - - - `; - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; -SkeletonExample.args = { +export const SkeletonCardExample: Story = renderComponent( + cardStoryTemplate +).bind({}); +SkeletonCardExample.args = { shimmer: true, + storyContent: html` + ${repeat(x => x.storyItems, storyTemplate)} + `, + storyItems: [ + { shimmer: true, shape: SkeletonShape.circle }, + { shape: SkeletonShape.rect, shimmer: true }, + { shape: SkeletonShape.rect, shimmer: true }, + { shape: SkeletonShape.rect, shimmer: true }, + { shape: SkeletonShape.rect, shimmer: true }, + ], }; -SkeletonExample.decorators = [ - (Story, { id }) => { +SkeletonCardExample.parameters = { controls: { disable: true } }; +SkeletonCardExample.decorators = [ + Story => { const renderedStory = Story() as FASTCard; - renderedStory.id = id; - - const styles = document.createElement("style"); - styles.innerHTML = /* css */ ` - #${id} { - width: 300px; + renderedStory.$fastController.addStyles(css` + :host(fast-card) { + height: auto; padding: 1rem; + width: 300px; + } + + ::slotted(fast-skeleton[shape="circle"]) { + height: 50px; + width: 50px; } - #${id} fast-skeleton[shape="rect"]:not(:first-of-type) { + + ::slotted(fast-skeleton[shape="rect"]:not(:first-of-type)) { border-radius: 4px; height: 10px; margin: 10px 0; } - #${id} fast-skeleton[shape="rect"]:last-of-type { + + ::slotted(fast-skeleton[shape="rect"]:last-of-type) { height: 30px; margin: 20px 0 0; width: 75px; } - `; + `); - renderedStory.append(styles); return renderedStory; }, ]; 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 fd245d0ffea..1ca53da6395 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 @@ -6,7 +6,7 @@ import { observable, } from "@microsoft/fast-element"; import { Direction, Orientation } from "@microsoft/fast-web-utilities"; -import type { SliderConfiguration } from "../slider/slider.js"; +import type { SliderConfiguration } from "../slider/slider.options.js"; import { convertPixelToPercent } from "../slider/slider-utilities.js"; const defaultConfig: SliderConfiguration = { diff --git a/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.stories.ts b/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.stories.ts index afbbd63ca98..fc3fd7c2c87 100644 --- a/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.stories.ts +++ b/packages/web-components/fast-foundation/src/slider-label/stories/slider-label.stories.ts @@ -1,34 +1,36 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { Orientation } from "@microsoft/fast-web-utilities"; +import { Meta, renderComponent, Story, StoryArgs } from "../../__test__/helpers.js"; import type { FASTSliderLabel } from "../slider-label.js"; -type SliderLabelStoryArgs = Args & FASTSliderLabel; -type SliderLabelStoryMeta = Meta; - -const componentTemplate = html` +export const storyTemplate = html>` - ${x => x.label} + ${x => x.storyContent} `; export default { - title: "Slider/Slider Label", + title: "Slider Label", + excludeStories: ["storyTemplate"], + args: { + disabled: false, + hideMark: false, + storyContent: "Slider label", + }, argTypes: { - hideMark: { control: { type: "boolean" } }, - content: { control: { type: "text" } }, - position: { control: { type: "number" } }, + disabled: { control: "boolean" }, + hideMark: { control: "boolean" }, + position: { control: "number" }, + sliderOrientation: { control: "radio", options: Object.values(Orientation) }, + storyContent: { table: { disable: true } }, }, -} as SliderLabelStoryMeta; +} as Meta; -export const SliderLabel = (args: SliderLabelStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; -SliderLabel.args = { - label: "Slider label", -}; +export const SliderLabel: Story = renderComponent(storyTemplate).bind( + {} +); diff --git a/packages/web-components/fast-foundation/src/slider/README.md b/packages/web-components/fast-foundation/src/slider/README.md index 60b8d8ff279..b98da7917db 100644 --- a/packages/web-components/fast-foundation/src/slider/README.md +++ b/packages/web-components/fast-foundation/src/slider/README.md @@ -145,6 +145,16 @@ export const mySliderLabel = SliderLabel.compose({ +### Variables + +| Name | Description | Type | +| ------------ | ----------------------------------------------------------------------- | ---------------------------------- | +| `SliderMode` | The selection modes of a @microsoft/fast-foundation#(FASTSlider:class). | `{ singleValue: "single-value", }` | + +
+ + + ### class: `FASTSlider` #### Superclass @@ -214,14 +224,6 @@ export const mySliderLabel = SliderLabel.compose({
-### Variables - -| Name | Description | Type | -| ------------ | ----------------------------------------------------------------------- | ---------------------------------- | -| `SliderMode` | The selection modes of a @microsoft/fast-foundation#(FASTSlider:class). | `{ singleValue: "single-value", }` | - -
- ### class: `FASTSliderLabel` diff --git a/packages/web-components/fast-foundation/src/slider/index.ts b/packages/web-components/fast-foundation/src/slider/index.ts index 0da6cb8bc4d..b074bc06669 100644 --- a/packages/web-components/fast-foundation/src/slider/index.ts +++ b/packages/web-components/fast-foundation/src/slider/index.ts @@ -1,2 +1,3 @@ -export * from "./slider.template.js"; export * from "./slider.js"; +export * from "./slider.options.js"; +export * from "./slider.template.js"; diff --git a/packages/web-components/fast-foundation/src/slider/slider.options.ts b/packages/web-components/fast-foundation/src/slider/slider.options.ts new file mode 100644 index 00000000000..83b2356df1d --- /dev/null +++ b/packages/web-components/fast-foundation/src/slider/slider.options.ts @@ -0,0 +1,36 @@ +import type { SyntheticViewTemplate } from "@microsoft/fast-element"; +import type { Direction, Orientation } from "@microsoft/fast-web-utilities"; + +/** + * The selection modes of a {@link @microsoft/fast-foundation#(FASTSlider:class)}. + * @public + */ +export const SliderMode = { + singleValue: "single-value", +} as const; + +/** + * The types for the selection mode of the slider + * @public + */ +export type SliderMode = typeof SliderMode[keyof typeof SliderMode]; + +/** + * The configuration structure of {@link @microsoft/fast-foundation#(FASTSlider:class)}. + * @public + */ +export interface SliderConfiguration { + max: number; + min: number; + orientation?: Orientation; + direction?: Direction; + disabled?: boolean; +} + +/** + * Slider configuration options + * @public + */ +export type SliderOptions = { + thumb?: string | SyntheticViewTemplate; +}; 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 fb09dd2ea0e..a53c2ccea49 100644 --- a/packages/web-components/fast-foundation/src/slider/slider.template.ts +++ b/packages/web-components/fast-foundation/src/slider/slider.template.ts @@ -1,6 +1,7 @@ import { ElementViewTemplate, html, ref } from "@microsoft/fast-element"; import { Orientation } from "@microsoft/fast-web-utilities"; -import type { FASTSlider, SliderOptions } from "./slider.js"; +import type { FASTSlider } from "./slider.js"; +import type { SliderOptions } from "./slider.options.js"; /** * The template for the {@link @microsoft/fast-foundation#(FASTSlider:class)} component. diff --git a/packages/web-components/fast-foundation/src/slider/slider.ts b/packages/web-components/fast-foundation/src/slider/slider.ts index 196be237263..c755a58059a 100644 --- a/packages/web-components/fast-foundation/src/slider/slider.ts +++ b/packages/web-components/fast-foundation/src/slider/slider.ts @@ -1,9 +1,4 @@ -import { - attr, - nullableNumberConverter, - observable, - SyntheticViewTemplate, -} from "@microsoft/fast-element"; +import { attr, nullableNumberConverter, observable } from "@microsoft/fast-element"; import { Direction, keyArrowDown, @@ -17,40 +12,7 @@ import { import { getDirection } from "../utilities/direction.js"; import { convertPixelToPercent } from "./slider-utilities.js"; import { FormAssociatedSlider } from "./slider.form-associated.js"; - -/** - * The selection modes of a {@link @microsoft/fast-foundation#(FASTSlider:class)}. - * @public - */ -export const SliderMode = { - singleValue: "single-value", -} as const; - -/** - * The types for the selection mode of the slider - * @public - */ -export type SliderMode = typeof SliderMode[keyof typeof SliderMode]; - -/** - * The configuration structure of {@link @microsoft/fast-foundation#(FASTSlider:class)}. - * @public - */ -export interface SliderConfiguration { - max: number; - min: number; - orientation?: Orientation; - direction?: Direction; - disabled?: boolean; -} - -/** - * Slider configuration options - * @public - */ -export type SliderOptions = { - thumb?: string | SyntheticViewTemplate; -}; +import { SliderConfiguration, SliderMode } from "./slider.options.js"; /** * A Slider Custom HTML Element. 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 42c8429339a..764f946370a 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 @@ -15,7 +15,6 @@ const styles = css` --track-width: var(--design-unit); --fast-slider-height: calc(var(--thumb-size) * 10); align-items: center; - width: 100%; margin: calc(var(--design-unit) * 1px) 0; user-select: none; box-sizing: border-box; @@ -23,12 +22,14 @@ const styles = css` outline: none; cursor: pointer; } + :host([orientation="horizontal"]) .positioning-region { position: relative; margin: 0 8px; display: grid; grid-template-rows: calc(var(--thumb-size) * 1px) 1fr; } + :host([orientation="vertical"]) .positioning-region { position: relative; margin: 0 8px; @@ -82,7 +83,9 @@ const styles = css` 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); @@ -104,7 +107,7 @@ const styles = css` :host([orientation="vertical"]) { height: calc(var(--fast-slider-height) * 1px); min-height: calc(var(--thumb-size) * 1px); - min-width: calc(var(--design-unit) * 20px); + touch-action: pan-x; } :host([orientation="vertical"]) .track-start { height: auto; 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 bf91db47418..be71eb6f0ed 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 @@ -1,64 +1,86 @@ -import { html } from "@microsoft/fast-element"; +import { css, html, repeat } from "@microsoft/fast-element"; import { Orientation } from "@microsoft/fast-web-utilities"; -import type { Args, Meta } from "@storybook/html"; +import { storyTemplate as sliderLabelStoryTemplate } from "../../slider-label/stories/slider-label.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTSlider } from "../slider.js"; +import { SliderMode } from "../slider.options.js"; -type SliderStoryArgs = Args & FASTSlider; -type SliderStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` - ${x => x.content} + ${x => x.storyContent} `; export default { title: "Slider", + args: { + disabled: false, + readOnly: false, + }, argTypes: { - content: { table: { disable: true } }, - orientation: { options: Object.values(Orientation), control: { type: "radio" } }, - min: { control: { type: "number" } }, - max: { control: { type: "number" } }, - step: { control: { type: "number" } }, - value: { control: { type: "text" } }, + disabled: { control: "boolean" }, + max: { control: "number" }, + min: { control: "number" }, + mode: { control: "radio", options: Object.values(SliderMode) }, + orientation: { control: "radio", options: Object.values(Orientation) }, + readOnly: { control: "boolean" }, + step: { control: "number" }, + storyContent: { table: { disable: true } }, + storyItems: { control: "object" }, + value: { control: "number" }, }, -} as SliderStoryMeta; +} as Meta; -export const Slider = (args: SliderStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const Slider: Story = renderComponent(storyTemplate).bind({}); -export const SliderWithLabels = Slider.bind({}); +export const SliderWithLabels: Story = Slider.bind({}); SliderWithLabels.args = { min: 0, max: 100, step: 10, - content: html` - - 0℃ - - - 10℃ - - - 90℃ - - - 100℃ - + storyContent: html` + ${repeat(x => x.storyItems, sliderLabelStoryTemplate)} `, + storyItems: [ + { position: 0, storyContent: "0℃" }, + { position: 10, storyContent: "10℃" }, + { position: 90, storyContent: "90℃" }, + { position: 100, storyContent: "100℃" }, + ], }; +SliderWithLabels.decorators = [ + Story => { + const renderedStory = Story() as FASTSlider; + renderedStory.$fastController.addStyles(css` + :host([orientation="horizontal"]) { + padding: 0 1em; + } + `); -export const SliderVertical = Slider.bind({}); -SliderVertical.storyName = "Vertical Slider"; -SliderVertical.args = { + return renderedStory; + }, +]; + +export const SliderVerticalOrientation: Story = Slider.bind({}); +SliderVerticalOrientation.args = { orientation: Orientation.vertical, }; + +export const SliderInForm: Story = renderComponent( + html>` +
+ ${storyTemplate} + Submit +
+ ` +).bind({}); diff --git a/packages/web-components/fast-foundation/src/switch/stories/switch.stories.ts b/packages/web-components/fast-foundation/src/switch/stories/switch.stories.ts index e9065fc6905..b9bbbf8499c 100644 --- a/packages/web-components/fast-foundation/src/switch/stories/switch.stories.ts +++ b/packages/web-components/fast-foundation/src/switch/stories/switch.stories.ts @@ -1,87 +1,64 @@ -import { html, repeat } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { html } from "@microsoft/fast-element"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTSwitch } from "../switch.js"; -type SwitchStoryArgs = Args & FASTSwitch; -type SwitchStoryMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` - ${x => x.label} - Dark - Light + ${x => x.storyContent} `; export default { title: "Switch", args: { - label: "Theme", - checked: true, - readOnly: false, + checked: false, disabled: false, + readOnly: false, required: false, }, argTypes: { - checked: { control: { type: "boolean" } }, - readOnly: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, - required: { control: { type: "boolean" } }, + checked: { control: "boolean" }, + disabled: { control: "boolean" }, + readOnly: { control: "boolean" }, + required: { control: "boolean" }, + storyContent: { table: { disable: true } }, + value: { control: "text" }, }, -} as SwitchStoryMeta; - -export const Switch = (args: SwitchStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +} as Meta; -export const DisabledSwitch: SwitchStoryMeta = (args: SwitchStoryArgs) => { - const disabledStoryTemplate = html` - ${repeat(x => x.items, storyTemplate)} - `; +export const Switch = renderComponent(storyTemplate).bind({}); - const storyFragment = new DocumentFragment(); - disabledStoryTemplate.render(args, storyFragment); - return storyFragment; +export const SwitchWithSlottedMessages: Story = renderComponent( + storyTemplate +).bind({}); +SwitchWithSlottedMessages.args = { + storyContent: html` + Checked + Unchecked + `, }; -DisabledSwitch.args = { - items: [ - { label: "Disabled (unchecked)", checked: false, disabled: true }, - { label: "Disabled (checked)", checked: true, disabled: true }, - ], -}; -DisabledSwitch.decorators = [ - Story => { - const renderedStory = Story() as DocumentFragment; - const styles = document.createElement("style"); - styles.innerHTML = /* css */ ` - fast-switch { - display: flex; - } - `; - renderedStory.append(styles); - return renderedStory; - }, -]; -export const Required: SwitchStoryMeta = (args: SwitchStoryArgs) => { - const requiredStoryTemplate = html` +export const SwitchInForm: Story = renderComponent( + html>`
${storyTemplate} +
Submit
- `; - - const storyFragment = new DocumentFragment(); - requiredStoryTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; -Required.args = { + ` +).bind({}); +SwitchInForm.args = { required: true, + storyContent: html` + Sign up for our newsletter? +
Yes, I would like to receive your newsletter
+
do not sign me up
+ `, }; diff --git a/packages/web-components/fast-foundation/src/tab-panel/stories/tab-panel.stories.ts b/packages/web-components/fast-foundation/src/tab-panel/stories/tab-panel.stories.ts index 1c0772427d6..d830d5677d8 100644 --- a/packages/web-components/fast-foundation/src/tab-panel/stories/tab-panel.stories.ts +++ b/packages/web-components/fast-foundation/src/tab-panel/stories/tab-panel.stories.ts @@ -1,29 +1,23 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTTabPanel } from "../tab-panel.js"; -type TabPanelStoryArgs = Args & FASTTabPanel; -type TabPanelStoryMeta = Meta; - -const componentTemplate = html` +export const storyTemplate = html>` - ${x => x.content} + ${x => x.storyContent} `; export default { title: "Tabs/Tab Panel", + excludeStories: ["storyTemplate"], + args: { + storyContent: "Tab panel", + }, argTypes: { - disabled: { control: { type: "boolean" } }, + storyContent: { table: { disable: true } }, }, -} as TabPanelStoryMeta; - -export const TabPanel = (args: TabPanelStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +} as Meta; -TabPanel.args = { - content: "Tab Panel", -}; +export const TabPanel: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/fast-foundation/src/tab/stories/tab.stories.ts b/packages/web-components/fast-foundation/src/tab/stories/tab.stories.ts index 9d70119c286..95bf2018057 100644 --- a/packages/web-components/fast-foundation/src/tab/stories/tab.stories.ts +++ b/packages/web-components/fast-foundation/src/tab/stories/tab.stories.ts @@ -1,27 +1,23 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTTab } from "../tab.js"; -type TabStoryArgs = Args & FASTTab; -type TabStoryMeta = Meta; - -const componentTemplate = html` - ${x => x.content} +export const storyTemplate = html>` + ${x => x.storyContent} `; export default { title: "Tabs/Tab", + excludeStories: ["storyTemplate"], + args: { + disabled: false, + storyContent: "Tab", + }, argTypes: { - disabled: { control: { type: "boolean" } }, + disabled: { control: "boolean" }, + storyContent: { table: { disable: true } }, }, -} as TabStoryMeta; - -export const Tab = (args: TabStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +} as Meta; -Tab.args = { - content: "Tab", -}; +export const Tab: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/fast-foundation/src/tabs/stories/tabs.register.ts b/packages/web-components/fast-foundation/src/tabs/stories/tabs.register.ts index bce6b0c0504..d3eb1f5f4d1 100644 --- a/packages/web-components/fast-foundation/src/tabs/stories/tabs.register.ts +++ b/packages/web-components/fast-foundation/src/tabs/stories/tabs.register.ts @@ -30,7 +30,7 @@ const styles = css` .end { align-self: center; } - .activeIndicator { + .active-indicator { grid-row: 2; grid-column: 1; width: 100%; diff --git a/packages/web-components/fast-foundation/src/tabs/stories/tabs.stories.ts b/packages/web-components/fast-foundation/src/tabs/stories/tabs.stories.ts index 7470c49c01a..d1b65ba8f33 100644 --- a/packages/web-components/fast-foundation/src/tabs/stories/tabs.stories.ts +++ b/packages/web-components/fast-foundation/src/tabs/stories/tabs.stories.ts @@ -1,89 +1,71 @@ import { html, repeat } from "@microsoft/fast-element"; import { Orientation } from "@microsoft/fast-web-utilities"; -import type { Args, Meta } from "@storybook/html"; +import { storyTemplate as tabPanelStoryTemplate } from "../../tab-panel/stories/tab-panel.stories.js"; +import { storyTemplate as tabStoryTemplate } from "../../tab/stories/tab.stories.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTTabs } from "../tabs.js"; -type TabsStoryArgs = Args & FASTTabs; -type TabsStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` - ${repeat( - x => x.items, - html` - ${x => x.tab} - - ${x => x.panel} - - ` - )} + ${x => x.storyContent} `; export default { title: "Tabs", + args: { + hideActiveIndicator: false, + storyContent: html>` + ${repeat(x => x.storyItems.tabs, tabStoryTemplate)} + ${repeat(x => x.storyItems.tabPanels, tabPanelStoryTemplate)} + `, + }, argTypes: { - disabled: { control: { type: "boolean" } }, - orientation: { options: Object.values(Orientation), control: { type: "radio" } }, + activeid: { control: "text" }, + hideActiveIndicator: { control: "boolean" }, + orientation: { control: "radio", options: Object.values(Orientation) }, + storyContent: { table: { disable: true } }, + storyItems: { table: { disable: true } }, }, -} as TabsStoryMeta; - -export const Tabs = (args: TabsStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +} as Meta; +export const Tabs: Story = renderComponent(storyTemplate).bind({}); Tabs.args = { - items: [ - { - tab: "Tab one", - panel: "Tab one content", - }, - { - tab: "Tab two", - panel: "Tab two content", - }, - { - tab: "Tab three", - panel: "Tab three content", - }, - ], -}; - -export const DisabledTabs = (args: TabsStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; + storyItems: { + tabs: [ + { storyContent: "Tab one" }, + { storyContent: "Tab two" }, + { storyContent: "Tab three" }, + ], + tabPanels: [ + { storyContent: "Tab panel one" }, + { storyContent: "Tab panel two" }, + { storyContent: "Tab panel three" }, + ], + }, }; +export const DisabledTabs: Story = Tabs.bind({}); DisabledTabs.args = { - items: [ - { - tab: "Tab one", - panel: "Tab one content", - disabled: true, - }, - { - tab: "Tab two", - panel: "Tab two content", - }, - { - tab: "Tab three", - panel: "Tab three content", - }, - { - tab: "Tab four", - panel: "Tab four content", - }, - { - tab: "Tab five", - panel: "Tab five content", - disabled: true, - }, - ], + storyItems: { + tabs: [ + { storyContent: "Tab one", disabled: true }, + { storyContent: "Tab two" }, + { storyContent: "Tab three" }, + { storyContent: "Tab four" }, + { storyContent: "Tab five", disabled: true }, + ], + tabPanels: [ + { storyContent: "Tab panel one" }, + { storyContent: "Tab panel two" }, + { storyContent: "Tab panel three" }, + { storyContent: "Tab panel four" }, + { storyContent: "Tab panel five" }, + ], + }, }; diff --git a/packages/web-components/fast-foundation/src/text-area/stories/text-area.stories.ts b/packages/web-components/fast-foundation/src/text-area/stories/text-area.stories.ts index 4b7a212470b..04a5366ef52 100644 --- a/packages/web-components/fast-foundation/src/text-area/stories/text-area.stories.ts +++ b/packages/web-components/fast-foundation/src/text-area/stories/text-area.stories.ts @@ -1,16 +1,15 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTTextArea } from "../text-area.js"; import { TextAreaResize } from "../text-area.options.js"; -type TextAreaStoryArgs = Args & FASTTextArea; -type TextAreaStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` ` rows="${x => x.rows}" size="${x => x.size}" value="${x => x.value}" + :ariaAtomic="${x => x.ariaAtomic}" + :ariaBusy="${x => x.ariaBusy}" + :ariaControls="${x => x.ariaControls}" + :ariaCurrent="${x => x.ariaCurrent}" + :ariaDescribedby="${x => x.ariaDescribedby}" + :ariaDetails="${x => x.ariaDetails}" + :ariaDisabled="${x => x.ariaDisabled}" + :ariaErrormessage="${x => x.ariaErrormessage}" + :ariaFlowto="${x => x.ariaFlowto}" + :ariaHaspopup="${x => x.ariaHaspopup}" + :ariaHidden="${x => x.ariaHidden}" + :ariaInvalid="${x => x.ariaInvalid}" + :ariaKeyshortcuts="${x => x.ariaKeyshortcuts}" + :ariaLabel="${x => x.ariaLabel}" + :ariaLabelledby="${x => x.ariaLabelledby}" + :ariaLive="${x => x.ariaLive}" + :ariaOwns="${x => x.ariaOwns}" + :ariaRelevant="${x => x.ariaRelevant}" + :ariaRoledescription="${x => x.ariaRoledescription}" > - ${x => x.label} + ${x => x.storyContent} `; export default { title: "Text Area", args: { - label: "Text Area", + autofocus: false, + disabled: false, + readOnly: false, + required: false, + spellcheck: false, + storyContent: "Text Area", }, argTypes: { - autofocus: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, - label: { control: { type: "text" } }, - list: { control: { type: "text" } }, - maxlength: { control: { type: "number" } }, - minlength: { control: { type: "number" } }, - name: { control: { type: "text" } }, - placeholder: { control: { type: "text" } }, - form: { control: { type: "text" } }, - readOnly: { control: { type: "boolean" } }, - cols: { control: { type: "number" } }, - rows: { control: { type: "number" } }, - resize: { options: Object.values(TextAreaResize), control: { type: "select" } }, - spellcheck: { control: { type: "boolean" } }, - value: { control: { type: "text" } }, + autofocus: { control: "boolean" }, + disabled: { control: "boolean" }, + list: { control: "text" }, + maxlength: { control: "number" }, + minlength: { control: "number" }, + name: { control: "text" }, + placeholder: { control: "text" }, + form: { control: "text" }, + readOnly: { control: "boolean" }, + cols: { control: "number" }, + rows: { control: "number" }, + required: { control: "boolean" }, + resize: { options: Object.values(TextAreaResize), control: "select" }, + spellcheck: { control: "boolean" }, + value: { control: "text" }, + ariaAtomic: { control: "text" }, + ariaBusy: { control: "text" }, + ariaControls: { control: "text" }, + ariaCurrent: { control: "text" }, + ariaDescribedby: { control: "text" }, + ariaDetails: { control: "text" }, + ariaDisabled: { control: "text" }, + ariaErrormessage: { control: "text" }, + ariaFlowto: { control: "text" }, + ariaHaspopup: { control: "text" }, + ariaHidden: { control: "text" }, + ariaInvalid: { control: "text" }, + ariaKeyshortcuts: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + ariaLive: { control: "text" }, + ariaOwns: { control: "text" }, + ariaRelevant: { control: "text" }, + ariaRoledescription: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as TextAreaStoryMeta; +} as Meta; + +export const TextArea: Story = renderComponent(storyTemplate).bind({}); -export const TextArea = (args: TextAreaStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const TextAreaInForm: Story = renderComponent(html` +
+ ${storyTemplate} +
+ Submit +
+`).bind({}); diff --git a/packages/web-components/fast-foundation/src/text-field/stories/text-field.stories.ts b/packages/web-components/fast-foundation/src/text-field/stories/text-field.stories.ts index b469cab072e..052b986b11d 100644 --- a/packages/web-components/fast-foundation/src/text-field/stories/text-field.stories.ts +++ b/packages/web-components/fast-foundation/src/text-field/stories/text-field.stories.ts @@ -1,15 +1,14 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import { FASTTextField, TextFieldType } from "../text-field.js"; -type TextFieldStoryArgs = Args & FASTTextField; -type TextFieldStoryMeta = Meta; - -const componentTemplate = html` +const storyTemplate = html>` ` placeholder="${x => x.placeholder}" resize="${x => x.resize}" size="${x => x.size}" + tabindex="${x => (x.disabled ? null : "0")}" type="${x => x.type}" value="${x => x.value}" + :ariaAtomic="${x => x.ariaAtomic}" + :ariaBusy="${x => x.ariaBusy}" + :ariaControls="${x => x.ariaControls}" + :ariaCurrent="${x => x.ariaCurrent}" + :ariaDescribedby="${x => x.ariaDescribedby}" + :ariaDetails="${x => x.ariaDetails}" + :ariaDisabled="${x => x.ariaDisabled}" + :ariaErrormessage="${x => x.ariaErrormessage}" + :ariaFlowto="${x => x.ariaFlowto}" + :ariaHaspopup="${x => x.ariaHaspopup}" + :ariaHidden="${x => x.ariaHidden}" + :ariaInvalid="${x => x.ariaInvalid}" + :ariaKeyshortcuts="${x => x.ariaKeyshortcuts}" + :ariaLabel="${x => x.ariaLabel}" + :ariaLabelledby="${x => x.ariaLabelledby}" + :ariaLive="${x => x.ariaLive}" + :ariaOwns="${x => x.ariaOwns}" + :ariaRelevant="${x => x.ariaRelevant}" + :ariaRoledescription="${x => x.ariaRoledescription}" > - ${x => x.label} + ${x => x.storyContent} `; export default { title: "Text Field", args: { - label: "Text Field", + autofocus: false, + disabled: false, + readOnly: false, + required: false, + spellcheck: false, + storyContent: "Text Field", }, argTypes: { - autofocus: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, - label: { control: { type: "text" } }, - list: { control: { type: "text" } }, - maxlength: { control: { type: "number" } }, - minlength: { control: { type: "number" } }, - name: { control: { type: "text" } }, - pattern: { control: { type: "text" } }, - placeholder: { control: { type: "text" } }, - readOnly: { control: { type: "boolean" } }, - size: { control: { type: "number" } }, - spellcheck: { control: { type: "boolean" } }, - type: { options: Object.values(TextFieldType), control: { type: "text" } }, - value: { control: { type: "text" } }, + autofocus: { control: "boolean" }, + disabled: { control: "boolean" }, + list: { control: "text" }, + maxlength: { control: "number" }, + minlength: { control: "number" }, + name: { control: "text" }, + pattern: { control: "text" }, + placeholder: { control: "text" }, + readOnly: { control: "boolean" }, + required: { control: "boolean" }, + size: { control: "number" }, + spellcheck: { control: "boolean" }, + type: { control: "select", options: Object.values(TextFieldType) }, + value: { control: "text" }, + ariaAtomic: { control: "text" }, + ariaBusy: { control: "text" }, + ariaControls: { control: "text" }, + ariaCurrent: { control: "text" }, + ariaDescribedby: { control: "text" }, + ariaDetails: { control: "text" }, + ariaDisabled: { control: "text" }, + ariaErrormessage: { control: "text" }, + ariaFlowto: { control: "text" }, + ariaHaspopup: { control: "text" }, + ariaHidden: { control: "text" }, + ariaInvalid: { control: "text" }, + ariaKeyshortcuts: { control: "text" }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + ariaLive: { control: "text" }, + ariaOwns: { control: "text" }, + ariaRelevant: { control: "text" }, + ariaRoledescription: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as TextFieldStoryMeta; +} as Meta; + +export const TextField: Story = renderComponent(storyTemplate).bind({}); -export const TextField = (args: TextFieldStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const TextFieldInForm: Story = renderComponent( + html>` +
+ ${storyTemplate} + Submit +
+ ` +).bind({}); diff --git a/packages/web-components/fast-foundation/src/toolbar/stories/toolbar.stories.ts b/packages/web-components/fast-foundation/src/toolbar/stories/toolbar.stories.ts index d2a9faef71c..ca443510edc 100644 --- a/packages/web-components/fast-foundation/src/toolbar/stories/toolbar.stories.ts +++ b/packages/web-components/fast-foundation/src/toolbar/stories/toolbar.stories.ts @@ -1,37 +1,32 @@ import { html } from "@microsoft/fast-element"; import { Orientation } from "@microsoft/fast-web-utilities"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTToolbar } from "../toolbar.js"; -type ToolbarStoryArgs = Args & FASTToolbar; -type ToolbarStoryMeta = Meta; - -const componentTemplate = html` - - ${x => x.content} +const storyTemplate = html>` + + ${x => x.storyContent} `; export default { title: "Toolbar", argTypes: { - content: { control: { type: "string" } }, - orientation: { options: Object.values(Orientation), control: { type: "radio" } }, + orientation: { control: "radio", options: Object.values(Orientation) }, + ariaLabel: { control: "text" }, + ariaLabelledby: { control: "text" }, + storyContent: { table: { disable: true } }, }, -} as ToolbarStoryMeta; - -export const Toolbar = (args: ToolbarStoryArgs) => { - const storyFragment = new DocumentFragment(); - componentTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; - -Toolbar.argTypes = { - content: { table: { disable: true } }, -}; +} as Meta; +export const Toolbar: Story = renderComponent(storyTemplate).bind({}); Toolbar.args = { - content: html` + storyContent: html` @@ -55,3 +50,16 @@ Toolbar.args = { `, }; + +export const ToolbarButtonFocusTest: Story = Toolbar.bind({}); +ToolbarButtonFocusTest.args = { + storyContent: html` + + + + + + + + `, +}; diff --git a/packages/web-components/fast-foundation/src/tooltip/README.md b/packages/web-components/fast-foundation/src/tooltip/README.md index a9325a1cb9b..0651e8b2112 100644 --- a/packages/web-components/fast-foundation/src/tooltip/README.md +++ b/packages/web-components/fast-foundation/src/tooltip/README.md @@ -50,9 +50,9 @@ export const myTooltip = Tooltip.compose({ ### Variables -| Name | Description | Type | -| ----------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `TooltipPosition` | Enumerates possible tooltip positions | `{ top: "top", right: "right", bottom: "bottom", left: "left", start: "start", end: "end", topLeft: "top-left", topRight: "top-right", bottomLeft: "bottom-left", bottomRight: "bottom-right", topStart: "top-start", topEnd: "top-end", bottomStart: "bottom-start", bottomEnd: "bottom-end", }` | +| Name | Description | Type | +| ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `TooltipPosition` | Enumerates possible tooltip positions | `{ top: "top", right: "right", bottom: "bottom", left: "left", center: "center", start: "start", end: "end", topLeft: "top-left", topCenter: "top-center", topRight: "top-right", bottomLeft: "bottom-left", bottomCenter: "bottom-center", bottomRight: "bottom-right", topStart: "top-start", topEnd: "top-end", bottomStart: "bottom-start", bottomEnd: "bottom-end", }` |
diff --git a/packages/web-components/fast-foundation/src/tooltip/stories/tooltip.stories.ts b/packages/web-components/fast-foundation/src/tooltip/stories/tooltip.stories.ts index 15ccd6850d3..9682951a56b 100644 --- a/packages/web-components/fast-foundation/src/tooltip/stories/tooltip.stories.ts +++ b/packages/web-components/fast-foundation/src/tooltip/stories/tooltip.stories.ts @@ -1,56 +1,48 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; import { AutoUpdateMode } from "../../index.js"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import { FASTTooltip, TooltipPosition } from "../tooltip.js"; -type TooltipStoryArgs = Args & FASTTooltip; -type TooltipStoryMeta = Meta; - -const storyTemplate = html` -
- - ${x => x.content} - - - anchor - -
+const storyTemplate = html>` + + ${x => x.storyContent} + `; export default { title: "Tooltip", args: { - content: "Here's a tooltip", + storyContent: "Tooltip", }, argTypes: { - visible: { control: { type: "boolean" } }, - delay: { control: { type: "number" } }, - position: { - options: Object.values(TooltipPosition), - control: { type: "select" }, - }, - autoUpdateMode: { - options: Object.values(AutoUpdateMode), - control: { type: "select" }, - }, - verticalViewportLock: { control: { type: "boolean" } }, - horizontalViewportLock: { control: { type: "boolean" } }, + autoUpdateMode: { control: "select", options: Object.values(AutoUpdateMode) }, + delay: { control: "number" }, + horizontalViewportLock: { control: "boolean" }, + position: { control: "select", options: Object.values(TooltipPosition) }, + verticalViewportLock: { control: "boolean" }, + visible: { control: "boolean" }, + }, + parameters: { + docs: { inlineStories: false }, }, -} as TooltipStoryMeta; +} as Meta; -export const Tooltip = (args: TooltipStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; -}; +export const Tooltip: Story = renderComponent( + html>` +
+ ${storyTemplate} + + Hover or focus me + +
+ ` +).bind({}); diff --git a/packages/web-components/fast-foundation/src/tooltip/tooltip.options.ts b/packages/web-components/fast-foundation/src/tooltip/tooltip.options.ts index a8bdff606e3..0e12c821086 100644 --- a/packages/web-components/fast-foundation/src/tooltip/tooltip.options.ts +++ b/packages/web-components/fast-foundation/src/tooltip/tooltip.options.ts @@ -24,6 +24,11 @@ export const TooltipPosition = { */ left: "left", + /** + * The tooltip is positioned in the center of the element + */ + center: "center", + /** * The tooltip is positioned before the element */ @@ -39,6 +44,11 @@ export const TooltipPosition = { */ topLeft: "top-left", + /** + * The tooltip is positioned above the element and horizontally centered + */ + topCenter: "top-center", + /** * The tooltip is positioned above the element and to the right */ @@ -49,6 +59,11 @@ export const TooltipPosition = { */ bottomLeft: "bottom-left", + /** + * The tooltip is positioned below the element and horizontally centered + */ + bottomCenter: "bottom-center", + /** * The tooltip is positioned below the element and to the right */ diff --git a/packages/web-components/fast-foundation/src/tooltip/tooltip.ts b/packages/web-components/fast-foundation/src/tooltip/tooltip.ts index ddbe7a704d8..13cb0af4284 100644 --- a/packages/web-components/fast-foundation/src/tooltip/tooltip.ts +++ b/packages/web-components/fast-foundation/src/tooltip/tooltip.ts @@ -6,12 +6,12 @@ import { Updates, } from "@microsoft/fast-element"; import { Direction, keyEscape } from "@microsoft/fast-web-utilities"; +import type { FASTAnchoredRegion } from "../anchored-region/anchored-region.js"; import type { AutoUpdateMode, AxisPositioningMode, AxisScalingMode, - FASTAnchoredRegion, -} from "../anchored-region/anchored-region.js"; +} from "../anchored-region/anchored-region.options.js"; import { getDirection } from "../utilities/direction.js"; import { TooltipPosition } from "./tooltip.options.js"; @@ -467,11 +467,26 @@ export class FASTTooltip extends FASTElement { this.horizontalDefaultPosition = this.position; break; + case TooltipPosition.center: + this.verticalDefaultPosition = "center"; + this.horizontalDefaultPosition = "center"; + break; + case TooltipPosition.topLeft: this.verticalDefaultPosition = "top"; this.horizontalDefaultPosition = "left"; break; + case TooltipPosition.topCenter: + this.verticalDefaultPosition = "top"; + this.horizontalDefaultPosition = "center"; + break; + + case TooltipPosition.bottomCenter: + this.verticalDefaultPosition = "bottom"; + this.horizontalDefaultPosition = "center"; + break; + case TooltipPosition.topRight: this.verticalDefaultPosition = "top"; this.horizontalDefaultPosition = "right"; diff --git a/packages/web-components/fast-foundation/src/tree-item/stories/tree-item.stories.ts b/packages/web-components/fast-foundation/src/tree-item/stories/tree-item.stories.ts index 52d18daf65c..3b0667ab4c7 100644 --- a/packages/web-components/fast-foundation/src/tree-item/stories/tree-item.stories.ts +++ b/packages/web-components/fast-foundation/src/tree-item/stories/tree-item.stories.ts @@ -1,37 +1,48 @@ -import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import { html, repeat } from "@microsoft/fast-element"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTTreeItem } from "../tree-item.js"; -type TreeItemStoryArgs = Args & FASTTreeItem; -type TreeItemStoryMeta = Meta; - -const storyTemplate = html` +const storyTemplate = html>` - ${x => x.content} + ${x => x.storyContent} `; export default { - title: "Tree view/Tree Item", + title: "Tree View/Tree Item", args: { - content: "Tree Item", - expanded: false, disabled: false, + expanded: false, + nested: false, selected: false, }, argTypes: { - expanded: { control: { type: "boolean" } }, - selected: { control: { type: "boolean" } }, - disabled: { control: { type: "boolean" } }, + expanded: { control: "boolean" }, + nested: { control: "boolean" }, + selected: { control: "boolean" }, + storyContent: { table: { disable: true } }, + storyItems: { table: { disable: true } }, }, -} as TreeItemStoryMeta; +} as Meta; + +export const TreeItem: Story = renderComponent(storyTemplate).bind({}); +TreeItem.args = { + storyContent: "Tree Item", +}; -export const TreeItem = (args: TreeItemStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; +export const TreeItemWithNestedItems: Story = TreeItem.bind({}); +TreeItemWithNestedItems.args = { + storyContent: html` + Tree Item ${repeat(x => x.storyItems, storyTemplate)} + `, + storyItems: [ + { storyContent: "Nested Tree Item" }, + { storyContent: "Nested Tree Item" }, + ], }; diff --git a/packages/web-components/fast-foundation/src/tree-view/stories/tree-view.stories.ts b/packages/web-components/fast-foundation/src/tree-view/stories/tree-view.stories.ts index ff97bf0b7ca..046b0459500 100644 --- a/packages/web-components/fast-foundation/src/tree-view/stories/tree-view.stories.ts +++ b/packages/web-components/fast-foundation/src/tree-view/stories/tree-view.stories.ts @@ -1,12 +1,28 @@ import { html } from "@microsoft/fast-element"; -import type { Args, Meta } from "@storybook/html"; +import type { Meta, Story, StoryArgs } from "../../__test__/helpers.js"; +import { renderComponent } from "../../__test__/helpers.js"; import type { FASTTreeView } from "../tree-view.js"; -type TreeViewStoryArgs = Args & FASTTreeView; -type TreeViewStoryMeta = Meta; +const storyTemplate = html>` + + ${x => x.storyContent} + +`; + +export default { + title: "Tree view", + args: { + renderCollapsedNodes: true, + }, + argTypes: { + renderCollapsedNodes: { control: "boolean" }, + storyContent: { table: { disable: true } }, + }, +} as Meta; -const storyTemplate = html` - +export const TreeView: Story = renderComponent(storyTemplate).bind({}); +TreeView.args = { + storyContent: html` Root item 1 @@ -41,27 +57,5 @@ const storyTemplate = html` Root item 3 - -`; - -export default { - title: "Tree view", - argTypes: { - args: { - content: "You got a fast tree item", - expanded: false, - disabled: false, - selected: false, - renderCollapsedNodes: true, - }, - renderCollapsedNodes: { - control: { type: "boolean" }, - }, - }, -} as TreeViewStoryMeta; - -export const TreeView = (args: TreeViewStoryArgs) => { - const storyFragment = new DocumentFragment(); - storyTemplate.render(args, storyFragment); - return storyFragment.firstElementChild; + `, }; diff --git a/packages/web-components/fast-foundation/tsconfig.json b/packages/web-components/fast-foundation/tsconfig.json index ad1d32465bf..51e623d6974 100644 --- a/packages/web-components/fast-foundation/tsconfig.json +++ b/packages/web-components/fast-foundation/tsconfig.json @@ -13,7 +13,7 @@ "moduleResolution": "Node16", "importHelpers": true, "types": ["mocha", "webpack-env"], - "lib": ["DOM", "ES2015", "ES2016.Array.Include"] + "lib": ["DOM", "ES2015", "ES2016.Array.Include", "ES2017.Object"] }, "include": ["src"] }