Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "removes TreeItemId type from react-tree",
"packageName": "@fluentui/react-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "feat: value property over id",
"packageName": "@fluentui/react-tree",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ import { treeClassNames } from '@fluentui/react-tree';
import { TreeContextValue } from '@fluentui/react-tree';
import { TreeItem } from '@fluentui/react-tree';
import { treeItemClassNames } from '@fluentui/react-tree';
import { TreeItemId } from '@fluentui/react-tree';
import { TreeItemLayout } from '@fluentui/react-tree';
import { treeItemLayoutClassNames } from '@fluentui/react-tree';
import { TreeItemLayoutProps } from '@fluentui/react-tree';
Expand Down Expand Up @@ -253,8 +252,6 @@ export { TreeItem }

export { treeItemClassNames }

export { TreeItemId }

export { TreeItemLayout }

export { treeItemLayoutClassNames }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ export type {
TreeItemLayoutState,
TreeItemLayoutSlots,
TreeItemLayoutProps,
TreeItemId,
TreeContextValue,
NestedTreeItem,
FlatTree,
Expand Down
103 changes: 63 additions & 40 deletions packages/react-components/react-tree/etc/react-tree.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,36 @@ import { ProviderProps } from 'react';
import * as React_2 from 'react';
import type { Slot } from '@fluentui/react-utilities';
import type { SlotClassNames } from '@fluentui/react-utilities';
import { SlotRenderFunction } from '@fluentui/react-utilities';

// @public
export const flattenTree_unstable: (items: NestedTreeItem[]) => FlatTreeItemProps[];
export const flattenTree_unstable: <Value = string>(items: NestedTreeItem<Value>[]) => FlatTreeItemProps<Value>[];

// @public
export type FlatTree = {
getTreeProps(): FlatTreeProps;
navigate(data: TreeNavigationData_unstable): void;
getNextNavigableItem(visibleItems: FlatTreeItem[], data: TreeNavigationData_unstable): FlatTreeItem | undefined;
items(): IterableIterator<FlatTreeItem>;
export type FlatTree<Value = string> = {
getTreeProps(): FlatTreeProps<Value>;
navigate(data: TreeNavigationData_unstable<Value>): void;
getNextNavigableItem(visibleItems: FlatTreeItem<Value>[], data: TreeNavigationData_unstable<Value>): FlatTreeItem<Value> | undefined;
items(): IterableIterator<FlatTreeItem<Value>>;
};

// @public (undocumented)
export type FlatTreeItem = Readonly<MutableFlatTreeItem>;
export type FlatTreeItem<Value = string> = Readonly<MutableFlatTreeItem<Value>>;

// @public (undocumented)
export type FlatTreeItemProps = TreeItemProps & {
id: TreeItemId;
parentId?: string;
export type FlatTreeItemProps<Value = string> = Omit<TreeItemProps, 'value'> & {
value: Value;
parentValue?: Value;
};

// @public (undocumented)
export type FlatTreeProps = Required<Pick<TreeProps, 'openItems' | 'onOpenChange' | 'onNavigation_unstable'> & {
export type FlatTreeProps<Value = string> = Required<Pick<TreeProps<Value>, 'openItems' | 'onOpenChange' | 'onNavigation_unstable'> & {
ref: React_2.Ref<HTMLDivElement>;
}>;

// @public (undocumented)
export type NestedTreeItem = Omit<TreeItemProps, 'subtree'> & {
subtree?: NestedTreeItem[];
export type NestedTreeItem<Value = string> = Omit<TreeItemProps<Value>, 'subtree'> & {
subtree?: NestedTreeItem<Value>[];
};

// @public (undocumented)
Expand All @@ -71,7 +72,22 @@ export const renderTreeItemLayout_unstable: (state: TreeItemLayoutState) => JSX.
export const renderTreeItemPersonaLayout_unstable: (state: TreeItemPersonaLayoutState, contextValues: TreeItemPersonaLayoutContextValues) => JSX.Element;

// @public
export const Tree: ForwardRefComponent<TreeProps>;
export const Tree: React_2.ForwardRefExoticComponent<Omit<TreeSlots, "root"> & Omit<{
as?: "div" | undefined;
} & Pick<React_2.DetailedHTMLProps<React_2.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React_2.HTMLAttributes<HTMLDivElement>> & {
ref?: ((instance: HTMLDivElement | null) => void) | React_2.RefObject<HTMLDivElement> | null | undefined;
} & {
children?: React_2.ReactNode | SlotRenderFunction<Pick<React_2.DetailedHTMLProps<React_2.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React_2.HTMLAttributes<HTMLDivElement>> & {
ref?: ((instance: HTMLDivElement | null) => void) | React_2.RefObject<HTMLDivElement> | null | undefined;
}>;
}, "ref"> & {
appearance?: "subtle" | "subtle-alpha" | "transparent" | undefined;
size?: "small" | "medium" | undefined;
openItems?: Iterable<string> | undefined;
defaultOpenItems?: Iterable<string> | undefined;
onOpenChange?(event: React_2.KeyboardEvent<HTMLElement> | React_2.MouseEvent<HTMLElement, MouseEvent>, data: TreeOpenChangeData<string>): void;
onNavigation_unstable?(event: React_2.KeyboardEvent<HTMLElement> | React_2.MouseEvent<HTMLElement, MouseEvent>, data: TreeNavigationData_unstable<string>): void;
} & React_2.RefAttributes<HTMLDivElement>> & (<Value = string>(props: TreeProps<Value>) => JSX.Element);

// @public (undocumented)
export const treeClassNames: SlotClassNames<TreeSlots>;
Expand All @@ -81,20 +97,30 @@ export type TreeContextValue = {
level: number;
appearance: 'subtle' | 'subtle-alpha' | 'transparent';
size: 'small' | 'medium';
openItems: ImmutableSet<TreeItemId>;
requestOpenChange(data: TreeOpenChangeData): void;
requestNavigation(data: TreeNavigationData_unstable): void;
openItems: ImmutableSet<unknown>;
requestOpenChange(data: TreeOpenChangeData<unknown>): void;
requestNavigation(data: TreeNavigationData_unstable<unknown>): void;
};

// @public
export const TreeItem: ForwardRefComponent<TreeItemProps>;
export const TreeItem: React_2.ForwardRefExoticComponent<Omit<Partial<TreeItemSlots>, "root"> & Omit<{
as?: "div" | undefined;
} & Pick<React_2.DetailedHTMLProps<React_2.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React_2.HTMLAttributes<HTMLDivElement>> & {
ref?: ((instance: HTMLDivElement | null) => void) | React_2.RefObject<HTMLDivElement> | null | undefined;
} & {
children?: React_2.ReactNode | SlotRenderFunction<Pick<React_2.DetailedHTMLProps<React_2.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React_2.HTMLAttributes<HTMLDivElement>> & {
ref?: ((instance: HTMLDivElement | null) => void) | React_2.RefObject<HTMLDivElement> | null | undefined;
}>;
} & {
style?: TreeItemCSSProperties | undefined;
}, "ref"> & {
value?: string | undefined;
leaf?: boolean | undefined;
} & React_2.RefAttributes<HTMLDivElement>> & (<Value = string>(props: TreeItemProps<Value>) => JSX.Element);

// @public (undocumented)
export const treeItemClassNames: SlotClassNames<TreeItemSlots>;

// @public (undocumented)
export type TreeItemId = string;

// @public
export const TreeItemLayout: ForwardRefComponent<TreeItemLayoutProps>;

Expand Down Expand Up @@ -143,7 +169,8 @@ export type TreeItemPersonaLayoutState = ComponentState<TreeItemPersonaLayoutSlo
};

// @public
export type TreeItemProps = ComponentProps<Partial<TreeItemSlots>> & {
export type TreeItemProps<Value = string> = ComponentProps<Partial<TreeItemSlots>> & {
value?: Value;
leaf?: boolean;
};

Expand Down Expand Up @@ -171,46 +198,42 @@ export type TreeItemState = ComponentState<TreeItemSlots> & {
};

// @public (undocumented)
export type TreeNavigationData_unstable = {
event: React_2.MouseEvent<HTMLElement>;
export type TreeNavigationData_unstable<Value = string> = {
value: Value;
target: HTMLElement;
} & ({
event: React_2.MouseEvent<HTMLElement>;
type: 'Click';
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: 'TypeAhead';
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: typeof ArrowRight;
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: typeof ArrowLeft;
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: typeof ArrowUp;
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: typeof ArrowDown;
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: typeof Home;
} | {
event: React_2.KeyboardEvent<HTMLElement>;
target: HTMLElement;
type: typeof End;
};
});

// @public (undocumented)
export type TreeNavigationEvent_unstable = TreeNavigationData_unstable['event'];

// @public (undocumented)
export type TreeOpenChangeData = {
export type TreeOpenChangeData<Value = string> = {
open: boolean;
value: Value;
} & ({
event: React_2.MouseEvent<HTMLElement>;
target: HTMLElement;
Expand All @@ -237,13 +260,13 @@ export type TreeOpenChangeData = {
export type TreeOpenChangeEvent = TreeOpenChangeData['event'];

// @public (undocumented)
export type TreeProps = ComponentProps<TreeSlots> & {
export type TreeProps<Value = string> = ComponentProps<TreeSlots> & {
appearance?: 'subtle' | 'subtle-alpha' | 'transparent';
size?: 'small' | 'medium';
openItems?: Iterable<TreeItemId>;
defaultOpenItems?: Iterable<TreeItemId>;
onOpenChange?(event: TreeOpenChangeEvent, data: TreeOpenChangeData): void;
onNavigation_unstable?(event: TreeNavigationEvent_unstable, data: TreeNavigationData_unstable): void;
openItems?: Iterable<Value>;
defaultOpenItems?: Iterable<Value>;
onOpenChange?(event: TreeOpenChangeEvent, data: TreeOpenChangeData<Value>): void;
onNavigation_unstable?(event: TreeNavigationEvent_unstable, data: TreeNavigationData_unstable<Value>): void;
};

// @public (undocumented)
Expand All @@ -258,7 +281,7 @@ export type TreeSlots = {
export type TreeState = ComponentState<TreeSlots> & TreeContextValue;

// @public
export function useFlatTree_unstable(flatTreeItemProps: FlatTreeItemProps[], options?: Pick<TreeProps, 'openItems' | 'defaultOpenItems' | 'onOpenChange' | 'onNavigation_unstable'>): FlatTree;
export function useFlatTree_unstable<Value = string>(flatTreeItemProps: FlatTreeItemProps<Value>[], options?: Pick<TreeProps<Value>, 'openItems' | 'defaultOpenItems' | 'onOpenChange' | 'onNavigation_unstable'>): FlatTree<Value>;

// @public
export const useTree_unstable: (props: TreeProps, ref: React_2.Ref<HTMLElement>) => TreeState;
Expand All @@ -270,7 +293,7 @@ export const useTreeContext_unstable: <T>(selector: ContextSelector<TreeContextV
export function useTreeContextValues_unstable(state: TreeState): TreeContextValues;

// @public
export const useTreeItem_unstable: (props: TreeItemProps, ref: React_2.Ref<HTMLDivElement>) => TreeItemState;
export function useTreeItem_unstable<Value = string>(props: TreeItemProps<Value>, ref: React_2.Ref<HTMLDivElement>): TreeItemState;

// @public (undocumented)
export const useTreeItemContext_unstable: () => TreeItemContextValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const FlatTree: React.FC<TreeProps> = (props: TreeProps) => {
return (
<Tree {...props} {...flatTree.getTreeProps()} id="tree" aria-label="Tree">
{Array.from(flatTree.items(), item => (
<TreeItem key={item.id} {...item.getTreeItemProps()} />
<TreeItem key={item.value} {...item.getTreeItemProps()} />
))}
</Tree>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import { useTreeContextValues_unstable } from './useTreeContextValues';
* an item representing a folder can be expanded to reveal the contents of the folder,
* which may be files, folders, or both.
*/
export const Tree: ForwardRefComponent<TreeProps> = React.forwardRef((props, ref) => {
export const Tree = React.forwardRef((props, ref) => {
const state = useTree_unstable(props, ref);
useTreeStyles_unstable(state);
const contextValues = useTreeContextValues_unstable(state);
return renderTree_unstable(state, contextValues);
});
}) as ForwardRefComponent<TreeProps> & (<Value = string>(props: TreeProps<Value>) => JSX.Element);

Tree.displayName = 'Tree';
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ import * as React from 'react';
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import { TreeContextValue } from '../../contexts/treeContext';
import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, End, Enter, Home } from '@fluentui/keyboard-keys';
import { TreeItemId } from '../TreeItem/TreeItem.types';

export type TreeSlots = {
root: Slot<'div'>;
};

// eslint-disable-next-line @typescript-eslint/naming-convention
export type TreeNavigationData_unstable =
| { event: React.MouseEvent<HTMLElement>; target: HTMLElement; type: 'Click' }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: 'TypeAhead' }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: typeof ArrowRight }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: typeof ArrowLeft }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: typeof ArrowUp }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: typeof ArrowDown }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: typeof Home }
| { event: React.KeyboardEvent<HTMLElement>; target: HTMLElement; type: typeof End };
export type TreeNavigationData_unstable<Value = string> = { value: Value; target: HTMLElement } & (
| { event: React.MouseEvent<HTMLElement>; type: 'Click' }
| { event: React.KeyboardEvent<HTMLElement>; type: 'TypeAhead' }
| { event: React.KeyboardEvent<HTMLElement>; type: typeof ArrowRight }
| { event: React.KeyboardEvent<HTMLElement>; type: typeof ArrowLeft }
| { event: React.KeyboardEvent<HTMLElement>; type: typeof ArrowUp }
| { event: React.KeyboardEvent<HTMLElement>; type: typeof ArrowDown }
| { event: React.KeyboardEvent<HTMLElement>; type: typeof Home }
| { event: React.KeyboardEvent<HTMLElement>; type: typeof End }
);

// eslint-disable-next-line @typescript-eslint/naming-convention
export type TreeNavigationEvent_unstable = TreeNavigationData_unstable['event'];

export type TreeOpenChangeData = { open: boolean } & (
export type TreeOpenChangeData<Value = string> = { open: boolean; value: Value } & (
| {
event: React.MouseEvent<HTMLElement>;
target: HTMLElement;
Expand Down Expand Up @@ -56,7 +56,7 @@ export type TreeContextValues = {
tree: TreeContextValue;
};

export type TreeProps = ComponentProps<TreeSlots> & {
export type TreeProps<Value = string> = ComponentProps<TreeSlots> & {
/**
* A tree item can have various appearances:
* - 'subtle' (default): The default tree item styles.
Expand All @@ -75,13 +75,13 @@ export type TreeProps = ComponentProps<TreeSlots> & {
* Controls the state of the open tree items.
* These property is ignored for subtrees.
*/
openItems?: Iterable<TreeItemId>;
openItems?: Iterable<Value>;
/**
* This refers to a list of ids of opened tree items.
* Default value for the uncontrolled state of open tree items.
* These property is ignored for subtrees.
*/
defaultOpenItems?: Iterable<TreeItemId>;
defaultOpenItems?: Iterable<Value>;
/**
* Callback fired when the component changes value from open state.
* These property is ignored for subtrees.
Expand All @@ -90,7 +90,7 @@ export type TreeProps = ComponentProps<TreeSlots> & {
* @param data - A data object with relevant information,
* such as open value and type of interaction that created the event.
*/
onOpenChange?(event: TreeOpenChangeEvent, data: TreeOpenChangeData): void;
onOpenChange?(event: TreeOpenChangeEvent, data: TreeOpenChangeData<Value>): void;

/**
* Callback fired when navigation happens inside the component.
Expand All @@ -102,7 +102,7 @@ export type TreeProps = ComponentProps<TreeSlots> & {
* @param data - A data object with relevant information,
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
onNavigation_unstable?(event: TreeNavigationEvent_unstable, data: TreeNavigationData_unstable): void;
onNavigation_unstable?(event: TreeNavigationEvent_unstable, data: TreeNavigationData_unstable<Value>): void;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import { useTreeItemContextValues_unstable } from './useTreeItemContextValues';
* The content and layout of a TreeItem can be defined using the TreeItemLayout or TreeItemPersonaLayout component,
* which should be used as a direct child of TreeItem.
*
* When a TreeItem has nsted child subtree, an expand/collapse control is displayed,
* When a TreeItem has nested child subtree, an expand/collapse control is displayed,
* allowing the user to show or hide the children.
*/
export const TreeItem: ForwardRefComponent<TreeItemProps> = React.forwardRef((props, ref) => {
export const TreeItem = React.forwardRef((props, ref) => {
const state = useTreeItem_unstable(props, ref);

useTreeItemStyles_unstable(state);
const contextValues = useTreeItemContextValues_unstable(state);
return renderTreeItem_unstable(state, contextValues);
});
}) as ForwardRefComponent<TreeItemProps> & (<Value = string>(props: TreeItemProps<Value>) => JSX.Element);

TreeItem.displayName = 'TreeItem';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { treeItemLevelToken } from '../../utils/tokens';
import * as React from 'react';

export type TreeItemCSSProperties = React.CSSProperties & { [treeItemLevelToken]?: string | number };
export type TreeItemId = string;

export type TreeItemSlots = {
root: Slot<ExtractSlotProps<Slot<'div'> & { style?: TreeItemCSSProperties }>>;
Expand All @@ -31,7 +30,8 @@ export type TreeItemContextValues = {
/**
* TreeItem Props
*/
export type TreeItemProps = ComponentProps<Partial<TreeItemSlots>> & {
export type TreeItemProps<Value = string> = ComponentProps<Partial<TreeItemSlots>> & {
value?: Value;
/**
* If a TreeItem is a leaf, it'll not present the `expandIcon` slot by default.
* This attribute is used to force the decision if a TreeItem is a leaf or not. By not providing this property
Expand Down
Loading