From 56754264ca65c1e5a6a36ec619b6217c9e48e458 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Fri, 13 Jan 2023 10:59:38 -0800 Subject: [PATCH 1/9] add badge as a new component --- ...-25e8f64c-845e-401f-a7f8-c9472a5720df.json | 7 + .../src/badge/badge.definition.ts | 19 ++ .../web-components/src/badge/badge.options.ts | 74 +++++ .../web-components/src/badge/badge.stories.ts | 126 ++++++++ .../web-components/src/badge/badge.styles.ts | 73 +++++ .../src/badge/badge.template.ts | 24 ++ packages/web-components/src/badge/badge.ts | 57 ++++ packages/web-components/src/badge/define.ts | 4 + packages/web-components/src/badge/index.ts | 5 + packages/web-components/src/index.ts | 1 + packages/web-components/src/styles/index.ts | 1 + .../src/styles/partials/badge.partials.ts | 297 ++++++++++++++++++ .../src/styles/partials/index.ts | 1 + 13 files changed, 689 insertions(+) create mode 100644 change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json create mode 100644 packages/web-components/src/badge/badge.definition.ts create mode 100644 packages/web-components/src/badge/badge.options.ts create mode 100644 packages/web-components/src/badge/badge.stories.ts create mode 100644 packages/web-components/src/badge/badge.styles.ts create mode 100644 packages/web-components/src/badge/badge.template.ts create mode 100644 packages/web-components/src/badge/badge.ts create mode 100644 packages/web-components/src/badge/define.ts create mode 100644 packages/web-components/src/badge/index.ts create mode 100644 packages/web-components/src/styles/index.ts create mode 100644 packages/web-components/src/styles/partials/badge.partials.ts create mode 100644 packages/web-components/src/styles/partials/index.ts diff --git a/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json new file mode 100644 index 0000000000000..ad13257ed2c24 --- /dev/null +++ b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "add badge as a new component", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/badge/badge.definition.ts b/packages/web-components/src/badge/badge.definition.ts new file mode 100644 index 0000000000000..f15da6d05174f --- /dev/null +++ b/packages/web-components/src/badge/badge.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Badge } from './badge.js'; +import { styles } from './badge.styles.js'; +import { template } from './badge.template.js'; + +/** + * The Fluent Badge Element. Implements {@link @microsoft/fast-foundation#Badge }, + * {@link @microsoft/fast-foundation#badgeTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Badge.compose({ + name: `${FluentDesignSystem.prefix}-badge`, + template, + styles, +}); diff --git a/packages/web-components/src/badge/badge.options.ts b/packages/web-components/src/badge/badge.options.ts new file mode 100644 index 0000000000000..9e668bc000884 --- /dev/null +++ b/packages/web-components/src/badge/badge.options.ts @@ -0,0 +1,74 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * BadgeAppearance constants + * @public + */ +export const BadgeAppearance = { + filled: 'filled', + ghost: 'ghost', + outline: 'outline', + tint: 'tint', +} as const; + +/** + * A Badge can be filled, outline, ghost, inverted + * @public + */ +export type BadgeAppearance = ValuesOf; + +/** + * BadgeColor constants + * @public + */ +export const BadgeColor = { + brand: 'brand', + danger: 'danger', + important: 'important', + informative: 'informative', + severe: 'severe', + subtle: 'subtle', + success: 'success', + warning: 'warning', +} as const; + +/** + * A Badge can be one of preset colors + * @public + */ +export type BadgeColor = ValuesOf; + +/** + * A Badge can be square, circular or rounded. + * @public + */ +export const BadgeShape = { + circular: 'circular', + rounded: 'rounded', + square: 'square', +} as const; + +/** + * A Badge can be one of preset colors + * @public + */ +export type BadgeShape = ValuesOf; + +/** + * A Badge can be square, circular or rounded. + * @public + */ +export const BadgeSize = { + tiny: 'tiny', + extraSmall: 'extra-small', + small: 'small', + medium: 'medium', + large: 'large', + extraLarge: 'extra-large', +} as const; + +/** + * A Badge can be on of several preset sizes. + * @public + */ +export type BadgeSize = ValuesOf; diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts new file mode 100644 index 0000000000000..0068a049d3164 --- /dev/null +++ b/packages/web-components/src/badge/badge.stories.ts @@ -0,0 +1,126 @@ +import { html, when } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import type { Badge as FluentBadge } from './badge.js'; +import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options'; +import './define.js'; + +type BadgeStoryArgs = Args & FluentBadge; +type BadgeStoryMeta = Meta; + +const storyTemplate = html` + + ${when( + x => x.iconPosition === 'start', + html``, + )} + ${x => x.content} + ${when( + x => x.iconPosition === 'end', + html``, + )} + +`; + +export default { + title: 'Components/Badge', + args: { + content: null, + }, + argTypes: { + appearance: { + options: Object.values(BadgeAppearance), + control: { + type: 'select', + }, + }, + color: { + options: Object.keys(BadgeColor), + control: { + type: 'select', + }, + }, + shape: { + options: Object.keys(BadgeShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.keys(BadgeSize), + control: { + type: 'select', + }, + }, + iconPosition: { + options: ['none', 'start', 'end'], + control: { + type: 'select', + }, + }, + content: { + type: 'string', + }, + }, +} as BadgeStoryMeta; + +export const Badge = renderComponent(storyTemplate).bind({}); + +export const Appearance = renderComponent(html` + filled + ghost + outline + tint +`); + +export const Color = renderComponent(html` + brand + danger + important + informative + severe + subtle + success + warning +`); + +export const Shape = renderComponent(html` + + + +`); + +export const Size = renderComponent(html` + + + + + + +`) as BadgeStoryMeta; diff --git a/packages/web-components/src/badge/badge.styles.ts b/packages/web-components/src/badge/badge.styles.ts new file mode 100644 index 0000000000000..410b3ec3f377a --- /dev/null +++ b/packages/web-components/src/badge/badge.styles.ts @@ -0,0 +1,73 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + badgeFilledStyles, + badgeGhostStyles, + badgeOutlineStyles, + badgeSizeStyles, + badgeTintStyles, +} from '../styles/index'; +import { + borderRadiusCircular, + borderRadiusMedium, + borderRadiusNone, + borderRadiusSmall, + fontFamilyBase, + fontSizeBase200, + fontWeightSemibold, + lineHeightBase200, + strokeWidthThin, +} from '../theme/design-tokens.js'; + +/** Badge styles + * @public + */ +export const styles = css` + ${display('inline-flex')} :host { + position: relative; + box-sizing: border-box; + align-items: center; + justify-content: center; + font-family: ${fontFamilyBase}; + font-weight: ${fontWeightSemibold}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + } + + :host(:not([appearance='ghost'])) { + content: ''; + position: 'absolute'; + top: 0; + left: 0; + bottom: 0; + right: 0; + border-style: solid; + border-width: ${strokeWidthThin}; + border-color: inherit; + border-radius: inherit; + } + + :host([shape='square']) { + border-radius: ${borderRadiusNone}; + } + + :host([shape='circular']) { + border-radius: ${borderRadiusCircular}; + } + + :host([shape='rounded']) { + border-radius: ${borderRadiusMedium}; + } + + :host([shape='rounded'][size='tiny']), + :host([shape='rounded'][size='extra-small']), + :host([shape='rounded'][size='small']) { + border-radius: ${borderRadiusSmall}; + } + + ${badgeSizeStyles} + ${badgeFilledStyles} + ${badgeGhostStyles} + ${badgeOutlineStyles} + ${badgeTintStyles} +`; diff --git a/packages/web-components/src/badge/badge.template.ts b/packages/web-components/src/badge/badge.template.ts new file mode 100644 index 0000000000000..b91078489b5de --- /dev/null +++ b/packages/web-components/src/badge/badge.template.ts @@ -0,0 +1,24 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { endSlotTemplate, StartEndOptions, startSlotTemplate } from '@microsoft/fast-foundation'; +import type { Badge } from './badge.js'; + +/** + * @internal - marking as internal + * Update with + */ +export type BadgeOptions = StartEndOptions; + +/** + * The template for the Badge component. + * TODO: Replace w/ updated FAST Badge when aligned + * @public + */ +function badgeTemplate(options: BadgeOptions = {}): ElementViewTemplate { + return html` + ${startSlotTemplate(options)} + + ${endSlotTemplate(options)} + `; +} + +export const template: ElementViewTemplate = badgeTemplate(); diff --git a/packages/web-components/src/badge/badge.ts b/packages/web-components/src/badge/badge.ts new file mode 100644 index 0000000000000..f0d6640cb396d --- /dev/null +++ b/packages/web-components/src/badge/badge.ts @@ -0,0 +1,57 @@ +import { attr, FASTElement } from '@microsoft/fast-element'; +import { applyMixins, StartEnd } from '@microsoft/fast-foundation'; +import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options'; + +/** + * The base class used for constructing a fluent-badge custom element + * @public + */ +export class Badge extends FASTElement { + /** + * The appearance the badge should have. + * + * @public + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance: BadgeAppearance = BadgeAppearance.filled; + + /** + * The color the badge should have. + * + * @public + * @remarks + * HTML Attribute: color + */ + @attr + public color: BadgeColor = BadgeColor.brand; + /** + * The shape the badge should have. + * + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape: BadgeShape = BadgeShape.circular; + + /** + * The size the badge should have. + * + * @public + * @remarks + * HTML Attribute: size + */ + @attr + public size: BadgeSize = BadgeSize.medium; +} + +/** + * Mark internal because exporting class and interface of the same name + * confuses API extractor. + * TODO: Below will be unnecessary when Badge class gets updated + * @internal + */ +export interface Badge extends StartEnd {} +applyMixins(Badge, StartEnd); diff --git a/packages/web-components/src/badge/define.ts b/packages/web-components/src/badge/define.ts new file mode 100644 index 0000000000000..d0e348b49c9c9 --- /dev/null +++ b/packages/web-components/src/badge/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './badge.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/badge/index.ts b/packages/web-components/src/badge/index.ts new file mode 100644 index 0000000000000..92e3fdcd87214 --- /dev/null +++ b/packages/web-components/src/badge/index.ts @@ -0,0 +1,5 @@ +export * from './badge.js'; +export * from './badge.options.js'; +export { template as BadgeTemplate } from './badge.template.js'; +export { styles as BadgeStyles } from './badge.styles.js'; +export { definition as BadgeDefinition } from './badge.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index dd622fd56e566..2bc95acee2656 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1 +1,2 @@ +export * from './badge/index.js'; export * from './text/index.js'; diff --git a/packages/web-components/src/styles/index.ts b/packages/web-components/src/styles/index.ts new file mode 100644 index 0000000000000..8613859ad3e89 --- /dev/null +++ b/packages/web-components/src/styles/index.ts @@ -0,0 +1 @@ +export * from './partials/index.js'; diff --git a/packages/web-components/src/styles/partials/badge.partials.ts b/packages/web-components/src/styles/partials/badge.partials.ts new file mode 100644 index 0000000000000..2a91221b14e57 --- /dev/null +++ b/packages/web-components/src/styles/partials/badge.partials.ts @@ -0,0 +1,297 @@ +import { css } from '@microsoft/fast-element'; +import { + colorBrandBackground, + colorBrandBackground2, + colorBrandForeground1, + colorBrandForeground2, + colorBrandStroke2, + colorNeutralBackground1, + colorNeutralBackground4, + colorNeutralBackground5, + colorNeutralForeground1, + colorNeutralForeground3, + colorNeutralForegroundInverted, + colorNeutralForegroundOnBrand, + colorNeutralForegroundStaticInverted, + colorNeutralStroke2, + colorNeutralStrokeAccessible, + colorPaletteDarkOrangeBackground1, + colorPaletteDarkOrangeBackground3, + colorPaletteDarkOrangeBorder1, + colorPaletteDarkOrangeForeground1, + colorPaletteDarkOrangeForeground3, + colorPaletteGreenBackground1, + colorPaletteGreenBackground3, + colorPaletteGreenBorder2, + colorPaletteGreenForeground1, + colorPaletteGreenForeground2, + colorPaletteGreenForeground3, + colorPaletteRedBackground1, + colorPaletteRedBackground3, + colorPaletteRedBorder1, + colorPaletteRedForeground1, + colorPaletteRedForeground3, + colorPaletteYellowBackground1, + colorPaletteYellowBackground3, + colorPaletteYellowBorder1, + colorPaletteYellowForeground2, + colorTransparentStroke, + fontSizeBase100, + lineHeightBase100, + spacingHorizontalSNudge, + spacingHorizontalXS, + spacingHorizontalXXS, +} from '../../theme/design-tokens.js'; + +const textPadding = spacingHorizontalXXS; + +/** + * @public + * The badge's size styles + */ +export const badgeSizeStyles = css.partial` + :host([size='tiny']) { + width: 6px; + height: 6px; + font-size: 4px; + line-height: 4px; + } + :host([size='tiny']) ::slotted(svg) { + font-size: 6px; + } + :host([size='extra-small']) { + width: 10px; + height: 10px; + font-size: 6px; + line-height: 6px; + } + :host([size='extra-small']) ::slotted(svg) { + font-size: 10px; + } + :host([size='small']) { + min-width: 16px; + height: 16px; + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + padding-inline: calc(${spacingHorizontalXXS} + ${textPadding}); + } + :host([size='small']) ::slotted(svg) { + font-size: 10px; + } + :host([size='medium']) { + min-width: 20px; + height: 20px; + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); + } + :host([size='medium']) ::slotted(svg) { + font-size: 10px; + } + :host([size='large']) { + min-width: 24px; + height: 24px; + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); + } + :host([size='large']) ::slotted(svg) { + font-size: 10px; + } + :host([size='extra-large']) { + min-width: 32px; + height: 32px; + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + padding-inline: calc(${spacingHorizontalSNudge} + ${textPadding}); + } + :host([size='extra-large']) ::slotted(svg) { + font-size: 20px; + } +`; + +/** + * The badge's `filled` appearance styles + * @public + */ +export const badgeFilledStyles = css.partial` + :host([appearance='filled']) { + border-color: ${colorTransparentStroke}; + } + + :host([appearance='filled'][color='brand']) { + background-color: ${colorBrandBackground}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([appearance='filled'][color='danger']) { + background-color: ${colorPaletteRedBackground3}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([appearance='filled'][color='important']) { + background-color: ${colorNeutralForeground1}; + color: ${colorNeutralBackground1}; + } + + :host([appearance='filled'][color='informative']) { + background-color: ${colorNeutralBackground5}; + color: ${colorNeutralForeground3}; + } + + :host([appearance='filled'][color='severe']) { + background-color: ${colorPaletteDarkOrangeBackground3}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([appearance='filled'][color='subtle']) { + background-color: ${colorNeutralBackground1}; + color: ${colorNeutralForeground1}; + } + + :host([appearance='filled'][color='success']) { + background-color: ${colorPaletteGreenBackground3}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([appearance='filled'][color='warning']) { + background-color: ${colorPaletteYellowBackground3}; + color: ${colorNeutralForeground1}; + } +`; + +/** + * The badge's `ghost` appearance styles + * @public + */ +export const badgeGhostStyles = css.partial` + :host([appearance='ghost'][color='brand']) { + color: ${colorBrandBackground}; + } + + :host([appearance='ghost'][color='danger']) { + color: ${colorPaletteRedForeground3}; + } + + :host([appearance='ghost'][color='important']) { + color: ${colorNeutralForeground1}; + } + + :host([appearance='ghost'][color='informative']) { + color: ${colorNeutralForeground3}; + } + + :host([appearance='ghost'][color='severe']) { + color: ${colorPaletteDarkOrangeForeground3}; + } + + :host([appearance='ghost'][color='subtle']) { + color: ${colorNeutralForegroundInverted}; + } + + :host([appearance='ghost'][color='success']) { + color: ${colorPaletteGreenForeground3}; + } + + :host([appearance='ghost'][color='warning']) { + color: ${colorPaletteYellowForeground2}; + } +`; + +/** + * The badge's `outline` appearance styles + * @public + */ +export const badgeOutlineStyles = css.partial` + :host([appearance='outline']) { + border-color: currentColor; + } + + :host([appearance='outline'][color='brand']) { + color: ${colorBrandForeground1}; + } + + :host([appearance='outline'][color='danger']) { + color: ${colorPaletteRedForeground3}; + } + + :host([appearance='outline'][color='important']) { + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStrokeAccessible}; + } + + :host([appearance='outline'][color='informative']) { + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStroke2}; + } + + :host([appearance='outline'][color='severe']) { + color: ${colorPaletteDarkOrangeForeground3}; + } + + :host([appearance='outline'][color='subtle']) { + color: ${colorNeutralForegroundStaticInverted}; + } + + :host([appearance='outline'][color='success']) { + color: ${colorPaletteGreenForeground2}; + } + + :host([appearance='outline'][color='warning']) { + color: ${colorPaletteYellowForeground2}; + } +`; + +/** + * The badge's `tint` appearance styles + * @public + */ +export const badgeTintStyles = css.partial` + :host([appearance='tint'][color='brand']) { + background-color: ${colorBrandBackground2}; + color: ${colorBrandForeground2}; + border-color: ${colorBrandStroke2}; + } + + :host([appearance='tint'][color='danger']) { + background-color: ${colorPaletteRedBackground1}; + color: ${colorPaletteRedForeground1}; + border-color: ${colorPaletteRedBorder1}; + } + + :host([appearance='tint'][color='important']) { + background-color: ${colorNeutralForeground3}; + color: ${colorNeutralBackground1}; + border-color: ${colorTransparentStroke}; + } + + :host([appearance='tint'][color='informative']) { + background-color: ${colorNeutralBackground4}; + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStroke2}; + } + + :host([appearance='tint'][color='severe']) { + background-color: ${colorPaletteDarkOrangeBackground1}; + color: ${colorPaletteDarkOrangeForeground1}; + border-color: ${colorPaletteDarkOrangeBorder1}; + } + + :host([appearance='tint'][color='subtle']) { + background-color: ${colorNeutralBackground1}; + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStroke2}; + } + + :host([appearance='tint'][color='success']) { + background-color: ${colorPaletteGreenBackground1}; + color: ${colorPaletteGreenForeground1}; + border-color: ${colorPaletteGreenBorder2}; + } + + :host([appearance='tint'][color='warning']) { + background-color: ${colorPaletteYellowBackground1}; + color: ${colorPaletteYellowForeground2}; + border-color: ${colorPaletteYellowBorder1}; + } +`; diff --git a/packages/web-components/src/styles/partials/index.ts b/packages/web-components/src/styles/partials/index.ts new file mode 100644 index 0000000000000..c7515fc1e06b2 --- /dev/null +++ b/packages/web-components/src/styles/partials/index.ts @@ -0,0 +1 @@ +export * from './badge.partials.js'; From b84500ac262445369fa5f27a1fa0568f49df592b Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Fri, 13 Jan 2023 19:55:30 -0800 Subject: [PATCH 2/9] add counter badge as a new component --- .../web-components/src/badge/badge.options.ts | 10 +- .../src/badge/badge.template.ts | 10 +- .../counter-badge/counter-badge.definition.ts | 19 +++ .../counter-badge/counter-badge.options.ts | 71 ++++++++ .../counter-badge/counter-badge.stories.ts | 152 ++++++++++++++++++ .../src/counter-badge/counter-badge.styles.ts | 67 ++++++++ .../counter-badge/counter-badge.template.ts | 15 ++ .../src/counter-badge/counter-badge.ts | 110 +++++++++++++ .../src/counter-badge/define.ts | 4 + .../web-components/src/counter-badge/index.ts | 5 + 10 files changed, 454 insertions(+), 9 deletions(-) create mode 100644 packages/web-components/src/counter-badge/counter-badge.definition.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.options.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.stories.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.styles.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.template.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.ts create mode 100644 packages/web-components/src/counter-badge/define.ts create mode 100644 packages/web-components/src/counter-badge/index.ts diff --git a/packages/web-components/src/badge/badge.options.ts b/packages/web-components/src/badge/badge.options.ts index 9e668bc000884..9e02e0abf7624 100644 --- a/packages/web-components/src/badge/badge.options.ts +++ b/packages/web-components/src/badge/badge.options.ts @@ -1,4 +1,12 @@ -import { ValuesOf } from '@microsoft/fast-foundation'; +import { StartEndOptions, StaticallyComposableHTML, ValuesOf } from '@microsoft/fast-foundation'; +import type { Badge } from './badge.js'; + +/** + * @internal - marking as internal update when Badge PR for start/end is in + */ +export type BadgeOptions = StartEndOptions & { + defaultContent?: StaticallyComposableHTML; +}; /** * BadgeAppearance constants diff --git a/packages/web-components/src/badge/badge.template.ts b/packages/web-components/src/badge/badge.template.ts index b91078489b5de..1c7e121bf58e7 100644 --- a/packages/web-components/src/badge/badge.template.ts +++ b/packages/web-components/src/badge/badge.template.ts @@ -1,19 +1,13 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import { endSlotTemplate, StartEndOptions, startSlotTemplate } from '@microsoft/fast-foundation'; +import { endSlotTemplate, startSlotTemplate } from '@microsoft/fast-foundation'; import type { Badge } from './badge.js'; -/** - * @internal - marking as internal - * Update with - */ -export type BadgeOptions = StartEndOptions; - /** * The template for the Badge component. * TODO: Replace w/ updated FAST Badge when aligned * @public */ -function badgeTemplate(options: BadgeOptions = {}): ElementViewTemplate { +export function badgeTemplate(options: BadgeOptions = {}): ElementViewTemplate { return html` ${startSlotTemplate(options)} diff --git a/packages/web-components/src/counter-badge/counter-badge.definition.ts b/packages/web-components/src/counter-badge/counter-badge.definition.ts new file mode 100644 index 0000000000000..2520d85972b6d --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { CounterBadge } from './counter-badge.js'; +import { styles } from './counter-badge.styles.js'; +import { template } from './counter-badge.template.js'; + +/** + * The Fluent CounterBadge Element. Implements {@link @microsoft/fast-foundation#Badge }, + * {@link @microsoft/fast-foundation#badgeTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = CounterBadge.compose({ + name: `${FluentDesignSystem.prefix}-counter-badge`, + template, + styles, +}); diff --git a/packages/web-components/src/counter-badge/counter-badge.options.ts b/packages/web-components/src/counter-badge/counter-badge.options.ts new file mode 100644 index 0000000000000..a2899500831c6 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.options.ts @@ -0,0 +1,71 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * CounterBadgeAppearance constants + * @public + */ +export const CounterBadgeAppearance = { + filled: 'filled', + ghost: 'ghost', +} as const; + +/** + * A CounterBadge can have an appearance of filled or ghost + * @public + */ +export type CounterBadgeAppearance = ValuesOf; + +/** + * CounterBadgeColor constants + * @public + */ +export const CounterBadgeColor = { + brand: 'brand', + danger: 'danger', + important: 'important', + informative: 'informative', + severe: 'severe', + subtle: 'subtle', + success: 'success', + warning: 'warning', +} as const; + +/** + * A CounterBadge can be one of preset colors + * @public + */ +export type CounterBadgeColor = ValuesOf; + +/** + * A CounterBadge shape can be circular or rounded. + * @public + */ +export const CounterBadgeShape = { + circular: 'circular', + rounded: 'rounded', +} as const; + +/** + * A CounterBadge can be one of preset colors + * @public + */ +export type CounterBadgeShape = ValuesOf; + +/** + * A CounterBadge can be square, circular or rounded. + * @public + */ +export const CounterBadgeSize = { + tiny: 'tiny', + extraSmall: 'extra-small', + small: 'small', + medium: 'medium', + large: 'large', + extraLarge: 'extra-large', +} as const; + +/** + * A CounterBadge can be on of several preset sizes. + * @public + */ +export type CounterBadgeSize = ValuesOf; diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts new file mode 100644 index 0000000000000..c8a02eefa7876 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -0,0 +1,152 @@ +import { html, when } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import type { CounterBadge as FluentCounterBadge } from './counter-badge.js'; +import { + CounterBadgeAppearance, + CounterBadgeColor, + CounterBadgeShape, + CounterBadgeSize, +} from './counter-badge.options'; +import './define.js'; + +type CounterBadgeStoryArgs = Args & FluentCounterBadge; +type CounterBadgeStoryMeta = Meta; + +const storyTemplate = html` + + ${when( + x => x.iconPosition === 'start', + html``, + )} + ${x => x.content} + ${when( + x => x.iconPosition === 'end', + html``, + )} + +`; + +export default { + title: 'Components/Counter Badge', + args: { + content: null, + }, + argTypes: { + appearance: { + options: Object.values(CounterBadgeAppearance), + control: { + type: 'select', + }, + }, + color: { + options: Object.keys(CounterBadgeColor), + control: { + type: 'select', + }, + }, + shape: { + options: Object.keys(CounterBadgeShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.keys(CounterBadgeSize), + control: { + type: 'select', + }, + }, + iconPosition: { + options: ['none', 'start', 'end'], + control: { + type: 'select', + }, + }, + dot: { + type: 'boolean', + }, + showZero: { + type: 'boolean', + }, + count: { + type: 'string', + defaultValue: '5', + }, + overflowCount: { + type: 'string', + }, + content: { + type: 'string', + }, + }, +} as CounterBadgeStoryMeta; + +export const Badge = renderComponent(storyTemplate).bind({}); + +export const Appearance = renderComponent(html` + filled + ghost +`); + +export const Color = renderComponent(html` + brand + danger + important + informative + severe + subtle + success + warning +`); + +export const Shape = renderComponent(html` + + +`); + +export const Size = renderComponent(html` + + + + + + +`) as CounterBadgeStoryMeta; + +export const Dot = renderComponent(html` `); diff --git a/packages/web-components/src/counter-badge/counter-badge.styles.ts b/packages/web-components/src/counter-badge/counter-badge.styles.ts new file mode 100644 index 0000000000000..5039dcb5b8674 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.styles.ts @@ -0,0 +1,67 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index'; +import { + borderRadiusCircular, + borderRadiusMedium, + borderRadiusSmall, + fontFamilyBase, + fontSizeBase200, + fontWeightSemibold, + lineHeightBase200, + strokeWidthThin, +} from '../theme/design-tokens.js'; + +/** Badge styles + * @public + */ +export const styles = css` + ${display('inline-flex')} :host { + position: relative; + box-sizing: border-box; + align-items: center; + justify-content: center; + font-family: ${fontFamilyBase}; + font-weight: ${fontWeightSemibold}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + } + + :host(:not([appearance='ghost'])) { + content: ''; + position: 'absolute'; + top: 0; + left: 0; + bottom: 0; + right: 0; + border-style: solid; + border-width: ${strokeWidthThin}; + border-color: inherit; + border-radius: inherit; + } + + :host([shape='circular']) { + border-radius: ${borderRadiusCircular}; + } + + :host([shape='rounded']) { + border-radius: ${borderRadiusMedium}; + } + + :host([shape='rounded'][size='tiny']), + :host([shape='rounded'][size='extra-small']), + :host([shape='rounded'][size='small']) { + border-radius: ${borderRadiusSmall}; + } + + :host([dot]) { + min-width: auto; + width: 6px; + height: 6px; + padding: 0; + } + + ${badgeSizeStyles} + ${badgeFilledStyles} + ${badgeGhostStyles} +`; diff --git a/packages/web-components/src/counter-badge/counter-badge.template.ts b/packages/web-components/src/counter-badge/counter-badge.template.ts new file mode 100644 index 0000000000000..7750eafc9741c --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.template.ts @@ -0,0 +1,15 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { html } from '../../../../node_modules/@microsoft/fast-element/dist/dts/index'; +import { BadgeOptions } from '../badge/badge.options.js'; +import { badgeTemplate } from '../badge/badge.template'; +import { CounterBadge } from './counter-badge'; + +/** + * CounterBadge options + * @public + */ +export type CounterBadgeOptions = BadgeOptions; + +export const template: ElementViewTemplate = badgeTemplate({ + defaultContent: html.partial(`${x => x.setCount()}`), +}); diff --git a/packages/web-components/src/counter-badge/counter-badge.ts b/packages/web-components/src/counter-badge/counter-badge.ts new file mode 100644 index 0000000000000..4c146256748b0 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.ts @@ -0,0 +1,110 @@ +import { attr, FASTElement } from '@microsoft/fast-element'; +import { applyMixins, StartEnd } from '@microsoft/fast-foundation'; +import { nullableNumberConverter } from '../../../../node_modules/@microsoft/fast-element/dist/dts/index'; +import { CounterBadgeAppearance, CounterBadgeColor, CounterBadgeShape, CounterBadgeSize } from './badge.options'; + +/** + * The base class used for constructing a fluent-badge custom element + * @public + */ +export class CounterBadge extends FASTElement { + /** + * The appearance the badge should have. + * + * @public + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance: CounterBadgeAppearance = CounterBadgeAppearance.filled; + + /** + * The color the badge should have. + * + * @public + * @remarks + * HTML Attribute: color + */ + @attr + public color: CounterBadgeColor = CounterBadgeColor; + /** + * The shape the badge should have. + * + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape: CounterBadgeShape = CounterBadgeAppearance.circular; + + /** + * The size the badge should have. + * + * @public + * @remarks + * HTML Attribute: size + */ + @attr + public size: CounterBadgeSize = CounterBadgeSize.medium; + + /** + * The count the badge should have. + * + * @public + * @remarks + * HTML Attribute: count + */ + @attr({ converter: nullableNumberConverter }) + public count: number = 0; + + /** + * Max number to be displayed + * + * @public + * @remarks + * HTML Attribute: overflow-count + */ + @attr({ attribute: 'overflow-count', converter: nullableNumberConverter }) + public overflowCount: number = 99; + + /** + * If the badge should be shown when count is 0 + * + * @public + * @remarks + * HTML Attribute: showzero + */ + @attr({ attribute: 'show-zero', mode: 'boolean' }) + public showZero: boolean = false; + + /** + * If a dot should be displayed without the count + * + * @public + * @remarks + * HTML Attribute: dot + */ + @attr + public dot: boolean = false; + + /** + * @internal + * Function to set the count + * This is the default slotted content for the counter badge + * If children are slotted, that will override the value returned + */ + public setCount() { + if ((this.count !== 0 || this.showZero) && !this.dot) { + return this.count > this.overflowCount ? `${this.overflowCount}+` : `${this.count}`; + } + } +} + +/** + * Mark internal because exporting class and interface of the same name + * confuses API extractor. + * TODO: Below will be unnecessary when Badge class gets updated + * @internal + */ +export type CounterBadge = StartEnd +applyMixins(CounterBadge, StartEnd); diff --git a/packages/web-components/src/counter-badge/define.ts b/packages/web-components/src/counter-badge/define.ts new file mode 100644 index 0000000000000..d0e348b49c9c9 --- /dev/null +++ b/packages/web-components/src/counter-badge/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './badge.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/counter-badge/index.ts b/packages/web-components/src/counter-badge/index.ts new file mode 100644 index 0000000000000..92e3fdcd87214 --- /dev/null +++ b/packages/web-components/src/counter-badge/index.ts @@ -0,0 +1,5 @@ +export * from './badge.js'; +export * from './badge.options.js'; +export { template as BadgeTemplate } from './badge.template.js'; +export { styles as BadgeStyles } from './badge.styles.js'; +export { definition as BadgeDefinition } from './badge.definition.js'; From 7540dc7a67a2579884f891521a6b07a414795abf Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Fri, 13 Jan 2023 20:00:23 -0800 Subject: [PATCH 3/9] fix broken import and add export paths --- packages/web-components/package.json | 8 ++++++++ .../web-components/src/badge/badge.template.ts | 1 + packages/web-components/src/badge/badge.ts | 3 ++- .../src/counter-badge/counter-badge.options.ts | 7 +++++++ .../src/counter-badge/counter-badge.stories.ts | 4 ++-- .../src/counter-badge/counter-badge.styles.ts | 2 +- .../src/counter-badge/counter-badge.template.ts | 16 ++++------------ .../src/counter-badge/counter-badge.ts | 13 +++++++++---- .../web-components/src/counter-badge/define.ts | 2 +- .../web-components/src/counter-badge/index.ts | 10 +++++----- packages/web-components/src/index.ts | 1 + 11 files changed, 41 insertions(+), 26 deletions(-) diff --git a/packages/web-components/package.json b/packages/web-components/package.json index cc6f872c50bfd..9cd9deeb1d6f2 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -24,6 +24,14 @@ "types": "./dist/dts/index.d.ts", "default": "./dist/esm/index.js" }, + "./badge": { + "types": "./dist/esm/badge/define.d.ts", + "default": "./dist/esm/badge/define.js" + }, + "./counter-badge": { + "types": "./dist/esm/counter-badge/define.d.ts", + "default": "./dist/esm/counter-badge/define.js" + }, "./text": { "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" diff --git a/packages/web-components/src/badge/badge.template.ts b/packages/web-components/src/badge/badge.template.ts index 1c7e121bf58e7..e5d10f2f960ce 100644 --- a/packages/web-components/src/badge/badge.template.ts +++ b/packages/web-components/src/badge/badge.template.ts @@ -1,6 +1,7 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; import { endSlotTemplate, startSlotTemplate } from '@microsoft/fast-foundation'; import type { Badge } from './badge.js'; +import type { BadgeOptions } from './badge.options.js'; /** * The template for the Badge component. diff --git a/packages/web-components/src/badge/badge.ts b/packages/web-components/src/badge/badge.ts index f0d6640cb396d..27dfc16ee52ac 100644 --- a/packages/web-components/src/badge/badge.ts +++ b/packages/web-components/src/badge/badge.ts @@ -1,6 +1,6 @@ import { attr, FASTElement } from '@microsoft/fast-element'; import { applyMixins, StartEnd } from '@microsoft/fast-foundation'; -import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options'; +import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; /** * The base class used for constructing a fluent-badge custom element @@ -53,5 +53,6 @@ export class Badge extends FASTElement { * TODO: Below will be unnecessary when Badge class gets updated * @internal */ +/* eslint-disable-next-line */ export interface Badge extends StartEnd {} applyMixins(Badge, StartEnd); diff --git a/packages/web-components/src/counter-badge/counter-badge.options.ts b/packages/web-components/src/counter-badge/counter-badge.options.ts index a2899500831c6..02db6af0a483e 100644 --- a/packages/web-components/src/counter-badge/counter-badge.options.ts +++ b/packages/web-components/src/counter-badge/counter-badge.options.ts @@ -1,4 +1,11 @@ import { ValuesOf } from '@microsoft/fast-foundation'; +import { BadgeOptions } from '../badge/badge.options.js'; + +/** + * CounterBadge options + * @public + */ +export type CounterBadgeOptions = BadgeOptions; /** * CounterBadgeAppearance constants diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts index c8a02eefa7876..0651402e4c58e 100644 --- a/packages/web-components/src/counter-badge/counter-badge.stories.ts +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -7,7 +7,7 @@ import { CounterBadgeColor, CounterBadgeShape, CounterBadgeSize, -} from './counter-badge.options'; +} from './counter-badge.options.js'; import './define.js'; type CounterBadgeStoryArgs = Args & FluentCounterBadge; @@ -117,7 +117,7 @@ export default { }, } as CounterBadgeStoryMeta; -export const Badge = renderComponent(storyTemplate).bind({}); +export const CounterBadge = renderComponent(storyTemplate).bind({}); export const Appearance = renderComponent(html` filled diff --git a/packages/web-components/src/counter-badge/counter-badge.styles.ts b/packages/web-components/src/counter-badge/counter-badge.styles.ts index 5039dcb5b8674..d27418bfbc33e 100644 --- a/packages/web-components/src/counter-badge/counter-badge.styles.ts +++ b/packages/web-components/src/counter-badge/counter-badge.styles.ts @@ -1,6 +1,6 @@ import { css } from '@microsoft/fast-element'; import { display } from '@microsoft/fast-foundation'; -import { badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index'; +import { badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index.js'; import { borderRadiusCircular, borderRadiusMedium, diff --git a/packages/web-components/src/counter-badge/counter-badge.template.ts b/packages/web-components/src/counter-badge/counter-badge.template.ts index 7750eafc9741c..1019a46195153 100644 --- a/packages/web-components/src/counter-badge/counter-badge.template.ts +++ b/packages/web-components/src/counter-badge/counter-badge.template.ts @@ -1,15 +1,7 @@ -import { ElementViewTemplate } from '@microsoft/fast-element'; -import { html } from '../../../../node_modules/@microsoft/fast-element/dist/dts/index'; -import { BadgeOptions } from '../badge/badge.options.js'; -import { badgeTemplate } from '../badge/badge.template'; -import { CounterBadge } from './counter-badge'; - -/** - * CounterBadge options - * @public - */ -export type CounterBadgeOptions = BadgeOptions; +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { badgeTemplate } from '../badge/badge.template.js'; +import { CounterBadge } from './counter-badge.js'; export const template: ElementViewTemplate = badgeTemplate({ - defaultContent: html.partial(`${x => x.setCount()}`), + defaultContent: html.partial(`${x => x.setCount()}`), }); diff --git a/packages/web-components/src/counter-badge/counter-badge.ts b/packages/web-components/src/counter-badge/counter-badge.ts index 4c146256748b0..e14fd128bb0a5 100644 --- a/packages/web-components/src/counter-badge/counter-badge.ts +++ b/packages/web-components/src/counter-badge/counter-badge.ts @@ -1,7 +1,11 @@ -import { attr, FASTElement } from '@microsoft/fast-element'; +import { attr, FASTElement, nullableNumberConverter } from '@microsoft/fast-element'; import { applyMixins, StartEnd } from '@microsoft/fast-foundation'; -import { nullableNumberConverter } from '../../../../node_modules/@microsoft/fast-element/dist/dts/index'; -import { CounterBadgeAppearance, CounterBadgeColor, CounterBadgeShape, CounterBadgeSize } from './badge.options'; +import { + CounterBadgeAppearance, + CounterBadgeColor, + CounterBadgeShape, + CounterBadgeSize, +} from './counter-badge.options.js'; /** * The base class used for constructing a fluent-badge custom element @@ -106,5 +110,6 @@ export class CounterBadge extends FASTElement { * TODO: Below will be unnecessary when Badge class gets updated * @internal */ -export type CounterBadge = StartEnd +/* eslint-disable-next-line */ +export interface CounterBadge extends StartEnd {} applyMixins(CounterBadge, StartEnd); diff --git a/packages/web-components/src/counter-badge/define.ts b/packages/web-components/src/counter-badge/define.ts index d0e348b49c9c9..e08fef18aeccb 100644 --- a/packages/web-components/src/counter-badge/define.ts +++ b/packages/web-components/src/counter-badge/define.ts @@ -1,4 +1,4 @@ import { FluentDesignSystem } from '../fluent-design-system.js'; -import { definition } from './badge.definition.js'; +import { definition } from './counter-badge.definition.js'; definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/counter-badge/index.ts b/packages/web-components/src/counter-badge/index.ts index 92e3fdcd87214..159c31d2e2f94 100644 --- a/packages/web-components/src/counter-badge/index.ts +++ b/packages/web-components/src/counter-badge/index.ts @@ -1,5 +1,5 @@ -export * from './badge.js'; -export * from './badge.options.js'; -export { template as BadgeTemplate } from './badge.template.js'; -export { styles as BadgeStyles } from './badge.styles.js'; -export { definition as BadgeDefinition } from './badge.definition.js'; +export * from './counter-badge.js'; +export * from './counter-badge.options.js'; +export { template as CounterBadgeTemplate } from './counter-badge.template.js'; +export { styles as CounterBadgeStyles } from './counter-badge.styles.js'; +export { definition as CounterBadgeDefinition } from './counter-badge.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 2bc95acee2656..bd9a8b7c5b0b6 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,2 +1,3 @@ export * from './badge/index.js'; +export * from './counter-badge/index.js'; export * from './text/index.js'; From e238735aead27243ad04ba0cdc8c9adcbd66c227 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Fri, 13 Jan 2023 20:57:05 -0800 Subject: [PATCH 4/9] use badge template for counter badge to render count --- ...-25e8f64c-845e-401f-a7f8-c9472a5720df.json | 2 +- .../web-components/src/badge/badge.options.ts | 6 +- .../web-components/src/badge/badge.stories.ts | 6 +- .../src/badge/badge.template.ts | 5 +- .../counter-badge/counter-badge.stories.ts | 107 +++++++----------- .../src/counter-badge/counter-badge.styles.ts | 10 +- .../counter-badge/counter-badge.template.ts | 17 ++- .../src/counter-badge/counter-badge.ts | 24 ++-- .../src/styles/partials/badge.partials.ts | 14 ++- 9 files changed, 90 insertions(+), 101 deletions(-) diff --git a/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json index ad13257ed2c24..094c23a891496 100644 --- a/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json +++ b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json @@ -1,6 +1,6 @@ { "type": "prerelease", - "comment": "add badge as a new component", + "comment": "add badge and counter badge as new components", "packageName": "@fluentui/web-components", "email": "chhol@microsoft.com", "dependentChangeType": "patch" diff --git a/packages/web-components/src/badge/badge.options.ts b/packages/web-components/src/badge/badge.options.ts index 9e02e0abf7624..1b53695e51e38 100644 --- a/packages/web-components/src/badge/badge.options.ts +++ b/packages/web-components/src/badge/badge.options.ts @@ -1,12 +1,10 @@ -import { StartEndOptions, StaticallyComposableHTML, ValuesOf } from '@microsoft/fast-foundation'; +import { StartEndOptions, ValuesOf } from '@microsoft/fast-foundation'; import type { Badge } from './badge.js'; /** * @internal - marking as internal update when Badge PR for start/end is in */ -export type BadgeOptions = StartEndOptions & { - defaultContent?: StaticallyComposableHTML; -}; +export type BadgeOptions = StartEndOptions; /** * BadgeAppearance constants diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts index 0068a049d3164..a8dcd39c4af36 100644 --- a/packages/web-components/src/badge/badge.stories.ts +++ b/packages/web-components/src/badge/badge.stories.ts @@ -49,7 +49,7 @@ const storyTemplate = html` `; export default { - title: 'Components/Badge', + title: 'Components/Badge/Badge', args: { content: null, }, @@ -73,7 +73,7 @@ export default { }, }, size: { - options: Object.keys(BadgeSize), + options: Object.values(BadgeSize), control: { type: 'select', }, @@ -85,7 +85,7 @@ export default { }, }, content: { - type: 'string', + control: 'text', }, }, } as BadgeStoryMeta; diff --git a/packages/web-components/src/badge/badge.template.ts b/packages/web-components/src/badge/badge.template.ts index e5d10f2f960ce..1b4fab522ff87 100644 --- a/packages/web-components/src/badge/badge.template.ts +++ b/packages/web-components/src/badge/badge.template.ts @@ -1,17 +1,16 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import { endSlotTemplate, startSlotTemplate } from '@microsoft/fast-foundation'; +import { endSlotTemplate, startSlotTemplate, staticallyCompose } from '@microsoft/fast-foundation'; import type { Badge } from './badge.js'; import type { BadgeOptions } from './badge.options.js'; /** * The template for the Badge component. - * TODO: Replace w/ updated FAST Badge when aligned * @public */ export function badgeTemplate(options: BadgeOptions = {}): ElementViewTemplate { return html` ${startSlotTemplate(options)} - + ${staticallyCompose(options.defaultContent)} ${endSlotTemplate(options)} `; } diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts index 0651402e4c58e..db1c551af0662 100644 --- a/packages/web-components/src/counter-badge/counter-badge.stories.ts +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -1,4 +1,4 @@ -import { html, when } from '@microsoft/fast-element'; +import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../__test__/helpers.js'; import type { CounterBadge as FluentCounterBadge } from './counter-badge.js'; @@ -13,6 +13,8 @@ import './define.js'; type CounterBadgeStoryArgs = Args & FluentCounterBadge; type CounterBadgeStoryMeta = Meta; +// TODO: Currently cannot show icon or content +// in the counter badge stories because it projects as slotted content const storyTemplate = html` ` overflow-count="${x => x.overflowCount}" ?show-zero="${x => x.showZero}" ?dot="${x => x.dot}" - > - ${when( - x => x.iconPosition === 'start', - html``, - )} - ${x => x.content} - ${when( - x => x.iconPosition === 'end', - html``, - )} - + > `; export default { - title: 'Components/Counter Badge', + title: 'Components/Badge/Counter Badge', args: { - content: null, + dot: false, + showZero: false, + appearance: CounterBadgeAppearance.filled, + color: CounterBadgeColor.brand, + shape: CounterBadgeShape.circular, + count: 5, }, argTypes: { appearance: { @@ -87,7 +58,7 @@ export default { }, }, size: { - options: Object.keys(CounterBadgeSize), + options: Object.values(CounterBadgeSize), control: { type: 'select', }, @@ -99,20 +70,16 @@ export default { }, }, dot: { - type: 'boolean', + control: 'boolean', }, showZero: { - type: 'boolean', + control: 'boolean', }, count: { - type: 'string', - defaultValue: '5', + control: 'number', }, overflowCount: { - type: 'string', - }, - content: { - type: 'string', + control: 'text', }, }, } as CounterBadgeStoryMeta; @@ -120,33 +87,37 @@ export default { export const CounterBadge = renderComponent(storyTemplate).bind({}); export const Appearance = renderComponent(html` - filled - ghost + + `); export const Color = renderComponent(html` - brand - danger - important - informative - severe - subtle - success - warning + + + + + + + + `); export const Shape = renderComponent(html` - - + + `); export const Size = renderComponent(html` - - - - - - + + + + + + `) as CounterBadgeStoryMeta; -export const Dot = renderComponent(html` `); +export const Dot = renderComponent(html``); + +export const ShowZero = renderComponent( + html``, +); diff --git a/packages/web-components/src/counter-badge/counter-badge.styles.ts b/packages/web-components/src/counter-badge/counter-badge.styles.ts index d27418bfbc33e..f68efdf917008 100644 --- a/packages/web-components/src/counter-badge/counter-badge.styles.ts +++ b/packages/web-components/src/counter-badge/counter-badge.styles.ts @@ -54,14 +54,14 @@ export const styles = css` border-radius: ${borderRadiusSmall}; } - :host([dot]) { + ${badgeSizeStyles} + ${badgeFilledStyles} + ${badgeGhostStyles} + + :host([dot][appearance][size]) { min-width: auto; width: 6px; height: 6px; padding: 0; } - - ${badgeSizeStyles} - ${badgeFilledStyles} - ${badgeGhostStyles} `; diff --git a/packages/web-components/src/counter-badge/counter-badge.template.ts b/packages/web-components/src/counter-badge/counter-badge.template.ts index 1019a46195153..11e266055f053 100644 --- a/packages/web-components/src/counter-badge/counter-badge.template.ts +++ b/packages/web-components/src/counter-badge/counter-badge.template.ts @@ -1,7 +1,16 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import { badgeTemplate } from '../badge/badge.template.js'; +import { badgeTemplate } from '../badge/badge.template'; import { CounterBadge } from './counter-badge.js'; +import { CounterBadgeOptions } from './counter-badge.options.js'; -export const template: ElementViewTemplate = badgeTemplate({ - defaultContent: html.partial(`${x => x.setCount()}`), -}); +function composeTemplate(options: CounterBadgeOptions = {}): ElementViewTemplate { + return badgeTemplate({ + defaultContent: html`${x => x.setCount()}`, + }); +} + +/** + * The template for the Counter Badge component. + * @public + */ +export const template: ElementViewTemplate = composeTemplate(); diff --git a/packages/web-components/src/counter-badge/counter-badge.ts b/packages/web-components/src/counter-badge/counter-badge.ts index e14fd128bb0a5..596c16efe817e 100644 --- a/packages/web-components/src/counter-badge/counter-badge.ts +++ b/packages/web-components/src/counter-badge/counter-badge.ts @@ -30,7 +30,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: color */ @attr - public color: CounterBadgeColor = CounterBadgeColor; + public color: CounterBadgeColor = CounterBadgeColor.brand; /** * The shape the badge should have. * @@ -39,7 +39,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: shape */ @attr - public shape: CounterBadgeShape = CounterBadgeAppearance.circular; + public shape: CounterBadgeShape = CounterBadgeShape.circular; /** * The size the badge should have. @@ -60,6 +60,9 @@ export class CounterBadge extends FASTElement { */ @attr({ converter: nullableNumberConverter }) public count: number = 0; + protected countChanged() { + this.setCount(); + } /** * Max number to be displayed @@ -70,13 +73,16 @@ export class CounterBadge extends FASTElement { */ @attr({ attribute: 'overflow-count', converter: nullableNumberConverter }) public overflowCount: number = 99; + protected overflowCountChanged() { + this.setCount(); + } /** * If the badge should be shown when count is 0 * * @public * @remarks - * HTML Attribute: showzero + * HTML Attribute: show-zero */ @attr({ attribute: 'show-zero', mode: 'boolean' }) public showZero: boolean = false; @@ -88,7 +94,7 @@ export class CounterBadge extends FASTElement { * @remarks * HTML Attribute: dot */ - @attr + @attr({ mode: 'boolean' }) public dot: boolean = false; /** @@ -97,10 +103,14 @@ export class CounterBadge extends FASTElement { * This is the default slotted content for the counter badge * If children are slotted, that will override the value returned */ - public setCount() { - if ((this.count !== 0 || this.showZero) && !this.dot) { - return this.count > this.overflowCount ? `${this.overflowCount}+` : `${this.count}`; + public setCount(): string | void { + const count: number | null = this.count ?? 0; + + if ((count !== 0 || this.showZero) && !this.dot) { + return count > this.overflowCount ? `${this.overflowCount}+` : `${count}`; } + + return; } } diff --git a/packages/web-components/src/styles/partials/badge.partials.ts b/packages/web-components/src/styles/partials/badge.partials.ts index 2a91221b14e57..5d4f159a1f174 100644 --- a/packages/web-components/src/styles/partials/badge.partials.ts +++ b/packages/web-components/src/styles/partials/badge.partials.ts @@ -37,7 +37,9 @@ import { colorPaletteYellowForeground2, colorTransparentStroke, fontSizeBase100, + fontSizeBase200, lineHeightBase100, + lineHeightBase200, spacingHorizontalSNudge, spacingHorizontalXS, spacingHorizontalXXS, @@ -81,8 +83,8 @@ export const badgeSizeStyles = css.partial` :host([size='medium']) { min-width: 20px; height: 20px; - font-size: ${fontSizeBase100}; - line-height: ${lineHeightBase100}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); } :host([size='medium']) ::slotted(svg) { @@ -91,8 +93,8 @@ export const badgeSizeStyles = css.partial` :host([size='large']) { min-width: 24px; height: 24px; - font-size: ${fontSizeBase100}; - line-height: ${lineHeightBase100}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); } :host([size='large']) ::slotted(svg) { @@ -101,8 +103,8 @@ export const badgeSizeStyles = css.partial` :host([size='extra-large']) { min-width: 32px; height: 32px; - font-size: ${fontSizeBase100}; - line-height: ${lineHeightBase100}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; padding-inline: calc(${spacingHorizontalSNudge} + ${textPadding}); } :host([size='extra-large']) ::slotted(svg) { From 967f001f08dce616d05993d380f06a0896284b94 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 17 Jan 2023 09:40:47 -0800 Subject: [PATCH 5/9] update badge svg styles and fix import syntax --- .../src/counter-badge/counter-badge.template.ts | 2 +- .../web-components/src/styles/partials/badge.partials.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web-components/src/counter-badge/counter-badge.template.ts b/packages/web-components/src/counter-badge/counter-badge.template.ts index 11e266055f053..f0049a3abc528 100644 --- a/packages/web-components/src/counter-badge/counter-badge.template.ts +++ b/packages/web-components/src/counter-badge/counter-badge.template.ts @@ -1,5 +1,5 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import { badgeTemplate } from '../badge/badge.template'; +import { badgeTemplate } from '../badge/badge.template.js'; import { CounterBadge } from './counter-badge.js'; import { CounterBadgeOptions } from './counter-badge.options.js'; diff --git a/packages/web-components/src/styles/partials/badge.partials.ts b/packages/web-components/src/styles/partials/badge.partials.ts index 5d4f159a1f174..108a8a9dd8049 100644 --- a/packages/web-components/src/styles/partials/badge.partials.ts +++ b/packages/web-components/src/styles/partials/badge.partials.ts @@ -78,7 +78,7 @@ export const badgeSizeStyles = css.partial` padding-inline: calc(${spacingHorizontalXXS} + ${textPadding}); } :host([size='small']) ::slotted(svg) { - font-size: 10px; + font-size: 12px; } :host([size='medium']) { min-width: 20px; @@ -88,7 +88,7 @@ export const badgeSizeStyles = css.partial` padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); } :host([size='medium']) ::slotted(svg) { - font-size: 10px; + font-size: 12px; } :host([size='large']) { min-width: 24px; @@ -98,7 +98,7 @@ export const badgeSizeStyles = css.partial` padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); } :host([size='large']) ::slotted(svg) { - font-size: 10px; + font-size: 16px; } :host([size='extra-large']) { min-width: 32px; From 703338465b1fba3aeb77dc13d2e8ada2fbda145c Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 17 Jan 2023 11:11:53 -0800 Subject: [PATCH 6/9] fixup imports for stories --- packages/web-components/src/badge/badge.stories.ts | 6 +++--- .../src/counter-badge/counter-badge.stories.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts index a8dcd39c4af36..f931eadf524be 100644 --- a/packages/web-components/src/badge/badge.stories.ts +++ b/packages/web-components/src/badge/badge.stories.ts @@ -2,7 +2,7 @@ import { html, when } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../__test__/helpers.js'; import type { Badge as FluentBadge } from './badge.js'; -import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options'; +import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; import './define.js'; type BadgeStoryArgs = Args & FluentBadge; @@ -61,13 +61,13 @@ export default { }, }, color: { - options: Object.keys(BadgeColor), + options: Object.values(BadgeColor), control: { type: 'select', }, }, shape: { - options: Object.keys(BadgeShape), + options: Object.values(BadgeShape), control: { type: 'select', }, diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts index db1c551af0662..0eb8cb50e6cb6 100644 --- a/packages/web-components/src/counter-badge/counter-badge.stories.ts +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -46,13 +46,13 @@ export default { }, }, color: { - options: Object.keys(CounterBadgeColor), + options: Object.values(CounterBadgeColor), control: { type: 'select', }, }, shape: { - options: Object.keys(CounterBadgeShape), + options: Object.values(CounterBadgeShape), control: { type: 'select', }, From cf326183b157148be375b9f04047e2cf3e1f66ed Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 17 Jan 2023 12:10:02 -0800 Subject: [PATCH 7/9] update partial with default styles --- .../web-components/src/badge/badge.styles.ts | 45 +--------- packages/web-components/src/badge/badge.ts | 4 +- .../counter-badge/counter-badge.stories.ts | 24 ++--- .../src/counter-badge/counter-badge.styles.ts | 44 +-------- .../src/counter-badge/counter-badge.ts | 8 +- .../src/styles/partials/badge.partials.ts | 90 ++++++++++++------- 6 files changed, 85 insertions(+), 130 deletions(-) diff --git a/packages/web-components/src/badge/badge.styles.ts b/packages/web-components/src/badge/badge.styles.ts index 410b3ec3f377a..7b73ab0f6bc08 100644 --- a/packages/web-components/src/badge/badge.styles.ts +++ b/packages/web-components/src/badge/badge.styles.ts @@ -1,60 +1,22 @@ import { css } from '@microsoft/fast-element'; -import { display } from '@microsoft/fast-foundation'; import { + badgeBaseStyles, badgeFilledStyles, badgeGhostStyles, badgeOutlineStyles, badgeSizeStyles, badgeTintStyles, } from '../styles/index'; -import { - borderRadiusCircular, - borderRadiusMedium, - borderRadiusNone, - borderRadiusSmall, - fontFamilyBase, - fontSizeBase200, - fontWeightSemibold, - lineHeightBase200, - strokeWidthThin, -} from '../theme/design-tokens.js'; - +import { borderRadiusMedium, borderRadiusNone, borderRadiusSmall } from '../theme/design-tokens.js'; +// why is the border not showing up? /** Badge styles * @public */ export const styles = css` - ${display('inline-flex')} :host { - position: relative; - box-sizing: border-box; - align-items: center; - justify-content: center; - font-family: ${fontFamilyBase}; - font-weight: ${fontWeightSemibold}; - font-size: ${fontSizeBase200}; - line-height: ${lineHeightBase200}; - } - - :host(:not([appearance='ghost'])) { - content: ''; - position: 'absolute'; - top: 0; - left: 0; - bottom: 0; - right: 0; - border-style: solid; - border-width: ${strokeWidthThin}; - border-color: inherit; - border-radius: inherit; - } - :host([shape='square']) { border-radius: ${borderRadiusNone}; } - :host([shape='circular']) { - border-radius: ${borderRadiusCircular}; - } - :host([shape='rounded']) { border-radius: ${borderRadiusMedium}; } @@ -70,4 +32,5 @@ export const styles = css` ${badgeGhostStyles} ${badgeOutlineStyles} ${badgeTintStyles} + ${badgeBaseStyles} `; diff --git a/packages/web-components/src/badge/badge.ts b/packages/web-components/src/badge/badge.ts index 27dfc16ee52ac..25481e08d57a5 100644 --- a/packages/web-components/src/badge/badge.ts +++ b/packages/web-components/src/badge/badge.ts @@ -34,7 +34,7 @@ export class Badge extends FASTElement { * HTML Attribute: shape */ @attr - public shape: BadgeShape = BadgeShape.circular; + public shape: BadgeShape; /** * The size the badge should have. @@ -44,7 +44,7 @@ export class Badge extends FASTElement { * HTML Attribute: size */ @attr - public size: BadgeSize = BadgeSize.medium; + public size: BadgeSize; } /** diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts index 0eb8cb50e6cb6..aa3011ade4622 100644 --- a/packages/web-components/src/counter-badge/counter-badge.stories.ts +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -87,24 +87,24 @@ export default { export const CounterBadge = renderComponent(storyTemplate).bind({}); export const Appearance = renderComponent(html` - - + + `); export const Color = renderComponent(html` - - - - - - - - + + + + + + + + `); export const Shape = renderComponent(html` - - + + `); export const Size = renderComponent(html` diff --git a/packages/web-components/src/counter-badge/counter-badge.styles.ts b/packages/web-components/src/counter-badge/counter-badge.styles.ts index f68efdf917008..7db498fccc673 100644 --- a/packages/web-components/src/counter-badge/counter-badge.styles.ts +++ b/packages/web-components/src/counter-badge/counter-badge.styles.ts @@ -1,49 +1,11 @@ import { css } from '@microsoft/fast-element'; -import { display } from '@microsoft/fast-foundation'; -import { badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index.js'; -import { - borderRadiusCircular, - borderRadiusMedium, - borderRadiusSmall, - fontFamilyBase, - fontSizeBase200, - fontWeightSemibold, - lineHeightBase200, - strokeWidthThin, -} from '../theme/design-tokens.js'; +import { badgeBaseStyles, badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index.js'; +import { borderRadiusMedium, borderRadiusSmall } from '../theme/design-tokens.js'; /** Badge styles * @public */ export const styles = css` - ${display('inline-flex')} :host { - position: relative; - box-sizing: border-box; - align-items: center; - justify-content: center; - font-family: ${fontFamilyBase}; - font-weight: ${fontWeightSemibold}; - font-size: ${fontSizeBase200}; - line-height: ${lineHeightBase200}; - } - - :host(:not([appearance='ghost'])) { - content: ''; - position: 'absolute'; - top: 0; - left: 0; - bottom: 0; - right: 0; - border-style: solid; - border-width: ${strokeWidthThin}; - border-color: inherit; - border-radius: inherit; - } - - :host([shape='circular']) { - border-radius: ${borderRadiusCircular}; - } - :host([shape='rounded']) { border-radius: ${borderRadiusMedium}; } @@ -57,7 +19,9 @@ export const styles = css` ${badgeSizeStyles} ${badgeFilledStyles} ${badgeGhostStyles} + ${badgeBaseStyles} + :host([dot]), :host([dot][appearance][size]) { min-width: auto; width: 6px; diff --git a/packages/web-components/src/counter-badge/counter-badge.ts b/packages/web-components/src/counter-badge/counter-badge.ts index 596c16efe817e..38ca98713df4b 100644 --- a/packages/web-components/src/counter-badge/counter-badge.ts +++ b/packages/web-components/src/counter-badge/counter-badge.ts @@ -20,7 +20,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: appearance */ @attr - public appearance: CounterBadgeAppearance = CounterBadgeAppearance.filled; + public appearance: CounterBadgeAppearance; /** * The color the badge should have. @@ -30,7 +30,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: color */ @attr - public color: CounterBadgeColor = CounterBadgeColor.brand; + public color: CounterBadgeColor; /** * The shape the badge should have. * @@ -39,7 +39,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: shape */ @attr - public shape: CounterBadgeShape = CounterBadgeShape.circular; + public shape: CounterBadgeShape; /** * The size the badge should have. @@ -49,7 +49,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: size */ @attr - public size: CounterBadgeSize = CounterBadgeSize.medium; + public size: CounterBadgeSize; /** * The count the badge should have. diff --git a/packages/web-components/src/styles/partials/badge.partials.ts b/packages/web-components/src/styles/partials/badge.partials.ts index 108a8a9dd8049..cb1263e59d458 100644 --- a/packages/web-components/src/styles/partials/badge.partials.ts +++ b/packages/web-components/src/styles/partials/badge.partials.ts @@ -1,5 +1,7 @@ import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; import { + borderRadiusCircular, colorBrandBackground, colorBrandBackground2, colorBrandForeground1, @@ -36,17 +38,57 @@ import { colorPaletteYellowBorder1, colorPaletteYellowForeground2, colorTransparentStroke, + fontFamilyBase, fontSizeBase100, fontSizeBase200, + fontWeightSemibold, lineHeightBase100, lineHeightBase200, spacingHorizontalSNudge, spacingHorizontalXS, spacingHorizontalXXS, + strokeWidthThin, } from '../../theme/design-tokens.js'; const textPadding = spacingHorizontalXXS; +export const badgeBaseStyles = css.partial` + ${display('inline-flex')} :host { + position: relative; + box-sizing: border-box; + align-items: center; + justify-content: center; + font-family: ${fontFamilyBase}; + font-weight: ${fontWeightSemibold}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + min-width: 20px; + height: 20px; + padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); + border-radius: ${borderRadiusCircular}; + border-color: ${colorTransparentStroke}; + background-color: ${colorBrandBackground}; + color: ${colorNeutralForegroundOnBrand}; + } + + ::slotted(svg) { + font-size: 12px; + } + + :host(:not([appearance='ghost']))::after { + position: absolute; + content: ''; + top: 0; + left: 0; + bottom: 0; + right: 0; + border-style: solid; + border-width: ${strokeWidthThin}; + border-color: inherit; + border-radius: inherit; + } +`; + /** * @public * The badge's size styles @@ -57,6 +99,8 @@ export const badgeSizeStyles = css.partial` height: 6px; font-size: 4px; line-height: 4px; + padding-inline: 0; + min-width: unset; } :host([size='tiny']) ::slotted(svg) { font-size: 6px; @@ -66,6 +110,8 @@ export const badgeSizeStyles = css.partial` height: 10px; font-size: 6px; line-height: 6px; + padding-inline: 0; + min-width: unset; } :host([size='extra-small']) ::slotted(svg) { font-size: 10px; @@ -80,16 +126,6 @@ export const badgeSizeStyles = css.partial` :host([size='small']) ::slotted(svg) { font-size: 12px; } - :host([size='medium']) { - min-width: 20px; - height: 20px; - font-size: ${fontSizeBase200}; - line-height: ${lineHeightBase200}; - padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); - } - :host([size='medium']) ::slotted(svg) { - font-size: 12px; - } :host([size='large']) { min-width: 24px; height: 24px; @@ -114,49 +150,42 @@ export const badgeSizeStyles = css.partial` /** * The badge's `filled` appearance styles + * Filled appearance is default so do not + * Include that attribute as it's not present by default * @public */ export const badgeFilledStyles = css.partial` - :host([appearance='filled']) { - border-color: ${colorTransparentStroke}; - } - - :host([appearance='filled'][color='brand']) { - background-color: ${colorBrandBackground}; - color: ${colorNeutralForegroundOnBrand}; - } - - :host([appearance='filled'][color='danger']) { + :host([color='danger']) { background-color: ${colorPaletteRedBackground3}; color: ${colorNeutralForegroundOnBrand}; } - :host([appearance='filled'][color='important']) { + :host([color='important']) { background-color: ${colorNeutralForeground1}; color: ${colorNeutralBackground1}; } - :host([appearance='filled'][color='informative']) { + :host([color='informative']) { background-color: ${colorNeutralBackground5}; color: ${colorNeutralForeground3}; } - :host([appearance='filled'][color='severe']) { + :host([color='severe']) { background-color: ${colorPaletteDarkOrangeBackground3}; color: ${colorNeutralForegroundOnBrand}; } - :host([appearance='filled'][color='subtle']) { + :host([color='subtle']) { background-color: ${colorNeutralBackground1}; color: ${colorNeutralForeground1}; } - :host([appearance='filled'][color='success']) { + :host([color='success']) { background-color: ${colorPaletteGreenBackground3}; color: ${colorNeutralForegroundOnBrand}; } - :host([appearance='filled'][color='warning']) { + :host([color='warning']) { background-color: ${colorPaletteYellowBackground3}; color: ${colorNeutralForeground1}; } @@ -167,8 +196,9 @@ export const badgeFilledStyles = css.partial` * @public */ export const badgeGhostStyles = css.partial` - :host([appearance='ghost'][color='brand']) { + :host([appearance='ghost']) { color: ${colorBrandBackground}; + background-color: initial; } :host([appearance='ghost'][color='danger']) { @@ -207,10 +237,8 @@ export const badgeGhostStyles = css.partial` export const badgeOutlineStyles = css.partial` :host([appearance='outline']) { border-color: currentColor; - } - - :host([appearance='outline'][color='brand']) { color: ${colorBrandForeground1}; + background-color: initial; } :host([appearance='outline'][color='danger']) { @@ -249,7 +277,7 @@ export const badgeOutlineStyles = css.partial` * @public */ export const badgeTintStyles = css.partial` - :host([appearance='tint'][color='brand']) { + :host([appearance='tint']) { background-color: ${colorBrandBackground2}; color: ${colorBrandForeground2}; border-color: ${colorBrandStroke2}; From 280254fd42722bcf8d1fed83477969a7533ba8bd Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 17 Jan 2023 12:55:24 -0800 Subject: [PATCH 8/9] js extension missing from partial imports --- packages/web-components/src/badge/badge.styles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-components/src/badge/badge.styles.ts b/packages/web-components/src/badge/badge.styles.ts index 7b73ab0f6bc08..64da6c5d16470 100644 --- a/packages/web-components/src/badge/badge.styles.ts +++ b/packages/web-components/src/badge/badge.styles.ts @@ -6,7 +6,7 @@ import { badgeOutlineStyles, badgeSizeStyles, badgeTintStyles, -} from '../styles/index'; +} from '../styles/index.js'; import { borderRadiusMedium, borderRadiusNone, borderRadiusSmall } from '../theme/design-tokens.js'; // why is the border not showing up? /** Badge styles From 33ce22b3eb54759b4a32990aa0c502e31493d66b Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 17 Jan 2023 18:01:04 -0800 Subject: [PATCH 9/9] update api report --- packages/web-components/docs/api-report.md | 166 ++++++++++++++++++ .../web-components/src/badge/badge.options.ts | 6 +- 2 files changed, 170 insertions(+), 2 deletions(-) diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index c027d600e8202..2796247c3e572 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -8,8 +8,174 @@ import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; +import { StartEnd } from '@microsoft/fast-foundation'; +import { StartEndOptions } from '@microsoft/fast-foundation'; +import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; import { ValuesOf } from '@microsoft/fast-foundation'; +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "Badge" because one of its declarations is marked as @internal +// +// @public +export class Badge extends FASTElement { + appearance: BadgeAppearance; + color: BadgeColor; + shape: BadgeShape; + size: BadgeSize; +} + +// @internal +export interface Badge extends StartEnd { +} + +// @public +export const BadgeAppearance: { + readonly filled: "filled"; + readonly ghost: "ghost"; + readonly outline: "outline"; + readonly tint: "tint"; +}; + +// @public +export type BadgeAppearance = ValuesOf; + +// @public +export const BadgeColor: { + readonly brand: "brand"; + readonly danger: "danger"; + readonly important: "important"; + readonly informative: "informative"; + readonly severe: "severe"; + readonly subtle: "subtle"; + readonly success: "success"; + readonly warning: "warning"; +}; + +// @public +export type BadgeColor = ValuesOf; + +// @public +export const BadgeDefinition: FASTElementDefinition; + +// Warning: (ae-internal-missing-underscore) The name "BadgeOptions" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal +export type BadgeOptions = StartEndOptions & { + defaultContent?: StaticallyComposableHTML; +}; + +// @public +export const BadgeShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; + readonly square: "square"; +}; + +// @public +export type BadgeShape = ValuesOf; + +// @public +export const BadgeSize: { + readonly tiny: "tiny"; + readonly extraSmall: "extra-small"; + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; + readonly extraLarge: "extra-large"; +}; + +// @public +export type BadgeSize = ValuesOf; + +// @public +export const BadgeStyles: ElementStyles; + +// @public (undocumented) +export const BadgeTemplate: ElementViewTemplate; + +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "CounterBadge" because one of its declarations is marked as @internal +// +// @public +export class CounterBadge extends FASTElement { + appearance: CounterBadgeAppearance; + color: CounterBadgeColor; + count: number; + // (undocumented) + protected countChanged(): void; + dot: boolean; + overflowCount: number; + // (undocumented) + protected overflowCountChanged(): void; + // @internal + setCount(): string | void; + shape: CounterBadgeShape; + showZero: boolean; + size: CounterBadgeSize; +} + +// @internal +export interface CounterBadge extends StartEnd { +} + +// @public +export const CounterBadgeAppearance: { + readonly filled: "filled"; + readonly ghost: "ghost"; +}; + +// @public +export type CounterBadgeAppearance = ValuesOf; + +// @public +export const CounterBadgeColor: { + readonly brand: "brand"; + readonly danger: "danger"; + readonly important: "important"; + readonly informative: "informative"; + readonly severe: "severe"; + readonly subtle: "subtle"; + readonly success: "success"; + readonly warning: "warning"; +}; + +// @public +export type CounterBadgeColor = ValuesOf; + +// @public +export const CounterBadgeDefinition: FASTElementDefinition; + +// Warning: (ae-incompatible-release-tags) The symbol "CounterBadgeOptions" is marked as @public, but its signature references "BadgeOptions" which is marked as @internal +// +// @public +export type CounterBadgeOptions = BadgeOptions; + +// @public +export const CounterBadgeShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; +}; + +// @public +export type CounterBadgeShape = ValuesOf; + +// @public +export const CounterBadgeSize: { + readonly tiny: "tiny"; + readonly extraSmall: "extra-small"; + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; + readonly extraLarge: "extra-large"; +}; + +// @public +export type CounterBadgeSize = ValuesOf; + +// @public +export const CounterBadgeStyles: ElementStyles; + +// @public +export const CounterBadgeTemplate: ElementViewTemplate; + // @public class Text_2 extends FASTElement { align: TextAlign; diff --git a/packages/web-components/src/badge/badge.options.ts b/packages/web-components/src/badge/badge.options.ts index 1b53695e51e38..9fd2a6613ca89 100644 --- a/packages/web-components/src/badge/badge.options.ts +++ b/packages/web-components/src/badge/badge.options.ts @@ -1,10 +1,12 @@ -import { StartEndOptions, ValuesOf } from '@microsoft/fast-foundation'; +import { StartEndOptions, StaticallyComposableHTML, ValuesOf } from '@microsoft/fast-foundation'; import type { Badge } from './badge.js'; /** * @internal - marking as internal update when Badge PR for start/end is in */ -export type BadgeOptions = StartEndOptions; +export type BadgeOptions = StartEndOptions & { + defaultContent?: StaticallyComposableHTML; +}; /** * BadgeAppearance constants