Skip to content

Commit 9f68ccb

Browse files
committed
feat(react-tag-picker): add base hooks for TagPicker components
1 parent 5a2ed7e commit 9f68ccb

23 files changed

+359
-73
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "feat: add base hooks for TagPicker components",
4+
"packageName": "@fluentui/react-tag-picker",
5+
"email": "dmytrokirpa@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type { OptionState } from '@fluentui/react-combobox';
2828
import * as React_2 from 'react';
2929
import type { Slot } from '@fluentui/react-utilities';
3030
import type { SlotClassNames } from '@fluentui/react-utilities';
31+
import type { TagGroupBaseState } from '@fluentui/react-tags';
3132
import { TagGroupContextValues } from '@fluentui/react-tags';
3233
import type { TagGroupSlots } from '@fluentui/react-tags';
3334
import type { TagGroupState } from '@fluentui/react-tags';
@@ -59,9 +60,21 @@ export const renderTagPickerOptionGroup: (state: TagPickerOptionGroupState) => J
5960
// @public
6061
export const TagPicker: React_2.FC<TagPickerProps>;
6162

63+
// @public
64+
export type TagPickerBaseProps = Omit<TagPickerProps, 'size' | 'appearance'>;
65+
66+
// @public
67+
export type TagPickerBaseState = Omit<TagPickerState, 'size' | 'appearance'>;
68+
6269
// @public
6370
export const TagPickerButton: ForwardRefComponent<TagPickerButtonProps>;
6471

72+
// @public
73+
export type TagPickerButtonBaseProps = Omit<TagPickerButtonProps, 'size' | 'appearance'>;
74+
75+
// @public
76+
export type TagPickerButtonBaseState = Omit<TagPickerButtonState, 'size'>;
77+
6578
// @public (undocumented)
6679
export const tagPickerButtonClassNames: SlotClassNames<TagPickerButtonSlots>;
6780

@@ -110,6 +123,12 @@ export type TagPickerContextValues = {
110123
// @public
111124
export const TagPickerControl: ForwardRefComponent<TagPickerControlProps>;
112125

126+
// @public
127+
export type TagPickerControlBaseProps = TagPickerControlProps;
128+
129+
// @public
130+
export type TagPickerControlBaseState = Omit<TagPickerControlState, 'size' | 'appearance'>;
131+
113132
// @public (undocumented)
114133
export const tagPickerControlClassNames: SlotClassNames<TagPickerControlSlots & TagPickerControlInternalSlots>;
115134

@@ -132,6 +151,14 @@ export type TagPickerControlState = ComponentState<TagPickerControlSlots & TagPi
132151
// @public
133152
export const TagPickerGroup: ForwardRefComponent<TagPickerGroupProps>;
134153

154+
// @public
155+
export type TagPickerGroupBaseProps = TagPickerGroupProps;
156+
157+
// @public
158+
export type TagPickerGroupBaseState = TagGroupBaseState & {
159+
hasSelectedOptions: boolean;
160+
};
161+
135162
// @public (undocumented)
136163
export const tagPickerGroupClassNames: SlotClassNames<TagPickerGroupSlots>;
137164

@@ -149,6 +176,12 @@ export type TagPickerGroupState = TagGroupState & {
149176
// @public
150177
export const TagPickerInput: ForwardRefComponent<TagPickerInputProps>;
151178

179+
// @public
180+
export type TagPickerInputBaseProps = Omit<TagPickerInputProps, 'appearance'>;
181+
182+
// @public
183+
export type TagPickerInputBaseState = Omit<TagPickerInputState, 'size'>;
184+
152185
// @public (undocumented)
153186
export const tagPickerInputClassNames: SlotClassNames<TagPickerInputSlots>;
154187

@@ -262,9 +295,15 @@ export type TagPickerState = ComponentState<TagPickerSlots> & Pick<ComboboxState
262295
// @public
263296
export const useTagPicker_unstable: (props: TagPickerProps) => TagPickerState;
264297

298+
// @public
299+
export const useTagPickerBase_unstable: (props: TagPickerBaseProps) => TagPickerBaseState;
300+
265301
// @public
266302
export const useTagPickerButton_unstable: (props: TagPickerButtonProps, ref: React_2.Ref<HTMLButtonElement>) => TagPickerButtonState;
267303

304+
// @public
305+
export const useTagPickerButtonBase_unstable: (props: TagPickerButtonBaseProps, ref: React_2.Ref<HTMLButtonElement>) => TagPickerButtonBaseState;
306+
268307
// @public
269308
export const useTagPickerButtonStyles_unstable: (state: TagPickerButtonState) => TagPickerButtonState;
270309

@@ -274,6 +313,9 @@ export const useTagPickerContext_unstable: <T>(selector: ContextSelector<TagPick
274313
// @public
275314
export const useTagPickerControl_unstable: (props: TagPickerControlProps, ref: React_2.Ref<HTMLDivElement>) => TagPickerControlState;
276315

316+
// @public
317+
export const useTagPickerControlBase_unstable: (props: TagPickerControlBaseProps, ref: React_2.Ref<HTMLDivElement>) => TagPickerControlBaseState;
318+
277319
// @public
278320
export const useTagPickerControlStyles_unstable: (state: TagPickerControlState) => TagPickerControlState;
279321

@@ -283,12 +325,18 @@ export function useTagPickerFilter({ filter: filterOverride, noOptionsElement, r
283325
// @public
284326
export const useTagPickerGroup_unstable: (props: TagPickerGroupProps, ref: React_2.Ref<HTMLDivElement>) => TagPickerGroupState;
285327

328+
// @public
329+
export const useTagPickerGroupBase_unstable: (props: TagPickerGroupBaseProps, ref: React_2.Ref<HTMLDivElement>) => TagPickerGroupBaseState;
330+
286331
// @public
287332
export const useTagPickerGroupStyles_unstable: (state: TagPickerGroupState) => TagPickerGroupState;
288333

289334
// @public
290335
export const useTagPickerInput_unstable: (propsArg: TagPickerInputProps, ref: React_2.Ref<HTMLInputElement>) => TagPickerInputState;
291336

337+
// @public
338+
export const useTagPickerInputBase_unstable: (propsArg: TagPickerInputBaseProps, ref: React_2.Ref<HTMLInputElement>) => TagPickerInputBaseState;
339+
292340
// @public
293341
export const useTagPickerInputStyles_unstable: (state: TagPickerInputState) => TagPickerInputState;
294342

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export type {
2+
TagPickerBaseProps,
3+
TagPickerBaseState,
24
TagPickerContextValues,
35
TagPickerOnOpenChangeData,
46
TagPickerOnOptionSelectData,
@@ -7,4 +9,9 @@ export type {
79
TagPickerSlots,
810
TagPickerState,
911
} from './components/TagPicker/index';
10-
export { TagPicker, renderTagPicker_unstable, useTagPicker_unstable } from './components/TagPicker/index';
12+
export {
13+
TagPicker,
14+
renderTagPicker_unstable,
15+
useTagPickerBase_unstable,
16+
useTagPicker_unstable,
17+
} from './components/TagPicker/index';

packages/react-components/react-tag-picker/library/src/TagPickerButton.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export type {
2+
TagPickerButtonBaseProps,
3+
TagPickerButtonBaseState,
24
TagPickerButtonProps,
35
TagPickerButtonSlots,
46
TagPickerButtonState,
@@ -8,5 +10,6 @@ export {
810
renderTagPickerButton_unstable,
911
tagPickerButtonClassNames,
1012
useTagPickerButtonStyles_unstable,
13+
useTagPickerButtonBase_unstable,
1114
useTagPickerButton_unstable,
1215
} from './components/TagPickerButton/index';

packages/react-components/react-tag-picker/library/src/TagPickerControl.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export type {
2+
TagPickerControlBaseProps,
3+
TagPickerControlBaseState,
24
TagPickerControlCSSProperties,
35
TagPickerControlInternalSlots,
46
TagPickerControlProps,
@@ -12,5 +14,6 @@ export {
1214
tagPickerControlAsideWidthToken,
1315
tagPickerControlClassNames,
1416
useTagPickerControlStyles_unstable,
17+
useTagPickerControlBase_unstable,
1518
useTagPickerControl_unstable,
1619
} from './components/TagPickerControl/index';
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
export type { TagPickerGroupProps, TagPickerGroupSlots, TagPickerGroupState } from './components/TagPickerGroup/index';
1+
export type {
2+
TagPickerGroupBaseProps,
3+
TagPickerGroupBaseState,
4+
TagPickerGroupProps,
5+
TagPickerGroupSlots,
6+
TagPickerGroupState,
7+
} from './components/TagPickerGroup/index';
28
export {
39
TagPickerGroup,
410
renderTagPickerGroup_unstable,
511
tagPickerGroupClassNames,
612
useTagPickerGroupStyles_unstable,
13+
useTagPickerGroupBase_unstable,
714
useTagPickerGroup_unstable,
815
} from './components/TagPickerGroup/index';
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
export type { TagPickerInputProps, TagPickerInputSlots, TagPickerInputState } from './components/TagPickerInput/index';
1+
export type {
2+
TagPickerInputBaseProps,
3+
TagPickerInputBaseState,
4+
TagPickerInputProps,
5+
TagPickerInputSlots,
6+
TagPickerInputState,
7+
} from './components/TagPickerInput/index';
28
export {
39
TagPickerInput,
410
renderTagPickerInput_unstable,
511
tagPickerInputClassNames,
612
useTagPickerInputStyles_unstable,
13+
useTagPickerInputBase_unstable,
714
useTagPickerInput_unstable,
815
} from './components/TagPickerInput/index';

packages/react-components/react-tag-picker/library/src/components/TagPicker/TagPicker.types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ export type TagPickerContextValues = {
106106
activeDescendant: ActiveDescendantContextValue;
107107
listbox: ListboxContextValue;
108108
};
109+
110+
/**
111+
* TagPicker Base Props - omits design-only props
112+
*/
113+
export type TagPickerBaseProps = Omit<TagPickerProps, 'size' | 'appearance'>;
114+
115+
/**
116+
* TagPicker Base State - omits design-only state
117+
*/
118+
export type TagPickerBaseState = Omit<TagPickerState, 'size' | 'appearance'>;

packages/react-components/react-tag-picker/library/src/components/TagPicker/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export { TagPicker } from './TagPicker';
22
export type {
3+
TagPickerBaseProps,
4+
TagPickerBaseState,
35
TagPickerContextValues,
46
TagPickerOnOpenChangeData,
57
TagPickerOnOptionSelectData,
@@ -9,4 +11,4 @@ export type {
911
TagPickerState,
1012
} from './TagPicker.types';
1113
export { renderTagPicker_unstable } from './renderTagPicker';
12-
export { useTagPicker_unstable } from './useTagPicker';
14+
export { useTagPickerBase_unstable, useTagPicker_unstable } from './useTagPicker';

packages/react-components/react-tag-picker/library/src/components/TagPicker/useTagPicker.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
import * as React from 'react';
44
import { elementContains, useEventCallback, useId, useMergedRefs } from '@fluentui/react-utilities';
55
import type {
6+
TagPickerBaseProps,
7+
TagPickerBaseState,
68
TagPickerOnOpenChangeData,
79
TagPickerOnOptionSelectData,
810
TagPickerProps,
911
TagPickerState,
1012
} from './TagPicker.types';
1113
import { optionClassNames } from '@fluentui/react-combobox';
12-
import type { PositioningShorthandValue } from '@fluentui/react-positioning';
13-
import { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';
14+
import {
15+
type PositioningShorthandValue,
16+
resolvePositioningShorthand,
17+
usePositioning,
18+
} from '@fluentui/react-positioning';
1419
import { useActiveDescendant } from '@fluentui/react-aria';
1520
import { useComboboxBaseState } from '@fluentui/react-combobox';
1621

@@ -26,11 +31,27 @@ const fallbackPositions: PositioningShorthandValue[] = ['above', 'after', 'after
2631
* @param props - props from this instance of Picker
2732
*/
2833
export const useTagPicker_unstable = (props: TagPickerProps): TagPickerState => {
34+
const { size = 'medium', appearance = 'outline', ...baseProps } = props;
35+
const state = useTagPickerBase_unstable(baseProps);
36+
37+
return {
38+
...state,
39+
size,
40+
appearance,
41+
};
42+
};
43+
44+
/**
45+
* Create the base state required to render TagPicker, without design-only props.
46+
*
47+
* @param props - props from this instance of TagPicker (without size, appearance)
48+
*/
49+
export const useTagPickerBase_unstable = (props: TagPickerBaseProps): TagPickerBaseState => {
2950
const popoverId = useId('picker-listbox');
3051
const triggerInnerRef = React.useRef<HTMLInputElement | HTMLButtonElement>(null);
3152
const secondaryActionRef = React.useRef<HTMLSpanElement>(null);
3253
const tagPickerGroupRef = React.useRef<HTMLDivElement>(null);
33-
const { positioning, size = 'medium', inline = false, noPopover = false, disableAutoFocus } = props;
54+
const { positioning, inline = false, noPopover = false, disableAutoFocus } = props;
3455

3556
const { targetRef, containerRef } = usePositioning({
3657
position: 'below' as const,
@@ -87,15 +108,13 @@ export const useTagPicker_unstable = (props: TagPickerProps): TagPickerState =>
87108
secondaryActionRef,
88109
tagPickerGroupRef,
89110
targetRef,
90-
size,
91111
inline,
92112
open: comboboxState.open,
93113
mountNode: comboboxState.mountNode,
94114
onOptionClick: useEventCallback(event => {
95115
comboboxState.onOptionClick(event);
96116
comboboxState.setOpen(event, false);
97117
}),
98-
appearance: comboboxState.appearance,
99118
clearSelection: comboboxState.clearSelection,
100119
getOptionById: comboboxState.getOptionById,
101120
getOptionsMatchingValue: comboboxState.getOptionsMatchingValue,

0 commit comments

Comments
 (0)