From c1b698715e26465469dfa7b9608bd149ee215537 Mon Sep 17 00:00:00 2001 From: David Zukowski Date: Mon, 9 Mar 2026 21:06:56 -0700 Subject: [PATCH 1/3] react-cap-theme: publish 1074d9c --- packages/react-cap-theme/.storybook/main.ts | 1 - .../react-cap-theme/.storybook/preview.tsx | 54 +-- packages/react-cap-theme/eslint.config.js | 9 + .../src/components/Badge/Badge.styles.ts | 166 ------- .../src/components/Button/Button.styles.ts | 55 --- .../src/components/Button/Button.tsx | 9 - .../src/components/Button/Button.types.ts | 16 - .../src/components/Card/Card.styles.ts | 20 - .../src/components/Card/CardFooter.styles.ts | 19 - .../src/components/Card/CardHeader.styles.ts | 19 - .../components/Dialog/DialogBody.styles.ts | 28 -- .../components/Dialog/DialogSurface.styles.ts | 29 -- .../src/components/Drawer/Drawer.styles.ts | 21 - .../components/Drawer/DrawerBody.styles.ts | 24 - .../components/Drawer/DrawerFooter.styles.ts | 26 -- .../components/Drawer/DrawerHeader.styles.ts | 26 -- .../Drawer/DrawerHeaderNavigation.styles.ts | 19 - .../Drawer/DrawerHeaderTitle.styles.ts | 35 -- .../components/Drawer/InlineDrawer.styles.ts | 19 - .../components/Drawer/OverlayDrawer.styles.ts | 19 - .../src/components/Input/Input.styles.ts | 17 - .../src/components/react-button/Button.ts | 13 + .../src/components/react-button/MenuButton.ts | 12 + .../components/react-button/SplitButton.ts | 12 + .../components/react-button/ToggleButton.ts | 11 + .../react-button/components/Button/Button.tsx | 20 + .../components/Button/Button.types.ts | 28 ++ .../components/Button/Button.utils.ts | 32 ++ .../components/Button/renderButton.tsx | 12 + .../components/Button/useButton.ts | 15 + .../Button/useButtonStyles.styles.ts | 281 ++++++++++++ .../components/MenuButton/MenuButton.tsx | 19 + .../components/MenuButton/MenuButton.types.ts | 11 + .../MenuButton/renderMenuButton.tsx | 11 + .../components/MenuButton/useMenuButton.ts | 19 + .../MenuButton/useMenuButtonStyles.styles.ts | 61 +++ .../components/SplitButton/SplitButton.tsx | 16 + .../SplitButton/SplitButton.types.ts | 25 + .../SplitButton/renderSplitButton.tsx | 15 + .../components/SplitButton/useSplitButton.ts | 85 ++++ .../useSplitButtonStyles.styles.ts | 266 +++++++++++ .../components/ToggleButton/ToggleButton.tsx | 26 ++ .../ToggleButton/ToggleButton.types.ts | 8 + .../ToggleButton/renderToggleButton.tsx | 6 + .../ToggleButton/useToggleButton.ts | 15 + .../useToggleButtonStyles.styles.ts | 139 ++++++ .../src/components/react-button/index.ts | 45 ++ .../tokens/alias/colors/darkColor.ts | 49 ++ .../tokens/alias/colors/lightColor.ts | 52 +++ .../tokens/alias/fonts/fontFamily.ts | 23 + .../tokens/alias/fonts/fontWeight.ts | 22 + .../components/tokens/alias/fonts/index.ts | 2 + .../components/tokens/global/brandColors.ts | 22 + .../src/components/tokens/global/fonts.ts | 18 + .../components/tokens/global/neutralColors.ts | 59 +++ .../tokens/global/typographyStyles.ts | 148 ++++++ .../src/components/tokens/index.ts | 79 ++++ .../components/tokens/themeToTokensObject.ts | 1 + .../src/components/tokens/themes/darkTheme.ts | 5 + .../components/tokens/themes/lightTheme.ts | 5 + .../src/components/tokens/tokens.ts | 55 +++ .../src/components/tokens/types.ts | 230 ++++++++++ .../src/components/tokens/utils/applyFonts.ts | 30 ++ .../tokens/utils/createDarkTheme.ts | 38 ++ .../tokens/utils/createLightTheme.ts | 38 ++ .../tokens/utils/extractNeutralTokens.ts | 12 + packages/react-cap-theme/src/index.ts | 47 +- .../react-cap-theme/src/theme/CAPTheme.tsx | 302 ------------ .../src/theme/CAPThemeProvider.tsx | 104 ----- packages/react-cap-theme/stories/.gitkeep | 0 .../stories/StorybookUtils.tsx | 250 ---------- .../components/Badge/WithControls.stories.tsx | 167 ------- .../components/Badge/WithTable.stories.tsx | 431 ------------------ .../stories/components/Button.stories.tsx | 195 -------- .../stories/components/Card.stories.tsx | 47 -- .../Dialog/WithControls.stories.tsx | 58 --- .../stories/components/Dialog/WithTable.tsx | 74 --- .../stories/components/Drawer.stories.tsx | 110 ----- .../stories/components/Input.stories.tsx | 18 - .../stories/components/Menu.stories.tsx | 6 - .../stories/components/Tooltip.stories.tsx | 6 - .../react-cap-theme/stories/index.stories.tsx | 21 - packages/react-cap-theme/tsconfig.json | 12 +- 83 files changed, 2149 insertions(+), 2421 deletions(-) delete mode 100644 packages/react-cap-theme/src/components/Badge/Badge.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Button/Button.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Button/Button.tsx delete mode 100644 packages/react-cap-theme/src/components/Button/Button.types.ts delete mode 100644 packages/react-cap-theme/src/components/Card/Card.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Card/CardFooter.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Card/CardHeader.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Dialog/DialogBody.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Dialog/DialogSurface.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/Drawer.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/DrawerBody.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/DrawerFooter.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/DrawerHeader.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/DrawerHeaderNavigation.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/DrawerHeaderTitle.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/InlineDrawer.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Drawer/OverlayDrawer.styles.ts delete mode 100644 packages/react-cap-theme/src/components/Input/Input.styles.ts create mode 100644 packages/react-cap-theme/src/components/react-button/Button.ts create mode 100644 packages/react-cap-theme/src/components/react-button/MenuButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/SplitButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/ToggleButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx create mode 100644 packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts create mode 100644 packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts create mode 100644 packages/react-cap-theme/src/components/react-button/index.ts create mode 100644 packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts create mode 100644 packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts create mode 100644 packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts create mode 100644 packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts create mode 100644 packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts create mode 100644 packages/react-cap-theme/src/components/tokens/global/brandColors.ts create mode 100644 packages/react-cap-theme/src/components/tokens/global/fonts.ts create mode 100644 packages/react-cap-theme/src/components/tokens/global/neutralColors.ts create mode 100644 packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts create mode 100644 packages/react-cap-theme/src/components/tokens/index.ts create mode 100644 packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts create mode 100644 packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts create mode 100644 packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts create mode 100644 packages/react-cap-theme/src/components/tokens/tokens.ts create mode 100644 packages/react-cap-theme/src/components/tokens/types.ts create mode 100644 packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts create mode 100644 packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts create mode 100644 packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts create mode 100644 packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts delete mode 100644 packages/react-cap-theme/src/theme/CAPTheme.tsx delete mode 100644 packages/react-cap-theme/src/theme/CAPThemeProvider.tsx create mode 100644 packages/react-cap-theme/stories/.gitkeep delete mode 100644 packages/react-cap-theme/stories/StorybookUtils.tsx delete mode 100644 packages/react-cap-theme/stories/components/Badge/WithControls.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Badge/WithTable.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Button.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Card.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Dialog/WithControls.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Dialog/WithTable.tsx delete mode 100644 packages/react-cap-theme/stories/components/Drawer.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Input.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Menu.stories.tsx delete mode 100644 packages/react-cap-theme/stories/components/Tooltip.stories.tsx delete mode 100644 packages/react-cap-theme/stories/index.stories.tsx diff --git a/packages/react-cap-theme/.storybook/main.ts b/packages/react-cap-theme/.storybook/main.ts index 521468ce..9f7d90b3 100644 --- a/packages/react-cap-theme/.storybook/main.ts +++ b/packages/react-cap-theme/.storybook/main.ts @@ -1,6 +1,5 @@ import type { StorybookConfig } from '@storybook/react-webpack5'; -// eslint-disable-next-line @nx/enforce-module-boundaries import rootConfig from '../../../.storybook/main'; const config: StorybookConfig = { diff --git a/packages/react-cap-theme/.storybook/preview.tsx b/packages/react-cap-theme/.storybook/preview.tsx index 39683877..2b8a55ac 100644 --- a/packages/react-cap-theme/.storybook/preview.tsx +++ b/packages/react-cap-theme/.storybook/preview.tsx @@ -1,61 +1,9 @@ -import * as React from 'react'; -import type { Decorator, Preview } from '@storybook/react'; +import type { Preview } from '@storybook/react'; -// eslint-disable-next-line @nx/enforce-module-boundaries import rootPreview from '../../../.storybook/preview'; -import { CAPThemeSelectionProvider } from '../stories/StorybookUtils'; - -const withCAPTheme: Decorator = (Story, context) => { - const themeKey = - (context.globals.capTheme as - | 'current' - | 'teams' - | 'onedrive' - | 'sharepoint') ?? 'current'; - return ( - - - - ); -}; - -const rootDecorators = rootPreview.decorators; -const normalizedDecorators: Decorator[] = Array.isArray(rootDecorators) - ? rootDecorators - : rootDecorators - ? [rootDecorators] - : []; const preview: Preview = { ...rootPreview, - decorators: [...normalizedDecorators, withCAPTheme], - parameters: { - ...rootPreview.parameters, - controls: { - ...(rootPreview.parameters?.controls ?? {}), - disable: false, - expanded: true, - }, - }, - globalTypes: { - ...(rootPreview.globalTypes ?? {}), - capTheme: { - name: 'Themes', - description: 'Select the theme for all CAP stories', - defaultValue: 'default', - toolbar: { - icon: 'paintbrush', - showName: true, - dynamicTitle: true, - items: [ - { value: 'default', title: 'Default' }, - { value: 'teams', title: 'CAP (Teams)' }, - { value: 'onedrive', title: 'CAP (OneDrive)' }, - { value: 'sharepoint', title: 'CAP (SharePoint)' }, - ], - }, - }, - }, tags: ['autodocs'], }; diff --git a/packages/react-cap-theme/eslint.config.js b/packages/react-cap-theme/eslint.config.js index 2be3ed1b..dfcfe4b6 100644 --- a/packages/react-cap-theme/eslint.config.js +++ b/packages/react-cap-theme/eslint.config.js @@ -12,4 +12,13 @@ module.exports = [ // Override or add rules here rules: {}, }, + { + "files": [ + "**/*.ts", + "**/*.tsx" + ], + "rules": { + "@nx/enforce-module-boundaries": "off" + } +}, ]; diff --git a/packages/react-cap-theme/src/components/Badge/Badge.styles.ts b/packages/react-cap-theme/src/components/Badge/Badge.styles.ts deleted file mode 100644 index 09aeed2a..00000000 --- a/packages/react-cap-theme/src/components/Badge/Badge.styles.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { - makeStyles, - mergeClasses, - shorthands, - tokens, - type BadgeState, - useBadgeStyles_unstable, -} from '@fluentui/react-components'; -import * as React from 'react'; - -import { CAP_TOKENS } from '../../theme/CAPTheme'; - -// Copied from Fluent's badge.styles.ts: we are only overriding a few styles, we don't want to break the styles we don't override -// so we follow the existing pattern here -// The text content of the badge has additional horizontal padding, but there is no `text` slot to add that padding to. -// Instead, add extra padding to the root, and a negative margin on the icon to "remove" the extra padding on the icon. -const textPadding = tokens.spacingHorizontalXXS; - -export const useBadgeStyles = makeStyles({ - root: { - padding: `0 calc(${CAP_TOKENS['cap/badge-m/padding']} + ${textPadding})`, - }, - - tiny: { - padding: 'unset', - }, - - 'extra-small': { - padding: 'unset', - }, - - small: { - padding: `0 calc(${CAP_TOKENS['cap/badge-s/padding']} + ${textPadding})`, - }, - - medium: { - // Set by root - }, - - large: { - padding: `0 calc(${CAP_TOKENS['cap/badge-l/padding']} + ${textPadding})`, - }, - - 'extra-large': { - padding: `0 calc(${CAP_TOKENS['cap/badge-xl/padding']} + ${textPadding})`, - }, - - // shape - 'rounded-extra-large': { - borderRadius: CAP_TOKENS['cap/badge-xl/corner-rounded'], - }, - 'rounded-large': { borderRadius: CAP_TOKENS['cap/badge-l/corner-rounded'] }, - - 'outline-brand': { - ...shorthands.borderColor(CAP_TOKENS['cap/badge/brand/outlined/stroke']), - }, - 'outline-warning': { - ...shorthands.borderColor(CAP_TOKENS['cap/badge/warning/outlined/stroke']), - }, - 'outline-important': { - ...shorthands.borderColor( - CAP_TOKENS['cap/badge/important/outlined/stroke'] - ), - }, - 'outline-danger': { - ...shorthands.borderColor(CAP_TOKENS['cap/badge/danger/outlined/stroke']), - }, - 'outline-success': { - ...shorthands.borderColor(CAP_TOKENS['cap/badge/success/outlined/stroke']), - }, - 'outline-informative': { - ...shorthands.borderColor( - CAP_TOKENS['cap/badge/informative/outlined/stroke'] - ), - }, - 'outline-subtle': { - color: CAP_TOKENS['cap/badge/subtle/outlined/foreground'], - ...shorthands.borderColor( - CAP_TOKENS['cap/badge/subtle/outlined/foreground'] - ), - }, - - 'tint-brand': { - color: CAP_TOKENS['cap/badge/brand/tint/foreground'], - }, - - 'ghost-brand': { - color: CAP_TOKENS['cap/badge/brand/ghost/foreground'], - }, - - 'filled-warning': { - color: CAP_TOKENS['cap/badge/warning/filled/foreground'], - backgroundColor: CAP_TOKENS['cap/badge/warning/filled/background'], - }, - - 'tint-informative': { - backgroundColor: CAP_TOKENS['cap/badge/informative/tint/background'], - ...shorthands.borderColor(CAP_TOKENS['cap/badge/informative/tint/stroke']), - }, - - 'filled-important': { - backgroundColor: CAP_TOKENS['cap/badge/important/filled/background'], - color: CAP_TOKENS['cap/badge/important/filled/foreground'], - }, - - 'tint-important': { - backgroundColor: CAP_TOKENS['cap/badge/important/tint/background'], - color: CAP_TOKENS['cap/badge/important/tint/foreground'], - ...shorthands.borderColor(CAP_TOKENS['cap/badge/important/tint/stroke']), - }, - - 'filled-subtle': { - color: CAP_TOKENS['cap/badge/subtle/filled/foreground'], - backgroundColor: CAP_TOKENS['cap/badge/subtle/filled/background'], - }, - - 'tint-subtle': { - ...shorthands.borderColor(CAP_TOKENS['cap/badge/subtle/tint/stroke']), - }, -}); - -const useBadgeIconStyles = makeStyles({ - beforeTextSmall: { - marginRight: `calc(${CAP_TOKENS['cap/badge-s/gap']} + ${textPadding})`, - }, - afterTextSmall: { - marginLeft: `calc(${CAP_TOKENS['cap/badge-s/gap-toSecondaryIcon']} + ${textPadding})`, - }, -}); - -export function useBadgeStylesHook(state: BadgeState): BadgeState { - // Apply base Badge styles first - useBadgeStyles_unstable(state); - - // Then override with CAP styles - const styles = useBadgeStyles(); - const iconStyles = useBadgeIconStyles(); - - state.root.className = mergeClasses( - state.root.className, - styles.root, - styles[state.size], - state.shape === 'rounded' && - `rounded-${state.size}` in styles && - styles[`rounded-${state.size}` as keyof typeof styles], - `${state.appearance}-${state.color}` in styles && - styles[`${state.appearance}-${state.color}` as keyof typeof styles] - ); - - // Copied from Fluent: Handle the edge case where children is 0 (a falsy value that should still render text and have margin) - if (React.Children.toArray(state.root.children).length > 0) { - // Override icon spacing for small size - if (state.icon && state.size === 'small') { - const iconPositionClass = - state.iconPosition === 'after' - ? iconStyles.afterTextSmall - : iconStyles.beforeTextSmall; - state.icon.className = mergeClasses( - state.icon.className, - iconPositionClass - ); - } - } - - return state; -} diff --git a/packages/react-cap-theme/src/components/Button/Button.styles.ts b/packages/react-cap-theme/src/components/Button/Button.styles.ts deleted file mode 100644 index c6ec8b9b..00000000 --- a/packages/react-cap-theme/src/components/Button/Button.styles.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { makeStyles, mergeClasses } from '@fluentui/react-components'; -import type { ButtonState } from './Button.types'; -import { CAP_TOKENS } from '../../theme/CAPTheme'; - -export const useButtonStyles = makeStyles({ - root: { - borderRadius: CAP_TOKENS['fixme/ctrl/button/corner-radius'], - }, - primary: { - backgroundColor: CAP_TOKENS['fixme/ctrl/button/primary-background-color'], - - ':hover': { - backgroundColor: - CAP_TOKENS['fixme/ctrl/button/primary-background-color-hover'], - }, - }, - secondary: { - backgroundColor: CAP_TOKENS['fixme/ctrl/button/secondary-background-color'], - - ':hover': { - backgroundColor: - CAP_TOKENS['fixme/ctrl/button/secondary-background-color-hover'], - }, - }, - outline: { - backgroundColor: CAP_TOKENS['fixme/ctrl/button/outline-background-color'], - - ':hover': { - backgroundColor: - CAP_TOKENS['fixme/ctrl/button/outline-background-color-hover'], - }, - }, - subtle: {}, - tint: { - backgroundColor: CAP_TOKENS['fixme/ctrl/button/tint-background-color'], - - ':hover': { - backgroundColor: - CAP_TOKENS['fixme/ctrl/button/tint-background-color-hover'], - }, - }, - transparent: {}, -}); - -export function useButtonStylesHook(state: ButtonState): ButtonState { - const styles = useButtonStyles(); - - state.root.className = mergeClasses( - state.root.className, - styles.root, - state.appearance && styles[state.appearance] - ); - - return state; -} diff --git a/packages/react-cap-theme/src/components/Button/Button.tsx b/packages/react-cap-theme/src/components/Button/Button.tsx deleted file mode 100644 index a2c6c5e4..00000000 --- a/packages/react-cap-theme/src/components/Button/Button.tsx +++ /dev/null @@ -1,9 +0,0 @@ -'use client'; - -import type { ForwardRefComponent } from '@fluentui/react-utilities'; -import { Button as FluentButton } from '@fluentui/react-components'; -import type { ButtonProps } from './Button.types'; - -export const Button = FluentButton as ForwardRefComponent; - -Button.displayName = 'Button'; diff --git a/packages/react-cap-theme/src/components/Button/Button.types.ts b/packages/react-cap-theme/src/components/Button/Button.types.ts deleted file mode 100644 index a27f0a24..00000000 --- a/packages/react-cap-theme/src/components/Button/Button.types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { - ButtonProps as FluentButtonProps, - ButtonState as FluentButtonState, -} from '@fluentui/react-components'; - -export type ButtonAppearance = - | NonNullable - | 'tint'; - -export type ButtonProps = Omit & { - appearance?: ButtonAppearance; -}; - -export type ButtonState = Omit & { - appearance?: ButtonAppearance; -}; diff --git a/packages/react-cap-theme/src/components/Card/Card.styles.ts b/packages/react-cap-theme/src/components/Card/Card.styles.ts deleted file mode 100644 index 49b7fb1c..00000000 --- a/packages/react-cap-theme/src/components/Card/Card.styles.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - makeStyles, - mergeClasses, - type CardState, -} from '@fluentui/react-components'; -import { CAP_TOKENS } from '../../theme/CAPTheme'; - -export const useCardStyles = makeStyles({ - root: { - borderRadius: CAP_TOKENS['fixme/ctrl/card/corner-radius'], - }, -}); - -export function useCardStylesHook(state: CardState): CardState { - const styles = useCardStyles(); - - state.root.className = mergeClasses(state.root.className, styles.root); - - return state; -} diff --git a/packages/react-cap-theme/src/components/Card/CardFooter.styles.ts b/packages/react-cap-theme/src/components/Card/CardFooter.styles.ts deleted file mode 100644 index 8d6a5ed6..00000000 --- a/packages/react-cap-theme/src/components/Card/CardFooter.styles.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - makeStyles, - mergeClasses, - type CardFooterState, -} from '@fluentui/react-components'; - -export const useCardFooterStyles = makeStyles({ - root: {}, -}); - -export function useCardFooterStylesHook( - state: CardFooterState -): CardFooterState { - const styles = useCardFooterStyles(); - - state.root.className = mergeClasses(state.root.className, styles.root); - - return state; -} diff --git a/packages/react-cap-theme/src/components/Card/CardHeader.styles.ts b/packages/react-cap-theme/src/components/Card/CardHeader.styles.ts deleted file mode 100644 index 46373c2c..00000000 --- a/packages/react-cap-theme/src/components/Card/CardHeader.styles.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - makeStyles, - mergeClasses, - type CardHeaderState, -} from '@fluentui/react-components'; - -export const useCardHeaderStyles = makeStyles({ - root: {}, -}); - -export function useCardHeaderStylesHook( - state: CardHeaderState -): CardHeaderState { - const styles = useCardHeaderStyles(); - - state.root.className = mergeClasses(state.root.className, styles.root); - - return state; -} diff --git a/packages/react-cap-theme/src/components/Dialog/DialogBody.styles.ts b/packages/react-cap-theme/src/components/Dialog/DialogBody.styles.ts deleted file mode 100644 index 4b7fba5b..00000000 --- a/packages/react-cap-theme/src/components/Dialog/DialogBody.styles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - makeStyles, - mergeClasses, - type DialogBodyState, - useDialogBodyStyles_unstable, -} from '@fluentui/react-components'; - -import { CAP_TOKENS } from '../../theme/CAPTheme'; - -export const useDialogBodyStyles = makeStyles({ - root: { - gap: CAP_TOKENS['cap/Dialog/Header/Gap'], - }, -}); - -export function useDialogBodyStylesHook( - state: DialogBodyState -): DialogBodyState { - // Apply base DialogBody styles first - useDialogBodyStyles_unstable(state); - - // Then override with CAP styles - const styles = useDialogBodyStyles(); - - state.root.className = mergeClasses(state.root.className, styles.root); - - return state; -} diff --git a/packages/react-cap-theme/src/components/Dialog/DialogSurface.styles.ts b/packages/react-cap-theme/src/components/Dialog/DialogSurface.styles.ts deleted file mode 100644 index edfb3f02..00000000 --- a/packages/react-cap-theme/src/components/Dialog/DialogSurface.styles.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - makeStyles, - mergeClasses, - type DialogSurfaceState, - useDialogSurfaceStyles_unstable, -} from '@fluentui/react-components'; - -import { CAP_TOKENS } from '../../theme/CAPTheme'; - -export const useDialogSurfaceStyles = makeStyles({ - root: { - borderRadius: CAP_TOKENS['cap/Dialog/Corner'], - border: `${CAP_TOKENS['cap/Dialog/strokeWidth']} solid ${CAP_TOKENS['cap/Dialog/strokeColor']}`, - }, -}); - -export function useDialogSurfaceStylesHook( - state: DialogSurfaceState -): DialogSurfaceState { - // Apply base DialogSurface styles first - useDialogSurfaceStyles_unstable(state); - - // Then override with CAP styles - const styles = useDialogSurfaceStyles(); - - state.root.className = mergeClasses(state.root.className, styles.root); - - return state; -} diff --git a/packages/react-cap-theme/src/components/Drawer/Drawer.styles.ts b/packages/react-cap-theme/src/components/Drawer/Drawer.styles.ts deleted file mode 100644 index 21365892..00000000 --- a/packages/react-cap-theme/src/components/Drawer/Drawer.styles.ts +++ /dev/null @@ -1,21 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/DrawerBody.styles.ts b/packages/react-cap-theme/src/components/Drawer/DrawerBody.styles.ts deleted file mode 100644 index 9e0e3386..00000000 --- a/packages/react-cap-theme/src/components/Drawer/DrawerBody.styles.ts +++ /dev/null @@ -1,24 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/DrawerFooter.styles.ts b/packages/react-cap-theme/src/components/Drawer/DrawerFooter.styles.ts deleted file mode 100644 index 65611ee4..00000000 --- a/packages/react-cap-theme/src/components/Drawer/DrawerFooter.styles.ts +++ /dev/null @@ -1,26 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/DrawerHeader.styles.ts b/packages/react-cap-theme/src/components/Drawer/DrawerHeader.styles.ts deleted file mode 100644 index 06a0c7d1..00000000 --- a/packages/react-cap-theme/src/components/Drawer/DrawerHeader.styles.ts +++ /dev/null @@ -1,26 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/DrawerHeaderNavigation.styles.ts b/packages/react-cap-theme/src/components/Drawer/DrawerHeaderNavigation.styles.ts deleted file mode 100644 index 9a308dd0..00000000 --- a/packages/react-cap-theme/src/components/Drawer/DrawerHeaderNavigation.styles.ts +++ /dev/null @@ -1,19 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/DrawerHeaderTitle.styles.ts b/packages/react-cap-theme/src/components/Drawer/DrawerHeaderTitle.styles.ts deleted file mode 100644 index f6fc2b88..00000000 --- a/packages/react-cap-theme/src/components/Drawer/DrawerHeaderTitle.styles.ts +++ /dev/null @@ -1,35 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/InlineDrawer.styles.ts b/packages/react-cap-theme/src/components/Drawer/InlineDrawer.styles.ts deleted file mode 100644 index 1ddea5c0..00000000 --- a/packages/react-cap-theme/src/components/Drawer/InlineDrawer.styles.ts +++ /dev/null @@ -1,19 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Drawer/OverlayDrawer.styles.ts b/packages/react-cap-theme/src/components/Drawer/OverlayDrawer.styles.ts deleted file mode 100644 index f8c15699..00000000 --- a/packages/react-cap-theme/src/components/Drawer/OverlayDrawer.styles.ts +++ /dev/null @@ -1,19 +0,0 @@ -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; -} diff --git a/packages/react-cap-theme/src/components/Input/Input.styles.ts b/packages/react-cap-theme/src/components/Input/Input.styles.ts deleted file mode 100644 index 67e85b21..00000000 --- a/packages/react-cap-theme/src/components/Input/Input.styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - makeStyles, - mergeClasses, - type InputState, -} from '@fluentui/react-components'; - -export const useInputStyles = makeStyles({ - root: {}, -}); - -export function useInputStylesHook(state: InputState): InputState { - const styles = useInputStyles(); - - state.root.className = mergeClasses(state.root.className, styles.root); - - return state; -} diff --git a/packages/react-cap-theme/src/components/react-button/Button.ts b/packages/react-cap-theme/src/components/react-button/Button.ts new file mode 100644 index 00000000..8294438e --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/Button.ts @@ -0,0 +1,13 @@ +export { Button } from "./components/Button/Button"; +export { renderButton } from "./components/Button/renderButton"; +export { useButton } from "./components/Button/useButton"; +export { + buttonClassNames, + useButtonStyles, +} from "./components/Button/useButtonStyles.styles"; +export type { + ButtonProps, + ButtonSlots, + ButtonState, + ButtonAppearance, +} from "./components/Button/Button.types"; diff --git a/packages/react-cap-theme/src/components/react-button/MenuButton.ts b/packages/react-cap-theme/src/components/react-button/MenuButton.ts new file mode 100644 index 00000000..53f900f1 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/MenuButton.ts @@ -0,0 +1,12 @@ +export { MenuButton } from "./components/MenuButton/MenuButton"; +export { renderMenuButton } from "./components/MenuButton/renderMenuButton"; +export { useMenuButton } from "./components/MenuButton/useMenuButton"; +export { + menuButtonClassNames, + useMenuButtonStyles, +} from "./components/MenuButton/useMenuButtonStyles.styles"; +export type { + MenuButtonProps, + MenuButtonSlots, + MenuButtonState, +} from "./components/MenuButton/MenuButton.types"; diff --git a/packages/react-cap-theme/src/components/react-button/SplitButton.ts b/packages/react-cap-theme/src/components/react-button/SplitButton.ts new file mode 100644 index 00000000..d1be00f8 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/SplitButton.ts @@ -0,0 +1,12 @@ +export { SplitButton } from "./components/SplitButton/SplitButton"; +export { renderSplitButton } from "./components/SplitButton/renderSplitButton"; +export { useSplitButton } from "./components/SplitButton/useSplitButton"; +export { + splitButtonClassNames, + useSplitButtonStyles, +} from "./components/SplitButton/useSplitButtonStyles.styles"; +export type { + SplitButtonProps, + SplitButtonSlots, + SplitButtonState, +} from "./components/SplitButton/SplitButton.types"; diff --git a/packages/react-cap-theme/src/components/react-button/ToggleButton.ts b/packages/react-cap-theme/src/components/react-button/ToggleButton.ts new file mode 100644 index 00000000..71371ea9 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/ToggleButton.ts @@ -0,0 +1,11 @@ +export { ToggleButton } from "./components/ToggleButton/ToggleButton"; +export { renderToggleButton } from "./components/ToggleButton/renderToggleButton"; +export { useToggleButton } from "./components/ToggleButton/useToggleButton"; +export { + toggleButtonClassNames, + useToggleButtonStyles, +} from "./components/ToggleButton/useToggleButtonStyles.styles"; +export type { + ToggleButtonProps, + ToggleButtonState, +} from "./components/ToggleButton/ToggleButton.types"; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx b/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx new file mode 100644 index 00000000..2ca14e56 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx @@ -0,0 +1,20 @@ +import { useButtonStyles_unstable } from "@fluentui/react-button"; +import type { ForwardRefComponent } from "@fluentui/react-utilities"; +import * as React from "react"; +import type { ButtonProps } from "./Button.types"; +import { toBaseState } from "./Button.utils"; +import { renderButton } from "./renderButton"; +import { useButton } from "./useButton"; +import { useButtonStyles } from "./useButtonStyles.styles"; + +export const Button: ForwardRefComponent = React.forwardRef( + (props, ref) => { + const state = useButton(props, ref); + useButtonStyles_unstable(toBaseState(state)); + useButtonStyles(state); + return renderButton(state); + // Casting is required due to lack of distributive union to support unions on @types/react + }, +) as ForwardRefComponent; + +Button.displayName = "Button"; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts b/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts new file mode 100644 index 00000000..97a1149f --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts @@ -0,0 +1,28 @@ +import type { + ButtonSlots, + ButtonProps as BaseButtonProps, + ButtonState as BaseButtonState, +} from "@fluentui/react-button"; +import type { ComponentProps } from "@fluentui/react-utilities"; + +export type { ButtonSlots } from "@fluentui/react-button"; + +export type ButtonAppearance = + | "primary" + | "tint" + | "outline" + | "outlineColor" + | "secondary" + | "subtle" + | "transparent"; + +export type ButtonProps = ComponentProps & + Pick< + BaseButtonProps, + "disabledFocusable" | "disabled" | "iconPosition" | "size" + > & { + appearance?: ButtonAppearance; + }; + +export type ButtonState = Omit & + Required>; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts b/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts new file mode 100644 index 00000000..eca12cf5 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts @@ -0,0 +1,32 @@ +import type { + ButtonState as BaseButtonState, + ButtonProps as BaseButtonProps, +} from "@fluentui/react-button"; +import type { + ButtonAppearance, + ButtonProps, + ButtonState, +} from "./Button.types"; + +export const baseAppearanceMap: Record< + ButtonAppearance, + BaseButtonProps["appearance"] +> = { + secondary: "secondary", + primary: "primary", + outline: "outline", + outlineColor: "outline", + subtle: "subtle", + transparent: "transparent", + tint: "primary", +}; + +export const toBaseProps = (props: ButtonProps): BaseButtonProps => ({ + ...props, + appearance: props.appearance && baseAppearanceMap[props.appearance], +}); + +export const toBaseState = (state: ButtonState): BaseButtonState => ({ + ...state, + appearance: baseAppearanceMap[state.appearance] ?? "secondary", +}); diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx b/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx new file mode 100644 index 00000000..240e31f1 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx @@ -0,0 +1,12 @@ +import { + renderButton_unstable, + type ButtonState as BaseButtonState, +} from "@fluentui/react-button"; +import type { ReactElement } from "react"; +import type { ButtonState } from "./Button.types"; +import { toBaseState } from "./Button.utils"; + +export const renderButton = (state: ButtonState): ReactElement => { + const baseState: BaseButtonState = toBaseState(state); + return renderButton_unstable(baseState); +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts b/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts new file mode 100644 index 00000000..1f274d3b --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts @@ -0,0 +1,15 @@ +import { useButton_unstable as useBaseState } from "@fluentui/react-button"; +import type { ButtonProps, ButtonState } from "./Button.types"; +import { toBaseProps } from "./Button.utils"; + +export const useButton = ( + props: ButtonProps, + ref: React.Ref, +): ButtonState => { + const appearance = props.appearance ?? "secondary"; + + return { + ...useBaseState(toBaseProps(props), ref), + appearance, + } as ButtonState; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts new file mode 100644 index 00000000..192745cf --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts @@ -0,0 +1,281 @@ +import { createCustomFocusIndicatorStyle } from "@fluentui/react-tabster"; +import type { SlotClassNames } from "@fluentui/react-utilities"; +import { + tokens, + typographyStyles, +} from "../../../tokens"; +import { makeStyles, mergeClasses, shorthands } from "@griffel/react"; +import type { ButtonSlots, ButtonState } from "./Button.types"; + +export const buttonClassNames: SlotClassNames = { + root: "fui-Button", + icon: "fui-Button__icon", +}; + +const BORDER_WIDTH = tokens.strokeWidthThin; +const buttonSpacingSmall = `calc(${tokens.spacingVerticalSNudge} - ${BORDER_WIDTH})`; +const buttonSpacingMedium = `calc(${tokens.spacingVerticalS} - ${BORDER_WIDTH})`; +const buttonSpacingLarge = `calc(${tokens.spacingVerticalMNudge} - ${BORDER_WIDTH})`; + +const iconFilledClassName = "fui-Icon-filled"; +const iconRegularClassName = "fui-Icon-regular"; + +const displayInline = { display: "inline" }; +const displayNone = { display: "none" }; + +const useRootStyles = makeStyles({ + base: { + borderRadius: "12px", + minWidth: "unset", + [`:hover .${iconFilledClassName}`]: displayInline, + [`:hover .${iconRegularClassName}`]: displayNone, + [`:hover:active .${iconFilledClassName}`]: displayInline, + [`:hover:active .${iconRegularClassName}`]: displayNone, + + ...createCustomFocusIndicatorStyle({ + borderRadius: "12px", + boxShadow: ` + 0 0 0 ${tokens.strokeWidthThin} ${tokens.colorStrokeFocus2} inset, + 0 0 0 ${tokens.strokeWidthThick} ${tokens.colorStrokeFocus1} inset + `, + }), + }, + small: { + ...typographyStyles.caption1Strong, + borderRadius: "8px", + height: "28px", + padding: `${buttonSpacingSmall} calc(${tokens.spacingHorizontalS} - ${BORDER_WIDTH})`, + }, + medium: { + height: "36px", + padding: `${buttonSpacingMedium} calc(${tokens.spacingHorizontalM} - ${BORDER_WIDTH})`, + }, + large: { + ...typographyStyles.body1Strong, + height: "44px", + padding: `${buttonSpacingLarge} calc(${tokens.spacingHorizontalM} - ${BORDER_WIDTH})`, + }, + outline: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + color: tokens.colorNeutralForeground3, + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralStroke2), + backgroundColor: tokens.colorNeutralBackground3Hover, + color: tokens.colorNeutralForeground1Hover, + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorNeutralBackground3Pressed), + backgroundColor: tokens.colorNeutralBackground3Pressed, + color: tokens.colorNeutralForeground1Pressed, + }, + }, + primary: { + ...shorthands.borderColor(tokens.colorBrandBackground), + ":hover": { + ...shorthands.borderColor(tokens.colorBrandBackgroundHover), + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorBrandBackgroundPressed), + }, + }, + secondary: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForeground3, + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralStroke2), + backgroundColor: tokens.colorNeutralBackground3Hover, + color: tokens.colorNeutralForeground1Hover, + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorNeutralBackground3Pressed), + backgroundColor: tokens.colorNeutralBackground3Pressed, + color: tokens.colorNeutralForeground1Pressed, + }, + }, + subtle: { + ...shorthands.borderColor(tokens.colorTransparentStroke), + backgroundColor: tokens.colorTransparentBackground, + color: tokens.colorNeutralForeground3, + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralBackground3Hover), + backgroundColor: tokens.colorNeutralBackground3Hover, + color: tokens.colorNeutralForeground1, + [`& .${buttonClassNames.icon}`]: { + color: tokens.colorNeutralForeground1, + }, + }, + ":hover:active": { + backgroundColor: tokens.colorNeutralBackground1Pressed, + color: tokens.colorNeutralForeground3Pressed, + [`& .${buttonClassNames.icon}`]: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + }, + transparent: { + ...shorthands.borderColor(tokens.colorTransparentStroke), + backgroundColor: tokens.colorTransparentBackground, + color: tokens.colorNeutralForeground3, + ":hover": { color: tokens.colorCompoundBrandForeground1Hover }, + [":hover:active"]: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + tint: { + ...shorthands.borderColor(tokens.colorBrandStroke2), + backgroundColor: tokens.colorBrandBackground2, + color: tokens.colorCompoundBrandForeground1, + ":hover": { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + backgroundColor: tokens.colorBrandBackground2Hover, + color: tokens.colorCompoundBrandForeground1Hover, + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + outlineColor: { + ...shorthands.borderColor(tokens.colorBrandStroke2), + backgroundColor: "transparent", + color: tokens.colorCompoundBrandForeground1, + ":hover": { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + backgroundColor: tokens.colorBrandBackground2Hover, + color: tokens.colorCompoundBrandForeground1Hover, + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, +}); + +const useRootDisabledStyles = makeStyles({ + outline: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: "transparent", + color: tokens.colorNeutralForegroundDisabled, + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: "transparent", + color: tokens.colorNeutralForegroundDisabled, + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: "transparent", + color: tokens.colorNeutralForegroundDisabled, + }, + }, + secondary: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForegroundDisabled, + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForegroundDisabled, + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForegroundDisabled, + }, + }, + subtle: {}, + transparent: {}, + primary: { + ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), + }, + }, + tint: { + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + ":hover": { + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + ":hover:active": { + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + }, + outlineColor: { + backgroundColor: "transparent", + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + ":hover": { + backgroundColor: "transparent", + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + ":hover:active": { + backgroundColor: "transparent", + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + }, +}); + +const useRootIconOnlyStyles = makeStyles({ + small: { + minWidth: "28px", + maxWidth: "28px", + padding: buttonSpacingSmall, + }, + medium: { + minWidth: "36px", + maxWidth: "36px", + padding: buttonSpacingMedium, + }, + large: { + minWidth: "40px", + maxWidth: "40px", + padding: buttonSpacingLarge, + }, +}); + +const useIconStyles = makeStyles({ + small: { + fontSize: "16px", + height: "16px", + width: "16px", + }, + medium: {}, + large: { + fontSize: "20px", + height: "20px", + width: "20px", + }, +}); + +export const useButtonStyles = (state: ButtonState): ButtonState => { + const rootStyles = useRootStyles(); + const rootDisabledStyles = useRootDisabledStyles(); + const rootIconOnlyStyles = useRootIconOnlyStyles(); + const iconStyles = useIconStyles(); + + const { appearance, disabled, disabledFocusable, iconOnly, size } = state; + + state.root.className = mergeClasses( + state.root.className, + buttonClassNames.root, + rootStyles.base, + rootStyles[appearance], + (disabled || disabledFocusable) && rootDisabledStyles[appearance], + rootStyles[size], + iconOnly && rootIconOnlyStyles[size], + ); + + if (state.icon) { + state.icon.className = mergeClasses( + state.icon.className, + buttonClassNames.icon, + iconStyles[size], + ); + } + + return state; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx new file mode 100644 index 00000000..ad25980a --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx @@ -0,0 +1,19 @@ +import { useButtonStyles_unstable } from "@fluentui/react-button"; +import type { ForwardRefComponent } from "@fluentui/react-utilities"; +import * as React from "react"; +import type { ButtonState } from "../Button/Button.types"; +import { toBaseState } from "../Button/Button.utils"; +import type { MenuButtonProps } from "./MenuButton.types"; +import { renderMenuButton } from "./renderMenuButton"; +import { useMenuButton } from "./useMenuButton"; +import { useMenuButtonStyles } from "./useMenuButtonStyles.styles"; + +export const MenuButton: ForwardRefComponent = + React.forwardRef((props, ref) => { + const state = useMenuButton(props, ref); + useButtonStyles_unstable(toBaseState(state as ButtonState)); + useMenuButtonStyles(state); + return renderMenuButton(state); + }) as ForwardRefComponent; + +MenuButton.displayName = "MenuButton"; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts new file mode 100644 index 00000000..a10750fd --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts @@ -0,0 +1,11 @@ +import type { MenuButtonSlots } from "@fluentui/react-button"; +import type { ComponentProps, ComponentState } from "@fluentui/react-utilities"; +import type { ButtonProps, ButtonState, ButtonSlots } from "../../Button"; + +export type { MenuButtonSlots } from "@fluentui/react-button"; + +export type MenuButtonProps = ComponentProps & + Pick; + +export type MenuButtonState = ComponentState & + Omit; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx b/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx new file mode 100644 index 00000000..883b07fd --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx @@ -0,0 +1,11 @@ +import { renderMenuButton_unstable } from "@fluentui/react-button"; +import type { ReactElement } from "react"; +import { baseAppearanceMap } from "../Button/Button.utils"; +import type { MenuButtonState } from "./MenuButton.types"; + +export const renderMenuButton = (state: MenuButtonState): ReactElement => { + return renderMenuButton_unstable({ + ...state, + appearance: baseAppearanceMap[state.appearance] ?? "secondary", + }); +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts new file mode 100644 index 00000000..fd7cdccd --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts @@ -0,0 +1,19 @@ +import { useMenuButton_unstable } from "@fluentui/react-button"; +import type * as React from "react"; +import { baseAppearanceMap } from "../Button/Button.utils"; +import type { MenuButtonProps, MenuButtonState } from "./MenuButton.types"; + +export const useMenuButton = ( + props: MenuButtonProps, + ref: React.Ref, +): MenuButtonState => { + const { appearance = "secondary" } = props; + const baseState = useMenuButton_unstable( + { + ...props, + appearance: appearance && baseAppearanceMap[appearance], + }, + ref, + ); + return { ...baseState, appearance } as MenuButtonState; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts new file mode 100644 index 00000000..d546b715 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts @@ -0,0 +1,61 @@ +import type { SlotClassNames } from "@fluentui/react-utilities"; +import { tokens } from "../../../tokens"; +import { makeStyles, mergeClasses } from "@griffel/react"; +import { useButtonStyles } from "../Button/useButtonStyles.styles"; +import type { MenuButtonSlots, MenuButtonState } from "./MenuButton.types"; + +export const menuButtonClassNames: SlotClassNames = { + root: "fui-MenuButton", + icon: "fui-MenuButton__icon", + menuIcon: "fui-MenuButton__menuIcon", +}; + +const useMenuIconStyles = makeStyles({ + base: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + + small: { + fontSize: tokens.fontSizeBase200, + height: "16px", + lineHeight: tokens.lineHeightBase200, + width: "16px", + }, + medium: { + fontSize: tokens.fontSizeBase400, + height: "20px", + lineHeight: tokens.lineHeightBase400, + width: "20px", + }, + large: { + fontSize: tokens.fontSizeBase400, + height: "20px", + lineHeight: tokens.lineHeightBase400, + width: "20px", + }, + + noIconOnly: { + marginLeft: tokens.spacingHorizontalSNudge, + }, +}); + +export const useMenuButtonStyles = ( + state: MenuButtonState, +): MenuButtonState => { + const menuIconStyles = useMenuIconStyles(); + + if (state.menuIcon) { + state.menuIcon.className = mergeClasses( + state.menuIcon.className, + menuButtonClassNames.menuIcon, + menuIconStyles.base, + menuIconStyles[state.size], + !state.iconOnly && menuIconStyles.noIconOnly, + ); + } + + useButtonStyles({ ...state, iconPosition: "before" }); + return state; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx new file mode 100644 index 00000000..47682b3f --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx @@ -0,0 +1,16 @@ +import type { ForwardRefComponent } from "@fluentui/react-utilities"; +import * as React from "react"; +import { renderSplitButton } from "./renderSplitButton"; +import type { SplitButtonProps } from "./SplitButton.types"; +import { useSplitButton } from "./useSplitButton"; +import { useSplitButtonStyles } from "./useSplitButtonStyles.styles"; + +export const SplitButton: ForwardRefComponent = + React.forwardRef((props, ref) => { + const state = useSplitButton(props, ref); + useSplitButtonStyles(state); + return renderSplitButton(state); + // Casting is required due to lack of distributive union to support unions on @types/react + }) as ForwardRefComponent; + +SplitButton.displayName = "SplitButton"; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts new file mode 100644 index 00000000..1c71d042 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts @@ -0,0 +1,25 @@ +import type { + ComponentProps, + ComponentState, + Slot, +} from "@fluentui/react-utilities"; +import type { Button, ButtonProps, ButtonState } from "../../Button"; +import type { + MenuButton, + MenuButtonProps, + MenuButtonState, +} from "../../MenuButton"; + +export type SplitButtonSlots = { + root: NonNullable>; + menuButton?: Slot; + primaryActionButton?: Slot; +}; + +export type SplitButtonProps = ComponentProps & + Omit & + Omit; + +export type SplitButtonState = ComponentState & + Omit & + Omit; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx b/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx new file mode 100644 index 00000000..bee302c6 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx @@ -0,0 +1,15 @@ + +import { assertSlots } from "@fluentui/react-utilities"; +import type { ReactElement } from "react"; +import type { SplitButtonSlots, SplitButtonState } from "./SplitButton.types"; + +export const renderSplitButton = (state: SplitButtonState): ReactElement => { + assertSlots(state); + + return ( + + {state.primaryActionButton && } + {state.menuButton && } + + ); +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts new file mode 100644 index 00000000..ebee0aae --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts @@ -0,0 +1,85 @@ +import { + getIntrinsicElementProps, + useId, + slot, +} from "@fluentui/react-utilities"; +import type * as React from "react"; +import { Button } from "../Button/Button"; +import { MenuButton } from "../MenuButton/MenuButton"; +import type { SplitButtonProps, SplitButtonState } from "./SplitButton.types"; + +export const useSplitButton = ( + props: SplitButtonProps, + ref: React.Ref, +): SplitButtonState => { + const { + appearance = "secondary", + children, + disabled = false, + disabledFocusable = false, + icon, + iconPosition = "before", + menuButton, + menuIcon, + primaryActionButton, + size = "medium", + } = props; + + const baseId = useId("splitButton-"); + + const menuButtonShorthand = slot.optional(menuButton, { + defaultProps: { + appearance, + disabled, + disabledFocusable, + menuIcon, + size, + }, + renderByDefault: true, + elementType: MenuButton, + }); + + const primaryActionButtonShorthand = slot.optional(primaryActionButton, { + defaultProps: { + appearance, + children, + disabled, + disabledFocusable, + icon, + iconPosition, + id: baseId + "__primaryActionButton", + size, + }, + renderByDefault: true, + elementType: Button, + }); + + if ( + menuButtonShorthand && + primaryActionButtonShorthand && + !menuButtonShorthand["aria-label"] && + !menuButtonShorthand["aria-labelledby"] + ) { + menuButtonShorthand["aria-labelledby"] = + primaryActionButtonShorthand.id; + } + + return { + components: { + root: "div", + menuButton: MenuButton, + primaryActionButton: Button, + }, + root: slot.always(getIntrinsicElementProps("div", { ref, ...props }), { + elementType: "div", + }), + primaryActionButton: primaryActionButtonShorthand, + menuButton: menuButtonShorthand, + appearance, + disabled, + disabledFocusable, + iconPosition, + shape: "rounded", + size, + }; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts new file mode 100644 index 00000000..525aaed8 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts @@ -0,0 +1,266 @@ +import { createCustomFocusIndicatorStyle } from "@fluentui/react-tabster"; +import type { SlotClassNames } from "@fluentui/react-utilities"; +import { tokens } from "../../../tokens"; +import { makeStyles, mergeClasses, shorthands } from "@griffel/react"; +import type { SplitButtonSlots, SplitButtonState } from "./SplitButton.types"; + +export const splitButtonClassNames: SlotClassNames = { + root: "fui-SplitButton", + primaryActionButton: "fui-SplitButton__primaryActionButton", + menuButton: "fui-SplitButton__menuButton", +}; + +const createPaddingWithStrokeAdjustment = ( + horizontal: string, +): { + paddingLeft: string; + paddingRight: string; +} => ({ + paddingLeft: `calc(${horizontal} - ${tokens.strokeWidthThin})`, + paddingRight: horizontal, +}); + +const createSizeStyles = ( + dimension: string, +): { + height: string; + width: string; +} => ({ + height: dimension, + width: dimension, +}); + +const useFocusStyles = makeStyles({ + primaryActionButton: createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorStrokeFocus1), + borderRadius: 0, + borderRightWidth: 0, + boxShadow: "none", + outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, + ":after": { + borderRightColor: "inherit", + height: "100%", + }, + }), + + menuButton: createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorStrokeFocus1), + borderRadius: 0, + borderLeft: "none", + boxShadow: "none", + outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, + position: "relative", + zIndex: 1, + ":after": { + content: '""', + borderLeft: `${tokens.strokeWidthThin} solid ${tokens.colorStrokeFocus1}`, + }, + }), +}); + +const useRootStyles = makeStyles({ + small: { + [`& .${splitButtonClassNames.primaryActionButton}`]: { + borderTopLeftRadius: "8px", + borderBottomLeftRadius: "8px", + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${splitButtonClassNames.menuButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderTopRightRadius: "8px", + borderBottomRightRadius: "8px", + }, + }, + medium: { + [`& .${splitButtonClassNames.primaryActionButton}`]: { + borderTopLeftRadius: "12px", + borderBottomLeftRadius: "12px", + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${splitButtonClassNames.menuButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderTopRightRadius: "12px", + borderBottomRightRadius: "12px", + }, + }, + large: { + [`& .${splitButtonClassNames.primaryActionButton}`]: { + borderTopLeftRadius: "12px", + borderBottomLeftRadius: "12px", + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${splitButtonClassNames.menuButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderTopRightRadius: "12px", + borderBottomRightRadius: "12px", + }, + }, +}); + +const useRootAppearanceStyles = makeStyles({ + tint: { + [`&:hover .${splitButtonClassNames.primaryActionButton}`]: { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + }, + [`&:hover .${splitButtonClassNames.menuButton}`]: { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + }, + }, + outlineColor: {}, + primary: {}, + outline: {}, + secondary: {}, + subtle: {}, + transparent: {}, +}); + +const usePrimaryActionButtonStyles = makeStyles({ + base: { + borderRadius: tokens.borderRadiusNone, + borderRightWidth: "0", + position: "relative", + ":after": { + content: '""', + borderRight: `${tokens.strokeWidthThin} solid`, + borderRightColor: "inherit", + boxSizing: "border-box", + height: `calc(100% - ${tokens.strokeWidthThin} * 2 - ${tokens.spacingVerticalS} * 2)`, + opacity: 0.3, + position: "absolute", + right: 0, + }, + + "@media (forced-colors: active)": { + ":after": { borderRightColor: "inherit" }, + ":hover:after": { borderRightColor: "inherit" }, + ":active:after": { borderRightColor: "inherit" }, + }, + }, + outline: {}, + primary: { + ":after": { borderRightColor: tokens.colorNeutralStrokeOnBrand2 }, + ":hover:after": { + borderRightColor: tokens.colorNeutralStrokeOnBrand2Hover, + }, + ":active:after": { + borderRightColor: tokens.colorNeutralStrokeOnBrand2Pressed, + }, + }, + secondary: {}, + subtle: { + ":after": { borderRightColor: tokens.colorNeutralStroke1 }, + ":hover:after": { borderRightColor: tokens.colorNeutralStroke1Hover }, + ":active:after": { + borderRightColor: tokens.colorNeutralStroke1Pressed, + }, + }, + transparent: { + ":after": { borderRightColor: tokens.colorNeutralStroke1 }, + ":hover:after": { borderRightColor: tokens.colorNeutralStroke1Hover }, + ":active:after": { + borderRightColor: tokens.colorNeutralStroke1Pressed, + }, + }, + tint: { + ":after": { + borderRightColor: tokens.colorBrandStroke2, + opacity: 1, + }, + ":hover:after": { + borderRightColor: tokens.colorBrandStroke2Hover, + }, + ":active:after": { + borderRightColor: tokens.colorBrandStroke2Pressed, + }, + }, + outlineColor: {}, + disabled: { + ":after": { borderRightColor: tokens.colorNeutralStrokeDisabled }, + ":hover:after": { borderRightColor: tokens.colorNeutralStrokeDisabled }, + ":active:after": { + borderRightColor: tokens.colorNeutralStrokeDisabled, + }, + }, + small: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalS), + medium: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalM), + large: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalM), +}); + +const useMenuButtonStyles = makeStyles({ + base: { + borderRadius: tokens.borderRadiusNone, + borderLeft: "none", + ":after": { + borderLeft: `${tokens.strokeWidthThin} solid`, + boxSizing: "border-box", + height: "100%", + position: "absolute", + width: "100%", + }, + }, + small: { paddingLeft: tokens.spacingHorizontalSNudge }, + medium: { paddingLeft: tokens.spacingHorizontalS }, + large: { paddingLeft: tokens.spacingHorizontalMNudge }, +}); + +const useMenuIconStyles = makeStyles({ + small: createSizeStyles("12px"), + medium: createSizeStyles("16px"), + large: createSizeStyles("16px"), +}); + +export const useSplitButtonStyles = ( + state: SplitButtonState, +): SplitButtonState => { + const rootStyles = useRootStyles(); + const rootAppearanceStyles = useRootAppearanceStyles(); + const focusStyles = useFocusStyles(); + const primaryActionButtonStyles = usePrimaryActionButtonStyles(); + const menuButtonStyles = useMenuButtonStyles(); + const menuIconStyles = useMenuIconStyles(); + + state.root.className = mergeClasses( + splitButtonClassNames.root, + rootStyles[state.size], + rootAppearanceStyles[state.appearance], + state.root.className, + ); + + if (state.primaryActionButton) { + state.primaryActionButton.className = mergeClasses( + splitButtonClassNames.primaryActionButton, + primaryActionButtonStyles.base, + primaryActionButtonStyles[state.appearance], + primaryActionButtonStyles[state.size], + focusStyles.primaryActionButton, + (state.disabled || state.disabledFocusable) && + primaryActionButtonStyles.disabled, + state.primaryActionButton.className, + ); + } + + if (state.menuButton) { + state.menuButton.className = mergeClasses( + splitButtonClassNames.menuButton, + menuButtonStyles.base, + menuButtonStyles[state.size], + focusStyles.menuButton, + state.menuButton.className, + ); + } + + if (state.menuIcon) { + state.menuIcon.className = mergeClasses( + menuIconStyles[state.size], + state.menuIcon.className, + ); + } + + return state; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx new file mode 100644 index 00000000..121f45db --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx @@ -0,0 +1,26 @@ +import { + useButtonStyles_unstable, + useToggleButtonStyles_unstable, +} from "@fluentui/react-button"; +import type { ForwardRefComponent } from "@fluentui/react-utilities"; +import * as React from "react"; + +import { toBaseState } from "../Button/Button.utils"; +import { renderToggleButton } from "./renderToggleButton"; +import type { ToggleButtonProps } from "./ToggleButton.types"; +import { useToggleButton } from "./useToggleButton"; +import { useToggleButtonStyles } from "./useToggleButtonStyles.styles"; + +export const ToggleButton: ForwardRefComponent = + React.forwardRef((props, ref) => { + const state = useToggleButton(props, ref); + const baseState = toBaseState(state); + useButtonStyles_unstable(baseState); + useToggleButtonStyles_unstable({ + ...baseState, + checked: state.checked, + }); + useToggleButtonStyles(state); + return renderToggleButton(state); + }) as ForwardRefComponent; +ToggleButton.displayName = "ToggleButton"; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts new file mode 100644 index 00000000..e6074e6c --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts @@ -0,0 +1,8 @@ +import type { ToggleButtonProps as BaseToggleButtonProps } from "@fluentui/react-button"; +import type { ButtonProps, ButtonState } from "../../Button"; + +export type ToggleButtonProps = ButtonProps & + Pick; + +export type ToggleButtonState = ButtonState & + Required>; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx new file mode 100644 index 00000000..c7cb6ec8 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx @@ -0,0 +1,6 @@ +import type { ReactElement } from "react"; +import { renderButton } from "../../Button"; +import type { ToggleButtonState } from "./ToggleButton.types"; + +export const renderToggleButton = (state: ToggleButtonState): ReactElement => + renderButton(state); diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts new file mode 100644 index 00000000..1f1c0a1f --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts @@ -0,0 +1,15 @@ +import { useToggleState } from "@fluentui/react-button"; +import { useButton } from "../../Button"; + +import type { + ToggleButtonProps, + ToggleButtonState, +} from "./ToggleButton.types"; + +export const useToggleButton = ( + props: ToggleButtonProps, + ref: React.Ref, +): ToggleButtonState => { + const buttonState = useButton(props, ref) as ToggleButtonState; + return useToggleState(props, buttonState) as ToggleButtonState; +}; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts new file mode 100644 index 00000000..ea4d92d6 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts @@ -0,0 +1,139 @@ +import type { SlotClassNames } from "@fluentui/react-utilities"; +import { tokens } from "../../../tokens"; +import { makeStyles, shorthands, mergeClasses } from "@griffel/react"; +import { useButtonStyles, type ButtonSlots } from "../../Button"; +import type { ToggleButtonState } from "./ToggleButton.types"; + +export const toggleButtonClassNames: SlotClassNames = { + root: "fui-ToggleButton", + icon: "fui-ToggleButton__icon", +}; + +const iconFilledClassName = "fui-Icon-filled"; +const iconRegularClassName = "fui-Icon-regular"; + +const displayInline = { display: "inline" }; +const displayNone = { display: "none" }; + +const useRootCheckedStyles = makeStyles({ + base: { + [`:hover .${iconFilledClassName}`]: { + color: tokens.colorCompoundBrandForeground1Hover, + }, + }, + outline: { + ...shorthands.borderColor(tokens.colorNeutralStroke1Selected), + color: tokens.colorNeutralForeground3Selected, + }, + + primary: { + [`:hover .${iconFilledClassName}`]: { + color: tokens.colorNeutralForegroundOnBrand, + }, + }, + tint: { + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, + outlineColor: { + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, + secondary: { + backgroundColor: tokens.colorNeutralBackground3, + ...shorthands.borderColor(tokens.colorNeutralBackground3Hover), + color: tokens.colorNeutralForeground1, + [`& .${toggleButtonClassNames.icon}`]: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + ":hover": { + color: tokens.colorCompoundBrandForeground1Hover, + }, + ":hover:active": { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + subtle: { + backgroundColor: tokens.colorNeutralBackground1Selected, + color: tokens.colorNeutralForeground3Selected, + ":hover": { + backgroundColor: tokens.colorNeutralBackground1Hover, + }, + }, + transparent: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, +}); + +const useRootCheckedDisabledStyles = makeStyles({ + base: { + ":hover": { + [`& .${iconFilledClassName}`]: displayInline, + [`& .${iconRegularClassName}`]: displayNone, + }, + ":hover:active": { + [`& .${iconFilledClassName}`]: displayInline, + [`& .${iconRegularClassName}`]: displayNone, + }, + [`:hover .${iconFilledClassName}`]: { + color: tokens.colorNeutralForegroundDisabled, + }, + [`:hover:active .${iconFilledClassName}`]: { + color: tokens.colorNeutralForegroundDisabled, + }, + }, + secondary: {}, + primary: {}, + outline: {}, + transparent: {}, + subtle: {}, + tint: { + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, + outlineColor: { + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, +}); + +const useIconCheckedStyles = makeStyles({ + outline: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, +}); + +export const useToggleButtonStyles = ( + state: ToggleButtonState, +): ToggleButtonState => { + "use no memo"; + + const rootCheckedStyles = useRootCheckedStyles(); + const iconCheckedStyles = useIconCheckedStyles(); + const checkedDisabledStyles = useRootCheckedDisabledStyles(); + const { appearance, checked, disabled, disabledFocusable } = state; + const showAsDisabled = disabled || disabledFocusable; + + useButtonStyles(state); + + state.root.className = mergeClasses( + state.root.className, + toggleButtonClassNames.root, + checked && !showAsDisabled && rootCheckedStyles.base, + checked && !showAsDisabled && rootCheckedStyles[appearance], + checked && showAsDisabled && checkedDisabledStyles.base, + checked && showAsDisabled && checkedDisabledStyles[appearance], + ); + + if (state.icon) { + state.icon.className = mergeClasses( + state.icon.className, + toggleButtonClassNames.icon, + checked && appearance === "outline" && iconCheckedStyles.outline, + ); + } + + return state; +}; diff --git a/packages/react-cap-theme/src/components/react-button/index.ts b/packages/react-cap-theme/src/components/react-button/index.ts new file mode 100644 index 00000000..ccaf6411 --- /dev/null +++ b/packages/react-cap-theme/src/components/react-button/index.ts @@ -0,0 +1,45 @@ +export { + Button, + buttonClassNames, + renderButton, + useButton, + useButtonStyles, +} from "./Button"; +export type { + ButtonProps, + ButtonSlots, + ButtonState, + ButtonAppearance, +} from "./Button"; +export { + MenuButton, + menuButtonClassNames, + renderMenuButton, + useMenuButton, + useMenuButtonStyles, +} from "./MenuButton"; +export type { + MenuButtonProps, + MenuButtonSlots, + MenuButtonState, +} from "./MenuButton"; +export { + SplitButton, + splitButtonClassNames, + renderSplitButton, + useSplitButton, + useSplitButtonStyles, +} from "./SplitButton"; +export type { + SplitButtonProps, + SplitButtonSlots, + SplitButtonState, +} from "./SplitButton"; +export { + ToggleButton, + toggleButtonClassNames, + renderToggleButton, + useToggleButton, + useToggleButtonStyles, +} from "./ToggleButton"; +export type { ToggleButtonProps, ToggleButtonState } from "./ToggleButton"; diff --git a/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts b/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts new file mode 100644 index 00000000..b7553cc4 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts @@ -0,0 +1,49 @@ +import type { BrandVariants } from "@fluentui/tokens"; +import type { ColorTokens } from "../../types"; + +export const generateBrandColorTokens = ( + brand: BrandVariants, +): Partial => ({ + colorNeutralForeground2BrandHover: brand[110], + colorNeutralForeground2BrandPressed: brand[90], + colorNeutralForeground2BrandSelected: brand[110], + colorNeutralForeground3BrandHover: brand[110], + colorNeutralForeground3BrandPressed: brand[90], + colorNeutralForeground3BrandSelected: brand[110], + colorBrandForegroundLink: brand[110], + colorBrandForegroundLinkHover: brand[130], + colorBrandForegroundLinkPressed: brand[100], + colorBrandForegroundLinkSelected: brand[110], + colorCompoundBrandForeground1: brand[110], + colorCompoundBrandForeground1Hover: brand[130], + colorCompoundBrandForeground1Pressed: brand[100], + colorBrandForeground1: brand[110], + colorBrandForeground2: brand[120], + colorBrandForeground2Hover: brand[140], + colorBrandForeground2Pressed: brand[160], + colorBrandForegroundOnLight: brand[80], + colorBrandForegroundOnLightHover: brand[70], + colorBrandForegroundOnLightPressed: brand[40], + colorBrandForegroundOnLightSelected: brand[60], + colorBrandBackground: brand[70], + colorBrandBackgroundHover: brand[80], + colorBrandBackgroundPressed: brand[40], + colorBrandBackgroundSelected: brand[60], + colorCompoundBrandBackground: brand[110], + colorCompoundBrandBackgroundHover: brand[130], + colorCompoundBrandBackgroundPressed: brand[90], + colorBrandBackgroundStatic: brand[80], + colorBrandBackground2: brand[20], + colorBrandBackground2Hover: brand[40], + colorBrandBackground2Pressed: brand[10], + colorBrandBackgroundInvertedHover: brand[160], + colorBrandBackgroundInvertedPressed: brand[140], + colorBrandBackgroundInvertedSelected: brand[160], + colorBrandStroke1: brand[110], + colorBrandStroke2: brand[50], + colorBrandStroke2Hover: brand[70], + colorBrandStroke2Pressed: brand[40], + colorCompoundBrandStroke: brand[110], + colorCompoundBrandStrokeHover: brand[130], + colorCompoundBrandStrokePressed: brand[100], +}); diff --git a/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts b/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts new file mode 100644 index 00000000..db8fd60f --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts @@ -0,0 +1,52 @@ +import type { BrandVariants } from "@fluentui/tokens"; +import type { ColorTokens } from "../../types"; + +export const generateBrandColorTokens = ( + brand: BrandVariants, +): Partial => ({ + colorNeutralForeground2BrandHover: brand[80], + colorNeutralForeground2BrandPressed: brand[70], + colorNeutralForeground2BrandSelected: brand[80], + colorNeutralForeground3BrandHover: brand[80], + colorNeutralForeground3BrandPressed: brand[70], + colorNeutralForeground3BrandSelected: brand[80], + colorBrandForegroundLink: brand[70], + colorBrandForegroundLinkHover: brand[60], + colorBrandForegroundLinkPressed: brand[40], + colorBrandForegroundLinkSelected: brand[70], + colorCompoundBrandForeground1: brand[80], + colorCompoundBrandForeground1Hover: brand[70], + colorCompoundBrandForeground1Pressed: brand[40], + colorBrandForeground1: brand[80], + colorBrandForeground2: brand[70], + colorBrandForeground2Hover: brand[60], + colorBrandForeground2Pressed: brand[30], + colorBrandForegroundInverted: brand[110], + colorBrandForegroundInvertedHover: brand[130], + colorBrandForegroundInvertedPressed: brand[100], + colorBrandForegroundOnLight: brand[80], + colorBrandForegroundOnLightHover: brand[70], + colorBrandForegroundOnLightPressed: brand[40], + colorBrandForegroundOnLightSelected: brand[60], + colorBrandBackground: brand[80], + colorBrandBackgroundHover: brand[70], + colorBrandBackgroundPressed: brand[40], + colorBrandBackgroundSelected: brand[60], + colorCompoundBrandBackground: brand[80], + colorCompoundBrandBackgroundHover: brand[70], + colorCompoundBrandBackgroundPressed: brand[40], + colorBrandBackgroundStatic: brand[80], + colorBrandBackground2: brand[160], + colorBrandBackground2Hover: brand[150], + colorBrandBackground2Pressed: brand[130], + colorBrandBackgroundInvertedHover: brand[160], + colorBrandBackgroundInvertedPressed: brand[140], + colorBrandBackgroundInvertedSelected: brand[160], + colorBrandStroke1: brand[80], + colorBrandStroke2: brand[140], + colorBrandStroke2Hover: brand[130], + colorBrandStroke2Pressed: brand[90], + colorCompoundBrandStroke: brand[80], + colorCompoundBrandStrokeHover: brand[70], + colorCompoundBrandStrokePressed: brand[40], +}); diff --git a/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts new file mode 100644 index 00000000..33644b6d --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts @@ -0,0 +1,23 @@ +import type { FontVariants, FontFamilyCustomFontTokens } from "../../types"; + +export const generateTokens = ( + font: FontVariants, +): FontFamilyCustomFontTokens => ({ + fontFamilyCustomFont100: font[100].fontFamily, + fontFamilyCustomFont200: font[200].fontFamily, + fontFamilyCustomFont300: font[300].fontFamily, + fontFamilyCustomFont400: font[400].fontFamily, + fontFamilyCustomFont500: font[500].fontFamily, + fontFamilyCustomFont600: font[600].fontFamily, + fontFamilyCustomFont700: font[700].fontFamily, + fontFamilyCustomFont800: font[800].fontFamily, + fontFamilyCustomFont900: font[900].fontFamily, + fontFamilyCustomFont1000: font[1000].fontFamily, + fontFamilyCustomFont1100: font[1100].fontFamily, + fontFamilyCustomFont1200: font[1200].fontFamily, + fontFamilyCustomFont1300: font[1300].fontFamily, + fontFamilyCustomFont1400: font[1400].fontFamily, + fontFamilyCustomFont1500: font[1500].fontFamily, + fontFamilyCustomFont1600: font[1600].fontFamily, + fontFamilyCustomFont1700: font[1700].fontFamily, +}); diff --git a/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts new file mode 100644 index 00000000..0b62ccd4 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts @@ -0,0 +1,22 @@ +import type { + Font, + FontVariants, + FontWeightCustomFontTokens, +} from "../../types"; + +export const generateTokens = ( + font: FontVariants, +): Partial => { + const tokens: Partial = {}; + const fontKeys: string[] = Object.keys(font); + + fontKeys.forEach((key) => { + const fontKey: Font = Number(key) as Font; + const value: number | undefined = font[fontKey].fontWeight; + if (value !== undefined) { + tokens[`fontWeightCustomFont${fontKey}`] = value; + } + }); + + return tokens; +}; diff --git a/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts b/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts new file mode 100644 index 00000000..61e5ee7c --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts @@ -0,0 +1,2 @@ +export { generateTokens as generateFontFamilyTokens } from "./fontFamily"; +export { generateTokens as generateFontWeightTokens } from "./fontWeight"; diff --git a/packages/react-cap-theme/src/components/tokens/global/brandColors.ts b/packages/react-cap-theme/src/components/tokens/global/brandColors.ts new file mode 100644 index 00000000..7b075164 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/global/brandColors.ts @@ -0,0 +1,22 @@ +import type { BrandVariants } from "@fluentui/tokens"; + +export const brandTeal: BrandVariants = { + 10: "#091e1f", + 20: "#0b2829", + 30: "#0d3133", + 40: "#0e3d40", + 50: "#0f4b4f", + 60: "#0f575c", + 70: "#0e656b", + 80: "#0c757d", + 90: "#17878f", + 100: "#2799a1", + 110: "#3babb2", + 120: "#55b9c2", + 130: "#74ccd4", + 140: "#94dae0", + 150: "#b6eaf0", + 160: "#d7f2f5", +}; + +export const brandCAP: BrandVariants = brandTeal; diff --git a/packages/react-cap-theme/src/components/tokens/global/fonts.ts b/packages/react-cap-theme/src/components/tokens/global/fonts.ts new file mode 100644 index 00000000..2b211370 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/global/fonts.ts @@ -0,0 +1,18 @@ +import type { + FontSizeTokens, + FontStyleTokens, + LineHeightTokens, +} from "../types"; + +export const fontSizes: Pick = { + fontSizeBase450: "18px", +}; + +export const fontStyles: FontStyleTokens = { + fontStyleRegular: "normal", + fontStyleItalic: "italic", +}; + +export const lineHeights: Pick = { + lineHeightBase450: "24px", +}; diff --git a/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts b/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts new file mode 100644 index 00000000..a163397c --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts @@ -0,0 +1,59 @@ +import type { Greys } from "../types"; + +export const black: string = "#000000"; + +export const white: string = "#ffffff"; + +export const grey: Record = { + "0": black, + "2": "#050505", + "4": "#0a0a0a", + "6": "#0f0f0f", + "8": "#141414", + "10": "#1a1a1a", + "12": "#1f1f1f", + "14": "#242424", + "16": "#292929", + "18": "#2e2e2e", + "20": "#333333", + "22": "#383838", + "24": "#3d3d3d", + "26": "#424242", + "28": "#474747", + "30": "#4d4d4d", + "32": "#525252", + "34": "#575757", + "36": "#5c5c5c", + "38": "#616161", + "40": "#666666", + "42": "#6b6b6b", + "44": "#707070", + "46": "#757575", + "48": "#7a7a7a", + "50": "#808080", + "52": "#858585", + "54": "#8a8a8a", + "56": "#8f8f8f", + "58": "#949494", + "60": "#999999", + "62": "#9e9e9e", + "64": "#a3a3a3", + "66": "#a8a8a8", + "68": "#adadad", + "70": "#b3b3b3", + "72": "#b8b8b8", + "74": "#bdbdbd", + "76": "#c2c2c2", + "78": "#c7c7c7", + "80": "#cccccc", + "82": "#d1d1d1", + "84": "#d6d6d6", + "86": "#dbdbdb", + "88": "#e0e0e0", + "90": "#e6e6e6", + "92": "#ebebeb", + "94": "#f0f0f0", + "96": "#f5f5f5", + "98": "#fafafa", + "100": white, +}; diff --git a/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts b/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts new file mode 100644 index 00000000..72afb40a --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts @@ -0,0 +1,148 @@ +import { typographyStyles as defaultTypographyStyles } from "@fluentui/tokens"; +import { tokens } from "../tokens"; +import type { Font, TypographyStyle, TypographyStyles } from "../types"; + +export const typographyStyles: TypographyStyles = { + ...defaultTypographyStyles, + custom: { + body1: createVariableFallback(700, { + ...defaultTypographyStyles.body1, + fontStyle: tokens.fontStyleRegular, + }), + body1Mono: createVariableFallback(700, { + ...defaultTypographyStyles.body1, + fontFamily: tokens.fontFamilyMonospace, + fontStyle: tokens.fontStyleRegular, + }), + body1Strong: createVariableFallback(700, { + ...defaultTypographyStyles.body1Strong, + fontStyle: tokens.fontStyleRegular, + }), + body1Stronger: createVariableFallback(700, { + ...defaultTypographyStyles.body1Stronger, + fontStyle: tokens.fontStyleRegular, + }), + body2: createVariableFallback(800, { + ...defaultTypographyStyles.body2, + fontStyle: tokens.fontStyleRegular, + }), + body2Italic: createVariableFallback(800, { + ...defaultTypographyStyles.body2, + fontStyle: tokens.fontStyleItalic, + }), + body2Mono: createVariableFallback(800, { + ...defaultTypographyStyles.body2, + fontFamily: tokens.fontFamilyMonospace, + fontStyle: tokens.fontStyleRegular, + }), + body3: createVariableFallback(900, { + fontFamily: tokens.fontFamilyBase, + fontSize: tokens.fontSizeBase450, + fontStyle: tokens.fontStyleRegular, + fontWeight: tokens.fontWeightRegular, + lineHeight: tokens.lineHeightBase450, + }), + body3Strong: createVariableFallback(900, { + fontFamily: tokens.fontFamilyBase, + fontSize: tokens.fontSizeBase450, + fontStyle: tokens.fontStyleRegular, + fontWeight: tokens.fontWeightSemibold, + lineHeight: tokens.lineHeightBase450, + }), + buttonLarge: createVariableFallback(600, { + ...defaultTypographyStyles.subtitle2, + fontStyle: tokens.fontStyleRegular, + }), + buttonMedium: createVariableFallback(500, { + ...defaultTypographyStyles.body1Strong, + fontStyle: tokens.fontStyleRegular, + }), + buttonSmall: createVariableFallback(400, { + ...defaultTypographyStyles.caption1, + fontStyle: tokens.fontStyleRegular, + }), + caption1: createVariableFallback(200, { + ...defaultTypographyStyles.caption1, + fontStyle: tokens.fontStyleRegular, + }), + caption1Strong: createVariableFallback(200, { + ...defaultTypographyStyles.caption1Strong, + fontStyle: tokens.fontStyleRegular, + }), + caption1Stronger: createVariableFallback(200, { + ...defaultTypographyStyles.caption1Stronger, + fontStyle: tokens.fontStyleRegular, + }), + caption2: createVariableFallback(100, { + ...defaultTypographyStyles.caption2, + fontStyle: tokens.fontStyleRegular, + }), + caption2Strong: createVariableFallback(100, { + ...defaultTypographyStyles.caption2Strong, + fontStyle: tokens.fontStyleRegular, + }), + heading2: createVariableFallback(1300, { + ...defaultTypographyStyles.title2, + fontStyle: tokens.fontStyleRegular, + }), + heading3: createVariableFallback(1200, { + ...defaultTypographyStyles.title3, + fontStyle: tokens.fontStyleRegular, + }), + heading4: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleRegular, + }), + subtitle1: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleRegular, + }), + subtitle1Italic: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleItalic, + }), + subtitle2: createVariableFallback(1000, { + ...defaultTypographyStyles.subtitle2, + fontStyle: tokens.fontStyleRegular, + }), + subtitle2Stronger: createVariableFallback(1000, { + ...defaultTypographyStyles.subtitle2Stronger, + fontStyle: tokens.fontStyleRegular, + }), + title1: createVariableFallback(1400, { + ...defaultTypographyStyles.title1, + fontStyle: tokens.fontStyleRegular, + }), + title2: createVariableFallback(1300, { + ...defaultTypographyStyles.title2, + fontStyle: tokens.fontStyleRegular, + }), + title3: createVariableFallback(1200, { + ...defaultTypographyStyles.title3, + fontStyle: tokens.fontStyleRegular, + }), + largeTitle: createVariableFallback(1500, { + ...defaultTypographyStyles.largeTitle, + fontStyle: tokens.fontStyleRegular, + }), + display: createVariableFallback(1600, { + ...defaultTypographyStyles.display, + fontStyle: tokens.fontStyleRegular, + }), + webPartHeader: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleRegular, + }), + }, +}; + +function createVariableFallback( + font: Font, + style: TypographyStyle, +): TypographyStyle { + return { + ...style, + fontFamily: `var(--fontFamilyCustomFont${font}, ${style.fontFamily})`, + fontWeight: `var(--fontWeightCustomFont${font}, ${style.fontWeight})`, + }; +} diff --git a/packages/react-cap-theme/src/components/tokens/index.ts b/packages/react-cap-theme/src/components/tokens/index.ts new file mode 100644 index 00000000..688923e6 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/index.ts @@ -0,0 +1,79 @@ + +export { black, white, grey } from "./global/neutralColors"; +export { typographyStyles } from "./global/typographyStyles"; +export { darkTheme } from "./themes/darkTheme"; +export { lightTheme } from "./themes/lightTheme"; +export { themeToTokensObject } from "./themeToTokensObject"; +export { tokens } from "./tokens"; +export type { + BorderRadiusTokens, + Brands, + BrandVariants, + ColorPaletteAnchor, + ColorPaletteBeige, + ColorPaletteBerry, + ColorPaletteBlue, + ColorPaletteBrass, + ColorPaletteBrown, + ColorPaletteCornflower, + ColorPaletteCranberry, + ColorPaletteDarkGreen, + ColorPaletteDarkOrange, + ColorPaletteDarkRed, + ColorPaletteForest, + ColorPaletteGrape, + ColorPaletteGold, + ColorPaletteGreen, + ColorPaletteLavender, + ColorPaletteLilac, + ColorPaletteLightGreen, + ColorPaletteLightTeal, + ColorPaletteMagenta, + ColorPaletteMarigold, + ColorPaletteMink, + ColorPaletteNavy, + ColorPalettePeach, + ColorPalettePink, + ColorPalettePlatinum, + ColorPalettePlum, + ColorPalettePumpkin, + ColorPalettePurple, + ColorPaletteRed, + ColorPaletteRoyalBlue, + ColorPaletteSeafoam, + ColorPaletteSteel, + ColorPaletteTeal, + ColorPaletteTokens, + ColorPaletteYellow, + ColorTokens, + CurveTokens, + CustomizableTypographyStyle, + CustomizableTypographyStyles, + DurationTokens, + Font, + FontFamilyCustomFontTokens, + FontFamilyTokens, + FontSizeTokens, + FontStyleTokens, + FontVariants, + FontWeightCustomFontTokens, + FontWeightTokens, + Greys, + HorizontalSpacingTokens, + LineHeightTokens, + PartialTheme, + ShadowBrandTokens, + ShadowTokens, + SpacingTokens, + StrokeWidthTokens, + Theme, + TokenName, + TypographyStyle, + TypographyStyles, + VerticalSpacingTokens, + ZIndexTokens, +} from "./types"; +export { applyFonts } from "./utils/applyFonts"; +export { createDarkTheme } from "./utils/createDarkTheme"; +export { createLightTheme } from "./utils/createLightTheme"; +export { extractNeutralTokens } from "./utils/extractNeutralTokens"; diff --git a/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts b/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts new file mode 100644 index 00000000..4e6a823e --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts @@ -0,0 +1 @@ +export { themeToTokensObject } from "@fluentui/tokens"; diff --git a/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts b/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts new file mode 100644 index 00000000..e650d043 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts @@ -0,0 +1,5 @@ +import { brandCAP } from "../global/brandColors"; +import type { Theme } from "../types"; +import { createDarkTheme } from "../utils/createDarkTheme"; + +export const darkTheme: Theme = { ...createDarkTheme(brandCAP) }; diff --git a/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts b/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts new file mode 100644 index 00000000..7e4244b8 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts @@ -0,0 +1,5 @@ +import { brandCAP } from "../global/brandColors"; +import type { Theme } from "../types"; +import { createLightTheme } from "../utils/createLightTheme"; + +export const lightTheme: Theme = { ...createLightTheme(brandCAP) }; diff --git a/packages/react-cap-theme/src/components/tokens/tokens.ts b/packages/react-cap-theme/src/components/tokens/tokens.ts new file mode 100644 index 00000000..a8973da9 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/tokens.ts @@ -0,0 +1,55 @@ +import { tokens as fluentTokens } from "@fluentui/tokens"; +import type { TokenName } from "./types"; + +export const tokens: Record = { + ...fluentTokens, + + fontFamilyCustomFont100: "var(--fontFamilyCustomFont100)", + fontFamilyCustomFont200: "var(--fontFamilyCustomFont200)", + fontFamilyCustomFont300: "var(--fontFamilyCustomFont300)", + fontFamilyCustomFont400: "var(--fontFamilyCustomFont400)", + fontFamilyCustomFont500: "var(--fontFamilyCustomFont500)", + fontFamilyCustomFont600: "var(--fontFamilyCustomFont600)", + fontFamilyCustomFont700: "var(--fontFamilyCustomFont700)", + fontFamilyCustomFont800: "var(--fontFamilyCustomFont800)", + fontFamilyCustomFont900: "var(--fontFamilyCustomFont900)", + fontFamilyCustomFont1000: "var(--fontFamilyCustomFont1000)", + fontFamilyCustomFont1100: "var(--fontFamilyCustomFont1100)", + fontFamilyCustomFont1200: "var(--fontFamilyCustomFont1200)", + fontFamilyCustomFont1300: "var(--fontFamilyCustomFont1300)", + fontFamilyCustomFont1400: "var(--fontFamilyCustomFont1400)", + fontFamilyCustomFont1500: "var(--fontFamilyCustomFont1500)", + fontFamilyCustomFont1600: "var(--fontFamilyCustomFont1600)", + fontFamilyCustomFont1700: "var(--fontFamilyCustomFont1700)", + + fontSizeBase450: "var(--fontSizeBase450)", + + fontStyleItalic: "var(--fontStyleItalic)", + fontStyleRegular: "var(--fontStyleRegular)", + + fontWeightCustomFont100: "var(--fontWeightCustomFont100)", + fontWeightCustomFont200: "var(--fontWeightCustomFont200)", + fontWeightCustomFont300: "var(--fontWeightCustomFont300)", + fontWeightCustomFont400: "var(--fontWeightCustomFont400)", + fontWeightCustomFont500: "var(--fontWeightCustomFont500)", + fontWeightCustomFont600: "var(--fontWeightCustomFont600)", + fontWeightCustomFont700: "var(--fontWeightCustomFont700)", + fontWeightCustomFont800: "var(--fontWeightCustomFont800)", + fontWeightCustomFont900: "var(--fontWeightCustomFont900)", + fontWeightCustomFont1000: "var(--fontWeightCustomFont1000)", + fontWeightCustomFont1100: "var(--fontWeightCustomFont1100)", + fontWeightCustomFont1200: "var(--fontWeightCustomFont1200)", + fontWeightCustomFont1300: "var(--fontWeightCustomFont1300)", + fontWeightCustomFont1400: "var(--fontWeightCustomFont1400)", + fontWeightCustomFont1500: "var(--fontWeightCustomFont1500)", + fontWeightCustomFont1600: "var(--fontWeightCustomFont1600)", + fontWeightCustomFont1700: "var(--fontWeightCustomFont1700)", + + lineHeightBase450: "var(--lineHeightBase450)", + + borderRadius2XLarge: "var(--borderRadius2XLarge)", + borderRadius4XLarge: "var(--borderRadius4XLarge)", + colorNeutralStroke4: "var(--colorNeutralStroke4)", + colorNeutralStroke4Hover: "var(--colorNeutralStroke4Hover)", + colorNeutralStroke4Pressed: "var(--colorNeutralStroke4Pressed)", +}; diff --git a/packages/react-cap-theme/src/components/tokens/types.ts b/packages/react-cap-theme/src/components/tokens/types.ts new file mode 100644 index 00000000..44771117 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/types.ts @@ -0,0 +1,230 @@ +import type { + ColorTokens as BaseColorTokens, + FontFamilyTokens as BaseFontFamilyTokens, + FontSizeTokens as BaseFontSizeTokens, + FontWeightTokens as BaseFontWeightTokens, + LineHeightTokens as BaseLineHeightTokens, + Theme as BaseTheme, + TypographyStyle as BaseTypographyStyle, + TypographyStyles as BaseTypographyStyles, +} from "@fluentui/tokens"; + +export type Greys = + | 0 + | 2 + | 4 + | 6 + | 8 + | 10 + | 12 + | 14 + | 16 + | 18 + | 20 + | 22 + | 24 + | 26 + | 28 + | 30 + | 32 + | 34 + | 36 + | 38 + | 40 + | 42 + | 44 + | 46 + | 48 + | 50 + | 52 + | 54 + | 56 + | 58 + | 60 + | 62 + | 64 + | 66 + | 68 + | 70 + | 72 + | 74 + | 76 + | 78 + | 80 + | 82 + | 84 + | 86 + | 88 + | 90 + | 92 + | 94 + | 96 + | 98 + | 100; + +export type Font = + | 100 + | 200 + | 300 + | 400 + | 500 + | 600 + | 700 + | 800 + | 900 + | 1000 + | 1100 + | 1200 + | 1300 + | 1400 + | 1500 + | 1600 + | 1700; + +export type ColorTokens = BaseColorTokens & { + /* placeholder: may be used to create custom color tokens to support Theme v2 */ +}; + +export type FontSizeTokens = BaseFontSizeTokens & { + fontSizeBase450: string; +}; + +export type FontFamilyCustomFontTokens = Record< + `fontFamilyCustomFont${Font}`, + string +>; + +export type FontStyleTokens = { + fontStyleRegular: string; + fontStyleItalic: string; +}; + +export type FontWeightCustomFontTokens = Record< + `fontWeightCustomFont${Font}`, + number +>; + +export type LineHeightTokens = BaseLineHeightTokens & { + lineHeightBase450: string; +}; + +export type TypographyStyle = BaseTypographyStyle & { + fontStyle: string; + lineHeight: string; +}; + +export type TypographyStyles = BaseTypographyStyles & { + custom: CustomizableTypographyStyles; +}; + +export type CustomizableTypographyStyles = Record< + keyof BaseTypographyStyles, + TypographyStyle +> & { + body1Mono: TypographyStyle; + body2Italic: TypographyStyle; + body2Mono: TypographyStyle; + body3: TypographyStyle; + body3Strong: TypographyStyle; + buttonLarge: TypographyStyle; + buttonMedium: TypographyStyle; + buttonSmall: TypographyStyle; + subtitle1Italic: TypographyStyle; + webPartHeader: TypographyStyle; + heading2: TypographyStyle; + heading3: TypographyStyle; + heading4: TypographyStyle; +}; + +export type CustomizableTypographyStyle = { + fontFamily: string; + fontWeight?: number; +}; + +export type FontVariants = Record; + +export type FontFamilyTokens = BaseFontFamilyTokens & + Partial; + +export type FontWeightTokens = BaseFontWeightTokens & + Partial; + +export type FIXME_MISSING_TOKENS = { + borderRadius2XLarge: string; + borderRadius4XLarge: string; + colorNeutralStroke4: string; + colorNeutralStroke4Hover: string; + colorNeutralStroke4Pressed: string; +}; + +export const FIXME_MISSING_TOKENS_DEFAULTS: FIXME_MISSING_TOKENS = { + borderRadius2XLarge: "", + borderRadius4XLarge: "", + colorNeutralStroke4: "", + colorNeutralStroke4Hover: "", + colorNeutralStroke4Pressed: "", +}; + +export type Theme = BaseTheme & + ColorTokens & + FontFamilyTokens & + FontSizeTokens & + FontStyleTokens & + FontWeightTokens & + LineHeightTokens & + FIXME_MISSING_TOKENS; + +export type PartialTheme = Partial; + +export type TokenName = keyof Theme; + +export type { + BorderRadiusTokens, + Brands, + BrandVariants, + ColorPaletteAnchor, + ColorPaletteBeige, + ColorPaletteBerry, + ColorPaletteBlue, + ColorPaletteBrass, + ColorPaletteBrown, + ColorPaletteCornflower, + ColorPaletteCranberry, + ColorPaletteDarkGreen, + ColorPaletteDarkOrange, + ColorPaletteDarkRed, + ColorPaletteForest, + ColorPaletteGrape, + ColorPaletteGold, + ColorPaletteGreen, + ColorPaletteLavender, + ColorPaletteLilac, + ColorPaletteLightGreen, + ColorPaletteLightTeal, + ColorPaletteMagenta, + ColorPaletteMarigold, + ColorPaletteMink, + ColorPaletteNavy, + ColorPalettePeach, + ColorPalettePink, + ColorPalettePlatinum, + ColorPalettePlum, + ColorPalettePumpkin, + ColorPalettePurple, + ColorPaletteRed, + ColorPaletteRoyalBlue, + ColorPaletteSeafoam, + ColorPaletteSteel, + ColorPaletteTeal, + ColorPaletteTokens, + ColorPaletteYellow, + CurveTokens, + DurationTokens, + HorizontalSpacingTokens, + ShadowBrandTokens, + ShadowTokens, + SpacingTokens, + StrokeWidthTokens, + VerticalSpacingTokens, + ZIndexTokens, +} from "@fluentui/tokens"; diff --git a/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts b/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts new file mode 100644 index 00000000..b09875bb --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts @@ -0,0 +1,30 @@ +import type { Theme as FluentTheme } from "@fluentui/tokens"; +import { + generateFontFamilyTokens, + generateFontWeightTokens, +} from "../alias/fonts/index"; +import { fontSizes, fontStyles, lineHeights } from "../global/fonts"; +import { + FIXME_MISSING_TOKENS_DEFAULTS, + type FontFamilyCustomFontTokens, + type FontVariants, + type FontWeightCustomFontTokens, + type Theme, +} from "../types"; + +export const applyFonts = (theme: FluentTheme, font?: FontVariants): Theme => { + const fontFamilies: FontFamilyCustomFontTokens | undefined = + font && generateFontFamilyTokens(font); + const fontWeights: Partial | undefined = + font && generateFontWeightTokens(font); + + return { + ...FIXME_MISSING_TOKENS_DEFAULTS, + ...theme, + ...fontFamilies, + ...fontSizes, + ...fontStyles, + ...fontWeights, + ...lineHeights, + }; +}; diff --git a/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts b/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts new file mode 100644 index 00000000..08c22b43 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts @@ -0,0 +1,38 @@ +import type { BrandVariants, Theme as FluentTheme } from "@fluentui/tokens"; +import { createDarkTheme as createFluentDarkTheme } from "@fluentui/tokens"; +import { generateBrandColorTokens } from "../alias/colors/darkColor"; +import { + generateFontFamilyTokens, + generateFontWeightTokens, +} from "../alias/fonts"; +import { brandCAP } from "../global/brandColors"; +import { fontSizes, fontStyles, lineHeights } from "../global/fonts"; +import { + FIXME_MISSING_TOKENS_DEFAULTS, + type FontFamilyCustomFontTokens, + type FontVariants, + type FontWeightCustomFontTokens, + type Theme, +} from "../types"; + +export const createDarkTheme: ( + brand?: BrandVariants, + font?: FontVariants, +) => Theme = (brand = brandCAP, font) => { + const fluentTheme: FluentTheme = createFluentDarkTheme(brand); + const fontFamilies: FontFamilyCustomFontTokens | undefined = + font && generateFontFamilyTokens(font); + const fontWeights: Partial | undefined = + font && generateFontWeightTokens(font); + + return { + ...FIXME_MISSING_TOKENS_DEFAULTS, + ...fluentTheme, + ...fontFamilies, + ...fontSizes, + ...fontStyles, + ...fontWeights, + ...lineHeights, + ...generateBrandColorTokens(brand), + }; +}; diff --git a/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts b/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts new file mode 100644 index 00000000..0a51c284 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts @@ -0,0 +1,38 @@ +import type { BrandVariants, Theme as FluentTheme } from "@fluentui/tokens"; +import { createLightTheme as createFluentLightTheme } from "@fluentui/tokens"; +import { generateBrandColorTokens } from "../alias/colors/lightColor"; +import { + generateFontFamilyTokens, + generateFontWeightTokens, +} from "../alias/fonts"; +import { brandCAP } from "../global/brandColors"; +import { fontSizes, fontStyles, lineHeights } from "../global/fonts"; +import { + FIXME_MISSING_TOKENS_DEFAULTS, + type FontFamilyCustomFontTokens, + type FontVariants, + type FontWeightCustomFontTokens, + type Theme, +} from "../types"; + +export const createLightTheme: ( + brand?: BrandVariants, + font?: FontVariants, +) => Theme = (brand = brandCAP, font) => { + const fluentTheme: FluentTheme = createFluentLightTheme(brand); + const fontFamilies: FontFamilyCustomFontTokens | undefined = + font && generateFontFamilyTokens(font); + const fontWeights: Partial | undefined = + font && generateFontWeightTokens(font); + + return { + ...FIXME_MISSING_TOKENS_DEFAULTS, + ...fluentTheme, + ...fontFamilies, + ...fontSizes, + ...fontStyles, + ...fontWeights, + ...lineHeights, + ...generateBrandColorTokens(brand), + }; +}; diff --git a/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts b/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts new file mode 100644 index 00000000..8c76c785 --- /dev/null +++ b/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts @@ -0,0 +1,12 @@ +import type { PartialTheme } from "../types"; + +export const extractNeutralTokens = ( + theme: PartialTheme, +): { token: string; value: string }[] => { + return Object.entries(theme) + .filter( + ([key, value]) => + key.startsWith("colorNeutral") && typeof value === "string", + ) + .map(([key, value]) => ({ token: key, value: value as string })); +}; diff --git a/packages/react-cap-theme/src/index.ts b/packages/react-cap-theme/src/index.ts index d4b15be2..11f15be2 100644 --- a/packages/react-cap-theme/src/index.ts +++ b/packages/react-cap-theme/src/index.ts @@ -1,11 +1,38 @@ -export { CAPThemeProvider } from './theme/CAPThemeProvider'; +import { FluentProviderProps } from "@fluentui/react-components"; +import { + useButtonStyles, + useMenuButtonStyles, + useSplitButtonStyles, + useToggleButtonStyles, + type ButtonState, + type MenuButtonState, + type SplitButtonState, + type ToggleButtonState, +} from "./components/react-button"; + +export { getIntrinsicElementProps, slot } from "@fluentui/react-utilities"; export { - CAP_THEME_ONE_DRIVE, - CAP_THEME_SHAREPOINT, - CAP_THEME_TEAMS, -} from './theme/CAPTheme'; -export { Button } from './components/Button/Button'; -export type { - ButtonProps, - ButtonState, -} from './components/Button/Button.types'; + motionTokens, + makeStyles, + mergeClasses, +} from "@fluentui/react-components"; + +export * from "./components/react-button"; +export * from "./components/tokens"; + +export const CAP_STYLE_HOOKS: NonNullable< + FluentProviderProps["customStyleHooks_unstable"] +> = { + useButtonStyles_unstable: (state) => { + return useButtonStyles(state as ButtonState); + }, + useMenuButtonStyles_unstable: (state) => { + return useMenuButtonStyles(state as MenuButtonState); + }, + useSplitButtonStyles_unstable: (state) => { + return useSplitButtonStyles(state as SplitButtonState); + }, + useToggleButtonStyles_unstable: (state) => { + return useToggleButtonStyles(state as ToggleButtonState); + }, +}; diff --git a/packages/react-cap-theme/src/theme/CAPTheme.tsx b/packages/react-cap-theme/src/theme/CAPTheme.tsx deleted file mode 100644 index 049f2d54..00000000 --- a/packages/react-cap-theme/src/theme/CAPTheme.tsx +++ /dev/null @@ -1,302 +0,0 @@ -import { tokens } from '@fluentui/react-components'; - -type TokenType = 'color' | 'dimension' | 'shadow' | 'alignment'; - -export interface TokenSchema { - type: TokenType; -} - -type AllowedTokenName = - // This token does not exist in semantic tokens and is new to CAP. - | `cap/${string}` - // This token should exist in Fluent v9 (we expect it to be pushed upstream to fluent core). - | `fluent-ext/${string}` - // This token exists in semantic tokens v1 - | `smtc/v1/${string}` - // This token exists in semantic tokens v2 - | `smtc/v2/${string}` - // This token doesn't follow any known structure and needs to be fixed. - | `fixme/${string}`; - -/** - * @param varName - The token name (e.g., 'cap/badge-xl/padding') - * @returns The formatted CSS variable name (e.g., 'cap-badge-xl-padding') - * @remarks Temporarily using dashes instead of escaped slashes to avoid CSS escaping issues in Griffel. - * This is a workaround until the underlying Griffel issue is resolved. - */ -export function formatCAPTokenCssVar(varName: string): string { - return varName.replace(/\//g, '-'); -} - -/** - * FluentExtendedTokens are tokens that should exist in Fluent v9 but don't yet. - * We expect them to be pushed upstream to Fluent core, at which point you can swap them: - * - * ```ts - * // before - * borderRadius: CAP_TOKENS['fluent-ext/borderRadius2XLarge'] - * - * // after - * import { tokens } from '@fluentui/react-components'; - * borderRadius: tokens.borderRadius2XLarge - * ``` - */ -const FluentExtendedTokens = { - 'fluent-ext/borderRadius2XLarge': { type: 'dimension' }, - 'fluent-ext/borderRadius3XLarge': { type: 'dimension' }, - 'fluent-ext/borderRadius2XXLarge': { type: 'dimension' }, - // 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/brandForegroundCompound': { type: 'color' }, -} as const satisfies Record; - -/** - * ControlTokens are used across multiple components to control a particular aspect - * of the design system (e.g. border radii). - */ -const ControlTokens = { - 'smtc/v1/ctrl/corner/rest': { type: 'dimension' }, -} as const satisfies Record; - -const BadgeTokens = { - 'cap/badge-xl/corner-rounded': { type: 'dimension' }, - 'cap/badge-l/corner-rounded': { type: 'dimension' }, - 'cap/badge-xl/padding': { type: 'dimension' }, - 'cap/badge-l/padding': { type: 'dimension' }, - 'cap/badge-m/padding': { type: 'dimension' }, - 'cap/badge-s/padding': { type: 'dimension' }, - 'cap/badge-s/gap': { type: 'dimension' }, - 'cap/badge-s/gap-toSecondaryIcon': { type: 'dimension' }, - 'cap/badge/brand/outlined/stroke': { type: 'color' }, - 'cap/badge/brand/tint/foreground': { type: 'color' }, - 'cap/badge/brand/tint/iconColor': { type: 'color' }, - 'cap/badge/brand/ghost/foreground': { type: 'color' }, - 'cap/badge/brand/ghost/iconColor': { type: 'color' }, - 'cap/badge/danger/outlined/stroke': { type: 'color' }, - 'cap/badge/warning/filled/background': { type: 'color' }, - 'cap/badge/warning/filled/iconColor': { type: 'color' }, - 'cap/badge/warning/filled/foreground': { type: 'color' }, - 'cap/badge/warning/outlined/stroke': { type: 'color' }, - 'cap/badge/success/outlined/stroke': { type: 'color' }, - 'cap/badge/informative/outlined/stroke': { type: 'color' }, - 'cap/badge/informative/tint/background': { type: 'color' }, - 'cap/badge/informative/tint/stroke': { type: 'color' }, - 'cap/badge/important/filled/background': { type: 'color' }, - 'cap/badge/important/filled/foreground': { type: 'color' }, - 'cap/badge/important/filled/iconColor': { type: 'color' }, - 'cap/badge/important/outlined/stroke': { type: 'color' }, - 'cap/badge/important/tint/background': { type: 'color' }, - 'cap/badge/important/tint/foreground': { type: 'color' }, - 'cap/badge/important/tint/iconColor': { type: 'color' }, - 'cap/badge/important/tint/stroke': { type: 'color' }, - 'cap/badge/subtle/filled/background': { type: 'color' }, - 'cap/badge/subtle/filled/foreground': { type: 'color' }, - 'cap/badge/subtle/filled/iconColor': { type: 'color' }, - 'cap/badge/subtle/outlined/foreground': { type: 'color' }, - 'cap/badge/subtle/outlined/iconColor': { type: 'color' }, - 'cap/badge/subtle/tint/stroke': { type: 'color' }, -} as const satisfies Record; - -const ButtonTokens = { - 'fixme/ctrl/button/corner-radius': { type: 'dimension' }, - 'fixme/ctrl/button/primary-background-color': { type: 'color' }, - 'fixme/ctrl/button/primary-background-color-hover': { type: 'color' }, - 'fixme/ctrl/button/secondary-background-color': { type: 'color' }, - 'fixme/ctrl/button/secondary-background-color-hover': { type: 'color' }, - 'fixme/ctrl/button/subtle-background-color': { type: 'color' }, - 'fixme/ctrl/button/subtle-background-color-hover': { type: 'color' }, - 'fixme/ctrl/button/outline-background-color': { type: 'color' }, - 'fixme/ctrl/button/outline-background-color-hover': { type: 'color' }, - 'fixme/ctrl/button/tint-background-color': { type: 'color' }, - 'fixme/ctrl/button/tint-background-color-hover': { type: 'color' }, -} as const satisfies Record; - -const CardTokens = { - 'fixme/ctrl/card/background-color': { type: 'color' }, - 'fixme/ctrl/card/foreground-color': { type: 'color' }, - 'fixme/ctrl/card/background-color-hover': { type: 'color' }, - 'fixme/ctrl/card/foreground-color-hover': { type: 'color' }, - 'fixme/ctrl/card/background-color-pressed': { type: 'color' }, - 'fixme/ctrl/card/foreground-color-pressed': { type: 'color' }, - 'fixme/ctrl/card/background-color-disabled': { type: 'color' }, - 'fixme/ctrl/card/foreground-color-disabled': { type: 'color' }, - 'fixme/ctrl/card/corner-radius': { type: 'dimension' }, - 'fixme/ctrl/card/header-padding-outside': { type: 'dimension' }, - 'fixme/ctrl/card/header-padding-inside': { type: 'dimension' }, - 'fixme/ctrl/card/footer-horizontal-gap': { type: 'dimension' }, -} as const satisfies Record; - -const DialogTokens = { - 'cap/Dialog/Corner': { type: 'dimension' }, - 'cap/Dialog/Header/Gap': { type: 'dimension' }, - 'cap/Dialog/strokeWidth': { type: 'dimension' }, - 'cap/Dialog/strokeColor': { type: 'color' }, -} as const satisfies Record; - -const InputTokens = {} as const satisfies Record; - -const MenuTokens = {} as const satisfies Record; - -const TooltipTokens = {} as const satisfies Record< - AllowedTokenName, - 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; - -export const CAPTokensSchema = { - ...FluentExtendedTokens, - ...ControlTokens, - ...BadgeTokens, - ...ButtonTokens, - ...CardTokens, - ...DialogTokens, - ...InputTokens, - ...MenuTokens, - ...TooltipTokens, - ...DrawerTokens, -} as const satisfies { [key: AllowedTokenName]: TokenSchema }; - -export const CAP_TOKENS = Object.keys(CAPTokensSchema).reduce((acc, key) => { - return { ...acc, [key]: `var(--${formatCAPTokenCssVar(key)})` }; -}, {} as Record); - -export type CAPTheme = { - [k in keyof typeof CAP_TOKENS]: string | null; -}; - -export const CAP_THEME_DEFAULTS = { - // fluent-ext - 'fluent-ext/brandForegroundCompound': '#03787C', - 'fluent-ext/spacingHorizontalNone': '0px', - 'fluent-ext/borderRadius2XLarge': '12px', - 'fluent-ext/borderRadius3XLarge': '16px', - 'fluent-ext/borderRadius2XXLarge': '24px', - - // smtc/v1 - 'smtc/v1/ctrl/corner/rest': CAP_TOKENS['fluent-ext/borderRadius2XLarge'], - - // badge - 'cap/badge-xl/corner-rounded': tokens.borderRadiusXLarge, - 'cap/badge-l/corner-rounded': tokens.borderRadiusLarge, - 'cap/badge-xl/padding': tokens.spacingHorizontalS, - 'cap/badge-l/padding': tokens.spacingHorizontalSNudge, - 'cap/badge-m/padding': tokens.spacingHorizontalSNudge, - 'cap/badge-s/padding': tokens.spacingHorizontalXS, - 'cap/badge-s/gap': CAP_TOKENS['fluent-ext/spacingHorizontalNone'], - 'cap/badge-s/gap-toSecondaryIcon': - CAP_TOKENS['fluent-ext/spacingHorizontalNone'], - 'cap/badge/brand/outlined/stroke': tokens.colorBrandStroke2, - 'cap/badge/brand/tint/foreground': - CAP_TOKENS['fluent-ext/brandForegroundCompound'], - 'cap/badge/brand/tint/iconColor': - CAP_TOKENS['fluent-ext/brandForegroundCompound'], - 'cap/badge/brand/ghost/foreground': - CAP_TOKENS['fluent-ext/brandForegroundCompound'], - 'cap/badge/brand/ghost/iconColor': - CAP_TOKENS['fluent-ext/brandForegroundCompound'], - 'cap/badge/danger/outlined/stroke': tokens.colorStatusDangerBorder1, - 'cap/badge/warning/filled/background': tokens.colorStatusWarningBackground3, - 'cap/badge/warning/filled/iconColor': tokens.colorNeutralForegroundOnBrand, - 'cap/badge/warning/filled/foreground': tokens.colorNeutralForegroundOnBrand, - 'cap/badge/warning/outlined/stroke': tokens.colorStatusWarningBorder1, - 'cap/badge/success/outlined/stroke': tokens.colorStatusSuccessBorder1, - 'cap/badge/informative/outlined/stroke': tokens.colorNeutralStroke1, - 'cap/badge/informative/tint/background': tokens.colorNeutralBackground5, - 'cap/badge/informative/tint/stroke': tokens.colorNeutralStroke1, - 'cap/badge/important/filled/background': - tokens.colorNeutralBackgroundInverted, - 'cap/badge/important/filled/foreground': tokens.colorNeutralForegroundOnBrand, - 'cap/badge/important/filled/iconColor': tokens.colorNeutralForegroundOnBrand, - 'cap/badge/important/outlined/stroke': tokens.colorNeutralStroke1, - 'cap/badge/important/tint/background': tokens.colorNeutralBackground5, - 'cap/badge/important/tint/foreground': tokens.colorNeutralForeground3, - 'cap/badge/important/tint/iconColor': tokens.colorNeutralForeground3, - 'cap/badge/important/tint/stroke': tokens.colorNeutralStroke1, - 'cap/badge/subtle/filled/background': tokens.colorNeutralBackground5, - 'cap/badge/subtle/filled/foreground': tokens.colorNeutralForeground3, - 'cap/badge/subtle/filled/iconColor': tokens.colorNeutralForeground3, - 'cap/badge/subtle/outlined/foreground': tokens.colorNeutralForeground3, - 'cap/badge/subtle/outlined/iconColor': tokens.colorNeutralForeground3, - 'cap/badge/subtle/tint/stroke': tokens.colorNeutralStroke1, - - // dialog - 'cap/Dialog/Corner': CAP_TOKENS['fluent-ext/borderRadius2XXLarge'], - 'cap/Dialog/Header/Gap': tokens.spacingVerticalL, - 'cap/Dialog/strokeColor': tokens.colorNeutralStroke3, - // Note: the strokeWidthThin token was 1px and now it is also 1px, but defined here for clarity as it is in Diff section in figma - 'cap/Dialog/strokeWidth': tokens.strokeWidthThin, - - // button - 'fixme/ctrl/button/corner-radius': CAP_TOKENS['smtc/v1/ctrl/corner/rest'], - 'fixme/ctrl/button/primary-background-color': tokens.colorBrandBackground, - 'fixme/ctrl/button/primary-background-color-hover': - tokens.colorBrandBackgroundHover, - 'fixme/ctrl/button/secondary-background-color': null, - 'fixme/ctrl/button/secondary-background-color-hover': null, - 'fixme/ctrl/button/subtle-background-color': tokens.colorBrandBackground, - 'fixme/ctrl/button/subtle-background-color-hover': - tokens.colorBrandBackground, - 'fixme/ctrl/button/outline-background-color': - tokens.colorTransparentBackground, - 'fixme/ctrl/button/outline-background-color-hover': - tokens.colorTransparentBackground, - 'fixme/ctrl/button/tint-background-color': 'red', - 'fixme/ctrl/button/tint-background-color-hover': null, - - // card - 'fixme/ctrl/card/corner-radius': tokens.borderRadiusXLarge, // 8px - 'fixme/ctrl/card/background-color': tokens.colorNeutralBackground1, - 'fixme/ctrl/card/foreground-color': tokens.colorNeutralBackground1, - 'fixme/ctrl/card/background-color-hover': '', - 'fixme/ctrl/card/foreground-color-hover': '', - 'fixme/ctrl/card/background-color-pressed': '', - 'fixme/ctrl/card/foreground-color-pressed': '', - 'fixme/ctrl/card/background-color-disabled': '', - 'fixme/ctrl/card/foreground-color-disabled': '', - '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 = { - ...CAP_THEME_DEFAULTS, -} as const satisfies CAPTheme; - -export const CAP_THEME_ONE_DRIVE = { - ...CAP_THEME_DEFAULTS, -} as const satisfies CAPTheme; - -export const CAP_THEME_SHAREPOINT = { - ...CAP_THEME_DEFAULTS, -} as const satisfies CAPTheme; diff --git a/packages/react-cap-theme/src/theme/CAPThemeProvider.tsx b/packages/react-cap-theme/src/theme/CAPThemeProvider.tsx deleted file mode 100644 index f82b45e0..00000000 --- a/packages/react-cap-theme/src/theme/CAPThemeProvider.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import * as React from 'react'; -import { - BadgeState, - ButtonState, - CardFooterState, - CardHeaderState, - CardState, - DialogBodyState, - DialogSurfaceState, - DrawerBodyState, - DrawerFooterState, - DrawerHeaderNavigationState, - DrawerHeaderState, - DrawerHeaderTitleState, - DrawerState, - FluentProvider, - FluentProviderProps, - InputState, - InlineDrawerState, - OverlayDrawerState, - type Theme, -} from '@fluentui/react-components'; - -import { useButtonStylesHook } from '../components/Button/Button.styles'; -import { CAPTheme, formatCAPTokenCssVar } from './CAPTheme'; -import { useBadgeStylesHook } from '../components/Badge/Badge.styles'; -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 { useDialogBodyStylesHook } from '../components/Dialog/DialogBody.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'; -import { useDialogSurfaceStylesHook } from '../components/Dialog/DialogSurface.styles'; - -const customStyleHooks: NonNullable< - FluentProviderProps['customStyleHooks_unstable'] -> = { - useBadgeStyles_unstable: (state) => useBadgeStylesHook(state as BadgeState), - useButtonStyles_unstable: (state) => - useButtonStylesHook(state as ButtonState), - useCardStyles_unstable: (state) => useCardStylesHook(state as CardState), - useCardHeaderStyles_unstable: (state) => - useCardHeaderStylesHook(state as CardHeaderState), - useCardFooterStyles_unstable: (state) => - useCardFooterStylesHook(state as CardFooterState), - useDialogBodyStyles_unstable: (state) => - useDialogBodyStylesHook(state as DialogBodyState), - useDialogSurfaceStyles_unstable: (state) => - useDialogSurfaceStylesHook(state as DialogSurfaceState), - 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), -}; - -type CAPThemeProviderProps = Omit< - FluentProviderProps, - 'theme' | 'customStyleHooks_unstable' -> & { - theme: Partial & Partial; -}; -export const CAPThemeProvider = ({ - children, - theme: _theme, - ...rest -}: CAPThemeProviderProps): React.ReactElement => { - const theme: Record = {}; - for (const [key, value] of Object.entries(_theme)) { - theme[formatCAPTokenCssVar(key)] = value; - } - return ( - - {children} - - ); -}; diff --git a/packages/react-cap-theme/stories/.gitkeep b/packages/react-cap-theme/stories/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/packages/react-cap-theme/stories/StorybookUtils.tsx b/packages/react-cap-theme/stories/StorybookUtils.tsx deleted file mode 100644 index 786ee2c0..00000000 --- a/packages/react-cap-theme/stories/StorybookUtils.tsx +++ /dev/null @@ -1,250 +0,0 @@ -import * as React from 'react'; -import { - FluentProvider, - makeStyles, - teamsLightV21Theme, -} from '@fluentui/react-components'; -import { - CAPThemeProvider, - CAP_THEME_ONE_DRIVE, - CAP_THEME_SHAREPOINT, - CAP_THEME_TEAMS, -} from '@fluentui-contrib/react-cap-theme'; - -export interface CAPThemeExample { - title?: string; - render(variant: 'v9' | 'cap'): React.ReactElement | 'NOT_IMPLEMENTED'; - note?: string; -} - -const CAP_THEMES = { - current: { - label: 'Current', - variant: 'v9' as const, - theme: null, - wrap: (children: React.ReactNode) => <>{children}, - }, - teams: { - label: 'CAP (Teams)', - variant: 'cap' as const, - theme: { ...teamsLightV21Theme, ...CAP_THEME_TEAMS }, - wrap: (children: React.ReactNode) => ( - - {children} - - ), - }, - onedrive: { - label: 'CAP (OneDrive)', - variant: 'cap' as const, - theme: CAP_THEME_ONE_DRIVE, - wrap: (children: React.ReactNode) => ( - - {children} - - ), - }, - sharepoint: { - label: 'CAP (SharePoint)', - variant: 'cap' as const, - theme: CAP_THEME_SHAREPOINT, - wrap: (children: React.ReactNode) => ( - - {children} - - ), - }, -} as const; - -type CAPThemeKey = keyof typeof CAP_THEMES; -type CAPThemeSelection = (typeof CAP_THEMES)[CAPThemeKey]; - -const CAPThemeSelectionContext = React.createContext( - CAP_THEMES.current -); - -export const CAPThemeSelectionProvider = ({ - themeKey, - children, -}: { - themeKey: CAPThemeKey; - children: React.ReactNode; -}) => { - const selection = CAP_THEMES[themeKey] ?? CAP_THEMES.current; - return ( - - {children} - - ); -}; - -export const useCAPThemeSelection = () => - React.useContext(CAPThemeSelectionContext); - -// Single column view that shows only the selected theme -export const CAPThemeExamples = ({ - examples, -}: { - examples: CAPThemeExample[]; -}) => { - const styles = useCAPThemeExamplesStyles(); - const selectedTheme = useCAPThemeSelection(); - - return selectedTheme.wrap( -
-
Showing: {selectedTheme.label}
- {examples.map((example) => ( -
- {example.title && ( -
{example.title}
- )} -
- {renderExample(example, selectedTheme.variant)} -
- {example.note &&
{example.note}
} -
- ))} -
- ); -}; - -// Table view that shows Current + all three CAP themes side by side -export const CAPThemeExamplesTable = ({ - examples, -}: { - examples: CAPThemeExample[]; -}) => { - const styles = useCAPThemeExamplesTableStyles(); - const selectedTheme = useCAPThemeSelection(); - - // Map the selected theme label to our theme config - const getSelectedThemeConfig = () => { - if (selectedTheme.label === 'CAP (Teams)') return CAP_THEMES.teams; - if (selectedTheme.label === 'CAP (OneDrive)') return CAP_THEMES.onedrive; - if (selectedTheme.label === 'CAP (SharePoint)') - return CAP_THEMES.sharepoint; - return CAP_THEMES.current; - }; - - const selectedConfig = getSelectedThemeConfig(); - const themesToShow = [ - selectedConfig, - CAP_THEMES.teams, - - // We intentionally don't show these other themes in the side-by-side comparison tables. - // They currently look exactly the same as the Teams theme, so they eat up horizontal - // space without adding any value. - // CAP_THEMES.onedrive, - // CAP_THEMES.sharepoint, - ]; - - return ( - -
-
-
Example
- {themesToShow.map((config, idx) => ( -
- {idx === 0 ? 'Current' : config.label} -
- ))} -
Note
-
- {examples.map((example, index) => { - return ( -
-
{example.title}
- {themesToShow.map((config, idx) => ( -
- {config.theme ? ( - - {renderExample(example, config.variant)} - - ) : ( - renderExample(example, config.variant) - )} -
- ))} -
- {example.note && ( - - {example.note} - - )} -
-
- ); - })} -
-
- ); -}; - -function renderExample(example: CAPThemeExample, variant: 'v9' | 'cap') { - const result = example.render(variant); - if (result === 'NOT_IMPLEMENTED') { - return NOT IMPLEMENTED; - } - return result; -} - -const useCAPThemeExamplesStyles = makeStyles({ - table: { - display: 'flex', - flexDirection: 'column', - gap: '12px', - }, - themeLabel: { - fontWeight: 700, - padding: '8px 0', - }, - row: { - display: 'flex', - alignItems: 'center', - gap: '16px', - padding: '12px 16px', - border: '1px solid #ddd', - borderRadius: '8px', - backgroundColor: 'white', - }, - example: { - minWidth: '200px', - fontWeight: 600, - }, - note: { - minWidth: '200px', - fontWeight: 600, - }, - rendered: { - flex: 1, - '& > div': { - width: 'fit-content', - }, - }, -}); - -const useCAPThemeExamplesTableStyles = makeStyles({ - table: { - display: 'flex', - flexDirection: 'column', - }, - row: { - display: 'flex', - '& > div': { - flex: 2, - padding: '16px', - border: '1px solid #ddd', - }, - '& > div:first-child': { - flex: 1, - }, - '& > div:last-child': { - flex: 1, - }, - }, - noteColumn: { - flex: 1, - padding: '16px', - border: '1px solid #ddd', - }, -}); diff --git a/packages/react-cap-theme/stories/components/Badge/WithControls.stories.tsx b/packages/react-cap-theme/stories/components/Badge/WithControls.stories.tsx deleted file mode 100644 index 9526acd8..00000000 --- a/packages/react-cap-theme/stories/components/Badge/WithControls.stories.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import * as React from 'react'; -import { Badge, BadgeProps } from '@fluentui/react-components'; -import { CAPThemeExamples } from '../../StorybookUtils'; -import { CircleRegular } from '@fluentui/react-icons'; - -const badgeAppearances = ['outline', 'filled', 'ghost', 'tint'] as const; - -const badgeSizes = [ - 'tiny', - 'extra-small', - 'small', - 'medium', - 'large', - 'extra-large', -] as const; - -export const CAPBadgeWithCtrlsStory = ({ - color, - iconPosition, - shape, -}: { - color: BadgeProps['color']; - iconPosition: BadgeProps['iconPosition']; - shape: BadgeProps['shape']; -}) => { - return ( - - {/* Header row */} -
- {badgeAppearances.map((appearance) => ( -
- {appearance} -
- ))} -
- Icon Only / Filled -
- - {/* Data rows */} - {badgeSizes.map((size) => { - return ( - -
- {size} -
- {badgeAppearances.map((appearance) => ( -
- {size === 'tiny' || size === 'extra-small' ? ( - } - /> - ) : ( - } - > - badge - - )} -
- ))} -
- } - /> -
-
- ); - })} - - ); - }, - }, - ]} - /> - ); -}; - -CAPBadgeWithCtrlsStory.argTypes = { - color: { - options: [ - 'neutral', - 'brand', - 'strong', - 'important', - 'severe', - 'warning', - 'success', - 'informative', - ], - control: { type: 'radio' }, - }, - iconPosition: { - options: ['before', 'after'], - control: { type: 'radio' }, - }, - shape: { - options: ['rounded', 'circular', 'square'], - control: { type: 'radio' }, - }, -}; - -CAPBadgeWithCtrlsStory.args = { - color: 'brand', - iconPosition: 'before', - shape: 'rounded', -}; diff --git a/packages/react-cap-theme/stories/components/Badge/WithTable.stories.tsx b/packages/react-cap-theme/stories/components/Badge/WithTable.stories.tsx deleted file mode 100644 index 70c5cb5f..00000000 --- a/packages/react-cap-theme/stories/components/Badge/WithTable.stories.tsx +++ /dev/null @@ -1,431 +0,0 @@ -import * as React from 'react'; -import { Badge } from '@fluentui/react-components'; -import { CAPThemeExamplesTable } from '../../StorybookUtils'; -import { CircleRegular } from '@fluentui/react-icons'; - -export const CAPBadgeStory = () => { - return ( - } />; - }, - }, - { - title: 'Extra Small', - render() { - return } />; - }, - }, - { - title: 'Small', - render() { - return ( - }> - Badge - - ); - }, - }, - { - title: 'Default/Medium', - render() { - return }> Badge; - }, - }, - { - title: 'Medium No Icon', - render() { - return Badge; - }, - }, - { - title: 'Large', - render() { - return ( - }> - Badge - - ); - }, - }, - { - title: 'Extra Large', - render() { - return ( - }> - Badge - - ); - }, - }, - { - title: 'Tiny Square', - render() { - return ( - } shape="square" /> - ); - }, - }, - { - title: 'Extra Small Square', - render() { - return ( - } - shape="square" - /> - ); - }, - }, - { - title: 'Small Square', - render() { - return ( - } shape="square"> - Badge - - ); - }, - }, - { - title: 'Default/Medium Square', - render() { - return ( - } shape="square"> - {' '} - Badge - - ); - }, - }, - { - title: 'Medium No Icon Square', - render() { - return Badge; - }, - }, - { - title: 'Large Square', - render() { - return ( - } shape="square"> - Badge - - ); - }, - }, - { - title: 'Extra Large Square', - render() { - return ( - } shape="square"> - Badge - - ); - }, - }, - { - title: 'Tiny Rounded', - render() { - return ( - } shape="rounded" /> - ); - }, - }, - { - title: 'Extra Small Rounded ', - render() { - return ( - } - shape="rounded" - /> - ); - }, - }, - { - title: 'Small Rounded', - render() { - return ( - } shape="rounded"> - Badge - - ); - }, - }, - { - title: 'Default/Medium Rounded', - render() { - return ( - } shape="rounded"> - {' '} - Badge - - ); - }, - }, - { - title: 'Medium No Icon Rounded', - render() { - return Badge; - }, - }, - { - title: 'Large Rounded', - render() { - return ( - } shape="rounded"> - Badge - - ); - }, - }, - { - title: 'Extra Large Rounded', - render() { - return ( - } - shape="rounded" - > - Badge - - ); - }, - }, - { - title: 'Outline / Important', - render() { - return ( - } - color="important" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Brand', - render() { - return ( - } - color="brand" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Danger', - render() { - return ( - } - color="danger" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Warning', - render() { - return ( - } - color="warning" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Success', - render() { - return ( - } - color="success" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Informative', - render() { - return ( - } - color="informative" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Subtle', - render() { - return ( - } - color="subtle" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Outline / Severe', - render() { - return ( - } - color="severe" - appearance="outline" - > - Badge - - ); - }, - }, - { - title: 'Brand / Tint', - render() { - return ( - } color="brand" appearance="tint"> - Badge - - ); - }, - }, - { - title: 'Brand / Ghost', - render() { - return ( - } color="brand" appearance="ghost"> - Badge - - ); - }, - }, - { - title: 'Warning / Filled', - render() { - return ( - } - color="warning" - appearance="filled" - > - Badge - - ); - }, - }, - { - title: 'Informative / Tint', - render() { - return ( - } - color="informative" - appearance="tint" - > - Badge - - ); - }, - }, - { - title: 'Important / Filled', - render() { - return ( - } - color="important" - appearance="filled" - > - Badge - - ); - }, - }, - { - title: 'Important / Tint', - render() { - return ( - } - color="important" - appearance="tint" - > - Badge - - ); - }, - }, - { - title: 'Subtle / Filled', - render() { - return ( - } - color="subtle" - appearance="filled" - > - Badge - - ); - }, - }, - { - title: 'Subtle / Tint', - render() { - return ( - } color="subtle" appearance="tint"> - Badge - - ); - }, - }, - { - title: 'Small Icon only badge', - render() { - return ( - } - /> - ); - }, - }, - ]} - /> - ); -}; diff --git a/packages/react-cap-theme/stories/components/Button.stories.tsx b/packages/react-cap-theme/stories/components/Button.stories.tsx deleted file mode 100644 index 4894530c..00000000 --- a/packages/react-cap-theme/stories/components/Button.stories.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import * as React from 'react'; -import { Button, type ButtonProps } from '@fluentui-contrib/react-cap-theme'; -import { CAPThemeExamples, useCAPThemeSelection } from '../StorybookUtils'; -import { - bundleIcon, - CalendarMonthFilled, - CalendarMonthRegular, -} from '@fluentui/react-icons'; - -const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); - -const buttonAppearances = [ - 'secondary', - 'primary', - 'outline', - 'subtle', - 'transparent', -] as const; - -type ButtonState = 'default' | 'hover' | 'active' | 'focus' | 'disabled'; - -const stateId = ( - appearance: (typeof buttonAppearances)[number], - state: ButtonState -) => `cap-button-${appearance}-${state}`; - -const hoverSelectors = buttonAppearances.map( - (appearance) => `#${stateId(appearance, 'hover')}` -); -const activeSelectors = buttonAppearances.map( - (appearance) => `#${stateId(appearance, 'active')}` -); -const focusSelectors = buttonAppearances.map( - (appearance) => `#${stateId(appearance, 'focus')}` -); - -export const CAPButtonWithCtrlsStory = ({ - disabledFocusable = false, - iconPosition = 'before', - shape = 'rounded', - size = 'medium', -}: ButtonProps) => { - const selectedTheme = useCAPThemeSelection(); - const commonButtonProps: ButtonProps = { - iconPosition, - shape, - size, - }; - - React.useEffect(() => { - // Force pseudo-state classes back onto the demo buttons whenever the story re-renders for a new theme or arg change. - const doc = globalThis?.document; - if (!doc) { - return; - } - - buttonAppearances.forEach((appearance) => { - const hoverButton = doc.getElementById(stateId(appearance, 'hover')); - hoverButton?.classList.add('pseudo-hover'); - - const activeButton = doc.getElementById(stateId(appearance, 'active')); - activeButton?.classList.add('pseudo-hover', 'pseudo-active'); - - const focusButton = doc.getElementById(stateId(appearance, 'focus')); - if (focusButton) { - focusButton.classList.add('pseudo-focus-visible'); - focusButton.setAttribute('data-fui-focus-visible', 'true'); - } - }); - }, [selectedTheme, iconPosition, shape, size, disabledFocusable]); - - return ( - - {buttonAppearances.map((appearance) => { - return ( -
-
- {appearance} -
- - - - - -
- ); - })} - - ); - }, - }, - ]} - /> - ); -}; - -CAPButtonWithCtrlsStory.parameters = { - pseudo: { - // Keep pressed buttons hovered too since older Button styles rely on :hover:active - hover: [...hoverSelectors, ...activeSelectors], - active: activeSelectors, - focusVisible: focusSelectors, - }, -}; - -CAPButtonWithCtrlsStory.argTypes = { - disabledFocusable: { - control: false, - table: { disable: true }, - }, - iconPosition: { - options: ['before', 'after'], - control: { type: 'radio' }, - }, - shape: { - options: ['rounded', 'circular', 'square'], - control: { type: 'radio' }, - }, - size: { - options: ['small', 'medium', 'large'], - control: { type: 'radio' }, - }, -}; - -CAPButtonWithCtrlsStory.args = { - disabledFocusable: false, - iconPosition: 'before', - shape: 'rounded', - size: 'medium', -}; diff --git a/packages/react-cap-theme/stories/components/Card.stories.tsx b/packages/react-cap-theme/stories/components/Card.stories.tsx deleted file mode 100644 index 3cb9f6fd..00000000 --- a/packages/react-cap-theme/stories/components/Card.stories.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import * as React from 'react'; -import { - Button, - Caption1, - Card, - CardHeader, - Text, -} from '@fluentui/react-components'; -import { CAPThemeExamplesTable } from '../StorybookUtils'; -import { MoreHorizontal20Regular } from '@fluentui/react-icons'; - -export const CAPCardStory = () => { - return ( - - - App Name - - } - description={Developer} - action={ - - - - - Dialog title - Dialog Content goes here. - - - - - - - - - - ), - }, - ]} - /> - ); -}; - -CAPDialogWithCtrlsStory.argTypes = { - modalType: { - options: ['modal', 'non-modal', 'alert'], - control: { type: 'radio' }, - }, -}; - -CAPDialogWithCtrlsStory.args = { - modalType: 'modal', -}; diff --git a/packages/react-cap-theme/stories/components/Dialog/WithTable.tsx b/packages/react-cap-theme/stories/components/Dialog/WithTable.tsx deleted file mode 100644 index 57fc7778..00000000 --- a/packages/react-cap-theme/stories/components/Dialog/WithTable.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import * as React from 'react'; -import { - Dialog, - DialogTrigger, - DialogSurface, - DialogTitle, - DialogBody, - DialogActions, - DialogContent, - Button, -} from '@fluentui/react-components'; -import { CAPThemeExamplesTable } from '../../StorybookUtils'; - -export const CAPDialogStory = () => { - return ( - - Dialog title - - This shows the Dialogbody component used standalone, without - the Dialog wrapper or overlay. To see the border radius and - border color change, use the next row to open a full Dialog. - - - - - - - - - ); - }, - }, - { - title: 'Regular modal Dialog', - render() { - return ( - - - - - - - Modal dialog title - - This is a regular modal dialog. When this type of dialog - is open, the rest of the page is dimmed out and cannot be - interacted with. * The tab sequence is kept within the - dialog and moving the focus outside * the dialog will - imply closing it. This is the default type of the - component. - - - - - - - - - - - ); - }, - }, - ]} - /> - ); -}; diff --git a/packages/react-cap-theme/stories/components/Drawer.stories.tsx b/packages/react-cap-theme/stories/components/Drawer.stories.tsx deleted file mode 100644 index 78977bbc..00000000 --- a/packages/react-cap-theme/stories/components/Drawer.stories.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import * as React from 'react'; -import { - Button, - Drawer, - DrawerBody, - DrawerFooter, - DrawerHeader, - DrawerHeaderTitle, - DrawerProps, -} from '@fluentui/react-components'; -import { DismissRegular } from '@fluentui/react-icons'; -import { CAPThemeExamples } from '../StorybookUtils'; - -const drawerBodyText = [ - 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Doloribus nam aut amet similique, iure vel voluptates cum cumque repellendus perferendis maiores officia unde in?', - 'Autem neque sequi maiores eum omnis. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Perspiciatis ipsam explicabo tempora ipsum saepe nam.', - 'Eum aliquid aperiam, laborum labore excepturi nisi odio deserunt facilis error. Mollitia dolor quidem a.', -].join(' '); - -const DrawerContent = ({ onClose }: { onClose: () => void }) => ( - <> - - } - onClick={onClose} - /> - } - > - Title goes here - - - - {drawerBodyText} - - - - - - -); - -const PositionExample = ({ - size, - position, -}: { - size: DrawerProps['size']; - position: DrawerProps['position']; -}) => { - const [isOpen, setIsOpen] = React.useState(false); - - return ( -
- - - setIsOpen(open)} - > - setIsOpen(false)} /> - -
- ); -}; - -export const CAPDrawerWithCtrlsStory = ({ - size, - position, -}: { - size: DrawerProps['size']; - position: DrawerProps['position']; -}) => { - return ( - , - }, - ]} - /> - ); -}; - -CAPDrawerWithCtrlsStory.argTypes = { - size: { - options: ['small', 'medium', 'large', 'full'], - control: { type: 'radio' }, - }, - position: { - options: ['start', 'end', 'bottom'], - control: { type: 'radio' }, - }, -}; - -CAPDrawerWithCtrlsStory.args = { - size: 'small', - position: 'end', -}; diff --git a/packages/react-cap-theme/stories/components/Input.stories.tsx b/packages/react-cap-theme/stories/components/Input.stories.tsx deleted file mode 100644 index 7d39b99a..00000000 --- a/packages/react-cap-theme/stories/components/Input.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import * as React from 'react'; -import { Input } from '@fluentui/react-components'; -import { CAPThemeExamplesTable } from '../StorybookUtils'; - -export const CAPInputStory = () => { - return ( - ; - }, - }, - ]} - /> - ); -}; diff --git a/packages/react-cap-theme/stories/components/Menu.stories.tsx b/packages/react-cap-theme/stories/components/Menu.stories.tsx deleted file mode 100644 index c476434e..00000000 --- a/packages/react-cap-theme/stories/components/Menu.stories.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from 'react'; -import { CAPThemeExamplesTable } from '../StorybookUtils'; - -export const CAPMenuStory = () => { - return ; -}; diff --git a/packages/react-cap-theme/stories/components/Tooltip.stories.tsx b/packages/react-cap-theme/stories/components/Tooltip.stories.tsx deleted file mode 100644 index 64f5418a..00000000 --- a/packages/react-cap-theme/stories/components/Tooltip.stories.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from 'react'; -import { CAPThemeExamplesTable } from '../StorybookUtils'; - -export const CAPTooltipStory = () => { - return ; -}; diff --git a/packages/react-cap-theme/stories/index.stories.tsx b/packages/react-cap-theme/stories/index.stories.tsx deleted file mode 100644 index e17a91d8..00000000 --- a/packages/react-cap-theme/stories/index.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import { Meta } from '@storybook/react'; - -export { CAPBadgeStory as Badge } from './components/Badge/WithTable.stories'; -export { CAPBadgeWithCtrlsStory as BadgeWithControls } from './components/Badge/WithControls.stories'; -export { CAPButtonWithCtrlsStory as ButtonWithControls } from './components/Button.stories'; -export { CAPCardStory as Card } from './components/Card.stories'; -export { CAPDialogStory as Dialog } from './components/Dialog/WithTable'; -export { CAPDialogWithCtrlsStory as DialogWithControls } from './components/Dialog/WithControls.stories'; -export { CAPDrawerWithCtrlsStory as DrawerWithControls } from './components/Drawer.stories'; -export { CAPInputStory as Input } from './components/Input.stories'; -export { CAPMenuStory as Menu } from './components/Menu.stories'; -export { CAPTooltipStory as Tooltip } from './components/Tooltip.stories'; - -const DefaultStory = () =>
; - -export default { - title: 'Components/CAP', - component: DefaultStory, - parameters: {}, -} as Meta; diff --git a/packages/react-cap-theme/tsconfig.json b/packages/react-cap-theme/tsconfig.json index 15d0c1ca..7747dab4 100644 --- a/packages/react-cap-theme/tsconfig.json +++ b/packages/react-cap-theme/tsconfig.json @@ -2,7 +2,17 @@ "extends": "../../tsconfig.base.json", "files": [], "compilerOptions": { - "jsx": "react" + "jsx": "react-jsx", + "allowSyntheticDefaultImports": false, + "baseUrl": ".", + "paths": { + "@fluentui-contrib/react-cap-theme/react-icons": [ + "src/components/react-icons/index.ts" + ], + "@fluentui-contrib/react-cap-theme/*": [ + "src/components/*" + ] + } }, "include": [], "references": [ From 755df765d1f7bc987f4db9244ab0505435f67499 Mon Sep 17 00:00:00 2001 From: David Zukowski Date: Mon, 9 Mar 2026 21:06:59 -0700 Subject: [PATCH 2/3] react-cap-theme: format + eslint --fix --- packages/react-cap-theme/eslint.config.js | 13 +- .../src/components/react-button/Button.ts | 22 +- .../src/components/react-button/MenuButton.ts | 20 +- .../components/react-button/SplitButton.ts | 20 +- .../components/react-button/ToggleButton.ts | 18 +- .../react-button/components/Button/Button.tsx | 32 +- .../components/Button/Button.types.ts | 42 +- .../components/Button/Button.utils.ts | 40 +- .../components/Button/renderButton.tsx | 16 +- .../components/Button/useButton.ts | 20 +- .../Button/useButtonStyles.styles.ts | 493 +++++++++--------- .../components/MenuButton/MenuButton.tsx | 32 +- .../components/MenuButton/MenuButton.types.ts | 12 +- .../MenuButton/renderMenuButton.tsx | 16 +- .../components/MenuButton/useMenuButton.ts | 30 +- .../MenuButton/useMenuButtonStyles.styles.ts | 94 ++-- .../components/SplitButton/SplitButton.tsx | 26 +- .../SplitButton/SplitButton.types.ts | 32 +- .../SplitButton/renderSplitButton.tsx | 21 +- .../components/SplitButton/useSplitButton.ts | 149 +++--- .../useSplitButtonStyles.styles.ts | 448 ++++++++-------- .../components/ToggleButton/ToggleButton.tsx | 44 +- .../ToggleButton/ToggleButton.types.ts | 8 +- .../ToggleButton/renderToggleButton.tsx | 8 +- .../ToggleButton/useToggleButton.ts | 18 +- .../useToggleButtonStyles.styles.ts | 230 ++++---- .../src/components/react-button/index.ts | 76 +-- .../tokens/alias/colors/darkColor.ts | 90 ++-- .../tokens/alias/colors/lightColor.ts | 96 ++-- .../tokens/alias/fonts/fontFamily.ts | 38 +- .../tokens/alias/fonts/fontWeight.ts | 30 +- .../components/tokens/alias/fonts/index.ts | 4 +- .../components/tokens/global/brandColors.ts | 34 +- .../src/components/tokens/global/fonts.ts | 20 +- .../components/tokens/global/neutralColors.ts | 108 ++-- .../tokens/global/typographyStyles.ts | 282 +++++----- .../src/components/tokens/index.ts | 155 +++--- .../components/tokens/themeToTokensObject.ts | 2 +- .../src/components/tokens/themes/darkTheme.ts | 6 +- .../components/tokens/themes/lightTheme.ts | 6 +- .../src/components/tokens/tokens.ts | 92 ++-- .../src/components/tokens/types.ts | 348 ++++++------- .../src/components/tokens/utils/applyFonts.ts | 48 +- .../tokens/utils/createDarkTheme.ts | 62 +-- .../tokens/utils/createLightTheme.ts | 62 +-- .../tokens/utils/extractNeutralTokens.ts | 16 +- packages/react-cap-theme/src/index.ts | 176 +++++-- packages/react-cap-theme/tsconfig.json | 4 +- 48 files changed, 1882 insertions(+), 1777 deletions(-) diff --git a/packages/react-cap-theme/eslint.config.js b/packages/react-cap-theme/eslint.config.js index dfcfe4b6..5ea41166 100644 --- a/packages/react-cap-theme/eslint.config.js +++ b/packages/react-cap-theme/eslint.config.js @@ -13,12 +13,9 @@ module.exports = [ rules: {}, }, { - "files": [ - "**/*.ts", - "**/*.tsx" - ], - "rules": { - "@nx/enforce-module-boundaries": "off" - } -}, + files: ['**/*.ts', '**/*.tsx'], + rules: { + '@nx/enforce-module-boundaries': 'off', + }, + }, ]; diff --git a/packages/react-cap-theme/src/components/react-button/Button.ts b/packages/react-cap-theme/src/components/react-button/Button.ts index 8294438e..b11788d2 100644 --- a/packages/react-cap-theme/src/components/react-button/Button.ts +++ b/packages/react-cap-theme/src/components/react-button/Button.ts @@ -1,13 +1,13 @@ -export { Button } from "./components/Button/Button"; -export { renderButton } from "./components/Button/renderButton"; -export { useButton } from "./components/Button/useButton"; +export { Button } from './components/Button/Button'; +export { renderButton } from './components/Button/renderButton'; +export { useButton } from './components/Button/useButton'; export { - buttonClassNames, - useButtonStyles, -} from "./components/Button/useButtonStyles.styles"; + buttonClassNames, + useButtonStyles, +} from './components/Button/useButtonStyles.styles'; export type { - ButtonProps, - ButtonSlots, - ButtonState, - ButtonAppearance, -} from "./components/Button/Button.types"; + ButtonProps, + ButtonSlots, + ButtonState, + ButtonAppearance, +} from './components/Button/Button.types'; diff --git a/packages/react-cap-theme/src/components/react-button/MenuButton.ts b/packages/react-cap-theme/src/components/react-button/MenuButton.ts index 53f900f1..08de201c 100644 --- a/packages/react-cap-theme/src/components/react-button/MenuButton.ts +++ b/packages/react-cap-theme/src/components/react-button/MenuButton.ts @@ -1,12 +1,12 @@ -export { MenuButton } from "./components/MenuButton/MenuButton"; -export { renderMenuButton } from "./components/MenuButton/renderMenuButton"; -export { useMenuButton } from "./components/MenuButton/useMenuButton"; +export { MenuButton } from './components/MenuButton/MenuButton'; +export { renderMenuButton } from './components/MenuButton/renderMenuButton'; +export { useMenuButton } from './components/MenuButton/useMenuButton'; export { - menuButtonClassNames, - useMenuButtonStyles, -} from "./components/MenuButton/useMenuButtonStyles.styles"; + menuButtonClassNames, + useMenuButtonStyles, +} from './components/MenuButton/useMenuButtonStyles.styles'; export type { - MenuButtonProps, - MenuButtonSlots, - MenuButtonState, -} from "./components/MenuButton/MenuButton.types"; + MenuButtonProps, + MenuButtonSlots, + MenuButtonState, +} from './components/MenuButton/MenuButton.types'; diff --git a/packages/react-cap-theme/src/components/react-button/SplitButton.ts b/packages/react-cap-theme/src/components/react-button/SplitButton.ts index d1be00f8..9973ef64 100644 --- a/packages/react-cap-theme/src/components/react-button/SplitButton.ts +++ b/packages/react-cap-theme/src/components/react-button/SplitButton.ts @@ -1,12 +1,12 @@ -export { SplitButton } from "./components/SplitButton/SplitButton"; -export { renderSplitButton } from "./components/SplitButton/renderSplitButton"; -export { useSplitButton } from "./components/SplitButton/useSplitButton"; +export { SplitButton } from './components/SplitButton/SplitButton'; +export { renderSplitButton } from './components/SplitButton/renderSplitButton'; +export { useSplitButton } from './components/SplitButton/useSplitButton'; export { - splitButtonClassNames, - useSplitButtonStyles, -} from "./components/SplitButton/useSplitButtonStyles.styles"; + splitButtonClassNames, + useSplitButtonStyles, +} from './components/SplitButton/useSplitButtonStyles.styles'; export type { - SplitButtonProps, - SplitButtonSlots, - SplitButtonState, -} from "./components/SplitButton/SplitButton.types"; + SplitButtonProps, + SplitButtonSlots, + SplitButtonState, +} from './components/SplitButton/SplitButton.types'; diff --git a/packages/react-cap-theme/src/components/react-button/ToggleButton.ts b/packages/react-cap-theme/src/components/react-button/ToggleButton.ts index 71371ea9..2d261e8c 100644 --- a/packages/react-cap-theme/src/components/react-button/ToggleButton.ts +++ b/packages/react-cap-theme/src/components/react-button/ToggleButton.ts @@ -1,11 +1,11 @@ -export { ToggleButton } from "./components/ToggleButton/ToggleButton"; -export { renderToggleButton } from "./components/ToggleButton/renderToggleButton"; -export { useToggleButton } from "./components/ToggleButton/useToggleButton"; +export { ToggleButton } from './components/ToggleButton/ToggleButton'; +export { renderToggleButton } from './components/ToggleButton/renderToggleButton'; +export { useToggleButton } from './components/ToggleButton/useToggleButton'; export { - toggleButtonClassNames, - useToggleButtonStyles, -} from "./components/ToggleButton/useToggleButtonStyles.styles"; + toggleButtonClassNames, + useToggleButtonStyles, +} from './components/ToggleButton/useToggleButtonStyles.styles'; export type { - ToggleButtonProps, - ToggleButtonState, -} from "./components/ToggleButton/ToggleButton.types"; + ToggleButtonProps, + ToggleButtonState, +} from './components/ToggleButton/ToggleButton.types'; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx b/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx index 2ca14e56..1f9ce074 100644 --- a/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/Button/Button.tsx @@ -1,20 +1,20 @@ -import { useButtonStyles_unstable } from "@fluentui/react-button"; -import type { ForwardRefComponent } from "@fluentui/react-utilities"; -import * as React from "react"; -import type { ButtonProps } from "./Button.types"; -import { toBaseState } from "./Button.utils"; -import { renderButton } from "./renderButton"; -import { useButton } from "./useButton"; -import { useButtonStyles } from "./useButtonStyles.styles"; +import { useButtonStyles_unstable } from '@fluentui/react-button'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import * as React from 'react'; +import type { ButtonProps } from './Button.types'; +import { toBaseState } from './Button.utils'; +import { renderButton } from './renderButton'; +import { useButton } from './useButton'; +import { useButtonStyles } from './useButtonStyles.styles'; export const Button: ForwardRefComponent = React.forwardRef( - (props, ref) => { - const state = useButton(props, ref); - useButtonStyles_unstable(toBaseState(state)); - useButtonStyles(state); - return renderButton(state); - // Casting is required due to lack of distributive union to support unions on @types/react - }, + (props, ref) => { + const state = useButton(props, ref); + useButtonStyles_unstable(toBaseState(state)); + useButtonStyles(state); + return renderButton(state); + // Casting is required due to lack of distributive union to support unions on @types/react + } ) as ForwardRefComponent; -Button.displayName = "Button"; +Button.displayName = 'Button'; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts b/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts index 97a1149f..c01d663b 100644 --- a/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts +++ b/packages/react-cap-theme/src/components/react-button/components/Button/Button.types.ts @@ -1,28 +1,28 @@ import type { - ButtonSlots, - ButtonProps as BaseButtonProps, - ButtonState as BaseButtonState, -} from "@fluentui/react-button"; -import type { ComponentProps } from "@fluentui/react-utilities"; + ButtonSlots, + ButtonProps as BaseButtonProps, + ButtonState as BaseButtonState, +} from '@fluentui/react-button'; +import type { ComponentProps } from '@fluentui/react-utilities'; -export type { ButtonSlots } from "@fluentui/react-button"; +export type { ButtonSlots } from '@fluentui/react-button'; export type ButtonAppearance = - | "primary" - | "tint" - | "outline" - | "outlineColor" - | "secondary" - | "subtle" - | "transparent"; + | 'primary' + | 'tint' + | 'outline' + | 'outlineColor' + | 'secondary' + | 'subtle' + | 'transparent'; export type ButtonProps = ComponentProps & - Pick< - BaseButtonProps, - "disabledFocusable" | "disabled" | "iconPosition" | "size" - > & { - appearance?: ButtonAppearance; - }; + Pick< + BaseButtonProps, + 'disabledFocusable' | 'disabled' | 'iconPosition' | 'size' + > & { + appearance?: ButtonAppearance; + }; -export type ButtonState = Omit & - Required>; +export type ButtonState = Omit & + Required>; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts b/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts index eca12cf5..2f7508d8 100644 --- a/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts +++ b/packages/react-cap-theme/src/components/react-button/components/Button/Button.utils.ts @@ -1,32 +1,32 @@ import type { - ButtonState as BaseButtonState, - ButtonProps as BaseButtonProps, -} from "@fluentui/react-button"; + ButtonState as BaseButtonState, + ButtonProps as BaseButtonProps, +} from '@fluentui/react-button'; import type { - ButtonAppearance, - ButtonProps, - ButtonState, -} from "./Button.types"; + ButtonAppearance, + ButtonProps, + ButtonState, +} from './Button.types'; export const baseAppearanceMap: Record< - ButtonAppearance, - BaseButtonProps["appearance"] + ButtonAppearance, + BaseButtonProps['appearance'] > = { - secondary: "secondary", - primary: "primary", - outline: "outline", - outlineColor: "outline", - subtle: "subtle", - transparent: "transparent", - tint: "primary", + secondary: 'secondary', + primary: 'primary', + outline: 'outline', + outlineColor: 'outline', + subtle: 'subtle', + transparent: 'transparent', + tint: 'primary', }; export const toBaseProps = (props: ButtonProps): BaseButtonProps => ({ - ...props, - appearance: props.appearance && baseAppearanceMap[props.appearance], + ...props, + appearance: props.appearance && baseAppearanceMap[props.appearance], }); export const toBaseState = (state: ButtonState): BaseButtonState => ({ - ...state, - appearance: baseAppearanceMap[state.appearance] ?? "secondary", + ...state, + appearance: baseAppearanceMap[state.appearance] ?? 'secondary', }); diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx b/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx index 240e31f1..8708093e 100644 --- a/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/Button/renderButton.tsx @@ -1,12 +1,12 @@ import { - renderButton_unstable, - type ButtonState as BaseButtonState, -} from "@fluentui/react-button"; -import type { ReactElement } from "react"; -import type { ButtonState } from "./Button.types"; -import { toBaseState } from "./Button.utils"; + renderButton_unstable, + type ButtonState as BaseButtonState, +} from '@fluentui/react-button'; +import type { ReactElement } from 'react'; +import type { ButtonState } from './Button.types'; +import { toBaseState } from './Button.utils'; export const renderButton = (state: ButtonState): ReactElement => { - const baseState: BaseButtonState = toBaseState(state); - return renderButton_unstable(baseState); + const baseState: BaseButtonState = toBaseState(state); + return renderButton_unstable(baseState); }; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts b/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts index 1f274d3b..6f284a16 100644 --- a/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts +++ b/packages/react-cap-theme/src/components/react-button/components/Button/useButton.ts @@ -1,15 +1,15 @@ -import { useButton_unstable as useBaseState } from "@fluentui/react-button"; -import type { ButtonProps, ButtonState } from "./Button.types"; -import { toBaseProps } from "./Button.utils"; +import { useButton_unstable as useBaseState } from '@fluentui/react-button'; +import type { ButtonProps, ButtonState } from './Button.types'; +import { toBaseProps } from './Button.utils'; export const useButton = ( - props: ButtonProps, - ref: React.Ref, + props: ButtonProps, + ref: React.Ref ): ButtonState => { - const appearance = props.appearance ?? "secondary"; + const appearance = props.appearance ?? 'secondary'; - return { - ...useBaseState(toBaseProps(props), ref), - appearance, - } as ButtonState; + return { + ...useBaseState(toBaseProps(props), ref), + appearance, + } as ButtonState; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts index 192745cf..052b3446 100644 --- a/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts +++ b/packages/react-cap-theme/src/components/react-button/components/Button/useButtonStyles.styles.ts @@ -1,15 +1,12 @@ -import { createCustomFocusIndicatorStyle } from "@fluentui/react-tabster"; -import type { SlotClassNames } from "@fluentui/react-utilities"; -import { - tokens, - typographyStyles, -} from "../../../tokens"; -import { makeStyles, mergeClasses, shorthands } from "@griffel/react"; -import type { ButtonSlots, ButtonState } from "./Button.types"; +import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens, typographyStyles } from '../../../tokens'; +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; +import type { ButtonSlots, ButtonState } from './Button.types'; export const buttonClassNames: SlotClassNames = { - root: "fui-Button", - icon: "fui-Button__icon", + root: 'fui-Button', + icon: 'fui-Button__icon', }; const BORDER_WIDTH = tokens.strokeWidthThin; @@ -17,265 +14,265 @@ const buttonSpacingSmall = `calc(${tokens.spacingVerticalSNudge} - ${BORDER_WIDT const buttonSpacingMedium = `calc(${tokens.spacingVerticalS} - ${BORDER_WIDTH})`; const buttonSpacingLarge = `calc(${tokens.spacingVerticalMNudge} - ${BORDER_WIDTH})`; -const iconFilledClassName = "fui-Icon-filled"; -const iconRegularClassName = "fui-Icon-regular"; +const iconFilledClassName = 'fui-Icon-filled'; +const iconRegularClassName = 'fui-Icon-regular'; -const displayInline = { display: "inline" }; -const displayNone = { display: "none" }; +const displayInline = { display: 'inline' }; +const displayNone = { display: 'none' }; const useRootStyles = makeStyles({ - base: { - borderRadius: "12px", - minWidth: "unset", - [`:hover .${iconFilledClassName}`]: displayInline, - [`:hover .${iconRegularClassName}`]: displayNone, - [`:hover:active .${iconFilledClassName}`]: displayInline, - [`:hover:active .${iconRegularClassName}`]: displayNone, + base: { + borderRadius: '12px', + minWidth: 'unset', + [`:hover .${iconFilledClassName}`]: displayInline, + [`:hover .${iconRegularClassName}`]: displayNone, + [`:hover:active .${iconFilledClassName}`]: displayInline, + [`:hover:active .${iconRegularClassName}`]: displayNone, - ...createCustomFocusIndicatorStyle({ - borderRadius: "12px", - boxShadow: ` + ...createCustomFocusIndicatorStyle({ + borderRadius: '12px', + boxShadow: ` 0 0 0 ${tokens.strokeWidthThin} ${tokens.colorStrokeFocus2} inset, 0 0 0 ${tokens.strokeWidthThick} ${tokens.colorStrokeFocus1} inset `, - }), - }, - small: { - ...typographyStyles.caption1Strong, - borderRadius: "8px", - height: "28px", - padding: `${buttonSpacingSmall} calc(${tokens.spacingHorizontalS} - ${BORDER_WIDTH})`, - }, - medium: { - height: "36px", - padding: `${buttonSpacingMedium} calc(${tokens.spacingHorizontalM} - ${BORDER_WIDTH})`, - }, - large: { - ...typographyStyles.body1Strong, - height: "44px", - padding: `${buttonSpacingLarge} calc(${tokens.spacingHorizontalM} - ${BORDER_WIDTH})`, - }, - outline: { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - color: tokens.colorNeutralForeground3, - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralStroke2), - backgroundColor: tokens.colorNeutralBackground3Hover, - color: tokens.colorNeutralForeground1Hover, - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorNeutralBackground3Pressed), - backgroundColor: tokens.colorNeutralBackground3Pressed, - color: tokens.colorNeutralForeground1Pressed, - }, - }, - primary: { - ...shorthands.borderColor(tokens.colorBrandBackground), - ":hover": { - ...shorthands.borderColor(tokens.colorBrandBackgroundHover), - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorBrandBackgroundPressed), - }, - }, - secondary: { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: tokens.colorNeutralBackground3, - color: tokens.colorNeutralForeground3, - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralStroke2), - backgroundColor: tokens.colorNeutralBackground3Hover, - color: tokens.colorNeutralForeground1Hover, - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorNeutralBackground3Pressed), - backgroundColor: tokens.colorNeutralBackground3Pressed, - color: tokens.colorNeutralForeground1Pressed, - }, - }, - subtle: { - ...shorthands.borderColor(tokens.colorTransparentStroke), - backgroundColor: tokens.colorTransparentBackground, - color: tokens.colorNeutralForeground3, - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralBackground3Hover), - backgroundColor: tokens.colorNeutralBackground3Hover, - color: tokens.colorNeutralForeground1, - [`& .${buttonClassNames.icon}`]: { - color: tokens.colorNeutralForeground1, - }, - }, - ":hover:active": { - backgroundColor: tokens.colorNeutralBackground1Pressed, - color: tokens.colorNeutralForeground3Pressed, - [`& .${buttonClassNames.icon}`]: { - color: tokens.colorCompoundBrandForeground1Pressed, - }, - }, - }, - transparent: { - ...shorthands.borderColor(tokens.colorTransparentStroke), - backgroundColor: tokens.colorTransparentBackground, - color: tokens.colorNeutralForeground3, - ":hover": { color: tokens.colorCompoundBrandForeground1Hover }, - [":hover:active"]: { - color: tokens.colorCompoundBrandForeground1Pressed, - }, - }, - tint: { - ...shorthands.borderColor(tokens.colorBrandStroke2), - backgroundColor: tokens.colorBrandBackground2, - color: tokens.colorCompoundBrandForeground1, - ":hover": { - ...shorthands.borderColor(tokens.colorBrandStroke2Hover), - backgroundColor: tokens.colorBrandBackground2Hover, - color: tokens.colorCompoundBrandForeground1Hover, - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), - backgroundColor: tokens.colorBrandBackground2Pressed, - color: tokens.colorCompoundBrandForeground1Pressed, - }, - }, - outlineColor: { - ...shorthands.borderColor(tokens.colorBrandStroke2), - backgroundColor: "transparent", - color: tokens.colorCompoundBrandForeground1, - ":hover": { - ...shorthands.borderColor(tokens.colorBrandStroke2Hover), - backgroundColor: tokens.colorBrandBackground2Hover, - color: tokens.colorCompoundBrandForeground1Hover, - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), - backgroundColor: tokens.colorBrandBackground2Pressed, - color: tokens.colorCompoundBrandForeground1Pressed, - }, - }, + }), + }, + small: { + ...typographyStyles.caption1Strong, + borderRadius: '8px', + height: '28px', + padding: `${buttonSpacingSmall} calc(${tokens.spacingHorizontalS} - ${BORDER_WIDTH})`, + }, + medium: { + height: '36px', + padding: `${buttonSpacingMedium} calc(${tokens.spacingHorizontalM} - ${BORDER_WIDTH})`, + }, + large: { + ...typographyStyles.body1Strong, + height: '44px', + padding: `${buttonSpacingLarge} calc(${tokens.spacingHorizontalM} - ${BORDER_WIDTH})`, + }, + outline: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + color: tokens.colorNeutralForeground3, + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralStroke2), + backgroundColor: tokens.colorNeutralBackground3Hover, + color: tokens.colorNeutralForeground1Hover, + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorNeutralBackground3Pressed), + backgroundColor: tokens.colorNeutralBackground3Pressed, + color: tokens.colorNeutralForeground1Pressed, + }, + }, + primary: { + ...shorthands.borderColor(tokens.colorBrandBackground), + ':hover': { + ...shorthands.borderColor(tokens.colorBrandBackgroundHover), + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorBrandBackgroundPressed), + }, + }, + secondary: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForeground3, + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralStroke2), + backgroundColor: tokens.colorNeutralBackground3Hover, + color: tokens.colorNeutralForeground1Hover, + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorNeutralBackground3Pressed), + backgroundColor: tokens.colorNeutralBackground3Pressed, + color: tokens.colorNeutralForeground1Pressed, + }, + }, + subtle: { + ...shorthands.borderColor(tokens.colorTransparentStroke), + backgroundColor: tokens.colorTransparentBackground, + color: tokens.colorNeutralForeground3, + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralBackground3Hover), + backgroundColor: tokens.colorNeutralBackground3Hover, + color: tokens.colorNeutralForeground1, + [`& .${buttonClassNames.icon}`]: { + color: tokens.colorNeutralForeground1, + }, + }, + ':hover:active': { + backgroundColor: tokens.colorNeutralBackground1Pressed, + color: tokens.colorNeutralForeground3Pressed, + [`& .${buttonClassNames.icon}`]: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + }, + transparent: { + ...shorthands.borderColor(tokens.colorTransparentStroke), + backgroundColor: tokens.colorTransparentBackground, + color: tokens.colorNeutralForeground3, + ':hover': { color: tokens.colorCompoundBrandForeground1Hover }, + [':hover:active']: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + tint: { + ...shorthands.borderColor(tokens.colorBrandStroke2), + backgroundColor: tokens.colorBrandBackground2, + color: tokens.colorCompoundBrandForeground1, + ':hover': { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + backgroundColor: tokens.colorBrandBackground2Hover, + color: tokens.colorCompoundBrandForeground1Hover, + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + outlineColor: { + ...shorthands.borderColor(tokens.colorBrandStroke2), + backgroundColor: 'transparent', + color: tokens.colorCompoundBrandForeground1, + ':hover': { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + backgroundColor: tokens.colorBrandBackground2Hover, + color: tokens.colorCompoundBrandForeground1Hover, + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, }); const useRootDisabledStyles = makeStyles({ - outline: { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: "transparent", - color: tokens.colorNeutralForegroundDisabled, - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: "transparent", - color: tokens.colorNeutralForegroundDisabled, - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: "transparent", - color: tokens.colorNeutralForegroundDisabled, - }, - }, - secondary: { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: tokens.colorNeutralBackground3, - color: tokens.colorNeutralForegroundDisabled, - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: tokens.colorNeutralBackground3, - color: tokens.colorNeutralForegroundDisabled, - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorNeutralBackground5), - backgroundColor: tokens.colorNeutralBackground3, - color: tokens.colorNeutralForegroundDisabled, - }, - }, - subtle: {}, - transparent: {}, - primary: { - ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), - }, - }, - tint: { - ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), - ":hover": { - ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), - }, - ":hover:active": { - ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), - }, - }, - outlineColor: { - backgroundColor: "transparent", - ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), - ":hover": { - backgroundColor: "transparent", - ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), - }, - ":hover:active": { - backgroundColor: "transparent", - ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), - }, - }, + outline: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: 'transparent', + color: tokens.colorNeutralForegroundDisabled, + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: 'transparent', + color: tokens.colorNeutralForegroundDisabled, + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: 'transparent', + color: tokens.colorNeutralForegroundDisabled, + }, + }, + secondary: { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForegroundDisabled, + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForegroundDisabled, + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorNeutralBackground5), + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForegroundDisabled, + }, + }, + subtle: {}, + transparent: {}, + primary: { + ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorNeutralBackgroundDisabled), + }, + }, + tint: { + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + ':hover': { + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + ':hover:active': { + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + }, + outlineColor: { + backgroundColor: 'transparent', + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + ':hover': { + backgroundColor: 'transparent', + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + ':hover:active': { + backgroundColor: 'transparent', + ...shorthands.borderColor(tokens.colorNeutralStrokeDisabled), + }, + }, }); const useRootIconOnlyStyles = makeStyles({ - small: { - minWidth: "28px", - maxWidth: "28px", - padding: buttonSpacingSmall, - }, - medium: { - minWidth: "36px", - maxWidth: "36px", - padding: buttonSpacingMedium, - }, - large: { - minWidth: "40px", - maxWidth: "40px", - padding: buttonSpacingLarge, - }, + small: { + minWidth: '28px', + maxWidth: '28px', + padding: buttonSpacingSmall, + }, + medium: { + minWidth: '36px', + maxWidth: '36px', + padding: buttonSpacingMedium, + }, + large: { + minWidth: '40px', + maxWidth: '40px', + padding: buttonSpacingLarge, + }, }); const useIconStyles = makeStyles({ - small: { - fontSize: "16px", - height: "16px", - width: "16px", - }, - medium: {}, - large: { - fontSize: "20px", - height: "20px", - width: "20px", - }, + small: { + fontSize: '16px', + height: '16px', + width: '16px', + }, + medium: {}, + large: { + fontSize: '20px', + height: '20px', + width: '20px', + }, }); export const useButtonStyles = (state: ButtonState): ButtonState => { - const rootStyles = useRootStyles(); - const rootDisabledStyles = useRootDisabledStyles(); - const rootIconOnlyStyles = useRootIconOnlyStyles(); - const iconStyles = useIconStyles(); + const rootStyles = useRootStyles(); + const rootDisabledStyles = useRootDisabledStyles(); + const rootIconOnlyStyles = useRootIconOnlyStyles(); + const iconStyles = useIconStyles(); - const { appearance, disabled, disabledFocusable, iconOnly, size } = state; + const { appearance, disabled, disabledFocusable, iconOnly, size } = state; - state.root.className = mergeClasses( - state.root.className, - buttonClassNames.root, - rootStyles.base, - rootStyles[appearance], - (disabled || disabledFocusable) && rootDisabledStyles[appearance], - rootStyles[size], - iconOnly && rootIconOnlyStyles[size], - ); + state.root.className = mergeClasses( + state.root.className, + buttonClassNames.root, + rootStyles.base, + rootStyles[appearance], + (disabled || disabledFocusable) && rootDisabledStyles[appearance], + rootStyles[size], + iconOnly && rootIconOnlyStyles[size] + ); - if (state.icon) { - state.icon.className = mergeClasses( - state.icon.className, - buttonClassNames.icon, - iconStyles[size], - ); - } + if (state.icon) { + state.icon.className = mergeClasses( + state.icon.className, + buttonClassNames.icon, + iconStyles[size] + ); + } - return state; + return state; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx index ad25980a..1c36a60c 100644 --- a/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.tsx @@ -1,19 +1,19 @@ -import { useButtonStyles_unstable } from "@fluentui/react-button"; -import type { ForwardRefComponent } from "@fluentui/react-utilities"; -import * as React from "react"; -import type { ButtonState } from "../Button/Button.types"; -import { toBaseState } from "../Button/Button.utils"; -import type { MenuButtonProps } from "./MenuButton.types"; -import { renderMenuButton } from "./renderMenuButton"; -import { useMenuButton } from "./useMenuButton"; -import { useMenuButtonStyles } from "./useMenuButtonStyles.styles"; +import { useButtonStyles_unstable } from '@fluentui/react-button'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import * as React from 'react'; +import type { ButtonState } from '../Button/Button.types'; +import { toBaseState } from '../Button/Button.utils'; +import type { MenuButtonProps } from './MenuButton.types'; +import { renderMenuButton } from './renderMenuButton'; +import { useMenuButton } from './useMenuButton'; +import { useMenuButtonStyles } from './useMenuButtonStyles.styles'; export const MenuButton: ForwardRefComponent = - React.forwardRef((props, ref) => { - const state = useMenuButton(props, ref); - useButtonStyles_unstable(toBaseState(state as ButtonState)); - useMenuButtonStyles(state); - return renderMenuButton(state); - }) as ForwardRefComponent; + React.forwardRef((props, ref) => { + const state = useMenuButton(props, ref); + useButtonStyles_unstable(toBaseState(state as ButtonState)); + useMenuButtonStyles(state); + return renderMenuButton(state); + }) as ForwardRefComponent; -MenuButton.displayName = "MenuButton"; +MenuButton.displayName = 'MenuButton'; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts index a10750fd..b56d94a2 100644 --- a/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/MenuButton.types.ts @@ -1,11 +1,11 @@ -import type { MenuButtonSlots } from "@fluentui/react-button"; -import type { ComponentProps, ComponentState } from "@fluentui/react-utilities"; -import type { ButtonProps, ButtonState, ButtonSlots } from "../../Button"; +import type { MenuButtonSlots } from '@fluentui/react-button'; +import type { ComponentProps, ComponentState } from '@fluentui/react-utilities'; +import type { ButtonProps, ButtonState, ButtonSlots } from '../../Button'; -export type { MenuButtonSlots } from "@fluentui/react-button"; +export type { MenuButtonSlots } from '@fluentui/react-button'; export type MenuButtonProps = ComponentProps & - Pick; + Pick; export type MenuButtonState = ComponentState & - Omit; + Omit; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx b/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx index 883b07fd..ceeacee1 100644 --- a/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/renderMenuButton.tsx @@ -1,11 +1,11 @@ -import { renderMenuButton_unstable } from "@fluentui/react-button"; -import type { ReactElement } from "react"; -import { baseAppearanceMap } from "../Button/Button.utils"; -import type { MenuButtonState } from "./MenuButton.types"; +import { renderMenuButton_unstable } from '@fluentui/react-button'; +import type { ReactElement } from 'react'; +import { baseAppearanceMap } from '../Button/Button.utils'; +import type { MenuButtonState } from './MenuButton.types'; export const renderMenuButton = (state: MenuButtonState): ReactElement => { - return renderMenuButton_unstable({ - ...state, - appearance: baseAppearanceMap[state.appearance] ?? "secondary", - }); + return renderMenuButton_unstable({ + ...state, + appearance: baseAppearanceMap[state.appearance] ?? 'secondary', + }); }; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts index fd7cdccd..be760ca7 100644 --- a/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButton.ts @@ -1,19 +1,19 @@ -import { useMenuButton_unstable } from "@fluentui/react-button"; -import type * as React from "react"; -import { baseAppearanceMap } from "../Button/Button.utils"; -import type { MenuButtonProps, MenuButtonState } from "./MenuButton.types"; +import { useMenuButton_unstable } from '@fluentui/react-button'; +import type * as React from 'react'; +import { baseAppearanceMap } from '../Button/Button.utils'; +import type { MenuButtonProps, MenuButtonState } from './MenuButton.types'; export const useMenuButton = ( - props: MenuButtonProps, - ref: React.Ref, + props: MenuButtonProps, + ref: React.Ref ): MenuButtonState => { - const { appearance = "secondary" } = props; - const baseState = useMenuButton_unstable( - { - ...props, - appearance: appearance && baseAppearanceMap[appearance], - }, - ref, - ); - return { ...baseState, appearance } as MenuButtonState; + const { appearance = 'secondary' } = props; + const baseState = useMenuButton_unstable( + { + ...props, + appearance: appearance && baseAppearanceMap[appearance], + }, + ref + ); + return { ...baseState, appearance } as MenuButtonState; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts index d546b715..d216a3ff 100644 --- a/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts +++ b/packages/react-cap-theme/src/components/react-button/components/MenuButton/useMenuButtonStyles.styles.ts @@ -1,61 +1,61 @@ -import type { SlotClassNames } from "@fluentui/react-utilities"; -import { tokens } from "../../../tokens"; -import { makeStyles, mergeClasses } from "@griffel/react"; -import { useButtonStyles } from "../Button/useButtonStyles.styles"; -import type { MenuButtonSlots, MenuButtonState } from "./MenuButton.types"; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens } from '../../../tokens'; +import { makeStyles, mergeClasses } from '@griffel/react'; +import { useButtonStyles } from '../Button/useButtonStyles.styles'; +import type { MenuButtonSlots, MenuButtonState } from './MenuButton.types'; export const menuButtonClassNames: SlotClassNames = { - root: "fui-MenuButton", - icon: "fui-MenuButton__icon", - menuIcon: "fui-MenuButton__menuIcon", + root: 'fui-MenuButton', + icon: 'fui-MenuButton__icon', + menuIcon: 'fui-MenuButton__menuIcon', }; const useMenuIconStyles = makeStyles({ - base: { - display: "flex", - justifyContent: "center", - alignItems: "center", - }, + base: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }, - small: { - fontSize: tokens.fontSizeBase200, - height: "16px", - lineHeight: tokens.lineHeightBase200, - width: "16px", - }, - medium: { - fontSize: tokens.fontSizeBase400, - height: "20px", - lineHeight: tokens.lineHeightBase400, - width: "20px", - }, - large: { - fontSize: tokens.fontSizeBase400, - height: "20px", - lineHeight: tokens.lineHeightBase400, - width: "20px", - }, + small: { + fontSize: tokens.fontSizeBase200, + height: '16px', + lineHeight: tokens.lineHeightBase200, + width: '16px', + }, + medium: { + fontSize: tokens.fontSizeBase400, + height: '20px', + lineHeight: tokens.lineHeightBase400, + width: '20px', + }, + large: { + fontSize: tokens.fontSizeBase400, + height: '20px', + lineHeight: tokens.lineHeightBase400, + width: '20px', + }, - noIconOnly: { - marginLeft: tokens.spacingHorizontalSNudge, - }, + noIconOnly: { + marginLeft: tokens.spacingHorizontalSNudge, + }, }); export const useMenuButtonStyles = ( - state: MenuButtonState, + state: MenuButtonState ): MenuButtonState => { - const menuIconStyles = useMenuIconStyles(); + const menuIconStyles = useMenuIconStyles(); - if (state.menuIcon) { - state.menuIcon.className = mergeClasses( - state.menuIcon.className, - menuButtonClassNames.menuIcon, - menuIconStyles.base, - menuIconStyles[state.size], - !state.iconOnly && menuIconStyles.noIconOnly, - ); - } + if (state.menuIcon) { + state.menuIcon.className = mergeClasses( + state.menuIcon.className, + menuButtonClassNames.menuIcon, + menuIconStyles.base, + menuIconStyles[state.size], + !state.iconOnly && menuIconStyles.noIconOnly + ); + } - useButtonStyles({ ...state, iconPosition: "before" }); - return state; + useButtonStyles({ ...state, iconPosition: 'before' }); + return state; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx index 47682b3f..e35d0e40 100644 --- a/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.tsx @@ -1,16 +1,16 @@ -import type { ForwardRefComponent } from "@fluentui/react-utilities"; -import * as React from "react"; -import { renderSplitButton } from "./renderSplitButton"; -import type { SplitButtonProps } from "./SplitButton.types"; -import { useSplitButton } from "./useSplitButton"; -import { useSplitButtonStyles } from "./useSplitButtonStyles.styles"; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import * as React from 'react'; +import { renderSplitButton } from './renderSplitButton'; +import type { SplitButtonProps } from './SplitButton.types'; +import { useSplitButton } from './useSplitButton'; +import { useSplitButtonStyles } from './useSplitButtonStyles.styles'; export const SplitButton: ForwardRefComponent = - React.forwardRef((props, ref) => { - const state = useSplitButton(props, ref); - useSplitButtonStyles(state); - return renderSplitButton(state); - // Casting is required due to lack of distributive union to support unions on @types/react - }) as ForwardRefComponent; + React.forwardRef((props, ref) => { + const state = useSplitButton(props, ref); + useSplitButtonStyles(state); + return renderSplitButton(state); + // Casting is required due to lack of distributive union to support unions on @types/react + }) as ForwardRefComponent; -SplitButton.displayName = "SplitButton"; +SplitButton.displayName = 'SplitButton'; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts index 1c71d042..f703188b 100644 --- a/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/SplitButton.types.ts @@ -1,25 +1,25 @@ import type { - ComponentProps, - ComponentState, - Slot, -} from "@fluentui/react-utilities"; -import type { Button, ButtonProps, ButtonState } from "../../Button"; + ComponentProps, + ComponentState, + Slot, +} from '@fluentui/react-utilities'; +import type { Button, ButtonProps, ButtonState } from '../../Button'; import type { - MenuButton, - MenuButtonProps, - MenuButtonState, -} from "../../MenuButton"; + MenuButton, + MenuButtonProps, + MenuButtonState, +} from '../../MenuButton'; export type SplitButtonSlots = { - root: NonNullable>; - menuButton?: Slot; - primaryActionButton?: Slot; + root: NonNullable>; + menuButton?: Slot; + primaryActionButton?: Slot; }; export type SplitButtonProps = ComponentProps & - Omit & - Omit; + Omit & + Omit; export type SplitButtonState = ComponentState & - Omit & - Omit; + Omit & + Omit; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx b/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx index bee302c6..a5686cb3 100644 --- a/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/renderSplitButton.tsx @@ -1,15 +1,14 @@ - -import { assertSlots } from "@fluentui/react-utilities"; -import type { ReactElement } from "react"; -import type { SplitButtonSlots, SplitButtonState } from "./SplitButton.types"; +import { assertSlots } from '@fluentui/react-utilities'; +import type { ReactElement } from 'react'; +import type { SplitButtonSlots, SplitButtonState } from './SplitButton.types'; export const renderSplitButton = (state: SplitButtonState): ReactElement => { - assertSlots(state); + assertSlots(state); - return ( - - {state.primaryActionButton && } - {state.menuButton && } - - ); + return ( + + {state.primaryActionButton && } + {state.menuButton && } + + ); }; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts index ebee0aae..b4efb3b6 100644 --- a/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButton.ts @@ -1,85 +1,84 @@ import { - getIntrinsicElementProps, - useId, - slot, -} from "@fluentui/react-utilities"; -import type * as React from "react"; -import { Button } from "../Button/Button"; -import { MenuButton } from "../MenuButton/MenuButton"; -import type { SplitButtonProps, SplitButtonState } from "./SplitButton.types"; + getIntrinsicElementProps, + useId, + slot, +} from '@fluentui/react-utilities'; +import type * as React from 'react'; +import { Button } from '../Button/Button'; +import { MenuButton } from '../MenuButton/MenuButton'; +import type { SplitButtonProps, SplitButtonState } from './SplitButton.types'; export const useSplitButton = ( - props: SplitButtonProps, - ref: React.Ref, + props: SplitButtonProps, + ref: React.Ref ): SplitButtonState => { - const { - appearance = "secondary", - children, - disabled = false, - disabledFocusable = false, - icon, - iconPosition = "before", - menuButton, - menuIcon, - primaryActionButton, - size = "medium", - } = props; + const { + appearance = 'secondary', + children, + disabled = false, + disabledFocusable = false, + icon, + iconPosition = 'before', + menuButton, + menuIcon, + primaryActionButton, + size = 'medium', + } = props; - const baseId = useId("splitButton-"); + const baseId = useId('splitButton-'); - const menuButtonShorthand = slot.optional(menuButton, { - defaultProps: { - appearance, - disabled, - disabledFocusable, - menuIcon, - size, - }, - renderByDefault: true, - elementType: MenuButton, - }); + const menuButtonShorthand = slot.optional(menuButton, { + defaultProps: { + appearance, + disabled, + disabledFocusable, + menuIcon, + size, + }, + renderByDefault: true, + elementType: MenuButton, + }); - const primaryActionButtonShorthand = slot.optional(primaryActionButton, { - defaultProps: { - appearance, - children, - disabled, - disabledFocusable, - icon, - iconPosition, - id: baseId + "__primaryActionButton", - size, - }, - renderByDefault: true, - elementType: Button, - }); + const primaryActionButtonShorthand = slot.optional(primaryActionButton, { + defaultProps: { + appearance, + children, + disabled, + disabledFocusable, + icon, + iconPosition, + id: baseId + '__primaryActionButton', + size, + }, + renderByDefault: true, + elementType: Button, + }); - if ( - menuButtonShorthand && - primaryActionButtonShorthand && - !menuButtonShorthand["aria-label"] && - !menuButtonShorthand["aria-labelledby"] - ) { - menuButtonShorthand["aria-labelledby"] = - primaryActionButtonShorthand.id; - } + if ( + menuButtonShorthand && + primaryActionButtonShorthand && + !menuButtonShorthand['aria-label'] && + !menuButtonShorthand['aria-labelledby'] + ) { + menuButtonShorthand['aria-labelledby'] = primaryActionButtonShorthand.id; + } - return { - components: { - root: "div", - menuButton: MenuButton, - primaryActionButton: Button, - }, - root: slot.always(getIntrinsicElementProps("div", { ref, ...props }), { - elementType: "div", - }), - primaryActionButton: primaryActionButtonShorthand, - menuButton: menuButtonShorthand, - appearance, - disabled, - disabledFocusable, - iconPosition, - shape: "rounded", - size, - }; + return { + components: { + root: 'div', + menuButton: MenuButton, + primaryActionButton: Button, + }, + root: slot.always(getIntrinsicElementProps('div', { ref, ...props }), { + elementType: 'div', + }), + primaryActionButton: primaryActionButtonShorthand, + menuButton: menuButtonShorthand, + appearance, + disabled, + disabledFocusable, + iconPosition, + shape: 'rounded', + size, + }; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts index 525aaed8..2e2cc67d 100644 --- a/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts +++ b/packages/react-cap-theme/src/components/react-button/components/SplitButton/useSplitButtonStyles.styles.ts @@ -1,266 +1,266 @@ -import { createCustomFocusIndicatorStyle } from "@fluentui/react-tabster"; -import type { SlotClassNames } from "@fluentui/react-utilities"; -import { tokens } from "../../../tokens"; -import { makeStyles, mergeClasses, shorthands } from "@griffel/react"; -import type { SplitButtonSlots, SplitButtonState } from "./SplitButton.types"; +import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens } from '../../../tokens'; +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; +import type { SplitButtonSlots, SplitButtonState } from './SplitButton.types'; export const splitButtonClassNames: SlotClassNames = { - root: "fui-SplitButton", - primaryActionButton: "fui-SplitButton__primaryActionButton", - menuButton: "fui-SplitButton__menuButton", + root: 'fui-SplitButton', + primaryActionButton: 'fui-SplitButton__primaryActionButton', + menuButton: 'fui-SplitButton__menuButton', }; const createPaddingWithStrokeAdjustment = ( - horizontal: string, + horizontal: string ): { - paddingLeft: string; - paddingRight: string; + paddingLeft: string; + paddingRight: string; } => ({ - paddingLeft: `calc(${horizontal} - ${tokens.strokeWidthThin})`, - paddingRight: horizontal, + paddingLeft: `calc(${horizontal} - ${tokens.strokeWidthThin})`, + paddingRight: horizontal, }); const createSizeStyles = ( - dimension: string, + dimension: string ): { - height: string; - width: string; + height: string; + width: string; } => ({ - height: dimension, - width: dimension, + height: dimension, + width: dimension, }); const useFocusStyles = makeStyles({ - primaryActionButton: createCustomFocusIndicatorStyle({ - ...shorthands.borderColor(tokens.colorStrokeFocus1), - borderRadius: 0, - borderRightWidth: 0, - boxShadow: "none", - outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, - ":after": { - borderRightColor: "inherit", - height: "100%", - }, - }), + primaryActionButton: createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorStrokeFocus1), + borderRadius: 0, + borderRightWidth: 0, + boxShadow: 'none', + outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, + ':after': { + borderRightColor: 'inherit', + height: '100%', + }, + }), - menuButton: createCustomFocusIndicatorStyle({ - ...shorthands.borderColor(tokens.colorStrokeFocus1), - borderRadius: 0, - borderLeft: "none", - boxShadow: "none", - outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, - position: "relative", - zIndex: 1, - ":after": { - content: '""', - borderLeft: `${tokens.strokeWidthThin} solid ${tokens.colorStrokeFocus1}`, - }, - }), + menuButton: createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorStrokeFocus1), + borderRadius: 0, + borderLeft: 'none', + boxShadow: 'none', + outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, + position: 'relative', + zIndex: 1, + ':after': { + content: '""', + borderLeft: `${tokens.strokeWidthThin} solid ${tokens.colorStrokeFocus1}`, + }, + }), }); const useRootStyles = makeStyles({ - small: { - [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderTopLeftRadius: "8px", - borderBottomLeftRadius: "8px", - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - }, - [`& .${splitButtonClassNames.menuButton}`]: { - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - borderTopRightRadius: "8px", - borderBottomRightRadius: "8px", - }, - }, - medium: { - [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderTopLeftRadius: "12px", - borderBottomLeftRadius: "12px", - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - }, - [`& .${splitButtonClassNames.menuButton}`]: { - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - borderTopRightRadius: "12px", - borderBottomRightRadius: "12px", - }, - }, - large: { - [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderTopLeftRadius: "12px", - borderBottomLeftRadius: "12px", - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - }, - [`& .${splitButtonClassNames.menuButton}`]: { - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - borderTopRightRadius: "12px", - borderBottomRightRadius: "12px", - }, - }, + small: { + [`& .${splitButtonClassNames.primaryActionButton}`]: { + borderTopLeftRadius: '8px', + borderBottomLeftRadius: '8px', + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${splitButtonClassNames.menuButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderTopRightRadius: '8px', + borderBottomRightRadius: '8px', + }, + }, + medium: { + [`& .${splitButtonClassNames.primaryActionButton}`]: { + borderTopLeftRadius: '12px', + borderBottomLeftRadius: '12px', + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${splitButtonClassNames.menuButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderTopRightRadius: '12px', + borderBottomRightRadius: '12px', + }, + }, + large: { + [`& .${splitButtonClassNames.primaryActionButton}`]: { + borderTopLeftRadius: '12px', + borderBottomLeftRadius: '12px', + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${splitButtonClassNames.menuButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + borderTopRightRadius: '12px', + borderBottomRightRadius: '12px', + }, + }, }); const useRootAppearanceStyles = makeStyles({ - tint: { - [`&:hover .${splitButtonClassNames.primaryActionButton}`]: { - ...shorthands.borderColor(tokens.colorBrandStroke2Hover), - }, - [`&:hover .${splitButtonClassNames.menuButton}`]: { - ...shorthands.borderColor(tokens.colorBrandStroke2Hover), - }, - }, - outlineColor: {}, - primary: {}, - outline: {}, - secondary: {}, - subtle: {}, - transparent: {}, + tint: { + [`&:hover .${splitButtonClassNames.primaryActionButton}`]: { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + }, + [`&:hover .${splitButtonClassNames.menuButton}`]: { + ...shorthands.borderColor(tokens.colorBrandStroke2Hover), + }, + }, + outlineColor: {}, + primary: {}, + outline: {}, + secondary: {}, + subtle: {}, + transparent: {}, }); const usePrimaryActionButtonStyles = makeStyles({ - base: { - borderRadius: tokens.borderRadiusNone, - borderRightWidth: "0", - position: "relative", - ":after": { - content: '""', - borderRight: `${tokens.strokeWidthThin} solid`, - borderRightColor: "inherit", - boxSizing: "border-box", - height: `calc(100% - ${tokens.strokeWidthThin} * 2 - ${tokens.spacingVerticalS} * 2)`, - opacity: 0.3, - position: "absolute", - right: 0, - }, + base: { + borderRadius: tokens.borderRadiusNone, + borderRightWidth: '0', + position: 'relative', + ':after': { + content: '""', + borderRight: `${tokens.strokeWidthThin} solid`, + borderRightColor: 'inherit', + boxSizing: 'border-box', + height: `calc(100% - ${tokens.strokeWidthThin} * 2 - ${tokens.spacingVerticalS} * 2)`, + opacity: 0.3, + position: 'absolute', + right: 0, + }, - "@media (forced-colors: active)": { - ":after": { borderRightColor: "inherit" }, - ":hover:after": { borderRightColor: "inherit" }, - ":active:after": { borderRightColor: "inherit" }, - }, - }, - outline: {}, - primary: { - ":after": { borderRightColor: tokens.colorNeutralStrokeOnBrand2 }, - ":hover:after": { - borderRightColor: tokens.colorNeutralStrokeOnBrand2Hover, - }, - ":active:after": { - borderRightColor: tokens.colorNeutralStrokeOnBrand2Pressed, - }, - }, - secondary: {}, - subtle: { - ":after": { borderRightColor: tokens.colorNeutralStroke1 }, - ":hover:after": { borderRightColor: tokens.colorNeutralStroke1Hover }, - ":active:after": { - borderRightColor: tokens.colorNeutralStroke1Pressed, - }, - }, - transparent: { - ":after": { borderRightColor: tokens.colorNeutralStroke1 }, - ":hover:after": { borderRightColor: tokens.colorNeutralStroke1Hover }, - ":active:after": { - borderRightColor: tokens.colorNeutralStroke1Pressed, - }, - }, - tint: { - ":after": { - borderRightColor: tokens.colorBrandStroke2, - opacity: 1, - }, - ":hover:after": { - borderRightColor: tokens.colorBrandStroke2Hover, - }, - ":active:after": { - borderRightColor: tokens.colorBrandStroke2Pressed, - }, - }, - outlineColor: {}, - disabled: { - ":after": { borderRightColor: tokens.colorNeutralStrokeDisabled }, - ":hover:after": { borderRightColor: tokens.colorNeutralStrokeDisabled }, - ":active:after": { - borderRightColor: tokens.colorNeutralStrokeDisabled, - }, - }, - small: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalS), - medium: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalM), - large: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalM), + '@media (forced-colors: active)': { + ':after': { borderRightColor: 'inherit' }, + ':hover:after': { borderRightColor: 'inherit' }, + ':active:after': { borderRightColor: 'inherit' }, + }, + }, + outline: {}, + primary: { + ':after': { borderRightColor: tokens.colorNeutralStrokeOnBrand2 }, + ':hover:after': { + borderRightColor: tokens.colorNeutralStrokeOnBrand2Hover, + }, + ':active:after': { + borderRightColor: tokens.colorNeutralStrokeOnBrand2Pressed, + }, + }, + secondary: {}, + subtle: { + ':after': { borderRightColor: tokens.colorNeutralStroke1 }, + ':hover:after': { borderRightColor: tokens.colorNeutralStroke1Hover }, + ':active:after': { + borderRightColor: tokens.colorNeutralStroke1Pressed, + }, + }, + transparent: { + ':after': { borderRightColor: tokens.colorNeutralStroke1 }, + ':hover:after': { borderRightColor: tokens.colorNeutralStroke1Hover }, + ':active:after': { + borderRightColor: tokens.colorNeutralStroke1Pressed, + }, + }, + tint: { + ':after': { + borderRightColor: tokens.colorBrandStroke2, + opacity: 1, + }, + ':hover:after': { + borderRightColor: tokens.colorBrandStroke2Hover, + }, + ':active:after': { + borderRightColor: tokens.colorBrandStroke2Pressed, + }, + }, + outlineColor: {}, + disabled: { + ':after': { borderRightColor: tokens.colorNeutralStrokeDisabled }, + ':hover:after': { borderRightColor: tokens.colorNeutralStrokeDisabled }, + ':active:after': { + borderRightColor: tokens.colorNeutralStrokeDisabled, + }, + }, + small: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalS), + medium: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalM), + large: createPaddingWithStrokeAdjustment(tokens.spacingHorizontalM), }); const useMenuButtonStyles = makeStyles({ - base: { - borderRadius: tokens.borderRadiusNone, - borderLeft: "none", - ":after": { - borderLeft: `${tokens.strokeWidthThin} solid`, - boxSizing: "border-box", - height: "100%", - position: "absolute", - width: "100%", - }, - }, - small: { paddingLeft: tokens.spacingHorizontalSNudge }, - medium: { paddingLeft: tokens.spacingHorizontalS }, - large: { paddingLeft: tokens.spacingHorizontalMNudge }, + base: { + borderRadius: tokens.borderRadiusNone, + borderLeft: 'none', + ':after': { + borderLeft: `${tokens.strokeWidthThin} solid`, + boxSizing: 'border-box', + height: '100%', + position: 'absolute', + width: '100%', + }, + }, + small: { paddingLeft: tokens.spacingHorizontalSNudge }, + medium: { paddingLeft: tokens.spacingHorizontalS }, + large: { paddingLeft: tokens.spacingHorizontalMNudge }, }); const useMenuIconStyles = makeStyles({ - small: createSizeStyles("12px"), - medium: createSizeStyles("16px"), - large: createSizeStyles("16px"), + small: createSizeStyles('12px'), + medium: createSizeStyles('16px'), + large: createSizeStyles('16px'), }); export const useSplitButtonStyles = ( - state: SplitButtonState, + state: SplitButtonState ): SplitButtonState => { - const rootStyles = useRootStyles(); - const rootAppearanceStyles = useRootAppearanceStyles(); - const focusStyles = useFocusStyles(); - const primaryActionButtonStyles = usePrimaryActionButtonStyles(); - const menuButtonStyles = useMenuButtonStyles(); - const menuIconStyles = useMenuIconStyles(); + const rootStyles = useRootStyles(); + const rootAppearanceStyles = useRootAppearanceStyles(); + const focusStyles = useFocusStyles(); + const primaryActionButtonStyles = usePrimaryActionButtonStyles(); + const menuButtonStyles = useMenuButtonStyles(); + const menuIconStyles = useMenuIconStyles(); - state.root.className = mergeClasses( - splitButtonClassNames.root, - rootStyles[state.size], - rootAppearanceStyles[state.appearance], - state.root.className, - ); + state.root.className = mergeClasses( + splitButtonClassNames.root, + rootStyles[state.size], + rootAppearanceStyles[state.appearance], + state.root.className + ); - if (state.primaryActionButton) { - state.primaryActionButton.className = mergeClasses( - splitButtonClassNames.primaryActionButton, - primaryActionButtonStyles.base, - primaryActionButtonStyles[state.appearance], - primaryActionButtonStyles[state.size], - focusStyles.primaryActionButton, - (state.disabled || state.disabledFocusable) && - primaryActionButtonStyles.disabled, - state.primaryActionButton.className, - ); - } + if (state.primaryActionButton) { + state.primaryActionButton.className = mergeClasses( + splitButtonClassNames.primaryActionButton, + primaryActionButtonStyles.base, + primaryActionButtonStyles[state.appearance], + primaryActionButtonStyles[state.size], + focusStyles.primaryActionButton, + (state.disabled || state.disabledFocusable) && + primaryActionButtonStyles.disabled, + state.primaryActionButton.className + ); + } - if (state.menuButton) { - state.menuButton.className = mergeClasses( - splitButtonClassNames.menuButton, - menuButtonStyles.base, - menuButtonStyles[state.size], - focusStyles.menuButton, - state.menuButton.className, - ); - } + if (state.menuButton) { + state.menuButton.className = mergeClasses( + splitButtonClassNames.menuButton, + menuButtonStyles.base, + menuButtonStyles[state.size], + focusStyles.menuButton, + state.menuButton.className + ); + } - if (state.menuIcon) { - state.menuIcon.className = mergeClasses( - menuIconStyles[state.size], - state.menuIcon.className, - ); - } + if (state.menuIcon) { + state.menuIcon.className = mergeClasses( + menuIconStyles[state.size], + state.menuIcon.className + ); + } - return state; + return state; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx index 121f45db..2f404134 100644 --- a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.tsx @@ -1,26 +1,26 @@ import { - useButtonStyles_unstable, - useToggleButtonStyles_unstable, -} from "@fluentui/react-button"; -import type { ForwardRefComponent } from "@fluentui/react-utilities"; -import * as React from "react"; + useButtonStyles_unstable, + useToggleButtonStyles_unstable, +} from '@fluentui/react-button'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import * as React from 'react'; -import { toBaseState } from "../Button/Button.utils"; -import { renderToggleButton } from "./renderToggleButton"; -import type { ToggleButtonProps } from "./ToggleButton.types"; -import { useToggleButton } from "./useToggleButton"; -import { useToggleButtonStyles } from "./useToggleButtonStyles.styles"; +import { toBaseState } from '../Button/Button.utils'; +import { renderToggleButton } from './renderToggleButton'; +import type { ToggleButtonProps } from './ToggleButton.types'; +import { useToggleButton } from './useToggleButton'; +import { useToggleButtonStyles } from './useToggleButtonStyles.styles'; export const ToggleButton: ForwardRefComponent = - React.forwardRef((props, ref) => { - const state = useToggleButton(props, ref); - const baseState = toBaseState(state); - useButtonStyles_unstable(baseState); - useToggleButtonStyles_unstable({ - ...baseState, - checked: state.checked, - }); - useToggleButtonStyles(state); - return renderToggleButton(state); - }) as ForwardRefComponent; -ToggleButton.displayName = "ToggleButton"; + React.forwardRef((props, ref) => { + const state = useToggleButton(props, ref); + const baseState = toBaseState(state); + useButtonStyles_unstable(baseState); + useToggleButtonStyles_unstable({ + ...baseState, + checked: state.checked, + }); + useToggleButtonStyles(state); + return renderToggleButton(state); + }) as ForwardRefComponent; +ToggleButton.displayName = 'ToggleButton'; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts index e6074e6c..39ee1088 100644 --- a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/ToggleButton.types.ts @@ -1,8 +1,8 @@ -import type { ToggleButtonProps as BaseToggleButtonProps } from "@fluentui/react-button"; -import type { ButtonProps, ButtonState } from "../../Button"; +import type { ToggleButtonProps as BaseToggleButtonProps } from '@fluentui/react-button'; +import type { ButtonProps, ButtonState } from '../../Button'; export type ToggleButtonProps = ButtonProps & - Pick; + Pick; export type ToggleButtonState = ButtonState & - Required>; + Required>; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx index c7cb6ec8..0bc41b44 100644 --- a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/renderToggleButton.tsx @@ -1,6 +1,6 @@ -import type { ReactElement } from "react"; -import { renderButton } from "../../Button"; -import type { ToggleButtonState } from "./ToggleButton.types"; +import type { ReactElement } from 'react'; +import { renderButton } from '../../Button'; +import type { ToggleButtonState } from './ToggleButton.types'; export const renderToggleButton = (state: ToggleButtonState): ReactElement => - renderButton(state); + renderButton(state); diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts index 1f1c0a1f..f82d5f08 100644 --- a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButton.ts @@ -1,15 +1,15 @@ -import { useToggleState } from "@fluentui/react-button"; -import { useButton } from "../../Button"; +import { useToggleState } from '@fluentui/react-button'; +import { useButton } from '../../Button'; import type { - ToggleButtonProps, - ToggleButtonState, -} from "./ToggleButton.types"; + ToggleButtonProps, + ToggleButtonState, +} from './ToggleButton.types'; export const useToggleButton = ( - props: ToggleButtonProps, - ref: React.Ref, + props: ToggleButtonProps, + ref: React.Ref ): ToggleButtonState => { - const buttonState = useButton(props, ref) as ToggleButtonState; - return useToggleState(props, buttonState) as ToggleButtonState; + const buttonState = useButton(props, ref) as ToggleButtonState; + return useToggleState(props, buttonState) as ToggleButtonState; }; diff --git a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts index ea4d92d6..a320ac0d 100644 --- a/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts +++ b/packages/react-cap-theme/src/components/react-button/components/ToggleButton/useToggleButtonStyles.styles.ts @@ -1,139 +1,139 @@ -import type { SlotClassNames } from "@fluentui/react-utilities"; -import { tokens } from "../../../tokens"; -import { makeStyles, shorthands, mergeClasses } from "@griffel/react"; -import { useButtonStyles, type ButtonSlots } from "../../Button"; -import type { ToggleButtonState } from "./ToggleButton.types"; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens } from '../../../tokens'; +import { makeStyles, shorthands, mergeClasses } from '@griffel/react'; +import { useButtonStyles, type ButtonSlots } from '../../Button'; +import type { ToggleButtonState } from './ToggleButton.types'; export const toggleButtonClassNames: SlotClassNames = { - root: "fui-ToggleButton", - icon: "fui-ToggleButton__icon", + root: 'fui-ToggleButton', + icon: 'fui-ToggleButton__icon', }; -const iconFilledClassName = "fui-Icon-filled"; -const iconRegularClassName = "fui-Icon-regular"; +const iconFilledClassName = 'fui-Icon-filled'; +const iconRegularClassName = 'fui-Icon-regular'; -const displayInline = { display: "inline" }; -const displayNone = { display: "none" }; +const displayInline = { display: 'inline' }; +const displayNone = { display: 'none' }; const useRootCheckedStyles = makeStyles({ - base: { - [`:hover .${iconFilledClassName}`]: { - color: tokens.colorCompoundBrandForeground1Hover, - }, - }, - outline: { - ...shorthands.borderColor(tokens.colorNeutralStroke1Selected), - color: tokens.colorNeutralForeground3Selected, - }, + base: { + [`:hover .${iconFilledClassName}`]: { + color: tokens.colorCompoundBrandForeground1Hover, + }, + }, + outline: { + ...shorthands.borderColor(tokens.colorNeutralStroke1Selected), + color: tokens.colorNeutralForeground3Selected, + }, - primary: { - [`:hover .${iconFilledClassName}`]: { - color: tokens.colorNeutralForegroundOnBrand, - }, - }, - tint: { - backgroundColor: tokens.colorBrandBackground2Pressed, - color: tokens.colorCompoundBrandForeground1Pressed, - ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), - ...shorthands.borderWidth(tokens.strokeWidthThicker), - }, - outlineColor: { - backgroundColor: tokens.colorBrandBackground2Pressed, - color: tokens.colorCompoundBrandForeground1Pressed, - ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), - ...shorthands.borderWidth(tokens.strokeWidthThicker), - }, - secondary: { - backgroundColor: tokens.colorNeutralBackground3, - ...shorthands.borderColor(tokens.colorNeutralBackground3Hover), - color: tokens.colorNeutralForeground1, - [`& .${toggleButtonClassNames.icon}`]: { - color: tokens.colorCompoundBrandForeground1Pressed, - }, - ":hover": { - color: tokens.colorCompoundBrandForeground1Hover, - }, - ":hover:active": { - color: tokens.colorCompoundBrandForeground1Pressed, - }, - }, - subtle: { - backgroundColor: tokens.colorNeutralBackground1Selected, - color: tokens.colorNeutralForeground3Selected, - ":hover": { - backgroundColor: tokens.colorNeutralBackground1Hover, - }, - }, - transparent: { - color: tokens.colorCompoundBrandForeground1Pressed, - }, + primary: { + [`:hover .${iconFilledClassName}`]: { + color: tokens.colorNeutralForegroundOnBrand, + }, + }, + tint: { + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, + outlineColor: { + backgroundColor: tokens.colorBrandBackground2Pressed, + color: tokens.colorCompoundBrandForeground1Pressed, + ...shorthands.borderColor(tokens.colorBrandStroke2Pressed), + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, + secondary: { + backgroundColor: tokens.colorNeutralBackground3, + ...shorthands.borderColor(tokens.colorNeutralBackground3Hover), + color: tokens.colorNeutralForeground1, + [`& .${toggleButtonClassNames.icon}`]: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + ':hover': { + color: tokens.colorCompoundBrandForeground1Hover, + }, + ':hover:active': { + color: tokens.colorCompoundBrandForeground1Pressed, + }, + }, + subtle: { + backgroundColor: tokens.colorNeutralBackground1Selected, + color: tokens.colorNeutralForeground3Selected, + ':hover': { + backgroundColor: tokens.colorNeutralBackground1Hover, + }, + }, + transparent: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, }); const useRootCheckedDisabledStyles = makeStyles({ - base: { - ":hover": { - [`& .${iconFilledClassName}`]: displayInline, - [`& .${iconRegularClassName}`]: displayNone, - }, - ":hover:active": { - [`& .${iconFilledClassName}`]: displayInline, - [`& .${iconRegularClassName}`]: displayNone, - }, - [`:hover .${iconFilledClassName}`]: { - color: tokens.colorNeutralForegroundDisabled, - }, - [`:hover:active .${iconFilledClassName}`]: { - color: tokens.colorNeutralForegroundDisabled, - }, - }, - secondary: {}, - primary: {}, - outline: {}, - transparent: {}, - subtle: {}, - tint: { - ...shorthands.borderWidth(tokens.strokeWidthThicker), - }, - outlineColor: { - ...shorthands.borderWidth(tokens.strokeWidthThicker), - }, + base: { + ':hover': { + [`& .${iconFilledClassName}`]: displayInline, + [`& .${iconRegularClassName}`]: displayNone, + }, + ':hover:active': { + [`& .${iconFilledClassName}`]: displayInline, + [`& .${iconRegularClassName}`]: displayNone, + }, + [`:hover .${iconFilledClassName}`]: { + color: tokens.colorNeutralForegroundDisabled, + }, + [`:hover:active .${iconFilledClassName}`]: { + color: tokens.colorNeutralForegroundDisabled, + }, + }, + secondary: {}, + primary: {}, + outline: {}, + transparent: {}, + subtle: {}, + tint: { + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, + outlineColor: { + ...shorthands.borderWidth(tokens.strokeWidthThicker), + }, }); const useIconCheckedStyles = makeStyles({ - outline: { - color: tokens.colorCompoundBrandForeground1Pressed, - }, + outline: { + color: tokens.colorCompoundBrandForeground1Pressed, + }, }); export const useToggleButtonStyles = ( - state: ToggleButtonState, + state: ToggleButtonState ): ToggleButtonState => { - "use no memo"; + 'use no memo'; - const rootCheckedStyles = useRootCheckedStyles(); - const iconCheckedStyles = useIconCheckedStyles(); - const checkedDisabledStyles = useRootCheckedDisabledStyles(); - const { appearance, checked, disabled, disabledFocusable } = state; - const showAsDisabled = disabled || disabledFocusable; + const rootCheckedStyles = useRootCheckedStyles(); + const iconCheckedStyles = useIconCheckedStyles(); + const checkedDisabledStyles = useRootCheckedDisabledStyles(); + const { appearance, checked, disabled, disabledFocusable } = state; + const showAsDisabled = disabled || disabledFocusable; - useButtonStyles(state); + useButtonStyles(state); - state.root.className = mergeClasses( - state.root.className, - toggleButtonClassNames.root, - checked && !showAsDisabled && rootCheckedStyles.base, - checked && !showAsDisabled && rootCheckedStyles[appearance], - checked && showAsDisabled && checkedDisabledStyles.base, - checked && showAsDisabled && checkedDisabledStyles[appearance], - ); + state.root.className = mergeClasses( + state.root.className, + toggleButtonClassNames.root, + checked && !showAsDisabled && rootCheckedStyles.base, + checked && !showAsDisabled && rootCheckedStyles[appearance], + checked && showAsDisabled && checkedDisabledStyles.base, + checked && showAsDisabled && checkedDisabledStyles[appearance] + ); - if (state.icon) { - state.icon.className = mergeClasses( - state.icon.className, - toggleButtonClassNames.icon, - checked && appearance === "outline" && iconCheckedStyles.outline, - ); - } + if (state.icon) { + state.icon.className = mergeClasses( + state.icon.className, + toggleButtonClassNames.icon, + checked && appearance === 'outline' && iconCheckedStyles.outline + ); + } - return state; + return state; }; diff --git a/packages/react-cap-theme/src/components/react-button/index.ts b/packages/react-cap-theme/src/components/react-button/index.ts index ccaf6411..81a1f07e 100644 --- a/packages/react-cap-theme/src/components/react-button/index.ts +++ b/packages/react-cap-theme/src/components/react-button/index.ts @@ -1,45 +1,45 @@ export { - Button, - buttonClassNames, - renderButton, - useButton, - useButtonStyles, -} from "./Button"; + Button, + buttonClassNames, + renderButton, + useButton, + useButtonStyles, +} from './Button'; export type { - ButtonProps, - ButtonSlots, - ButtonState, - ButtonAppearance, -} from "./Button"; + ButtonProps, + ButtonSlots, + ButtonState, + ButtonAppearance, +} from './Button'; export { - MenuButton, - menuButtonClassNames, - renderMenuButton, - useMenuButton, - useMenuButtonStyles, -} from "./MenuButton"; + MenuButton, + menuButtonClassNames, + renderMenuButton, + useMenuButton, + useMenuButtonStyles, +} from './MenuButton'; export type { - MenuButtonProps, - MenuButtonSlots, - MenuButtonState, -} from "./MenuButton"; + MenuButtonProps, + MenuButtonSlots, + MenuButtonState, +} from './MenuButton'; export { - SplitButton, - splitButtonClassNames, - renderSplitButton, - useSplitButton, - useSplitButtonStyles, -} from "./SplitButton"; + SplitButton, + splitButtonClassNames, + renderSplitButton, + useSplitButton, + useSplitButtonStyles, +} from './SplitButton'; export type { - SplitButtonProps, - SplitButtonSlots, - SplitButtonState, -} from "./SplitButton"; + SplitButtonProps, + SplitButtonSlots, + SplitButtonState, +} from './SplitButton'; export { - ToggleButton, - toggleButtonClassNames, - renderToggleButton, - useToggleButton, - useToggleButtonStyles, -} from "./ToggleButton"; -export type { ToggleButtonProps, ToggleButtonState } from "./ToggleButton"; + ToggleButton, + toggleButtonClassNames, + renderToggleButton, + useToggleButton, + useToggleButtonStyles, +} from './ToggleButton'; +export type { ToggleButtonProps, ToggleButtonState } from './ToggleButton'; diff --git a/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts b/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts index b7553cc4..f0573658 100644 --- a/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts +++ b/packages/react-cap-theme/src/components/tokens/alias/colors/darkColor.ts @@ -1,49 +1,49 @@ -import type { BrandVariants } from "@fluentui/tokens"; -import type { ColorTokens } from "../../types"; +import type { BrandVariants } from '@fluentui/tokens'; +import type { ColorTokens } from '../../types'; export const generateBrandColorTokens = ( - brand: BrandVariants, + brand: BrandVariants ): Partial => ({ - colorNeutralForeground2BrandHover: brand[110], - colorNeutralForeground2BrandPressed: brand[90], - colorNeutralForeground2BrandSelected: brand[110], - colorNeutralForeground3BrandHover: brand[110], - colorNeutralForeground3BrandPressed: brand[90], - colorNeutralForeground3BrandSelected: brand[110], - colorBrandForegroundLink: brand[110], - colorBrandForegroundLinkHover: brand[130], - colorBrandForegroundLinkPressed: brand[100], - colorBrandForegroundLinkSelected: brand[110], - colorCompoundBrandForeground1: brand[110], - colorCompoundBrandForeground1Hover: brand[130], - colorCompoundBrandForeground1Pressed: brand[100], - colorBrandForeground1: brand[110], - colorBrandForeground2: brand[120], - colorBrandForeground2Hover: brand[140], - colorBrandForeground2Pressed: brand[160], - colorBrandForegroundOnLight: brand[80], - colorBrandForegroundOnLightHover: brand[70], - colorBrandForegroundOnLightPressed: brand[40], - colorBrandForegroundOnLightSelected: brand[60], - colorBrandBackground: brand[70], - colorBrandBackgroundHover: brand[80], - colorBrandBackgroundPressed: brand[40], - colorBrandBackgroundSelected: brand[60], - colorCompoundBrandBackground: brand[110], - colorCompoundBrandBackgroundHover: brand[130], - colorCompoundBrandBackgroundPressed: brand[90], - colorBrandBackgroundStatic: brand[80], - colorBrandBackground2: brand[20], - colorBrandBackground2Hover: brand[40], - colorBrandBackground2Pressed: brand[10], - colorBrandBackgroundInvertedHover: brand[160], - colorBrandBackgroundInvertedPressed: brand[140], - colorBrandBackgroundInvertedSelected: brand[160], - colorBrandStroke1: brand[110], - colorBrandStroke2: brand[50], - colorBrandStroke2Hover: brand[70], - colorBrandStroke2Pressed: brand[40], - colorCompoundBrandStroke: brand[110], - colorCompoundBrandStrokeHover: brand[130], - colorCompoundBrandStrokePressed: brand[100], + colorNeutralForeground2BrandHover: brand[110], + colorNeutralForeground2BrandPressed: brand[90], + colorNeutralForeground2BrandSelected: brand[110], + colorNeutralForeground3BrandHover: brand[110], + colorNeutralForeground3BrandPressed: brand[90], + colorNeutralForeground3BrandSelected: brand[110], + colorBrandForegroundLink: brand[110], + colorBrandForegroundLinkHover: brand[130], + colorBrandForegroundLinkPressed: brand[100], + colorBrandForegroundLinkSelected: brand[110], + colorCompoundBrandForeground1: brand[110], + colorCompoundBrandForeground1Hover: brand[130], + colorCompoundBrandForeground1Pressed: brand[100], + colorBrandForeground1: brand[110], + colorBrandForeground2: brand[120], + colorBrandForeground2Hover: brand[140], + colorBrandForeground2Pressed: brand[160], + colorBrandForegroundOnLight: brand[80], + colorBrandForegroundOnLightHover: brand[70], + colorBrandForegroundOnLightPressed: brand[40], + colorBrandForegroundOnLightSelected: brand[60], + colorBrandBackground: brand[70], + colorBrandBackgroundHover: brand[80], + colorBrandBackgroundPressed: brand[40], + colorBrandBackgroundSelected: brand[60], + colorCompoundBrandBackground: brand[110], + colorCompoundBrandBackgroundHover: brand[130], + colorCompoundBrandBackgroundPressed: brand[90], + colorBrandBackgroundStatic: brand[80], + colorBrandBackground2: brand[20], + colorBrandBackground2Hover: brand[40], + colorBrandBackground2Pressed: brand[10], + colorBrandBackgroundInvertedHover: brand[160], + colorBrandBackgroundInvertedPressed: brand[140], + colorBrandBackgroundInvertedSelected: brand[160], + colorBrandStroke1: brand[110], + colorBrandStroke2: brand[50], + colorBrandStroke2Hover: brand[70], + colorBrandStroke2Pressed: brand[40], + colorCompoundBrandStroke: brand[110], + colorCompoundBrandStrokeHover: brand[130], + colorCompoundBrandStrokePressed: brand[100], }); diff --git a/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts b/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts index db8fd60f..89c0ea76 100644 --- a/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts +++ b/packages/react-cap-theme/src/components/tokens/alias/colors/lightColor.ts @@ -1,52 +1,52 @@ -import type { BrandVariants } from "@fluentui/tokens"; -import type { ColorTokens } from "../../types"; +import type { BrandVariants } from '@fluentui/tokens'; +import type { ColorTokens } from '../../types'; export const generateBrandColorTokens = ( - brand: BrandVariants, + brand: BrandVariants ): Partial => ({ - colorNeutralForeground2BrandHover: brand[80], - colorNeutralForeground2BrandPressed: brand[70], - colorNeutralForeground2BrandSelected: brand[80], - colorNeutralForeground3BrandHover: brand[80], - colorNeutralForeground3BrandPressed: brand[70], - colorNeutralForeground3BrandSelected: brand[80], - colorBrandForegroundLink: brand[70], - colorBrandForegroundLinkHover: brand[60], - colorBrandForegroundLinkPressed: brand[40], - colorBrandForegroundLinkSelected: brand[70], - colorCompoundBrandForeground1: brand[80], - colorCompoundBrandForeground1Hover: brand[70], - colorCompoundBrandForeground1Pressed: brand[40], - colorBrandForeground1: brand[80], - colorBrandForeground2: brand[70], - colorBrandForeground2Hover: brand[60], - colorBrandForeground2Pressed: brand[30], - colorBrandForegroundInverted: brand[110], - colorBrandForegroundInvertedHover: brand[130], - colorBrandForegroundInvertedPressed: brand[100], - colorBrandForegroundOnLight: brand[80], - colorBrandForegroundOnLightHover: brand[70], - colorBrandForegroundOnLightPressed: brand[40], - colorBrandForegroundOnLightSelected: brand[60], - colorBrandBackground: brand[80], - colorBrandBackgroundHover: brand[70], - colorBrandBackgroundPressed: brand[40], - colorBrandBackgroundSelected: brand[60], - colorCompoundBrandBackground: brand[80], - colorCompoundBrandBackgroundHover: brand[70], - colorCompoundBrandBackgroundPressed: brand[40], - colorBrandBackgroundStatic: brand[80], - colorBrandBackground2: brand[160], - colorBrandBackground2Hover: brand[150], - colorBrandBackground2Pressed: brand[130], - colorBrandBackgroundInvertedHover: brand[160], - colorBrandBackgroundInvertedPressed: brand[140], - colorBrandBackgroundInvertedSelected: brand[160], - colorBrandStroke1: brand[80], - colorBrandStroke2: brand[140], - colorBrandStroke2Hover: brand[130], - colorBrandStroke2Pressed: brand[90], - colorCompoundBrandStroke: brand[80], - colorCompoundBrandStrokeHover: brand[70], - colorCompoundBrandStrokePressed: brand[40], + colorNeutralForeground2BrandHover: brand[80], + colorNeutralForeground2BrandPressed: brand[70], + colorNeutralForeground2BrandSelected: brand[80], + colorNeutralForeground3BrandHover: brand[80], + colorNeutralForeground3BrandPressed: brand[70], + colorNeutralForeground3BrandSelected: brand[80], + colorBrandForegroundLink: brand[70], + colorBrandForegroundLinkHover: brand[60], + colorBrandForegroundLinkPressed: brand[40], + colorBrandForegroundLinkSelected: brand[70], + colorCompoundBrandForeground1: brand[80], + colorCompoundBrandForeground1Hover: brand[70], + colorCompoundBrandForeground1Pressed: brand[40], + colorBrandForeground1: brand[80], + colorBrandForeground2: brand[70], + colorBrandForeground2Hover: brand[60], + colorBrandForeground2Pressed: brand[30], + colorBrandForegroundInverted: brand[110], + colorBrandForegroundInvertedHover: brand[130], + colorBrandForegroundInvertedPressed: brand[100], + colorBrandForegroundOnLight: brand[80], + colorBrandForegroundOnLightHover: brand[70], + colorBrandForegroundOnLightPressed: brand[40], + colorBrandForegroundOnLightSelected: brand[60], + colorBrandBackground: brand[80], + colorBrandBackgroundHover: brand[70], + colorBrandBackgroundPressed: brand[40], + colorBrandBackgroundSelected: brand[60], + colorCompoundBrandBackground: brand[80], + colorCompoundBrandBackgroundHover: brand[70], + colorCompoundBrandBackgroundPressed: brand[40], + colorBrandBackgroundStatic: brand[80], + colorBrandBackground2: brand[160], + colorBrandBackground2Hover: brand[150], + colorBrandBackground2Pressed: brand[130], + colorBrandBackgroundInvertedHover: brand[160], + colorBrandBackgroundInvertedPressed: brand[140], + colorBrandBackgroundInvertedSelected: brand[160], + colorBrandStroke1: brand[80], + colorBrandStroke2: brand[140], + colorBrandStroke2Hover: brand[130], + colorBrandStroke2Pressed: brand[90], + colorCompoundBrandStroke: brand[80], + colorCompoundBrandStrokeHover: brand[70], + colorCompoundBrandStrokePressed: brand[40], }); diff --git a/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts index 33644b6d..8cd3cb5f 100644 --- a/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts +++ b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontFamily.ts @@ -1,23 +1,23 @@ -import type { FontVariants, FontFamilyCustomFontTokens } from "../../types"; +import type { FontVariants, FontFamilyCustomFontTokens } from '../../types'; export const generateTokens = ( - font: FontVariants, + font: FontVariants ): FontFamilyCustomFontTokens => ({ - fontFamilyCustomFont100: font[100].fontFamily, - fontFamilyCustomFont200: font[200].fontFamily, - fontFamilyCustomFont300: font[300].fontFamily, - fontFamilyCustomFont400: font[400].fontFamily, - fontFamilyCustomFont500: font[500].fontFamily, - fontFamilyCustomFont600: font[600].fontFamily, - fontFamilyCustomFont700: font[700].fontFamily, - fontFamilyCustomFont800: font[800].fontFamily, - fontFamilyCustomFont900: font[900].fontFamily, - fontFamilyCustomFont1000: font[1000].fontFamily, - fontFamilyCustomFont1100: font[1100].fontFamily, - fontFamilyCustomFont1200: font[1200].fontFamily, - fontFamilyCustomFont1300: font[1300].fontFamily, - fontFamilyCustomFont1400: font[1400].fontFamily, - fontFamilyCustomFont1500: font[1500].fontFamily, - fontFamilyCustomFont1600: font[1600].fontFamily, - fontFamilyCustomFont1700: font[1700].fontFamily, + fontFamilyCustomFont100: font[100].fontFamily, + fontFamilyCustomFont200: font[200].fontFamily, + fontFamilyCustomFont300: font[300].fontFamily, + fontFamilyCustomFont400: font[400].fontFamily, + fontFamilyCustomFont500: font[500].fontFamily, + fontFamilyCustomFont600: font[600].fontFamily, + fontFamilyCustomFont700: font[700].fontFamily, + fontFamilyCustomFont800: font[800].fontFamily, + fontFamilyCustomFont900: font[900].fontFamily, + fontFamilyCustomFont1000: font[1000].fontFamily, + fontFamilyCustomFont1100: font[1100].fontFamily, + fontFamilyCustomFont1200: font[1200].fontFamily, + fontFamilyCustomFont1300: font[1300].fontFamily, + fontFamilyCustomFont1400: font[1400].fontFamily, + fontFamilyCustomFont1500: font[1500].fontFamily, + fontFamilyCustomFont1600: font[1600].fontFamily, + fontFamilyCustomFont1700: font[1700].fontFamily, }); diff --git a/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts index 0b62ccd4..0ef4dd93 100644 --- a/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts +++ b/packages/react-cap-theme/src/components/tokens/alias/fonts/fontWeight.ts @@ -1,22 +1,22 @@ import type { - Font, - FontVariants, - FontWeightCustomFontTokens, -} from "../../types"; + Font, + FontVariants, + FontWeightCustomFontTokens, +} from '../../types'; export const generateTokens = ( - font: FontVariants, + font: FontVariants ): Partial => { - const tokens: Partial = {}; - const fontKeys: string[] = Object.keys(font); + const tokens: Partial = {}; + const fontKeys: string[] = Object.keys(font); - fontKeys.forEach((key) => { - const fontKey: Font = Number(key) as Font; - const value: number | undefined = font[fontKey].fontWeight; - if (value !== undefined) { - tokens[`fontWeightCustomFont${fontKey}`] = value; - } - }); + fontKeys.forEach((key) => { + const fontKey: Font = Number(key) as Font; + const value: number | undefined = font[fontKey].fontWeight; + if (value !== undefined) { + tokens[`fontWeightCustomFont${fontKey}`] = value; + } + }); - return tokens; + return tokens; }; diff --git a/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts b/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts index 61e5ee7c..90bb81d4 100644 --- a/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts +++ b/packages/react-cap-theme/src/components/tokens/alias/fonts/index.ts @@ -1,2 +1,2 @@ -export { generateTokens as generateFontFamilyTokens } from "./fontFamily"; -export { generateTokens as generateFontWeightTokens } from "./fontWeight"; +export { generateTokens as generateFontFamilyTokens } from './fontFamily'; +export { generateTokens as generateFontWeightTokens } from './fontWeight'; diff --git a/packages/react-cap-theme/src/components/tokens/global/brandColors.ts b/packages/react-cap-theme/src/components/tokens/global/brandColors.ts index 7b075164..a485ff68 100644 --- a/packages/react-cap-theme/src/components/tokens/global/brandColors.ts +++ b/packages/react-cap-theme/src/components/tokens/global/brandColors.ts @@ -1,22 +1,22 @@ -import type { BrandVariants } from "@fluentui/tokens"; +import type { BrandVariants } from '@fluentui/tokens'; export const brandTeal: BrandVariants = { - 10: "#091e1f", - 20: "#0b2829", - 30: "#0d3133", - 40: "#0e3d40", - 50: "#0f4b4f", - 60: "#0f575c", - 70: "#0e656b", - 80: "#0c757d", - 90: "#17878f", - 100: "#2799a1", - 110: "#3babb2", - 120: "#55b9c2", - 130: "#74ccd4", - 140: "#94dae0", - 150: "#b6eaf0", - 160: "#d7f2f5", + 10: '#091e1f', + 20: '#0b2829', + 30: '#0d3133', + 40: '#0e3d40', + 50: '#0f4b4f', + 60: '#0f575c', + 70: '#0e656b', + 80: '#0c757d', + 90: '#17878f', + 100: '#2799a1', + 110: '#3babb2', + 120: '#55b9c2', + 130: '#74ccd4', + 140: '#94dae0', + 150: '#b6eaf0', + 160: '#d7f2f5', }; export const brandCAP: BrandVariants = brandTeal; diff --git a/packages/react-cap-theme/src/components/tokens/global/fonts.ts b/packages/react-cap-theme/src/components/tokens/global/fonts.ts index 2b211370..782eaa56 100644 --- a/packages/react-cap-theme/src/components/tokens/global/fonts.ts +++ b/packages/react-cap-theme/src/components/tokens/global/fonts.ts @@ -1,18 +1,18 @@ import type { - FontSizeTokens, - FontStyleTokens, - LineHeightTokens, -} from "../types"; + FontSizeTokens, + FontStyleTokens, + LineHeightTokens, +} from '../types'; -export const fontSizes: Pick = { - fontSizeBase450: "18px", +export const fontSizes: Pick = { + fontSizeBase450: '18px', }; export const fontStyles: FontStyleTokens = { - fontStyleRegular: "normal", - fontStyleItalic: "italic", + fontStyleRegular: 'normal', + fontStyleItalic: 'italic', }; -export const lineHeights: Pick = { - lineHeightBase450: "24px", +export const lineHeights: Pick = { + lineHeightBase450: '24px', }; diff --git a/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts b/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts index a163397c..3c83a730 100644 --- a/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts +++ b/packages/react-cap-theme/src/components/tokens/global/neutralColors.ts @@ -1,59 +1,59 @@ -import type { Greys } from "../types"; +import type { Greys } from '../types'; -export const black: string = "#000000"; +export const black = '#000000'; -export const white: string = "#ffffff"; +export const white = '#ffffff'; export const grey: Record = { - "0": black, - "2": "#050505", - "4": "#0a0a0a", - "6": "#0f0f0f", - "8": "#141414", - "10": "#1a1a1a", - "12": "#1f1f1f", - "14": "#242424", - "16": "#292929", - "18": "#2e2e2e", - "20": "#333333", - "22": "#383838", - "24": "#3d3d3d", - "26": "#424242", - "28": "#474747", - "30": "#4d4d4d", - "32": "#525252", - "34": "#575757", - "36": "#5c5c5c", - "38": "#616161", - "40": "#666666", - "42": "#6b6b6b", - "44": "#707070", - "46": "#757575", - "48": "#7a7a7a", - "50": "#808080", - "52": "#858585", - "54": "#8a8a8a", - "56": "#8f8f8f", - "58": "#949494", - "60": "#999999", - "62": "#9e9e9e", - "64": "#a3a3a3", - "66": "#a8a8a8", - "68": "#adadad", - "70": "#b3b3b3", - "72": "#b8b8b8", - "74": "#bdbdbd", - "76": "#c2c2c2", - "78": "#c7c7c7", - "80": "#cccccc", - "82": "#d1d1d1", - "84": "#d6d6d6", - "86": "#dbdbdb", - "88": "#e0e0e0", - "90": "#e6e6e6", - "92": "#ebebeb", - "94": "#f0f0f0", - "96": "#f5f5f5", - "98": "#fafafa", - "100": white, + '0': black, + '2': '#050505', + '4': '#0a0a0a', + '6': '#0f0f0f', + '8': '#141414', + '10': '#1a1a1a', + '12': '#1f1f1f', + '14': '#242424', + '16': '#292929', + '18': '#2e2e2e', + '20': '#333333', + '22': '#383838', + '24': '#3d3d3d', + '26': '#424242', + '28': '#474747', + '30': '#4d4d4d', + '32': '#525252', + '34': '#575757', + '36': '#5c5c5c', + '38': '#616161', + '40': '#666666', + '42': '#6b6b6b', + '44': '#707070', + '46': '#757575', + '48': '#7a7a7a', + '50': '#808080', + '52': '#858585', + '54': '#8a8a8a', + '56': '#8f8f8f', + '58': '#949494', + '60': '#999999', + '62': '#9e9e9e', + '64': '#a3a3a3', + '66': '#a8a8a8', + '68': '#adadad', + '70': '#b3b3b3', + '72': '#b8b8b8', + '74': '#bdbdbd', + '76': '#c2c2c2', + '78': '#c7c7c7', + '80': '#cccccc', + '82': '#d1d1d1', + '84': '#d6d6d6', + '86': '#dbdbdb', + '88': '#e0e0e0', + '90': '#e6e6e6', + '92': '#ebebeb', + '94': '#f0f0f0', + '96': '#f5f5f5', + '98': '#fafafa', + '100': white, }; diff --git a/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts b/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts index 72afb40a..bbaf5a77 100644 --- a/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts +++ b/packages/react-cap-theme/src/components/tokens/global/typographyStyles.ts @@ -1,148 +1,148 @@ -import { typographyStyles as defaultTypographyStyles } from "@fluentui/tokens"; -import { tokens } from "../tokens"; -import type { Font, TypographyStyle, TypographyStyles } from "../types"; +import { typographyStyles as defaultTypographyStyles } from '@fluentui/tokens'; +import { tokens } from '../tokens'; +import type { Font, TypographyStyle, TypographyStyles } from '../types'; export const typographyStyles: TypographyStyles = { - ...defaultTypographyStyles, - custom: { - body1: createVariableFallback(700, { - ...defaultTypographyStyles.body1, - fontStyle: tokens.fontStyleRegular, - }), - body1Mono: createVariableFallback(700, { - ...defaultTypographyStyles.body1, - fontFamily: tokens.fontFamilyMonospace, - fontStyle: tokens.fontStyleRegular, - }), - body1Strong: createVariableFallback(700, { - ...defaultTypographyStyles.body1Strong, - fontStyle: tokens.fontStyleRegular, - }), - body1Stronger: createVariableFallback(700, { - ...defaultTypographyStyles.body1Stronger, - fontStyle: tokens.fontStyleRegular, - }), - body2: createVariableFallback(800, { - ...defaultTypographyStyles.body2, - fontStyle: tokens.fontStyleRegular, - }), - body2Italic: createVariableFallback(800, { - ...defaultTypographyStyles.body2, - fontStyle: tokens.fontStyleItalic, - }), - body2Mono: createVariableFallback(800, { - ...defaultTypographyStyles.body2, - fontFamily: tokens.fontFamilyMonospace, - fontStyle: tokens.fontStyleRegular, - }), - body3: createVariableFallback(900, { - fontFamily: tokens.fontFamilyBase, - fontSize: tokens.fontSizeBase450, - fontStyle: tokens.fontStyleRegular, - fontWeight: tokens.fontWeightRegular, - lineHeight: tokens.lineHeightBase450, - }), - body3Strong: createVariableFallback(900, { - fontFamily: tokens.fontFamilyBase, - fontSize: tokens.fontSizeBase450, - fontStyle: tokens.fontStyleRegular, - fontWeight: tokens.fontWeightSemibold, - lineHeight: tokens.lineHeightBase450, - }), - buttonLarge: createVariableFallback(600, { - ...defaultTypographyStyles.subtitle2, - fontStyle: tokens.fontStyleRegular, - }), - buttonMedium: createVariableFallback(500, { - ...defaultTypographyStyles.body1Strong, - fontStyle: tokens.fontStyleRegular, - }), - buttonSmall: createVariableFallback(400, { - ...defaultTypographyStyles.caption1, - fontStyle: tokens.fontStyleRegular, - }), - caption1: createVariableFallback(200, { - ...defaultTypographyStyles.caption1, - fontStyle: tokens.fontStyleRegular, - }), - caption1Strong: createVariableFallback(200, { - ...defaultTypographyStyles.caption1Strong, - fontStyle: tokens.fontStyleRegular, - }), - caption1Stronger: createVariableFallback(200, { - ...defaultTypographyStyles.caption1Stronger, - fontStyle: tokens.fontStyleRegular, - }), - caption2: createVariableFallback(100, { - ...defaultTypographyStyles.caption2, - fontStyle: tokens.fontStyleRegular, - }), - caption2Strong: createVariableFallback(100, { - ...defaultTypographyStyles.caption2Strong, - fontStyle: tokens.fontStyleRegular, - }), - heading2: createVariableFallback(1300, { - ...defaultTypographyStyles.title2, - fontStyle: tokens.fontStyleRegular, - }), - heading3: createVariableFallback(1200, { - ...defaultTypographyStyles.title3, - fontStyle: tokens.fontStyleRegular, - }), - heading4: createVariableFallback(1100, { - ...defaultTypographyStyles.subtitle1, - fontStyle: tokens.fontStyleRegular, - }), - subtitle1: createVariableFallback(1100, { - ...defaultTypographyStyles.subtitle1, - fontStyle: tokens.fontStyleRegular, - }), - subtitle1Italic: createVariableFallback(1100, { - ...defaultTypographyStyles.subtitle1, - fontStyle: tokens.fontStyleItalic, - }), - subtitle2: createVariableFallback(1000, { - ...defaultTypographyStyles.subtitle2, - fontStyle: tokens.fontStyleRegular, - }), - subtitle2Stronger: createVariableFallback(1000, { - ...defaultTypographyStyles.subtitle2Stronger, - fontStyle: tokens.fontStyleRegular, - }), - title1: createVariableFallback(1400, { - ...defaultTypographyStyles.title1, - fontStyle: tokens.fontStyleRegular, - }), - title2: createVariableFallback(1300, { - ...defaultTypographyStyles.title2, - fontStyle: tokens.fontStyleRegular, - }), - title3: createVariableFallback(1200, { - ...defaultTypographyStyles.title3, - fontStyle: tokens.fontStyleRegular, - }), - largeTitle: createVariableFallback(1500, { - ...defaultTypographyStyles.largeTitle, - fontStyle: tokens.fontStyleRegular, - }), - display: createVariableFallback(1600, { - ...defaultTypographyStyles.display, - fontStyle: tokens.fontStyleRegular, - }), - webPartHeader: createVariableFallback(1100, { - ...defaultTypographyStyles.subtitle1, - fontStyle: tokens.fontStyleRegular, - }), - }, + ...defaultTypographyStyles, + custom: { + body1: createVariableFallback(700, { + ...defaultTypographyStyles.body1, + fontStyle: tokens.fontStyleRegular, + }), + body1Mono: createVariableFallback(700, { + ...defaultTypographyStyles.body1, + fontFamily: tokens.fontFamilyMonospace, + fontStyle: tokens.fontStyleRegular, + }), + body1Strong: createVariableFallback(700, { + ...defaultTypographyStyles.body1Strong, + fontStyle: tokens.fontStyleRegular, + }), + body1Stronger: createVariableFallback(700, { + ...defaultTypographyStyles.body1Stronger, + fontStyle: tokens.fontStyleRegular, + }), + body2: createVariableFallback(800, { + ...defaultTypographyStyles.body2, + fontStyle: tokens.fontStyleRegular, + }), + body2Italic: createVariableFallback(800, { + ...defaultTypographyStyles.body2, + fontStyle: tokens.fontStyleItalic, + }), + body2Mono: createVariableFallback(800, { + ...defaultTypographyStyles.body2, + fontFamily: tokens.fontFamilyMonospace, + fontStyle: tokens.fontStyleRegular, + }), + body3: createVariableFallback(900, { + fontFamily: tokens.fontFamilyBase, + fontSize: tokens.fontSizeBase450, + fontStyle: tokens.fontStyleRegular, + fontWeight: tokens.fontWeightRegular, + lineHeight: tokens.lineHeightBase450, + }), + body3Strong: createVariableFallback(900, { + fontFamily: tokens.fontFamilyBase, + fontSize: tokens.fontSizeBase450, + fontStyle: tokens.fontStyleRegular, + fontWeight: tokens.fontWeightSemibold, + lineHeight: tokens.lineHeightBase450, + }), + buttonLarge: createVariableFallback(600, { + ...defaultTypographyStyles.subtitle2, + fontStyle: tokens.fontStyleRegular, + }), + buttonMedium: createVariableFallback(500, { + ...defaultTypographyStyles.body1Strong, + fontStyle: tokens.fontStyleRegular, + }), + buttonSmall: createVariableFallback(400, { + ...defaultTypographyStyles.caption1, + fontStyle: tokens.fontStyleRegular, + }), + caption1: createVariableFallback(200, { + ...defaultTypographyStyles.caption1, + fontStyle: tokens.fontStyleRegular, + }), + caption1Strong: createVariableFallback(200, { + ...defaultTypographyStyles.caption1Strong, + fontStyle: tokens.fontStyleRegular, + }), + caption1Stronger: createVariableFallback(200, { + ...defaultTypographyStyles.caption1Stronger, + fontStyle: tokens.fontStyleRegular, + }), + caption2: createVariableFallback(100, { + ...defaultTypographyStyles.caption2, + fontStyle: tokens.fontStyleRegular, + }), + caption2Strong: createVariableFallback(100, { + ...defaultTypographyStyles.caption2Strong, + fontStyle: tokens.fontStyleRegular, + }), + heading2: createVariableFallback(1300, { + ...defaultTypographyStyles.title2, + fontStyle: tokens.fontStyleRegular, + }), + heading3: createVariableFallback(1200, { + ...defaultTypographyStyles.title3, + fontStyle: tokens.fontStyleRegular, + }), + heading4: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleRegular, + }), + subtitle1: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleRegular, + }), + subtitle1Italic: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleItalic, + }), + subtitle2: createVariableFallback(1000, { + ...defaultTypographyStyles.subtitle2, + fontStyle: tokens.fontStyleRegular, + }), + subtitle2Stronger: createVariableFallback(1000, { + ...defaultTypographyStyles.subtitle2Stronger, + fontStyle: tokens.fontStyleRegular, + }), + title1: createVariableFallback(1400, { + ...defaultTypographyStyles.title1, + fontStyle: tokens.fontStyleRegular, + }), + title2: createVariableFallback(1300, { + ...defaultTypographyStyles.title2, + fontStyle: tokens.fontStyleRegular, + }), + title3: createVariableFallback(1200, { + ...defaultTypographyStyles.title3, + fontStyle: tokens.fontStyleRegular, + }), + largeTitle: createVariableFallback(1500, { + ...defaultTypographyStyles.largeTitle, + fontStyle: tokens.fontStyleRegular, + }), + display: createVariableFallback(1600, { + ...defaultTypographyStyles.display, + fontStyle: tokens.fontStyleRegular, + }), + webPartHeader: createVariableFallback(1100, { + ...defaultTypographyStyles.subtitle1, + fontStyle: tokens.fontStyleRegular, + }), + }, }; function createVariableFallback( - font: Font, - style: TypographyStyle, + font: Font, + style: TypographyStyle ): TypographyStyle { - return { - ...style, - fontFamily: `var(--fontFamilyCustomFont${font}, ${style.fontFamily})`, - fontWeight: `var(--fontWeightCustomFont${font}, ${style.fontWeight})`, - }; + return { + ...style, + fontFamily: `var(--fontFamilyCustomFont${font}, ${style.fontFamily})`, + fontWeight: `var(--fontWeightCustomFont${font}, ${style.fontWeight})`, + }; } diff --git a/packages/react-cap-theme/src/components/tokens/index.ts b/packages/react-cap-theme/src/components/tokens/index.ts index 688923e6..1f968917 100644 --- a/packages/react-cap-theme/src/components/tokens/index.ts +++ b/packages/react-cap-theme/src/components/tokens/index.ts @@ -1,79 +1,78 @@ - -export { black, white, grey } from "./global/neutralColors"; -export { typographyStyles } from "./global/typographyStyles"; -export { darkTheme } from "./themes/darkTheme"; -export { lightTheme } from "./themes/lightTheme"; -export { themeToTokensObject } from "./themeToTokensObject"; -export { tokens } from "./tokens"; +export { black, white, grey } from './global/neutralColors'; +export { typographyStyles } from './global/typographyStyles'; +export { darkTheme } from './themes/darkTheme'; +export { lightTheme } from './themes/lightTheme'; +export { themeToTokensObject } from './themeToTokensObject'; +export { tokens } from './tokens'; export type { - BorderRadiusTokens, - Brands, - BrandVariants, - ColorPaletteAnchor, - ColorPaletteBeige, - ColorPaletteBerry, - ColorPaletteBlue, - ColorPaletteBrass, - ColorPaletteBrown, - ColorPaletteCornflower, - ColorPaletteCranberry, - ColorPaletteDarkGreen, - ColorPaletteDarkOrange, - ColorPaletteDarkRed, - ColorPaletteForest, - ColorPaletteGrape, - ColorPaletteGold, - ColorPaletteGreen, - ColorPaletteLavender, - ColorPaletteLilac, - ColorPaletteLightGreen, - ColorPaletteLightTeal, - ColorPaletteMagenta, - ColorPaletteMarigold, - ColorPaletteMink, - ColorPaletteNavy, - ColorPalettePeach, - ColorPalettePink, - ColorPalettePlatinum, - ColorPalettePlum, - ColorPalettePumpkin, - ColorPalettePurple, - ColorPaletteRed, - ColorPaletteRoyalBlue, - ColorPaletteSeafoam, - ColorPaletteSteel, - ColorPaletteTeal, - ColorPaletteTokens, - ColorPaletteYellow, - ColorTokens, - CurveTokens, - CustomizableTypographyStyle, - CustomizableTypographyStyles, - DurationTokens, - Font, - FontFamilyCustomFontTokens, - FontFamilyTokens, - FontSizeTokens, - FontStyleTokens, - FontVariants, - FontWeightCustomFontTokens, - FontWeightTokens, - Greys, - HorizontalSpacingTokens, - LineHeightTokens, - PartialTheme, - ShadowBrandTokens, - ShadowTokens, - SpacingTokens, - StrokeWidthTokens, - Theme, - TokenName, - TypographyStyle, - TypographyStyles, - VerticalSpacingTokens, - ZIndexTokens, -} from "./types"; -export { applyFonts } from "./utils/applyFonts"; -export { createDarkTheme } from "./utils/createDarkTheme"; -export { createLightTheme } from "./utils/createLightTheme"; -export { extractNeutralTokens } from "./utils/extractNeutralTokens"; + BorderRadiusTokens, + Brands, + BrandVariants, + ColorPaletteAnchor, + ColorPaletteBeige, + ColorPaletteBerry, + ColorPaletteBlue, + ColorPaletteBrass, + ColorPaletteBrown, + ColorPaletteCornflower, + ColorPaletteCranberry, + ColorPaletteDarkGreen, + ColorPaletteDarkOrange, + ColorPaletteDarkRed, + ColorPaletteForest, + ColorPaletteGrape, + ColorPaletteGold, + ColorPaletteGreen, + ColorPaletteLavender, + ColorPaletteLilac, + ColorPaletteLightGreen, + ColorPaletteLightTeal, + ColorPaletteMagenta, + ColorPaletteMarigold, + ColorPaletteMink, + ColorPaletteNavy, + ColorPalettePeach, + ColorPalettePink, + ColorPalettePlatinum, + ColorPalettePlum, + ColorPalettePumpkin, + ColorPalettePurple, + ColorPaletteRed, + ColorPaletteRoyalBlue, + ColorPaletteSeafoam, + ColorPaletteSteel, + ColorPaletteTeal, + ColorPaletteTokens, + ColorPaletteYellow, + ColorTokens, + CurveTokens, + CustomizableTypographyStyle, + CustomizableTypographyStyles, + DurationTokens, + Font, + FontFamilyCustomFontTokens, + FontFamilyTokens, + FontSizeTokens, + FontStyleTokens, + FontVariants, + FontWeightCustomFontTokens, + FontWeightTokens, + Greys, + HorizontalSpacingTokens, + LineHeightTokens, + PartialTheme, + ShadowBrandTokens, + ShadowTokens, + SpacingTokens, + StrokeWidthTokens, + Theme, + TokenName, + TypographyStyle, + TypographyStyles, + VerticalSpacingTokens, + ZIndexTokens, +} from './types'; +export { applyFonts } from './utils/applyFonts'; +export { createDarkTheme } from './utils/createDarkTheme'; +export { createLightTheme } from './utils/createLightTheme'; +export { extractNeutralTokens } from './utils/extractNeutralTokens'; diff --git a/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts b/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts index 4e6a823e..e4a25fa6 100644 --- a/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts +++ b/packages/react-cap-theme/src/components/tokens/themeToTokensObject.ts @@ -1 +1 @@ -export { themeToTokensObject } from "@fluentui/tokens"; +export { themeToTokensObject } from '@fluentui/tokens'; diff --git a/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts b/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts index e650d043..1405b412 100644 --- a/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts +++ b/packages/react-cap-theme/src/components/tokens/themes/darkTheme.ts @@ -1,5 +1,5 @@ -import { brandCAP } from "../global/brandColors"; -import type { Theme } from "../types"; -import { createDarkTheme } from "../utils/createDarkTheme"; +import { brandCAP } from '../global/brandColors'; +import type { Theme } from '../types'; +import { createDarkTheme } from '../utils/createDarkTheme'; export const darkTheme: Theme = { ...createDarkTheme(brandCAP) }; diff --git a/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts b/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts index 7e4244b8..6784bc84 100644 --- a/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts +++ b/packages/react-cap-theme/src/components/tokens/themes/lightTheme.ts @@ -1,5 +1,5 @@ -import { brandCAP } from "../global/brandColors"; -import type { Theme } from "../types"; -import { createLightTheme } from "../utils/createLightTheme"; +import { brandCAP } from '../global/brandColors'; +import type { Theme } from '../types'; +import { createLightTheme } from '../utils/createLightTheme'; export const lightTheme: Theme = { ...createLightTheme(brandCAP) }; diff --git a/packages/react-cap-theme/src/components/tokens/tokens.ts b/packages/react-cap-theme/src/components/tokens/tokens.ts index a8973da9..46977844 100644 --- a/packages/react-cap-theme/src/components/tokens/tokens.ts +++ b/packages/react-cap-theme/src/components/tokens/tokens.ts @@ -1,55 +1,55 @@ -import { tokens as fluentTokens } from "@fluentui/tokens"; -import type { TokenName } from "./types"; +import { tokens as fluentTokens } from '@fluentui/tokens'; +import type { TokenName } from './types'; export const tokens: Record = { - ...fluentTokens, + ...fluentTokens, - fontFamilyCustomFont100: "var(--fontFamilyCustomFont100)", - fontFamilyCustomFont200: "var(--fontFamilyCustomFont200)", - fontFamilyCustomFont300: "var(--fontFamilyCustomFont300)", - fontFamilyCustomFont400: "var(--fontFamilyCustomFont400)", - fontFamilyCustomFont500: "var(--fontFamilyCustomFont500)", - fontFamilyCustomFont600: "var(--fontFamilyCustomFont600)", - fontFamilyCustomFont700: "var(--fontFamilyCustomFont700)", - fontFamilyCustomFont800: "var(--fontFamilyCustomFont800)", - fontFamilyCustomFont900: "var(--fontFamilyCustomFont900)", - fontFamilyCustomFont1000: "var(--fontFamilyCustomFont1000)", - fontFamilyCustomFont1100: "var(--fontFamilyCustomFont1100)", - fontFamilyCustomFont1200: "var(--fontFamilyCustomFont1200)", - fontFamilyCustomFont1300: "var(--fontFamilyCustomFont1300)", - fontFamilyCustomFont1400: "var(--fontFamilyCustomFont1400)", - fontFamilyCustomFont1500: "var(--fontFamilyCustomFont1500)", - fontFamilyCustomFont1600: "var(--fontFamilyCustomFont1600)", - fontFamilyCustomFont1700: "var(--fontFamilyCustomFont1700)", + fontFamilyCustomFont100: 'var(--fontFamilyCustomFont100)', + fontFamilyCustomFont200: 'var(--fontFamilyCustomFont200)', + fontFamilyCustomFont300: 'var(--fontFamilyCustomFont300)', + fontFamilyCustomFont400: 'var(--fontFamilyCustomFont400)', + fontFamilyCustomFont500: 'var(--fontFamilyCustomFont500)', + fontFamilyCustomFont600: 'var(--fontFamilyCustomFont600)', + fontFamilyCustomFont700: 'var(--fontFamilyCustomFont700)', + fontFamilyCustomFont800: 'var(--fontFamilyCustomFont800)', + fontFamilyCustomFont900: 'var(--fontFamilyCustomFont900)', + fontFamilyCustomFont1000: 'var(--fontFamilyCustomFont1000)', + fontFamilyCustomFont1100: 'var(--fontFamilyCustomFont1100)', + fontFamilyCustomFont1200: 'var(--fontFamilyCustomFont1200)', + fontFamilyCustomFont1300: 'var(--fontFamilyCustomFont1300)', + fontFamilyCustomFont1400: 'var(--fontFamilyCustomFont1400)', + fontFamilyCustomFont1500: 'var(--fontFamilyCustomFont1500)', + fontFamilyCustomFont1600: 'var(--fontFamilyCustomFont1600)', + fontFamilyCustomFont1700: 'var(--fontFamilyCustomFont1700)', - fontSizeBase450: "var(--fontSizeBase450)", + fontSizeBase450: 'var(--fontSizeBase450)', - fontStyleItalic: "var(--fontStyleItalic)", - fontStyleRegular: "var(--fontStyleRegular)", + fontStyleItalic: 'var(--fontStyleItalic)', + fontStyleRegular: 'var(--fontStyleRegular)', - fontWeightCustomFont100: "var(--fontWeightCustomFont100)", - fontWeightCustomFont200: "var(--fontWeightCustomFont200)", - fontWeightCustomFont300: "var(--fontWeightCustomFont300)", - fontWeightCustomFont400: "var(--fontWeightCustomFont400)", - fontWeightCustomFont500: "var(--fontWeightCustomFont500)", - fontWeightCustomFont600: "var(--fontWeightCustomFont600)", - fontWeightCustomFont700: "var(--fontWeightCustomFont700)", - fontWeightCustomFont800: "var(--fontWeightCustomFont800)", - fontWeightCustomFont900: "var(--fontWeightCustomFont900)", - fontWeightCustomFont1000: "var(--fontWeightCustomFont1000)", - fontWeightCustomFont1100: "var(--fontWeightCustomFont1100)", - fontWeightCustomFont1200: "var(--fontWeightCustomFont1200)", - fontWeightCustomFont1300: "var(--fontWeightCustomFont1300)", - fontWeightCustomFont1400: "var(--fontWeightCustomFont1400)", - fontWeightCustomFont1500: "var(--fontWeightCustomFont1500)", - fontWeightCustomFont1600: "var(--fontWeightCustomFont1600)", - fontWeightCustomFont1700: "var(--fontWeightCustomFont1700)", + fontWeightCustomFont100: 'var(--fontWeightCustomFont100)', + fontWeightCustomFont200: 'var(--fontWeightCustomFont200)', + fontWeightCustomFont300: 'var(--fontWeightCustomFont300)', + fontWeightCustomFont400: 'var(--fontWeightCustomFont400)', + fontWeightCustomFont500: 'var(--fontWeightCustomFont500)', + fontWeightCustomFont600: 'var(--fontWeightCustomFont600)', + fontWeightCustomFont700: 'var(--fontWeightCustomFont700)', + fontWeightCustomFont800: 'var(--fontWeightCustomFont800)', + fontWeightCustomFont900: 'var(--fontWeightCustomFont900)', + fontWeightCustomFont1000: 'var(--fontWeightCustomFont1000)', + fontWeightCustomFont1100: 'var(--fontWeightCustomFont1100)', + fontWeightCustomFont1200: 'var(--fontWeightCustomFont1200)', + fontWeightCustomFont1300: 'var(--fontWeightCustomFont1300)', + fontWeightCustomFont1400: 'var(--fontWeightCustomFont1400)', + fontWeightCustomFont1500: 'var(--fontWeightCustomFont1500)', + fontWeightCustomFont1600: 'var(--fontWeightCustomFont1600)', + fontWeightCustomFont1700: 'var(--fontWeightCustomFont1700)', - lineHeightBase450: "var(--lineHeightBase450)", + lineHeightBase450: 'var(--lineHeightBase450)', - borderRadius2XLarge: "var(--borderRadius2XLarge)", - borderRadius4XLarge: "var(--borderRadius4XLarge)", - colorNeutralStroke4: "var(--colorNeutralStroke4)", - colorNeutralStroke4Hover: "var(--colorNeutralStroke4Hover)", - colorNeutralStroke4Pressed: "var(--colorNeutralStroke4Pressed)", + borderRadius2XLarge: 'var(--borderRadius2XLarge)', + borderRadius4XLarge: 'var(--borderRadius4XLarge)', + colorNeutralStroke4: 'var(--colorNeutralStroke4)', + colorNeutralStroke4Hover: 'var(--colorNeutralStroke4Hover)', + colorNeutralStroke4Pressed: 'var(--colorNeutralStroke4Pressed)', }; diff --git a/packages/react-cap-theme/src/components/tokens/types.ts b/packages/react-cap-theme/src/components/tokens/types.ts index 44771117..08daef0d 100644 --- a/packages/react-cap-theme/src/components/tokens/types.ts +++ b/packages/react-cap-theme/src/components/tokens/types.ts @@ -1,230 +1,230 @@ import type { - ColorTokens as BaseColorTokens, - FontFamilyTokens as BaseFontFamilyTokens, - FontSizeTokens as BaseFontSizeTokens, - FontWeightTokens as BaseFontWeightTokens, - LineHeightTokens as BaseLineHeightTokens, - Theme as BaseTheme, - TypographyStyle as BaseTypographyStyle, - TypographyStyles as BaseTypographyStyles, -} from "@fluentui/tokens"; + ColorTokens as BaseColorTokens, + FontFamilyTokens as BaseFontFamilyTokens, + FontSizeTokens as BaseFontSizeTokens, + FontWeightTokens as BaseFontWeightTokens, + LineHeightTokens as BaseLineHeightTokens, + Theme as BaseTheme, + TypographyStyle as BaseTypographyStyle, + TypographyStyles as BaseTypographyStyles, +} from '@fluentui/tokens'; export type Greys = - | 0 - | 2 - | 4 - | 6 - | 8 - | 10 - | 12 - | 14 - | 16 - | 18 - | 20 - | 22 - | 24 - | 26 - | 28 - | 30 - | 32 - | 34 - | 36 - | 38 - | 40 - | 42 - | 44 - | 46 - | 48 - | 50 - | 52 - | 54 - | 56 - | 58 - | 60 - | 62 - | 64 - | 66 - | 68 - | 70 - | 72 - | 74 - | 76 - | 78 - | 80 - | 82 - | 84 - | 86 - | 88 - | 90 - | 92 - | 94 - | 96 - | 98 - | 100; + | 0 + | 2 + | 4 + | 6 + | 8 + | 10 + | 12 + | 14 + | 16 + | 18 + | 20 + | 22 + | 24 + | 26 + | 28 + | 30 + | 32 + | 34 + | 36 + | 38 + | 40 + | 42 + | 44 + | 46 + | 48 + | 50 + | 52 + | 54 + | 56 + | 58 + | 60 + | 62 + | 64 + | 66 + | 68 + | 70 + | 72 + | 74 + | 76 + | 78 + | 80 + | 82 + | 84 + | 86 + | 88 + | 90 + | 92 + | 94 + | 96 + | 98 + | 100; export type Font = - | 100 - | 200 - | 300 - | 400 - | 500 - | 600 - | 700 - | 800 - | 900 - | 1000 - | 1100 - | 1200 - | 1300 - | 1400 - | 1500 - | 1600 - | 1700; + | 100 + | 200 + | 300 + | 400 + | 500 + | 600 + | 700 + | 800 + | 900 + | 1000 + | 1100 + | 1200 + | 1300 + | 1400 + | 1500 + | 1600 + | 1700; export type ColorTokens = BaseColorTokens & { - /* placeholder: may be used to create custom color tokens to support Theme v2 */ + /* placeholder: may be used to create custom color tokens to support Theme v2 */ }; export type FontSizeTokens = BaseFontSizeTokens & { - fontSizeBase450: string; + fontSizeBase450: string; }; export type FontFamilyCustomFontTokens = Record< - `fontFamilyCustomFont${Font}`, - string + `fontFamilyCustomFont${Font}`, + string >; export type FontStyleTokens = { - fontStyleRegular: string; - fontStyleItalic: string; + fontStyleRegular: string; + fontStyleItalic: string; }; export type FontWeightCustomFontTokens = Record< - `fontWeightCustomFont${Font}`, - number + `fontWeightCustomFont${Font}`, + number >; export type LineHeightTokens = BaseLineHeightTokens & { - lineHeightBase450: string; + lineHeightBase450: string; }; export type TypographyStyle = BaseTypographyStyle & { - fontStyle: string; - lineHeight: string; + fontStyle: string; + lineHeight: string; }; export type TypographyStyles = BaseTypographyStyles & { - custom: CustomizableTypographyStyles; + custom: CustomizableTypographyStyles; }; export type CustomizableTypographyStyles = Record< - keyof BaseTypographyStyles, - TypographyStyle + keyof BaseTypographyStyles, + TypographyStyle > & { - body1Mono: TypographyStyle; - body2Italic: TypographyStyle; - body2Mono: TypographyStyle; - body3: TypographyStyle; - body3Strong: TypographyStyle; - buttonLarge: TypographyStyle; - buttonMedium: TypographyStyle; - buttonSmall: TypographyStyle; - subtitle1Italic: TypographyStyle; - webPartHeader: TypographyStyle; - heading2: TypographyStyle; - heading3: TypographyStyle; - heading4: TypographyStyle; + body1Mono: TypographyStyle; + body2Italic: TypographyStyle; + body2Mono: TypographyStyle; + body3: TypographyStyle; + body3Strong: TypographyStyle; + buttonLarge: TypographyStyle; + buttonMedium: TypographyStyle; + buttonSmall: TypographyStyle; + subtitle1Italic: TypographyStyle; + webPartHeader: TypographyStyle; + heading2: TypographyStyle; + heading3: TypographyStyle; + heading4: TypographyStyle; }; export type CustomizableTypographyStyle = { - fontFamily: string; - fontWeight?: number; + fontFamily: string; + fontWeight?: number; }; export type FontVariants = Record; export type FontFamilyTokens = BaseFontFamilyTokens & - Partial; + Partial; export type FontWeightTokens = BaseFontWeightTokens & - Partial; + Partial; export type FIXME_MISSING_TOKENS = { - borderRadius2XLarge: string; - borderRadius4XLarge: string; - colorNeutralStroke4: string; - colorNeutralStroke4Hover: string; - colorNeutralStroke4Pressed: string; + borderRadius2XLarge: string; + borderRadius4XLarge: string; + colorNeutralStroke4: string; + colorNeutralStroke4Hover: string; + colorNeutralStroke4Pressed: string; }; export const FIXME_MISSING_TOKENS_DEFAULTS: FIXME_MISSING_TOKENS = { - borderRadius2XLarge: "", - borderRadius4XLarge: "", - colorNeutralStroke4: "", - colorNeutralStroke4Hover: "", - colorNeutralStroke4Pressed: "", + borderRadius2XLarge: '', + borderRadius4XLarge: '', + colorNeutralStroke4: '', + colorNeutralStroke4Hover: '', + colorNeutralStroke4Pressed: '', }; export type Theme = BaseTheme & - ColorTokens & - FontFamilyTokens & - FontSizeTokens & - FontStyleTokens & - FontWeightTokens & - LineHeightTokens & - FIXME_MISSING_TOKENS; + ColorTokens & + FontFamilyTokens & + FontSizeTokens & + FontStyleTokens & + FontWeightTokens & + LineHeightTokens & + FIXME_MISSING_TOKENS; export type PartialTheme = Partial; export type TokenName = keyof Theme; export type { - BorderRadiusTokens, - Brands, - BrandVariants, - ColorPaletteAnchor, - ColorPaletteBeige, - ColorPaletteBerry, - ColorPaletteBlue, - ColorPaletteBrass, - ColorPaletteBrown, - ColorPaletteCornflower, - ColorPaletteCranberry, - ColorPaletteDarkGreen, - ColorPaletteDarkOrange, - ColorPaletteDarkRed, - ColorPaletteForest, - ColorPaletteGrape, - ColorPaletteGold, - ColorPaletteGreen, - ColorPaletteLavender, - ColorPaletteLilac, - ColorPaletteLightGreen, - ColorPaletteLightTeal, - ColorPaletteMagenta, - ColorPaletteMarigold, - ColorPaletteMink, - ColorPaletteNavy, - ColorPalettePeach, - ColorPalettePink, - ColorPalettePlatinum, - ColorPalettePlum, - ColorPalettePumpkin, - ColorPalettePurple, - ColorPaletteRed, - ColorPaletteRoyalBlue, - ColorPaletteSeafoam, - ColorPaletteSteel, - ColorPaletteTeal, - ColorPaletteTokens, - ColorPaletteYellow, - CurveTokens, - DurationTokens, - HorizontalSpacingTokens, - ShadowBrandTokens, - ShadowTokens, - SpacingTokens, - StrokeWidthTokens, - VerticalSpacingTokens, - ZIndexTokens, -} from "@fluentui/tokens"; + BorderRadiusTokens, + Brands, + BrandVariants, + ColorPaletteAnchor, + ColorPaletteBeige, + ColorPaletteBerry, + ColorPaletteBlue, + ColorPaletteBrass, + ColorPaletteBrown, + ColorPaletteCornflower, + ColorPaletteCranberry, + ColorPaletteDarkGreen, + ColorPaletteDarkOrange, + ColorPaletteDarkRed, + ColorPaletteForest, + ColorPaletteGrape, + ColorPaletteGold, + ColorPaletteGreen, + ColorPaletteLavender, + ColorPaletteLilac, + ColorPaletteLightGreen, + ColorPaletteLightTeal, + ColorPaletteMagenta, + ColorPaletteMarigold, + ColorPaletteMink, + ColorPaletteNavy, + ColorPalettePeach, + ColorPalettePink, + ColorPalettePlatinum, + ColorPalettePlum, + ColorPalettePumpkin, + ColorPalettePurple, + ColorPaletteRed, + ColorPaletteRoyalBlue, + ColorPaletteSeafoam, + ColorPaletteSteel, + ColorPaletteTeal, + ColorPaletteTokens, + ColorPaletteYellow, + CurveTokens, + DurationTokens, + HorizontalSpacingTokens, + ShadowBrandTokens, + ShadowTokens, + SpacingTokens, + StrokeWidthTokens, + VerticalSpacingTokens, + ZIndexTokens, +} from '@fluentui/tokens'; diff --git a/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts b/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts index b09875bb..8bf333d6 100644 --- a/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts +++ b/packages/react-cap-theme/src/components/tokens/utils/applyFonts.ts @@ -1,30 +1,30 @@ -import type { Theme as FluentTheme } from "@fluentui/tokens"; +import type { Theme as FluentTheme } from '@fluentui/tokens'; import { - generateFontFamilyTokens, - generateFontWeightTokens, -} from "../alias/fonts/index"; -import { fontSizes, fontStyles, lineHeights } from "../global/fonts"; + generateFontFamilyTokens, + generateFontWeightTokens, +} from '../alias/fonts/index'; +import { fontSizes, fontStyles, lineHeights } from '../global/fonts'; import { - FIXME_MISSING_TOKENS_DEFAULTS, - type FontFamilyCustomFontTokens, - type FontVariants, - type FontWeightCustomFontTokens, - type Theme, -} from "../types"; + FIXME_MISSING_TOKENS_DEFAULTS, + type FontFamilyCustomFontTokens, + type FontVariants, + type FontWeightCustomFontTokens, + type Theme, +} from '../types'; export const applyFonts = (theme: FluentTheme, font?: FontVariants): Theme => { - const fontFamilies: FontFamilyCustomFontTokens | undefined = - font && generateFontFamilyTokens(font); - const fontWeights: Partial | undefined = - font && generateFontWeightTokens(font); + const fontFamilies: FontFamilyCustomFontTokens | undefined = + font && generateFontFamilyTokens(font); + const fontWeights: Partial | undefined = + font && generateFontWeightTokens(font); - return { - ...FIXME_MISSING_TOKENS_DEFAULTS, - ...theme, - ...fontFamilies, - ...fontSizes, - ...fontStyles, - ...fontWeights, - ...lineHeights, - }; + return { + ...FIXME_MISSING_TOKENS_DEFAULTS, + ...theme, + ...fontFamilies, + ...fontSizes, + ...fontStyles, + ...fontWeights, + ...lineHeights, + }; }; diff --git a/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts b/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts index 08c22b43..8bbae532 100644 --- a/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts +++ b/packages/react-cap-theme/src/components/tokens/utils/createDarkTheme.ts @@ -1,38 +1,38 @@ -import type { BrandVariants, Theme as FluentTheme } from "@fluentui/tokens"; -import { createDarkTheme as createFluentDarkTheme } from "@fluentui/tokens"; -import { generateBrandColorTokens } from "../alias/colors/darkColor"; +import type { BrandVariants, Theme as FluentTheme } from '@fluentui/tokens'; +import { createDarkTheme as createFluentDarkTheme } from '@fluentui/tokens'; +import { generateBrandColorTokens } from '../alias/colors/darkColor'; import { - generateFontFamilyTokens, - generateFontWeightTokens, -} from "../alias/fonts"; -import { brandCAP } from "../global/brandColors"; -import { fontSizes, fontStyles, lineHeights } from "../global/fonts"; + generateFontFamilyTokens, + generateFontWeightTokens, +} from '../alias/fonts'; +import { brandCAP } from '../global/brandColors'; +import { fontSizes, fontStyles, lineHeights } from '../global/fonts'; import { - FIXME_MISSING_TOKENS_DEFAULTS, - type FontFamilyCustomFontTokens, - type FontVariants, - type FontWeightCustomFontTokens, - type Theme, -} from "../types"; + FIXME_MISSING_TOKENS_DEFAULTS, + type FontFamilyCustomFontTokens, + type FontVariants, + type FontWeightCustomFontTokens, + type Theme, +} from '../types'; export const createDarkTheme: ( - brand?: BrandVariants, - font?: FontVariants, + brand?: BrandVariants, + font?: FontVariants ) => Theme = (brand = brandCAP, font) => { - const fluentTheme: FluentTheme = createFluentDarkTheme(brand); - const fontFamilies: FontFamilyCustomFontTokens | undefined = - font && generateFontFamilyTokens(font); - const fontWeights: Partial | undefined = - font && generateFontWeightTokens(font); + const fluentTheme: FluentTheme = createFluentDarkTheme(brand); + const fontFamilies: FontFamilyCustomFontTokens | undefined = + font && generateFontFamilyTokens(font); + const fontWeights: Partial | undefined = + font && generateFontWeightTokens(font); - return { - ...FIXME_MISSING_TOKENS_DEFAULTS, - ...fluentTheme, - ...fontFamilies, - ...fontSizes, - ...fontStyles, - ...fontWeights, - ...lineHeights, - ...generateBrandColorTokens(brand), - }; + return { + ...FIXME_MISSING_TOKENS_DEFAULTS, + ...fluentTheme, + ...fontFamilies, + ...fontSizes, + ...fontStyles, + ...fontWeights, + ...lineHeights, + ...generateBrandColorTokens(brand), + }; }; diff --git a/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts b/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts index 0a51c284..9d273815 100644 --- a/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts +++ b/packages/react-cap-theme/src/components/tokens/utils/createLightTheme.ts @@ -1,38 +1,38 @@ -import type { BrandVariants, Theme as FluentTheme } from "@fluentui/tokens"; -import { createLightTheme as createFluentLightTheme } from "@fluentui/tokens"; -import { generateBrandColorTokens } from "../alias/colors/lightColor"; +import type { BrandVariants, Theme as FluentTheme } from '@fluentui/tokens'; +import { createLightTheme as createFluentLightTheme } from '@fluentui/tokens'; +import { generateBrandColorTokens } from '../alias/colors/lightColor'; import { - generateFontFamilyTokens, - generateFontWeightTokens, -} from "../alias/fonts"; -import { brandCAP } from "../global/brandColors"; -import { fontSizes, fontStyles, lineHeights } from "../global/fonts"; + generateFontFamilyTokens, + generateFontWeightTokens, +} from '../alias/fonts'; +import { brandCAP } from '../global/brandColors'; +import { fontSizes, fontStyles, lineHeights } from '../global/fonts'; import { - FIXME_MISSING_TOKENS_DEFAULTS, - type FontFamilyCustomFontTokens, - type FontVariants, - type FontWeightCustomFontTokens, - type Theme, -} from "../types"; + FIXME_MISSING_TOKENS_DEFAULTS, + type FontFamilyCustomFontTokens, + type FontVariants, + type FontWeightCustomFontTokens, + type Theme, +} from '../types'; export const createLightTheme: ( - brand?: BrandVariants, - font?: FontVariants, + brand?: BrandVariants, + font?: FontVariants ) => Theme = (brand = brandCAP, font) => { - const fluentTheme: FluentTheme = createFluentLightTheme(brand); - const fontFamilies: FontFamilyCustomFontTokens | undefined = - font && generateFontFamilyTokens(font); - const fontWeights: Partial | undefined = - font && generateFontWeightTokens(font); + const fluentTheme: FluentTheme = createFluentLightTheme(brand); + const fontFamilies: FontFamilyCustomFontTokens | undefined = + font && generateFontFamilyTokens(font); + const fontWeights: Partial | undefined = + font && generateFontWeightTokens(font); - return { - ...FIXME_MISSING_TOKENS_DEFAULTS, - ...fluentTheme, - ...fontFamilies, - ...fontSizes, - ...fontStyles, - ...fontWeights, - ...lineHeights, - ...generateBrandColorTokens(brand), - }; + return { + ...FIXME_MISSING_TOKENS_DEFAULTS, + ...fluentTheme, + ...fontFamilies, + ...fontSizes, + ...fontStyles, + ...fontWeights, + ...lineHeights, + ...generateBrandColorTokens(brand), + }; }; diff --git a/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts b/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts index 8c76c785..e6dd90e2 100644 --- a/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts +++ b/packages/react-cap-theme/src/components/tokens/utils/extractNeutralTokens.ts @@ -1,12 +1,12 @@ -import type { PartialTheme } from "../types"; +import type { PartialTheme } from '../types'; export const extractNeutralTokens = ( - theme: PartialTheme, + theme: PartialTheme ): { token: string; value: string }[] => { - return Object.entries(theme) - .filter( - ([key, value]) => - key.startsWith("colorNeutral") && typeof value === "string", - ) - .map(([key, value]) => ({ token: key, value: value as string })); + return Object.entries(theme) + .filter( + ([key, value]) => + key.startsWith('colorNeutral') && typeof value === 'string' + ) + .map(([key, value]) => ({ token: key, value: value as string })); }; diff --git a/packages/react-cap-theme/src/index.ts b/packages/react-cap-theme/src/index.ts index 11f15be2..b05449a8 100644 --- a/packages/react-cap-theme/src/index.ts +++ b/packages/react-cap-theme/src/index.ts @@ -1,38 +1,154 @@ -import { FluentProviderProps } from "@fluentui/react-components"; +import { FluentProviderProps } from '@fluentui/react-components'; import { - useButtonStyles, - useMenuButtonStyles, - useSplitButtonStyles, - useToggleButtonStyles, - type ButtonState, - type MenuButtonState, - type SplitButtonState, - type ToggleButtonState, -} from "./components/react-button"; + useButtonStyles, + useMenuButtonStyles, + useSplitButtonStyles, + useToggleButtonStyles, + type ButtonState, + type MenuButtonState, + type SplitButtonState, + type ToggleButtonState, +} from './components/react-button'; -export { getIntrinsicElementProps, slot } from "@fluentui/react-utilities"; +export { getIntrinsicElementProps, slot } from '@fluentui/react-utilities'; export { - motionTokens, - makeStyles, - mergeClasses, -} from "@fluentui/react-components"; + motionTokens, + makeStyles, + mergeClasses, +} from '@fluentui/react-components'; -export * from "./components/react-button"; -export * from "./components/tokens"; +export type { + ButtonAppearance, + ButtonProps, + ButtonSlots, + ButtonState, + MenuButtonProps, + MenuButtonSlots, + MenuButtonState, + SplitButtonProps, + SplitButtonSlots, + SplitButtonState, + ToggleButtonProps, + ToggleButtonState, +} from './components/react-button'; +export { + Button, + MenuButton, + SplitButton, + ToggleButton, + buttonClassNames, + menuButtonClassNames, + renderButton, + renderMenuButton, + renderSplitButton, + renderToggleButton, + splitButtonClassNames, + toggleButtonClassNames, + useButton, + useButtonStyles, + useMenuButton, + useMenuButtonStyles, + useSplitButton, + useSplitButtonStyles, + useToggleButton, + useToggleButtonStyles, +} from './components/react-button'; +export type { + BorderRadiusTokens, + BrandVariants, + Brands, + ColorPaletteAnchor, + ColorPaletteBeige, + ColorPaletteBerry, + ColorPaletteBlue, + ColorPaletteBrass, + ColorPaletteBrown, + ColorPaletteCornflower, + ColorPaletteCranberry, + ColorPaletteDarkGreen, + ColorPaletteDarkOrange, + ColorPaletteDarkRed, + ColorPaletteForest, + ColorPaletteGold, + ColorPaletteGrape, + ColorPaletteGreen, + ColorPaletteLavender, + ColorPaletteLightGreen, + ColorPaletteLightTeal, + ColorPaletteLilac, + ColorPaletteMagenta, + ColorPaletteMarigold, + ColorPaletteMink, + ColorPaletteNavy, + ColorPalettePeach, + ColorPalettePink, + ColorPalettePlatinum, + ColorPalettePlum, + ColorPalettePumpkin, + ColorPalettePurple, + ColorPaletteRed, + ColorPaletteRoyalBlue, + ColorPaletteSeafoam, + ColorPaletteSteel, + ColorPaletteTeal, + ColorPaletteTokens, + ColorPaletteYellow, + ColorTokens, + CurveTokens, + CustomizableTypographyStyle, + CustomizableTypographyStyles, + DurationTokens, + Font, + FontFamilyCustomFontTokens, + FontFamilyTokens, + FontSizeTokens, + FontStyleTokens, + FontVariants, + FontWeightCustomFontTokens, + FontWeightTokens, + Greys, + HorizontalSpacingTokens, + LineHeightTokens, + PartialTheme, + ShadowBrandTokens, + ShadowTokens, + SpacingTokens, + StrokeWidthTokens, + Theme, + TokenName, + TypographyStyle, + TypographyStyles, + VerticalSpacingTokens, + ZIndexTokens, +} from './components/tokens'; +export { + applyFonts, + black, + createDarkTheme, + createLightTheme, + darkTheme, + extractNeutralTokens, + grey, + lightTheme, + themeToTokensObject, + tokens, + typographyStyles, + white, +} from './components/tokens'; export const CAP_STYLE_HOOKS: NonNullable< - FluentProviderProps["customStyleHooks_unstable"] + FluentProviderProps['customStyleHooks_unstable'] > = { - useButtonStyles_unstable: (state) => { - return useButtonStyles(state as ButtonState); - }, - useMenuButtonStyles_unstable: (state) => { - return useMenuButtonStyles(state as MenuButtonState); - }, - useSplitButtonStyles_unstable: (state) => { - return useSplitButtonStyles(state as SplitButtonState); - }, - useToggleButtonStyles_unstable: (state) => { - return useToggleButtonStyles(state as ToggleButtonState); - }, + useButtonStyles_unstable: (state) => { + return useButtonStyles(state as ButtonState); + }, + useMenuButtonStyles_unstable: (state) => { + return useMenuButtonStyles(state as MenuButtonState); + }, + useSplitButtonStyles_unstable: (state) => { + return useSplitButtonStyles(state as SplitButtonState); + }, + useToggleButtonStyles_unstable: (state) => { + return useToggleButtonStyles(state as ToggleButtonState); + }, }; diff --git a/packages/react-cap-theme/tsconfig.json b/packages/react-cap-theme/tsconfig.json index 7747dab4..37b4d743 100644 --- a/packages/react-cap-theme/tsconfig.json +++ b/packages/react-cap-theme/tsconfig.json @@ -9,9 +9,7 @@ "@fluentui-contrib/react-cap-theme/react-icons": [ "src/components/react-icons/index.ts" ], - "@fluentui-contrib/react-cap-theme/*": [ - "src/components/*" - ] + "@fluentui-contrib/react-cap-theme/*": ["src/components/*"] } }, "include": [], From d1ebecbb99a04786c77f6f3efc81391f4be0d5ae Mon Sep 17 00:00:00 2001 From: David Zukowski Date: Mon, 9 Mar 2026 21:07:08 -0700 Subject: [PATCH 3/3] Change files --- ...act-cap-theme-90c43f06-4a43-493e-a1c2-0cb63a2feb0a.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-contrib-react-cap-theme-90c43f06-4a43-493e-a1c2-0cb63a2feb0a.json diff --git a/change/@fluentui-contrib-react-cap-theme-90c43f06-4a43-493e-a1c2-0cb63a2feb0a.json b/change/@fluentui-contrib-react-cap-theme-90c43f06-4a43-493e-a1c2-0cb63a2feb0a.json new file mode 100644 index 00000000..fb46ac10 --- /dev/null +++ b/change/@fluentui-contrib-react-cap-theme-90c43f06-4a43-493e-a1c2-0cb63a2feb0a.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "publish component updates", + "packageName": "@fluentui-contrib/react-cap-theme", + "email": "dzukowski@microsoft.com", + "dependentChangeType": "patch" +}