Skip to content

Commit

Permalink
Adding web component Tabs, Tab and TabPanel (#27167)
Browse files Browse the repository at this point in the history
* adding tab list spec

* adding files for tab list, tab, and tab-panel

* adding files for tab list, tab, and tab-panel

* adding tab

* working tab list web components. no styling. no re-referencing of attributes

* adding styling for tabList

* commenting out unused styling

* adding tab-list styles

* basic api working. styling not correct in all cases.

* Adding svgs. they are not rendering for some reason

* svgs working

* updating styling

* removing fill on svg

* adding logic to track tab selection and css variables. broken

* commit before refactor

* addint html data attr

* updating how tab data is handled

* Animations not working

* animations not working

* broken animation

* location of tab is not correct

* refactoring dataActiveTabChanged

* removing class field for current active tab

* adding method to add and remove classes

* tab animates to offset location

* animating almost correctly

* horizontal animations working

* adding vertical positioning logic

* tabs animations working vertical and horizontal

* Adding tab-list options. adding comments

* adjusting styling

* removing unused vars

* removing comments

* Adding change file

* updating readme. fixing naming conflict in exports of tab-panel index

* fixing default value for tablist size

* removing check for activeid in setTabData

* removing patch for removing activeIndicator

* moving pointer events none to disabled fluent tab

* removing boolean converters, adding type consts, renaming TabList to Tabs.

* documenting difference between tabs and tab list

* updating tabs index.js

* fixing circular dependency import

* removing references to TabList, renaming to Tabs. Removing Tabs orientation type const  and importing it from FAST

* Refactoring tab into tabs

* updating token names object

* updating css for tab token names

* updating tab token names in tabs.ts

* removing unused vars

* adding pseudo element to account for spacing difference of bold and unbolded text on active states

* adding placeholder element to render active indicator

* updating :focus-visible style

* removing unused vars

* adding tab-content span and 2px margin for tab-content span

* updating color foreground for unselected and selected tabs

* removing unused var

* removing host-context

* removing tab content part

* putting back tab content part

* removing unecessary dom element

* removing unecessary z index

* adding tab-content class. removing tab-content part

* adding display helper function to tab-panel

* shorthanding tab padding in tab styles

* removing duplicate selector

* fixing display helper implementation

* removing divs in storybook.ts

* removing divs from stories.ts

* adding second display helper

* adding display helper in tab.styles

* removing stray div in stories.ts

* adding display helper in tabs.styles

* removing active indicator css

* removing important

* removing unused vars

* renaming getSelectedTab to getTab, since tab is passed into method

* updating TabData

* updating check for previous tab for first render

* replacing document add style with fast controller add style

* grabbing scale and offset token names from const

* updating stories, removing redundant code and renaming tabids

* using const objects to provide default values

* Removing animation clear method. apparently not needed

* updating comments

* removing duplicate display

* setting display to inline-flex

* removing unnecessary disabled font-weight in tab

* removing unnecessary outline

* replacing margin-right with margin-inline-end

* Reducing number of duplicarte border radius

Removing horizontal selector in css since it's default

Removing the TabTokenNames and hard coding tokens into css

Combining selectors in css and refactoring css overall

Setting fill for subtle appearance selectors

* adding margin-inline-end

* Adding max width on tab content

* Revert "Adding max width on tab content"

This reverts commit b8dffde.

* fixing focus visible border

* combining padding

* Removing margin auto on right margin

---------

Co-authored-by: Chris Holt <chhol@microsoft.com>
  • Loading branch information
bearcat-msft and chrisdholt authored Apr 5, 2023
1 parent 2a1f8f6 commit 55024b9
Show file tree
Hide file tree
Showing 23 changed files with 1,126 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Adding TabList, Tab, and TabPanel web components",
"packageName": "@fluentui/web-components",
"email": "mibaraka@microsoft.com",
"dependentChangeType": "patch"
}
3 changes: 3 additions & 0 deletions packages/web-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export * from './progress-bar/index.js';
export * from './slider/index.js';
export * from './spinner/index.js';
export * from './switch/index.js';
export * from './tabs/index.js';
export * from './tab/index.js';
export * from './tab-panel/index.js';
export * from './text/index.js';

export * from './theme/index.js';
4 changes: 4 additions & 0 deletions packages/web-components/src/tab-panel/define.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { FluentDesignSystem } from '../fluent-design-system.js';
import { definition } from './tab-panel.definition.js';

definition.define(FluentDesignSystem.registry);
4 changes: 4 additions & 0 deletions packages/web-components/src/tab-panel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './tab-panel.js';
export { template as TabPanelTemplate } from './tab-panel.template.js';
export { styles as TabPanelStyles } from './tab-panel.styles.js';
export { definition as TabPanelDefinition } from './tab-panel.definition.js';
10 changes: 10 additions & 0 deletions packages/web-components/src/tab-panel/tab-panel.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FluentDesignSystem } from '../fluent-design-system.js';
import { TabPanel } from './tab-panel.js';
import { template } from './tab-panel.template.js';
import { styles } from './tab-panel.styles.js';

export const definition = TabPanel.compose({
name: `${FluentDesignSystem.prefix}-tab-panel`,
template,
styles,
});
12 changes: 12 additions & 0 deletions packages/web-components/src/tab-panel/tab-panel.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { css } from '@microsoft/fast-element';
import { display } from '@microsoft/fast-foundation';
import { spacingHorizontalM, spacingHorizontalMNudge } from '../theme/design-tokens.js';

export const styles = css`
${display('block')}
:host {
box-sizing: border-box;
padding: ${spacingHorizontalM} ${spacingHorizontalMNudge};
}
`;
3 changes: 3 additions & 0 deletions packages/web-components/src/tab-panel/tab-panel.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { tabPanelTemplate } from '@microsoft/fast-foundation';

export const template = tabPanelTemplate();
3 changes: 3 additions & 0 deletions packages/web-components/src/tab-panel/tab-panel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { FASTTabPanel } from '@microsoft/fast-foundation';

export class TabPanel extends FASTTabPanel {}
4 changes: 4 additions & 0 deletions packages/web-components/src/tab/define.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { FluentDesignSystem } from '../fluent-design-system.js';
import { definition } from './tab.definition.js';

definition.define(FluentDesignSystem.registry);
4 changes: 4 additions & 0 deletions packages/web-components/src/tab/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './tab.js';
export { template as TabTemplate } from './tab.template.js';
export { styles as TabStyles } from './tab.styles.js';
export { definition as TabDefinition } from './tab.definition.js';
10 changes: 10 additions & 0 deletions packages/web-components/src/tab/tab.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FluentDesignSystem } from '../fluent-design-system.js';
import { Tab } from './tab.js';
import { template } from './tab.template.js';
import { styles } from './tab.styles.js';

export const definition = Tab.compose({
name: `${FluentDesignSystem.prefix}-tab`,
template,
styles,
});
111 changes: 111 additions & 0 deletions packages/web-components/src/tab/tab.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { css } from '@microsoft/fast-element';
import { display } from '@microsoft/fast-foundation';
import {
borderRadiusCircular,
borderRadiusMedium,
borderRadiusSmall,
colorCompoundBrandStroke,
colorNeutralForeground1,
colorNeutralForeground2,
colorNeutralForegroundDisabled,
colorNeutralStroke1Hover,
colorStrokeFocus1,
colorStrokeFocus2,
fontFamilyBase,
fontSizeBase300,
fontWeightSemibold,
lineHeightBase300,
spacingHorizontalM,
spacingHorizontalMNudge,
} from '../theme/design-tokens.js';

export const styles = css`
${display('inline-flex')}
:host {
position: relative;
flex-direction: column;
cursor: pointer;
box-sizing: border-box;
justify-content: center;
line-height: ${lineHeightBase300};
font-family: ${fontFamilyBase};
font-size: ${fontSizeBase300};
color: ${colorNeutralForeground2};
fill: currentcolor;
grid-row: 1;
padding: ${spacingHorizontalM} ${spacingHorizontalMNudge};
border-radius: ${borderRadiusMedium};
}
:host .tab-content {
display: inline-flex;
flex-direction: column;
padding: 0 2px;
}
:host([aria-selected='true']) {
color: ${colorNeutralForeground1};
font-weight: ${fontWeightSemibold};
}
/* adds hidden textContent to prevent shifting ui on bold / unbolding of text */
:host .tab-content::after {
content: var(--textContent);
visibility: hidden;
height: 0;
line-height: ${lineHeightBase300};
font-weight: ${fontWeightSemibold};
}
:host([aria-selected='true'])::after {
background-color: ${colorCompoundBrandStroke};
border-radius: ${borderRadiusCircular};
content: '';
inset: 0;
position: absolute;
z-index: 2;
}
:host([aria-selected='false']:hover)::after {
background-color: ${colorNeutralStroke1Hover};
border-radius: ${borderRadiusCircular};
content: '';
inset: 0;
position: absolute;
z-index: 1;
}
:host([aria-selected='true'][disabled])::after {
background-color: ${colorNeutralForegroundDisabled};
}
::slotted([slot='start']),
::slotted([slot='end']) {
display: flex;
}
::slotted([slot='start']) {
margin-inline-end: 11px;
}
::slotted([slot='end']) {
margin-inline-start: 11px;
}
:host([disabled]) {
cursor: not-allowed;
fill: ${colorNeutralForegroundDisabled};
color: ${colorNeutralForegroundDisabled};
}
:host([disabled]:hover)::after {
background-color: unset;
}
:host(:focus) {
outline: none;
}
:host(:focus-visible) {
border-radius: ${borderRadiusSmall};
box-shadow: 0 0 0 3px ${colorStrokeFocus2};
outline: 1px solid ${colorStrokeFocus1};
}
`;
14 changes: 14 additions & 0 deletions packages/web-components/src/tab/tab.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { endSlotTemplate, FASTTab, startSlotTemplate, TabOptions } from '@microsoft/fast-foundation';
import { ElementViewTemplate, html } from '@microsoft/fast-element';

export function tabTemplate<T extends FASTTab>(options: TabOptions = {}): ElementViewTemplate<T> {
return html<T>`
<template slot="tab" role="tab" aria-disabled="${x => x.disabled}">
${startSlotTemplate(options)}
<span class="tab-content"><slot></slot></span>
${endSlotTemplate(options)}
</template>
`;
}

export const template = tabTemplate({});
25 changes: 25 additions & 0 deletions packages/web-components/src/tab/tab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { css, ElementStyles } from '@microsoft/fast-element';
import { FASTTab } from '@microsoft/fast-foundation';

/**
* Tab extends the FASTTab and is a child of the TabList
*/
export class Tab extends FASTTab {
private styles: ElementStyles | undefined;

connectedCallback() {
super.connectedCallback();

if (this.styles !== undefined) {
this.$fastController.removeStyles(this.styles);
}

this.styles = css/**css*/ `
:host {
--textContent: '${this.textContent as any}';
}
`;

this.$fastController.addStyles(this.styles);
}
}
4 changes: 4 additions & 0 deletions packages/web-components/src/tabs/define.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { FluentDesignSystem } from '../fluent-design-system.js';
import { definition } from './tabs.definition.js';

definition.define(FluentDesignSystem.registry);
5 changes: 5 additions & 0 deletions packages/web-components/src/tabs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './tabs.js';
export * from './tabs.options.js';
export { template as TabsTemplate } from './tabs.template.js';
export { styles as TabsStyles } from './tabs.styles.js';
export { definition as TabsDefinition } from './tabs.definition.js';
10 changes: 10 additions & 0 deletions packages/web-components/src/tabs/tabs.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FluentDesignSystem } from '../fluent-design-system.js';
import { Tabs } from './tabs.js';
import { template } from './tabs.template.js';
import { styles } from './tabs.styles.js';

export const definition = Tabs.compose({
name: `${FluentDesignSystem.prefix}-tabs`,
template,
styles,
});
19 changes: 19 additions & 0 deletions packages/web-components/src/tabs/tabs.options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ValuesOf } from '@microsoft/fast-foundation';
import { TabsOrientation } from '@microsoft/fast-foundation';

export const TabsAppearance = {
subtle: 'subtle',
transparent: 'transparent',
} as const;

export type TabsAppearance = ValuesOf<typeof TabsAppearance>;

export const TabsSize = {
small: 'small',
medium: 'medium',
large: 'large',
} as const;

export type TabsSize = ValuesOf<typeof TabsSize>;

export { TabsOrientation };
Loading

0 comments on commit 55024b9

Please sign in to comment.