From b8d90756a6d10f9a8681540aaeb3228187eeaa89 Mon Sep 17 00:00:00 2001 From: Bernardo Sunderhus Date: Fri, 25 Nov 2022 06:58:12 +0000 Subject: [PATCH] chore(react-tree): scaffold TreeItemLayout + export composition methods --- .../react-tree/etc/react-tree.api.md | 44 +++++++++++++++++++ .../react-tree/src/TreeItemLayout.ts | 1 + .../TreeItemLayout/TreeItemLayout.test.tsx | 18 ++++++++ .../TreeItemLayout/TreeItemLayout.tsx | 18 ++++++++ .../TreeItemLayout/TreeItemLayout.types.ts | 15 +++++++ .../TreeItemLayout.test.tsx.snap | 11 +++++ .../src/components/TreeItemLayout/index.ts | 5 +++ .../TreeItemLayout/renderTreeItemLayout.tsx | 13 ++++++ .../TreeItemLayout/useTreeItemLayout.ts | 31 +++++++++++++ .../TreeItemLayout/useTreeItemLayoutStyles.ts | 33 ++++++++++++++ .../react-components/react-tree/src/index.ts | 19 +++++++- 11 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 packages/react-components/react-tree/src/TreeItemLayout.ts create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.test.tsx create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.tsx create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.types.ts create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/__snapshots__/TreeItemLayout.test.tsx.snap create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/index.ts create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/renderTreeItemLayout.tsx create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayout.ts create mode 100644 packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayoutStyles.ts diff --git a/packages/react-components/react-tree/etc/react-tree.api.md b/packages/react-components/react-tree/etc/react-tree.api.md index 2f6c6cc1814c3..3937b23100ad1 100644 --- a/packages/react-components/react-tree/etc/react-tree.api.md +++ b/packages/react-components/react-tree/etc/react-tree.api.md @@ -17,6 +17,15 @@ import * as React_2 from 'react'; import type { Slot } from '@fluentui/react-utilities'; import type { SlotClassNames } from '@fluentui/react-utilities'; +// @public (undocumented) +export const renderTree_unstable: (state: TreeState, contextValues: TreeContextValues) => JSX.Element; + +// @public +export const renderTreeItem_unstable: (state: TreeItemState) => JSX.Element; + +// @public +export const renderTreeItemLayout_unstable: (state: TreeItemLayoutState) => JSX.Element; + // @public export const Tree: ForwardRefComponent; @@ -38,6 +47,23 @@ export const TreeItem: ForwardRefComponent; // @public (undocumented) export const treeItemClassNames: SlotClassNames; +// @public +export const TreeItemLayout: ForwardRefComponent; + +// @public (undocumented) +export const treeItemLayoutClassNames: SlotClassNames; + +// @public +export type TreeItemLayoutProps = ComponentProps; + +// @public (undocumented) +export type TreeItemLayoutSlots = { + root: Slot<'div'>; +}; + +// @public +export type TreeItemLayoutState = ComponentState; + // @public export type TreeItemProps = ComponentProps; @@ -69,9 +95,27 @@ export type TreeState = ComponentState & TreeContextValue & { open: boolean; }; +// @public +export const useTree_unstable: (props: TreeProps, ref: React_2.Ref) => TreeState; + // @public (undocumented) export const useTreeContext_unstable: (selector: ContextSelector) => T; +// @public +export const useTreeItem_unstable: (props: TreeItemProps, ref: React_2.Ref) => TreeItemState; + +// @public +export const useTreeItemLayout_unstable: (props: TreeItemLayoutProps, ref: React_2.Ref) => TreeItemLayoutState; + +// @public +export const useTreeItemLayoutStyles_unstable: (state: TreeItemLayoutState) => TreeItemLayoutState; + +// @public +export const useTreeItemStyles_unstable: (state: TreeItemState) => TreeItemState; + +// @public (undocumented) +export const useTreeStyles_unstable: (state: TreeState) => TreeState; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-components/react-tree/src/TreeItemLayout.ts b/packages/react-components/react-tree/src/TreeItemLayout.ts new file mode 100644 index 0000000000000..0fd4c2613f9bd --- /dev/null +++ b/packages/react-components/react-tree/src/TreeItemLayout.ts @@ -0,0 +1 @@ +export * from './components/TreeItemLayout/index'; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.test.tsx b/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.test.tsx new file mode 100644 index 0000000000000..c6d3a09452d4f --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.test.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { TreeItemLayout } from './TreeItemLayout'; +import { isConformant } from '../../testing/isConformant'; + +describe('TreeItemLayout', () => { + isConformant({ + Component: TreeItemLayout, + displayName: 'TreeItemLayout', + }); + + // TODO add more tests here, and create visual regression tests in /apps/vr-tests + + it('renders a default state', () => { + const result = render(Default TreeItemLayout); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.tsx b/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.tsx new file mode 100644 index 0000000000000..9eb0c32604cc5 --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { useTreeItemLayout_unstable } from './useTreeItemLayout'; +import { renderTreeItemLayout_unstable } from './renderTreeItemLayout'; +import { useTreeItemLayoutStyles_unstable } from './useTreeItemLayoutStyles'; +import type { TreeItemLayoutProps } from './TreeItemLayout.types'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +/** + * TreeItemLayout component - TODO: add more docs + */ +export const TreeItemLayout: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useTreeItemLayout_unstable(props, ref); + + useTreeItemLayoutStyles_unstable(state); + return renderTreeItemLayout_unstable(state); +}); + +TreeItemLayout.displayName = 'TreeItemLayout'; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.types.ts b/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.types.ts new file mode 100644 index 0000000000000..6e0e9c6ebe811 --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/TreeItemLayout.types.ts @@ -0,0 +1,15 @@ +import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; + +export type TreeItemLayoutSlots = { + root: Slot<'div'>; +}; + +/** + * TreeItemLayout Props + */ +export type TreeItemLayoutProps = ComponentProps; + +/** + * State used in rendering TreeItemLayout + */ +export type TreeItemLayoutState = ComponentState; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/__snapshots__/TreeItemLayout.test.tsx.snap b/packages/react-components/react-tree/src/components/TreeItemLayout/__snapshots__/TreeItemLayout.test.tsx.snap new file mode 100644 index 0000000000000..f07aa64b74c75 --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/__snapshots__/TreeItemLayout.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TreeItemLayout renders a default state 1`] = ` +
+
+ Default TreeItemLayout +
+
+`; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/index.ts b/packages/react-components/react-tree/src/components/TreeItemLayout/index.ts new file mode 100644 index 0000000000000..dde92733e51c3 --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/index.ts @@ -0,0 +1,5 @@ +export * from './TreeItemLayout'; +export * from './TreeItemLayout.types'; +export * from './renderTreeItemLayout'; +export * from './useTreeItemLayout'; +export * from './useTreeItemLayoutStyles'; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/renderTreeItemLayout.tsx b/packages/react-components/react-tree/src/components/TreeItemLayout/renderTreeItemLayout.tsx new file mode 100644 index 0000000000000..538ae7ba81d1b --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/renderTreeItemLayout.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import { getSlots } from '@fluentui/react-utilities'; +import type { TreeItemLayoutState, TreeItemLayoutSlots } from './TreeItemLayout.types'; + +/** + * Render the final JSX of TreeItemLayout + */ +export const renderTreeItemLayout_unstable = (state: TreeItemLayoutState) => { + const { slots, slotProps } = getSlots(state); + + // TODO Add additional slots in the appropriate place + return ; +}; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayout.ts b/packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayout.ts new file mode 100644 index 0000000000000..8f120a1f6196d --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayout.ts @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { getNativeElementProps } from '@fluentui/react-utilities'; +import type { TreeItemLayoutProps, TreeItemLayoutState } from './TreeItemLayout.types'; + +/** + * Create the state required to render TreeItemLayout. + * + * The returned state can be modified with hooks such as useTreeItemLayoutStyles_unstable, + * before being passed to renderTreeItemLayout_unstable. + * + * @param props - props from this instance of TreeItemLayout + * @param ref - reference to root HTMLElement of TreeItemLayout + */ +export const useTreeItemLayout_unstable = ( + props: TreeItemLayoutProps, + ref: React.Ref, +): TreeItemLayoutState => { + return { + // TODO add appropriate props/defaults + components: { + // TODO add each slot's element type or component + root: 'div', + }, + // TODO add appropriate slots, for example: + // mySlot: resolveShorthand(props.mySlot), + root: getNativeElementProps('div', { + ref, + ...props, + }), + }; +}; diff --git a/packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayoutStyles.ts b/packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayoutStyles.ts new file mode 100644 index 0000000000000..ca4280ec2eb9e --- /dev/null +++ b/packages/react-components/react-tree/src/components/TreeItemLayout/useTreeItemLayoutStyles.ts @@ -0,0 +1,33 @@ +import { makeStyles, mergeClasses } from '@griffel/react'; +import type { TreeItemLayoutSlots, TreeItemLayoutState } from './TreeItemLayout.types'; +import type { SlotClassNames } from '@fluentui/react-utilities'; + +export const treeItemLayoutClassNames: SlotClassNames = { + root: 'fui-TreeItemLayout', + // TODO: add class names for all slots on TreeItemLayoutSlots. + // Should be of the form `: 'fui-TreeItemLayout__` +}; + +/** + * Styles for the root slot + */ +const useStyles = makeStyles({ + root: { + // TODO Add default styles for the root element + }, + + // TODO add additional classes for different states and/or slots +}); + +/** + * Apply styling to the TreeItemLayout slots based on the state + */ +export const useTreeItemLayoutStyles_unstable = (state: TreeItemLayoutState): TreeItemLayoutState => { + const styles = useStyles(); + state.root.className = mergeClasses(treeItemLayoutClassNames.root, styles.root, state.root.className); + + // TODO Add class names to slots, for example: + // state.mySlot.className = mergeClasses(styles.mySlot, state.mySlot.className); + + return state; +}; diff --git a/packages/react-components/react-tree/src/index.ts b/packages/react-components/react-tree/src/index.ts index 50487eaadfc15..302a61e13b2d0 100644 --- a/packages/react-components/react-tree/src/index.ts +++ b/packages/react-components/react-tree/src/index.ts @@ -1,7 +1,22 @@ -export { Tree, treeClassNames } from './Tree'; +export { Tree, treeClassNames, renderTree_unstable, useTreeStyles_unstable, useTree_unstable } from './Tree'; export type { TreeProps, TreeState, TreeSlots } from './Tree'; -export { TreeItem, treeItemClassNames } from './TreeItem'; +export { + TreeItem, + treeItemClassNames, + renderTreeItem_unstable, + useTreeItemStyles_unstable, + useTreeItem_unstable, +} from './TreeItem'; export type { TreeItemProps, TreeItemState, TreeItemSlots } from './TreeItem'; export type { TreeContextValue, useTreeContext_unstable, TreeProvider } from './contexts'; + +export { + TreeItemLayout, + treeItemLayoutClassNames, + renderTreeItemLayout_unstable, + useTreeItemLayoutStyles_unstable, + useTreeItemLayout_unstable, +} from './TreeItemLayout'; +export type { TreeItemLayoutProps, TreeItemLayoutState, TreeItemLayoutSlots } from './TreeItemLayout';