diff --git a/change/@fluentui-react-swatch-picker-c346c0ef-e11a-45a1-91b0-4efbf20a3127.json b/change/@fluentui-react-swatch-picker-c346c0ef-e11a-45a1-91b0-4efbf20a3127.json new file mode 100644 index 0000000000000..6a3dfca6b4645 --- /dev/null +++ b/change/@fluentui-react-swatch-picker-c346c0ef-e11a-45a1-91b0-4efbf20a3127.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: expose headless base APIs", + "packageName": "@fluentui/react-swatch-picker", + "email": "dmytrokirpa@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-swatch-picker/library/etc/react-swatch-picker.api.md b/packages/react-components/react-swatch-picker/library/etc/react-swatch-picker.api.md index ee9ecdafdd803..17d1b20ffe8c9 100644 --- a/packages/react-components/react-swatch-picker/library/etc/react-swatch-picker.api.md +++ b/packages/react-components/react-swatch-picker/library/etc/react-swatch-picker.api.md @@ -18,6 +18,12 @@ import type { SlotClassNames } from '@fluentui/react-utilities'; // @public export const ColorSwatch: ForwardRefComponent; +// @public (undocumented) +export type ColorSwatchBaseProps = Omit; + +// @public (undocumented) +export type ColorSwatchBaseState = Omit; + // @public (undocumented) export const colorSwatchClassNames: SlotClassNames; @@ -44,6 +50,12 @@ export type ColorSwatchState = ComponentState & Pick; +// @public (undocumented) +export type EmptySwatchBaseProps = ComponentProps; + +// @public (undocumented) +export type EmptySwatchBaseState = ComponentState; + // @public (undocumented) export const emptySwatchClassNames: SlotClassNames; @@ -61,6 +73,12 @@ export type EmptySwatchState = ComponentState & Pick; +// @public (undocumented) +export type ImageSwatchBaseProps = Omit; + +// @public (undocumented) +export type ImageSwatchBaseState = Omit; + // @public (undocumented) export const imageSwatchClassNames: SlotClassNames; @@ -81,22 +99,22 @@ export type ImageSwatchState = ComponentState & Pick JSXElement; +export const renderColorSwatch_unstable: (state: ColorSwatchBaseState) => JSXElement; // @public -export const renderEmptySwatch_unstable: (state: EmptySwatchState) => JSXElement; +export const renderEmptySwatch_unstable: (state: EmptySwatchBaseState) => JSXElement; // @public -export const renderImageSwatch_unstable: (state: ImageSwatchState) => JSXElement; +export const renderImageSwatch_unstable: (state: ImageSwatchBaseState) => JSXElement; // @public -export const renderSwatchPicker_unstable: (state: SwatchPickerState, contextValues: SwatchPickerContextValues) => JSXElement; +export const renderSwatchPicker_unstable: (state: SwatchPickerBaseState, contextValues: SwatchPickerContextValues) => JSXElement; // @public (undocumented) export const renderSwatchPickerGrid: (props: SwatchPickerGridProps) => JSXElement[]; // @public -export const renderSwatchPickerRow_unstable: (state: SwatchPickerRowState) => JSXElement; +export const renderSwatchPickerRow_unstable: (state: SwatchPickerRowBaseState) => JSXElement; // @public (undocumented) export const swatchCSSVars: { @@ -107,6 +125,12 @@ export const swatchCSSVars: { // @public export const SwatchPicker: ForwardRefComponent; +// @public (undocumented) +export type SwatchPickerBaseProps = Omit; + +// @public (undocumented) +export type SwatchPickerBaseState = Omit; + // @public (undocumented) export const swatchPickerClassNames: SlotClassNames; @@ -165,6 +189,12 @@ export const SwatchPickerProvider: React_2.Provider & // @public export const SwatchPickerRow: ForwardRefComponent; +// @public (undocumented) +export type SwatchPickerRowBaseProps = ComponentProps; + +// @public (undocumented) +export type SwatchPickerRowBaseState = ComponentState; + // @public (undocumented) export const swatchPickerRowClassNames: SlotClassNames; @@ -195,24 +225,36 @@ export type SwatchProps = ImageSwatchProps | ColorSwatchProps; // @public export const useColorSwatch_unstable: (props: ColorSwatchProps, ref: React_2.Ref) => ColorSwatchState; +// @public +export const useColorSwatchBase_unstable: (props: ColorSwatchBaseProps, ref: React_2.Ref) => ColorSwatchBaseState; + // @public export const useColorSwatchStyles_unstable: (state: ColorSwatchState) => ColorSwatchState; // @public export const useEmptySwatch_unstable: (props: EmptySwatchProps, ref: React_2.Ref) => EmptySwatchState; +// @public +export const useEmptySwatchBase_unstable: (props: EmptySwatchBaseProps, ref: React_2.Ref) => EmptySwatchBaseState; + // @public export const useEmptySwatchStyles_unstable: (state: EmptySwatchState) => EmptySwatchState; // @public export const useImageSwatch_unstable: (props: ImageSwatchProps, ref: React_2.Ref) => ImageSwatchState; +// @public +export const useImageSwatchBase_unstable: (props: ImageSwatchBaseProps, ref: React_2.Ref) => ImageSwatchBaseState; + // @public export const useImageSwatchStyles_unstable: (state: ImageSwatchState) => ImageSwatchState; // @public export const useSwatchPicker_unstable: (props: SwatchPickerProps, ref: React_2.Ref) => SwatchPickerState; +// @public +export const useSwatchPickerBase_unstable: (props: SwatchPickerBaseProps, ref: React_2.Ref) => SwatchPickerBaseState; + // @public (undocumented) export const useSwatchPickerContextValue_unstable: (selector: ContextSelector) => T; @@ -222,6 +264,9 @@ export const useSwatchPickerContextValues: (state: SwatchPickerState) => SwatchP // @public export const useSwatchPickerRow_unstable: (props: SwatchPickerRowProps, ref: React_2.Ref) => SwatchPickerRowState; +// @public +export const useSwatchPickerRowBase_unstable: (props: SwatchPickerRowBaseProps, ref: React_2.Ref) => SwatchPickerRowBaseState; + // @public export const useSwatchPickerRowStyles_unstable: (state: SwatchPickerRowState) => SwatchPickerRowState; diff --git a/packages/react-components/react-swatch-picker/library/src/ColorSwatch.ts b/packages/react-components/react-swatch-picker/library/src/ColorSwatch.ts index 49d83f567eace..75dae5f4d87fe 100644 --- a/packages/react-components/react-swatch-picker/library/src/ColorSwatch.ts +++ b/packages/react-components/react-swatch-picker/library/src/ColorSwatch.ts @@ -1,4 +1,10 @@ -export type { ColorSwatchProps, ColorSwatchSlots, ColorSwatchState } from './components/ColorSwatch/index'; +export type { + ColorSwatchBaseProps, + ColorSwatchBaseState, + ColorSwatchProps, + ColorSwatchSlots, + ColorSwatchState, +} from './components/ColorSwatch/index'; export { ColorSwatch, colorSwatchClassNames, @@ -6,4 +12,5 @@ export { swatchCSSVars, useColorSwatchStyles_unstable, useColorSwatch_unstable, + useColorSwatchBase_unstable, } from './components/ColorSwatch/index'; diff --git a/packages/react-components/react-swatch-picker/library/src/EmptySwatch.ts b/packages/react-components/react-swatch-picker/library/src/EmptySwatch.ts index e3f07b3ca09b1..8b7bea451c4b7 100644 --- a/packages/react-components/react-swatch-picker/library/src/EmptySwatch.ts +++ b/packages/react-components/react-swatch-picker/library/src/EmptySwatch.ts @@ -1,8 +1,15 @@ -export type { EmptySwatchProps, EmptySwatchSlots, EmptySwatchState } from './components/EmptySwatch/index'; +export type { + EmptySwatchBaseProps, + EmptySwatchBaseState, + EmptySwatchProps, + EmptySwatchSlots, + EmptySwatchState, +} from './components/EmptySwatch/index'; export { EmptySwatch, emptySwatchClassNames, renderEmptySwatch_unstable, + useEmptySwatchBase_unstable, useEmptySwatchStyles_unstable, useEmptySwatch_unstable, } from './components/EmptySwatch/index'; diff --git a/packages/react-components/react-swatch-picker/library/src/ImageSwatch.ts b/packages/react-components/react-swatch-picker/library/src/ImageSwatch.ts index 91d5b933fce0d..e726858537267 100644 --- a/packages/react-components/react-swatch-picker/library/src/ImageSwatch.ts +++ b/packages/react-components/react-swatch-picker/library/src/ImageSwatch.ts @@ -1,8 +1,15 @@ -export type { ImageSwatchProps, ImageSwatchSlots, ImageSwatchState } from './components/ImageSwatch/index'; +export type { + ImageSwatchBaseProps, + ImageSwatchBaseState, + ImageSwatchProps, + ImageSwatchSlots, + ImageSwatchState, +} from './components/ImageSwatch/index'; export { ImageSwatch, imageSwatchClassNames, renderImageSwatch_unstable, useImageSwatchStyles_unstable, useImageSwatch_unstable, + useImageSwatchBase_unstable, } from './components/ImageSwatch/index'; diff --git a/packages/react-components/react-swatch-picker/library/src/SwatchPicker.ts b/packages/react-components/react-swatch-picker/library/src/SwatchPicker.ts index f745cebd312d8..4260050a1c1f5 100644 --- a/packages/react-components/react-swatch-picker/library/src/SwatchPicker.ts +++ b/packages/react-components/react-swatch-picker/library/src/SwatchPicker.ts @@ -1,4 +1,6 @@ export type { + SwatchPickerBaseProps, + SwatchPickerBaseState, SwatchPickerOnSelectEventHandler, SwatchPickerOnSelectionChangeData, SwatchPickerProps, @@ -11,4 +13,5 @@ export { swatchPickerClassNames, useSwatchPickerStyles_unstable, useSwatchPicker_unstable, + useSwatchPickerBase_unstable, } from './components/SwatchPicker/index'; diff --git a/packages/react-components/react-swatch-picker/library/src/SwatchPickerRow.ts b/packages/react-components/react-swatch-picker/library/src/SwatchPickerRow.ts index e895c28862f58..271d0159c9363 100644 --- a/packages/react-components/react-swatch-picker/library/src/SwatchPickerRow.ts +++ b/packages/react-components/react-swatch-picker/library/src/SwatchPickerRow.ts @@ -1,4 +1,6 @@ export type { + SwatchPickerRowBaseProps, + SwatchPickerRowBaseState, SwatchPickerRowProps, SwatchPickerRowSlots, SwatchPickerRowState, @@ -9,4 +11,5 @@ export { swatchPickerRowClassNames, useSwatchPickerRowStyles_unstable, useSwatchPickerRow_unstable, + useSwatchPickerRowBase_unstable, } from './components/SwatchPickerRow/index'; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/ColorSwatch.types.ts b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/ColorSwatch.types.ts index af41ad9d8b8e4..7b2a43968a71a 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/ColorSwatch.types.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/ColorSwatch.types.ts @@ -33,6 +33,8 @@ export type ColorSwatchProps = ComponentProps & value: string; }; +export type ColorSwatchBaseProps = Omit; + /** * State used in rendering ColorSwatch */ @@ -40,3 +42,5 @@ export type ColorSwatchState = ComponentState & Pick & { selected: boolean; }; + +export type ColorSwatchBaseState = Omit; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/index.ts b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/index.ts index 73095cbd7936a..a9a4b2398b42d 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/index.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/index.ts @@ -1,5 +1,11 @@ export { ColorSwatch } from './ColorSwatch'; -export type { ColorSwatchProps, ColorSwatchSlots, ColorSwatchState } from './ColorSwatch.types'; +export type { + ColorSwatchBaseProps, + ColorSwatchBaseState, + ColorSwatchProps, + ColorSwatchSlots, + ColorSwatchState, +} from './ColorSwatch.types'; export { renderColorSwatch_unstable } from './renderColorSwatch'; -export { useColorSwatch_unstable } from './useColorSwatch'; +export { useColorSwatch_unstable, useColorSwatchBase_unstable } from './useColorSwatch'; export { colorSwatchClassNames, swatchCSSVars, useColorSwatchStyles_unstable } from './useColorSwatchStyles.styles'; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/renderColorSwatch.tsx b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/renderColorSwatch.tsx index ba11faab441cd..4171bcd84f1b5 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/renderColorSwatch.tsx +++ b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/renderColorSwatch.tsx @@ -3,12 +3,12 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; -import type { ColorSwatchState, ColorSwatchSlots } from './ColorSwatch.types'; +import type { ColorSwatchBaseState, ColorSwatchSlots } from './ColorSwatch.types'; /** * Render the final JSX of ColorSwatch */ -export const renderColorSwatch_unstable = (state: ColorSwatchState): JSXElement => { +export const renderColorSwatch_unstable = (state: ColorSwatchBaseState): JSXElement => { assertSlots(state); return ( diff --git a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/useColorSwatch.tsx b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/useColorSwatch.tsx index c2bada3e516a1..1eb0a19b74b55 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/useColorSwatch.tsx +++ b/packages/react-components/react-swatch-picker/library/src/components/ColorSwatch/useColorSwatch.tsx @@ -2,28 +2,30 @@ import * as React from 'react'; import { slot, useEventCallback, getIntrinsicElementProps, mergeCallbacks } from '@fluentui/react-utilities'; -import type { ColorSwatchProps, ColorSwatchState } from './ColorSwatch.types'; +import type { + ColorSwatchBaseProps, + ColorSwatchBaseState, + ColorSwatchProps, + ColorSwatchState, +} from './ColorSwatch.types'; import { useSwatchPickerContextValue_unstable } from '../../contexts/swatchPicker'; import { swatchCSSVars } from './useColorSwatchStyles.styles'; import { ProhibitedFilled } from '@fluentui/react-icons'; import { tokens } from '@fluentui/react-theme'; /** - * Create the state required to render ColorSwatch. + * Create the basee state required to render unstyled ColorSwatch. * - * The returned state can be modified with hooks such as useColorSwatchStyles_unstable, - * before being passed to renderColorSwatch_unstable. + * The returned state can be modified with hooks before being passed to renderColorSwatch_unstable. * * @param props - props from this instance of ColorSwatch * @param ref - reference to root HTMLButtonElement of ColorSwatch */ -export const useColorSwatch_unstable = ( - props: ColorSwatchProps, +export const useColorSwatchBase_unstable = ( + props: ColorSwatchBaseProps, ref: React.Ref, -): ColorSwatchState => { - const { borderColor, color, disabled, disabledIcon, icon, value, onClick, size, shape, style, ...rest } = props; - const _size = useSwatchPickerContextValue_unstable(ctx => ctx.size); - const _shape = useSwatchPickerContextValue_unstable(ctx => ctx.shape); +): ColorSwatchBaseState => { + const { borderColor, color, disabled, disabledIcon, icon, value, onClick, style, ...rest } = props; const isGrid = useSwatchPickerContextValue_unstable(ctx => ctx.isGrid); const requestSelectionChange = useSwatchPickerContextValue_unstable(ctx => ctx.requestSelectionChange); @@ -52,10 +54,6 @@ export const useColorSwatch_unstable = ( const iconShorthand = slot.optional(icon, { elementType: 'span' }); const disabledIconShorthand = slot.optional(disabledIcon, { - defaultProps: { - children: , - }, - renderByDefault: true, elementType: 'span', }); @@ -84,10 +82,42 @@ export const useColorSwatch_unstable = ( icon: iconShorthand, disabledIcon: disabledIconShorthand, disabled, - size: size ?? _size, - shape: shape ?? _shape, selected, color, value, }; }; + +/** + * Create the state required to render ColorSwatch. + * + * The returned state can be modified with hooks such as useColorSwatchStyles_unstable, + * before being passed to renderColorSwatch_unstable. + * + * @param props - props from this instance of ColorSwatch + * @param ref - reference to root HTMLButtonElement of ColorSwatch + */ +export const useColorSwatch_unstable = ( + props: ColorSwatchProps, + ref: React.Ref, +): ColorSwatchState => { + const sizeFromContext = useSwatchPickerContextValue_unstable(ctx => ctx.size); + const shapeFromContext = useSwatchPickerContextValue_unstable(ctx => ctx.shape); + const { size = sizeFromContext, shape = shapeFromContext, disabledIcon, ...rest } = props; + + const baseState = useColorSwatchBase_unstable(rest, ref); + + return { + ...baseState, + size, + shape, + disabledIcon: slot.optional(disabledIcon, { + defaultProps: { + ...baseState.disabledIcon, + children: , + }, + renderByDefault: true, + elementType: 'span', + }), + }; +}; diff --git a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/EmptySwatch.types.ts b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/EmptySwatch.types.ts index f3f1ccace6d40..8a22612bf2c6b 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/EmptySwatch.types.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/EmptySwatch.types.ts @@ -10,7 +10,11 @@ export type EmptySwatchSlots = { */ export type EmptySwatchProps = ComponentProps & Pick; +export type EmptySwatchBaseProps = ComponentProps; + /** * State used in rendering EmptySwatch */ export type EmptySwatchState = ComponentState & Pick; + +export type EmptySwatchBaseState = ComponentState; diff --git a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/index.ts b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/index.ts index 53a36de504647..b705fcb1e8757 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/index.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/index.ts @@ -1,5 +1,11 @@ export { EmptySwatch } from './EmptySwatch'; -export type { EmptySwatchProps, EmptySwatchSlots, EmptySwatchState } from './EmptySwatch.types'; +export type { + EmptySwatchBaseProps, + EmptySwatchBaseState, + EmptySwatchProps, + EmptySwatchSlots, + EmptySwatchState, +} from './EmptySwatch.types'; export { renderEmptySwatch_unstable } from './renderEmptySwatch'; -export { useEmptySwatch_unstable } from './useEmptySwatch'; +export { useEmptySwatch_unstable, useEmptySwatchBase_unstable } from './useEmptySwatch'; export { emptySwatchClassNames, useEmptySwatchStyles_unstable } from './useEmptySwatchStyles.styles'; diff --git a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/renderEmptySwatch.tsx b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/renderEmptySwatch.tsx index 47785923e2401..603c0b3cf2392 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/renderEmptySwatch.tsx +++ b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/renderEmptySwatch.tsx @@ -3,12 +3,12 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; -import type { EmptySwatchState, EmptySwatchSlots } from './EmptySwatch.types'; +import type { EmptySwatchBaseState, EmptySwatchSlots } from './EmptySwatch.types'; /** * Render the final JSX of EmptySwatch */ -export const renderEmptySwatch_unstable = (state: EmptySwatchState): JSXElement => { +export const renderEmptySwatch_unstable = (state: EmptySwatchBaseState): JSXElement => { assertSlots(state); return ; diff --git a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/useEmptySwatch.ts b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/useEmptySwatch.ts index 830969f5f35e8..fcb74d989a010 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/useEmptySwatch.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/EmptySwatch/useEmptySwatch.ts @@ -2,25 +2,26 @@ import type * as React from 'react'; import { getIntrinsicElementProps, slot } from '@fluentui/react-utilities'; -import type { EmptySwatchProps, EmptySwatchState } from './EmptySwatch.types'; +import type { + EmptySwatchBaseProps, + EmptySwatchBaseState, + EmptySwatchProps, + EmptySwatchState, +} from './EmptySwatch.types'; import { useSwatchPickerContextValue_unstable } from '../../contexts/swatchPicker'; /** - * Create the state required to render EmptySwatch. + * Create the base state required to render unstyled EmptySwatch. * - * The returned state can be modified with hooks such as useEmptySwatchStyles_unstable, - * before being passed to renderEmptySwatch_unstable. + * The returned state can be modified with hooks before being passed to renderEmptySwatch_unstable. * * @param props - props from this instance of EmptySwatch * @param ref - reference to root HTMLDivElement of EmptySwatch */ -export const useEmptySwatch_unstable = ( - props: EmptySwatchProps, +export const useEmptySwatchBase_unstable = ( + props: EmptySwatchBaseProps, ref: React.Ref, -): EmptySwatchState => { - const { size, shape, ...rest } = props; - const _size = useSwatchPickerContextValue_unstable(ctx => ctx.size); - const _shape = useSwatchPickerContextValue_unstable(ctx => ctx.shape); +): EmptySwatchBaseState => { const isGrid = useSwatchPickerContextValue_unstable(ctx => ctx.isGrid); const role = isGrid ? 'gridcell' : 'radio'; @@ -34,11 +35,35 @@ export const useEmptySwatch_unstable = ( ref, role, ...a11yProps, - ...rest, + ...props, }), { elementType: 'button' }, ), - size: size ?? _size, - shape: shape ?? _shape, + }; +}; + +/** + * Create the state required to render EmptySwatch. + * + * The returned state can be modified with hooks such as useEmptySwatchStyles_unstable, + * before being passed to renderEmptySwatch_unstable. + * + * @param props - props from this instance of EmptySwatch + * @param ref - reference to root HTMLDivElement of EmptySwatch + */ +export const useEmptySwatch_unstable = ( + props: EmptySwatchProps, + ref: React.Ref, +): EmptySwatchState => { + const sizeFromContext = useSwatchPickerContextValue_unstable(ctx => ctx.size); + const shapeFromContext = useSwatchPickerContextValue_unstable(ctx => ctx.shape); + const { size = sizeFromContext, shape = shapeFromContext, ...rest } = props; + + const baseState = useEmptySwatchBase_unstable(rest, ref); + + return { + ...baseState, + size, + shape, }; }; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/ImageSwatch.types.ts b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/ImageSwatch.types.ts index 5ed9117013589..f4a0ccb2d2b8d 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/ImageSwatch.types.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/ImageSwatch.types.ts @@ -21,6 +21,8 @@ export type ImageSwatchProps = ComponentProps & value: string; }; +export type ImageSwatchBaseProps = Omit; + /** * State used in rendering ImageSwatch */ @@ -28,3 +30,5 @@ export type ImageSwatchState = ComponentState & Pick & { selected: boolean; }; + +export type ImageSwatchBaseState = Omit; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/index.ts b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/index.ts index bd86939248ce1..16a5a998b7473 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/index.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/index.ts @@ -1,5 +1,11 @@ export { ImageSwatch } from './ImageSwatch'; -export type { ImageSwatchProps, ImageSwatchSlots, ImageSwatchState } from './ImageSwatch.types'; +export type { + ImageSwatchBaseProps, + ImageSwatchBaseState, + ImageSwatchProps, + ImageSwatchSlots, + ImageSwatchState, +} from './ImageSwatch.types'; export { renderImageSwatch_unstable } from './renderImageSwatch'; -export { useImageSwatch_unstable } from './useImageSwatch'; +export { useImageSwatch_unstable, useImageSwatchBase_unstable } from './useImageSwatch'; export { imageSwatchClassNames, useImageSwatchStyles_unstable } from './useImageSwatchStyles.styles'; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/renderImageSwatch.tsx b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/renderImageSwatch.tsx index 1c9ec30fab848..8aea8fce31bcf 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/renderImageSwatch.tsx +++ b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/renderImageSwatch.tsx @@ -3,12 +3,12 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; -import type { ImageSwatchState, ImageSwatchSlots } from './ImageSwatch.types'; +import type { ImageSwatchBaseState, ImageSwatchSlots } from './ImageSwatch.types'; /** * Render the final JSX of ImageSwatch */ -export const renderImageSwatch_unstable = (state: ImageSwatchState): JSXElement => { +export const renderImageSwatch_unstable = (state: ImageSwatchBaseState): JSXElement => { assertSlots(state); return ; diff --git a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/useImageSwatch.ts b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/useImageSwatch.ts index 4030a53f5a8e6..1dfbefb011fd3 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/useImageSwatch.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/ImageSwatch/useImageSwatch.ts @@ -2,25 +2,27 @@ import type * as React from 'react'; import { getIntrinsicElementProps, slot, useEventCallback, mergeCallbacks } from '@fluentui/react-utilities'; -import type { ImageSwatchProps, ImageSwatchState } from './ImageSwatch.types'; +import type { + ImageSwatchBaseProps, + ImageSwatchBaseState, + ImageSwatchProps, + ImageSwatchState, +} from './ImageSwatch.types'; import { useSwatchPickerContextValue_unstable } from '../../contexts/swatchPicker'; /** - * Create the state required to render ImageSwatch. + * Create the base state required to render unstyled ImageSwatch. * - * The returned state can be modified with hooks such as useImageSwatchStyles_unstable, - * before being passed to renderImageSwatch_unstable. + * The returned state can be modified with hooks before being passed to renderImageSwatch_unstable. * * @param props - props from this instance of ImageSwatch * @param ref - reference to root HTMLDivElement of ImageSwatch */ -export const useImageSwatch_unstable = ( - props: ImageSwatchProps, +export const useImageSwatchBase_unstable = ( + props: ImageSwatchBaseProps, ref: React.Ref, -): ImageSwatchState => { +): ImageSwatchBaseState => { const { src, value, onClick, style, ...rest } = props; - const size = useSwatchPickerContextValue_unstable(ctx => ctx.size); - const shape = useSwatchPickerContextValue_unstable(ctx => ctx.shape); const isGrid = useSwatchPickerContextValue_unstable(ctx => ctx.isGrid); const requestSelectionChange = useSwatchPickerContextValue_unstable(ctx => ctx.requestSelectionChange); @@ -62,7 +64,32 @@ export const useImageSwatch_unstable = ( ), value, selected, - size, - shape, + }; +}; + +/** + * Create the state required to render ImageSwatch. + * + * The returned state can be modified with hooks such as useImageSwatchStyles_unstable, + * before being passed to renderImageSwatch_unstable. + * + * @param props - props from this instance of ImageSwatch + * @param ref - reference to root HTMLDivElement of ImageSwatch + */ +export const useImageSwatch_unstable = ( + props: ImageSwatchProps, + ref: React.Ref, +): ImageSwatchState => { + const sizeFromContext = useSwatchPickerContextValue_unstable(ctx => ctx.size); + const shapeFromContext = useSwatchPickerContextValue_unstable(ctx => ctx.shape); + + const { size: _size, shape: _shape, ...rest } = props; + + const baseState = useImageSwatchBase_unstable(rest, ref); + + return { + ...baseState, + size: sizeFromContext, + shape: shapeFromContext, }; }; diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/SwatchPicker.types.ts b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/SwatchPicker.types.ts index 5e25a408535d4..a91811406e5da 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/SwatchPicker.types.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/SwatchPicker.types.ts @@ -69,6 +69,8 @@ export type SwatchPickerProps = ComponentProps & { spacing?: 'small' | 'medium'; }; +export type SwatchPickerBaseProps = Omit; + /** * State used in rendering SwatchPicker */ @@ -77,3 +79,5 @@ export type SwatchPickerState = ComponentState & Pick & { isGrid: boolean; }; + +export type SwatchPickerBaseState = Omit; diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/index.ts b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/index.ts index aeb175311cc05..52a626a0c4e96 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/index.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/index.ts @@ -1,5 +1,7 @@ export { SwatchPicker } from './SwatchPicker'; export type { + SwatchPickerBaseProps, + SwatchPickerBaseState, SwatchPickerOnSelectEventHandler, SwatchPickerOnSelectionChangeData, SwatchPickerProps, @@ -7,5 +9,5 @@ export type { SwatchPickerState, } from './SwatchPicker.types'; export { renderSwatchPicker_unstable } from './renderSwatchPicker'; -export { useSwatchPicker_unstable } from './useSwatchPicker'; +export { useSwatchPicker_unstable, useSwatchPickerBase_unstable } from './useSwatchPicker'; export { swatchPickerClassNames, useSwatchPickerStyles_unstable } from './useSwatchPickerStyles.styles'; diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/renderSwatchPicker.tsx b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/renderSwatchPicker.tsx index 27e90ef25a8ff..1150b6fc0ac35 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/renderSwatchPicker.tsx +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/renderSwatchPicker.tsx @@ -5,13 +5,13 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; import { SwatchPickerProvider } from '../../contexts/swatchPicker'; import type { SwatchPickerContextValues } from '../../contexts/swatchPicker'; -import type { SwatchPickerState, SwatchPickerSlots } from './SwatchPicker.types'; +import type { SwatchPickerBaseState, SwatchPickerSlots } from './SwatchPicker.types'; /** * Render the final JSX of SwatchPicker */ export const renderSwatchPicker_unstable = ( - state: SwatchPickerState, + state: SwatchPickerBaseState, contextValues: SwatchPickerContextValues, ): JSXElement => { assertSlots(state); diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/useSwatchPicker.ts b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/useSwatchPicker.ts index accf01d22a880..7351c28179ae0 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/useSwatchPicker.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPicker/useSwatchPicker.ts @@ -6,41 +6,31 @@ import { useFieldControlProps_unstable } from '@fluentui/react-field'; import { useArrowNavigationGroup } from '@fluentui/react-tabster'; import { getIntrinsicElementProps, useControllableState, useEventCallback, slot } from '@fluentui/react-utilities'; -import type { SwatchPickerProps, SwatchPickerState } from './SwatchPicker.types'; +import type { + SwatchPickerBaseProps, + SwatchPickerBaseState, + SwatchPickerProps, + SwatchPickerState, +} from './SwatchPicker.types'; /** - * Create the state required to render SwatchPicker. + * Create the base state required to render unstyled SwatchPicker. * - * The returned state can be modified with hooks such as useSwatchPickerStyles_unstable, - * before being passed to renderSwatchPicker_unstable. + * The returned state can be modified with hooks before being passed to renderSwatchPicker_unstable. * * @param props - props from this instance of SwatchPicker * @param ref - reference to root HTMLElement of SwatchPicker */ -export const useSwatchPicker_unstable = ( - props: SwatchPickerProps, +export const useSwatchPickerBase_unstable = ( + props: SwatchPickerBaseProps, ref: React.Ref, -): SwatchPickerState => { +): SwatchPickerBaseState => { // Merge props from surrounding , if any props = useFieldControlProps_unstable(props); - const { - focusMode = 'arrow', - layout, - onSelectionChange, - size = 'medium', - shape, - spacing = 'medium', - style, - ...rest - } = props; + const { layout, onSelectionChange, style, ...rest } = props; const isGrid = layout === 'grid'; - const focusAttributes = useArrowNavigationGroup({ - circular: true, - axis: isGrid ? 'grid-linear' : 'both', - memorizeCurrent: true, - }); const role = isGrid ? 'grid' : 'radiogroup'; @@ -68,7 +58,6 @@ export const useSwatchPicker_unstable = ( getIntrinsicElementProps('div', { ref, role, - ...(focusMode === 'arrow' ? focusAttributes : {}), ...rest, }), { elementType: 'div' }, @@ -76,6 +65,38 @@ export const useSwatchPicker_unstable = ( isGrid, requestSelectionChange, selectedValue, + }; +}; + +/** + * Create the state required to render SwatchPicker. + * + * The returned state can be modified with hooks such as useSwatchPickerStyles_unstable, + * before being passed to renderSwatchPicker_unstable. + * + * @param props - props from this instance of SwatchPicker + * @param ref - reference to root HTMLElement of SwatchPicker + */ +export const useSwatchPicker_unstable = ( + props: SwatchPickerProps, + ref: React.Ref, +): SwatchPickerState => { + const { focusMode = 'arrow', size = 'medium', shape, spacing = 'medium', ...rest } = props; + + const baseState = useSwatchPickerBase_unstable(rest, ref); + + const focusAttributes = useArrowNavigationGroup({ + circular: true, + axis: baseState.isGrid ? 'grid-linear' : 'both', + memorizeCurrent: true, + }); + + return { + ...baseState, + root: { + ...baseState.root, + ...(focusMode === 'arrow' ? focusAttributes : {}), + }, size, shape, spacing, diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/SwatchPickerRow.types.ts b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/SwatchPickerRow.types.ts index c72bf702d2a07..6bccf9f90b874 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/SwatchPickerRow.types.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/SwatchPickerRow.types.ts @@ -10,7 +10,11 @@ export type SwatchPickerRowSlots = { */ export type SwatchPickerRowProps = ComponentProps; +export type SwatchPickerRowBaseProps = ComponentProps; + /** * State used in rendering SwatchPickerRow */ export type SwatchPickerRowState = ComponentState & Pick; + +export type SwatchPickerRowBaseState = ComponentState; diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/index.ts b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/index.ts index c948a0da0e7ce..43447884be283 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/index.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/index.ts @@ -1,5 +1,11 @@ export { SwatchPickerRow } from './SwatchPickerRow'; -export type { SwatchPickerRowProps, SwatchPickerRowSlots, SwatchPickerRowState } from './SwatchPickerRow.types'; +export type { + SwatchPickerRowBaseProps, + SwatchPickerRowBaseState, + SwatchPickerRowProps, + SwatchPickerRowSlots, + SwatchPickerRowState, +} from './SwatchPickerRow.types'; export { renderSwatchPickerRow_unstable } from './renderSwatchPickerRow'; -export { useSwatchPickerRow_unstable } from './useSwatchPickerRow'; +export { useSwatchPickerRow_unstable, useSwatchPickerRowBase_unstable } from './useSwatchPickerRow'; export { swatchPickerRowClassNames, useSwatchPickerRowStyles_unstable } from './useSwatchPickerRowStyles.styles'; diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/renderSwatchPickerRow.tsx b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/renderSwatchPickerRow.tsx index b5d04b63ee252..308b3279e7768 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/renderSwatchPickerRow.tsx +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/renderSwatchPickerRow.tsx @@ -3,12 +3,12 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; -import type { SwatchPickerRowState, SwatchPickerRowSlots } from './SwatchPickerRow.types'; +import type { SwatchPickerRowBaseState, SwatchPickerRowSlots } from './SwatchPickerRow.types'; /** * Render the final JSX of SwatchPickerRow */ -export const renderSwatchPickerRow_unstable = (state: SwatchPickerRowState): JSXElement => { +export const renderSwatchPickerRow_unstable = (state: SwatchPickerRowBaseState): JSXElement => { assertSlots(state); return ; }; diff --git a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/useSwatchPickerRow.ts b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/useSwatchPickerRow.ts index 5f13568814b49..935a8507b7508 100644 --- a/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/useSwatchPickerRow.ts +++ b/packages/react-components/react-swatch-picker/library/src/components/SwatchPickerRow/useSwatchPickerRow.ts @@ -2,24 +2,27 @@ import type * as React from 'react'; import { getIntrinsicElementProps, slot } from '@fluentui/react-utilities'; -import type { SwatchPickerRowProps, SwatchPickerRowState } from './SwatchPickerRow.types'; +import type { + SwatchPickerRowBaseProps, + SwatchPickerRowBaseState, + SwatchPickerRowProps, + SwatchPickerRowState, +} from './SwatchPickerRow.types'; import { useSwatchPickerContextValue_unstable } from '../../contexts/swatchPicker'; /** - * Create the state required to render SwatchPickerRow. + * Create the base state required to render unstyled SwatchPickerRow. * - * The returned state can be modified with hooks such as useSwatchPickerRowStyles_unstable, - * before being passed to renderSwatchPickerRow_unstable. + * The returned state can be modified with hooks before being passed to renderSwatchPickerRow_unstable. * * @param props - props from this instance of SwatchPickerRow * @param ref - reference to root HTMLDivElement of SwatchPickerRow */ -export const useSwatchPickerRow_unstable = ( - props: SwatchPickerRowProps, +export const useSwatchPickerRowBase_unstable = ( + props: SwatchPickerRowBaseProps, ref: React.Ref, -): SwatchPickerRowState => { +): SwatchPickerRowBaseState => { const { style, ...rest } = props; - const spacing = useSwatchPickerContextValue_unstable(ctx => ctx.spacing); return { components: { @@ -33,6 +36,27 @@ export const useSwatchPickerRow_unstable = ( }), { elementType: 'div' }, ), + }; +}; + +/** + * Create the state required to render SwatchPickerRow. + * + * The returned state can be modified with hooks such as useSwatchPickerRowStyles_unstable, + * before being passed to renderSwatchPickerRow_unstable. + * + * @param props - props from this instance of SwatchPickerRow + * @param ref - reference to root HTMLDivElement of SwatchPickerRow + */ +export const useSwatchPickerRow_unstable = ( + props: SwatchPickerRowProps, + ref: React.Ref, +): SwatchPickerRowState => { + const spacing = useSwatchPickerContextValue_unstable(ctx => ctx.spacing); + const baseState = useSwatchPickerRowBase_unstable(props, ref); + + return { + ...baseState, spacing, }; }; diff --git a/packages/react-components/react-swatch-picker/library/src/index.ts b/packages/react-components/react-swatch-picker/library/src/index.ts index 7a4d2157f9c6b..e531f78d5311f 100644 --- a/packages/react-components/react-swatch-picker/library/src/index.ts +++ b/packages/react-components/react-swatch-picker/library/src/index.ts @@ -3,6 +3,7 @@ export { renderSwatchPicker_unstable, useSwatchPickerStyles_unstable, useSwatchPicker_unstable, + useSwatchPickerBase_unstable, swatchPickerClassNames, } from './SwatchPicker'; export { @@ -13,6 +14,8 @@ export { } from './contexts'; export type { SwatchPickerContextValue, SwatchPickerContextValues } from './contexts'; export type { + SwatchPickerBaseProps, + SwatchPickerBaseState, SwatchPickerProps, SwatchPickerSlots, SwatchPickerState, @@ -24,23 +27,44 @@ export { renderColorSwatch_unstable, useColorSwatchStyles_unstable, useColorSwatch_unstable, + useColorSwatchBase_unstable, colorSwatchClassNames, swatchCSSVars, } from './ColorSwatch'; -export type { ColorSwatchProps, ColorSwatchSlots, ColorSwatchState } from './ColorSwatch'; +export type { + ColorSwatchBaseProps, + ColorSwatchBaseState, + ColorSwatchProps, + ColorSwatchSlots, + ColorSwatchState, +} from './ColorSwatch'; export { ImageSwatch, renderImageSwatch_unstable, useImageSwatchStyles_unstable, useImageSwatch_unstable, + useImageSwatchBase_unstable, imageSwatchClassNames, } from './ImageSwatch'; -export type { ImageSwatchProps, ImageSwatchSlots, ImageSwatchState } from './ImageSwatch'; -export type { SwatchPickerRowProps, SwatchPickerRowSlots, SwatchPickerRowState } from './SwatchPickerRow'; +export type { + ImageSwatchBaseProps, + ImageSwatchBaseState, + ImageSwatchProps, + ImageSwatchSlots, + ImageSwatchState, +} from './ImageSwatch'; +export type { + SwatchPickerRowBaseProps, + SwatchPickerRowBaseState, + SwatchPickerRowProps, + SwatchPickerRowSlots, + SwatchPickerRowState, +} from './SwatchPickerRow'; export { SwatchPickerRow, renderSwatchPickerRow_unstable, useSwatchPickerRowStyles_unstable, + useSwatchPickerRowBase_unstable, useSwatchPickerRow_unstable, swatchPickerRowClassNames, } from './SwatchPickerRow'; @@ -51,6 +75,13 @@ export { renderEmptySwatch_unstable, useEmptySwatchStyles_unstable, useEmptySwatch_unstable, + useEmptySwatchBase_unstable, emptySwatchClassNames, } from './EmptySwatch'; -export type { EmptySwatchProps, EmptySwatchSlots, EmptySwatchState } from './EmptySwatch'; +export type { + EmptySwatchBaseProps, + EmptySwatchBaseState, + EmptySwatchProps, + EmptySwatchSlots, + EmptySwatchState, +} from './EmptySwatch';