diff --git a/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/Popover/index.ts b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/Popover/index.ts new file mode 100644 index 0000000000000..b2e34657a7ccf --- /dev/null +++ b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/Popover/index.ts @@ -0,0 +1 @@ +export { useSemanticPopoverSurfaceStyles } from './useSemanticPopoverStyles.styles'; diff --git a/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/Popover/useSemanticPopoverStyles.styles.ts b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/Popover/useSemanticPopoverStyles.styles.ts new file mode 100644 index 0000000000000..4616753b6e41e --- /dev/null +++ b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/Popover/useSemanticPopoverStyles.styles.ts @@ -0,0 +1,90 @@ +import { makeStyles, mergeClasses } from '@griffel/react'; +import { createArrowHeightStyles, createArrowStyles, createSlideStyles } from '@fluentui/react-positioning'; +import { tokens } from '@fluentui/react-theme'; +import type { PopoverSize, PopoverSurfaceState } from '@fluentui/react-popover'; +import { popoverSurfaceClassNames } from '@fluentui/react-popover'; +import { getSlotClassNameProp_unstable } from '@fluentui/react-utilities'; +import * as semanticTokens from '@fluentui/semantic-tokens'; + +export const arrowHeights: Record = { + small: 6, + medium: 8, + large: 8, +}; + +/** + * Styles for the root slot + */ +const useStyles = makeStyles({ + root: { + color: semanticTokens.foregroundContentNeutralPrimary, + backgroundColor: semanticTokens.backgroundFlyoutSolid, + borderRadius: semanticTokens.cornerCtrlRest, + border: `1px solid ${semanticTokens.strokeLayer}`, + fontFamily: semanticTokens.textStyleDefaultRegularFontFamily, + fontSize: semanticTokens.textGlobalBody3FontSize, + fontWeight: semanticTokens.textStyleDefaultRegularWeight, + lineHeight: semanticTokens.textGlobalBody3LineHeight, + ...createSlideStyles(10), + + // TODO need to add versions of tokens.alias.shadow.shadow16, etc. that work with filter + filter: semanticTokens._ctrlPopoverShadowFilter, + }, + + inline: { + // When rendering inline, the PopoverSurface will be rendered under relatively positioned elements such as Input. + // This is due to the surface being positioned as absolute, therefore zIndex: 1 ensures that won't happen. + zIndex: 1, + }, + + inverted: { + backgroundColor: tokens.colorNeutralBackgroundStatic, + color: tokens.colorNeutralForegroundStaticInverted, + }, + + brand: { + backgroundColor: semanticTokens.backgroundCtrlBrandRest, + color: semanticTokens.foregroundCtrlOnBrandRest, + }, + + smallPadding: { padding: semanticTokens.paddingContentSmall }, + + mediumPadding: { padding: semanticTokens.paddingContentMedium }, + + largePadding: { padding: semanticTokens._ctrlPopoverPaddingContentLarge }, + + smallArrow: createArrowHeightStyles(arrowHeights.small), + mediumLargeArrow: createArrowHeightStyles(arrowHeights.medium), + arrow: createArrowStyles({ arrowHeight: undefined }), +}); + +/** + * Apply styling to the PopoverSurface slots based on the state + */ +export const useSemanticPopoverSurfaceStyles = (_state: unknown): PopoverSurfaceState => { + 'use no memo'; + + const state = _state as PopoverSurfaceState; + + const styles = useStyles(); + state.root.className = mergeClasses( + state.root.className, + popoverSurfaceClassNames.root, + styles.root, + state.inline && styles.inline, + state.size === 'small' && styles.smallPadding, + state.size === 'medium' && styles.mediumPadding, + state.size === 'large' && styles.largePadding, + state.appearance === 'inverted' && styles.inverted, + state.appearance === 'brand' && styles.brand, + getSlotClassNameProp_unstable(state.root), + ); + + state.arrowClassName = mergeClasses( + state.arrowClassName, + styles.arrow, + state.size === 'small' ? styles.smallArrow : styles.mediumLargeArrow, + ); + + return state; +}; diff --git a/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/TeachingPopover/useSemanticTeachingPopoverSurfaceStyles.styles.ts b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/TeachingPopover/useSemanticTeachingPopoverSurfaceStyles.styles.ts index e48d75c7426a9..773501f0e07ec 100644 --- a/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/TeachingPopover/useSemanticTeachingPopoverSurfaceStyles.styles.ts +++ b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/TeachingPopover/useSemanticTeachingPopoverSurfaceStyles.styles.ts @@ -1,8 +1,7 @@ import { makeStyles, mergeClasses } from '@griffel/react'; import { getSlotClassNameProp_unstable } from '@fluentui/react-utilities'; import { teachingPopoverSurfaceClassNames, type TeachingPopoverSurfaceState } from '@fluentui/react-teaching-popover'; -import { usePopoverSurfaceStyles_unstable } from '@fluentui/react-popover'; -// import { useSemanticPopoverSurfaceStyles } from '../Popover'; +import { useSemanticPopoverSurfaceStyles } from '../Popover'; import * as semanticTokens from '@fluentui/semantic-tokens'; const useStyles = makeStyles({ @@ -32,8 +31,7 @@ export const useSemanticTeachingPopoverSurfaceStyles = (_state: unknown): Teachi getSlotClassNameProp_unstable(state.root), ); - const updatedState = usePopoverSurfaceStyles_unstable(state); - // const updatedState = useSemanticPopoverSurfaceStyles(state); + const updatedState = useSemanticPopoverSurfaceStyles(state); return updatedState; }; diff --git a/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/semanticStyleHooks.ts b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/semanticStyleHooks.ts index 1a966a1480927..cf974901cdde4 100644 --- a/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/semanticStyleHooks.ts +++ b/packages/react-components/semantic-style-hooks-preview/library/src/component-styles/semanticStyleHooks.ts @@ -70,6 +70,7 @@ import { useSemanticBreadcrumbItemStyles, } from './Breadcrumb'; import { useSemanticSpinButtonStyles } from './SpinButton'; +import { useSemanticPopoverSurfaceStyles } from './Popover'; import { useSemanticInputStyles } from './Input/useSemanticInputStyles.styles'; import { useSemanticToolbarStyles, @@ -198,6 +199,8 @@ export const SEMANTIC_STYLE_HOOKS: FluentProviderCustomStyleHooks = { useRadioStyles_unstable: useSemanticRadioStyles, // Persona styles usePersonaStyles_unstable: useSemanticPersonaStyles, + // Popover styles + usePopoverSurfaceStyles_unstable: useSemanticPopoverSurfaceStyles, // Search styles useSearchBoxStyles_unstable: useSemanticSearchBoxStyles, // Checkbox styles diff --git a/packages/semantic-tokens/etc/semantic-tokens.api.md b/packages/semantic-tokens/etc/semantic-tokens.api.md index b552a0b965676..64d2b80f91c3a 100644 --- a/packages/semantic-tokens/etc/semantic-tokens.api.md +++ b/packages/semantic-tokens/etc/semantic-tokens.api.md @@ -2491,6 +2491,12 @@ export const _ctrlMessageBarTitleLineHeight = "var(--smtc-text-ramp-item-header- // @public export const _ctrlPersonaTreeIconOnSubtlePressed = "var(--smtc-foreground-ctrl-on-subtle-pressed, var(--smtc-foreground-ctrl-neutral-primary-pressed, var(--colorNeutralForeground3Pressed)))"; +// @public +export const _ctrlPopoverPaddingContentLarge = "var(--smtc-padding-content-large, 20px)"; + +// @public +export const _ctrlPopoverShadowFilter = "var(--smtc-shadow-flyout, drop-shadow(0 0 2px var(--colorNeutralShadowAmbient)) drop-shadow(0 8px 16px var(--colorNeutralShadowKey)))"; + // @public (undocumented) export const ctrlProgressBackgroundEmpty = "var(--smtc-ctrl-progress-background-empty, var(--colorNeutralBackground6))"; @@ -4603,7 +4609,7 @@ export const paddingContentLarge = "var(--smtc-padding-content-large, var(--spac export const paddingContentLargeRaw = "--smtc-padding-content-large"; // @public (undocumented) -export const paddingContentMedium = "var(--smtc-padding-content-medium)"; +export const paddingContentMedium = "var(--smtc-padding-content-medium, 16px)"; // @public (undocumented) export const paddingContentMediumRaw = "--smtc-padding-content-medium"; diff --git a/packages/semantic-tokens/src/control/tokens.ts b/packages/semantic-tokens/src/control/tokens.ts index 84978cce9facb..987510dbda5c2 100644 --- a/packages/semantic-tokens/src/control/tokens.ts +++ b/packages/semantic-tokens/src/control/tokens.ts @@ -323,7 +323,7 @@ export const paddingContentAlignOutdentTextOnSubtle = `var(${paddingContentAlign export const paddingContentXxSmall = `var(${paddingContentXxSmallRaw})`; export const paddingContentXSmall = `var(${paddingContentXSmallRaw})`; export const paddingContentSmall = `var(${paddingContentSmallRaw}, 12px)`; -export const paddingContentMedium = `var(${paddingContentMediumRaw})`; +export const paddingContentMedium = `var(${paddingContentMediumRaw}, 16px)`; export const paddingContentLarge = `var(${paddingContentLargeRaw}, ${spacingHorizontalXXL})`; export const paddingContentXLarge = `var(${paddingContentXLargeRaw})`; export const paddingContentXxLarge = `var(${paddingContentXxLargeRaw})`; diff --git a/packages/semantic-tokens/src/fluentLegacyVariants.ts b/packages/semantic-tokens/src/fluentLegacyVariants.ts index 8edd767babc5f..7d08caf815dc4 100644 --- a/packages/semantic-tokens/src/fluentLegacyVariants.ts +++ b/packages/semantic-tokens/src/fluentLegacyVariants.ts @@ -481,6 +481,14 @@ export const legacyFluentVariantsValues: LegacyFluentVariants = { f2Token: 'colorNeutralForeground3Pressed', originalToken: 'foregroundCtrlOnSubtlePressed', }, + _ctrlPopoverPaddingContentLarge: { + originalToken: 'paddingContentLarge', + rawValue: '20px', + }, + _ctrlPopoverShadowFilter: { + originalToken: 'shadowFlyout', + rawValue: `drop-shadow(0 0 2px var(--colorNeutralShadowAmbient)) drop-shadow(0 8px 16px var(--colorNeutralShadowKey))`, + }, _ctrlRadioBackgroundActiveBrandHover: { f2Token: 'colorTransparentBackground', originalToken: 'backgroundCtrlActiveBrandHover', diff --git a/packages/semantic-tokens/src/fluentOverrides.ts b/packages/semantic-tokens/src/fluentOverrides.ts index d5a33d0555ae6..8c90338408470 100644 --- a/packages/semantic-tokens/src/fluentOverrides.ts +++ b/packages/semantic-tokens/src/fluentOverrides.ts @@ -155,15 +155,9 @@ export const fluentOverrides: FluentOverrides = { ctrlSliderThumbSizePressed: { rawValue: '20px' }, ctrlSliderThumbSizeRest: { rawValue: '20px' }, ctrlSpinnerStrokeWidth: { f2Token: 'strokeWidthThicker' }, - ctrlTooltipBackground: { - f2Token: 'colorNeutralBackground1', - }, - ctrlTooltipCorner: { - f2Token: 'borderRadiusMedium', - }, - ctrlTooltipForeground: { - f2Token: 'colorNeutralForeground1', - }, + ctrlTooltipBackground: { f2Token: 'colorNeutralBackground1' }, + ctrlTooltipCorner: { f2Token: 'borderRadiusMedium' }, + ctrlTooltipForeground: { f2Token: 'colorNeutralForeground1' }, ctrlTooltipShadow: { rawValue: `drop-shadow(0 0 2px var(--colorNeutralShadowAmbient)) ` + `drop-shadow(0 4px 8px var(--colorNeutralShadowKey))`, @@ -224,6 +218,7 @@ export const fluentOverrides: FluentOverrides = { paddingContentAlignDefault: { f2Token: 'spacingVerticalS' }, paddingContentAlignOutdentIconOnSubtle: { f2Token: 'spacingHorizontalM' }, paddingContentLarge: { f2Token: 'spacingHorizontalXXL' }, + paddingContentMedium: { rawValue: '16px' }, paddingContentNone: { f2Token: 'spacingHorizontalNone' }, paddingContentSmall: { rawValue: '12px' }, paddingCtrlHorizontalDefault: { f2Token: 'spacingHorizontalM' }, diff --git a/packages/semantic-tokens/src/index.ts b/packages/semantic-tokens/src/index.ts index a52e0b9fed6f7..3b6862e91652f 100644 --- a/packages/semantic-tokens/src/index.ts +++ b/packages/semantic-tokens/src/index.ts @@ -1899,6 +1899,8 @@ export { _ctrlMessageBarSpacingTop, _ctrlMessageBarTitleLineHeight, _ctrlPersonaTreeIconOnSubtlePressed, + _ctrlPopoverPaddingContentLarge, + _ctrlPopoverShadowFilter, _ctrlRadioBackgroundActiveBrandHover, _ctrlRadioBackgroundActiveBrandPressed, _ctrlRadioBackgroundActiveBrandRest, diff --git a/packages/semantic-tokens/src/legacyVariant/tokens.ts b/packages/semantic-tokens/src/legacyVariant/tokens.ts index 772361b4758da..3ccc18fd6acd5 100644 --- a/packages/semantic-tokens/src/legacyVariant/tokens.ts +++ b/packages/semantic-tokens/src/legacyVariant/tokens.ts @@ -70,6 +70,7 @@ import { gapBetweenCtrlDefaultRaw, paddingContentAlignOutdentIconOnSubtleRaw, textGlobalBody2LineHeightRaw, + paddingContentLargeRaw, backgroundCtrlBrandDisabledRaw, sizeCtrlIconRaw, foregroundCtrlOnBrandRestRaw, @@ -1042,6 +1043,20 @@ export const _ctrlMessageBarTitleLineHeight = `var(${textRampItemHeaderLineHeigh * please use foregroundCtrlOnSubtlePressed instead. */ export const _ctrlPersonaTreeIconOnSubtlePressed = `var(${foregroundCtrlOnSubtlePressedRaw}, var(${foregroundCtrlNeutralPrimaryPressedRaw}, ${colorNeutralForeground3Pressed}))`; +/** + * This is a legacy variant for paddingContentLarge to enable backwards compatibility. + * It's purpose is to support Fluent UI legacy fallback variants only. + * This token is not intended for use in new semantic theme implementations + * please use paddingContentLarge instead. + */ +export const _ctrlPopoverPaddingContentLarge = `var(${paddingContentLargeRaw}, 20px)`; +/** + * This is a legacy variant for shadowFlyout to enable backwards compatibility. + * It's purpose is to support Fluent UI legacy fallback variants only. + * This token is not intended for use in new semantic theme implementations + * please use shadowFlyout instead. + */ +export const _ctrlPopoverShadowFilter = `var(${shadowFlyoutRaw}, drop-shadow(0 0 2px var(--colorNeutralShadowAmbient)) drop-shadow(0 8px 16px var(--colorNeutralShadowKey)))`; /** * This is a legacy variant for backgroundCtrlActiveBrandHover to enable backwards compatibility. * It's purpose is to support Fluent UI legacy fallback variants only.