From 8c419dcc098bfc82236856426c2bbdb72d1b86e0 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 3 Jul 2026 04:09:06 +0000 Subject: [PATCH 1/2] release: applying package updates - web-components --- ...ents-66ae5150-e0b3-4a9f-a60f-82d4d6fbf79c.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-66ae5150-e0b3-4a9f-a60f-82d4d6fbf79c.json diff --git a/change/@fluentui-web-components-66ae5150-e0b3-4a9f-a60f-82d4d6fbf79c.json b/change/@fluentui-web-components-66ae5150-e0b3-4a9f-a60f-82d4d6fbf79c.json deleted file mode 100644 index bf1bb4570e242..0000000000000 --- a/change/@fluentui-web-components-66ae5150-e0b3-4a9f-a60f-82d4d6fbf79c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "add sticker sheet page to storybook ", - "packageName": "@fluentui/web-components", - "email": "863023+radium-v@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index d00ac72875a15..887a3d0a449f1 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 03 Jul 2026 04:08:59 GMT", + "tag": "@fluentui/web-components_v3.0.0", + "version": "3.0.0", + "comments": { + "none": [ + { + "author": "863023+radium-v@users.noreply.github.com", + "package": "@fluentui/web-components", + "commit": "da54a2c150e0fe31b7a6342f1e2b9a3aaee4baae", + "comment": "add sticker sheet page to storybook " + } + ] + } + }, { "date": "Mon, 29 Jun 2026 22:18:05 GMT", "tag": "@fluentui/web-components_v3.0.0", From 65db820de531aa7ec14bb33644cd93162722af30 Mon Sep 17 00:00:00 2001 From: Victor Genaev Date: Fri, 3 Jul 2026 11:21:05 +0200 Subject: [PATCH 2/2] feat(react-tag-picker): export headless building blocks and align TagPicker with base-type pattern (#36353) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...cker-d940d709-b689-43c2-b24b-094e17f8e1ff.json | 7 +++++++ .../library/etc/react-tag-picker.api.md | 15 +++++++++++++-- .../react-tag-picker/library/src/TagPicker.ts | 2 ++ .../src/components/TagPicker/TagPicker.types.ts | 15 ++++++++++++--- .../library/src/components/TagPicker/index.ts | 2 ++ .../components/TagPicker/useTagPicker.test.tsx | 10 ++++++++++ .../src/components/TagPicker/useTagPicker.ts | 14 +++++++------- .../react-tag-picker/library/src/index.ts | 10 +++++++++- 8 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 change/@fluentui-react-tag-picker-d940d709-b689-43c2-b24b-094e17f8e1ff.json diff --git a/change/@fluentui-react-tag-picker-d940d709-b689-43c2-b24b-094e17f8e1ff.json b/change/@fluentui-react-tag-picker-d940d709-b689-43c2-b24b-094e17f8e1ff.json new file mode 100644 index 0000000000000..8749c0af57c7c --- /dev/null +++ b/change/@fluentui-react-tag-picker-d940d709-b689-43c2-b24b-094e17f8e1ff.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: export useTagPickerContextValues and TagPickerControlInternalSlots for headless composition", + "packageName": "@fluentui/react-tag-picker", + "email": "vgenaev@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md b/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md index 4ede286a13a3e..a8de5263b8a07 100644 --- a/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md +++ b/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md @@ -61,7 +61,10 @@ export const renderTagPickerOptionGroup: (state: TagPickerOptionGroupState) => J export const TagPicker: React_2.FC; // @public -export type TagPickerBaseProps = DistributiveOmit; +export type TagPickerBaseProps = DistributiveOmit; + +// @public +export type TagPickerBaseState = Omit; // @public export const TagPickerButton: ForwardRefComponent; @@ -129,6 +132,11 @@ export type TagPickerControlBaseState = DistributiveOmit; +// @public (undocumented) +export type TagPickerControlInternalSlots = { + aside?: NonNullable>; +}; + // @public export type TagPickerControlProps = ComponentProps>; @@ -285,7 +293,7 @@ export type TagPickerState = ComponentState & Pick TagPickerState; // @public -export const useTagPickerBase_unstable: (props: TagPickerBaseProps) => TagPickerState; +export const useTagPickerBase_unstable: (props: TagPickerBaseProps) => TagPickerBaseState; // @public export const useTagPickerButton_unstable: (props: TagPickerButtonProps, ref: React_2.Ref) => TagPickerButtonState; @@ -299,6 +307,9 @@ export const useTagPickerButtonStyles_unstable: (state: TagPickerButtonState) => // @public (undocumented) export const useTagPickerContext_unstable: (selector: ContextSelector) => T; +// @public (undocumented) +export function useTagPickerContextValues(state: TagPickerState): TagPickerContextValues; + // @public export const useTagPickerControl_unstable: (props: TagPickerControlProps, ref: React_2.Ref) => TagPickerControlState; diff --git a/packages/react-components/react-tag-picker/library/src/TagPicker.ts b/packages/react-components/react-tag-picker/library/src/TagPicker.ts index 529fff4c9ca27..de35c946bc720 100644 --- a/packages/react-components/react-tag-picker/library/src/TagPicker.ts +++ b/packages/react-components/react-tag-picker/library/src/TagPicker.ts @@ -1,5 +1,6 @@ export type { TagPickerBaseProps, + TagPickerBaseState, TagPickerContextValues, TagPickerOnOpenChangeData, TagPickerOnOptionSelectData, @@ -13,4 +14,5 @@ export { renderTagPicker_unstable, useTagPicker_unstable, useTagPickerBase_unstable, + useTagPickerContextValues, } from './components/TagPicker/index'; diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPicker/TagPicker.types.ts b/packages/react-components/react-tag-picker/library/src/components/TagPicker/TagPicker.types.ts index dfa68936da66a..d14ce9972c67e 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPicker/TagPicker.types.ts +++ b/packages/react-components/react-tag-picker/library/src/components/TagPicker/TagPicker.types.ts @@ -115,7 +115,16 @@ export type TagPickerContextValues = { }; /** - * TagPicker Base Props - omits the floating-ui `positioning` prop; the styled wrapper - * {@link TagPickerProps} re-introduces it via `usePositioning`. + * TagPicker Base Props - omits the presentation-related props that the base hook does not handle: + * the floating-ui `positioning` prop (the styled {@link TagPickerProps} re-introduces it via + * `usePositioning`) as well as `size`, `appearance` and `inline` (layered on by the styled + * {@link useTagPicker_unstable} hook). */ -export type TagPickerBaseProps = DistributiveOmit; +export type TagPickerBaseProps = DistributiveOmit; + +/** + * TagPicker Base State - the state produced by the base hook, which does not interact with the + * `size`, `appearance` and `inline` props. These are layered on by the styled + * {@link useTagPicker_unstable} hook. + */ +export type TagPickerBaseState = Omit; diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPicker/index.ts b/packages/react-components/react-tag-picker/library/src/components/TagPicker/index.ts index 1c1d0bb6f6a0b..919539cb07693 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPicker/index.ts +++ b/packages/react-components/react-tag-picker/library/src/components/TagPicker/index.ts @@ -1,6 +1,7 @@ export { TagPicker } from './TagPicker'; export type { TagPickerBaseProps, + TagPickerBaseState, TagPickerContextValues, TagPickerOnOpenChangeData, TagPickerOnOptionSelectData, @@ -11,3 +12,4 @@ export type { } from './TagPicker.types'; export { renderTagPicker_unstable } from './renderTagPicker'; export { useTagPicker_unstable, useTagPickerBase_unstable } from './useTagPicker'; +export { useTagPickerContextValues } from './useTagPickerContextValues'; diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.test.tsx b/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.test.tsx index 5e142b0d24d7a..5a64c565bb279 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.test.tsx +++ b/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.test.tsx @@ -18,12 +18,22 @@ describe('useTagPicker_unstable', () => { expect(result.current.noPopover).toBe(false); }); + it('defaults appearance to "outline"', () => { + const { result } = renderRoot(); + expect(result.current.appearance).toBe('outline'); + }); + it('honors explicit size and inline props', () => { const { result } = renderRoot({ size: 'large', inline: true }); expect(result.current.size).toBe('large'); expect(result.current.inline).toBe(true); }); + it('honors an explicit appearance prop', () => { + const { result } = renderRoot({ appearance: 'filled-darker' }); + expect(result.current.appearance).toBe('filled-darker'); + }); + it('generates a non-empty popoverId', () => { const { result } = renderRoot(); expect(result.current.popoverId.length).toBeGreaterThan(0); diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.ts b/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.ts index 23047513c5849..6c47cbb52f7cb 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.ts +++ b/packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.ts @@ -4,6 +4,7 @@ import * as React from 'react'; import { elementContains, useEventCallback, useId, useMergedRefs } from '@fluentui/react-utilities'; import type { TagPickerBaseProps, + TagPickerBaseState, TagPickerOnOpenChangeData, TagPickerOnOptionSelectData, TagPickerProps, @@ -22,13 +23,13 @@ const fallbackPositions: PositioningShorthandValue[] = ['above', 'after', 'after * Create the base state required to render TagPicker, without floating-ui positioning. * @param props - props from this instance of TagPicker (without `positioning`) */ -export const useTagPickerBase_unstable = (props: TagPickerBaseProps): TagPickerState => { +export const useTagPickerBase_unstable = (props: TagPickerBaseProps): TagPickerBaseState => { const popoverId = useId('picker-listbox'); const triggerInnerRef = React.useRef(null); const secondaryActionRef = React.useRef(null); const tagPickerGroupRef = React.useRef(null); const passiveTargetRef = React.useRef(null); - const { size = 'medium', inline = false, noPopover = false, disableAutoFocus } = props; + const { noPopover = false, disableAutoFocus } = props; const { controller: activeDescendantController, @@ -59,7 +60,6 @@ export const useTagPickerBase_unstable = (props: TagPickerBaseProps): TagPickerS disableAutoFocus, editable: true, multiselect: true, - size: 'medium', }); const { trigger, popover } = childrenToTriggerAndPopover(props.children, noPopover); @@ -76,15 +76,12 @@ export const useTagPickerBase_unstable = (props: TagPickerBaseProps): TagPickerS secondaryActionRef, tagPickerGroupRef, targetRef: passiveTargetRef, - size, - inline, open: comboboxState.open, mountNode: comboboxState.mountNode, onOptionClick: useEventCallback(event => { comboboxState.onOptionClick(event); comboboxState.setOpen(event, false); }), - appearance: comboboxState.appearance, clearSelection: comboboxState.clearSelection, getOptionById: comboboxState.getOptionById, getOptionsMatchingValue: comboboxState.getOptionsMatchingValue, @@ -123,7 +120,7 @@ export const useTagPickerBase_unstable = (props: TagPickerBaseProps): TagPickerS * @param props - props from this instance of Picker */ export const useTagPicker_unstable = (props: TagPickerProps): TagPickerState => { - const { positioning } = props; + const { positioning, size = 'medium', appearance = 'outline', inline = false } = props; const { targetRef, containerRef } = usePositioning({ position: 'below' as const, @@ -138,6 +135,9 @@ export const useTagPicker_unstable = (props: TagPickerProps): TagPickerState => return { ...baseState, + size, + appearance, + inline, targetRef, popoverRef: useMergedRefs(baseState.popoverRef, containerRef), }; diff --git a/packages/react-components/react-tag-picker/library/src/index.ts b/packages/react-components/react-tag-picker/library/src/index.ts index 20e641c30f2b2..4ea0edf4b40e4 100644 --- a/packages/react-components/react-tag-picker/library/src/index.ts +++ b/packages/react-components/react-tag-picker/library/src/index.ts @@ -1,6 +1,13 @@ -export { TagPicker, renderTagPicker_unstable, useTagPicker_unstable, useTagPickerBase_unstable } from './TagPicker'; +export { + TagPicker, + renderTagPicker_unstable, + useTagPicker_unstable, + useTagPickerBase_unstable, + useTagPickerContextValues, +} from './TagPicker'; export type { TagPickerBaseProps, + TagPickerBaseState, TagPickerContextValues, TagPickerProps, TagPickerSlots, @@ -57,6 +64,7 @@ export { } from './TagPickerControl'; export type { TagPickerControlBaseState, + TagPickerControlInternalSlots, TagPickerControlProps, TagPickerControlSlots, TagPickerControlState,