Skip to content

Commit

Permalink
Improved support for design system neutral color (#16899)
Browse files Browse the repository at this point in the history
* Improved support for design system neutral color
- Added a neutralBaseColor property in the design system
- Update neutralPalette and accentPalette when respective baseColor changes
- Updated Card to base background color on local neutralPalette
- Updated Card stories to illustrate use cases

* Change files

* Update api report

* Added null checking on parsed color

Co-authored-by: Brian Heston <brheston@microsoft.com>
  • Loading branch information
bheston and Brian Heston authored Feb 11, 2021
1 parent 4e3e437 commit c71f383
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Improved support for design system neutral color - Added a neutralBaseColor property in the design system - Update neutralPalette and accentPalette when respective baseColor changes - Updated Card to base background color on local neutralPalette - Updated Card stories to illustrate use cases",
"packageName": "@fluentui/web-components",
"email": "brheston@microsoft.com",
"dependentChangeType": "patch"
}
12 changes: 8 additions & 4 deletions packages/web-components/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export interface DesignSystem {
disabledOpacity: number;
elevatedCornerRadius?: number;
focusOutlineWidth: number;
neutralBaseColor: string;
// (undocumented)
neutralContrastFillActiveDelta: number;
// (undocumented)
Expand Down Expand Up @@ -444,15 +445,12 @@ export class FluentButton extends Button {
}

// @public
export class FluentCard extends DesignSystemProvider implements Pick<DesignSystem, 'backgroundColor' | 'neutralPalette'> {
backgroundColor: string;
export class FluentCard extends FluentDesignSystemProvider {
cardBackgroundColor: string;
// (undocumented)
connectedCallback(): void;
// @internal (undocumented)
handleChange(source: DesignSystem, name: string): void;
// @internal
neutralPalette: string[];
}

// @public
Expand All @@ -467,6 +465,8 @@ export class FluentDesignSystemProvider extends DesignSystemProvider implements
// (undocumented)
accentBaseColor: string;
// (undocumented)
protected accentBaseColorChanged(oldValue: string, newValue: string): void;
// (undocumented)
accentFillActiveDelta: number;
// (undocumented)
accentFillFocusDelta: number;
Expand Down Expand Up @@ -511,6 +511,10 @@ export class FluentDesignSystemProvider extends DesignSystemProvider implements
elevatedCornerRadius: number;
// (undocumented)
focusOutlineWidth: number;
// (undocumented)
neutralBaseColor: string;
// (undocumented)
protected neutralBaseColorChanged(oldValue: string, newValue: string): void;
neutralContrastFillActiveDelta: number;
neutralContrastFillFocusDelta: number;
neutralContrastFillHoverDelta: number;
Expand Down
9 changes: 0 additions & 9 deletions packages/web-components/src/card/card.stories.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { ColorRGBA64 } from '@microsoft/fast-colors';
import { createColorPalette } from '../color/create-color-palette';
import { FluentDesignSystemProvider } from '../design-system-provider';
import CardTemplate from './fixtures/card.html';
import { FluentCard } from './';
Expand All @@ -13,10 +11,3 @@ export default {
};

export const Card = (): string => CardTemplate;

document.addEventListener('readystatechange', e => {
if (document.readyState === 'complete') {
const red = document.getElementById('red') as FluentDesignSystemProvider;
red.neutralPalette = createColorPalette(new ColorRGBA64(1, 0, 0));
}
});
74 changes: 54 additions & 20 deletions packages/web-components/src/card/fixtures/card.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<fluent-design-system-provider use-defaults background-color="#F7F7F7">
<fluent-design-system-provider use-defaults background-color="#F7F7F7" corner-radius="10">
<style>
fluent-card {
--card-height: 400px;
--card-width: 500px;
padding: 20px;
margin: 12px;
}

.class-override {
height: 163px;
width: 300px;
Expand All @@ -15,24 +22,42 @@
--elevation: 12;
}

.controls {
.contents {
display: flex;
margin: 20px;
flex-direction: column;
}
</style>
<div>
<fluent-card style="--card-height: 400px; --card-width: 500px;">
<button>Button</button>Card with text
</fluent-card>
<br />
<fluent-card class="state-override">Custom depth on hover using CSS</fluent-card>
<br />
<fluent-card class="state-override">Custom size and elevation on hover using CSS</fluent-card>

<fluent-design-system-provider background-color="#333333">
<fluent-card>
<div class="contents">
Dark
<fluent-button appearance="accent">Accent</fluent-button>
<fluent-button appearance="stealth">Stealth</fluent-button>
<fluent-button appearance="outline">Outline</fluent-button>
<fluent-button appearance="lightweight">Lightweight</fluent-button>
</div>
</fluent-card>
</fluent-design-system-provider>

<fluent-design-system-provider background-color="#E5E5E5">
<fluent-card neutral-base-color="#3995C9">
<div class="contents">
Tinted neutral, light
<fluent-button appearance="accent">Accent</fluent-button>
<fluent-button appearance="stealth">Stealth</fluent-button>
<fluent-button appearance="outline">Outline</fluent-button>
<fluent-button appearance="lightweight">Lightweight</fluent-button>
</div>
</fluent-card>
</fluent-design-system-provider>

<fluent-design-system-provider use-defaults background-color="#333333">
<fluent-card style="--card-height: 400px; --card-width: 500px; color: white">
Dark
<div class="controls">
<fluent-design-system-provider background-color="#333333">
<fluent-card neutral-base-color="#3995C9">
<div class="contents">
Tinted neutral, dark
<fluent-button appearance="accent">Accent</fluent-button>
<fluent-button appearance="stealth">Stealth</fluent-button>
<fluent-button appearance="outline">Outline</fluent-button>
Expand All @@ -41,21 +66,30 @@
</fluent-card>
</fluent-design-system-provider>

<fluent-design-system-provider use-defaults background-color="#FF0000" id="red">
<fluent-card style="--card-height: 400px; --card-width: 500px;">
Red
<div class="controls">
<fluent-design-system-provider background-color="#333333">
<fluent-card neutral-base-color="#3995C9">
<div class="contents">
Tinted neutral, dark
<fluent-button appearance="accent">Accent</fluent-button>
<fluent-button appearance="stealth">Stealth</fluent-button>
<fluent-button appearance="outline">Outline</fluent-button>
<fluent-button appearance="lightweight">Lightweight</fluent-button>
</div>
<fluent-card neutral-base-color="#00A900" style="margin: 0; --card-height: 200px; --card-width: 460px;">
<div class="contents">
Tinted neutral, nested, dark
<fluent-button appearance="accent">Accent</fluent-button>
<fluent-button appearance="stealth">Stealth</fluent-button>
<fluent-button appearance="outline">Outline</fluent-button>
<fluent-button appearance="lightweight">Lightweight</fluent-button>
</div>
</fluent-card>
</fluent-card>
</fluent-design-system-provider>

<fluent-card card-background-color="#333333" style="--card-height: 400px; --card-width: 500px; color: white">
Custom card background
<div class="controls">
<fluent-card card-background-color="#2A5193">
<div class="contents">
Custom card background color
<fluent-button appearance="accent">Accent</fluent-button>
<fluent-button appearance="stealth">Stealth</fluent-button>
<fluent-button appearance="outline">Outline</fluent-button>
Expand Down
48 changes: 12 additions & 36 deletions packages/web-components/src/card/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { attr, Notifier, Observable } from '@microsoft/fast-element';
import { parseColorHexRGB } from '@microsoft/fast-colors';
import {
designSystemProperty,
DesignSystemProvider,
designSystemProvider,
CardTemplate as template,
} from '@microsoft/fast-foundation';
import { createColorPalette, neutralFillCard } from '../color';
import { designSystemProvider, CardTemplate as template } from '@microsoft/fast-foundation';
import { neutralFillCard } from '../color';
import { DesignSystem } from '../fluent-design-system';
import { FluentDesignSystemProvider } from '../design-system-provider';
import { CardStyles as styles } from './card.styles';

/**
Expand All @@ -27,25 +23,12 @@ import { CardStyles as styles } from './card.styles';
mode: 'closed',
},
})
export class FluentCard extends DesignSystemProvider
implements Pick<DesignSystem, 'backgroundColor' | 'neutralPalette'> {
export class FluentCard extends FluentDesignSystemProvider {
/**
* Background color for the banner component. Sets context for the design system.
* Background color for the card component. Sets context for the design system.
* @public
* @remarks
* HTML Attribute: background-color
*/
@designSystemProperty({
attribute: 'background-color',
default: '#FFFFFF',
})
public backgroundColor: string;

/**
* Background color for the banner component. Sets context for the design system.
* @public
* @remarks
* HTML Attribute: background-color
* HTML Attribute: card-background-color
*/
@attr({
attribute: 'card-background-color',
Expand All @@ -56,31 +39,24 @@ export class FluentCard extends DesignSystemProvider
const parsedColor = parseColorHexRGB(this.cardBackgroundColor);

if (parsedColor !== null) {
this.neutralPalette = createColorPalette(parsedColor);
this.neutralBaseColor = this.cardBackgroundColor;
this.backgroundColor = this.cardBackgroundColor;
}
} else if (this.provider && this.provider.designSystem) {
this.handleChange(this.provider.designSystem as DesignSystem, 'backgroundColor');
}
}

/**
* Neutral pallette for the the design system provider.
* @internal
*/
@designSystemProperty({
attribute: false,
default: createColorPalette(parseColorHexRGB('#FFFFFF')!),
cssCustomProperty: false,
})
public neutralPalette: string[];

/**
* @internal
*/
public handleChange(source: DesignSystem, name: string): void {
if (!this.cardBackgroundColor) {
this.backgroundColor = neutralFillCard(source);
if (this.neutralBaseColor) {
this.backgroundColor = neutralFillCard(this.designSystem as DesignSystem);
} else {
this.backgroundColor = neutralFillCard(source);
}
}
}

Expand Down
22 changes: 21 additions & 1 deletion packages/web-components/src/design-system-provider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
designSystemProvider,
DesignSystemProviderTemplate as template,
} from '@microsoft/fast-foundation';
import { neutralForegroundRest } from '../color';
import { parseColorHexRGB } from '@microsoft/fast-colors';
import { createColorPalette, neutralForegroundRest } from '../color';
import { DensityOffset, DesignSystem, DesignSystemDefaults } from '../fluent-design-system';
import { DesignSystemProviderStyles as styles } from './design-system-provider.styles';

Expand Down Expand Up @@ -76,12 +77,31 @@ export class FluentDesignSystemProvider extends DesignSystemProvider
this.noPaintChanged();
}

@designSystemProperty({
attribute: 'neutral-base-color',
cssCustomProperty: false,
default: DesignSystemDefaults.neutralBaseColor,
})
public neutralBaseColor: string;
protected neutralBaseColorChanged(oldValue: string, newValue: string): void {
const color = parseColorHexRGB(newValue);
if (color) {
this.neutralPalette = createColorPalette(color);
}
}

@designSystemProperty({
attribute: 'accent-base-color',
cssCustomProperty: false,
default: DesignSystemDefaults.accentBaseColor,
})
public accentBaseColor: string;
protected accentBaseColorChanged(oldValue: string, newValue: string): void {
const color = parseColorHexRGB(newValue);
if (color) {
this.accentPalette = createColorPalette(color);
}
}

@designSystemProperty({
attribute: false,
Expand Down
13 changes: 13 additions & 0 deletions packages/web-components/src/fluent-design-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ export interface DesignSystem {
*/
backgroundColor: string;

/**
* The neutral color, which the neutral palette is based on.
* Keep this value in sync with neutralPalette.
*/
neutralBaseColor: string;

/**
* The accent color, which the accent palette is based on.
* Keep this value in sync with accentPalette.
Expand All @@ -46,6 +52,7 @@ export interface DesignSystem {

/**
* An array of colors in a ramp from light to dark, used to look up values for neutral color recipes.
* Keep this value in sync with neutralBaseColor.
* Generate by calling createColorPalette.
*/
neutralPalette: string[];
Expand Down Expand Up @@ -236,6 +243,7 @@ export const DesignSystemDefaults: DesignSystem = {
direction: Direction.ltr,
disabledOpacity: 0.3,
focusOutlineWidth: 2,
neutralBaseColor: '#808080',
neutralPalette: defaultNeutralPalette,
outlineWidth: 1,

Expand Down Expand Up @@ -319,6 +327,11 @@ export function getDesignSystemValue<T extends DesignSystem, K extends keyof T>(
*/
export const backgroundColor: DesignSystemResolver<string> = getDesignSystemValue('backgroundColor');

/**
* Retrieve the neutralBaseColor when invoked with a DesignSystem
*/
export const neutralBaseColor: DesignSystemResolver<string> = getDesignSystemValue('neutralBaseColor');

/**
* Retrieve the accentBaseColor when invoked with a DesignSystem
*/
Expand Down

0 comments on commit c71f383

Please sign in to comment.