diff --git a/.changeset/famous-peas-own.md b/.changeset/famous-peas-own.md new file mode 100644 index 000000000..60e93e4da --- /dev/null +++ b/.changeset/famous-peas-own.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": minor +--- + +Search header for filter menu & filter menu button diff --git a/.changeset/great-ants-watch.md b/.changeset/great-ants-watch.md new file mode 100644 index 000000000..7073f5f5b --- /dev/null +++ b/.changeset/great-ants-watch.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": patch +--- + +Added localization for ebay-video component diff --git a/.changeset/mighty-buckets-tan.md b/.changeset/mighty-buckets-tan.md new file mode 100644 index 000000000..a4f012e4b --- /dev/null +++ b/.changeset/mighty-buckets-tan.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": minor +--- + +fix(combobox): added viewAllOptions control diff --git a/.changeset/plenty-drinks-sniff.md b/.changeset/plenty-drinks-sniff.md new file mode 100644 index 000000000..e174782d3 --- /dev/null +++ b/.changeset/plenty-drinks-sniff.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": patch +--- + +refactor(storybook/examples): fully migrate stories and examples to typescript diff --git a/.changeset/plenty-tips-perform.md b/.changeset/plenty-tips-perform.md new file mode 100644 index 000000000..e3482bcad --- /dev/null +++ b/.changeset/plenty-tips-perform.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": minor +--- + +feat(carousel): respect reduced-motion during autoplay diff --git a/.changeset/sixty-bananas-kick.md b/.changeset/sixty-bananas-kick.md new file mode 100644 index 000000000..40e784667 --- /dev/null +++ b/.changeset/sixty-bananas-kick.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": minor +--- + +ebay-ccd: new component diff --git a/package-lock.json b/package-lock.json index 32aa45329..ad0effc95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "@commitlint/cli": "^19", "@commitlint/config-conventional": "^19", "@ebay/browserslist-config": "^2.10.0", - "@ebay/skin": "~18.4.0", + "@ebay/skin": "~18.5.0", "@google/model-viewer": "3.5.0", "@marko/compiler": "^5.37.23", "@marko/prettyprint": "^3.0.1", @@ -2691,10 +2691,11 @@ "license": "MIT" }, "node_modules/@ebay/skin": { - "version": "18.4.0", - "resolved": "https://registry.npmjs.org/@ebay/skin/-/skin-18.4.0.tgz", - "integrity": "sha512-zqrc/eSc0kCe/EitMA8OwkKs4/GKGRtumkm98EcOeOd+4t6eltujagzZuqoujUldkurjFg4isZIncJEV/Lqdow==", - "dev": true + "version": "18.5.0", + "resolved": "https://registry.npmjs.org/@ebay/skin/-/skin-18.5.0.tgz", + "integrity": "sha512-j7nYSZTMLoX28rwxMTd66jKQJW2XfGjo01Uo5RPow6SDZht7f9mwyF/Op8Y9G0VKmcnoRDXxAKX81nqBZNWBhg==", + "dev": true, + "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { "version": "0.23.1", diff --git a/package.json b/package.json index 6ea85095e..a1695efbd 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,9 @@ "marko.json", "package-lock.json", "*.browser.json", - "marketplace.json" + "marketplace.json", + "!**/{,*.}stories.*", + "!**/{,*.}stories-ignore.*" ], "license": "MIT", "repository": { @@ -76,7 +78,7 @@ "@commitlint/cli": "^19", "@commitlint/config-conventional": "^19", "@ebay/browserslist-config": "^2.10.0", - "@ebay/skin": "~18.4.0", + "@ebay/skin": "~18.5.0", "@google/model-viewer": "3.5.0", "@marko/compiler": "^5.37.23", "@marko/prettyprint": "^3.0.1", diff --git a/src/common/dom/index.ts b/src/common/dom/index.ts index 2e8b60709..a45ac11f0 100644 --- a/src/common/dom/index.ts +++ b/src/common/dom/index.ts @@ -14,3 +14,17 @@ export function getMaxWidth(el: HTMLElement) { el.style.width = width; return result; } + +/** + * Determines if the user has requested reduced motion in their system preferences. + * + * This function checks the `prefers-reduced-motion` media query to see if the user + * has indicated that they prefer reduced motion. This can be useful for improving + * accessibility by disabling animations or transitions for users who may be sensitive + * to motion. + * + * @returns {boolean} `true` if the user prefers reduced motion, `false` otherwise. + */ +export const useReducedMotion = + typeof window !== "undefined" && + window.matchMedia("(prefers-reduced-motion: reduce)").matches; diff --git a/src/common/menu-utils/index.ts b/src/common/menu-utils/index.ts index eb363f9ed..94aafe2bc 100644 --- a/src/common/menu-utils/index.ts +++ b/src/common/menu-utils/index.ts @@ -10,6 +10,7 @@ export interface MenuItem extends Omit, `on${string}`> { export interface BaseMenuInput { items?: Marko.AttrTag; type?: string; + separator?: Marko.AttrTag<{}>; } export interface MenuState { diff --git a/.storybook/storybook-code-source/index.ts b/src/common/storybook/storybook-code-source.ts similarity index 100% rename from .storybook/storybook-code-source/index.ts rename to src/common/storybook/storybook-code-source.ts diff --git a/.storybook/utils.ts b/src/common/storybook/utils.ts similarity index 95% rename from .storybook/utils.ts rename to src/common/storybook/utils.ts index a4df24f0f..1bc006c62 100644 --- a/.storybook/utils.ts +++ b/src/common/storybook/utils.ts @@ -1,4 +1,4 @@ -function addRenderBodies(input: any) { +function addRenderBodies(input: any): any { if (input && typeof input === "object") { if (Array.isArray(input)) { return input.map(addRenderBodies); diff --git a/src/components/components/ebay-dialog-base/component.ts b/src/components/components/ebay-dialog-base/component.ts index d2f5192fd..9fc7aea15 100644 --- a/src/components/components/ebay-dialog-base/component.ts +++ b/src/components/components/ebay-dialog-base/component.ts @@ -20,7 +20,7 @@ interface DialogBaseInput extends Omit, `on${string}`> { "close-button-text"?: AttrString; "close-button-class"?: AttrClass; "a11y-close-text"?: AttrString; - "close-button"?: Marko.Renderable; + "close-button"?: Marko.Renderable | Marko.AttrTag<{ renderBody: Marko.Body }>; "is-modal"?: boolean; "ignore-escape"?: boolean; "window-type"?: string; diff --git a/src/components/ebay-3d-viewer/3d-viewer.stories.ts b/src/components/ebay-3d-viewer/3d-viewer.stories.ts index 1f8f0c897..14de0d721 100644 --- a/src/components/ebay-3d-viewer/3d-viewer.stories.ts +++ b/src/components/ebay-3d-viewer/3d-viewer.stories.ts @@ -1,9 +1,11 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./index.marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); export default { @@ -150,7 +152,7 @@ export default { }, }, }, -}; +} ; export const Default = Template.bind({}); Default.args = { diff --git a/src/components/ebay-alert-dialog/alert-dialog.stories.ts b/src/components/ebay-alert-dialog/alert-dialog.stories.ts index 3cbf0396f..60edc70ec 100644 --- a/src/components/ebay-alert-dialog/alert-dialog.stories.ts +++ b/src/components/ebay-alert-dialog/alert-dialog.stories.ts @@ -1,9 +1,11 @@ -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./examples/default.marko"; +import type { Input } from "./index.marko"; import code from "./examples/default.marko?raw"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -87,7 +89,7 @@ Default.args = { renderBody: `OK`, }, renderBody: `You must acknowledge this alert to continue.`, -}; +} as any; Default.parameters = { docs: { source: { diff --git a/src/components/ebay-alert-dialog/test/test.browser.js b/src/components/ebay-alert-dialog/test/test.browser.js index 2801293d6..fbd2947b0 100644 --- a/src/components/ebay-alert-dialog/test/test.browser.js +++ b/src/components/ebay-alert-dialog/test/test.browser.js @@ -9,9 +9,9 @@ import { } from "vitest"; import { render, fireEvent, waitFor, cleanup } from "@marko/testing-library"; import { composeStories } from "@storybook/marko"; -import { addRenderBodies } from "../../../../.storybook/utils"; import { fastAnimations } from "../../../common/test-utils/browser"; import * as stories from "../alert-dialog.stories"; // import all stories from the stories file +import { addRenderBodies } from "../../../common/storybook/utils"; const { Default } = composeStories(stories); beforeAll(() => fastAnimations.start()); diff --git a/src/components/ebay-area-chart/area-chart.stories-ignore.ts b/src/components/ebay-area-chart/area-chart.stories-ignore.ts index 15f99afe4..4ba576e1c 100644 --- a/src/components/ebay-area-chart/area-chart.stories-ignore.ts +++ b/src/components/ebay-area-chart/area-chart.stories-ignore.ts @@ -1,10 +1,12 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./index.marko"; import sampleSeriesData from "./examples/data.json"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -70,7 +72,7 @@ export const Standard = Template.bind({}); Standard.args = { title: "Single series sample area chart", description: "this chart displays 30 days of sample values", - series: sampleSeriesData.slice(0, 1), + series: sampleSeriesData.slice(0, 1) as any, }; Standard.parameters = { docs: { @@ -85,7 +87,7 @@ TwoSeries.args = { title: "Two series sample area chart", description: "this chart displays 30 days of values for sample1 and sample2", - series: sampleSeriesData.slice(0, 2), + series: sampleSeriesData.slice(0, 2) as any, }; TwoSeries.parameters = { docs: { @@ -100,7 +102,7 @@ ThreeSeries.args = { title: "Three series sample area chart", description: "this chart displays 30 days of values for sample1, sample2 and sample3", - series: sampleSeriesData.slice(0, 3), + series: sampleSeriesData.slice(0, 3) as any, }; ThreeSeries.parameters = { docs: { @@ -115,7 +117,7 @@ FourSeries.args = { title: "Four series sample area chart", description: "this chart displays 30 days of values for sample1, sample2, sample3, and sample4", - series: sampleSeriesData.slice(0, 4), + series: sampleSeriesData.slice(0, 4) as any, }; FourSeries.parameters = { docs: { @@ -130,7 +132,7 @@ FiveSeries.args = { title: "Five series sample area chart", description: "this chart displays 30 days of values for sample1, sample2, sample3, sample4, and sample5", - series: sampleSeriesData, + series: sampleSeriesData as any, }; FiveSeries.parameters = { docs: { diff --git a/src/components/ebay-avatar/avatar.stories.ts b/src/components/ebay-avatar/avatar.stories.ts index ecbf5837a..cce89bc3a 100644 --- a/src/components/ebay-avatar/avatar.stories.ts +++ b/src/components/ebay-avatar/avatar.stories.ts @@ -1,14 +1,16 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; +} from "../../common/storybook/utils"; import avatar from "./index.marko"; import Readme from "./README.md"; import imageTemplate from "./examples/image.marko"; import imageTemplateCode from "./examples/image.marko?raw"; +import { Story } from "@storybook/marko"; +import type { Input } from "./index.marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); diff --git a/src/components/ebay-avatar/test/test.server.js b/src/components/ebay-avatar/test/test.server.js index 9f4a11de3..cd24b45ed 100644 --- a/src/components/ebay-avatar/test/test.server.js +++ b/src/components/ebay-avatar/test/test.server.js @@ -3,9 +3,9 @@ import { describe, it } from "vitest"; import { composeStories } from "@storybook/marko"; import { snapshotHTML } from "../../../common/test-utils/snapshots"; import * as stories from "../avatar.stories"; // import all stories from the stories file +import { addRenderBodies } from "../../../common/storybook/utils"; const { Default, WithImage, SignedOut } = composeStories(stories); const htmlSnap = snapshotHTML(__dirname); -import { addRenderBodies } from "../../../../.storybook/utils"; describe("avatar", () => { it("renders defaults", async () => { diff --git a/src/components/ebay-badge/badge.stories.ts b/src/components/ebay-badge/badge.stories.ts index a1ad3af2c..aca7df7e9 100644 --- a/src/components/ebay-badge/badge.stories.ts +++ b/src/components/ebay-badge/badge.stories.ts @@ -1,8 +1,9 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import badge from "./index.marko"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import badge, { type Input } from "./index.marko"; import Readme from "./README.md"; -const Template = (args) => ({ input: args }); +const Template: Story = (args) => ({ input: args }); export default { title: "graphics & icons/ebay-badge", diff --git a/src/components/ebay-badge/examples/menu.marko b/src/components/ebay-badge/examples/menu.marko index 8b610128f..629e2a824 100644 --- a/src/components/ebay-badge/examples/menu.marko +++ b/src/components/ebay-badge/examples/menu.marko @@ -1,5 +1,5 @@ - <@item badgeNumber="5" aria-label="item 1 (5 unread items)">item 1 - <@item badgeNumber="23" aria-label="item 2 (23 unread items)">item 2 + <@item badgeNumber=5 aria-label="item 1 (5 unread items)">item 1 + <@item badgeNumber=23 aria-label="item 2 (23 unread items)">item 2 <@item>item 3 diff --git a/src/components/ebay-bar-chart/bar-chart.stories-ignore.ts b/src/components/ebay-bar-chart/bar-chart.stories-ignore.ts index cc6b33dd8..365c0d4e2 100644 --- a/src/components/ebay-bar-chart/bar-chart.stories-ignore.ts +++ b/src/components/ebay-bar-chart/bar-chart.stories-ignore.ts @@ -1,9 +1,11 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./index.marko"; +import type { Input } from "./component"; import sampleSeriesData from "./examples/data.json"; -const Template = (args) => ({ +import { Story } from "@storybook/marko"; +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -75,7 +77,7 @@ export default { }, }; -function getSeriesData(series, days) { +function getSeriesData(series: number, days: number): any { return sampleSeriesData.slice(0, series).map((s) => ({ ...s, data: s.data.slice(0, days), diff --git a/src/components/ebay-breadcrumbs/breadcrumbs.stories.ts b/src/components/ebay-breadcrumbs/breadcrumbs.stories.ts index 9c4c89ec8..30c234b8f 100644 --- a/src/components/ebay-breadcrumbs/breadcrumbs.stories.ts +++ b/src/components/ebay-breadcrumbs/breadcrumbs.stories.ts @@ -1,5 +1,5 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Component from "./index.marko"; import breadcrumb2 from "./examples/last-page-as-current.marko"; import breadcrumb3 from "./examples/last-page-as-parent.marko"; @@ -9,10 +9,11 @@ import breadcrumb2Code from "./examples/last-page-as-current.marko?raw"; import breadcrumb3Code from "./examples/last-page-as-parent.marko?raw"; import breadcrumb4Code from "./examples/page-custom-attrs.marko?raw"; import breadcrumb5Code from "./examples/buttons.marko?raw"; - +import type { Input } from "./component"; import Readme from "./README.md"; +import { Story } from "@storybook/marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -93,7 +94,7 @@ heading.args = { href: "https://www.ebay.com/b/Smart-Watch-Bands/182068/bn_16565906", renderBody: "Smart Watch Bands", }, - ], + ] as any, }; heading.parameters = { diff --git a/src/components/ebay-button/button.stories.ts b/src/components/ebay-button/button.stories.ts index 5e8d6add0..468eacc93 100644 --- a/src/components/ebay-button/button.stories.ts +++ b/src/components/ebay-button/button.stories.ts @@ -1,14 +1,15 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; -import button from "./index.marko"; +} from "../../common/storybook/utils"; +import button, { type Input } from "./index.marko"; import Readme from "./README.md"; import ExpandButtonTemplate from "./examples/expand-button.marko"; import ExpandButtonTemplateCode from "./examples/expand-button.marko?raw"; +import { Story } from "@storybook/marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); // const Template = args =({ input: withRenderBody(args) }) @@ -211,7 +212,7 @@ Standard.args = { transparent: false, fixedHeight: false, truncate: false, -}; +} as any; Standard.parameters = { docs: { diff --git a/src/components/ebay-calendar/calendar.stories.ts b/src/components/ebay-calendar/calendar.stories.ts index 3f793d032..233e6d959 100644 --- a/src/components/ebay-calendar/calendar.stories.ts +++ b/src/components/ebay-calendar/calendar.stories.ts @@ -1,16 +1,18 @@ import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +} from "../../common/storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Component from "./index.marko"; +import type { Input } from "./component"; import WithLinksTemplate from "./examples/links.marko"; import WithLinksTemplateCode from "./examples/links.marko?raw"; import WithSpecificLinksTemplate from "./examples/linkMap.marko"; import WithSpecificLinksTemplateCode from "./examples/linkMap.marko?raw"; +import { Story } from "@storybook/marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); diff --git a/src/components/ebay-carousel/README.md b/src/components/ebay-carousel/README.md index 1c7960a4e..063fb76c2 100644 --- a/src/components/ebay-carousel/README.md +++ b/src/components/ebay-carousel/README.md @@ -19,3 +19,7 @@ Descrete or Continuious carousel component. Can show items as a slide or various When scrolling items, focusable elements that are not visible in the carousel should not be tabbable by default. When the carousel scrolls, it then removes the tabindex to allow the item to be focusable. In order to preserve the tabindex on an item, pass `data-carousel-tabindex="-1"` attribute to a given focusable element in order to default to that tabindex instead of removing the tabindex when the item is visible. + +## Reduced motion + +The carousel doesnot autoplay by respecting the `prefers-reduced-motion` media query. Toggle your reduced motion settings to view autoplay example with the default behavior and reduced motion behavior. diff --git a/src/components/ebay-carousel/carousel.stories.ts b/src/components/ebay-carousel/carousel.stories.ts index ec8849d8d..3c5378179 100644 --- a/src/components/ebay-carousel/carousel.stories.ts +++ b/src/components/ebay-carousel/carousel.stories.ts @@ -1,9 +1,6 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; import { - addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; - +} from "../../common/storybook/utils"; import carousel from "./index.marko"; import Readme from "./README.md"; import continiousTemplate from "./examples/continuous.marko"; diff --git a/src/components/ebay-carousel/component.ts b/src/components/ebay-carousel/component.ts index 7a47c62ea..34073a561 100644 --- a/src/components/ebay-carousel/component.ts +++ b/src/components/ebay-carousel/component.ts @@ -6,6 +6,7 @@ import { processHtmlAttributes } from "../../common/html-attributes"; import { onScrollDebounced as onScroll } from "./utils/on-scroll-debounced"; import { scrollTransition } from "./utils/scroll-transition"; import type { WithNormalizedProps } from "../../global"; +import { useReducedMotion } from "../../common/dom"; type Direction = typeof LEFT | typeof RIGHT; // Used for carousel slide direction. @@ -517,6 +518,11 @@ class Carousel extends Marko.Component { }); this.skipScrolling = false; + // If user had reduced motion turned on in OS settings, pause autoplay. + if(useReducedMotion) { + this.state.paused = true; + } + if (isNativeScrolling(this.listEl)) { config.nativeScrolling = true; this.once( diff --git a/src/components/ebay-carousel/examples/autoplay.marko b/src/components/ebay-carousel/examples/autoplay.marko index b3c82b36a..7b60d6731 100644 --- a/src/components/ebay-carousel/examples/autoplay.marko +++ b/src/components/ebay-carousel/examples/autoplay.marko @@ -33,14 +33,14 @@ export interface Input { on-slide("emit", "slide") on-play("emit", "play") on-pause("emit", "pause")> - <@item style={ width: 400 } class="demo2-card">Card 1 - <@item style={ width: 400 } class="demo2-card">Card 2 - <@item style={ width: 400 } class="demo2-card">Card 3 - <@item style={ width: 400 } class="demo2-card">Card 4 - <@item style={ width: 400 } class="demo2-card">Card 5 - <@item style={ width: 400 } class="demo2-card">Card 6 - <@item style={ width: 400 } class="demo2-card">Card 7 - <@item style={ width: 400 } class="demo2-card">Card 8 - <@item style={ width: 400 } class="demo2-card">Card 9 - <@item style={ width: 400 } class="demo2-card">Card 10 + <@item style={ width: "400px" } class="demo2-card">Card 1 + <@item style={ width: "400px" } class="demo2-card">Card 2 + <@item style={ width: "400px" } class="demo2-card">Card 3 + <@item style={ width: "400px" } class="demo2-card">Card 4 + <@item style={ width: "400px" } class="demo2-card">Card 5 + <@item style={ width: "400px" } class="demo2-card">Card 6 + <@item style={ width: "400px" } class="demo2-card">Card 7 + <@item style={ width: "400px" } class="demo2-card">Card 8 + <@item style={ width: "400px" } class="demo2-card">Card 9 + <@item style={ width: "400px" } class="demo2-card">Card 10 diff --git a/src/components/ebay-carousel/examples/continuous-image-treatment.marko b/src/components/ebay-carousel/examples/continuous-image-treatment.marko index 1eb20d25d..41680c0a8 100644 --- a/src/components/ebay-carousel/examples/continuous-image-treatment.marko +++ b/src/components/ebay-carousel/examples/continuous-image-treatment.marko @@ -24,7 +24,6 @@ export interface Input { - <@item style={ width: 400 } class="demo-card"> + <@item style={ width: "400px" } class="demo-card"> Additional Item - <@item style={ width: 400 } class="demo-card"> + <@item style={ width: "400px" } class="demo-card"> Additional Item 2 diff --git a/src/components/ebay-carousel/examples/continuous.marko b/src/components/ebay-carousel/examples/continuous.marko index 2024f7f6f..7a97ccc22 100644 --- a/src/components/ebay-carousel/examples/continuous.marko +++ b/src/components/ebay-carousel/examples/continuous.marko @@ -28,14 +28,14 @@ export interface Input { on-previous("emit", "previous") on-scroll("emit", "scroll") on-slide("emit", "slide")> - <@item style={ width: 400 } class="demo-card">Card 1 - <@item style={ width: 400 } class="demo-card">Card 2 - <@item style={ width: 400 } class="demo-card">Card 3 - <@item style={ width: 400 } class="demo-card">Card 4 - <@item style={ width: 400 } class="demo-card">Card 5 - <@item style={ width: 400 } class="demo-card">Card 6 - <@item style={ width: 400 } class="demo-card">Card 7 - <@item style={ width: 400 } class="demo-card">Card 8 - <@item style={ width: 400 } class="demo-card">Card 9 - <@item style={ width: 400 } class="demo-card">Card 10 + <@item style={ width: "400px" } class="demo-card">Card 1 + <@item style={ width: "400px" } class="demo-card">Card 2 + <@item style={ width: "400px" } class="demo-card">Card 3 + <@item style={ width: "400px" } class="demo-card">Card 4 + <@item style={ width: "400px" } class="demo-card">Card 5 + <@item style={ width: "400px" } class="demo-card">Card 6 + <@item style={ width: "400px" } class="demo-card">Card 7 + <@item style={ width: "400px" } class="demo-card">Card 8 + <@item style={ width: "400px" } class="demo-card">Card 9 + <@item style={ width: "400px" } class="demo-card">Card 10 diff --git a/src/components/ebay-carousel/examples/discrete-controlled.marko b/src/components/ebay-carousel/examples/discrete-controlled.marko index cbfc0f832..30e538609 100644 --- a/src/components/ebay-carousel/examples/discrete-controlled.marko +++ b/src/components/ebay-carousel/examples/discrete-controlled.marko @@ -1,3 +1,5 @@ +import type { Input as CarouselInput } from ""; + export interface Input { items: number; index: number; @@ -12,12 +14,13 @@ export interface State { } class { + declare state: State; onCreate() { this.state = { index: 0 } } - onMove({visibleIndexes}) { + onMove: CarouselInput["on-move"] = ({visibleIndexes}) => { this.state.index = visibleIndexes[0]; } } @@ -41,14 +44,14 @@ class { on-next("emit", "next") on-previous("emit", "previous") on-move("onMove")> - <@item style={ width: 400 } class="demo2-card">Card 1 - <@item style={ width: 400 } class="demo2-card">Card 2 - <@item style={ width: 400 } class="demo2-card">Card 3 - <@item style={ width: 400 } class="demo2-card">Card 4 - <@item style={ width: 400 } class="demo2-card">Card 5 - <@item style={ width: 400 } class="demo2-card">Card 6 - <@item style={ width: 400 } class="demo2-card">Card 7 - <@item style={ width: 400 } class="demo2-card">Card 8 - <@item style={ width: 400 } class="demo2-card">Card 9 - <@item style={ width: 400 } class="demo2-card">Card 10 + <@item style={ width: "400px" } class="demo2-card">Card 1 + <@item style={ width: "400px" } class="demo2-card">Card 2 + <@item style={ width: "400px" } class="demo2-card">Card 3 + <@item style={ width: "400px" } class="demo2-card">Card 4 + <@item style={ width: "400px" } class="demo2-card">Card 5 + <@item style={ width: "400px" } class="demo2-card">Card 6 + <@item style={ width: "400px" } class="demo2-card">Card 7 + <@item style={ width: "400px" } class="demo2-card">Card 8 + <@item style={ width: "400px" } class="demo2-card">Card 9 + <@item style={ width: "400px" } class="demo2-card">Card 10 diff --git a/src/components/ebay-carousel/examples/discrete.marko b/src/components/ebay-carousel/examples/discrete.marko index 1bd92ec47..5d93ee805 100644 --- a/src/components/ebay-carousel/examples/discrete.marko +++ b/src/components/ebay-carousel/examples/discrete.marko @@ -27,14 +27,14 @@ export interface Input { on-previous("emit", "previous") on-scroll("emit", "scroll") on-slide("emit", "slide")> - <@item style={ width: 400 } class="demo2-card">Card 1 - <@item style={ width: 400 } class="demo2-card">Card 2 - <@item style={ width: 400 } class="demo2-card">Card 3 - <@item style={ width: 400 } class="demo2-card">Card 4 - <@item style={ width: 400 } class="demo2-card">Card 5 - <@item style={ width: 400 } class="demo2-card">Card 6 - <@item style={ width: 400 } class="demo2-card">Card 7 - <@item style={ width: 400 } class="demo2-card">Card 8 - <@item style={ width: 400 } class="demo2-card">Card 9 - <@item style={ width: 400 } class="demo2-card">Card 10 + <@item style={ width: "400px" } class="demo2-card">Card 1 + <@item style={ width: "400px" } class="demo2-card">Card 2 + <@item style={ width: "400px" } class="demo2-card">Card 3 + <@item style={ width: "400px" } class="demo2-card">Card 4 + <@item style={ width: "400px" } class="demo2-card">Card 5 + <@item style={ width: "400px" } class="demo2-card">Card 6 + <@item style={ width: "400px" } class="demo2-card">Card 7 + <@item style={ width: "400px" } class="demo2-card">Card 8 + <@item style={ width: "400px" } class="demo2-card">Card 9 + <@item style={ width: "400px" } class="demo2-card">Card 10 diff --git a/src/components/ebay-ccd/README.md b/src/components/ebay-ccd/README.md new file mode 100644 index 000000000..d600adeb3 --- /dev/null +++ b/src/components/ebay-ccd/README.md @@ -0,0 +1,16 @@ +

+ + ebayccd- + + + DS v1.0.0 + +

+ +EU energy label + +## Examples and Documentation + +- [Storybook](https://ebay.github.io/ebayui-core/?path=/story/graphics-icons-ebay-ccd) +- [Storybook Docs](https://ebay.github.io/ebayui-core/?path=/docs/graphics-icons-ebay-ccd) +- [Code Examples](https://github.com/eBay/ebayui-core/tree/master/src/components/ebay-ccd/examples) diff --git a/src/components/ebay-ccd/browser.json b/src/components/ebay-ccd/browser.json new file mode 100644 index 000000000..b498bbf77 --- /dev/null +++ b/src/components/ebay-ccd/browser.json @@ -0,0 +1,9 @@ +{ + "requireRemap": [ + { + "from": "./style", + "to": "../../common/empty", + "if-flag": "ebayui-no-skin" + } + ] +} diff --git a/src/components/ebay-ccd/ccd.stories.ts b/src/components/ebay-ccd/ccd.stories.ts new file mode 100644 index 000000000..cc72bc4a8 --- /dev/null +++ b/src/components/ebay-ccd/ccd.stories.ts @@ -0,0 +1,90 @@ +import Readme from "./README.md"; +import { buildExtensionTemplate } from "../../common/storybook/utils"; +import ccd from "./index.marko"; +import DefaultTemplate from "./examples/default.marko"; +import DefaultTemplateCode from "./examples/default.marko?raw"; + +export default { + title: "graphics & icons/ebay-ccd", + component: ccd, + parameters: { + docs: { + description: { + component: Readme, + }, + }, + }, + + argTypes: { + max: { + control: { type: "text" }, + description: "The maximum range", + }, + min: { + control: { type: "text" }, + description: "The minimum range", + }, + chargerIcon: { + control: { type: "select" }, + options: [undefined, "included", "not-included"], + description: + "Toggles the charger icon visible or if its included or not", + table: { + defaultValue: { + summary: "none", + }, + }, + }, + units: { + control: { type: "text" }, + description: "The units of the rating.", + table: { + defaultValue: { + summary: "w", + }, + }, + }, + secondaryType: { + control: { type: "select" }, + options: ["none", "usbpd"], + description: "Toggles the usbpd secondary text", + table: { + defaultValue: { + summary: "none", + }, + }, + }, + secondaryText: { + control: { type: "text" }, + description: + "The text used for secodnary text. Will also be used in aria-label", + table: { + defaultValue: { + summary: "usbpd", + }, + }, + }, + a11yUnits: { + control: { type: "text" }, + description: "The units for the rating used for a11y", + table: { + defaultValue: { + summary: "watts", + }, + }, + }, + a11yText: { + control: { type: "text" }, + description: "Overrides the default aria-label text", + }, + }, +}; + +export const Default = buildExtensionTemplate( + DefaultTemplate, + DefaultTemplateCode, + { + max: "2000", + min: "1000", + }, +); diff --git a/src/components/ebay-ccd/examples/default.marko b/src/components/ebay-ccd/examples/default.marko new file mode 100644 index 000000000..3bacd2e69 --- /dev/null +++ b/src/components/ebay-ccd/examples/default.marko @@ -0,0 +1 @@ + diff --git a/src/components/ebay-ccd/examples/withCharger.marko b/src/components/ebay-ccd/examples/withCharger.marko new file mode 100644 index 000000000..ae135de2a --- /dev/null +++ b/src/components/ebay-ccd/examples/withCharger.marko @@ -0,0 +1 @@ + diff --git a/src/components/ebay-ccd/examples/withChargerAndUSBPD.marko b/src/components/ebay-ccd/examples/withChargerAndUSBPD.marko new file mode 100644 index 000000000..7c2a9bdf9 --- /dev/null +++ b/src/components/ebay-ccd/examples/withChargerAndUSBPD.marko @@ -0,0 +1 @@ + diff --git a/src/components/ebay-ccd/examples/withUSBPD.marko b/src/components/ebay-ccd/examples/withUSBPD.marko new file mode 100644 index 000000000..159a6f70b --- /dev/null +++ b/src/components/ebay-ccd/examples/withUSBPD.marko @@ -0,0 +1 @@ + diff --git a/src/components/ebay-ccd/examples/withoutCharger.marko b/src/components/ebay-ccd/examples/withoutCharger.marko new file mode 100644 index 000000000..2184c0f50 --- /dev/null +++ b/src/components/ebay-ccd/examples/withoutCharger.marko @@ -0,0 +1 @@ + diff --git a/src/components/ebay-ccd/index.marko b/src/components/ebay-ccd/index.marko new file mode 100644 index 000000000..1a3bab737 --- /dev/null +++ b/src/components/ebay-ccd/index.marko @@ -0,0 +1,59 @@ +import { processHtmlAttributes } from "../../common/html-attributes"; +import type { WithNormalizedProps } from "../../global"; +static interface CCDInput extends Omit, `on${string}`> { + max?: string; + min?: string; + "charger-icon"?: "included" | "not-included"; + units?: string; + "secondary-type"?: string; + "secondary-text"?: string; + "a11y-units"?: string; + "a11y-text"?: string; +} +export interface Input extends WithNormalizedProps {} +static function noop() {} +$ const { + class: inputClass, + style, + a11yText, + chargerIcon, + units = "W", + a11yUnits = "watts", + max, + min, + secondaryType = "none", + secondaryText = "USB PD", + ...htmlInput +} = input; +$ (input as any).toJSON = noop; + +$ const hasFastCharging = secondaryType === "usbpd"; + +
+ + + + + + +
+ +
+
${min} - ${max}
+
${units}
+ +
${secondaryText}
+ +
+
+
diff --git a/src/components/ebay-ccd/marko-tag.json b/src/components/ebay-ccd/marko-tag.json new file mode 100644 index 000000000..5b2091dae --- /dev/null +++ b/src/components/ebay-ccd/marko-tag.json @@ -0,0 +1,21 @@ +{ + "attribute-groups": ["html-attributes"], + "@*": { + "targetProperty": null, + "type": "expression" + }, + "@html-attributes": "expression", + "@max": "string", + "@min": "string", + "@charger-icon": { + "enum": ["included", "not-included"] + }, + "@units": "string", + "@secondary-type": { + "enum": ["none", "usbpd"] + }, + "@secondary-text": "string", + "@a11y-units": "string", + "@a11y-text": "string", + "description": "[view documentation](https://ebay.github.io/ebayui-core/?path=/story/graphics-icons-ebay-ccd)" +} diff --git a/src/components/ebay-ccd/style.ts b/src/components/ebay-ccd/style.ts new file mode 100644 index 000000000..db487bd4a --- /dev/null +++ b/src/components/ebay-ccd/style.ts @@ -0,0 +1 @@ +import "@ebay/skin/ccd"; diff --git a/src/components/ebay-ccd/test/__snapshots__/test.server.js.snap b/src/components/ebay-ccd/test/__snapshots__/test.server.js.snap new file mode 100644 index 000000000..f3126bc3a --- /dev/null +++ b/src/components/ebay-ccd/test/__snapshots__/test.server.js.snap @@ -0,0 +1,564 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`ccd > passes through additional html attributes 1`] = ` +
+
+ + + +
+
+ 1000 - 2000 +
+
+ W +
+
+
+
+`; + +exports[`ccd > passes through additional html attributes 2`] = ` +
+
+ + + +
+
+ 1000 - 2000 +
+
+ W +
+
+
+
+`; + +exports[`ccd > renders ccd with charger included 1`] = ` +" +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 + 1000 - 2000 + 
 + 
 + W + 
 +  +  +  +
" +`; + +exports[`ccd > renders ccd with charger included and usbpd 1`] = ` +" +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 + 1000 - 2000 + 
 + 
 + W + 
 +  +  +  +
" +`; + +exports[`ccd > renders ccd with charger not included 1`] = ` +" +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 + 1000 - 2000 + 
 + 
 + W + 
 +  +  +  +
" +`; + +exports[`ccd > renders ccd with custom a11y 1`] = ` +" +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 + 1000 - 2000 + 
 + 
 + W + 
 +  +  +  +
" +`; + +exports[`ccd > renders ccd with usbpd included 1`] = ` +" +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 + 1000 - 2000 + 
 + 
 + W + 
 +  +  +  +
" +`; + +exports[`ccd > renders default ccd 1`] = ` +" +  +  +  +  +  +  +  +  +  +  +  +  +  + 
 + 1000 - 2000 + 
 + 
 + W + 
 +  +  +  +
" +`; diff --git a/src/components/ebay-ccd/test/test.server.js b/src/components/ebay-ccd/test/test.server.js new file mode 100644 index 000000000..26349e7be --- /dev/null +++ b/src/components/ebay-ccd/test/test.server.js @@ -0,0 +1,42 @@ +import { describe, it } from "vitest"; +import { testPassThroughAttributes } from "../../../common/test-utils/server"; +import { composeStories } from "@storybook/marko"; +import { snapshotHTML } from "../../../common/test-utils/snapshots"; +import * as stories from "../ccd.stories"; // import all stories from the stories file +const { Default } = composeStories(stories); +const htmlSnap = snapshotHTML(__dirname); + +describe("ccd", () => { + it("renders default ccd", async () => { + await htmlSnap(Default); + }); + + it("renders ccd with charger included", async () => { + await htmlSnap(Default, { chargerIcon: "included" }); + }); + + it("renders ccd with charger not included", async () => { + await htmlSnap(Default, { chargerIcon: "not-included" }); + }); + + it("renders ccd with usbpd included", async () => { + await htmlSnap(Default, { secondary: "usbpd" }); + }); + + it("renders ccd with charger included and usbpd", async () => { + await htmlSnap(Default, { + chargerIcon: "included", + secondary: "usbpd", + }); + }); + + it("renders ccd with custom a11y", async () => { + await htmlSnap(Default, { + chargerIcon: "included", + secondary: "usbpd", + a11yText: "custom text", + }); + }); + + testPassThroughAttributes(Default); +}); diff --git a/src/components/ebay-character-count/character-count.stories.ts b/src/components/ebay-character-count/character-count.stories.ts index 0a40b9569..27fc08ed4 100644 --- a/src/components/ebay-character-count/character-count.stories.ts +++ b/src/components/ebay-character-count/character-count.stories.ts @@ -1,16 +1,18 @@ import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +} from "../../common/storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Component from "./index.marko"; +import type { Input } from "./component"; import InFieldTemplate from "./examples/in-field.marko"; import InFieldCode from "./examples/in-field.marko?raw"; import CustomTextTemplate from "./examples/custom-text.marko"; import CustomTextCode from "./examples/custom-text.marko?raw"; +import { Story } from "@storybook/marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); diff --git a/src/components/ebay-character-count/examples/custom-text.marko b/src/components/ebay-character-count/examples/custom-text.marko index 3c1e372b9..4f938fb59 100644 --- a/src/components/ebay-character-count/examples/custom-text.marko +++ b/src/components/ebay-character-count/examples/custom-text.marko @@ -1,4 +1,8 @@ -$ const { max = 120, clippedText } = input; +export interface Input { + max?: number; +} + +$ const { max = 120 } = input; class { + declare state: { + inputValue: string; + inputAriaLive: Marko.AriaAttributes["aria-live"]; + charCount: number; + }; onCreate() { this.state = { inputValue: "", @@ -35,12 +44,20 @@ class { charCount: 0 }; } - onTextChange({ originalEvent: e }) { - this.state.inputValue = e.target.value; + onTextChange({ value }: { value: string }) { + this.state.inputValue = value; } - onCharCountChange({ count, inputAriaLive }) { - this.state.inputAriaLive = inputAriaLive; - this.state.charCount = count; - this.emit('change', {count, inputAriaLive}) + onCharCountChange(e?: { + count: number; + inputAriaLive: Marko.AriaAttributes["aria-live"]; + }) { + if (e) { + this.state.inputAriaLive = e.inputAriaLive; + this.state.charCount = e.count; + this.emit("change", { + count: e.count, + inputAriaLive: e.inputAriaLive, + }); + } } } diff --git a/src/components/ebay-character-count/examples/in-field.marko b/src/components/ebay-character-count/examples/in-field.marko index 5bea09942..58879606a 100644 --- a/src/components/ebay-character-count/examples/in-field.marko +++ b/src/components/ebay-character-count/examples/in-field.marko @@ -1,3 +1,7 @@ +export interface Input { + max?: number; + clippedText?: string; +} $ const { max = 120, clippedText } = input; @@ -30,17 +34,29 @@ $ const { max = 120, clippedText } = input; class { + declare state: { + inputValue: string; + inputAriaLive: Marko.AriaAttributes["aria-live"]; + }; onCreate() { this.state = { inputValue: "", inputAriaLive: null, }; } - onTextChange({ originalEvent: e }) { - this.state.inputValue = e.target.value; + onTextChange({ value }: { value: string }) { + this.state.inputValue = value; } - onCharCountChange({ count, inputAriaLive }) { - this.state.inputAriaLive = inputAriaLive; - this.emit('change', {count, inputAriaLive}) + onCharCountChange(e?: { + count: number; + inputAriaLive: Marko.AriaAttributes["aria-live"]; + }) { + if (e) { + this.state.inputAriaLive = e.inputAriaLive; + this.emit("change", { + count: e.count, + inputAriaLive: e.inputAriaLive, + }); + } } } diff --git a/src/components/ebay-checkbox/checkbox.stories.ts b/src/components/ebay-checkbox/checkbox.stories.ts index 733462440..273f8e815 100644 --- a/src/components/ebay-checkbox/checkbox.stories.ts +++ b/src/components/ebay-checkbox/checkbox.stories.ts @@ -1,4 +1,4 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Checkbox from "./index.marko"; import GroupTemplate from "./examples/group.marko"; @@ -7,8 +7,10 @@ import DisabledTemplate from "./examples/DisabledWithLabel.marko"; import GroupCode from "./examples/group.marko?raw"; import WithLabelCode from "./examples/WithLabel.marko?raw"; import DisabledCode from "./examples/DisabledWithLabel.marko?raw"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component-browser"; -const Template = (args) => ({ input: args }); +const Template: Story = (args) => ({ input: args }); export default { title: "form input/ebay-checkbox", @@ -88,7 +90,7 @@ export default { }, }; -export const WithLabel = (args) => ({ +export const WithLabel: Story = (args) => ({ input: args, component: WithLabelTemplate, }); @@ -104,7 +106,7 @@ WithLabel.parameters = { }, }; -export const Disabled = (args) => ({ +export const Disabled: Story = (args) => ({ input: args, component: DisabledTemplate, }); @@ -120,7 +122,7 @@ Disabled.parameters = { }, }; -export const Group = (args) => ({ +export const Group: Story = (args) => ({ input: args, component: GroupTemplate, }); diff --git a/src/components/ebay-chip/chip.stories.ts b/src/components/ebay-chip/chip.stories.ts index 6119f255c..4c3727553 100644 --- a/src/components/ebay-chip/chip.stories.ts +++ b/src/components/ebay-chip/chip.stories.ts @@ -1,9 +1,10 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; -import Component from "./index.marko"; +import Component, { type Input } from "./index.marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -43,8 +44,8 @@ export default { export const Default = Template.bind({}); Default.args = { - renderBody: "chip text", -}; + renderBody: "chip text" as any, +} ; Default.parameters = { docs: { source: { @@ -55,7 +56,7 @@ Default.parameters = { export const WithDelete = Template.bind({}); WithDelete.args = { - renderBody: "chip text", + renderBody: "chip text" as any, a11yDeleteButtonText: "Delete", }; WithDelete.parameters = { diff --git a/src/components/ebay-chips-combobox/chips-combobox.stories.ts b/src/components/ebay-chips-combobox/chips-combobox.stories.ts index 45f96ac7e..3e85b743b 100644 --- a/src/components/ebay-chips-combobox/chips-combobox.stories.ts +++ b/src/components/ebay-chips-combobox/chips-combobox.stories.ts @@ -1,8 +1,4 @@ -import { - addRenderBodies, - buildExtensionTemplate, -} from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { buildExtensionTemplate } from "../../common/storybook/utils"; import Readme from "./README.md"; import Combobox from "./index.marko"; import DefaultTemplate from "./examples/default.marko"; @@ -10,9 +6,6 @@ import DefaultCode from "./examples/default.marko?raw"; import SelectedTemplate from "./examples/selected.marko"; import SelectedCode from "./examples/selected.marko?raw"; -const Template = (args) => ({ - input: addRenderBodies(args), -}); export default { title: "form input/ebay-chips-combobox", diff --git a/src/components/ebay-combobox/combobox.stories.ts b/src/components/ebay-combobox/combobox.stories.ts index 68acaa1c9..43c45418e 100644 --- a/src/components/ebay-combobox/combobox.stories.ts +++ b/src/components/ebay-combobox/combobox.stories.ts @@ -1,14 +1,16 @@ import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +} from "../../common/storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Combobox from "./index.marko"; +import type { Input } from "./component"; import SearchFilteringTemplate from "./examples/search-filtering.marko"; import SearchFilteringTemplateCode from "./examples/search-filtering.marko?raw"; +import { Story } from "@storybook/marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -53,6 +55,11 @@ export default { description: "default is `automatic`; available values are `automatic`, `manual`. If set to automatic will automatically fill in the input with the currently highlighted item when using the up/down keys.", }, + viewAllOptions: { + type: "boolean", + control: { type: "boolean" }, + description: "Filters listbox options based on user input", + }, "floating-label": { control: { type: "text" }, description: @@ -172,7 +179,7 @@ FloatingLabel.args = { { text: "Basic Offer 4" }, ], floatingLabel: "Default Label", -}; +} as any; FloatingLabel.parameters = { docs: { source: { @@ -200,7 +207,7 @@ Isolated.args = { { text: "Basic Offer 3", value: "5" }, { text: "Basic Offer 4", value: "6" }, ], -}; +} as any; Isolated.parameters = { docs: { source: { diff --git a/src/components/ebay-combobox/component.ts b/src/components/ebay-combobox/component.ts index 854dfad09..09bc6f131 100644 --- a/src/components/ebay-combobox/component.ts +++ b/src/components/ebay-combobox/component.ts @@ -27,10 +27,11 @@ interface ComboboxInput extends Omit, `on${string}`> { autocomplete?: "list" | "none"; "list-selection"?: "manual" | "automatic"; "floating-label"?: boolean; - button?: Marko.Input<"button"> & { + "view-all-options"?: boolean; + button?: Marko.Input<"button"> & Marko.AttrTag<{ htmlAttributes?: Record; renderBody?: Marko.Body; - }; + }>; options?: Marko.AttrTag; "chevron-size"?: "large"; "on-focus"?: (event: ComboboxEvent) => void; @@ -49,7 +50,6 @@ export interface Input extends WithNormalizedProps {} interface State { currentValue: Input["value"]; - viewAllOptions: boolean; } export default class Combobox extends Marko.Component { @@ -117,14 +117,7 @@ export default class Combobox extends Marko.Component { } handleExpand() { - if (this.state.viewAllOptions) { - this.setSelectedView(); - } else { - this.state.viewAllOptions = true; - this.once("update", () => { - this.setSelectedView(); - }); - } + this.setSelectedView(); this.emit("expand"); } @@ -179,7 +172,6 @@ export default class Combobox extends Marko.Component { // We force the expander open just in case. this.expand(); }); - this.state.viewAllOptions = false; this._emitComboboxEvent("input-change"); }); @@ -233,7 +225,6 @@ export default class Combobox extends Marko.Component { this.lastValue = input.value; this.state = { currentValue: this.lastValue, - viewAllOptions: (this.state && this.state.viewAllOptions) || true, }; if (this.expander) { this.expandedChange = input.expanded !== this.expanded; @@ -356,7 +347,10 @@ export default class Combobox extends Marko.Component { } _getVisibleOptions() { - if (this.autocomplete === "none" || this.state.viewAllOptions) { + if ( + this.autocomplete === "none" || + (this.input.viewAllOptions ?? true) + ) { return [...(this.input.options ?? [])]; } diff --git a/src/components/ebay-combobox/examples/floating-label.marko b/src/components/ebay-combobox/examples/floating-label.marko index e61268f7a..aaa6059c2 100644 --- a/src/components/ebay-combobox/examples/floating-label.marko +++ b/src/components/ebay-combobox/examples/floating-label.marko @@ -1,4 +1,4 @@ - + <@option text="August Campaign"/> <@option text="4th of July Sale (paused)"/> <@option text="Basic Offer"/> diff --git a/src/components/ebay-combobox/examples/search-filtering.marko b/src/components/ebay-combobox/examples/search-filtering.marko index ecbf92b75..c8adc29e2 100644 --- a/src/components/ebay-combobox/examples/search-filtering.marko +++ b/src/components/ebay-combobox/examples/search-filtering.marko @@ -1,45 +1,71 @@ -import countryList from './data.json'; +import countryList from "./data.json"; +import type { AttrStringOrNumber, AttrClass } from "marko/tags-html"; +import type { Input as ComboboxInput } from ""; class { + declare state: { + options: Array<{ + code: string; + name: string; + }>; + autocompleteOption: "list" | "none"; + value: AttrStringOrNumber; + }; + timeout: any; onCreate() { this.state = { options: countryList, - autocompleteOption: 'none', - value: '', + autocompleteOption: "none", + value: "", }; } - async inputChange({ currentInputValue }, { el, index, selected }) { - this.state.autocompleteOption = 'none'; - this.state.value = currentInputValue; - const options = await this.searchCountry(currentInputValue); + async inputChange(e: { + currentInputValue: AttrStringOrNumber; + options?: Marko.AttrTag<{ + text: string; + value?: string; + class?: AttrClass; + sticky?: boolean; + }>; + }) { + this.state.autocompleteOption = "none"; + this.state.value = e.currentInputValue; + const options = await this.searchCountry(e.currentInputValue); this.state.options = options; - this.state.autocompleteOption = 'list'; + this.state.autocompleteOption = "list"; } - async searchCountry(currentInputValue) { + async searchCountry(currentInputValue: AttrStringOrNumber): Promise< + Array<{ + code: string; + name: string; + }> + > { return new Promise((resolve) => { clearTimeout(this.timeout); this.timeout = setTimeout(() => { const filtered = countryList .filter((country) => - country.name.toLowerCase().startsWith(currentInputValue.toLowerCase()) + country.name + .toLowerCase() + .startsWith(`${currentInputValue}`.toLowerCase()), ) .slice(0, 10); resolve(filtered); }, 500); }); } - selected(el) { - console.log('selected', el); + selected: ComboboxInput["on-select"] = (e) => { + console.log("selected", e); } } <@option data-id=option.code text=option.name/> diff --git a/src/components/ebay-combobox/test/test.browser.js b/src/components/ebay-combobox/test/test.browser.js index d499cd97d..819394eba 100644 --- a/src/components/ebay-combobox/test/test.browser.js +++ b/src/components/ebay-combobox/test/test.browser.js @@ -239,6 +239,34 @@ describe("given the combobox with 3 items and 2 selected", () => { } }); +describe("given the combobox with 6 items and view all options false", () => { + beforeEach(async () => { + component = await render(Isolated, { + value: Isolated.args.options[2].text, + viewAllOptions: false, + }); + }); + + describe("when the input receives focus", () => { + beforeEach(async () => { + await fireEvent.focus(component.getByRole("combobox")); + }); + + it("then it should expand the combobox", () => { + expect(component.getByRole("combobox")).toHaveAttribute( + "aria-expanded", + "true", + ); + }); + + it("then should show filtered options with first one active", () => { + const options = component.getAllByRole("option"); + expect(options.length).to.equal(4); + expect(options[0]).toHaveClass("combobox__option--active"); + }); + }); +}); + describe("given the combobox with 3 items set to manual selection", () => { beforeEach(async () => { component = await render(Isolated, { diff --git a/src/components/ebay-confirm-dialog/confirm-dialog.stories.ts b/src/components/ebay-confirm-dialog/confirm-dialog.stories.ts index 5d45984e6..fc2b3bedd 100644 --- a/src/components/ebay-confirm-dialog/confirm-dialog.stories.ts +++ b/src/components/ebay-confirm-dialog/confirm-dialog.stories.ts @@ -1,9 +1,11 @@ -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Confirm from "./examples/default.marko"; import code from "./examples/default.marko?raw"; +import type { Input } from "./index.marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -118,7 +120,7 @@ Default.args = { renderBody: `Cancel`, }, renderBody: `You will permanently lose this address.`, -}; +} as any; Default.parameters = { docs: { source: { diff --git a/src/components/ebay-confirm-dialog/examples/default.marko b/src/components/ebay-confirm-dialog/examples/default.marko index 6ef7770a1..7a3a762fc 100644 --- a/src/components/ebay-confirm-dialog/examples/default.marko +++ b/src/components/ebay-confirm-dialog/examples/default.marko @@ -1,4 +1,7 @@ +import type { Input as ConfirmDialogInput } from ""; + export interface Input { + open?: boolean; renderBody?: Marko.Body; header: { renderBody?: Marko.Body; @@ -38,18 +41,21 @@ $ const { Open Confirm Dialog class { - onInput(input) { + declare state: { + open?: boolean; + } + onInput(input: Input) { this.state = { open: input.open }; } openDialog() { this.state.open = true; } - closeDialog(ev) { + closeDialog: ConfirmDialogInput["on-reject"] = (e: Event) => { this.state.open = false; - this.emit('reject', ev); + this.emit('reject', e); } - success(ev) { + success: ConfirmDialogInput["on-confirm"] = (e) => { this.state.open = false; - this.emit('confirm', ev); + this.emit('confirm', e); } } diff --git a/src/components/ebay-confirm-dialog/test/test.browser.js b/src/components/ebay-confirm-dialog/test/test.browser.js index 5048d5f6e..0dbb45fe0 100644 --- a/src/components/ebay-confirm-dialog/test/test.browser.js +++ b/src/components/ebay-confirm-dialog/test/test.browser.js @@ -9,9 +9,9 @@ import { } from "vitest"; import { composeStories } from "@storybook/marko"; import { render, fireEvent, waitFor, cleanup } from "@marko/testing-library"; -import { addRenderBodies } from "../../../../.storybook/utils"; import { fastAnimations } from "../../../common/test-utils/browser"; import * as stories from "../confirm-dialog.stories"; // import all stories from the stories file +import { addRenderBodies } from "../../../common/storybook/utils"; const { Default } = composeStories(stories); beforeAll(() => fastAnimations.start()); diff --git a/src/components/ebay-cta-button/cta-button.stories.ts b/src/components/ebay-cta-button/cta-button.stories.ts index a2fd7c243..f1515978c 100644 --- a/src/components/ebay-cta-button/cta-button.stories.ts +++ b/src/components/ebay-cta-button/cta-button.stories.ts @@ -1,13 +1,14 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; -import Cta from "./index.marko"; +import Cta, { type Input } from "./index.marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: { ...args, - renderBody(out) { + renderBody: function(out: any) { out.html(args.renderBody); - }, + } as any, }, }); @@ -50,7 +51,7 @@ Standard.args = { renderBody: "CTA button", href: "http://www.ebay.com", size: "regular", -}; +} as any; Standard.parameters = { docs: { diff --git a/src/components/ebay-date-textbox/component.ts b/src/components/ebay-date-textbox/component.ts index 11a87c633..e5c1ac002 100644 --- a/src/components/ebay-date-textbox/component.ts +++ b/src/components/ebay-date-textbox/component.ts @@ -64,10 +64,6 @@ class DateTextbox extends Marko.Component { secondSelected: null, popover: false, }; - - if (typeof document !== "undefined") { - this.calculateNumMonths(); - } } onMount() { @@ -119,6 +115,7 @@ class DateTextbox extends Marko.Component { } openPopover() { + this.calculateNumMonths(); this.state.popover = true; } diff --git a/src/components/ebay-date-textbox/date-textbox.stories.ts b/src/components/ebay-date-textbox/date-textbox.stories.ts index d97bb245c..d0de2579a 100644 --- a/src/components/ebay-date-textbox/date-textbox.stories.ts +++ b/src/components/ebay-date-textbox/date-textbox.stories.ts @@ -1,8 +1,8 @@ import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +} from "../../common/storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Component from "./index.marko"; import LocalizedTemplate from "./examples/localized.marko"; @@ -11,8 +11,10 @@ import WithClearTemplate from "./examples/with-clear.marko"; import WithClearTemplateCode from "./examples/with-clear.marko?raw"; import InField from "./examples/in-field.marko"; import InFieldCode from "./examples/in-field.marko?raw"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); diff --git a/src/components/ebay-date-textbox/examples/in-field.marko b/src/components/ebay-date-textbox/examples/in-field.marko index 9555d217a..87ff215a9 100644 --- a/src/components/ebay-date-textbox/examples/in-field.marko +++ b/src/components/ebay-date-textbox/examples/in-field.marko @@ -1,4 +1,7 @@ class { + declare state: { + invalid: boolean + } onCreate() { this.state = { invalid: false, diff --git a/src/components/ebay-date-textbox/examples/localized.marko b/src/components/ebay-date-textbox/examples/localized.marko index 43620cb69..096e9a92d 100644 --- a/src/components/ebay-date-textbox/examples/localized.marko +++ b/src/components/ebay-date-textbox/examples/localized.marko @@ -7,7 +7,6 @@ a11yRangeStartText="Reeks begin" a11yInRangeText="Binne bereik" a11yRangeEndText="Reeks einde" - localizeFormat on-change("emit", "change") ...input > diff --git a/src/components/ebay-date-textbox/examples/with-clear.marko b/src/components/ebay-date-textbox/examples/with-clear.marko index 75000d4ea..de26bd1fe 100644 --- a/src/components/ebay-date-textbox/examples/with-clear.marko +++ b/src/components/ebay-date-textbox/examples/with-clear.marko @@ -1,24 +1,37 @@ +export interface Input { + range?: boolean; +} + class { + declare state: { + value?: string; + rangeEnd?: string; + } onCreate() { this.state = { - value: null, + value: undefined, rangeEnd: undefined }; } - handleChange({ selected, rangeStart, rangeEnd }) { - if (selected) { - this.state.value = selected; + handleChange(e: { selected: string | null } + | { rangeStart: string | null; rangeEnd: string | null }) { + if ("selected" in e && e.selected) { + this.state.value = e.selected; } else { - this.state.value = rangeStart; - this.state.rangeEnd = rangeEnd; + if ("rangeStart" in e && e.rangeStart) { + this.state.value = e.rangeStart; + } + if ("rangeEnd" in e && e.rangeEnd) { + this.state.rangeEnd = e.rangeEnd; + } } } clear() { - this.state.value = null; + this.state.value = undefined; if (this.input.range) { - this.state.rangeEnd = null; + this.state.rangeEnd = undefined; } } } diff --git a/src/components/ebay-details/details.stories.ts b/src/components/ebay-details/details.stories.ts index 0f3a1252e..7b09c7c9d 100644 --- a/src/components/ebay-details/details.stories.ts +++ b/src/components/ebay-details/details.stories.ts @@ -1,13 +1,15 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Details from "./index.marko"; +import type { Input } from "./component-browser"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: { ...args, - renderBody(out) { + renderBody: function(out: any) { out.html(args.renderBody); - }, + } as any, }, }); @@ -86,7 +88,7 @@ export default { export const Standard = Template.bind({}); Standard.args = { - renderBody: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`, + renderBody: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.` as any, text: "Show me the details!", size: "regular", open: false, diff --git a/src/components/ebay-donut-chart/donut-chart.stories.ts b/src/components/ebay-donut-chart/donut-chart.stories.ts index 9b10f0b2a..f738c0c0c 100644 --- a/src/components/ebay-donut-chart/donut-chart.stories.ts +++ b/src/components/ebay-donut-chart/donut-chart.stories.ts @@ -1,5 +1,5 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./index.marko"; @@ -7,8 +7,10 @@ import WithAttrTagsTemplate from "./examples/with-attr-tags.marko"; import WithAttrTagsCode from "./examples/with-attr-tags.marko?raw"; import { data } from "./examples/data.json"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -187,7 +189,7 @@ NoMetrics.args = { highchartsDescription: "Donut chart description", }; -export const WithAttributeTags = (args) => ({ +export const WithAttributeTags: Story = (args) => ({ input: args, component: WithAttrTagsTemplate, }); diff --git a/src/components/ebay-drawer-dialog/drawer-dialog.stories.ts b/src/components/ebay-drawer-dialog/drawer-dialog.stories.ts index ab0d567dd..b1949a25a 100644 --- a/src/components/ebay-drawer-dialog/drawer-dialog.stories.ts +++ b/src/components/ebay-drawer-dialog/drawer-dialog.stories.ts @@ -1,9 +1,11 @@ -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./examples/default.marko"; import code from "./examples/default.marko?raw"; import withFooter from "./examples/withFooter.marko"; import withFooterCode from "./examples/withFooter.marko?raw"; +import type { Input } from "./component"; export default { title: "dialogs/ebay-drawer-dialog", @@ -124,7 +126,7 @@ export default { }, }; -export const Standard = (args) => ({ +export const Standard: Story = (args) => ({ input: addRenderBodies(args), }); Standard.args = { @@ -134,7 +136,7 @@ Standard.args = { renderBody: `Body Content`, a11yMinimizeText: "Minimize Drawer", a11yMaximizeText: "Maximize Drawer", -}; +} as any; Standard.parameters = { docs: { source: { @@ -143,7 +145,7 @@ Standard.parameters = { }, }; -export const WithFooter = (args) => ({ +export const WithFooter: Story = (args) => ({ component: withFooter, input: addRenderBodies(args), }); @@ -154,7 +156,7 @@ WithFooter.args = { renderBody: `Body Content`, a11yMinimizeText: "Minimize Drawer", a11yMaximizeText: "Maximize Drawer", -}; +} as any; WithFooter.parameters = { docs: { source: { diff --git a/src/components/ebay-drawer-dialog/examples/default.marko b/src/components/ebay-drawer-dialog/examples/default.marko index e3e35faee..57b97e5fd 100644 --- a/src/components/ebay-drawer-dialog/examples/default.marko +++ b/src/components/ebay-drawer-dialog/examples/default.marko @@ -14,6 +14,9 @@ export interface Input { Open drawer class { + declare state: { + open: boolean; + }; onCreate() { this.state = { open: false }; } diff --git a/src/components/ebay-drawer-dialog/examples/lots-of-text.marko b/src/components/ebay-drawer-dialog/examples/lots-of-text.marko index eb81bd3bb..86ed3dd9f 100644 --- a/src/components/ebay-drawer-dialog/examples/lots-of-text.marko +++ b/src/components/ebay-drawer-dialog/examples/lots-of-text.marko @@ -45,6 +45,9 @@ Open drawer class { + declare state: { + open: boolean; + }; onCreate() { this.state = { open: false }; } diff --git a/src/components/ebay-drawer-dialog/examples/no-handle.marko b/src/components/ebay-drawer-dialog/examples/no-handle.marko index 5b5213d0e..1e6ee6d49 100644 --- a/src/components/ebay-drawer-dialog/examples/no-handle.marko +++ b/src/components/ebay-drawer-dialog/examples/no-handle.marko @@ -13,6 +13,9 @@ Open drawer class { + declare state: { + open: boolean; + }; onCreate() { this.state = { open: false }; } diff --git a/src/components/ebay-drawer-dialog/test/test.browser.js b/src/components/ebay-drawer-dialog/test/test.browser.js index e5badcdf6..9f4a7f1e7 100644 --- a/src/components/ebay-drawer-dialog/test/test.browser.js +++ b/src/components/ebay-drawer-dialog/test/test.browser.js @@ -10,8 +10,8 @@ import { } from "vitest"; import { render, fireEvent, waitFor, cleanup } from "@marko/testing-library"; import { fastAnimations } from "../../../common/test-utils/browser"; -import { addRenderBodies } from "../../../../.storybook/utils"; import * as stories from "../drawer-dialog.stories"; // import all stories from the stories file +import { addRenderBodies } from "../../../common/storybook/utils"; const { Standard } = composeStories(stories); beforeAll(() => fastAnimations.start()); diff --git a/src/components/ebay-education-notice/education-notice.stories.ts b/src/components/ebay-education-notice/education-notice.stories.ts index e2c5ae15a..820ecb329 100644 --- a/src/components/ebay-education-notice/education-notice.stories.ts +++ b/src/components/ebay-education-notice/education-notice.stories.ts @@ -1,8 +1,8 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; +} from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./index.marko"; import withFooter from "./examples/with-footer.marko"; @@ -14,8 +14,10 @@ import ProminentIconTemplateCode from "./examples/prominent-icon.marko?raw"; import withDismiss from "./examples/with-dismiss.marko"; import withDismissCode from "./examples/with-dismiss.marko?raw"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -113,7 +115,7 @@ Default.args = { renderBody: "Education notice title", }, renderBody: "

Education notice info. Things you need to know.

", -}; +} as any; Default.parameters = { docs: { source: { diff --git a/src/components/ebay-eek/eek.stories.ts b/src/components/ebay-eek/eek.stories.ts index fa92e0fe3..5ec6c3873 100644 --- a/src/components/ebay-eek/eek.stories.ts +++ b/src/components/ebay-eek/eek.stories.ts @@ -1,6 +1,6 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; -import eek from "./index.marko"; +import eek, { type Input } from "./index.marko"; import example1 from "./examples/A+++.marko"; import example2 from "./examples/A++.marko"; import example3 from "./examples/A+.marko"; @@ -11,6 +11,7 @@ import example2Code from "./examples/A++.marko?raw"; import example3Code from "./examples/A+.marko?raw"; import example4Code from "./examples/A.marko?raw"; import example5Code from "./examples/invalid.marko?raw"; +import { Story } from "@storybook/marko"; export default { title: "graphics & icons/ebay-eek", @@ -39,7 +40,7 @@ export default { }, }; -export const Default = (args) => ({ input: args }); +export const Default: Story = (args) => ({ input: args }); Default.args = { max: "A+++", min: "E", diff --git a/src/components/ebay-fake-link/fake-link.stories.ts b/src/components/ebay-fake-link/fake-link.stories.ts index e12868db2..d4e10563a 100644 --- a/src/components/ebay-fake-link/fake-link.stories.ts +++ b/src/components/ebay-fake-link/fake-link.stories.ts @@ -1,13 +1,15 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import component from "./index.marko"; import Readme from "./README.md"; +import type { Input } from "./component-browser"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: { ...args, - renderBody(out) { + renderBody: function(out: any) { out.html(args.renderBody); - }, + } as any, }, }); @@ -88,7 +90,7 @@ export default { export const Standard = Template.bind({}); Standard.args = { - renderBody: "Fake-Link", + renderBody: "Fake-Link" as any, disabled: false, }; diff --git a/src/components/ebay-fake-menu-button/component.ts b/src/components/ebay-fake-menu-button/component.ts index 890fcd5cd..7dfa21dd9 100644 --- a/src/components/ebay-fake-menu-button/component.ts +++ b/src/components/ebay-fake-menu-button/component.ts @@ -16,16 +16,17 @@ interface FakeMenuButtonInput extends Omit, `on${string}`> { priority?: "primary" | "secondary" | "delete" | "tertiary" | "none"; borderless?: boolean; transparent?: boolean; - icon?: Marko.Renderable; + icon?: Marko.Renderable | Marko.AttrTag<{ renderBody: Marko.Body }>; "a11y-text"?: AttrString; disabled?: boolean; "no-toggle-icon"?: boolean; - label?: { renderBody?: Marko.Body }; + label?: Marko.AttrTag<{ renderBody?: Marko.Body }>; "text-align"?: "center"; type?: FakeMenuInput["type"]; reverse?: boolean; "fix-width"?: boolean; items?: Marko.AttrTag; + separator?: Marko.AttrTag<{}>; "collapse-on-select"?: boolean; "on-expand"?: (event: MenuEvent) => void; "on-collapse"?: (event: MenuEvent) => void; diff --git a/src/components/ebay-fake-menu-button/fake-menu-button.stories.ts b/src/components/ebay-fake-menu-button/fake-menu-button.stories.ts index 9dc5638b5..ecb7e3d1f 100644 --- a/src/components/ebay-fake-menu-button/fake-menu-button.stories.ts +++ b/src/components/ebay-fake-menu-button/fake-menu-button.stories.ts @@ -1,8 +1,8 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; +} from "../../common/storybook/utils"; import Readme from "./README.md"; import IconTemplate from "./examples/icon-with-text.marko"; import IconTemplateCode from "./examples/icon-with-text.marko?raw"; @@ -12,8 +12,10 @@ import SeparatorTemplate from "./examples/separator.marko"; import SeparatorTemplateCode from "./examples/separator.marko?raw"; import Component from "./index.marko"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -211,7 +213,7 @@ Standard.args = { renderBody: `item 3`, href: "https://www.ebay.com", }, - ], + ] as any, text: `eBay Menu`, }; Standard.parameters = { diff --git a/src/components/ebay-fake-menu/fake-menu.stories.ts b/src/components/ebay-fake-menu/fake-menu.stories.ts index 6ecf44c6a..eabe30c78 100644 --- a/src/components/ebay-fake-menu/fake-menu.stories.ts +++ b/src/components/ebay-fake-menu/fake-menu.stories.ts @@ -1,8 +1,8 @@ import { addRenderBodies, buildExtensionTemplate, -} from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +} from "../../common/storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; import Component from "./index.marko"; import ItemMatchesTemplate from "./examples/item-matches-url.marko"; @@ -11,8 +11,10 @@ import SpritesTemplate from "./examples/sprites.marko"; import SpritesTemplateCode from "./examples/sprites.marko?raw"; import SeparatorTemplate from "./examples/separator.marko"; import SeparatorTemplateCode from "./examples/separator.marko?raw"; +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -142,7 +144,7 @@ Standard.args = { renderBody: `item 3`, href: "https://www.ebay.com", }, - ], + ] as any, }; Standard.parameters = { docs: { diff --git a/src/components/ebay-fake-tabs/fake-tabs.stories.ts b/src/components/ebay-fake-tabs/fake-tabs.stories.ts index f8c402285..3aa653d18 100644 --- a/src/components/ebay-fake-tabs/fake-tabs.stories.ts +++ b/src/components/ebay-fake-tabs/fake-tabs.stories.ts @@ -1,9 +1,10 @@ -import { addRenderBodies } from "../../../.storybook/utils"; -import { tagToString } from "../../../.storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; +import { tagToString } from "../../common/storybook/storybook-code-source"; import Readme from "./README.md"; -import Component from "./index.marko"; +import Component, { type Input } from "./index.marko"; +import { Story } from "@storybook/marko"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -61,7 +62,7 @@ Standard.args = { }, ], renderBody: `Lorum ipsom dolor`, -}; +} as any; Standard.parameters = { docs: { source: { diff --git a/src/components/ebay-file-input/examples/with-mock-uploads.marko b/src/components/ebay-file-input/examples/with-mock-uploads.marko index a7f56a779..59dd08444 100644 --- a/src/components/ebay-file-input/examples/with-mock-uploads.marko +++ b/src/components/ebay-file-input/examples/with-mock-uploads.marko @@ -1,4 +1,4 @@ -import type { FileInputEvent } from "../component-browser"; +import type { FileInputEvent } from "../component"; static async function mockFetch() { await new Promise((resolve) => setTimeout(resolve, Math.random() * 5000)); return `https://fakeurl.com/${Math.random().toString(36).substring(7)}`; diff --git a/src/components/ebay-file-input/examples/with-preview-cards.marko b/src/components/ebay-file-input/examples/with-preview-cards.marko index 381e231fa..e711bd654 100644 --- a/src/components/ebay-file-input/examples/with-preview-cards.marko +++ b/src/components/ebay-file-input/examples/with-preview-cards.marko @@ -1,4 +1,4 @@ -import type { FileInputEvent } from "../component-browser"; +import type { FileInputEvent } from "../component"; class { declare state: { files: File[]; diff --git a/src/components/ebay-file-input/file-input.stories.ts b/src/components/ebay-file-input/file-input.stories.ts index 2349ff46d..b1cf5149f 100644 --- a/src/components/ebay-file-input/file-input.stories.ts +++ b/src/components/ebay-file-input/file-input.stories.ts @@ -1,5 +1,3 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; import Readme from "./README.md"; import component from "./index.marko"; import DefaultTemplate from "./examples/default.marko"; @@ -8,10 +6,8 @@ import WithPreviewCardsTemplate from "./examples/with-preview-cards.marko"; import WithPreviewCardsCode from "./examples/with-preview-cards.marko?raw"; import WithMockUploadsTemplate from "./examples/with-mock-uploads.marko"; import WithMockUploadsCode from "./examples/with-mock-uploads.marko?raw"; - -const Template = (args) => ({ - input: addRenderBodies(args), -}); +import { Story } from "@storybook/marko"; +import type { Input } from "./component"; export default { title: "form input/ebay-file-input", @@ -57,7 +53,7 @@ export default { }, }; -export const Default = (args) => ({ +export const Default: Story = (args) => ({ input: args, component: DefaultTemplate, }); @@ -73,7 +69,7 @@ Default.parameters = { }, }; -export const WithPreviewCards = (args) => ({ +export const WithPreviewCards: Story = (args) => ({ input: args, component: WithPreviewCardsTemplate, }); @@ -89,7 +85,7 @@ WithPreviewCards.parameters = { }, }; -export const WithMockUploads = (args) => ({ +export const WithMockUploads: Story = (args) => ({ input: args, component: WithMockUploadsTemplate, }); diff --git a/src/components/ebay-file-preview-card-group/file-preview-card-group.stories.ts b/src/components/ebay-file-preview-card-group/file-preview-card-group.stories.ts index 64d3585a1..4f21c03ba 100644 --- a/src/components/ebay-file-preview-card-group/file-preview-card-group.stories.ts +++ b/src/components/ebay-file-preview-card-group/file-preview-card-group.stories.ts @@ -1,9 +1,10 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import component from "./index.marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -104,7 +105,7 @@ Default.args = { { file: { ...frogImage }, }, - ], + ] as any, }; export const ManyCards = Template.bind({}); @@ -113,5 +114,5 @@ ManyCards.args = { deleteText: "Delete", card: [...Array(35)].map(() => ({ file: { ...frogImage }, - })), + })) as any, }; diff --git a/src/components/ebay-file-preview-card/file-preview-card.stories.ts b/src/components/ebay-file-preview-card/file-preview-card.stories.ts index e2b4ee8c7..e5333bbac 100644 --- a/src/components/ebay-file-preview-card/file-preview-card.stories.ts +++ b/src/components/ebay-file-preview-card/file-preview-card.stories.ts @@ -1,9 +1,11 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { addRenderBodies } from "../../common/storybook/utils"; import Readme from "./README.md"; import component from "./index.marko"; +import type { Input } from "./component"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -166,7 +168,7 @@ Video.args = { src: "https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4", }, labelText: "10:30:21", -}; +} as any; Video.parameters = { docs: { diff --git a/src/components/ebay-filter-menu-button/component.ts b/src/components/ebay-filter-menu-button/component.ts index cabc4713e..d318eed07 100644 --- a/src/components/ebay-filter-menu-button/component.ts +++ b/src/components/ebay-filter-menu-button/component.ts @@ -34,11 +34,15 @@ interface FilterMenuButtonInput "form-method"?: string; disabled?: boolean; "a11y-text"?: AttrString; + "search-header-value"?: string; + "search-header-placeholder-text"?: AttrString; + "a11y-search-header-clear-text"?: AttrString; "on-expand"?: () => void; "on-change"?: (event: FilterMenuButtonEvent) => void; "on-collapse"?: (event: FilterMenuButtonEvent) => void; "on-footer-click"?: (event: FilterMenuButtonEvent) => void; "on-form-submit"?: (event: FilterMenuButtonEvent) => void; + "on-search-change"?: (value: string) => void; } export interface Input extends WithNormalizedProps {} diff --git a/src/components/ebay-filter-menu-button/examples/data.json b/src/components/ebay-filter-menu-button/examples/data.json new file mode 100644 index 000000000..6de354b55 --- /dev/null +++ b/src/components/ebay-filter-menu-button/examples/data.json @@ -0,0 +1,974 @@ +[ + { + "name": "Afghanistan", + "code": "AF" + }, + { + "name": "Ã…landIslands", + "code": "AX" + }, + { + "name": "Albania", + "code": "AL" + }, + { + "name": "Algeria", + "code": "DZ" + }, + { + "name": "AmericanSamoa", + "code": "AS" + }, + { + "name": "AndorrA", + "code": "AD" + }, + { + "name": "Angola", + "code": "AO" + }, + { + "name": "Anguilla", + "code": "AI" + }, + { + "name": "Antarctica", + "code": "AQ" + }, + { + "name": "Antiguaand Barbuda", + "code": "AG" + }, + { + "name": "Argentina", + "code": "AR" + }, + { + "name": "Armenia", + "code": "AM" + }, + { + "name": "Aruba", + "code": "AW" + }, + { + "name": "Australia", + "code": "AU" + }, + { + "name": "Austria", + "code": "AT" + }, + { + "name": "Azerbaijan", + "code": "AZ" + }, + { + "name": "Bahamas", + "code": "BS" + }, + { + "name": "Bahrain", + "code": "BH" + }, + { + "name": "Bangladesh", + "code": "BD" + }, + { + "name": "Barbados", + "code": "BB" + }, + { + "name": "Belarus", + "code": "BY" + }, + { + "name": "Belgium", + "code": "BE" + }, + { + "name": "Belize", + "code": "BZ" + }, + { + "name": "Benin", + "code": "BJ" + }, + { + "name": "Bermuda", + "code": "BM" + }, + { + "name": "Bhutan", + "code": "BT" + }, + { + "name": "Bolivia", + "code": "BO" + }, + { + "name": "Bosniaand Herzegovina", + "code": "BA" + }, + { + "name": "Botswana", + "code": "BW" + }, + { + "name": "BouvetIsland", + "code": "BV" + }, + { + "name": "Brazil", + "code": "BR" + }, + { + "name": "BritishIndian Ocean Territory", + "code": "IO" + }, + { + "name": "BruneiDarussalam", + "code": "BN" + }, + { + "name": "Bulgaria", + "code": "BG" + }, + { + "name": "BurkinaFaso", + "code": "BF" + }, + { + "name": "Burundi", + "code": "BI" + }, + { + "name": "Cambodia", + "code": "KH" + }, + { + "name": "Cameroon", + "code": "CM" + }, + { + "name": "Canada", + "code": "CA" + }, + { + "name": "CapeVerde", + "code": "CV" + }, + { + "name": "CaymanIslands", + "code": "KY" + }, + { + "name": "CentralAfrican Republic", + "code": "CF" + }, + { + "name": "Chad", + "code": "TD" + }, + { + "name": "Chile", + "code": "CL" + }, + { + "name": "China", + "code": "CN" + }, + { + "name": "ChristmasIsland", + "code": "CX" + }, + { + "name": "Cocos(Keeling) Islands", + "code": "CC" + }, + { + "name": "Colombia", + "code": "CO" + }, + { + "name": "Comoros", + "code": "KM" + }, + { + "name": "Congo", + "code": "CG" + }, + { + "name": "Congo The Democratic Republic of the", + "code": "CD" + }, + { + "name": "CookIslands", + "code": "CK" + }, + { + "name": "CostaRica", + "code": "CR" + }, + { + "name": "CoteD'Ivoire", + "code": "CI" + }, + { + "name": "Croatia", + "code": "HR" + }, + { + "name": "Cuba", + "code": "CU" + }, + { + "name": "Cyprus", + "code": "CY" + }, + { + "name": "CzechRepublic", + "code": "CZ" + }, + { + "name": "Denmark", + "code": "DK" + }, + { + "name": "Djibouti", + "code": "DJ" + }, + { + "name": "Dominica", + "code": "DM" + }, + { + "name": "DominicanRepublic", + "code": "DO" + }, + { + "name": "Ecuador", + "code": "EC" + }, + { + "name": "Egypt", + "code": "EG" + }, + { + "name": "ElSalvador", + "code": "SV" + }, + { + "name": "EquatorialGuinea", + "code": "GQ" + }, + { + "name": "Eritrea", + "code": "ER" + }, + { + "name": "Estonia", + "code": "EE" + }, + { + "name": "Ethiopia", + "code": "ET" + }, + { + "name": "FalklandIslands (Malvinas)", + "code": "FK" + }, + { + "name": "FaroeIslands", + "code": "FO" + }, + { + "name": "Fiji", + "code": "FJ" + }, + { + "name": "Finland", + "code": "FI" + }, + { + "name": "France", + "code": "FR" + }, + { + "name": "FrenchGuiana", + "code": "GF" + }, + { + "name": "FrenchPolynesia", + "code": "PF" + }, + { + "name": "FrenchSouthern Territories", + "code": "TF" + }, + { + "name": "Gabon", + "code": "GA" + }, + { + "name": "Gambia", + "code": "GM" + }, + { + "name": "Georgia", + "code": "GE" + }, + { + "name": "Germany", + "code": "DE" + }, + { + "name": "Ghana", + "code": "GH" + }, + { + "name": "Gibraltar", + "code": "GI" + }, + { + "name": "Greece", + "code": "GR" + }, + { + "name": "Greenland", + "code": "GL" + }, + { + "name": "Grenada", + "code": "GD" + }, + { + "name": "Guadeloupe", + "code": "GP" + }, + { + "name": "Guam", + "code": "GU" + }, + { + "name": "Guatemala", + "code": "GT" + }, + { + "name": "Guernsey", + "code": "GG" + }, + { + "name": "Guinea", + "code": "GN" + }, + { + "name": "GuineaBissau", + "code": "GW" + }, + { + "name": "Guyana", + "code": "GY" + }, + { + "name": "Haiti", + "code": "HT" + }, + { + "name": "HeardIsland and Mcdonald Islands", + "code": "HM" + }, + { + "name": "HolySee (Vatican City State)", + "code": "VA" + }, + { + "name": "Honduras", + "code": "HN" + }, + { + "name": "HongKong", + "code": "HK" + }, + { + "name": "Hungary", + "code": "HU" + }, + { + "name": "Iceland", + "code": "IS" + }, + { + "name": "India", + "code": "IN" + }, + { + "name": "Indonesia", + "code": "ID" + }, + { + "name": "Iran Islamic Republic Of", + "code": "IR" + }, + { + "name": "Iraq", + "code": "IQ" + }, + { + "name": "Ireland", + "code": "IE" + }, + { + "name": "Isleof Man", + "code": "IM" + }, + { + "name": "Israel", + "code": "IL" + }, + { + "name": "Italy", + "code": "IT" + }, + { + "name": "Jamaica", + "code": "JM" + }, + { + "name": "Japan", + "code": "JP" + }, + { + "name": "Jersey", + "code": "JE" + }, + { + "name": "Jordan", + "code": "JO" + }, + { + "name": "Kazakhstan", + "code": "KZ" + }, + { + "name": "Kenya", + "code": "KE" + }, + { + "name": "Kiribati", + "code": "KI" + }, + { + "name": "Korea Democratic People'S Republic of", + "code": "KP" + }, + { + "name": "Korea Republic of", + "code": "KR" + }, + { + "name": "Kuwait", + "code": "KW" + }, + { + "name": "Kyrgyzstan", + "code": "KG" + }, + { + "name": "LaoPeopleS Democratic Republic", + "code": "LA" + }, + { + "name": "Latvia", + "code": "LV" + }, + { + "name": "Lebanon", + "code": "LB" + }, + { + "name": "Lesotho", + "code": "LS" + }, + { + "name": "Liberia", + "code": "LR" + }, + { + "name": "LibyanArab Jamahiriya", + "code": "LY" + }, + { + "name": "Liechtenstein", + "code": "LI" + }, + { + "name": "Lithuania", + "code": "LT" + }, + { + "name": "Luxembourg", + "code": "LU" + }, + { + "name": "Macao", + "code": "MO" + }, + { + "name": "Macedonia The Former Yugoslav Republic of", + "code": "MK" + }, + { + "name": "Madagascar", + "code": "MG" + }, + { + "name": "Malawi", + "code": "MW" + }, + { + "name": "Malaysia", + "code": "MY" + }, + { + "name": "Maldives", + "code": "MV" + }, + { + "name": "Mali", + "code": "ML" + }, + { + "name": "Malta", + "code": "MT" + }, + { + "name": "MarshallIslands", + "code": "MH" + }, + { + "name": "Martinique", + "code": "MQ" + }, + { + "name": "Mauritania", + "code": "MR" + }, + { + "name": "Mauritius", + "code": "MU" + }, + { + "name": "Mayotte", + "code": "YT" + }, + { + "name": "Mexico", + "code": "MX" + }, + { + "name": "Micronesia Federated States of", + "code": "FM" + }, + { + "name": "Moldova Republic of", + "code": "MD" + }, + { + "name": "Monaco", + "code": "MC" + }, + { + "name": "Mongolia", + "code": "MN" + }, + { + "name": "Montserrat", + "code": "MS" + }, + { + "name": "Morocco", + "code": "MA" + }, + { + "name": "Mozambique", + "code": "MZ" + }, + { + "name": "Myanmar", + "code": "MM" + }, + { + "name": "Namibia", + "code": "NA" + }, + { + "name": "Nauru", + "code": "NR" + }, + { + "name": "Nepal", + "code": "NP" + }, + { + "name": "Netherlands", + "code": "NL" + }, + { + "name": "NetherlandsAntilles", + "code": "AN" + }, + { + "name": "NewCaledonia", + "code": "NC" + }, + { + "name": "NewZealand", + "code": "NZ" + }, + { + "name": "Nicaragua", + "code": "NI" + }, + { + "name": "Niger", + "code": "NE" + }, + { + "name": "Nigeria", + "code": "NG" + }, + { + "name": "Niue", + "code": "NU" + }, + { + "name": "NorfolkIsland", + "code": "NF" + }, + { + "name": "NorthernMariana Islands", + "code": "MP" + }, + { + "name": "Norway", + "code": "NO" + }, + { + "name": "Oman", + "code": "OM" + }, + { + "name": "Pakistan", + "code": "PK" + }, + { + "name": "Palau", + "code": "PW" + }, + { + "name": "PalestinianTerritory Occupied", + "code": "PS" + }, + { + "name": "Panama", + "code": "PA" + }, + { + "name": "PapuaNew Guinea", + "code": "PG" + }, + { + "name": "Paraguay", + "code": "PY" + }, + { + "name": "Peru", + "code": "PE" + }, + { + "name": "Philippines", + "code": "PH" + }, + { + "name": "Pitcairn", + "code": "PN" + }, + { + "name": "Poland", + "code": "PL" + }, + { + "name": "Portugal", + "code": "PT" + }, + { + "name": "PuertoRico", + "code": "PR" + }, + { + "name": "Qatar", + "code": "QA" + }, + { + "name": "Reunion", + "code": "RE" + }, + { + "name": "Romania", + "code": "RO" + }, + { + "name": "RussianFederation", + "code": "RU" + }, + { + "name": "RWANDA", + "code": "RW" + }, + { + "name": "SaintHelena", + "code": "SH" + }, + { + "name": "SaintKitts and Nevis", + "code": "KN" + }, + { + "name": "SaintLucia", + "code": "LC" + }, + { + "name": "SaintPierre and Miquelon", + "code": "PM" + }, + { + "name": "SaintVincent and the Grenadines", + "code": "VC" + }, + { + "name": "Samoa", + "code": "WS" + }, + { + "name": "SanMarino", + "code": "SM" + }, + { + "name": "SaoTome and Principe", + "code": "ST" + }, + { + "name": "SaudiArabia", + "code": "SA" + }, + { + "name": "Senegal", + "code": "SN" + }, + { + "name": "Serbiaand Montenegro", + "code": "CS" + }, + { + "name": "Seychelles", + "code": "SC" + }, + { + "name": "SierraLeone", + "code": "SL" + }, + { + "name": "Singapore", + "code": "SG" + }, + { + "name": "Slovakia", + "code": "SK" + }, + { + "name": "Slovenia", + "code": "SI" + }, + { + "name": "SolomonIslands", + "code": "SB" + }, + { + "name": "Somalia", + "code": "SO" + }, + { + "name": "SouthAfrica", + "code": "ZA" + }, + { + "name": "SouthGeorgia and the South Sandwich Islands", + "code": "GS" + }, + { + "name": "Spain", + "code": "ES" + }, + { + "name": "SriLanka", + "code": "LK" + }, + { + "name": "Sudan", + "code": "SD" + }, + { + "name": "Suriname", + "code": "SR" + }, + { + "name": "Svalbardand Jan Mayen", + "code": "SJ" + }, + { + "name": "Swaziland", + "code": "SZ" + }, + { + "name": "Sweden", + "code": "SE" + }, + { + "name": "Switzerland", + "code": "CH" + }, + { + "name": "SyrianArab Republic", + "code": "SY" + }, + { + "name": "Taiwan Province of China", + "code": "TW" + }, + { + "name": "Tajikistan", + "code": "TJ" + }, + { + "name": "Tanzania United Republic of", + "code": "TZ" + }, + { + "name": "Thailand", + "code": "TH" + }, + { + "name": "TimorLeste", + "code": "TL" + }, + { + "name": "Togo", + "code": "TG" + }, + { + "name": "Tokelau", + "code": "TK" + }, + { + "name": "Tonga", + "code": "TO" + }, + { + "name": "Trinidadand Tobago", + "code": "TT" + }, + { + "name": "Tunisia", + "code": "TN" + }, + { + "name": "Turkey", + "code": "TR" + }, + { + "name": "Turkmenistan", + "code": "TM" + }, + { + "name": "Turksand Caicos Islands", + "code": "TC" + }, + { + "name": "Tuvalu", + "code": "TV" + }, + { + "name": "Uganda", + "code": "UG" + }, + { + "name": "Ukraine", + "code": "UA" + }, + { + "name": "UnitedArab Emirates", + "code": "AE" + }, + { + "name": "UnitedKingdom", + "code": "GB" + }, + { + "name": "United States", + "code": "US" + }, + { + "name": "United States Minor Outlying Islands", + "code": "UM" + }, + { + "name": "Uruguay", + "code": "UY" + }, + { + "name": "Uzbekistan", + "code": "UZ" + }, + { + "name": "Vanuatu", + "code": "VU" + }, + { + "name": "Venezuela", + "code": "VE" + }, + { + "name": "VietNam", + "code": "VN" + }, + { + "name": "VirginIslands British", + "code": "VG" + }, + { + "name": "VirginIslands U.S.", + "code": "VI" + }, + { + "name": "Wallisand Futuna", + "code": "WF" + }, + { + "name": "WesternSahara", + "code": "EH" + }, + { + "name": "Yemen", + "code": "YE" + }, + { + "name": "Zambia", + "code": "ZM" + }, + { + "name": "Zimbabwe", + "code": "ZW" + } +] diff --git a/src/components/ebay-filter-menu-button/examples/with-search.marko b/src/components/ebay-filter-menu-button/examples/with-search.marko new file mode 100644 index 000000000..68bdd9152 --- /dev/null +++ b/src/components/ebay-filter-menu-button/examples/with-search.marko @@ -0,0 +1,48 @@ +import countries from "./data.json"; +import type { Input as FilterMenuButtonInput } from ""; +class { + declare state: { + checkedCodes: { [code: string]: boolean }; + visibleCountries: typeof countries; + }; + + onCreate() { + this.state = { + checkedCodes: {}, + visibleCountries: countries, + }; + } + + handleSearchChange(value: string) { + const searchTerm = value.toLowerCase(); + this.state.visibleCountries = countries.filter(({ name }) => + name.toLowerCase().includes(searchTerm), + ); + } + + handleChange({ + index, + currentChecked, + }: Parameters>[0]) { + if (index === undefined) return; + this.state.checkedCodes = { + ...this.state.checkedCodes, + [this.state.visibleCountries[index].code]: !!currentChecked, + }; + } +} + + + + <@item value=code checked=state.checkedCodes[code]> + ${name} + + + diff --git a/src/components/ebay-filter-menu-button/filter-menu-button.stories.ts b/src/components/ebay-filter-menu-button/filter-menu-button.stories.ts index 62c60bd88..a7eac7723 100644 --- a/src/components/ebay-filter-menu-button/filter-menu-button.stories.ts +++ b/src/components/ebay-filter-menu-button/filter-menu-button.stories.ts @@ -1,9 +1,16 @@ -import { tagToString } from "../../../.storybook/storybook-code-source"; -import { addRenderBodies } from "../../../.storybook/utils"; +import { Story } from "@storybook/marko"; +import { tagToString } from "../../common/storybook/storybook-code-source"; +import { + addRenderBodies, + buildExtensionTemplate, +} from "../../common/storybook/utils"; import Readme from "./README.md"; import Component from "./index.marko"; +import type { Input } from "./component"; +import WithSearchTemplate from "./examples/with-search.marko"; +import WithSearchCode from "./examples/with-search.marko?raw"; -const Template = (args) => ({ +const Template: Story = (args) => ({ input: addRenderBodies(args), }); @@ -61,6 +68,20 @@ export default { category: "@attribute tags", }, }, + searchHeaderValue: { + control: { type: "text" }, + description: + "optional value override for the input in the search header", + }, + searchHeaderPlaceholderText: { + control: { type: "text" }, + description: + "enables the search header and populates placeholder text. `a11y-search-header-clear-text` is required if this is enabled.", + }, + a11ySearchHeaderClearText: { + control: { type: "text" }, + description: "a11y text for the search header clear button", + }, formName: { control: { type: "text" }, description: "forms `name` attribute", @@ -90,6 +111,12 @@ export default { description: "the items value (returned in emitted events when checked)", }, + footer: { + name: "@footer", + table: { + category: "@attribute tags", + }, + }, onCollapse: { action: "on-collapse", description: "Triggered on menu collapse", @@ -120,7 +147,7 @@ export default { }, }, }, - footerClick: { + "onFooter-click": { action: "on-footer-click", description: "Triggered on footer clicked", table: { @@ -130,7 +157,7 @@ export default { }, }, }, - formSubmit: { + "onForm-submit": { action: "on-form-submit", description: 'when using `variant="form"`, and form is submitted (emits current checked state)', @@ -141,10 +168,14 @@ export default { }, }, }, - footer: { - name: "@footer", + "onSearch-change": { + action: "on-search-change", + description: "Triggered when the search input updates", table: { - category: "@attribute tags", + category: "Events", + defaultValue: { + summary: "{ checked, originalEvent }", + }, }, }, }, @@ -168,7 +199,7 @@ Default.args = { }, ], a11yText: "filter menu button a11y text", -}; +} as any; Default.parameters = { docs: { source: { @@ -199,7 +230,7 @@ WithFooter.args = { renderBody: "Apply", a11yFooterText: "footer button a11y text", }, -}; +} as any; WithFooter.parameters = { docs: { source: { @@ -207,3 +238,9 @@ WithFooter.parameters = { }, }, }; + +export const WithSearch = buildExtensionTemplate( + WithSearchTemplate, + WithSearchCode, + {}, +); diff --git a/src/components/ebay-filter-menu-button/index.marko b/src/components/ebay-filter-menu-button/index.marko index 668f648cd..7527a1551 100644 --- a/src/components/ebay-filter-menu-button/index.marko +++ b/src/components/ebay-filter-menu-button/index.marko @@ -13,6 +13,9 @@ $ const { formAction, formMethod, items, + searchHeaderValue, + searchHeaderPlaceholderText, + a11ySearchHeaderClearText, type: inputType, ...htmlInput } = input; @@ -46,10 +49,14 @@ $ const { formMethod=formMethod footerText=footerText a11yFooterText=a11yFooterText + searchHeaderValue=searchHeaderValue + searchHeaderPlaceholderText=searchHeaderPlaceholderText + a11ySearchHeaderClearText=a11ySearchHeaderClearText on-keydown("handleMenuKeydown") on-change("handleMenuChange") on-form-submit("handleFormSubmit") - on-footer-click("handleFooterButtonClick")> + on-footer-click("handleFooterButtonClick") + on-search-change("emit", "search-change")> <@item ...item checked=component.isChecked(i)/> diff --git a/src/components/ebay-filter-menu-button/test/__snapshots__/test.server.js.snap b/src/components/ebay-filter-menu-button/test/__snapshots__/test.server.js.snap index c99fb3229..c91cb3ecd 100644 --- a/src/components/ebay-filter-menu-button/test/__snapshots__/test.server.js.snap +++ b/src/components/ebay-filter-menu-button/test/__snapshots__/test.server.js.snap @@ -49,9 +49,10 @@ exports[`filter-menu > passes through additional html attributes 1`] = ` - +