diff --git a/change/@fluentui-react-button-f3600003-d5e8-4448-b335-4a0ff4c76dfd.json b/change/@fluentui-react-button-f3600003-d5e8-4448-b335-4a0ff4c76dfd.json new file mode 100644 index 00000000000000..1f9a8301532503 --- /dev/null +++ b/change/@fluentui-react-button-f3600003-d5e8-4448-b335-4a0ff4c76dfd.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feature: creates ButtonContext", + "packageName": "@fluentui/react-button", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-button/etc/react-button.api.md b/packages/react-components/react-button/etc/react-button.api.md index 232ffc013e5799..02c480a808bdcb 100644 --- a/packages/react-components/react-button/etc/react-button.api.md +++ b/packages/react-components/react-button/etc/react-button.api.md @@ -20,6 +20,15 @@ export const Button: ForwardRefComponent; // @public (undocumented) export const buttonClassNames: SlotClassNames; +// @internal +export const ButtonContextProvider: React_2.Provider; + +// @internal +export interface ButtonContextValue { + // (undocumented) + size?: ButtonSize; +} + // @public (undocumented) export type ButtonProps = ComponentProps & { appearance?: 'secondary' | 'primary' | 'outline' | 'subtle' | 'transparent'; @@ -27,7 +36,7 @@ export type ButtonProps = ComponentProps & { disabled?: boolean; iconPosition?: 'before' | 'after'; shape?: 'rounded' | 'circular' | 'square'; - size?: 'small' | 'medium' | 'large'; + size?: ButtonSize; }; // @public (undocumented) @@ -127,6 +136,9 @@ export type ToggleButtonState = ButtonState & Required) => ButtonState; +// @internal +export const useButtonContext: () => ButtonContextValue; + // @public (undocumented) export const useButtonStyles_unstable: (state: ButtonState) => ButtonState; diff --git a/packages/react-components/react-button/src/components/Button/Button.types.ts b/packages/react-components/react-button/src/components/Button/Button.types.ts index 27bc93579ce184..201f264913be06 100644 --- a/packages/react-components/react-button/src/components/Button/Button.types.ts +++ b/packages/react-components/react-button/src/components/Button/Button.types.ts @@ -13,6 +13,11 @@ export type ButtonSlots = { icon?: Slot<'span'>; }; +/** + * A button supports different sizes. + */ +export type ButtonSize = 'small' | 'medium' | 'large'; + export type ButtonProps = ComponentProps & { /** * A button can have its content and borders styled for greater emphasis or to be subtle. @@ -61,7 +66,7 @@ export type ButtonProps = ComponentProps & { * * @default 'medium' */ - size?: 'small' | 'medium' | 'large'; + size?: ButtonSize; }; export type ButtonState = ComponentState & diff --git a/packages/react-components/react-button/src/components/Button/useButton.ts b/packages/react-components/react-button/src/components/Button/useButton.ts index b5988a1bad8233..eb1899903c4834 100644 --- a/packages/react-components/react-button/src/components/Button/useButton.ts +++ b/packages/react-components/react-button/src/components/Button/useButton.ts @@ -1,6 +1,7 @@ import * as React from 'react'; import { ARIAButtonSlotProps, useARIAButtonShorthand } from '@fluentui/react-aria'; import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; +import { useButtonContext } from '../../contexts/ButtonContext'; import type { ButtonProps, ButtonState } from './Button.types'; /** @@ -12,6 +13,7 @@ export const useButton_unstable = ( props: ButtonProps, ref: React.Ref, ): ButtonState => { + const { size: contextSize } = useButtonContext(); const { appearance = 'secondary', as = 'button', @@ -20,7 +22,7 @@ export const useButton_unstable = ( icon, iconPosition = 'before', shape = 'rounded', - size = 'medium', + size = contextSize ?? 'medium', } = props; const iconShorthand = resolveShorthand(icon); diff --git a/packages/react-components/react-button/src/contexts/ButtonContext.ts b/packages/react-components/react-button/src/contexts/ButtonContext.ts new file mode 100644 index 00000000000000..fd237b36ca2bfd --- /dev/null +++ b/packages/react-components/react-button/src/contexts/ButtonContext.ts @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { ButtonSize } from '../components/Button/Button.types'; + +const buttonContext = React.createContext(undefined); + +/** + * @internal + * Internal context value used to update default values between internal components + */ +export interface ButtonContextValue { + size?: ButtonSize; +} + +const buttonContextDefaultValue: ButtonContextValue = {}; + +/** + * @internal + * Internal context provider used to update default values between internal components + */ +export const ButtonContextProvider = buttonContext.Provider; + +/** + * @internal + * Internal context hook used to update default values between internal components + */ +export const useButtonContext = () => React.useContext(buttonContext) ?? buttonContextDefaultValue; diff --git a/packages/react-components/react-button/src/contexts/index.ts b/packages/react-components/react-button/src/contexts/index.ts new file mode 100644 index 00000000000000..e0b0457ba97a21 --- /dev/null +++ b/packages/react-components/react-button/src/contexts/index.ts @@ -0,0 +1 @@ +export * from './ButtonContext'; diff --git a/packages/react-components/react-button/src/index.ts b/packages/react-components/react-button/src/index.ts index 75ce388e1dfe96..baff4e44af77d3 100644 --- a/packages/react-components/react-button/src/index.ts +++ b/packages/react-components/react-button/src/index.ts @@ -40,3 +40,6 @@ export { export type { ToggleButtonProps, ToggleButtonState } from './ToggleButton'; export { useToggleState } from './utils/index'; + +export { ButtonContextProvider, useButtonContext } from './contexts/index'; +export type { ButtonContextValue } from './contexts/index';