From 58d263e3042a185671f3f93c8545be9249598045 Mon Sep 17 00:00:00 2001 From: Alexandra Turian Date: Wed, 30 Aug 2023 20:34:16 +0300 Subject: [PATCH 01/13] feat(steps): add stepper and step-item components --- packages/beeq/src/components.d.ts | 101 ++++++++++++ packages/beeq/src/components/avatar/readme.md | 13 ++ .../beeq/src/components/divider/readme.md | 13 ++ packages/beeq/src/components/icon/readme.md | 2 + .../step-item/__tests__/bq-step-item.e2e.ts | 52 ++++++ .../src/components/step-item/bq-step-item.tsx | 152 ++++++++++++++++++ .../step-item/bq-step-item.types.ts | 2 + .../beeq/src/components/step-item/readme.md | 55 +++++++ .../scss/bq-step-item-variables.scss | 7 + .../step-item/scss/bq-step-item.scss | 65 ++++++++ .../steps/__tests__/bq-steps.e2e.ts | 30 ++++ .../components/steps/_storybook/bq-steps.mdx | 15 ++ .../steps/_storybook/bq-steps.stories.tsx | 57 +++++++ .../beeq/src/components/steps/bq-steps.tsx | 96 +++++++++++ .../src/components/steps/bq-steps.types.ts | 5 + packages/beeq/src/components/steps/readme.md | 32 ++++ .../steps/scss/bq-steps-variables.scss | 7 + .../src/components/steps/scss/bq-steps.scss | 9 ++ 18 files changed, 713 insertions(+) create mode 100644 packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts create mode 100644 packages/beeq/src/components/step-item/bq-step-item.tsx create mode 100644 packages/beeq/src/components/step-item/bq-step-item.types.ts create mode 100644 packages/beeq/src/components/step-item/readme.md create mode 100644 packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss create mode 100644 packages/beeq/src/components/step-item/scss/bq-step-item.scss create mode 100644 packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts create mode 100644 packages/beeq/src/components/steps/_storybook/bq-steps.mdx create mode 100644 packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx create mode 100644 packages/beeq/src/components/steps/bq-steps.tsx create mode 100644 packages/beeq/src/components/steps/bq-steps.types.ts create mode 100644 packages/beeq/src/components/steps/readme.md create mode 100644 packages/beeq/src/components/steps/scss/bq-steps-variables.scss create mode 100644 packages/beeq/src/components/steps/scss/bq-steps.scss diff --git a/packages/beeq/src/components.d.ts b/packages/beeq/src/components.d.ts index af32fcc8e..08d07dee8 100644 --- a/packages/beeq/src/components.d.ts +++ b/packages/beeq/src/components.d.ts @@ -19,6 +19,8 @@ import { TSideMenuAppearance, TSideMenuSize } from "./components/side-menu/bq-si import { TSliderType } from "./components/slider/bq-slider.types"; import { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spinner.types"; import { TStatusType } from "./components/status/bq-status.types"; +import { TStepsSize, TStepsType } from "./components/steps/bq-steps.types"; +import { TStepItemStatus } from "./components/step-item/bq-step-item.types"; import { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types"; import { TTabSize } from "./components/tab/bq-tab.types"; import { TTextareaAutoCapitalize, TTextareaWrap } from "./components/textarea/bq-textarea.types"; @@ -37,6 +39,8 @@ export { TSideMenuAppearance, TSideMenuSize } from "./components/side-menu/bq-si export { TSliderType } from "./components/slider/bq-slider.types"; export { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spinner.types"; export { TStatusType } from "./components/status/bq-status.types"; +export { TStepsSize, TStepsType } from "./components/steps/bq-steps.types"; +export { TStepItemStatus } from "./components/step-item/bq-step-item.types"; export { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types"; export { TTabSize } from "./components/tab/bq-tab.types"; export { TTextareaAutoCapitalize, TTextareaWrap } from "./components/textarea/bq-textarea.types"; @@ -769,6 +773,39 @@ export namespace Components { */ "type": TStatusType; } + interface BqStepItem { + /** + * It defines whether this step item is last in stepper + */ + "isLast"?: boolean; + /** + * Step number + */ + "number"?: number; + /** + * It defines prefix size + */ + "size"?: TStepsSize; + /** + * It defines step item appearance based on its status + */ + "status"?: TStepItemStatus; + /** + * It defines the type of steps + */ + "type": TStepsType; + /** + * Step value + */ + "value"?: string; + } + interface BqSteps { + "size": TStepsSize; + /** + * It defines the type of steps + */ + "type": TStepsType; + } /** * Toggle switches are digital on/off switches. * They should provide immediate results, giving users the freedom to control their preferences as needed. @@ -1096,6 +1133,14 @@ export interface BqSliderCustomEvent extends CustomEvent { detail: T; target: HTMLBqSliderElement; } +export interface BqStepItemCustomEvent extends CustomEvent { + detail: T; + target: HTMLBqStepItemElement; +} +export interface BqStepsCustomEvent extends CustomEvent { + detail: T; + target: HTMLBqStepsElement; +} export interface BqSwitchCustomEvent extends CustomEvent { detail: T; target: HTMLBqSwitchElement; @@ -1270,6 +1315,18 @@ declare global { prototype: HTMLBqStatusElement; new (): HTMLBqStatusElement; }; + interface HTMLBqStepItemElement extends Components.BqStepItem, HTMLStencilElement { + } + var HTMLBqStepItemElement: { + prototype: HTMLBqStepItemElement; + new (): HTMLBqStepItemElement; + }; + interface HTMLBqStepsElement extends Components.BqSteps, HTMLStencilElement { + } + var HTMLBqStepsElement: { + prototype: HTMLBqStepsElement; + new (): HTMLBqStepsElement; + }; /** * Toggle switches are digital on/off switches. * They should provide immediate results, giving users the freedom to control their preferences as needed. @@ -1335,6 +1392,8 @@ declare global { "bq-slider": HTMLBqSliderElement; "bq-spinner": HTMLBqSpinnerElement; "bq-status": HTMLBqStatusElement; + "bq-step-item": HTMLBqStepItemElement; + "bq-steps": HTMLBqStepsElement; "bq-switch": HTMLBqSwitchElement; "bq-tab": HTMLBqTabElement; "bq-tab-group": HTMLBqTabGroupElement; @@ -2211,6 +2270,44 @@ declare namespace LocalJSX { */ "type"?: TStatusType; } + interface BqStepItem { + /** + * It defines whether this step item is last in stepper + */ + "isLast"?: boolean; + /** + * Step number + */ + "number"?: number; + "onBqClick"?: (event: BqStepItemCustomEvent<{ target: HTMLBqStepItemElement; value: string }>) => void; + /** + * It defines prefix size + */ + "size"?: TStepsSize; + /** + * It defines step item appearance based on its status + */ + "status"?: TStepItemStatus; + /** + * It defines the type of steps + */ + "type"?: TStepsType; + /** + * Step value + */ + "value"?: string; + } + interface BqSteps { + /** + * Handler to be called when the tab value changes + */ + "onBqChange"?: (event: BqStepsCustomEvent<{ target: HTMLBqStepItemElement; value: string }>) => void; + "size"?: TStepsSize; + /** + * It defines the type of steps + */ + "type"?: TStepsType; + } /** * Toggle switches are digital on/off switches. * They should provide immediate results, giving users the freedom to control their preferences as needed. @@ -2506,6 +2603,8 @@ declare namespace LocalJSX { "bq-slider": BqSlider; "bq-spinner": BqSpinner; "bq-status": BqStatus; + "bq-step-item": BqStepItem; + "bq-steps": BqSteps; "bq-switch": BqSwitch; "bq-tab": BqTab; "bq-tab-group": BqTabGroup; @@ -2551,6 +2650,8 @@ declare module "@stencil/core" { */ "bq-spinner": LocalJSX.BqSpinner & JSXBase.HTMLAttributes; "bq-status": LocalJSX.BqStatus & JSXBase.HTMLAttributes; + "bq-step-item": LocalJSX.BqStepItem & JSXBase.HTMLAttributes; + "bq-steps": LocalJSX.BqSteps & JSXBase.HTMLAttributes; /** * Toggle switches are digital on/off switches. * They should provide immediate results, giving users the freedom to control their preferences as needed. diff --git a/packages/beeq/src/components/avatar/readme.md b/packages/beeq/src/components/avatar/readme.md index 1bde16bc0..4b8f7bac9 100644 --- a/packages/beeq/src/components/avatar/readme.md +++ b/packages/beeq/src/components/avatar/readme.md @@ -26,6 +26,19 @@ | `"text"` | The `` tag element that renderd the `Initials` text string. | +## Dependencies + +### Used by + + - [bq-step-item](../step-item) + +### Graph +```mermaid +graph TD; + bq-step-item --> bq-avatar + style bq-avatar fill:#f9f,stroke:#333,stroke-width:4px +``` + ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/divider/readme.md b/packages/beeq/src/components/divider/readme.md index 7e8f860f9..a2f606f62 100644 --- a/packages/beeq/src/components/divider/readme.md +++ b/packages/beeq/src/components/divider/readme.md @@ -29,6 +29,19 @@ | `"dash-start-line"` | The component's internal line component of the divider's stroke | +## Dependencies + +### Used by + + - [bq-step-item](../step-item) + +### Graph +```mermaid +graph TD; + bq-step-item --> bq-divider + style bq-divider fill:#f9f,stroke:#333,stroke-width:4px +``` + ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/icon/readme.md b/packages/beeq/src/components/icon/readme.md index 50aebeec8..156d36224 100644 --- a/packages/beeq/src/components/icon/readme.md +++ b/packages/beeq/src/components/icon/readme.md @@ -41,6 +41,7 @@ Icons are simplified images that graphically explain the meaning of an object on - [bq-input](../input) - [bq-notification](../notification) - [bq-select](../select) + - [bq-step-item](../step-item) - [bq-switch](../switch) - [bq-toast](../toast) @@ -52,6 +53,7 @@ graph TD; bq-input --> bq-icon bq-notification --> bq-icon bq-select --> bq-icon + bq-step-item --> bq-icon bq-switch --> bq-icon bq-toast --> bq-icon style bq-icon fill:#f9f,stroke:#333,stroke-width:4px diff --git a/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts b/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts new file mode 100644 index 000000000..bf34f8b32 --- /dev/null +++ b/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts @@ -0,0 +1,52 @@ +import { newE2EPage } from '@stencil/core/testing'; + +describe('bq-step-item', () => { + it('should render', async () => { + const page = await newE2EPage(); + await page.setContent(''); + + const element = await page.find('bq-step-item'); + + expect(element).toHaveClass('hydrated'); + }); + + it('should have shadow root', async () => { + const page = await newE2EPage(); + await page.setContent(''); + + const element = await page.find('bq-step-item'); + + expect(element.shadowRoot).not.toBeNull(); + }); + + it('should display text', async () => { + const page = await newE2EPage(); + await page.setContent('

step item 1

'); + + // const element = await page.find('bq-step-item >>> p'); + const text = await page.$eval('bq-step-item', (element) => { + const slotElement = element.shadowRoot.querySelector('slot'); + const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; + + return assignedElements.textContent; + }); + + expect(text).toEqualText('step item 1'); + }); + + it('should display icon prefix', async () => { + const page = await newE2EPage(); + await page.setContent( + ' step item 1description for step', + ); + + const prefix = await page.$eval('bq-step-item', (element) => { + const slotElement = element.shadowRoot.querySelector('slot[name="prefix"]'); + const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; + + return assignedElements.tagName; + }); + + expect(prefix).toMatch(/bq-icon/i); + }); +}); diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx new file mode 100644 index 000000000..b6e810432 --- /dev/null +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -0,0 +1,152 @@ +import { h, Component, Prop, Watch, Element, Event, EventEmitter } from '@stencil/core'; +import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from '../steps/bq-steps.types'; +import { TStepItemStatus } from './bq-step-item.types'; +import { validatePropValue } from '../../shared/utils'; + +@Component({ + tag: 'bq-step-item', + styleUrl: './scss/bq-step-item.scss', + shadow: true, +}) +export class BqStepItem { + // Own Properties + // ==================== + + // Reference to host HTML element + // =================================== + @Element() el!: HTMLBqStepItemElement; + + // State() variables + // Inlined decorator, alphabetical order + // ======================================= + + // Public Property API + // ======================== + /** It defines the type of steps */ + @Prop({ reflect: true }) type: TStepsType = 'numeric'; + + /** Step number */ + @Prop({ reflect: true }) number?: number; + + /** It defines step item appearance based on its status */ + @Prop({ reflect: true }) status?: TStepItemStatus = 'default'; + + /** It defines prefix size */ + @Prop({ reflect: true }) size?: TStepsSize = 'medium'; + + /** It defines whether this step item is last in stepper */ + @Prop({ reflect: true }) isLast?: boolean = false; + + /** Step value */ + @Prop({ reflect: true }) value?: string = ''; + + // Prop lifecycle events + // ======================= + @Watch('type') + checkPropValues() { + validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); + validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); + } + // Events section + // Requires JSDocs for public API documentation + // ============================================== + @Event() bqClick: EventEmitter<{ target: HTMLBqStepItemElement; value: string }>; + + // Component lifecycle events + // Ordered by their natural call order + // ===================================== + + // Listeners + // ============== + + // Public methods API + // These methods are exposed on the host element. + // Always use two lines. + // Public Methods must be async. + // Requires JSDocs for public API documentation. + // =============================================== + + // Local methods + // Internal business logic. + // These methods cannot be called from the host element. + // ======================================================= + + handleClick = () => this.bqClick.emit({ target: this.el, value: this.value.toString() }); + + getIconName = () => { + if (this.status === 'completed') { + return 'check-circle'; + } + if (this.status === 'error') { + return 'x-circle'; + } + return 'circle'; + }; + + // render() function + // Always the last one in the class. + // =================================== + + render() { + const avatarSize = this.size === 'medium' ? 'small' : 'xsmall'; + const iconSize = this.size === 'medium' ? 27 : 24; + const isDisabled = this.status === 'disabled'; + const isCurrent = this.status === 'current'; + + return ( +
+ {this.type === 'numeric' ? ( + + ) : this.type === 'dot' ? ( + + ) : ( + + )} +
+ +
+ +
+
+ + {!this.isLast && ( + + )} +
+ ); + } +} diff --git a/packages/beeq/src/components/step-item/bq-step-item.types.ts b/packages/beeq/src/components/step-item/bq-step-item.types.ts new file mode 100644 index 000000000..42112de94 --- /dev/null +++ b/packages/beeq/src/components/step-item/bq-step-item.types.ts @@ -0,0 +1,2 @@ +export const STEP_ITEM_STATUS = ['default', 'current', 'completed', 'error', 'disabled'] as const; +export type TStepItemStatus = (typeof STEP_ITEM_STATUS)[number]; diff --git a/packages/beeq/src/components/step-item/readme.md b/packages/beeq/src/components/step-item/readme.md new file mode 100644 index 000000000..39f8e6168 --- /dev/null +++ b/packages/beeq/src/components/step-item/readme.md @@ -0,0 +1,55 @@ +# bq-step-item + + + + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| -------- | --------- | ---------------------------------------------------- | ---------------------------------------------------------------- | ----------- | +| `isLast` | `is-last` | It defines whether this step item is last in stepper | `boolean` | `false` | +| `number` | `number` | Step number | `number` | `undefined` | +| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `'medium'` | +| `status` | `status` | It defines step item appearance based on its status | `"completed" \| "current" \| "default" \| "disabled" \| "error"` | `'default'` | +| `type` | `type` | It defines the type of steps | `"dot" \| "icon" \| "numeric"` | `'numeric'` | +| `value` | `value` | Step value | `string` | `''` | + + +## Events + +| Event | Description | Type | +| --------- | ----------- | ---------------------------------------------------------------- | +| `bqClick` | | `CustomEvent<{ target: HTMLBqStepItemElement; value: string; }>` | + + +## Shadow Parts + +| Part | Description | +| --------------- | ----------- | +| `"base"` | | +| `"description"` | | +| `"title"` | | + + +## Dependencies + +### Depends on + +- [bq-avatar](../avatar) +- [bq-icon](../icon) +- [bq-divider](../divider) + +### Graph +```mermaid +graph TD; + bq-step-item --> bq-avatar + bq-step-item --> bq-icon + bq-step-item --> bq-divider + style bq-step-item fill:#f9f,stroke:#333,stroke-width:4px +``` + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss b/packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss new file mode 100644 index 000000000..4c94e60db --- /dev/null +++ b/packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss @@ -0,0 +1,7 @@ +/* -------------------------------------------------------------------------- */ +/* Step item custom properties */ +/* -------------------------------------------------------------------------- */ + +:host { + --bq-step-item--margin: 1px; +} diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.scss new file mode 100644 index 000000000..bcc289cc6 --- /dev/null +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.scss @@ -0,0 +1,65 @@ +/* -------------------------------------------------------------------------- */ +/* Step item styles */ +/* -------------------------------------------------------------------------- */ + +@import './bq-step-item-variables'; + +:host { + --bq-icon--color: var(--bq-icon--primary); + --bq-divider--stroke-color: var(--bq-ui--secondary); +} + +:host([status='current']) { + --bq-icon--color: var(--bq-icon--brand); +} + +:host([status='error']) { + --bq-icon--color: var(--bq-icon--danger); +} + +:host([status='completed']) { + --bq-icon--color: var(--bq-icon--success); +} + +:host([status='disabled']) { + --bq-icon--color: var(--bq-icon--primary-disabled); +} + +.bq-step-item { + bq-avatar::part(base) { + --bq-avatar--border-color: transparent; + @apply bg-ui-secondary text-text-secondary; + } +} + +.bq-step-item--error { + bq-avatar::part(base) { + @apply bg-ui-danger text-text-danger; + } +} + +.bq-step-item--current { + bq-avatar::part(base) { + @apply bg-ui-brand text-icon-secondary-inverse; + } +} + +.bq-step-item--disabled { + bq-avatar::part(base) { + @apply bg-ui-secondary-disabled text-text-secondary-disabled; + } +} + +.bq-step-item--completed { + bq-avatar::part(base) { + @apply bg-ui-success text-text-success; + } +} + +.bq-step-item__description::slotted(*) { + @apply mt-1 text-s; +} + +.bq-divider { + --bq-divider--stroke-color: var(--bq-ui--secondary); +} diff --git a/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts b/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts new file mode 100644 index 000000000..518f3338f --- /dev/null +++ b/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts @@ -0,0 +1,30 @@ +import { newE2EPage } from '@stencil/core/testing'; + +describe('bq-steps', () => { + it('should render', async () => { + const page = await newE2EPage(); + await page.setContent(''); + + const element = await page.find('bq-steps'); + + expect(element).toHaveClass('hydrated'); + }); + + it('should have shadow root', async () => { + const page = await newE2EPage(); + await page.setContent(''); + + const element = await page.find('bq-steps'); + + expect(element.shadowRoot).not.toBeNull(); + }); + + it('should display text', async () => { + const page = await newE2EPage(); + await page.setContent(''); + + const element = await page.find('bq-steps >>> p'); + + expect(element).toEqualText('My name is Stencil'); + }); +}); diff --git a/packages/beeq/src/components/steps/_storybook/bq-steps.mdx b/packages/beeq/src/components/steps/_storybook/bq-steps.mdx new file mode 100644 index 000000000..0eb1959cb --- /dev/null +++ b/packages/beeq/src/components/steps/_storybook/bq-steps.mdx @@ -0,0 +1,15 @@ +import { ArgsTable, Canvas, Story } from '@storybook/addon-docs'; + +# Steps + +## Variations + +### Default + + + + + +## Properties + + diff --git a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx new file mode 100644 index 000000000..defc4b0c4 --- /dev/null +++ b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx @@ -0,0 +1,57 @@ +import { html } from 'lit-html'; +import mdx from './bq-steps.mdx'; +import { STEPS_SIZE, STEPS_TYPE } from '../bq-steps.types'; + +export default { + title: 'Components/Steps', + component: 'bq-steps', + parameters: { + docs: { + page: mdx, + }, + }, + argTypes: { + text: { control: 'text', table: { disable: true } }, + type: { control: 'select', options: [...STEPS_TYPE] }, + size: { control: 'select', options: [...STEPS_SIZE] }, + }, + args: { + text: 'text', + }, +}; + +const Template = (args) => { + return html` + + + + + + + + + + + + + step item 1 + description for step + + + + + + + + step item 2 with longerlongerlongerlongerlonger title + description for step + + + + title + description for step 3 + + `; +}; + +export const Default = (args) => Template(args); diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx new file mode 100644 index 000000000..4d01575fe --- /dev/null +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -0,0 +1,96 @@ +import { h, Component, Element, Prop, Watch, Event, EventEmitter, Listen } from '@stencil/core'; +import { validatePropValue } from '../../shared/utils'; +import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from './bq-steps.types'; +// import { BqStepItem } from './step-item/bq-step-item'; + +@Component({ + // bq-stepper + tag: 'bq-steps', + styleUrl: './scss/bq-steps.scss', + shadow: true, +}) +export class BqSteps { + // Own Properties + // ==================== + + // Reference to host HTML element + // =================================== + @Element() el!: HTMLBqStepsElement; + + // State() variables + // Inlined decorator, alphabetical order + // ======================================= + + // Public Property API + // ======================== + + /** It defines the type of steps */ + @Prop({ reflect: true }) type: TStepsType = 'numeric'; + + @Prop({ reflect: true }) size: TStepsSize = 'medium'; + + // Prop lifecycle events + // ======================= + @Watch('type') + checkPropValues() { + validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); + validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); + } + // Events section + // Requires JSDocs for public API documentation + // ============================================== + + /** Handler to be called when the tab value changes */ + @Event() bqChange: EventEmitter<{ target: HTMLBqStepItemElement; value: string }>; + + // Component lifecycle events + // Ordered by their natural call order + // ===================================== + componentDidLoad() { + this.bqStepItemElements.forEach((bqStepItem: HTMLBqStepItemElement, index: number) => { + bqStepItem.type = this.type; + bqStepItem.number = index + 1; + + bqStepItem.size = this.size; + bqStepItem.isLast = index === this.bqStepItemElements.length - 1; + }); + } + + // Listeners + // ============== + @Listen('bqClick') + onBqStepItemChange(event: CustomEvent<{ target: HTMLBqStepItemElement; value: string }>) { + this.bqChange.emit(event.detail); + } + + // Public methods API + // These methods are exposed on the host element. + // Always use two lines. + // Public Methods must be async. + // Requires JSDocs for public API documentation. + // =============================================== + + // Local methods + // Internal business logic. + // These methods cannot be called from the host element. + // ======================================================= + private get bqStepItemElements(): HTMLBqStepItemElement[] { + return Array.from(this.el.querySelectorAll('bq-step-item')); + } + + // private handleChange = (event) => { + // this.bqChange.emit(event); + // } + + // render() function + // Always the last one in the class. + // =================================== + + render() { + return ( +
+ +
+ ); + } +} diff --git a/packages/beeq/src/components/steps/bq-steps.types.ts b/packages/beeq/src/components/steps/bq-steps.types.ts new file mode 100644 index 000000000..0944bd776 --- /dev/null +++ b/packages/beeq/src/components/steps/bq-steps.types.ts @@ -0,0 +1,5 @@ +export const STEPS_TYPE = ['numeric', 'icon', 'dot'] as const; +export type TStepsType = (typeof STEPS_TYPE)[number]; + +export const STEPS_SIZE = ['medium', 'small'] as const; +export type TStepsSize = (typeof STEPS_SIZE)[number]; diff --git a/packages/beeq/src/components/steps/readme.md b/packages/beeq/src/components/steps/readme.md new file mode 100644 index 000000000..c0f36c8a7 --- /dev/null +++ b/packages/beeq/src/components/steps/readme.md @@ -0,0 +1,32 @@ +# bq-steps + + + + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| -------- | --------- | ---------------------------- | ------------------------------ | ----------- | +| `size` | `size` | | `"medium" \| "small"` | `'medium'` | +| `type` | `type` | It defines the type of steps | `"dot" \| "icon" \| "numeric"` | `'numeric'` | + + +## Events + +| Event | Description | Type | +| ---------- | ----------------------------------------------- | ---------------------------------------------------------------- | +| `bqChange` | Handler to be called when the tab value changes | `CustomEvent<{ target: HTMLBqStepItemElement; value: string; }>` | + + +## Shadow Parts + +| Part | Description | +| ------------- | ----------- | +| `"container"` | | + + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/steps/scss/bq-steps-variables.scss b/packages/beeq/src/components/steps/scss/bq-steps-variables.scss new file mode 100644 index 000000000..3c6ce3d98 --- /dev/null +++ b/packages/beeq/src/components/steps/scss/bq-steps-variables.scss @@ -0,0 +1,7 @@ +/* -------------------------------------------------------------------------- */ +/* Steps custom properties */ +/* -------------------------------------------------------------------------- */ + +:host { + --bq-steps--margin: 1px; +} diff --git a/packages/beeq/src/components/steps/scss/bq-steps.scss b/packages/beeq/src/components/steps/scss/bq-steps.scss new file mode 100644 index 000000000..819ed616f --- /dev/null +++ b/packages/beeq/src/components/steps/scss/bq-steps.scss @@ -0,0 +1,9 @@ +/* -------------------------------------------------------------------------- */ +/* Steps styles */ +/* -------------------------------------------------------------------------- */ + +@import './bq-steps-variables'; + +:host { + @apply block; +} From 31bf616e6449b4d978cd4ba0342519517a46464b Mon Sep 17 00:00:00 2001 From: Alexandra Turian Date: Wed, 30 Aug 2023 20:35:58 +0300 Subject: [PATCH 02/13] feat(steps): add unit tests --- .../step-item/__tests__/bq-step-item.e2e.ts | 53 +++++++++++++++---- .../src/components/step-item/bq-step-item.tsx | 22 ++++---- .../steps/__tests__/bq-steps.e2e.ts | 49 +++++++++++++---- 3 files changed, 94 insertions(+), 30 deletions(-) diff --git a/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts b/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts index bf34f8b32..a92454671 100644 --- a/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts +++ b/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts @@ -2,8 +2,11 @@ import { newE2EPage } from '@stencil/core/testing'; describe('bq-step-item', () => { it('should render', async () => { - const page = await newE2EPage(); - await page.setContent(''); + const page = await newE2EPage({ + html: ` + + `, + }); const element = await page.find('bq-step-item'); @@ -11,8 +14,11 @@ describe('bq-step-item', () => { }); it('should have shadow root', async () => { - const page = await newE2EPage(); - await page.setContent(''); + const page = await newE2EPage({ + html: ` + + `, + }); const element = await page.find('bq-step-item'); @@ -20,10 +26,15 @@ describe('bq-step-item', () => { }); it('should display text', async () => { - const page = await newE2EPage(); - await page.setContent('

step item 1

'); + const page = await newE2EPage({ + html: ` + + step item 1 + Description for step 1 + + `, + }); - // const element = await page.find('bq-step-item >>> p'); const text = await page.$eval('bq-step-item', (element) => { const slotElement = element.shadowRoot.querySelector('slot'); const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; @@ -34,11 +45,31 @@ describe('bq-step-item', () => { expect(text).toEqualText('step item 1'); }); + it('should display description', async () => { + const page = await newE2EPage({ + html: ` + + + step item + Description for step item + + `, + }); + + const description = await page.find('bq-step-item >>> slot[name="description"]'); + expect(description).not.toBeNull(); + }); + it('should display icon prefix', async () => { - const page = await newE2EPage(); - await page.setContent( - ' step item 1description for step', - ); + const page = await newE2EPage({ + html: ` + + + step item 1 + Description for step 1 + + `, + }); const prefix = await page.$eval('bq-step-item', (element) => { const slotElement = element.shadowRoot.querySelector('slot[name="prefix"]'); diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index b6e810432..ef142cbc9 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -116,16 +116,18 @@ export class BqStepItem { ) : ( )} -
- +
+
+ +
+
{ it('should render', async () => { - const page = await newE2EPage(); - await page.setContent(''); + const page = await newE2EPage({ + html: ` + + + + Step 1 + Description for step 1 + + + `, + }); const element = await page.find('bq-steps'); @@ -11,20 +20,42 @@ describe('bq-steps', () => { }); it('should have shadow root', async () => { - const page = await newE2EPage(); - await page.setContent(''); + const page = await newE2EPage({ + html: ``, + }); const element = await page.find('bq-steps'); expect(element.shadowRoot).not.toBeNull(); }); - it('should display text', async () => { - const page = await newE2EPage(); - await page.setContent(''); + it('should emit bqChange on step item click', async () => { + const page = await newE2EPage({ + html: ` + + `, + }); - const element = await page.find('bq-steps >>> p'); + const stepItem = await page.find('bq-step-item'); + const bqChange = await page.spyOnEvent('bqChange'); - expect(element).toEqualText('My name is Stencil'); + await stepItem.click(); + + expect(bqChange).toHaveReceivedEventTimes(1); + }); + + it('should render the correct number of steps', async () => { + const page = await newE2EPage({ + html: ` + + Step 1 + Step 2 + + `, + }); + + const steps = await page.findAll('bq-step-item'); + + expect(steps.length).toBe(2); }); }); From 469ebb2f9ccaeb017e805423a32ed68be186dff2 Mon Sep 17 00:00:00 2001 From: Alexandra Turian Date: Thu, 31 Aug 2023 10:41:38 +0300 Subject: [PATCH 03/13] fix(step-item): fix divider color --- packages/beeq/src/components/step-item/bq-step-item.tsx | 3 ++- .../components/step-item/scss/bq-step-item-variables.scss | 1 + .../beeq/src/components/step-item/scss/bq-step-item.scss | 7 +------ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index ef142cbc9..8137ad04a 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -120,7 +120,7 @@ export class BqStepItem {
Date: Thu, 7 Sep 2023 12:35:32 +0300 Subject: [PATCH 04/13] docs(bq-steps): update storybook --- .../src/components/step-item/bq-step-item.tsx | 4 +++ .../step-item/scss/bq-step-item.scss | 1 + .../steps/_storybook/bq-steps.stories.tsx | 28 ++++++++----------- .../beeq/src/components/steps/bq-steps.tsx | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index 8137ad04a..4ef40a2b9 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -43,6 +43,7 @@ export class BqStepItem { // Prop lifecycle events // ======================= @Watch('type') + @Watch('size') checkPropValues() { validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); @@ -56,6 +57,9 @@ export class BqStepItem { // Ordered by their natural call order // ===================================== + componentWillLoad() { + this.checkPropValues(); + } // Listeners // ============== diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.scss index 48c493a19..de3b8ebae 100644 --- a/packages/beeq/src/components/step-item/scss/bq-step-item.scss +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.scss @@ -6,6 +6,7 @@ :host { --bq-icon--color: var(--bq-icon--primary); + flex: 1; } :host([status='current']) { diff --git a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx index defc4b0c4..acb7f6fb0 100644 --- a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx +++ b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx @@ -1,8 +1,10 @@ +import { Args, Meta, StoryObj } from '@storybook/web-components'; import { html } from 'lit-html'; + import mdx from './bq-steps.mdx'; import { STEPS_SIZE, STEPS_TYPE } from '../bq-steps.types'; -export default { +const meta: Meta = { title: 'Components/Steps', component: 'bq-steps', parameters: { @@ -14,35 +16,25 @@ export default { text: { control: 'text', table: { disable: true } }, type: { control: 'select', options: [...STEPS_TYPE] }, size: { control: 'select', options: [...STEPS_SIZE] }, + bqClick: { action: 'bqClick' }, }, args: { text: 'text', + type: 'numeric', + size: 'medium', }, }; +export default meta; -const Template = (args) => { +const Template = (args: Args) => { return html` - - - - - - - - - - step item 1 description for step - - - - step item 2 with longerlongerlongerlongerlonger title description for step @@ -54,4 +46,6 @@ const Template = (args) => { `; }; -export const Default = (args) => Template(args); +export const Default: StoryObj = { + render: Template, +}; diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index 4d01575fe..f47368207 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -88,7 +88,7 @@ export class BqSteps { render() { return ( -
+
); From a89e585f1ba13063329479cf4260a3e003df1564 Mon Sep 17 00:00:00 2001 From: Alexandra Turian Date: Tue, 12 Sep 2023 16:50:40 +0300 Subject: [PATCH 05/13] feat(step-item): add divider --- .../beeq/src/components/divider/readme.md | 13 ---------- .../src/components/step-item/bq-step-item.tsx | 13 ++-------- .../beeq/src/components/step-item/readme.md | 2 -- .../step-item/scss/bq-step-item.scss | 1 - .../beeq/src/components/steps/bq-steps.tsx | 26 ++++++++++++------- 5 files changed, 18 insertions(+), 37 deletions(-) diff --git a/packages/beeq/src/components/divider/readme.md b/packages/beeq/src/components/divider/readme.md index a2f606f62..7e8f860f9 100644 --- a/packages/beeq/src/components/divider/readme.md +++ b/packages/beeq/src/components/divider/readme.md @@ -29,19 +29,6 @@ | `"dash-start-line"` | The component's internal line component of the divider's stroke | -## Dependencies - -### Used by - - - [bq-step-item](../step-item) - -### Graph -```mermaid -graph TD; - bq-step-item --> bq-divider - style bq-divider fill:#f9f,stroke:#333,stroke-width:4px -``` - ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index 4ef40a2b9..0e8c3c58b 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -1,7 +1,8 @@ import { h, Component, Prop, Watch, Element, Event, EventEmitter } from '@stencil/core'; -import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from '../steps/bq-steps.types'; + import { TStepItemStatus } from './bq-step-item.types'; import { validatePropValue } from '../../shared/utils'; +import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from '../steps/bq-steps.types'; @Component({ tag: 'bq-step-item', @@ -143,16 +144,6 @@ export class BqStepItem {
- - {!this.isLast && ( - - )}
); } diff --git a/packages/beeq/src/components/step-item/readme.md b/packages/beeq/src/components/step-item/readme.md index 39f8e6168..3822e8da0 100644 --- a/packages/beeq/src/components/step-item/readme.md +++ b/packages/beeq/src/components/step-item/readme.md @@ -39,14 +39,12 @@ - [bq-avatar](../avatar) - [bq-icon](../icon) -- [bq-divider](../divider) ### Graph ```mermaid graph TD; bq-step-item --> bq-avatar bq-step-item --> bq-icon - bq-step-item --> bq-divider style bq-step-item fill:#f9f,stroke:#333,stroke-width:4px ``` diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.scss index de3b8ebae..48c493a19 100644 --- a/packages/beeq/src/components/step-item/scss/bq-step-item.scss +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.scss @@ -6,7 +6,6 @@ :host { --bq-icon--color: var(--bq-icon--primary); - flex: 1; } :host([status='current']) { diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index f47368207..a6256893c 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -1,7 +1,7 @@ import { h, Component, Element, Prop, Watch, Event, EventEmitter, Listen } from '@stencil/core'; -import { validatePropValue } from '../../shared/utils'; + import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from './bq-steps.types'; -// import { BqStepItem } from './step-item/bq-step-item'; +import { validatePropValue } from '../../shared/utils'; @Component({ // bq-stepper @@ -35,6 +35,8 @@ export class BqSteps { checkPropValues() { validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); + + this.setStepItemProps(); } // Events section // Requires JSDocs for public API documentation @@ -47,13 +49,7 @@ export class BqSteps { // Ordered by their natural call order // ===================================== componentDidLoad() { - this.bqStepItemElements.forEach((bqStepItem: HTMLBqStepItemElement, index: number) => { - bqStepItem.type = this.type; - bqStepItem.number = index + 1; - - bqStepItem.size = this.size; - bqStepItem.isLast = index === this.bqStepItemElements.length - 1; - }); + this.setStepItemProps(); } // Listeners @@ -78,6 +74,16 @@ export class BqSteps { return Array.from(this.el.querySelectorAll('bq-step-item')); } + private setStepItemProps = () => { + this.bqStepItemElements.forEach((bqStepItem: HTMLBqStepItemElement, index: number) => { + bqStepItem.type = this.type; + bqStepItem.number = index + 1; + + bqStepItem.size = this.size; + bqStepItem.isLast = index === this.bqStepItemElements.length - 1; + }); + }; + // private handleChange = (event) => { // this.bqChange.emit(event); // } @@ -88,7 +94,7 @@ export class BqSteps { render() { return ( -
+
); From 40a1c0f09cb347d518e9c0651ac642beed5c2ecc Mon Sep 17 00:00:00 2001 From: Alexandra Turian Date: Wed, 13 Sep 2023 17:16:20 +0300 Subject: [PATCH 06/13] feat(steps): add one divider below all step items --- packages/beeq/src/components/divider/readme.md | 13 +++++++++++++ .../src/components/step-item/bq-step-item.tsx | 15 +++++++++++---- packages/beeq/src/components/steps/bq-steps.tsx | 10 +++++++++- packages/beeq/src/components/steps/readme.md | 13 +++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/packages/beeq/src/components/divider/readme.md b/packages/beeq/src/components/divider/readme.md index 7e8f860f9..6602fa438 100644 --- a/packages/beeq/src/components/divider/readme.md +++ b/packages/beeq/src/components/divider/readme.md @@ -29,6 +29,19 @@ | `"dash-start-line"` | The component's internal line component of the divider's stroke | +## Dependencies + +### Used by + + - [bq-steps](../steps) + +### Graph +```mermaid +graph TD; + bq-steps --> bq-divider + style bq-divider fill:#f9f,stroke:#333,stroke-width:4px +``` + ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index 0e8c3c58b..2bdaf5f8a 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -110,18 +110,25 @@ export class BqStepItem { onClick={this.handleClick} > {this.type === 'numeric' ? ( - + ) : this.type === 'dot' ? ( ) : ( - + + + )} -
+
+
+
); } diff --git a/packages/beeq/src/components/steps/readme.md b/packages/beeq/src/components/steps/readme.md index c0f36c8a7..1065917ce 100644 --- a/packages/beeq/src/components/steps/readme.md +++ b/packages/beeq/src/components/steps/readme.md @@ -27,6 +27,19 @@ | `"container"` | | +## Dependencies + +### Depends on + +- [bq-divider](../divider) + +### Graph +```mermaid +graph TD; + bq-steps --> bq-divider + style bq-steps fill:#f9f,stroke:#333,stroke-width:4px +``` + ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* From 3d39c5307305bc797fc3bfa3680bfe6f156201a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dabiel=20Gonz=C3=A1lez=20Ramos?= Date: Fri, 6 Oct 2023 14:29:23 +0300 Subject: [PATCH 07/13] refactor: simplify Steps components' logic --- .../beeq/src/components/steps/bq-steps.tsx | 31 ++++++++----------- packages/beeq/src/components/steps/readme.md | 8 ++--- .../src/components/steps/scss/bq-steps.scss | 10 +++++- ...variables.scss => bq-steps.variables.scss} | 7 ++++- 4 files changed, 32 insertions(+), 24 deletions(-) rename packages/beeq/src/components/steps/scss/{bq-steps-variables.scss => bq-steps.variables.scss} (53%) diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index a8e6bc906..d998033bb 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -1,6 +1,6 @@ -import { h, Component, Element, Prop, Watch, Event, EventEmitter, Listen } from '@stencil/core'; +import { Component, Element, Event, EventEmitter, h, Listen, Prop, Watch } from '@stencil/core'; -import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from './bq-steps.types'; +import { STEPS_SIZE, TStepsSize } from './bq-steps.types'; import { validatePropValue } from '../../shared/utils'; @Component({ @@ -24,17 +24,17 @@ export class BqSteps { // Public Property API // ======================== - /** It defines the type of steps */ - @Prop({ reflect: true }) type: TStepsType = 'numeric'; - + /** The size of the steps */ @Prop({ reflect: true }) size: TStepsSize = 'medium'; + /** The color of the line that connects the steps. It should be a valid declarative color token. */ + @Prop({ reflect: true }) dividerColor: string = 'ui--secondary'; + // Prop lifecycle events // ======================= @Watch('type') @Watch('size') checkPropValues() { - validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); this.setStepItemProps(); @@ -71,17 +71,13 @@ export class BqSteps { // Internal business logic. // These methods cannot be called from the host element. // ======================================================= - private get bqStepItemElements(): HTMLBqStepItemElement[] { + private get bqSteps(): HTMLBqStepItemElement[] { return Array.from(this.el.querySelectorAll('bq-step-item')); } private setStepItemProps = () => { - this.bqStepItemElements.forEach((bqStepItem: HTMLBqStepItemElement, index: number) => { - bqStepItem.type = this.type; - bqStepItem.number = index + 1; - - bqStepItem.size = this.size; - bqStepItem.isLast = index === this.bqStepItemElements.length - 1; + this.bqSteps.forEach((bqStepElem: HTMLBqStepItemElement) => { + bqStepElem.size = this.size; }); }; @@ -94,15 +90,14 @@ export class BqSteps { // =================================== render() { + const dividerPaddingTop = this.size === 'small' ? 'pt-s' : 'pt-m'; + return (
); diff --git a/packages/beeq/src/components/steps/readme.md b/packages/beeq/src/components/steps/readme.md index 1065917ce..df3872dd4 100644 --- a/packages/beeq/src/components/steps/readme.md +++ b/packages/beeq/src/components/steps/readme.md @@ -7,10 +7,10 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| -------- | --------- | ---------------------------- | ------------------------------ | ----------- | -| `size` | `size` | | `"medium" \| "small"` | `'medium'` | -| `type` | `type` | It defines the type of steps | `"dot" \| "icon" \| "numeric"` | `'numeric'` | +| Property | Attribute | Description | Type | Default | +| -------------- | --------------- | -------------------------------------------------------------------------------------------- | --------------------- | ----------------- | +| `dividerColor` | `divider-color` | The color of the line that connects the steps. It should be a valid declarative color token. | `string` | `'ui--secondary'` | +| `size` | `size` | The size of the steps | `"medium" \| "small"` | `'medium'` | ## Events diff --git a/packages/beeq/src/components/steps/scss/bq-steps.scss b/packages/beeq/src/components/steps/scss/bq-steps.scss index 819ed616f..b6652a6a9 100644 --- a/packages/beeq/src/components/steps/scss/bq-steps.scss +++ b/packages/beeq/src/components/steps/scss/bq-steps.scss @@ -2,8 +2,16 @@ /* Steps styles */ /* -------------------------------------------------------------------------- */ -@import './bq-steps-variables'; +@import './bq-steps.variables'; :host { @apply block; } + +::slotted(bq-step-item:not(:first-child)) { + @apply ps-[--bq-steps--gap]; +} + +::slotted(bq-step-item:not(:last-child)) { + @apply pe-[--bq-steps--gap]; +} diff --git a/packages/beeq/src/components/steps/scss/bq-steps-variables.scss b/packages/beeq/src/components/steps/scss/bq-steps.variables.scss similarity index 53% rename from packages/beeq/src/components/steps/scss/bq-steps-variables.scss rename to packages/beeq/src/components/steps/scss/bq-steps.variables.scss index 3c6ce3d98..ad9a861b0 100644 --- a/packages/beeq/src/components/steps/scss/bq-steps-variables.scss +++ b/packages/beeq/src/components/steps/scss/bq-steps.variables.scss @@ -3,5 +3,10 @@ /* -------------------------------------------------------------------------- */ :host { - --bq-steps--margin: 1px; + /** + * @prop --bq-steps--divider-color - Divider color + * @prop --bq-steps--gap - Gap between steps + */ + --bq-steps--divider-color: theme('colors.ui.secondary'); + --bq-steps--gap: theme('spacing.m'); } From 638a09ddf8817acd6651e0fe0ec584030faa01b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dabiel=20Gonz=C3=A1lez=20Ramos?= Date: Fri, 6 Oct 2023 14:30:29 +0300 Subject: [PATCH 08/13] refactor: simplify Steps item for `dot` and `icon` types --- packages/beeq/src/components.d.ts | 52 ++------ .../src/components/step-item/bq-step-item.tsx | 111 +++++++----------- .../beeq/src/components/step-item/readme.md | 27 +---- .../scss/bq-step-item-variables.scss | 8 -- .../step-item/scss/bq-step-item.scss | 64 ++++------ .../scss/bq-step-item.variables.scss | 11 ++ .../components/steps/_storybook/bq-steps.mdx | 35 ++++-- 7 files changed, 123 insertions(+), 185 deletions(-) delete mode 100644 packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss create mode 100644 packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss diff --git a/packages/beeq/src/components.d.ts b/packages/beeq/src/components.d.ts index 08d07dee8..2744e0141 100644 --- a/packages/beeq/src/components.d.ts +++ b/packages/beeq/src/components.d.ts @@ -19,7 +19,7 @@ import { TSideMenuAppearance, TSideMenuSize } from "./components/side-menu/bq-si import { TSliderType } from "./components/slider/bq-slider.types"; import { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spinner.types"; import { TStatusType } from "./components/status/bq-status.types"; -import { TStepsSize, TStepsType } from "./components/steps/bq-steps.types"; +import { TStepsSize } from "./components/steps/bq-steps.types"; import { TStepItemStatus } from "./components/step-item/bq-step-item.types"; import { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types"; import { TTabSize } from "./components/tab/bq-tab.types"; @@ -39,7 +39,7 @@ export { TSideMenuAppearance, TSideMenuSize } from "./components/side-menu/bq-si export { TSliderType } from "./components/slider/bq-slider.types"; export { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spinner.types"; export { TStatusType } from "./components/status/bq-status.types"; -export { TStepsSize, TStepsType } from "./components/steps/bq-steps.types"; +export { TStepsSize } from "./components/steps/bq-steps.types"; export { TStepItemStatus } from "./components/step-item/bq-step-item.types"; export { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types"; export { TTabSize } from "./components/tab/bq-tab.types"; @@ -774,14 +774,6 @@ export namespace Components { "type": TStatusType; } interface BqStepItem { - /** - * It defines whether this step item is last in stepper - */ - "isLast"?: boolean; - /** - * Step number - */ - "number"?: number; /** * It defines prefix size */ @@ -790,21 +782,16 @@ export namespace Components { * It defines step item appearance based on its status */ "status"?: TStepItemStatus; + } + interface BqSteps { /** - * It defines the type of steps + * The color of the line that connects the steps. It should be a valid declarative color token. */ - "type": TStepsType; + "dividerColor": string; /** - * Step value + * The size of the steps */ - "value"?: string; - } - interface BqSteps { "size": TStepsSize; - /** - * It defines the type of steps - */ - "type": TStepsType; } /** * Toggle switches are digital on/off switches. @@ -2271,14 +2258,6 @@ declare namespace LocalJSX { "type"?: TStatusType; } interface BqStepItem { - /** - * It defines whether this step item is last in stepper - */ - "isLast"?: boolean; - /** - * Step number - */ - "number"?: number; "onBqClick"?: (event: BqStepItemCustomEvent<{ target: HTMLBqStepItemElement; value: string }>) => void; /** * It defines prefix size @@ -2288,25 +2267,20 @@ declare namespace LocalJSX { * It defines step item appearance based on its status */ "status"?: TStepItemStatus; - /** - * It defines the type of steps - */ - "type"?: TStepsType; - /** - * Step value - */ - "value"?: string; } interface BqSteps { + /** + * The color of the line that connects the steps. It should be a valid declarative color token. + */ + "dividerColor"?: string; /** * Handler to be called when the tab value changes */ "onBqChange"?: (event: BqStepsCustomEvent<{ target: HTMLBqStepItemElement; value: string }>) => void; - "size"?: TStepsSize; /** - * It defines the type of steps + * The size of the steps */ - "type"?: TStepsType; + "size"?: TStepsSize; } /** * Toggle switches are digital on/off switches. diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index 2bdaf5f8a..eacb03d1c 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -1,8 +1,8 @@ -import { h, Component, Prop, Watch, Element, Event, EventEmitter } from '@stencil/core'; +import { Component, Element, Event, EventEmitter, h, Prop, Watch } from '@stencil/core'; -import { TStepItemStatus } from './bq-step-item.types'; -import { validatePropValue } from '../../shared/utils'; -import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from '../steps/bq-steps.types'; +import { STEP_ITEM_STATUS, TStepItemStatus } from './bq-step-item.types'; +import { isHTMLElement, validatePropValue } from '../../shared/utils'; +import { STEPS_SIZE, TStepsSize } from '../steps/bq-steps.types'; @Component({ tag: 'bq-step-item', @@ -23,32 +23,25 @@ export class BqStepItem { // Public Property API // ======================== - /** It defines the type of steps */ - @Prop({ reflect: true }) type: TStepsType = 'numeric'; - - /** Step number */ - @Prop({ reflect: true }) number?: number; - - /** It defines step item appearance based on its status */ - @Prop({ reflect: true }) status?: TStepItemStatus = 'default'; /** It defines prefix size */ @Prop({ reflect: true }) size?: TStepsSize = 'medium'; - /** It defines whether this step item is last in stepper */ - @Prop({ reflect: true }) isLast?: boolean = false; - - /** Step value */ - @Prop({ reflect: true }) value?: string = ''; + /** It defines step item appearance based on its status */ + @Prop({ reflect: true }) status?: TStepItemStatus = 'default'; // Prop lifecycle events // ======================= - @Watch('type') + @Watch('size') + @Watch('status') checkPropValues() { - validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); + validatePropValue(STEP_ITEM_STATUS, 'default', this.el, 'status'); + + this.handleIconPrefix(); } + // Events section // Requires JSDocs for public API documentation // ============================================== @@ -61,6 +54,11 @@ export class BqStepItem { componentWillLoad() { this.checkPropValues(); } + + componentDidLoad() { + this.checkPropValues(); + } + // Listeners // ============== @@ -76,16 +74,20 @@ export class BqStepItem { // These methods cannot be called from the host element. // ======================================================= - handleClick = () => this.bqClick.emit({ target: this.el, value: this.value.toString() }); + private get isDisabled(): boolean { + return this.status === 'disabled'; + } + + private get isCurrent(): boolean { + return this.status === 'current'; + } + + private handleIconPrefix = () => { + const iconElem = this.el.querySelector('[slot="prefix"]'); + if (!iconElem || !isHTMLElement(iconElem, 'bq-icon')) return; - getIconName = () => { - if (this.status === 'completed') { - return 'check-circle'; - } - if (this.status === 'error') { - return 'x-circle'; - } - return 'circle'; + iconElem.size = this.size === 'small' ? 24 : 32; + iconElem.weight = this.isCurrent ? 'fill' : 'regular'; }; // render() function @@ -93,60 +95,37 @@ export class BqStepItem { // =================================== render() { - const avatarSize = this.size === 'medium' ? 'small' : 'xsmall'; - const iconSize = this.size === 'medium' ? 27 : 24; - const isDisabled = this.status === 'disabled'; - const isCurrent = this.status === 'current'; - return (
- {this.type === 'numeric' ? ( - - ) : this.type === 'dot' ? ( - - ) : ( - - - - )} -
+
+ +
+
+ {/* TITLE */}
- + {/* DESCRIPTION */}
diff --git a/packages/beeq/src/components/step-item/readme.md b/packages/beeq/src/components/step-item/readme.md index 3822e8da0..df106762b 100644 --- a/packages/beeq/src/components/step-item/readme.md +++ b/packages/beeq/src/components/step-item/readme.md @@ -7,14 +7,10 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| -------- | --------- | ---------------------------------------------------- | ---------------------------------------------------------------- | ----------- | -| `isLast` | `is-last` | It defines whether this step item is last in stepper | `boolean` | `false` | -| `number` | `number` | Step number | `number` | `undefined` | -| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `'medium'` | -| `status` | `status` | It defines step item appearance based on its status | `"completed" \| "current" \| "default" \| "disabled" \| "error"` | `'default'` | -| `type` | `type` | It defines the type of steps | `"dot" \| "icon" \| "numeric"` | `'numeric'` | -| `value` | `value` | Step value | `string` | `''` | +| Property | Attribute | Description | Type | Default | +| -------- | --------- | --------------------------------------------------- | ---------------------------------------------------------------- | ----------- | +| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `'medium'` | +| `status` | `status` | It defines step item appearance based on its status | `"completed" \| "current" \| "default" \| "disabled" \| "error"` | `'default'` | ## Events @@ -33,21 +29,6 @@ | `"title"` | | -## Dependencies - -### Depends on - -- [bq-avatar](../avatar) -- [bq-icon](../icon) - -### Graph -```mermaid -graph TD; - bq-step-item --> bq-avatar - bq-step-item --> bq-icon - style bq-step-item fill:#f9f,stroke:#333,stroke-width:4px -``` - ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss b/packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss deleted file mode 100644 index 76a5470d3..000000000 --- a/packages/beeq/src/components/step-item/scss/bq-step-item-variables.scss +++ /dev/null @@ -1,8 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* Step item custom properties */ -/* -------------------------------------------------------------------------- */ - -:host { - --bq-step-item--margin: 1px; - --bq-divider--stroke-color: var(--bq-ui--secondary); -} diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.scss index 48c493a19..ad772b172 100644 --- a/packages/beeq/src/components/step-item/scss/bq-step-item.scss +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.scss @@ -2,59 +2,43 @@ /* Step item styles */ /* -------------------------------------------------------------------------- */ -@import './bq-step-item-variables'; +@import './bq-step-item.variables'; :host { - --bq-icon--color: var(--bq-icon--primary); + --bq-icon--color: theme('colors.icon.primary'); + @apply bg-bg-primary; } -:host([status='current']) { - --bq-icon--color: var(--bq-icon--brand); -} - -:host([status='error']) { - --bq-icon--color: var(--bq-icon--danger); -} - -:host([status='completed']) { - --bq-icon--color: var(--bq-icon--success); -} - -:host([status='disabled']) { - --bq-icon--color: var(--bq-icon--primary-disabled); -} - -.bq-step-item { - bq-avatar::part(base) { - --bq-avatar--border-color: transparent; - @apply bg-ui-secondary text-text-secondary; +.bq-step-item__prefix { + ::slotted(bq-icon) { + --bq-icon--color: var(--bq-step-item--prefix-color); } -} -.bq-step-item--error { - bq-avatar::part(base) { - @apply bg-ui-danger text-text-danger; + &.current { + ::slotted(bq-icon) { + --bq-icon--color: var(--bq-step-item--prefix-color-current); + } } -} -.bq-step-item--current { - bq-avatar::part(base) { - @apply bg-ui-brand text-icon-secondary-inverse; + &.completed { + ::slotted(bq-icon) { + --bq-icon--color: var(--bq-step-item--prefix-color-completed); + } } -} -.bq-step-item--disabled { - bq-avatar::part(base) { - @apply bg-ui-secondary-disabled text-text-secondary-disabled; + &.error { + ::slotted(bq-icon) { + --bq-icon--color: var(--bq-step-item--prefix-color-error); + } } -} -.bq-step-item--completed { - bq-avatar::part(base) { - @apply bg-ui-success-alt text-text-success; + &.disabled { + ::slotted(bq-icon) { + --bq-icon--color: var(--bq-step-item--prefix-color-disabled); + } } } -.bq-step-item__description::slotted(*) { - @apply mt-1 text-s; +.bq-step-item__content--description::slotted(*) { + @apply text-s leading-regular text-text-primary-disabled; } diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss new file mode 100644 index 000000000..0a0b49375 --- /dev/null +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss @@ -0,0 +1,11 @@ +/* -------------------------------------------------------------------------- */ +/* Step item custom properties */ +/* -------------------------------------------------------------------------- */ + +:host { + --bq-step-item--prefix-color: theme('colors.icon.secondary'); + --bq-step-item--prefix-color-current: theme('colors.icon.brand'); + --bq-step-item--prefix-color-completed: theme('colors.icon.success'); + --bq-step-item--prefix-color-error: theme('colors.icon.danger'); + --bq-step-item--prefix-color-disabled: theme('colors.icon.secondary-disabled'); +} diff --git a/packages/beeq/src/components/steps/_storybook/bq-steps.mdx b/packages/beeq/src/components/steps/_storybook/bq-steps.mdx index 0eb1959cb..1d5f16acd 100644 --- a/packages/beeq/src/components/steps/_storybook/bq-steps.mdx +++ b/packages/beeq/src/components/steps/_storybook/bq-steps.mdx @@ -1,15 +1,32 @@ -import { ArgsTable, Canvas, Story } from '@storybook/addon-docs'; +import { ArgTypes, Title, Subtitle } from '@storybook/addon-docs'; -# Steps +
+
+ Steps -## Variations + The Steps Component is a UI element used to display a series of steps or stages in a process or task. Steps are commonly used in wizards, onboarding flows, or multi-step forms, and are a way to help users understand the progression of a task or process and their current status. + It typically consists of a visually appealing representation of the current step, along with optional labels, icons, or additional information associated with each step. -### Default + Usage - - - + - Displaying the steps in a wizard, onboarding flow, or multi-step form, so that users can understand the progression of the task and their current status. + - Providing an overview of the steps in a process or task, such as outlining the steps in a recipe or the stages of a project. + - Representing the progress of a task or process, such as indicating the current step, completed steps, and future steps. -## Properties + 👍 When to use - + 1. Multi-step processes: Use stepper items when there is a need to guide users through a multi-step process, such as signing up, completing a form, or placing an order. + 2. Wizard-like interfaces: Stepper items work well for implementing wizard-like interfaces where users need to progress through a series of steps to complete a task. + 3. Progress tracking: Stepper items can be used to visually track the progress of a user's actions, such as completing a tutorial or a course with multiple lessons. + + Properties + + bq-steps + + + + bq-step-item + + +
+
From df212071e706650e7c814b4d4983f426bfa66fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dabiel=20Gonz=C3=A1lez=20Ramos?= Date: Fri, 6 Oct 2023 14:37:34 +0300 Subject: [PATCH 09/13] refactor: use `slot.assignedElements()` instead to query all step items --- .../beeq/src/components/steps/bq-steps.tsx | 24 ++++++++++++++++--- packages/beeq/src/components/steps/readme.md | 6 ++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index d998033bb..8237e307e 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -3,8 +3,10 @@ import { Component, Element, Event, EventEmitter, h, Listen, Prop, Watch } from import { STEPS_SIZE, TStepsSize } from './bq-steps.types'; import { validatePropValue } from '../../shared/utils'; +/** + * @part container - The container wrapper of the Steps component + */ @Component({ - // bq-stepper tag: 'bq-steps', styleUrl: './scss/bq-steps.scss', shadow: true, @@ -13,8 +15,11 @@ export class BqSteps { // Own Properties // ==================== + private stepElem: HTMLElement; + // Reference to host HTML element // =================================== + @Element() el!: HTMLBqStepsElement; // State() variables @@ -32,6 +37,7 @@ export class BqSteps { // Prop lifecycle events // ======================= + @Watch('type') @Watch('size') checkPropValues() { @@ -49,12 +55,14 @@ export class BqSteps { // Component lifecycle events // Ordered by their natural call order // ===================================== + componentDidLoad() { this.setStepItemProps(); } // Listeners // ============== + @Listen('bqClick') onBqStepItemChange(event: CustomEvent<{ target: HTMLBqStepItemElement; value: string }>) { this.bqChange.emit(event.detail); @@ -71,8 +79,14 @@ export class BqSteps { // Internal business logic. // These methods cannot be called from the host element. // ======================================================= + private get bqSteps(): HTMLBqStepItemElement[] { - return Array.from(this.el.querySelectorAll('bq-step-item')); + if (!this.stepElem) return []; + + const slot = this.stepElem.querySelector('slot'); + return [...slot.assignedElements({ flatten: true })].filter( + (el: HTMLBqSideMenuItemElement) => el.tagName.toLowerCase() === 'bq-step-item', + ) as [HTMLBqSideMenuItemElement]; } private setStepItemProps = () => { @@ -93,7 +107,11 @@ export class BqSteps { const dividerPaddingTop = this.size === 'small' ? 'pt-s' : 'pt-m'; return ( -
+
(this.stepElem = div)} + part="container" + > Date: Fri, 6 Oct 2023 18:54:16 +0300 Subject: [PATCH 10/13] refactor: numeric step item type --- packages/beeq/src/components.d.ts | 20 ++++++++++-- .../src/components/step-item/bq-step-item.tsx | 9 ++++-- .../beeq/src/components/step-item/readme.md | 3 +- .../step-item/scss/bq-step-item.scss | 31 ++++++++++++++++++- .../scss/bq-step-item.variables.scss | 3 ++ .../beeq/src/components/steps/bq-steps.tsx | 11 +++++-- packages/beeq/src/components/steps/readme.md | 9 +++--- 7 files changed, 72 insertions(+), 14 deletions(-) diff --git a/packages/beeq/src/components.d.ts b/packages/beeq/src/components.d.ts index 2744e0141..48d496a9f 100644 --- a/packages/beeq/src/components.d.ts +++ b/packages/beeq/src/components.d.ts @@ -19,7 +19,7 @@ import { TSideMenuAppearance, TSideMenuSize } from "./components/side-menu/bq-si import { TSliderType } from "./components/slider/bq-slider.types"; import { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spinner.types"; import { TStatusType } from "./components/status/bq-status.types"; -import { TStepsSize } from "./components/steps/bq-steps.types"; +import { TStepsSize, TStepsType } from "./components/steps/bq-steps.types"; import { TStepItemStatus } from "./components/step-item/bq-step-item.types"; import { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types"; import { TTabSize } from "./components/tab/bq-tab.types"; @@ -39,7 +39,7 @@ export { TSideMenuAppearance, TSideMenuSize } from "./components/side-menu/bq-si export { TSliderType } from "./components/slider/bq-slider.types"; export { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spinner.types"; export { TStatusType } from "./components/status/bq-status.types"; -export { TStepsSize } from "./components/steps/bq-steps.types"; +export { TStepsSize, TStepsType } from "./components/steps/bq-steps.types"; export { TStepItemStatus } from "./components/step-item/bq-step-item.types"; export { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types"; export { TTabSize } from "./components/tab/bq-tab.types"; @@ -782,6 +782,10 @@ export namespace Components { * It defines step item appearance based on its status */ "status"?: TStepItemStatus; + /** + * It defines the step item type used + */ + "type"?: TStepsType; } interface BqSteps { /** @@ -792,6 +796,10 @@ export namespace Components { * The size of the steps */ "size": TStepsSize; + /** + * The type of prefix element to use on the step items + */ + "type": TStepsType; } /** * Toggle switches are digital on/off switches. @@ -2267,6 +2275,10 @@ declare namespace LocalJSX { * It defines step item appearance based on its status */ "status"?: TStepItemStatus; + /** + * It defines the step item type used + */ + "type"?: TStepsType; } interface BqSteps { /** @@ -2281,6 +2293,10 @@ declare namespace LocalJSX { * The size of the steps */ "size"?: TStepsSize; + /** + * The type of prefix element to use on the step items + */ + "type"?: TStepsType; } /** * Toggle switches are digital on/off switches. diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index eacb03d1c..1a274363b 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -2,7 +2,7 @@ import { Component, Element, Event, EventEmitter, h, Prop, Watch } from '@stenci import { STEP_ITEM_STATUS, TStepItemStatus } from './bq-step-item.types'; import { isHTMLElement, validatePropValue } from '../../shared/utils'; -import { STEPS_SIZE, TStepsSize } from '../steps/bq-steps.types'; +import { STEPS_SIZE, TStepsSize, TStepsType } from '../steps/bq-steps.types'; @Component({ tag: 'bq-step-item', @@ -25,11 +25,14 @@ export class BqStepItem { // ======================== /** It defines prefix size */ - @Prop({ reflect: true }) size?: TStepsSize = 'medium'; + @Prop({ reflect: true }) size?: TStepsSize; /** It defines step item appearance based on its status */ @Prop({ reflect: true }) status?: TStepItemStatus = 'default'; + /** It defines the step item type used */ + @Prop({ reflect: true }) type?: TStepsType; + // Prop lifecycle events // ======================= @@ -104,7 +107,7 @@ export class BqStepItem { }} part="base" > -
+
diff --git a/packages/beeq/src/components/step-item/readme.md b/packages/beeq/src/components/step-item/readme.md index df106762b..20c24f132 100644 --- a/packages/beeq/src/components/step-item/readme.md +++ b/packages/beeq/src/components/step-item/readme.md @@ -9,8 +9,9 @@ | Property | Attribute | Description | Type | Default | | -------- | --------- | --------------------------------------------------- | ---------------------------------------------------------------- | ----------- | -| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `'medium'` | +| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `undefined` | | `status` | `status` | It defines step item appearance based on its status | `"completed" \| "current" \| "default" \| "disabled" \| "error"` | `'default'` | +| `type` | `type` | It defines the step item type used | `"dot" \| "icon" \| "numeric"` | `undefined` | ## Events diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.scss index ad772b172..26a61b4ff 100644 --- a/packages/beeq/src/components/step-item/scss/bq-step-item.scss +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.scss @@ -9,7 +9,8 @@ @apply bg-bg-primary; } -.bq-step-item__prefix { +.bq-step-item__prefix.dot, +.bq-step-item__prefix.icon { ::slotted(bq-icon) { --bq-icon--color: var(--bq-step-item--prefix-color); } @@ -39,6 +40,34 @@ } } +.bq-step-item__prefix.numeric { + @apply flex items-center justify-center rounded-full; + @apply h-[--bq-step-item--prefix-num-size] w-[--bq-step-item--prefix-num-size] bg-[--bq-step-item--prefix-num-bg-color]; + @apply font-outfit text-m leading-regular font-semibold; + + &.small { + @apply [--bq-step-item--prefix-num-size:--bq-spacing-l] text-s; + } + + // Status + + &.current { + @apply bg-[var(--bq-step-item--prefix-color-current)] text-text-primary-alt; + } + + &.completed { + @apply bg-ui-success-alt text-text-success; + } + + &.error { + @apply bg-ui-danger-alt text-text-danger; + } + + &.disabled { + @apply bg-ui-secondary-disabled text-text-primary-disabled; + } +} + .bq-step-item__content--description::slotted(*) { @apply text-s leading-regular text-text-primary-disabled; } diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss index 0a0b49375..07243babe 100644 --- a/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss @@ -8,4 +8,7 @@ --bq-step-item--prefix-color-completed: theme('colors.icon.success'); --bq-step-item--prefix-color-error: theme('colors.icon.danger'); --bq-step-item--prefix-color-disabled: theme('colors.icon.secondary-disabled'); + + --bq-step-item--prefix-num-size: theme('spacing.xl'); + --bq-step-item--prefix-num-bg-color: theme('colors.ui.secondary'); } diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index 8237e307e..87069131e 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -1,6 +1,6 @@ import { Component, Element, Event, EventEmitter, h, Listen, Prop, Watch } from '@stencil/core'; -import { STEPS_SIZE, TStepsSize } from './bq-steps.types'; +import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from './bq-steps.types'; import { validatePropValue } from '../../shared/utils'; /** @@ -29,11 +29,14 @@ export class BqSteps { // Public Property API // ======================== + /** The color of the line that connects the steps. It should be a valid declarative color token. */ + @Prop({ reflect: true }) dividerColor: string = 'ui--secondary'; + /** The size of the steps */ @Prop({ reflect: true }) size: TStepsSize = 'medium'; - /** The color of the line that connects the steps. It should be a valid declarative color token. */ - @Prop({ reflect: true }) dividerColor: string = 'ui--secondary'; + /** The type of prefix element to use on the step items */ + @Prop({ reflect: true }) type: TStepsType; // Prop lifecycle events // ======================= @@ -42,6 +45,7 @@ export class BqSteps { @Watch('size') checkPropValues() { validatePropValue(STEPS_SIZE, 'medium', this.el, 'size'); + validatePropValue(STEPS_TYPE, 'numeric', this.el, 'type'); this.setStepItemProps(); } @@ -92,6 +96,7 @@ export class BqSteps { private setStepItemProps = () => { this.bqSteps.forEach((bqStepElem: HTMLBqStepItemElement) => { bqStepElem.size = this.size; + bqStepElem.type = this.type; }); }; diff --git a/packages/beeq/src/components/steps/readme.md b/packages/beeq/src/components/steps/readme.md index d792f9e79..9e43179ff 100644 --- a/packages/beeq/src/components/steps/readme.md +++ b/packages/beeq/src/components/steps/readme.md @@ -7,10 +7,11 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| -------------- | --------------- | -------------------------------------------------------------------------------------------- | --------------------- | ----------------- | -| `dividerColor` | `divider-color` | The color of the line that connects the steps. It should be a valid declarative color token. | `string` | `'ui--secondary'` | -| `size` | `size` | The size of the steps | `"medium" \| "small"` | `'medium'` | +| Property | Attribute | Description | Type | Default | +| -------------- | --------------- | -------------------------------------------------------------------------------------------- | ------------------------------ | ----------------- | +| `dividerColor` | `divider-color` | The color of the line that connects the steps. It should be a valid declarative color token. | `string` | `'ui--secondary'` | +| `size` | `size` | The size of the steps | `"medium" \| "small"` | `'medium'` | +| `type` | `type` | The type of prefix element to use on the step items | `"dot" \| "icon" \| "numeric"` | `undefined` | ## Events From 8f604c5b7ee9f9c3ebff476d19893e8aa45ea1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dabiel=20Gonz=C3=A1lez=20Ramos?= Date: Fri, 6 Oct 2023 18:55:09 +0300 Subject: [PATCH 11/13] docs: update storybook examples and generated readme files --- .vscode/settings.json | 1 - config/theme/default/light.ts | 4 +- packages/beeq/src/components/avatar/readme.md | 13 -- packages/beeq/src/components/icon/readme.md | 2 - .../steps/_storybook/bq-steps.stories.tsx | 130 +++++++++++++++--- packages/beeq/src/shared/utils/props.ts | 4 +- 6 files changed, 112 insertions(+), 42 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4a79363fd..a442a591d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,7 +36,6 @@ }, "html.customData": ["./dist/bee-q/custom-elements.json"], "less.validate": false, - "prettier.prettierPath": "node_modules/prettier", "scss.validate": false, "stylelint.configFile": ".stylelintrc.json", "stylelint.validate": [ diff --git a/config/theme/default/light.ts b/config/theme/default/light.ts index b1cc22305..c79d73a68 100644 --- a/config/theme/default/light.ts +++ b/config/theme/default/light.ts @@ -120,8 +120,8 @@ export const DefaultLightTheme = { 'bq-text--secondary-active': 'var(--bq-grey-700)', 'bq-text--secondary-disabled': 'var(--bq-grey-400)', /** Inverse */ - 'bq-text--inverse': 'var(--bq-neutral-white)', - 'bq-text--inverse-disabled': 'var(--bq-grey-50)', + 'bq-text--inverse': 'var(--bq-grey-50)', + 'bq-text--inverse-disabled': 'var(--bq-grey-100)', /** Brand */ 'bq-text--brand': 'var(--bq-iris-600)', 'bq-text--brand-hover': 'var(--bq-iris-500)', diff --git a/packages/beeq/src/components/avatar/readme.md b/packages/beeq/src/components/avatar/readme.md index 4b8f7bac9..1bde16bc0 100644 --- a/packages/beeq/src/components/avatar/readme.md +++ b/packages/beeq/src/components/avatar/readme.md @@ -26,19 +26,6 @@ | `"text"` | The `` tag element that renderd the `Initials` text string. | -## Dependencies - -### Used by - - - [bq-step-item](../step-item) - -### Graph -```mermaid -graph TD; - bq-step-item --> bq-avatar - style bq-avatar fill:#f9f,stroke:#333,stroke-width:4px -``` - ---------------------------------------------- *Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/beeq/src/components/icon/readme.md b/packages/beeq/src/components/icon/readme.md index 156d36224..50aebeec8 100644 --- a/packages/beeq/src/components/icon/readme.md +++ b/packages/beeq/src/components/icon/readme.md @@ -41,7 +41,6 @@ Icons are simplified images that graphically explain the meaning of an object on - [bq-input](../input) - [bq-notification](../notification) - [bq-select](../select) - - [bq-step-item](../step-item) - [bq-switch](../switch) - [bq-toast](../toast) @@ -53,7 +52,6 @@ graph TD; bq-input --> bq-icon bq-notification --> bq-icon bq-select --> bq-icon - bq-step-item --> bq-icon bq-switch --> bq-icon bq-toast --> bq-icon style bq-icon fill:#f9f,stroke:#333,stroke-width:4px diff --git a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx index acb7f6fb0..8ef396b23 100644 --- a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx +++ b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx @@ -1,5 +1,6 @@ import { Args, Meta, StoryObj } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html, nothing } from 'lit-html'; +import { ifDefined } from 'lit-html/directives/if-defined.js'; import mdx from './bq-steps.mdx'; import { STEPS_SIZE, STEPS_TYPE } from '../bq-steps.types'; @@ -13,39 +14,124 @@ const meta: Meta = { }, }, argTypes: { - text: { control: 'text', table: { disable: true } }, + 'divider-color': { control: 'text' }, type: { control: 'select', options: [...STEPS_TYPE] }, size: { control: 'select', options: [...STEPS_SIZE] }, - bqClick: { action: 'bqClick' }, + // Not part of the public API + children: { control: 'text', table: { disable: true } }, + icon: { control: 'text', table: { disable: true } }, + title: { control: 'text', table: { disable: true } }, + description: { control: 'text', table: { disable: true } }, }, args: { + 'divider-color': 'ui--secondary', text: 'text', - type: 'numeric', size: 'medium', }, }; export default meta; const Template = (args: Args) => { - return html` - - - step item 1 - description for step - - - - step item 2 with longerlongerlongerlongerlonger title - description for step - - - - title - description for step 3 - - `; + return html` + + ${ifDefined(args.children) ? args.children : nothing} + + `; +}; + +export const Dots: StoryObj = { + render: Template, + args: { + type: 'dot', + children: html` + + + Title + Description + + + + Title + Description + + + + Title + Description + + + + Title + Description + + + + Title + Description + + `, + }, +}; + +export const Icons: StoryObj = { + render: Template, + args: { + type: 'icon', + children: html` + + + Flight + Reserve your flight + + + + Accommodation + Reserve your accommodation + + + + Rent a car + There was an error with your reservation + + + + Enjoy your holidays! + You're ready for your vacations + + `, + }, }; -export const Default: StoryObj = { +export const Numbers: StoryObj = { render: Template, + args: { + type: 'numeric', + children: html` + + 1 + Title + Description + + + 2 + Title + Description + + + 3 + Title + Description + + + 4 + Title + Description + + + 4 + Title + Description + + `, + }, }; diff --git a/packages/beeq/src/shared/utils/props.ts b/packages/beeq/src/shared/utils/props.ts index fc23628a6..a3d357e37 100644 --- a/packages/beeq/src/shared/utils/props.ts +++ b/packages/beeq/src/shared/utils/props.ts @@ -5,7 +5,7 @@ export type TValidProperty = TExtractProp<{ [K in keyof E]: E[K] extends T * Validate the element property value, if is one of the accepted values * * @param {readonly} ACCEPTED_VALUES - The list of the accepted values to check against. - * @param {unknow} fallbackValue - The default value to assign + * @param {unknown} fallbackValue - The default value to assign * @param {Element} element - The component reference * @param {string} propertyName - The property name (will be used in the console notification) * @returns {void} @@ -17,7 +17,7 @@ export const validatePropValue = ( propertyName: TValidProperty, ): void => { const propertyValue = element[propertyName as string]; - // Early return if the property value is one of the accetped values + // Early return if the property value is one of the accepted values if (ACCEPTED_VALUES.includes(propertyValue)) return; // Override property with fallback value element[propertyName as string] = fallbackValue; From cb0c9dce0fb758d4a97faf48555c3880ebbe672f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dabiel=20Gonz=C3=A1lez=20Ramos?= Date: Fri, 6 Oct 2023 19:27:30 +0300 Subject: [PATCH 12/13] test: update e2e test and fix minor typos --- packages/beeq/src/components.d.ts | 12 +--- .../src/components/divider/bq-divider.tsx | 4 +- .../beeq/src/components/divider/readme.md | 4 +- .../step-item/__tests__/bq-step-item.e2e.ts | 68 ++++++++++--------- .../src/components/step-item/bq-step-item.tsx | 2 +- .../beeq/src/components/step-item/readme.md | 2 +- .../steps/__tests__/bq-steps.e2e.ts | 44 +++++------- .../steps/_storybook/bq-steps.stories.tsx | 4 -- .../beeq/src/components/steps/bq-steps.tsx | 10 +-- packages/beeq/src/components/steps/readme.md | 7 -- 10 files changed, 60 insertions(+), 97 deletions(-) diff --git a/packages/beeq/src/components.d.ts b/packages/beeq/src/components.d.ts index 48d496a9f..b5f200812 100644 --- a/packages/beeq/src/components.d.ts +++ b/packages/beeq/src/components.d.ts @@ -277,7 +277,7 @@ export namespace Components { */ "strokeDashWidth"?: number; /** - * Set the lineap of the divider's stroke. This is applicable when the stroke is dashed + * Set the line of the divider's stroke. This is applicable when the stroke is dashed */ "strokeLinecap"?: TDividerStrokeLinecap; /** @@ -1132,10 +1132,6 @@ export interface BqStepItemCustomEvent extends CustomEvent { detail: T; target: HTMLBqStepItemElement; } -export interface BqStepsCustomEvent extends CustomEvent { - detail: T; - target: HTMLBqStepsElement; -} export interface BqSwitchCustomEvent extends CustomEvent { detail: T; target: HTMLBqSwitchElement; @@ -1673,7 +1669,7 @@ declare namespace LocalJSX { */ "strokeDashWidth"?: number; /** - * Set the lineap of the divider's stroke. This is applicable when the stroke is dashed + * Set the line of the divider's stroke. This is applicable when the stroke is dashed */ "strokeLinecap"?: TDividerStrokeLinecap; /** @@ -2285,10 +2281,6 @@ declare namespace LocalJSX { * The color of the line that connects the steps. It should be a valid declarative color token. */ "dividerColor"?: string; - /** - * Handler to be called when the tab value changes - */ - "onBqChange"?: (event: BqStepsCustomEvent<{ target: HTMLBqStepItemElement; value: string }>) => void; /** * The size of the steps */ diff --git a/packages/beeq/src/components/divider/bq-divider.tsx b/packages/beeq/src/components/divider/bq-divider.tsx index 823ff819d..0a835d8cc 100644 --- a/packages/beeq/src/components/divider/bq-divider.tsx +++ b/packages/beeq/src/components/divider/bq-divider.tsx @@ -23,7 +23,7 @@ const strokeDrawPositions = { /** * @part base - The component's internal wrapper. * @part dash-start - The component's internal svg wrapper for the start line of the divider's stroke - * @part dash-end - The componet's internal svg wrapper for the end line of the divider's stroke + * @part dash-end - The component's internal svg wrapper for the end line of the divider's stroke * @part dash-start-line - The component's internal line component of the divider's stroke * @part dash-end-line - The component's internal line component of the divider's stroke */ @@ -76,7 +76,7 @@ export class BqDivider { /** Set the min width of the divider's stroke when text is not centered. Value expressed in px */ @Prop({ reflect: true }) strokeBasis?: number = 20; - /** Set the lineap of the divider's stroke. This is applicable when the stroke is dashed */ + /** Set the line of the divider's stroke. This is applicable when the stroke is dashed */ @Prop({ reflect: true }) strokeLinecap?: TDividerStrokeLinecap = 'butt'; // Prop lifecycle events diff --git a/packages/beeq/src/components/divider/readme.md b/packages/beeq/src/components/divider/readme.md index 6602fa438..93e71613d 100644 --- a/packages/beeq/src/components/divider/readme.md +++ b/packages/beeq/src/components/divider/readme.md @@ -13,7 +13,7 @@ | `strokeColor` | `stroke-color` | Set the stroke color of the divider. The value should be a valid value of the palette color | `string` | `'stroke--secondary'` | | `strokeDashGap` | `stroke-dash-gap` | Set the gap of the divider's stroke. This is applicable when the stroke is dashed | `number` | `7` | | `strokeDashWidth` | `stroke-dash-width` | Set the width of each dash of the divider's stroke. This is applicable when the stroke is dashed | `number` | `12` | -| `strokeLinecap` | `stroke-linecap` | Set the lineap of the divider's stroke. This is applicable when the stroke is dashed | `"butt" \| "round" \| "square"` | `'butt'` | +| `strokeLinecap` | `stroke-linecap` | Set the line of the divider's stroke. This is applicable when the stroke is dashed | `"butt" \| "round" \| "square"` | `'butt'` | | `strokeThickness` | `stroke-thickness` | Set the thickness of the divider's stroke. Value expressed in px | `number` | `2` | | `titleAlignment` | `title-alignment` | Set the alignment of the title on the main axis of the divider (horizontal / vertical) | `"end" \| "middle" \| "start"` | `'middle'` | @@ -23,7 +23,7 @@ | Part | Description | | ------------------- | ------------------------------------------------------------------------------- | | `"base"` | The component's internal wrapper. | -| `"dash-end"` | The componet's internal svg wrapper for the end line of the divider's stroke | +| `"dash-end"` | The component's internal svg wrapper for the end line of the divider's stroke | | `"dash-end-line"` | The component's internal line component of the divider's stroke | | `"dash-start"` | The component's internal svg wrapper for the start line of the divider's stroke | | `"dash-start-line"` | The component's internal line component of the divider's stroke | diff --git a/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts b/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts index a92454671..d17686c54 100644 --- a/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts +++ b/packages/beeq/src/components/step-item/__tests__/bq-step-item.e2e.ts @@ -3,72 +3,75 @@ import { newE2EPage } from '@stencil/core/testing'; describe('bq-step-item', () => { it('should render', async () => { const page = await newE2EPage({ - html: ` - - `, + html: ``, }); const element = await page.find('bq-step-item'); - expect(element).toHaveClass('hydrated'); }); it('should have shadow root', async () => { const page = await newE2EPage({ - html: ` - - `, + html: ``, }); const element = await page.find('bq-step-item'); - expect(element.shadowRoot).not.toBeNull(); }); - it('should display text', async () => { + it('should display text title', async () => { + const title = 'Title'; + const description = 'Description for step item'; + const page = await newE2EPage({ - html: ` - - step item 1 - Description for step 1 - - `, + html: ` + + ${title} + ${description} + + `, }); const text = await page.$eval('bq-step-item', (element) => { - const slotElement = element.shadowRoot.querySelector('slot'); + const slotElement = element.shadowRoot.querySelector('.bq-step-item__content--title').querySelector('slot'); const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; return assignedElements.textContent; }); - - expect(text).toEqualText('step item 1'); + expect(text).toEqualText(title); }); it('should display description', async () => { + const title = 'Title'; + const description = 'Description for step item'; + const page = await newE2EPage({ html: ` - - - step item - Description for step item + + ${title} + ${description} - `, + `, }); - const description = await page.find('bq-step-item >>> slot[name="description"]'); - expect(description).not.toBeNull(); + const text = await page.$eval('bq-step-item', (element) => { + const slotElement = element.shadowRoot.querySelector('slot[name="description"]'); + const assignedElements = (slotElement as HTMLSlotElement).assignedElements({ flatten: true })[0]; + + return assignedElements.textContent; + }); + expect(text).toEqualText(description); }); it('should display icon prefix', async () => { const page = await newE2EPage({ - html: ` - - - step item 1 - Description for step 1 - - `, + html: ` + + + Title + Description + + `, }); const prefix = await page.$eval('bq-step-item', (element) => { @@ -77,7 +80,6 @@ describe('bq-step-item', () => { return assignedElements.tagName; }); - expect(prefix).toMatch(/bq-icon/i); }); }); diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index 1a274363b..a7b282150 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -25,7 +25,7 @@ export class BqStepItem { // ======================== /** It defines prefix size */ - @Prop({ reflect: true }) size?: TStepsSize; + @Prop({ reflect: true }) size?: TStepsSize = 'medium'; /** It defines step item appearance based on its status */ @Prop({ reflect: true }) status?: TStepItemStatus = 'default'; diff --git a/packages/beeq/src/components/step-item/readme.md b/packages/beeq/src/components/step-item/readme.md index 20c24f132..a92a383c1 100644 --- a/packages/beeq/src/components/step-item/readme.md +++ b/packages/beeq/src/components/step-item/readme.md @@ -9,7 +9,7 @@ | Property | Attribute | Description | Type | Default | | -------- | --------- | --------------------------------------------------- | ---------------------------------------------------------------- | ----------- | -| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `undefined` | +| `size` | `size` | It defines prefix size | `"medium" \| "small"` | `'medium'` | | `status` | `status` | It defines step item appearance based on its status | `"completed" \| "current" \| "default" \| "disabled" \| "error"` | `'default'` | | `type` | `type` | It defines the step item type used | `"dot" \| "icon" \| "numeric"` | `undefined` | diff --git a/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts b/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts index fa773e809..86aa1699b 100644 --- a/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts +++ b/packages/beeq/src/components/steps/__tests__/bq-steps.e2e.ts @@ -4,58 +4,46 @@ describe('bq-steps', () => { it('should render', async () => { const page = await newE2EPage({ html: ` - - - - Step 1 - Description for step 1 + + + + Title + Description `, }); const element = await page.find('bq-steps'); - expect(element).toHaveClass('hydrated'); }); it('should have shadow root', async () => { const page = await newE2EPage({ - html: ``, + html: ``, }); const element = await page.find('bq-steps'); - expect(element.shadowRoot).not.toBeNull(); }); - it('should emit bqChange on step item click', async () => { - const page = await newE2EPage({ - html: ` - - `, - }); - - const stepItem = await page.find('bq-step-item'); - const bqChange = await page.spyOnEvent('bqChange'); - - await stepItem.click(); - - expect(bqChange).toHaveReceivedEventTimes(1); - }); - it('should render the correct number of steps', async () => { const page = await newE2EPage({ html: ` - - Step 1 - Step 2 + + + 1 + Title + + + 2 + Title + `, }); const steps = await page.findAll('bq-step-item'); - - expect(steps.length).toBe(2); + expect(steps).toHaveLength(2); }); }); diff --git a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx index 8ef396b23..b9d1ad2c0 100644 --- a/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx +++ b/packages/beeq/src/components/steps/_storybook/bq-steps.stories.tsx @@ -19,13 +19,9 @@ const meta: Meta = { size: { control: 'select', options: [...STEPS_SIZE] }, // Not part of the public API children: { control: 'text', table: { disable: true } }, - icon: { control: 'text', table: { disable: true } }, - title: { control: 'text', table: { disable: true } }, - description: { control: 'text', table: { disable: true } }, }, args: { 'divider-color': 'ui--secondary', - text: 'text', size: 'medium', }, }; diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index 87069131e..fdd258b55 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -1,4 +1,4 @@ -import { Component, Element, Event, EventEmitter, h, Listen, Prop, Watch } from '@stencil/core'; +import { Component, Element, h, Prop, Watch } from '@stencil/core'; import { STEPS_SIZE, STEPS_TYPE, TStepsSize, TStepsType } from './bq-steps.types'; import { validatePropValue } from '../../shared/utils'; @@ -53,9 +53,6 @@ export class BqSteps { // Requires JSDocs for public API documentation // ============================================== - /** Handler to be called when the tab value changes */ - @Event() bqChange: EventEmitter<{ target: HTMLBqStepItemElement; value: string }>; - // Component lifecycle events // Ordered by their natural call order // ===================================== @@ -67,11 +64,6 @@ export class BqSteps { // Listeners // ============== - @Listen('bqClick') - onBqStepItemChange(event: CustomEvent<{ target: HTMLBqStepItemElement; value: string }>) { - this.bqChange.emit(event.detail); - } - // Public methods API // These methods are exposed on the host element. // Always use two lines. diff --git a/packages/beeq/src/components/steps/readme.md b/packages/beeq/src/components/steps/readme.md index 9e43179ff..6244febdb 100644 --- a/packages/beeq/src/components/steps/readme.md +++ b/packages/beeq/src/components/steps/readme.md @@ -14,13 +14,6 @@ | `type` | `type` | The type of prefix element to use on the step items | `"dot" \| "icon" \| "numeric"` | `undefined` | -## Events - -| Event | Description | Type | -| ---------- | ----------------------------------------------- | ---------------------------------------------------------------- | -| `bqChange` | Handler to be called when the tab value changes | `CustomEvent<{ target: HTMLBqStepItemElement; value: string; }>` | - - ## Shadow Parts | Part | Description | From 856bbbdff7e46478122173f2aeb9e80dcbe1ae02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dabiel=20Gonz=C3=A1lez=20Ramos?= Date: Fri, 6 Oct 2023 19:50:48 +0300 Subject: [PATCH 13/13] docs: missing shadow DOM parts --- .../beeq/src/components/step-item/bq-step-item.tsx | 5 +++++ packages/beeq/src/components/step-item/readme.md | 10 +++++----- .../step-item/scss/bq-step-item.variables.scss | 9 +++++++++ packages/beeq/src/components/steps/bq-steps.tsx | 4 ++++ packages/beeq/src/components/steps/readme.md | 9 ++++++--- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index a7b282150..8e99b088d 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -4,6 +4,11 @@ import { STEP_ITEM_STATUS, TStepItemStatus } from './bq-step-item.types'; import { isHTMLElement, validatePropValue } from '../../shared/utils'; import { STEPS_SIZE, TStepsSize, TStepsType } from '../steps/bq-steps.types'; +/** + * @part base - The component's base wrapper. + * @part title - The component's title. + * @part description - The component's description. + */ @Component({ tag: 'bq-step-item', styleUrl: './scss/bq-step-item.scss', diff --git a/packages/beeq/src/components/step-item/readme.md b/packages/beeq/src/components/step-item/readme.md index a92a383c1..bc6a21815 100644 --- a/packages/beeq/src/components/step-item/readme.md +++ b/packages/beeq/src/components/step-item/readme.md @@ -23,11 +23,11 @@ ## Shadow Parts -| Part | Description | -| --------------- | ----------- | -| `"base"` | | -| `"description"` | | -| `"title"` | | +| Part | Description | +| --------------- | ----------------------------- | +| `"base"` | The component's base wrapper. | +| `"description"` | The component's description. | +| `"title"` | The component's title. | ---------------------------------------------- diff --git a/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss b/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss index 07243babe..70f9ee8b1 100644 --- a/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss +++ b/packages/beeq/src/components/step-item/scss/bq-step-item.variables.scss @@ -3,6 +3,15 @@ /* -------------------------------------------------------------------------- */ :host { + /** + * @prop --bq-step-item--prefix-color - Color of the prefix icon + * @prop --bq-step-item--prefix-color-current - Color of the prefix icon when current + * @prop --bq-step-item--prefix-color-completed - Color of the prefix icon when completed + * @prop --bq-step-item--prefix-color-error - Color of the prefix icon when error + * @prop --bq-step-item--prefix-color-disabled - Color of the prefix icon when disabled + * @prop --bq-step-item--prefix-num-size - Size of the prefix number + * @prop --bq-step-item--prefix-num-bg-color - Background color of the prefix number + */ --bq-step-item--prefix-color: theme('colors.icon.secondary'); --bq-step-item--prefix-color-current: theme('colors.icon.brand'); --bq-step-item--prefix-color-completed: theme('colors.icon.success'); diff --git a/packages/beeq/src/components/steps/bq-steps.tsx b/packages/beeq/src/components/steps/bq-steps.tsx index fdd258b55..9a768b3f7 100644 --- a/packages/beeq/src/components/steps/bq-steps.tsx +++ b/packages/beeq/src/components/steps/bq-steps.tsx @@ -5,6 +5,9 @@ import { validatePropValue } from '../../shared/utils'; /** * @part container - The container wrapper of the Steps component + * @part divider-base - The base wrapper of the divider component + * @part divider-dash-start - The dash start wrapper of the divider component + * @part divider-dash-end - The dash end wrapper of the divider component */ @Component({ tag: 'bq-steps', @@ -113,6 +116,7 @@ export class BqSteps {
); diff --git a/packages/beeq/src/components/steps/readme.md b/packages/beeq/src/components/steps/readme.md index 6244febdb..37b332e0e 100644 --- a/packages/beeq/src/components/steps/readme.md +++ b/packages/beeq/src/components/steps/readme.md @@ -16,9 +16,12 @@ ## Shadow Parts -| Part | Description | -| ------------- | -------------------------------------------- | -| `"container"` | The container wrapper of the Steps component | +| Part | Description | +| ---------------------- | ----------------------------------------------- | +| `"container"` | The container wrapper of the Steps component | +| `"divider-base"` | The base wrapper of the divider component | +| `"divider-dash-end"` | The dash end wrapper of the divider component | +| `"divider-dash-start"` | The dash start wrapper of the divider component | ## Dependencies