diff --git a/first-gen/packages/badge/src/Badge.ts b/first-gen/packages/badge/src/Badge.ts index 5bf63063d94..740e8056f02 100644 --- a/first-gen/packages/badge/src/Badge.ts +++ b/first-gen/packages/badge/src/Badge.ts @@ -17,12 +17,46 @@ import { TemplateResult, } from '@spectrum-web-components/base'; -import { BadgeBase } from '@swc/core/components/badge'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; + +import { + BADGE_VARIANTS_COLOR_S1, + BADGE_VARIANTS_S1, + BadgeBase, + type BadgeVariantS1, + FIXED_VALUES as FIXED_VALUES_BASE, + type FixedValues as FixedValuesBase, +} from '@swc/core/components/badge'; + import styles from './badge.css.js'; -// Export types and values to avoid breaking changes -export { BADGE_VARIANTS, FIXED_VALUES } from '@swc/core/components/badge'; -export type { BadgeVariant, FixedValues } from '@swc/core/components/badge'; +/** + * @deprecated The `BADGE_VARIANTS` export is deprecated and will be removed + * in a future release. If needed, you can access the internal + * `Badge.VARIANTS` property from the constructor. + */ +export const BADGE_VARIANTS = BADGE_VARIANTS_S1; + +/** + * @deprecated The `FIXED_VALUES` export is deprecated and will be removed + * in a future release. If needed, you can access the internal + * `Badge.FIXED_VALUES` property from the constructor. + */ +export const FIXED_VALUES = FIXED_VALUES_BASE; + +/** + * @deprecated The `BadgeVariant` type export is deprecated and will be removed + * in a future release. If needed, you can infer this type from the `Badge` + * prototype as follows: `typeof Badge.prototype.variant` + */ +export type BadgeVariant = BadgeVariantS1; + +/** + * @deprecated The `FixedValues` type export is deprecated and will be removed + * in a future release. If needed, you can infer this type from the `Badge` + * constructor as follows: `typeof Badge.FIXED_VALUES` + */ +export type FixedValues = FixedValuesBase; /** * @element sp-badge @@ -31,6 +65,30 @@ export type { BadgeVariant, FixedValues } from '@swc/core/components/badge'; * @slot icon - Optional icon that appears to the left of the label */ export class Badge extends BadgeBase { + // ──────────────────── + // API OVERRIDES + // ──────────────────── + + /** + * @internal + */ + static override readonly VARIANTS_COLOR = BADGE_VARIANTS_COLOR_S1; + + /** + * @internal + */ + static override readonly VARIANTS = BADGE_VARIANTS_S1; + + /** + * The variant of the badge. + */ + @property({ type: String, reflect: true }) + public override variant: BadgeVariantS1 = 'informative'; + + // ────────────────────────────── + // RENDERING & STYLING + // ────────────────────────────── + public static override get styles(): CSSResultArray { return [styles]; } diff --git a/first-gen/packages/progress-circle/src/ProgressCircle.ts b/first-gen/packages/progress-circle/src/ProgressCircle.ts index 77c73e43baa..f387cc45d3d 100644 --- a/first-gen/packages/progress-circle/src/ProgressCircle.ts +++ b/first-gen/packages/progress-circle/src/ProgressCircle.ts @@ -16,7 +16,12 @@ import { TemplateResult, } from '@spectrum-web-components/base'; import { ifDefined } from '@spectrum-web-components/base/src/directives.js'; -import { ProgressCircleBase } from '@swc/core/components/progress-circle'; +import { property } from '@spectrum-web-components/base/src/decorators.js'; +import { + PROGRESS_CIRCLE_STATIC_COLORS_S1, + ProgressCircleBase, + type ProgressCircleStaticColorS1, +} from '@swc/core/components/progress-circle'; import progressCircleStyles from './progress-circle.css.js'; @@ -24,6 +29,27 @@ import progressCircleStyles from './progress-circle.css.js'; * @element sp-progress-circle */ export class ProgressCircle extends ProgressCircleBase { + // ──────────────────── + // API OVERRIDES + // ──────────────────── + + /** + * @internal + */ + static override readonly STATIC_COLORS = PROGRESS_CIRCLE_STATIC_COLORS_S1; + + /** + * Static color variant for use on different backgrounds. + * + * When set to 'white', the component uses white styling for images with a dark tinted background. + */ + @property({ type: String, reflect: true, attribute: 'static-color' }) + public override staticColor?: ProgressCircleStaticColorS1; + + // ────────────────────────────── + // RENDERING & STYLING + // ────────────────────────────── + public static override get styles(): CSSResultArray { return [progressCircleStyles]; } diff --git a/second-gen/packages/core/components/badge/Badge.base.ts b/second-gen/packages/core/components/badge/Badge.base.ts index d360ada0387..73d3765d60c 100644 --- a/second-gen/packages/core/components/badge/Badge.base.ts +++ b/second-gen/packages/core/components/badge/Badge.base.ts @@ -16,41 +16,21 @@ import { SizedMixin, SpectrumElement } from '@swc/core/shared/base'; import { ObserveSlotPresence } from '@swc/core/shared/observe-slot-presence'; import { ObserveSlotText } from '@swc/core/shared/observe-slot-text'; -export const BADGE_VARIANTS = [ - 'accent', - 'neutral', - 'informative', - 'positive', - 'negative', - 'notice', - 'fuchsia', - 'indigo', - 'magenta', - 'purple', - 'seafoam', - 'yellow', - 'gray', - 'red', - 'orange', - 'chartreuse', - 'celery', - 'green', - 'cyan', - 'blue', -] as const; -export type BadgeVariant = (typeof BADGE_VARIANTS)[number]; -export const FIXED_VALUES = [ - 'inline-start', - 'inline-end', - 'block-start', - 'block-end', -] as const; -export type FixedValues = (typeof FIXED_VALUES)[number]; +import { + BADGE_VARIANTS_SEMANTIC, + type BadgeVariant, + FIXED_VALUES, + type FixedValues, +} from './Badge.types'; /** - * @element sp-badge-base - * @slot - The text label to display in the badge. - * @slot icon - The icon to display in the badge. + * A badge component that displays short, descriptive information about an element. + * Badges are typically used to indicate status, categories, or provide supplementary information. + * + * @attribute {ElementSize} size - The size of the badge. + * + * @slot - Text label of the badge. + * @slot icon - Optional icon that appears to the left of the label */ export abstract class BadgeBase extends SizedMixin( ObserveSlotText(ObserveSlotPresence(SpectrumElement, '[slot="icon"]'), ''), @@ -58,9 +38,72 @@ export abstract class BadgeBase extends SizedMixin( noDefaultSize: true, } ) { + // ───────────────────────── + // API TO OVERRIDE + // ───────────────────────── + + /** + * @internal + * + * A readonly array of the valid color variants for the badge. + * + * This is an actual internal property, intended not for customer use + * but for use in internal validation logic, stories, tests, etc. + * + * Because S1 and S2 support different color variants, the value of this + * property must be set in each subclass. + */ + static readonly VARIANTS_COLOR: readonly string[]; + + /** + * @internal + * + * A readonly array of all valid variants for the badge. + * + * This is an actual internal property, intended not for customer use + * but for use in internal validation logic, stories, tests, etc. + * + * Because S1 and S2 support different variants, the value of this + * property must be set in each subclass. + */ + static readonly VARIANTS: readonly string[]; + + /** + * @internal + * + * The variant of the badge. + * + * This is a public property, but its valid values vary between S1 and S2, + * so the property (and its docs) need to be redefined in each subclass. + * + * The type declared here is a union of the valid values for S1 and S2, + * and should be narrowed in each subclass. + */ @property({ type: String, reflect: true }) public variant: BadgeVariant = 'informative'; + // ────────────────── + // SHARED API + // ────────────────── + + /** + * @internal + */ + static readonly FIXED_VALUES: readonly string[] = FIXED_VALUES; + + /** + * @internal + */ + static readonly VARIANTS_SEMANTIC: readonly string[] = + BADGE_VARIANTS_SEMANTIC; + + /** + * The fixed position of the badge. + * + * @todo The purpose of the bespoke getter and setter is unclear, as it + * looks like they may be behaving just like a standard Lit reactive + * property. Explore replacing after the Barebones milestone. + */ @property({ reflect: true }) public get fixed(): FixedValues | undefined { return this._fixed; @@ -82,6 +125,13 @@ export abstract class BadgeBase extends SizedMixin( private _fixed?: FixedValues; + // ────────────────────── + // IMPLEMENTATION + // ────────────────────── + + /** + * @internal Used for rendering gap when the badge has an icon. + */ protected get hasIcon(): boolean { return this.slotContentIsPresent; } @@ -89,13 +139,29 @@ export abstract class BadgeBase extends SizedMixin( protected override update(changedProperties: PropertyValues): void { super.update(changedProperties); if (window.__swc?.DEBUG) { - if (!BADGE_VARIANTS.includes(this.variant)) { + const constructor = this.constructor as typeof BadgeBase; + if (!constructor.VARIANTS.includes(this.variant)) { window.__swc.warn( this, `<${this.localName}> element expect the "variant" attribute to be one of the following:`, 'https://opensource.adobe.com/spectrum-web-components/components/badge/#variants', { - issues: [...BADGE_VARIANTS], + issues: [...constructor.VARIANTS], + } + ); + } + // Check outline property if it exists (S2 only) + if ( + 'outline' in this && + (this as { outline: boolean }).outline === true && + !constructor.VARIANTS_SEMANTIC.includes(this.variant) + ) { + window.__swc.warn( + this, + `<${this.localName}> element only supports the outline styling if the variant is a semantic color variant.`, + 'https://opensource.adobe.com/spectrum-web-components/components/badge/#variants', + { + issues: [...constructor.VARIANTS_SEMANTIC], } ); } diff --git a/second-gen/packages/core/components/badge/Badge.types.ts b/second-gen/packages/core/components/badge/Badge.types.ts new file mode 100644 index 00000000000..05cf282b0e8 --- /dev/null +++ b/second-gen/packages/core/components/badge/Badge.types.ts @@ -0,0 +1,73 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +/* + * @todo The S1 types can be removed once we are no longer maintaining 1st-gen. + */ + +export const FIXED_VALUES = [ + 'inline-start', + 'inline-end', + 'block-start', + 'block-end', +] as const; + +export type FixedValues = (typeof FIXED_VALUES)[number]; + +export const BADGE_VARIANTS_SEMANTIC = [ + 'accent', + 'neutral', + 'informative', + 'positive', + 'negative', + 'notice', +] as const; + +export const BADGE_VARIANTS_COLOR_S1 = [ + 'fuchsia', + 'indigo', + 'magenta', + 'purple', + 'seafoam', + 'yellow', + 'gray', + 'red', + 'orange', + 'chartreuse', + 'celery', + 'green', + 'cyan', + 'blue', +] as const; + +export const BADGE_VARIANTS_COLOR_S2 = [ + ...BADGE_VARIANTS_COLOR_S1, + 'pink', + 'turquoise', + 'brown', + 'cinnamon', + 'silver', +] as const; + +export const BADGE_VARIANTS_S1 = [ + ...BADGE_VARIANTS_SEMANTIC, + ...BADGE_VARIANTS_COLOR_S1, +] as const; + +export const BADGE_VARIANTS_S2 = [ + ...BADGE_VARIANTS_SEMANTIC, + ...BADGE_VARIANTS_COLOR_S2, +] as const; + +export type BadgeVariantS1 = (typeof BADGE_VARIANTS_S1)[number]; +export type BadgeVariantS2 = (typeof BADGE_VARIANTS_S2)[number]; +export type BadgeVariant = BadgeVariantS1 | BadgeVariantS2; diff --git a/second-gen/packages/core/components/badge/index.ts b/second-gen/packages/core/components/badge/index.ts index 2d8e0590dca..79b06143fcd 100644 --- a/second-gen/packages/core/components/badge/index.ts +++ b/second-gen/packages/core/components/badge/index.ts @@ -10,3 +10,4 @@ * governing permissions and limitations under the License. */ export * from './Badge.base'; +export * from './Badge.types'; diff --git a/second-gen/packages/core/components/progress-circle/ProgressCircle.base.ts b/second-gen/packages/core/components/progress-circle/ProgressCircle.base.ts index a8aea763660..9051b49cb13 100644 --- a/second-gen/packages/core/components/progress-circle/ProgressCircle.base.ts +++ b/second-gen/packages/core/components/progress-circle/ProgressCircle.base.ts @@ -15,11 +15,68 @@ import { property, query } from 'lit/decorators.js'; import { SizedMixin, SpectrumElement } from '@swc/core/shared/base'; import { getLabelFromSlot } from '@swc/core/shared/get-label-from-slot'; +import { + PROGRESS_CIRCLE_VALID_SIZES, + ProgressCircleStaticColor, +} from './ProgressCircle.types'; + +/** + * A progress circle component that visually represents the completion progress of a task. + * Can be used in both determinate (with specific progress value) and indeterminate (loading) states. + * + * @attribute {ElementSize} size - The size of the progress circle. + * + * @todo Why do we support both the slot and the label attribute? Should we deprecate the slot? + * + * @todo Figure out why our tool chain doesn't respect the line breaks in this slot description. + * + * @slot - Accessible label for the progress circle. + * + * Used to provide context about what is loading or progressing. + * + * @fires progress-change - Dispatched when the progress value changes + */ export abstract class ProgressCircleBase extends SizedMixin(SpectrumElement, { - validSizes: ['s', 'm', 'l'], + validSizes: PROGRESS_CIRCLE_VALID_SIZES, }) { + // ───────────────────────── + // API TO OVERRIDE + // ───────────────────────── + + /** + * @internal + * + * A readonly array of the valid static colors for the progress circle. + * + * This is an actual internal property, intended not for customer use + * but for use in internal validation logic, stories, tests, etc. + * + * Because S1 and S2 support different static colors, the value of this + * property must be set in each subclass. + */ + static readonly STATIC_COLORS: readonly string[]; + + /** + * @internal + * + * Static color variant for use on different backgrounds. + * + * This is a public property, but its valid values vary between S1 and S2, + * so the property (and its docs) need to be redefined in each subclass. + * + * The type declared here is a union of the valid values for S1 and S2, + * and should be narrowed in each subclass. + */ + @property({ type: String, reflect: true, attribute: 'static-color' }) + public staticColor?: ProgressCircleStaticColor; + + // ────────────────── + // SHARED API + // ────────────────── + /** * Whether the progress circle shows indeterminate progress (loading state). + * * When true, displays an animated loading indicator instead of a specific progress value. */ @property({ type: Boolean, reflect: true }) @@ -27,25 +84,27 @@ export abstract class ProgressCircleBase extends SizedMixin(SpectrumElement, { /** * Accessible label for the progress circle. + * * Used to provide context about what is loading or progressing. */ @property({ type: String }) public label = ''; - /** - * Static color variant for use on different backgrounds. - * When set to 'white', the component uses white styling for dark backgrounds. - */ - @property({ reflect: true, attribute: 'static-color' }) - public staticColor?: 'white'; - /** * Progress value from 0 to 100. + * * Only relevant when indeterminate is false. */ @property({ type: Number }) public progress = 0; + // ────────────────────── + // IMPLEMENTATION + // ────────────────────── + + /** + * @internal + */ @query('slot') private slotEl!: HTMLSlotElement; diff --git a/second-gen/packages/core/components/progress-circle/ProgressCircle.types.ts b/second-gen/packages/core/components/progress-circle/ProgressCircle.types.ts new file mode 100644 index 00000000000..8e078003ad0 --- /dev/null +++ b/second-gen/packages/core/components/progress-circle/ProgressCircle.types.ts @@ -0,0 +1,32 @@ +/** + * Copyright 2025 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { ElementSize } from '@swc/core/shared/base'; + +export const PROGRESS_CIRCLE_VALID_SIZES: ElementSize[] = [ + 's', + 'm', + 'l', +] as const; +export const PROGRESS_CIRCLE_STATIC_COLORS_S1 = ['white'] as const; +export const PROGRESS_CIRCLE_STATIC_COLORS_S2 = [ + ...PROGRESS_CIRCLE_STATIC_COLORS_S1, + 'black', +] as const; + +export type ProgressCircleStaticColorS1 = + (typeof PROGRESS_CIRCLE_STATIC_COLORS_S1)[number]; +export type ProgressCircleStaticColorS2 = + (typeof PROGRESS_CIRCLE_STATIC_COLORS_S2)[number]; +export type ProgressCircleStaticColor = + | ProgressCircleStaticColorS1 + | ProgressCircleStaticColorS2; diff --git a/second-gen/packages/core/components/progress-circle/index.ts b/second-gen/packages/core/components/progress-circle/index.ts index 0673f7680ab..1b9c3877e9c 100644 --- a/second-gen/packages/core/components/progress-circle/index.ts +++ b/second-gen/packages/core/components/progress-circle/index.ts @@ -10,3 +10,4 @@ * governing permissions and limitations under the License. */ export * from './ProgressCircle.base'; +export * from './ProgressCircle.types'; diff --git a/second-gen/packages/core/shared/base/sizedMixin.ts b/second-gen/packages/core/shared/base/sizedMixin.ts index 173a7a3631c..c596dfea3e2 100644 --- a/second-gen/packages/core/shared/base/sizedMixin.ts +++ b/second-gen/packages/core/shared/base/sizedMixin.ts @@ -34,6 +34,10 @@ export interface SizedElementInterface { size: ElementSize; } +export interface SizedElementConstructor { + readonly VALID_SIZES: ElementSize[]; +} + export function SizedMixin>( constructor: T, { @@ -45,8 +49,13 @@ export function SizedMixin>( noDefaultSize?: boolean; defaultSize?: ElementSize; } = {} -): T & Constructor { +): T & Constructor & SizedElementConstructor { class SizedElement extends constructor { + /** + * @internal + */ + static readonly VALID_SIZES: ElementSize[] = validSizes; + @property({ type: String }) public get size(): ElementSize { return this._size || defaultSize; diff --git a/second-gen/packages/core/vite.config.js b/second-gen/packages/core/vite.config.js index a13c51d3f5a..eb48e207a45 100644 --- a/second-gen/packages/core/vite.config.js +++ b/second-gen/packages/core/vite.config.js @@ -95,7 +95,11 @@ export default defineConfig({ }, rollupOptions: { external: (id) => { - return id === 'lit' || id.startsWith('@swc/core/'); + return ( + id === 'lit' || + id.startsWith('@lit/') || + id.startsWith('@swc/core/') + ); }, output: { preserveModules: true, diff --git a/second-gen/packages/swc/.storybook/preview.ts b/second-gen/packages/swc/.storybook/preview.ts index ad1451291da..f5db9158f8d 100644 --- a/second-gen/packages/swc/.storybook/preview.ts +++ b/second-gen/packages/swc/.storybook/preview.ts @@ -4,11 +4,31 @@ import '../tokens/light-vars.css'; import '../tokens/medium-vars.css'; import '../tokens/global-vars.css'; -// import { setCustomElementsManifest } from '@storybook/web-components'; -// import customElements from './custom-elements.json'; +import { setCustomElementsManifest } from '@storybook/web-components'; +import { + setStorybookHelpersConfig, + type Options, +} from '@wc-toolkit/storybook-helpers'; +import customElements from './custom-elements.json'; -// // Set the Custom Elements Manifest for automatic controls generation -// setCustomElementsManifest(customElements); +const options: Options = { + categoryOrder: [ + 'attributes', + 'properties', + 'slots', + 'cssProps', + 'cssParts', + 'events', + 'methods', + ], + hideArgRef: true, + renderDefaultValues: true, +}; + +setStorybookHelpersConfig(options); + +// Set the Custom Elements Manifest for automatic controls generation +setCustomElementsManifest(customElements); const preview = { parameters: { diff --git a/second-gen/packages/swc/components/badge/Badge.ts b/second-gen/packages/swc/components/badge/Badge.ts index 950baf098d0..c90659c9ac6 100644 --- a/second-gen/packages/swc/components/badge/Badge.ts +++ b/second-gen/packages/swc/components/badge/Badge.ts @@ -10,31 +10,25 @@ * governing permissions and limitations under the License. */ -import { CSSResultArray, html, nothing, TemplateResult } from 'lit'; +import { CSSResultArray, html, TemplateResult } from 'lit'; +import { property } from 'lit/decorators.js'; +import { classMap } from 'lit/directives/class-map.js'; +import { when } from 'lit/directives/when.js'; -import { BadgeBase } from '@swc/core/components/badge'; +import { + BADGE_VARIANTS_COLOR_S2, + BADGE_VARIANTS_S2, + BadgeBase, + type BadgeVariantS2 as BadgeVariant, +} from '@swc/core/components/badge'; import styles from './badge.css'; -// Export types and values to avoid breaking changes -export { BADGE_VARIANTS, FIXED_VALUES } from '@swc/core/components/badge'; -export type { BadgeVariant, FixedValues } from '@swc/core/components/badge'; - /** * A badge component that displays short, descriptive information about an element. * Badges are typically used to indicate status, categories, or provide supplementary information. * * @element swc-badge - * @since 1.0.0 - * @status stable - * @github https://github.com/adobe/spectrum-web-components/tree/main/... - * @figma https://www.figma.com/design/... - * - * @slot - Text label of the badge - * @slot icon - Optional icon that appears to the left of the label - * - * @csspart label - The text content area of the badge - * @csspart icon - The icon area of the badge (when present) * * @example * New @@ -46,22 +40,88 @@ export type { BadgeVariant, FixedValues } from '@swc/core/components/badge'; * */ export class Badge extends BadgeBase { + // ──────────────────── + // API OVERRIDES + // ──────────────────── + + /** + * @internal + */ + static override readonly VARIANTS_COLOR = BADGE_VARIANTS_COLOR_S2; + + /** + * @internal + */ + static override readonly VARIANTS = BADGE_VARIANTS_S2; + + /** + * The variant of the badge. + */ + @property({ type: String, reflect: true }) + public override variant: BadgeVariant = 'informative'; + + // ─────────────────── + // API ADDITIONS + // ─────────────────── + + /** + * Whether the badge is subtle. + * + * @todo This can be moved to the base class once we are no longer maintaining 1st-gen. + */ + @property({ type: Boolean, reflect: true }) + public subtle: boolean = false; + + /** + * Whether the badge is outlined. + * + * Can only be used with semantic variants. + * + * @todo This can be moved to the base class once we are no longer maintaining 1st-gen. + */ + @property({ type: Boolean, reflect: true }) + public outline: boolean = false; + + // ────────────────────────────── + // RENDERING & STYLING + // ────────────────────────────── + public static override get styles(): CSSResultArray { return [styles]; } protected override render(): TemplateResult { return html` - ${this.hasIcon - ? html` - - ` - : nothing} -
- +
+ ${when( + this.hasIcon, + () => html` +
+ +
+ ` + )} +
+ +
`; } diff --git a/second-gen/packages/swc/components/badge/badge.css b/second-gen/packages/swc/components/badge/badge.css index 4c7871aa0bc..7dc3afde309 100644 --- a/second-gen/packages/swc/components/badge/badge.css +++ b/second-gen/packages/swc/components/badge/badge.css @@ -1,8 +1,9 @@ -/** - * Copyright 2025 Adobe. All rights reserved. +/*! + * Copyright 2024 Adobe. All rights reserved. + * * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * of the License at * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS @@ -11,9 +12,15 @@ */ :host { - --spectrum-badge-corner-radius: var(--spectrum-corner-radius-100); + display: inline-flex; +} + +.spectrum-Badge { + --spectrum-badge-border-width: var(--spectrum-border-width-200); + --spectrum-badge-border-color: transparent; --spectrum-badge-line-height: var(--spectrum-line-height-100); --spectrum-badge-line-height-cjk: var(--spectrum-cjk-line-height-100); + --spectrum-badge-font-weight: var(--spectrum-medium-font-weight); --spectrum-badge-label-icon-color: var(--spectrum-white); --spectrum-badge-background-color-default: var( --spectrum-neutral-subdued-background-color-default @@ -75,6 +82,122 @@ --spectrum-badge-background-color-magenta: var( --spectrum-magenta-background-color-default ); + --spectrum-badge-background-color-pink: var( + --spectrum-pink-background-color-default + ); + --spectrum-badge-background-color-turquoise: var( + --spectrum-turquoise-background-color-default + ); + --spectrum-badge-background-color-brown: var( + --spectrum-brown-background-color-default + ); + --spectrum-badge-background-color-cinnamon: var( + --spectrum-cinnamon-background-color-default + ); + --spectrum-badge-background-color-silver: var( + --spectrum-silver-background-color-default + ); + --spectrum-badge-subtle-label-icon-color: var(--spectrum-gray-1000); + --spectrum-badge-subtle-background-color-default: var( + --spectrum-neutral-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-accent: var( + --spectrum-accent-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-informative: var( + --spectrum-informative-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-negative: var( + --spectrum-negative-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-positive: var( + --spectrum-positive-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-notice: var( + --spectrum-notice-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-gray: var( + --spectrum-gray-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-red: var( + --spectrum-red-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-orange: var( + --spectrum-orange-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-yellow: var( + --spectrum-yellow-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-chartreuse: var( + --spectrum-chartreuse-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-celery: var( + --spectrum-celery-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-green: var( + --spectrum-green-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-seafoam: var( + --spectrum-seafoam-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-cyan: var( + --spectrum-cyan-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-blue: var( + --spectrum-blue-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-indigo: var( + --spectrum-indigo-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-purple: var( + --spectrum-purple-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-fuchsia: var( + --spectrum-fuchsia-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-magenta: var( + --spectrum-magenta-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-pink: var( + --spectrum-pink-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-turquoise: var( + --spectrum-turquoise-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-brown: var( + --spectrum-brown-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-cinnamon: var( + --spectrum-cinnamon-subtle-background-color-default + ); + --spectrum-badge-subtle-background-color-silver: var( + --spectrum-silver-subtle-background-color-default + ); + --spectrum-badge-outline-label-icon-color: var(--spectrum-gray-1000); + --spectrum-badge-outline-background-color: var( + --spectrum-background-layer-2-color + ); + --spectrum-badge-outline-border-color-neutral: var( + --spectrum-neutral-visual-color + ); + --spectrum-badge-outline-border-color-accent: var( + --spectrum-accent-visual-color + ); + --spectrum-badge-outline-border-color-informative: var( + --spectrum-informative-visual-color + ); + --spectrum-badge-outline-border-color-negative: var( + --spectrum-negative-visual-color + ); + --spectrum-badge-outline-border-color-notice: var( + --spectrum-notice-visual-color + ); + --spectrum-badge-outline-border-color-positive: var( + --spectrum-positive-visual-color + ); + --spectrum-badge-corner-radius: var( + --spectrum-corner-radius-medium-size-medium + ); --spectrum-badge-height: var(--spectrum-component-height-100); --spectrum-badge-font-size: var(--spectrum-font-size-100); --spectrum-badge-label-spacing-vertical-top: var( @@ -100,29 +223,18 @@ --highcontrast-badge-border-color: CanvasText; } -:host([variant='celery']), -:host([variant='chartreuse']), -:host([variant='orange']), -:host([variant='yellow']) { +.spectrum-Badge--celery, +.spectrum-Badge--chartreuse, +.spectrum-Badge--notice, +.spectrum-Badge--orange, +.spectrum-Badge--yellow { --spectrum-badge-label-icon-color: var(--spectrum-black); } -:host([variant='blue']), -:host([variant='cyan']), -:host([variant='fuchsia']), -:host([variant='gray']), -:host([variant='green']), -:host([variant='indigo']), -:host([variant='magenta']), -:host([variant='purple']), -:host([variant='red']), -:host([variant='seafoam']) { - --spectrum-badge-label-icon-color: var( - --spectrum-badge-label-icon-color-primary +.spectrum-Badge--sizeS { + --spectrum-badge-corner-radius: var( + --spectrum-corner-radius-medium-size-small ); -} - -:host([size='s']) { --spectrum-badge-height: var(--spectrum-component-height-75); --spectrum-badge-font-size: var(--spectrum-font-size-75); --spectrum-badge-label-spacing-vertical-top: var( @@ -147,7 +259,10 @@ ); } -:host([size='l']) { +.spectrum-Badge--sizeL { + --spectrum-badge-corner-radius: var( + --spectrum-corner-radius-medium-size-large + ); --spectrum-badge-height: var(--spectrum-component-height-100); --spectrum-badge-font-size: var(--spectrum-font-size-200); --spectrum-badge-label-spacing-vertical-top: var( @@ -172,7 +287,10 @@ ); } -:host([size='xl']) { +.spectrum-Badge--sizeXL { + --spectrum-badge-corner-radius: var( + --spectrum-corner-radius-medium-size-extra-large + ); --spectrum-badge-height: var(--spectrum-component-height-100); --spectrum-badge-font-size: var(--spectrum-font-size-300); --spectrum-badge-label-spacing-vertical-top: var( @@ -198,328 +316,348 @@ } @media (forced-colors: active) { - :host { + .spectrum-Badge { border-color: var(--highcontrast-badge-border-color); } } -:host { - min-block-size: var(--mod-badge-height, var(--spectrum-badge-height)); +.spectrum-Badge { + min-block-size: var(--spectrum-badge-height); inline-size: auto; - vertical-align: middle; - cursor: default; - -webkit-font-smoothing: subpixel-antialiased; - -moz-osx-font-smoothing: auto; - border-radius: var( - --mod-badge-corner-radius, - var(--spectrum-badge-corner-radius) - ); - color: var( - --mod-badge-label-icon-color, - var(--spectrum-badge-label-icon-color) - ); - border: 1px solid #0000; display: inline-flex; + vertical-align: middle; position: relative; + cursor: default; + border: var(--spectrum-badge-border-width) solid + var(--spectrum-badge-border-color); + border-radius: var(--spectrum-badge-corner-radius); + background: var(--spectrum-badge-background-color-default); + color: var(--spectrum-badge-label-icon-color); + background-origin: border-box; + align-self: start; } -:host, -:host([variant='neutral']) { - background: var( - --mod-badge-background-color-default, - var(--spectrum-badge-background-color-default) - ); +.spectrum-Badge--neutral { + background: var(--spectrum-badge-background-color-default); } -:host([variant='accent']) { - background: var( - --mod-badge-background-color-accent, - var(--spectrum-badge-background-color-accent) - ); +.spectrum-Badge--accent { + background: var(--spectrum-badge-background-color-accent); } -:host([variant='informative']) { - background: var( - --mod-badge-background-color-informative, - var(--spectrum-badge-background-color-informative) - ); +.spectrum-Badge--informative { + background: var(--spectrum-badge-background-color-informative); } -:host([variant='negative']) { - background: var( - --mod-badge-background-color-negative, - var(--spectrum-badge-background-color-negative) - ); +.spectrum-Badge--negative { + background: var(--spectrum-badge-background-color-negative); } -:host([variant='positive']) { - background: var( - --mod-badge-background-color-positive, - var(--spectrum-badge-background-color-positive) - ); +.spectrum-Badge--positive { + background: var(--spectrum-badge-background-color-positive); } -:host([variant='notice']) { - background: var( - --mod-badge-background-color-notice, - var(--spectrum-badge-background-color-notice) - ); +.spectrum-Badge--notice { + background: var(--spectrum-badge-background-color-notice); } -:host([variant='gray']) { - background: var( - --mod-badge-background-color-gray, - var(--spectrum-badge-background-color-gray) - ); +.spectrum-Badge--gray { + background: var(--spectrum-badge-background-color-gray); } -:host([variant='red']) { - background: var( - --mod-badge-background-color-red, - var(--spectrum-badge-background-color-red) - ); +.spectrum-Badge--red { + background: var(--spectrum-badge-background-color-red); } -:host([variant='orange']) { - background: var( - --mod-badge-background-color-orange, - var(--spectrum-badge-background-color-orange) - ); +.spectrum-Badge--orange { + background: var(--spectrum-badge-background-color-orange); } -:host([variant='yellow']) { - background: var( - --mod-badge-background-color-yellow, - var(--spectrum-badge-background-color-yellow) - ); +.spectrum-Badge--yellow { + background: var(--spectrum-badge-background-color-yellow); } -:host([variant='chartreuse']) { - background: var( - --mod-badge-background-color-chartreuse, - var(--spectrum-badge-background-color-chartreuse) - ); +.spectrum-Badge--chartreuse { + background: var(--spectrum-badge-background-color-chartreuse); } -:host([variant='celery']) { - background: var( - --mod-badge-background-color-celery, - var(--spectrum-badge-background-color-celery) - ); +.spectrum-Badge--celery { + background: var(--spectrum-badge-background-color-celery); } -:host([variant='green']) { - background: var( - --mod-badge-background-color-green, - var(--spectrum-badge-background-color-green) - ); +.spectrum-Badge--green { + background: var(--spectrum-badge-background-color-green); } -:host([variant='seafoam']) { - background: var( - --mod-badge-background-color-seafoam, - var(--spectrum-badge-background-color-seafoam) - ); +.spectrum-Badge--seafoam { + background: var(--spectrum-badge-background-color-seafoam); } -:host([variant='cyan']) { - background: var( - --mod-badge-background-color-cyan, - var(--spectrum-badge-background-color-cyan) - ); +.spectrum-Badge--cyan { + background: var(--spectrum-badge-background-color-cyan); } -:host([variant='blue']) { - background: var( - --mod-badge-background-color-blue, - var(--spectrum-badge-background-color-blue) - ); +.spectrum-Badge--blue { + background: var(--spectrum-badge-background-color-blue); } -:host([variant='indigo']) { - background: var( - --mod-badge-background-color-indigo, - var(--spectrum-badge-background-color-indigo) - ); +.spectrum-Badge--indigo { + background: var(--spectrum-badge-background-color-indigo); } -:host([variant='purple']) { - background: var( - --mod-badge-background-color-purple, - var(--spectrum-badge-background-color-purple) - ); +.spectrum-Badge--purple { + background: var(--spectrum-badge-background-color-purple); } -:host([variant='fuchsia']) { - background: var( - --mod-badge-background-color-fuchsia, - var(--spectrum-badge-background-color-fuchsia) - ); +.spectrum-Badge--fuchsia { + background: var(--spectrum-badge-background-color-fuchsia); } -:host([variant='magenta']) { - background: var( - --mod-badge-background-color-magenta, - var(--spectrum-badge-background-color-magenta) - ); +.spectrum-Badge--magenta { + background: var(--spectrum-badge-background-color-magenta); } -:host([fixed='inline-start']) { - border-start-start-radius: 0; - border-end-start-radius: 0; +.spectrum-Badge--pink { + background: var(--spectrum-badge-background-color-pink); } -:host([fixed='inline-end']) { - border-start-end-radius: 0; - border-end-end-radius: 0; +.spectrum-Badge--turquoise { + background: var(--spectrum-badge-background-color-turquoise); } -:host([fixed='block-start']) { - border-start-start-radius: 0; - border-start-end-radius: 0; +.spectrum-Badge--brown { + background: var(--spectrum-badge-background-color-brown); } -:host([fixed='block-end']) { - border-end-end-radius: 0; - border-end-start-radius: 0; +.spectrum-Badge--cinnamon { + background: var(--spectrum-badge-background-color-cinnamon); } -.label { - font-size: var(--mod-badge-font-size, var(--spectrum-badge-font-size)); - line-height: var( - --mod-badge-line-height, - var(--spectrum-badge-line-height) - ); - color: var( - --mod-badge-label-icon-color, - var(--spectrum-badge-label-icon-color) - ); - padding-block-start: var( - --mod-badge-label-spacing-vertical-top, - var(--spectrum-badge-label-spacing-vertical-top) - ); - padding-block-end: var( - --mod-badge-label-spacing-vertical-bottom, - var(--spectrum-badge-label-spacing-vertical-bottom) - ); - padding-inline-start: var( - --mod-badge-label-spacing-horizontal, - var(--spectrum-badge-label-spacing-horizontal) - ); - padding-inline-end: var( - --mod-badge-label-spacing-horizontal, - var(--spectrum-badge-label-spacing-horizontal) - ); +.spectrum-Badge--silver { + background: var(--spectrum-badge-background-color-silver); } -.label:lang(ja), -.label:lang(ko), -.label:lang(zh) { - line-height: var( - --mod-badge-line-height-cjk, - var(--spectrum-badge-line-height-cjk) - ); +.spectrum-Badge--subtle { + color: var(--spectrum-badge-subtle-label-icon-color); } -[name='icon'] + .label { - padding-inline-start: 0; +.spectrum-Badge--subtle.spectrum-Badge--neutral { + background: var(--spectrum-badge-subtle-background-color-default); } -::slotted([slot='icon']) { - block-size: var( - --mod-badge-workflow-icon-size, - var(--spectrum-badge-workflow-icon-size) - ); - inline-size: var( - --mod-badge-workflow-icon-size, - var(--spectrum-badge-workflow-icon-size) - ); - flex: 0 0 - var( - --mod-badge-workflow-icon-size, - var(--spectrum-badge-workflow-icon-size) - ); - color: var( - --mod-badge-label-icon-color, - var(--spectrum-badge-label-icon-color) - ); - padding-block-start: var( - --mod-badge-icon-spacing-vertical-top, - var(--spectrum-badge-icon-spacing-vertical-top) - ); - padding-block-end: var( - --mod-badge-icon-spacing-vertical-top, - var(--spectrum-badge-icon-spacing-vertical-top) - ); - padding-inline-start: var( - --mod-badge-icon-spacing-horizontal, - var(--spectrum-badge-icon-spacing-horizontal) - ); - padding-inline-end: var( - --mod-badge-icon-text-spacing, - var(--spectrum-badge-icon-text-spacing) - ); +.spectrum-Badge--subtle.spectrum-Badge--accent { + background: var(--spectrum-badge-subtle-background-color-accent); } -[icon-only]::slotted(*) { - padding-inline-start: var( - --mod-badge-icon-only-spacing-horizontal, - var(--spectrum-badge-icon-only-spacing-horizontal) - ); - padding-inline-end: var( - --mod-badge-icon-only-spacing-horizontal, - var(--spectrum-badge-icon-only-spacing-horizontal) - ); +.spectrum-Badge--subtle.spectrum-Badge--informative { + background: var(--spectrum-badge-subtle-background-color-informative); } -/* center align icons and text */ +.spectrum-Badge--subtle.spectrum-Badge--negative { + background: var(--spectrum-badge-subtle-background-color-negative); +} -:host { - align-items: center; +.spectrum-Badge--subtle.spectrum-Badge--positive { + background: var(--spectrum-badge-subtle-background-color-positive); +} + +.spectrum-Badge--subtle.spectrum-Badge--notice { + background: var(--spectrum-badge-subtle-background-color-notice); +} + +.spectrum-Badge--subtle.spectrum-Badge--gray { + background: var(--spectrum-badge-subtle-background-color-gray); +} + +.spectrum-Badge--subtle.spectrum-Badge--red { + background: var(--spectrum-badge-subtle-background-color-red); +} + +.spectrum-Badge--subtle.spectrum-Badge--orange { + background: var(--spectrum-badge-subtle-background-color-orange); +} + +.spectrum-Badge--subtle.spectrum-Badge--yellow { + background: var(--spectrum-badge-subtle-background-color-yellow); +} + +.spectrum-Badge--subtle.spectrum-Badge--chartreuse { + background: var(--spectrum-badge-subtle-background-color-chartreuse); +} + +.spectrum-Badge--subtle.spectrum-Badge--celery { + background: var(--spectrum-badge-subtle-background-color-celery); +} + +.spectrum-Badge--subtle.spectrum-Badge--green { + background: var(--spectrum-badge-subtle-background-color-green); +} + +.spectrum-Badge--subtle.spectrum-Badge--seafoam { + background: var(--spectrum-badge-subtle-background-color-seafoam); +} + +.spectrum-Badge--subtle.spectrum-Badge--cyan { + background: var(--spectrum-badge-subtle-background-color-cyan); +} + +.spectrum-Badge--subtle.spectrum-Badge--blue { + background: var(--spectrum-badge-subtle-background-color-blue); +} + +.spectrum-Badge--subtle.spectrum-Badge--indigo { + background: var(--spectrum-badge-subtle-background-color-indigo); +} + +.spectrum-Badge--subtle.spectrum-Badge--purple { + background: var(--spectrum-badge-subtle-background-color-purple); +} + +.spectrum-Badge--subtle.spectrum-Badge--fuchsia { + background: var(--spectrum-badge-subtle-background-color-fuchsia); +} + +.spectrum-Badge--subtle.spectrum-Badge--magenta { + background: var(--spectrum-badge-subtle-background-color-magenta); +} + +.spectrum-Badge--subtle.spectrum-Badge--pink { + background: var(--spectrum-badge-subtle-background-color-pink); +} + +.spectrum-Badge--subtle.spectrum-Badge--turquoise { + background: var(--spectrum-badge-subtle-background-color-turquoise); +} + +.spectrum-Badge--subtle.spectrum-Badge--brown { + background: var(--spectrum-badge-subtle-background-color-brown); +} + +.spectrum-Badge--subtle.spectrum-Badge--cinnamon { + background: var(--spectrum-badge-subtle-background-color-cinnamon); +} + +.spectrum-Badge--subtle.spectrum-Badge--silver { + background: var(--spectrum-badge-subtle-background-color-silver); +} + +.spectrum-Badge--outline:is( + .spectrum-Badge--neutral, + .spectrum-Badge--accent, + .spectrum-Badge--informative, + .spectrum-Badge--negative, + .spectrum-Badge--positive, + .spectrum-Badge--notice +) { + background: var(--spectrum-badge-outline-background-color); + color: var(--spectrum-badge-outline-label-icon-color); +} + +.spectrum-Badge--outline.spectrum-Badge--neutral { + border-color: var(--spectrum-badge-outline-border-color-neutral); +} + +.spectrum-Badge--outline.spectrum-Badge--accent { + border-color: var(--spectrum-badge-outline-border-color-accent); +} + +.spectrum-Badge--outline.spectrum-Badge--informative { + border-color: var(--spectrum-badge-outline-border-color-informative); } -/* cascade badge's size to its icon */ +.spectrum-Badge--outline.spectrum-Badge--negative { + border-color: var(--spectrum-badge-outline-border-color-negative); +} -:host([size='xs']) { - --spectrum-icon-size: var(--spectrum-workflow-icon-size-50); +.spectrum-Badge--outline.spectrum-Badge--positive { + border-color: var(--spectrum-badge-outline-border-color-positive); } -:host([size='s']) { - --spectrum-icon-size: var(--spectrum-workflow-icon-size-75); +.spectrum-Badge--outline.spectrum-Badge--notice { + border-color: var(--spectrum-badge-outline-border-color-notice); } -:host([size='m']) { - --spectrum-icon-size: var(--spectrum-workflow-icon-size-100); +.spectrum-Badge--fixed-inline-start { + border-start-start-radius: 0; + border-end-start-radius: 0; } -:host([size='l']) { - --spectrum-icon-size: var(--spectrum-workflow-icon-size-200); +.spectrum-Badge--fixed-inline-end { + border-start-end-radius: 0; + border-end-end-radius: 0; } -:host([size='xl']) { - --spectrum-icon-size: var(--spectrum-workflow-icon-size-300); +.spectrum-Badge--fixed-block-start { + border-start-start-radius: 0; + border-start-end-radius: 0; } -:host([size='xxl']) { - --spectrum-icon-size: var(--spectrum-workflow-icon-size-400); +.spectrum-Badge--fixed-block-end { + border-end-start-radius: 0; + border-end-end-radius: 0; } -/* don't shrink icons and ensure they're separated from labels */ +.spectrum-Badge-label { + font-size: var(--spectrum-badge-font-size); + font-weight: var(--spectrum-badge-font-weight); + line-height: var(--spectrum-badge-line-height); + padding-inline-end: calc( + var(--spectrum-badge-label-spacing-horizontal) - + var(--spectrum-badge-border-width) + ); + padding-inline-start: var(--spectrum-badge-label-spacing-horizontal); + padding-block-start: calc( + var(--spectrum-badge-label-spacing-vertical-top) - + var(--spectrum-badge-border-width) + ); + padding-block-end: calc( + var(--spectrum-badge-label-spacing-vertical-bottom) - + var(--spectrum-badge-border-width) + ); +} -::slotted([slot='icon']) { - flex-shrink: 0; +.spectrum-Badge-label:lang(ja), +.spectrum-Badge-label:lang(ko), +.spectrum-Badge-label:lang(zh) { + line-height: var(--spectrum-badge-line-height-cjk); +} + +.spectrum-Badge-icon + .spectrum-Badge-label { + padding-inline-start: 0; } -/* limit badge size to two lines */ +.spectrum-Badge-icon { + block-size: var(--spectrum-badge-workflow-icon-size); + inline-size: var(--spectrum-badge-workflow-icon-size); + flex: 0 0 var(--spectrum-badge-workflow-icon-size); + margin-inline-start: calc( + var(--spectrum-badge-icon-spacing-horizontal) - + var(--spectrum-badge-border-width) + ); + margin-inline-end: var(--spectrum-badge-icon-text-spacing); + margin-block-start: calc( + var(--spectrum-badge-icon-spacing-vertical-top) - + var(--spectrum-badge-border-width) + ); + margin-block-end: calc( + var(--spectrum-badge-icon-spacing-vertical-top) - + var(--spectrum-badge-border-width) + ); +} -.label slot { - display: block; - max-height: calc( - var(--spectrum-badge-line-height) * var(--spectrum-badge-font-size) * 2 +.spectrum-Badge-icon--no-label { + margin-inline-start: calc( + var(--spectrum-badge-icon-only-spacing-horizontal) - + var(--spectrum-badge-border-width) + ); + margin-inline-end: calc( + var(--spectrum-badge-icon-only-spacing-horizontal) - + var(--spectrum-badge-border-width) ); - overflow: hidden; } -[icon-only] + .label { - display: none; +.spectrum-Badge, +.spectrum-Badge-icon, +.spectrum-Badge-label { + box-sizing: border-box; } diff --git a/second-gen/packages/swc/components/badge/stories/badge.stories.ts b/second-gen/packages/swc/components/badge/stories/badge.stories.ts index 814880f8a9e..3a3129e5583 100644 --- a/second-gen/packages/swc/components/badge/stories/badge.stories.ts +++ b/second-gen/packages/swc/components/badge/stories/badge.stories.ts @@ -10,81 +10,206 @@ * governing permissions and limitations under the License. */ -import { html } from 'lit'; -import type { Meta, StoryObj } from '@storybook/web-components'; +import { html, TemplateResult } from 'lit'; +import { styleMap } from 'lit/directives/style-map.js'; +import type { Meta, StoryObj as Story } from '@storybook/web-components'; +import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers'; -import { BADGE_VARIANTS, FIXED_VALUES } from '@swc/components/badge'; +import { Badge } from '@swc/components/badge'; import '@swc/components/badge'; +// ──────────────── +// METADATA +// ──────────────── + +const { events, args, argTypes, template } = getStorybookHelpers('swc-badge'); + +argTypes.variant = { + ...argTypes.variant, + control: { type: 'select' }, + options: Badge.VARIANTS, +}; + +argTypes.fixed = { + ...argTypes.fixed, + control: { type: 'select' }, + options: [undefined, ...Badge.FIXED_VALUES], +}; + +/* + * @todo This is properly configuring the Select, but the control doesn't + * seem to work; need to investigate. + */ + +// argTypes.size = { +// ...argTypes.size, +// control: { type: 'select' }, +// options: Badge.VALID_SIZES, +// }; + +args['default-slot'] = 'Badge'; + +/** + * Badges are for showing a small amount of color-categorized metadata. They're ideal for getting a user's attention. There are two additional styles - subtle fill and outline - in addition to the default, bold fill style. + * + * Because outline and subtle fill styles draw a similar level of attention, choose only one to use consistently within a single product. Bold fill can be paired with either style, and is reserved for high-attention badging only. + */ const meta: Meta = { title: 'Components/Badge', component: 'swc-badge', - argTypes: { - variant: { - control: { type: 'select' }, - options: BADGE_VARIANTS, - }, - fixed: { - control: { type: 'select' }, - options: [undefined, ...FIXED_VALUES], - }, - size: { - control: { type: 'select' }, - options: ['s', 'm', 'l', 'xl'], + args, + argTypes, + render: (args) => template(args), + parameters: { + actions: { + handles: events, }, }, - args: { - variant: 'informative', - }, + tags: ['migrated'], }; export default meta; -type Story = StoryObj; +// ─────────────── +// STORIES +// ─────────────── + +type BadgeVariant = typeof Badge.prototype.variant; +type BadgeSize = typeof Badge.prototype.size; + +/** + * Badges can contain label, icon, or label and icon. Text wrapping is also included when a `max-inline-size` is applied to the badge. + */ export const Default: Story = { args: { - variant: 'informative', + size: 'm', }, - render: (args) => html` - - Badge - - `, }; -export const Variants: Story = { - render: () => html` -
- ${BADGE_VARIANTS.map( +/** + * Badges can be rendered with or without an icon. Icons can be passed to the component using the `icon` slot and can be sourced from either the Spectrum icon library or a custom icon library as needed. + */ +export const WithIcon: Story = { + args: { + ['icon-slot']: '✓', + }, + // Removes the story from the side navigation while keeping in the docs view + tags: ['!dev'], +}; + +/** + * Semantic variants allow you to render the badge with a descriptive name that maps to a design-system-aligned color. This is the preferred way to assign color to a badge because it will align more consistently with other components in your UI with the same meaning. + */ +export const SemanticVariants: Story = { + render: () => + CONTAINER( + Badge.VARIANTS_SEMANTIC.map( + (variant) => html` + ${capitalize(variant)} + ` + ) + ), + tags: ['!dev'], +}; + +/** + * The `outline` style is only valid for semantic color variants. + */ +export const Outline: Story = { + argTypes: { + variant: { + control: { type: 'select' }, + options: Badge.VARIANTS_SEMANTIC, + }, + }, + render: () => + CONTAINER( + Badge.VARIANTS_SEMANTIC.map( (variant) => html` - ${variant} + ${capitalize(variant)} ` - )} -
- `, + ) + ), + tags: ['!dev'], +}; + +/** + * Color variants are available for the badge component and provide a more granular access to the full color palette in the design system. + */ +export const ColorVariants: Story = { + render: () => + CONTAINER( + Badge.VARIANTS_COLOR.map( + (variant) => html` + ${capitalize(variant)} + ` + ) + ), + tags: ['!dev'], }; export const Sizes: Story = { - render: () => html` -
- Small - Medium - Large - Extra Large -
- `, + render: () => + CONTAINER( + Badge.VALID_SIZES.map( + (size) => html` + ${capitalize(size)} + ` + ) + ), + tags: ['!dev'], }; -export const WithIcon: Story = { - render: () => html` - - - With icon - - `, +/** + * The `subtle` style is available for all variants. It is useful when you want to reduce the visual prominence of the badge while still mapping to the design system color palette. + */ +export const Subtle: Story = { + render: () => + CONTAINER( + Badge.VARIANTS.map( + (variant) => html` + ${capitalize(variant)} + ` + ) + ), + tags: ['!dev'], }; + +// ──────────────────────── +// HELPER FUNCTIONS +// ──────────────────────── + +/* @todo Pull this up into a utility function for all components to leverage */ +function capitalize(str?: string): string { + if (typeof str !== 'string') { + return ''; + } + return str.charAt(0).toUpperCase() + str.slice(1); +} + +/* @todo Pull this up into a decorator for all stories to leverage */ +function CONTAINER(content: TemplateResult<1>[]): TemplateResult { + return html`
+ ${content} +
`; +} diff --git a/second-gen/packages/swc/components/progress-circle/ProgressCircle.ts b/second-gen/packages/swc/components/progress-circle/ProgressCircle.ts index fcdcdd3d0dc..061cbaaa4e0 100644 --- a/second-gen/packages/swc/components/progress-circle/ProgressCircle.ts +++ b/second-gen/packages/swc/components/progress-circle/ProgressCircle.ts @@ -11,28 +11,28 @@ */ import { CSSResultArray, html, TemplateResult } from 'lit'; -import { ifDefined } from 'lit/directives/if-defined.js'; +import { property } from 'lit/decorators.js'; +import { classMap } from 'lit/directives/class-map.js'; -import { ProgressCircleBase } from '@swc/core/components/progress-circle'; +import { + PROGRESS_CIRCLE_STATIC_COLORS_S2, + ProgressCircleBase, + type ProgressCircleStaticColorS2, +} from '@swc/core/components/progress-circle'; import progressCircleStyles from './progress-circle.css'; +function capitalize(str?: string): string { + if (typeof str !== 'string') { + return ''; + } + return str.charAt(0).toUpperCase() + str.slice(1); +} /** * A progress circle component that visually represents the completion progress of a task. * Can be used in both determinate (with specific progress value) and indeterminate (loading) states. * * @element swc-progress-circle - * @since 2.0.0 - * @status stable - * @github https://github.com/adobe/spectrum-web-components/tree/main/second-gen/packages/swc/components/progress-circle - * @figma https://spectrum.figma.com/file/progress-circle - * - * @slot - Optional content to display inside the progress circle (e.g., percentage text) - * - * @csspart track - The background track of the progress circle - * @csspart fill - The filled portion of the progress circle - * - * @fires progress-change - Dispatched when the progress value changes * * @example * @@ -41,34 +41,81 @@ import progressCircleStyles from './progress-circle.css'; * */ export class ProgressCircle extends ProgressCircleBase { + // ──────────────────── + // API OVERRIDES + // ──────────────────── + + /** + * @internal + */ + static override readonly STATIC_COLORS = PROGRESS_CIRCLE_STATIC_COLORS_S2; + + /** + * Static color variant for use on different backgrounds. + * + * When set to 'white', the component uses white styling for images with a dark tinted background. + * + * When set to 'black', the component uses black styling for images with a light tinted background. + */ + @property({ reflect: true, attribute: 'static-color' }) + public staticColor?: ProgressCircleStaticColorS2; + + // ────────────────────────────── + // RENDERING & STYLING + // ────────────────────────────── + public static override get styles(): CSSResultArray { return [progressCircleStyles]; } protected override render(): TemplateResult { - const styles = [ - this.makeRotation(-180 + (180 / 50) * Math.min(this.progress, 50)), - this.makeRotation( - -180 + (180 / 50) * Math.max(this.progress - 50, 0) - ), - ]; - const masks = ['Mask1', 'Mask2']; + const strokeWidth = this.size === 's' ? 2 : this.size === 'm' ? 4 : 6; + // SVG strokes are centered, so subtract half the stroke width from the radius to create an inner stroke. + const radius = `calc(50% - ${strokeWidth / 2}px)`; + return html` - -
-
- ${masks.map( - (mask, index) => html` -
-
-
-
-
- ` - )} +
+ + + + + +
`; } diff --git a/second-gen/packages/swc/components/progress-circle/progress-circle.css b/second-gen/packages/swc/components/progress-circle/progress-circle.css index 49625ee608f..8c3d93eb205 100644 --- a/second-gen/packages/swc/components/progress-circle/progress-circle.css +++ b/second-gen/packages/swc/components/progress-circle/progress-circle.css @@ -1,4 +1,4 @@ -/** +/*! * Copyright 2025 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy @@ -10,52 +10,36 @@ * governing permissions and limitations under the License. */ -@media (forced-colors: active) { - :host { - --highcontrast-progress-circle-fill-border-color: Highlight; - --highcontrast-progress-circle-fill-border-color-over-background: Highlight; +@keyframes spectrum-fills-rotate { + 0% { + transform: rotate(-90deg); } - .track { - --spectrum-progress-circle-track-border-style: double; + 100% { + transform: rotate(270deg); } } -:host { - --spectrum-progress-circle-track-border-color: var(--spectrum-gray-300); - --spectrum-progress-circle-fill-border-color: var( - --spectrum-accent-content-color-default - ); - --spectrum-progress-circle-track-border-color-over-background: var( - --spectrum-transparent-white-300 - ); - --spectrum-progress-circle-fill-border-color-over-background: var( - --spectrum-transparent-white-900 - ); - --spectrum-progress-circle-track-border-style: solid; +@keyframes spectrum-dashoffset-animation { + 0%, + 100% { + stroke-dashoffset: 75px; + } - inline-size: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - block-size: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - position: var(--mod-progress-circle-position, relative); - direction: ltr; - display: inline-block; - transform: translateZ(0); + 30% { + stroke-dashoffset: 20px; + } } -:host([size='s']) { - --spectrum-progress-circle-size: var(--spectrum-progress-circle-size-small); - --spectrum-progress-circle-thickness: var( - --spectrum-progress-circle-thickness-small - ); +:host { + display: inline-block; } -:host { +.spectrum-ProgressCircle { + --spectrum-progress-circle-track-border-color: var(--spectrum-track-color); + --spectrum-progress-circle-fill-border-color: var( + --spectrum-accent-content-color-default + ); --spectrum-progress-circle-size: var( --spectrum-progress-circle-size-medium ); @@ -64,707 +48,99 @@ ); } -:host([size='l']) { - --spectrum-progress-circle-size: var(--spectrum-progress-circle-size-large); +.spectrum-ProgressCircle--sizeS { + --spectrum-progress-circle-size: var(--spectrum-progress-circle-size-small); --spectrum-progress-circle-thickness: var( - --spectrum-progress-circle-thickness-large + --spectrum-progress-circle-thickness-small ); } -.track { - box-sizing: border-box; - inline-size: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - block-size: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - border-style: var( - --mod-progress-circle-track-border-style, - var(--spectrum-progress-circle-track-border-style) - ); - border-width: var( - --mod-progress-circle-thickness, - var(--spectrum-progress-circle-thickness) - ); - border-radius: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - border-color: var( - --mod-progress-circle-track-border-color, - var(--spectrum-progress-circle-track-border-color) +.spectrum-ProgressCircle--sizeL { + --spectrum-progress-circle-size: var(--spectrum-progress-circle-size-large); + --spectrum-progress-circle-thickness: var( + --spectrum-progress-circle-thickness-large ); } -.fills { - inline-size: 100%; - block-size: 100%; - position: absolute; - inset-block-start: 0; - inset-inline-start: 0; +.spectrum-ProgressCircle { + display: inline-block; + inline-size: var(--spectrum-progress-circle-size); + block-size: var(--spectrum-progress-circle-size); + position: relative; + direction: ltr; + transform: translateZ(0); } -.fill { - box-sizing: border-box; - inline-size: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - block-size: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) +.spectrum-ProgressCircle.spectrum-ProgressCircle--staticWhite { + --spectrum-progress-circle-track-border-color: var( + --spectrum-static-white-track-color ); - border-style: solid; - border-width: var( - --mod-progress-circle-thickness, - var(--spectrum-progress-circle-thickness) - ); - border-radius: var( - --mod-progress-circle-size, - var(--spectrum-progress-circle-size) - ); - border-color: var( - --highcontrast-progress-circle-fill-border-color, - var( - --mod-progress-circle-fill-border-color, - var(--spectrum-progress-circle-fill-border-color) - ) + --spectrum-progress-circle-fill-border-color: var( + --spectrum-static-white-track-indicator-color ); } -:host([static-color='white']) .track { - border-color: var( - --mod-progress-circle-track-border-color-over-background, - var(--spectrum-progress-circle-track-border-color-over-background) +.spectrum-ProgressCircle.spectrum-ProgressCircle--staticBlack { + --spectrum-progress-circle-track-border-color: var( + --spectrum-static-black-track-color ); -} - -:host([static-color='white']) .fill { - border-color: var( - --highcontrast-progress-circle-fill-border-color-over-background, - var( - --mod-progress-circle-fill-border-color-over-background, - var(--spectrum-progress-circle-fill-border-color-over-background) - ) + --spectrum-progress-circle-fill-border-color: var( + --spectrum-static-black-track-indicator-color ); } -.fillMask1, -.fillMask2 { - inline-size: 50%; - block-size: 100%; - transform-origin: 100%; - position: absolute; - overflow: hidden; - transform: rotate(180deg); -} - -.fillSubMask1, -.fillSubMask2 { - inline-size: 100%; - block-size: 100%; - transform-origin: 100%; - overflow: hidden; - transform: rotate(-180deg); +.spectrum-ProgressCircle-fill, +.spectrum-ProgressCircle-track { + box-sizing: border-box; + inline-size: var(--spectrum-progress-circle-size); + block-size: var(--spectrum-progress-circle-size); } -.fillMask2 { - transform: rotate(0); +.spectrum-ProgressCircle-track { + stroke-width: var(--spectrum-progress-circle-thickness); + stroke: var( + --highcontrast-progress-circle-track-color, + var(--spectrum-progress-circle-track-border-color) + ); } -:host([indeterminate]) .fills { - will-change: transform; +.spectrum-ProgressCircle-fill { + stroke-width: var(--spectrum-progress-circle-thickness); + stroke: var( + --highcontrast-progress-circle-fill-border-color, + var(--spectrum-progress-circle-fill-border-color) + ); + transform: rotate(-90deg); transform-origin: center; - animation: 1s cubic-bezier(0.25, 0.78, 0.48, 0.89) infinite - spectrum-fills-rotate; - transform: translateZ(0); } -:host([indeterminate]) .fillSubMask1 { +.spectrum-ProgressCircle--indeterminate .spectrum-ProgressCircle-fill { will-change: transform; - animation: 1s linear infinite spectrum-fill-mask-1; - transform: translateZ(0); -} - -:host([indeterminate]) .fillSubMask2 { - will-change: transform; - animation: 1s linear infinite spectrum-fill-mask-2; - transform: translateZ(0); -} - -.fill-submask-2 { - animation: 1s linear infinite spectrum-fill-mask-2; -} - -@keyframes spectrum-fill-mask-1 { - 0% { - transform: rotate(90deg); - } - - 1.69% { - transform: rotate(72.3deg); - } - - 3.39% { - transform: rotate(55.5deg); - } - - 5.08% { - transform: rotate(40.3deg); - } - - 6.78% { - transform: rotate(25deg); - } - - 8.47% { - transform: rotate(10.6deg); - } - - 10.17% { - transform: rotate(0); - } - - 11.86% { - transform: rotate(0); - } - - 13.56% { - transform: rotate(0); - } - - 15.25% { - transform: rotate(0); - } - - 16.95% { - transform: rotate(0); - } - - 18.64% { - transform: rotate(0); - } - - 20.34% { - transform: rotate(0); - } - - 22.03% { - transform: rotate(0); - } - - 23.73% { - transform: rotate(0); - } - - 25.42% { - transform: rotate(0); - } - - 27.12% { - transform: rotate(0); - } - - 28.81% { - transform: rotate(0); - } - - 30.51% { - transform: rotate(0); - } - - 32.2% { - transform: rotate(0); - } - - 33.9% { - transform: rotate(0); - } - - 35.59% { - transform: rotate(0); - } - - 37.29% { - transform: rotate(0); - } - - 38.98% { - transform: rotate(0); - } - - 40.68% { - transform: rotate(0); - } - - 42.37% { - transform: rotate(5.3deg); - } - - 44.07% { - transform: rotate(13.4deg); - } - - 45.76% { - transform: rotate(20.6deg); - } - - 47.46% { - transform: rotate(29deg); - } - - 49.15% { - transform: rotate(36.5deg); - } - - 50.85% { - transform: rotate(42.6deg); - } - - 52.54% { - transform: rotate(48.8deg); - } - - 54.24% { - transform: rotate(54.2deg); - } - - 55.93% { - transform: rotate(59.4deg); - } - - 57.63% { - transform: rotate(63.2deg); - } - - 59.32% { - transform: rotate(67.2deg); - } - - 61.02% { - transform: rotate(70.8deg); - } - - 62.71% { - transform: rotate(73.8deg); - } - - 64.41% { - transform: rotate(76.2deg); - } - - 66.1% { - transform: rotate(78.7deg); - } - - 67.8% { - transform: rotate(80.6deg); - } - - 69.49% { - transform: rotate(82.6deg); - } - - 71.19% { - transform: rotate(83.7deg); - } - - 72.88% { - transform: rotate(85deg); - } - - 74.58% { - transform: rotate(86.3deg); - } - - 76.27% { - transform: rotate(87deg); - } - - 77.97% { - transform: rotate(87.7deg); - } - - 79.66% { - transform: rotate(88.3deg); - } - - 81.36% { - transform: rotate(88.6deg); - } - - 83.05% { - transform: rotate(89.2deg); - } - - 84.75% { - transform: rotate(89.2deg); - } - - 86.44% { - transform: rotate(89.5deg); - } - - 88.14% { - transform: rotate(89.9deg); - } - - 89.83% { - transform: rotate(89.7deg); - } - - 91.53% { - transform: rotate(90.1deg); - } - - 93.22% { - transform: rotate(90.2deg); - } - - 94.92% { - transform: rotate(90.1deg); - } - - 96.61% { - transform: rotate(90deg); - } - - 98.31% { - transform: rotate(89.8deg); - } - - 100% { - transform: rotate(90deg); - } + animation: + spectrum-fills-rotate 1s cubic-bezier(0.6, 0.1, 0.3, 0.9) infinite, + spectrum-dashoffset-animation 1s cubic-bezier(0.25, 0.1, 0.25, 1.3) + infinite; + transform-origin: center; } -@keyframes spectrum-fill-mask-2 { - 0% { - transform: rotate(180deg); - } - - 1.69% { - transform: rotate(180deg); - } - - 3.39% { - transform: rotate(180deg); - } - - 5.08% { - transform: rotate(180deg); - } - - 6.78% { - transform: rotate(180deg); - } - - 8.47% { - transform: rotate(180deg); - } - - 10.17% { - transform: rotate(179.2deg); - } - - 11.86% { - transform: rotate(164deg); - } - - 13.56% { - transform: rotate(151.8deg); - } - - 15.25% { - transform: rotate(140.8deg); - } - - 16.95% { - transform: rotate(130.3deg); - } - - 18.64% { - transform: rotate(120.4deg); - } - - 20.34% { - transform: rotate(110.8deg); - } - - 22.03% { - transform: rotate(101.6deg); - } - - 23.73% { - transform: rotate(93.5deg); - } - - 25.42% { - transform: rotate(85.4deg); - } - - 27.12% { - transform: rotate(78.1deg); - } - - 28.81% { - transform: rotate(71.2deg); - } - - 30.51% { - transform: rotate(89.1deg); - } - - 32.2% { - transform: rotate(105.5deg); - } - - 33.9% { - transform: rotate(121.3deg); - } - - 35.59% { - transform: rotate(135.5deg); - } - - 37.29% { - transform: rotate(148.4deg); - } - - 38.98% { - transform: rotate(161deg); - } - - 40.68% { - transform: rotate(173.5deg); - } - - 42.37% { - transform: rotate(180deg); - } - - 44.07% { - transform: rotate(180deg); - } - - 45.76% { - transform: rotate(180deg); - } - - 47.46% { - transform: rotate(180deg); - } - - 49.15% { - transform: rotate(180deg); - } - - 50.85% { - transform: rotate(180deg); - } - - 52.54% { - transform: rotate(180deg); - } - - 54.24% { - transform: rotate(180deg); - } - - 55.93% { - transform: rotate(180deg); - } - - 57.63% { - transform: rotate(180deg); - } - - 59.32% { - transform: rotate(180deg); - } - - 61.02% { - transform: rotate(180deg); - } - - 62.71% { - transform: rotate(180deg); - } - - 64.41% { - transform: rotate(180deg); - } - - 66.1% { - transform: rotate(180deg); - } - - 67.8% { - transform: rotate(180deg); - } - - 69.49% { - transform: rotate(180deg); - } - - 71.19% { - transform: rotate(180deg); - } - - 72.88% { - transform: rotate(180deg); - } - - 74.58% { - transform: rotate(180deg); - } - - 76.27% { - transform: rotate(180deg); - } - - 77.97% { - transform: rotate(180deg); - } - - 79.66% { - transform: rotate(180deg); - } - - 81.36% { - transform: rotate(180deg); - } - - 83.05% { - transform: rotate(180deg); - } - - 84.75% { - transform: rotate(180deg); - } - - 86.44% { - transform: rotate(180deg); - } - - 88.14% { - transform: rotate(180deg); - } - - 89.83% { - transform: rotate(180deg); - } - - 91.53% { - transform: rotate(180deg); - } - - 93.22% { - transform: rotate(180deg); - } - - 94.92% { - transform: rotate(180deg); - } - - 96.61% { - transform: rotate(180deg); - } - - 98.31% { - transform: rotate(180deg); - } - - 100% { - transform: rotate(180deg); +@media (forced-colors: active) { + .spectrum-ProgressCircle { + --highcontrast-progress-circle-fill-border-color: Highlight; + --highcontrast-progress-circle-track-color: Background; } -} -@keyframes spectrum-fills-rotate { - 0% { - transform: rotate(-90deg); + .spectrum-ProgressCircle:not(.spectrum-ProgressCircle--indeterminate) + .spectrum-innerCircle { + stroke: CanvasText; } - 100% { - transform: rotate(270deg); + .spectrum-ProgressCircle:not(.spectrum-ProgressCircle--indeterminate) + .spectrum-outerCircle { + border: 1px solid CanvasText; + border-radius: 50%; } } -:host { - block-size: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); - inline-size: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); - - --spectrum-progress-circle-size: inherit; - --spectrum-progresscircle-m-over-background-track-fill-color: var( - --spectrum-alias-track-fill-color-overbackground - ); - --_spectrum-progress-circle-size: var( - --spectrum-progress-circle-size, - var(--spectrum-progress-circle-size-medium) - ); -} - -:host([size='s']) { - --_spectrum-progress-circle-size: var( - --spectrum-progress-circle-size, - var(--spectrum-progress-circle-size-small) - ); -} - -:host([size='l']) { - --_spectrum-progress-circle-size: var( - --spectrum-progress-circle-size, - var(--spectrum-progress-circle-size-large) - ); -} - slot { display: none; } - -.track { - block-size: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); - border-radius: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); - inline-size: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); -} - -.fill { - block-size: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); - border-radius: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); - inline-size: var( - --mod-progress-circle-size, - var(--_spectrum-progress-circle-size) - ); -} - -/* stylelint-disable */ -:host([indeterminate]) .fills, -:host([indeterminate]) .fillSubMask1, -:host([indeterminate]) .fillSubMask2 { - animation-duration: var(--spectrum-animation-duration-2000); -} -/* stylelint-enable */ diff --git a/second-gen/packages/swc/components/progress-circle/stories/progress-circle.stories.ts b/second-gen/packages/swc/components/progress-circle/stories/progress-circle.stories.ts index 085d5261a78..630dfa187d5 100644 --- a/second-gen/packages/swc/components/progress-circle/stories/progress-circle.stories.ts +++ b/second-gen/packages/swc/components/progress-circle/stories/progress-circle.stories.ts @@ -11,46 +11,69 @@ */ import { html } from 'lit'; -import { ifDefined } from 'lit/directives/if-defined.js'; -import type { Meta, StoryObj } from '@storybook/web-components'; +import type { Meta, StoryObj as Story } from '@storybook/web-components'; +import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers'; + +import { ProgressCircle } from '@swc/components/progress-circle'; import '@swc/components/progress-circle'; +// ──────────────── +// METADATA +// ──────────────── + +const { events, args, argTypes, template } = getStorybookHelpers( + 'swc-progress-circle' +); + +/* + * @todo Blurring the range control seems to cause a catastrophic Storybook + * render failure, so disabling for now. + */ +// argTypes.progress = { +// ...argTypes.progress, +// control: { type: 'range', min: 0, max: 100, step: 1 }, +// }; + +/* + * @todo This is properly configuring the Select, but the control doesn't + * seem to work; need to investigate. + */ +// argTypes.size = { +// ...argTypes.size, +// control: { type: 'select' }, +// options: ProgressCircle.VALID_SIZES, +// }; + +argTypes['static-color'] = { + ...argTypes['static-color'], + control: { type: 'select' }, + options: [undefined, ...ProgressCircle.STATIC_COLORS], +}; + +/** + * A progress circle component that visually represents the completion progress of a task. + * Can be used in both determinate (with specific progress value) and indeterminate (loading) states. + */ const meta: Meta = { title: 'Components/Progress Circle', component: 'swc-progress-circle', - argTypes: { - indeterminate: { - control: { type: 'boolean' }, - description: 'Whether the progress is indeterminate.', - }, - progress: { - control: { type: 'range', min: 0, max: 100, step: 1 }, - description: 'Progress value from 0 to 100.', + args, + argTypes, + render: (args) => template(args), + parameters: { + actions: { + handles: events, }, - size: { - control: { type: 'select' }, - options: ['s', 'm', 'l'], - description: 'Size of the progress circle.', - }, - staticColor: { - control: { type: 'select' }, - options: [undefined, 'white'], - description: 'Static color variant.', - }, - label: { - control: { type: 'text' }, - description: 'Accessible label for the progress circle.', - }, - }, - args: { - progress: 50, - size: 'm', }, + tags: ['migrated'], }; export default meta; -type Story = StoryObj; + +// ─────────────── +// STORIES +// ─────────────── export const Default: Story = { args: { @@ -58,15 +81,7 @@ export const Default: Story = { size: 'm', label: 'Loading progress', }, - render: (args) => html` - - `, + render: (args) => template(args), }; export const Sizes: Story = { @@ -89,6 +104,7 @@ export const Sizes: Story = { >
`, + tags: ['!dev'], }; export const ProgressValues: Story = { @@ -112,6 +128,7 @@ export const ProgressValues: Story = { >
`, + tags: ['!dev'], }; export const Indeterminate: Story = { @@ -134,12 +151,13 @@ export const Indeterminate: Story = { > `, + tags: ['!dev'], }; export const StaticWhite: Story = { render: () => html`
`, + tags: ['!dev'], +}; + +export const StaticBlack: Story = { + render: () => html` +
+ + + +
+ `, + tags: ['!dev'], }; export const IndeterminateStaticWhite: Story = { @@ -188,10 +235,5 @@ export const IndeterminateStaticWhite: Story = { > `, -}; - -export const WithSlottedContent: Story = { - render: () => html` - Loading... - `, + tags: ['!dev'], }; diff --git a/second-gen/packages/swc/package.json b/second-gen/packages/swc/package.json index 34d427a3ef5..debd13fe835 100644 --- a/second-gen/packages/swc/package.json +++ b/second-gen/packages/swc/package.json @@ -34,11 +34,12 @@ "dist/" ], "scripts": { + "analyze": "cem analyze --config cem.config.js", "build": "vite build", "clean": "rimraf dist", "dev": "vite build --watch", - "storybook": "storybook dev -p 6006", - "storybook:build": "storybook build", + "storybook": "yarn analyze && storybook dev -p 6006", + "storybook:build": "yarn analyze && storybook build", "test": "vitest", "test:coverage": "vitest --coverage", "test:ui": "vitest --ui" @@ -61,6 +62,7 @@ "@vitest/browser": "^3.2.4", "@vitest/coverage-v8": "3.2.4", "@vitest/ui": "^3.2.4", + "@wc-toolkit/storybook-helpers": "^9.0.1", "autoprefixer": "^10.4.21", "glob": "^11.0.0", "playwright": "^1.55.0", diff --git a/second-gen/packages/swc/vite.config.ts b/second-gen/packages/swc/vite.config.ts index b1952263cde..bfdc6225feb 100644 --- a/second-gen/packages/swc/vite.config.ts +++ b/second-gen/packages/swc/vite.config.ts @@ -65,7 +65,11 @@ export default defineConfig({ }, rollupOptions: { external: (id) => { - return id === 'lit' || id.startsWith('@swc/core/'); + return ( + id === 'lit' || + id.startsWith('@lit/') || + id.startsWith('@swc/core/') + ); }, output: { preserveModules: true, diff --git a/yarn.lock b/yarn.lock index fad10cd9eb8..afd98735143 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7210,6 +7210,7 @@ __metadata: "@vitest/browser": "npm:^3.2.4" "@vitest/coverage-v8": "npm:3.2.4" "@vitest/ui": "npm:^3.2.4" + "@wc-toolkit/storybook-helpers": "npm:^9.0.1" autoprefixer: "npm:^10.4.21" glob: "npm:^11.0.0" lit: "npm:^2.5.0 || ^3.1.3" @@ -9110,6 +9111,16 @@ __metadata: languageName: node linkType: hard +"@wc-toolkit/storybook-helpers@npm:^9.0.1": + version: 9.0.1 + resolution: "@wc-toolkit/storybook-helpers@npm:9.0.1" + peerDependencies: + lit: ^2.0.0 || ^3.0.0 + storybook: ">=9.0.0-0 <10.0.0-0" + checksum: 10c0/70f57c869c1d58f9eaf09d1cdc841784ceb01f7154452808d736431d79ba8757817320668e703a5136fe0b64428bdae386cd5b4b9cbabcfe75321eb234695673 + languageName: node + linkType: hard + "@wdio/logger@npm:^8.28.0": version: 8.38.0 resolution: "@wdio/logger@npm:8.38.0"