Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "Add Drawer component styles and integrate into CAP theme",
"packageName": "@fluentui-contrib/react-cap-theme",
"email": "olkatruk@microsoft.com",
"dependentChangeType": "none"
}
21 changes: 21 additions & 0 deletions packages/react-cap-theme/src/components/Drawer/Drawer.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
makeStyles,
mergeClasses,
type DrawerState,
} from '@fluentui/react-components';
import { CAP_TOKENS } from '../../theme/CAPTheme';

export const useDrawerStyles = makeStyles({
root: {
borderRadius: CAP_TOKENS['cap/ctrl/flyout/base-corner'],
boxShadow: CAP_TOKENS['cap/ctrl/flyout/Elevation'],
},
});

export function useDrawerStylesHook(state: DrawerState): DrawerState {
const styles = useDrawerStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
makeStyles,
mergeClasses,
tokens,
type DrawerBodyState,
} from '@fluentui/react-components';
import { CAP_TOKENS } from '../../theme/CAPTheme';

export const useDrawerBodyStyles = makeStyles({
root: {
paddingLeft: CAP_TOKENS['cap/ctrl/flyout/body-Padding-Left'],
paddingRight: CAP_TOKENS['cap/ctrl/flyout/body-Padding-Right'],
},
});

export function useDrawerBodyStylesHook(
state: DrawerBodyState
): DrawerBodyState {
const styles = useDrawerBodyStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
makeStyles,
mergeClasses,
type DrawerFooterState,
} from '@fluentui/react-components';
import { CAP_TOKENS } from '../../theme/CAPTheme';

export const useDrawerFooterStyles = makeStyles({
root: {
justifyContent: CAP_TOKENS['fixme/ctrl/drawer/footer/content-alignment'],
paddingTop: CAP_TOKENS['cap/ctrl/flyout/Footer-Padding-top'],
paddingRight: CAP_TOKENS['cap/ctrl/flyout/Footer-Padding-bottom'],
paddingBottom: CAP_TOKENS['cap/ctrl/flyout/footer-Padding-Left'],
paddingLeft: CAP_TOKENS['cap/ctrl/flyout/footer-Padding-Right'],
},
});

export function useDrawerFooterStylesHook(
state: DrawerFooterState
): DrawerFooterState {
const styles = useDrawerFooterStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
makeStyles,
mergeClasses,
tokens,
type DrawerHeaderState,
} from '@fluentui/react-components';
import { CAP_TOKENS } from '../../theme/CAPTheme';

export const useDrawerHeaderStyles = makeStyles({
root: {
paddingTop: CAP_TOKENS['smtc/v1/ctrl/flyout/header/paddingTop'],
paddingRight: CAP_TOKENS['smtc/v1/ctrl/flyout/header/Padding-Right'],
paddingBottom: CAP_TOKENS['fixme/ctrl/drawer/header/padding-bottom'],
paddingLeft: CAP_TOKENS['smtc/v1/ctrl/flyout/header/Padding-Left'],
},
});

export function useDrawerHeaderStylesHook(
state: DrawerHeaderState
): DrawerHeaderState {
const styles = useDrawerHeaderStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
makeStyles,
mergeClasses,
type DrawerHeaderNavigationState,
} from '@fluentui/react-components';

export const useDrawerHeaderNavigationStyles = makeStyles({
root: {},
});

export function useDrawerHeaderNavigationStylesHook(
state: DrawerHeaderNavigationState
): DrawerHeaderNavigationState {
const styles = useDrawerHeaderNavigationStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
makeStyles,
mergeClasses,
type DrawerHeaderTitleState,
} from '@fluentui/react-components';

export const useDrawerHeaderTitleStyles = makeStyles({
root: {},
heading: {},
action: {},
});

export function useDrawerHeaderTitleStylesHook(
state: DrawerHeaderTitleState
): DrawerHeaderTitleState {
const styles = useDrawerHeaderTitleStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

if (state.heading) {
state.heading.className = mergeClasses(
state.heading.className,
styles.heading
);
}

if (state.action) {
state.action.className = mergeClasses(
state.action.className,
styles.action
);
}

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
makeStyles,
mergeClasses,
type InlineDrawerState,
} from '@fluentui/react-components';

export const useInlineDrawerStyles = makeStyles({
root: {},
});

export function useInlineDrawerStylesHook(
state: InlineDrawerState
): InlineDrawerState {
const styles = useInlineDrawerStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
makeStyles,
mergeClasses,
type OverlayDrawerState,
} from '@fluentui/react-components';

export const useOverlayDrawerStyles = makeStyles({
root: {},
});

export function useOverlayDrawerStylesHook(
state: OverlayDrawerState
): OverlayDrawerState {
const styles = useOverlayDrawerStyles();

state.root.className = mergeClasses(state.root.className, styles.root);

return state;
}
37 changes: 36 additions & 1 deletion packages/react-cap-theme/src/theme/CAPTheme.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { tokens } from '@fluentui/react-components';

type TokenType = 'color' | 'dimension';
type TokenType = 'color' | 'dimension' | 'shadow' | 'alignment';

export interface TokenSchema {
type: TokenType;
Expand Down Expand Up @@ -40,6 +40,7 @@ const FluentExtendedTokens = {
'fluent-ext/brandForegroundCompound': { type: 'color' },
// reason we need this token is the fluent version has value of "0" instead of "0px", which causes issues in CSS var usage
'fluent-ext/spacingHorizontalNone': { type: 'dimension' },
'fluent-ext/borderRadius3XLarge': { type: 'dimension' },
} as const satisfies Record<AllowedTokenName, TokenSchema>;

/**
Expand Down Expand Up @@ -132,6 +133,22 @@ const TooltipTokens = {} as const satisfies Record<
TokenSchema
>;

const DrawerTokens = {
'cap/ctrl/flyout/base-corner': { type: 'dimension' },
'cap/ctrl/flyout/Elevation': { type: 'shadow' },
'smtc/v1/ctrl/flyout/header/paddingTop': { type: 'dimension' },
'smtc/v1/ctrl/flyout/header/Padding-Left': { type: 'dimension' },
'fixme/ctrl/drawer/header/padding-bottom': { type: 'dimension' },
'smtc/v1/ctrl/flyout/header/Padding-Right': { type: 'dimension' },
'cap/ctrl/flyout/body-Padding-Left': { type: 'dimension' },
'cap/ctrl/flyout/body-Padding-Right': { type: 'dimension' },
'cap/ctrl/flyout/Footer-Padding-top': { type: 'dimension' },
'cap/ctrl/flyout/Footer-Padding-bottom': { type: 'dimension' },
'cap/ctrl/flyout/footer-Padding-Left': { type: 'dimension' },
'cap/ctrl/flyout/footer-Padding-Right': { type: 'dimension' },
'fixme/ctrl/drawer/footer/content-alignment': { type: 'alignment' },
} as const satisfies Record<AllowedTokenName, TokenSchema>;

export const CAPTokensSchema = {
...FluentExtendedTokens,
...ControlTokens,
Expand All @@ -142,6 +159,7 @@ export const CAPTokensSchema = {
...InputTokens,
...MenuTokens,
...TooltipTokens,
...DrawerTokens,
} as const satisfies { [key: AllowedTokenName]: TokenSchema };

export const CAP_TOKENS = Object.keys(CAPTokensSchema).reduce((acc, key) => {
Expand All @@ -157,6 +175,7 @@ export const CAP_THEME_DEFAULTS = {
'fluent-ext/borderRadius2XLarge': '12px',
'fluent-ext/brandForegroundCompound': '#03787C',
'fluent-ext/spacingHorizontalNone': '0px',
'fluent-ext/borderRadius3XLarge': '16px',

// smtc/v1
'smtc/v1/ctrl/corner/rest': CAP_TOKENS['fluent-ext/borderRadius2XLarge'],
Expand Down Expand Up @@ -235,6 +254,22 @@ export const CAP_THEME_DEFAULTS = {
'fixme/ctrl/card/header-padding-outside': tokens.spacingVerticalM,
'fixme/ctrl/card/header-padding-inside': tokens.spacingVerticalS,
'fixme/ctrl/card/footer-horizontal-gap': tokens.spacingHorizontalS,

// drawer
// Notes: Component Drawer at design specs and in code, tokens are using 'flyout'
'cap/ctrl/flyout/base-corner': CAP_TOKENS['fluent-ext/borderRadius3XLarge'],
'cap/ctrl/flyout/Elevation': tokens.shadow2,
'smtc/v1/ctrl/flyout/header/paddingTop': tokens.spacingVerticalL,
'smtc/v1/ctrl/flyout/header/Padding-Left': tokens.spacingHorizontalXL,
'fixme/ctrl/drawer/header/padding-bottom': '12px', // Not exist in design specs and in tokens
'smtc/v1/ctrl/flyout/header/Padding-Right': tokens.spacingHorizontalXL, // layout is different, required different value from design spec tokens.spacingHorizontalMNudge
'cap/ctrl/flyout/body-Padding-Left': tokens.spacingHorizontalXL,
'cap/ctrl/flyout/body-Padding-Right': tokens.spacingHorizontalXL,
'cap/ctrl/flyout/Footer-Padding-top': tokens.spacingVerticalXXL,
'cap/ctrl/flyout/Footer-Padding-bottom': tokens.spacingVerticalXL,
'cap/ctrl/flyout/footer-Padding-Left': tokens.spacingHorizontalXL,
'cap/ctrl/flyout/footer-Padding-Right': tokens.spacingHorizontalXL,
'fixme/ctrl/drawer/footer/content-alignment': 'flex-end',
} as const satisfies CAPTheme;

export const CAP_THEME_TEAMS = {
Expand Down
36 changes: 36 additions & 0 deletions packages/react-cap-theme/src/theme/CAPThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@ import {
CardFooterState,
CardHeaderState,
CardState,
DrawerBodyState,
DrawerFooterState,
DrawerHeaderNavigationState,
DrawerHeaderState,
DrawerHeaderTitleState,
DrawerState,
FluentProvider,
FluentProviderProps,
InputState,
InlineDrawerState,
OverlayDrawerState,
type Theme,
} from '@fluentui/react-components';

Expand All @@ -18,6 +26,14 @@ import { useInputStylesHook } from '../components/Input/Input.styles';
import { useCardStylesHook } from '../components/Card/Card.styles';
import { useCardHeaderStylesHook } from '../components/Card/CardHeader.styles';
import { useCardFooterStylesHook } from '../components/Card/CardFooter.styles';
import { useDrawerStylesHook } from '../components/Drawer/Drawer.styles';
import { useDrawerBodyStylesHook } from '../components/Drawer/DrawerBody.styles';
import { useDrawerHeaderStylesHook } from '../components/Drawer/DrawerHeader.styles';
import { useDrawerHeaderTitleStylesHook } from '../components/Drawer/DrawerHeaderTitle.styles';
import { useDrawerHeaderNavigationStylesHook } from '../components/Drawer/DrawerHeaderNavigation.styles';
import { useDrawerFooterStylesHook } from '../components/Drawer/DrawerFooter.styles';
import { useInlineDrawerStylesHook } from '../components/Drawer/InlineDrawer.styles';
import { useOverlayDrawerStylesHook } from '../components/Drawer/OverlayDrawer.styles';

const customStyleHooks: NonNullable<
FluentProviderProps['customStyleHooks_unstable']
Expand All @@ -30,6 +46,26 @@ const customStyleHooks: NonNullable<
useCardHeaderStylesHook(state as CardHeaderState),
useCardFooterStyles_unstable: (state) =>
useCardFooterStylesHook(state as CardFooterState),
useDrawerStyles_unstable: (state) =>
useDrawerStylesHook(state as DrawerState),
useOverlayDrawerStyles_unstable: (state) =>
useOverlayDrawerStylesHook(state as OverlayDrawerState),
useDrawerOverlayStyles_unstable: (state) =>
useOverlayDrawerStylesHook(state as OverlayDrawerState),
useInlineDrawerStyles_unstable: (state) =>
useInlineDrawerStylesHook(state as InlineDrawerState),
useDrawerInlineStyles_unstable: (state) =>
useInlineDrawerStylesHook(state as InlineDrawerState),
useDrawerBodyStyles_unstable: (state) =>
useDrawerBodyStylesHook(state as DrawerBodyState),
useDrawerHeaderStyles_unstable: (state) =>
useDrawerHeaderStylesHook(state as DrawerHeaderState),
useDrawerHeaderTitleStyles_unstable: (state) =>
useDrawerHeaderTitleStylesHook(state as DrawerHeaderTitleState),
useDrawerHeaderNavigationStyles_unstable: (state) =>
useDrawerHeaderNavigationStylesHook(state as DrawerHeaderNavigationState),
useDrawerFooterStyles_unstable: (state) =>
useDrawerFooterStylesHook(state as DrawerFooterState),
useInputStyles_unstable: (state) => useInputStylesHook(state as InputState),
};

Expand Down
6 changes: 4 additions & 2 deletions packages/react-cap-theme/stories/StorybookUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '@fluentui-contrib/react-cap-theme';

export interface CAPThemeExample {
title: string;
title?: string;
render(variant: 'v9' | 'cap'): React.ReactElement | 'NOT_IMPLEMENTED';
}

Expand Down Expand Up @@ -94,7 +94,9 @@ export const CAPThemeExamples = ({
<div className={styles.themeLabel}>Showing: {selectedTheme.label}</div>
{examples.map((example) => (
<div className={styles.row} key={example.title}>
<div className={styles.example}>{example.title}</div>
{example.title && (
<div className={styles.example}>{example.title}</div>
)}
<div className={styles.rendered}>
{renderExample(example, selectedTheme.variant)}
</div>
Expand Down
Loading