Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Divider to accept View Props #3520

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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": "minor",
"comment": "Enable passing view props into the Divider",
"packageName": "@fluentui-react-native/divider",
"email": "[email protected]",
"dependentChangeType": "patch"
}
23 changes: 13 additions & 10 deletions packages/components/Divider/src/Divider.styling.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useMemo } from 'react';
import type { ViewProps, ColorValue, StyleProp, ViewStyle } from 'react-native';
import type { ViewProps, ColorValue } from 'react-native';
import { Platform } from 'react-native';

import { memoize, mergeStyles } from '@fluentui-react-native/framework';
import { memoize, mergeProps, mergeStyles } from '@fluentui-react-native/framework';
import type { Theme } from '@fluentui-react-native/framework';
import type { IconPropsV1 as IconProps } from '@fluentui-react-native/icon';
import type { TextProps } from '@fluentui-react-native/text';
Expand Down Expand Up @@ -174,23 +174,26 @@ export const colorsFromAppearance = (
* At the second render stage, if the minHeight token isn't set, we calculate and memoize a default value based on whether the
* Divider is vertical and has content.
*/
export const getRootStyle = memoize(getRootStyleWorker);
function getRootStyleWorker(rootStyle: StyleProp<ViewStyle>, isVertical: boolean, hasContent: boolean): StyleProp<ViewStyle> {
export const getRootSlotProps = memoize(rootSlotPropsWorker);
function rootSlotPropsWorker(dividerProps: DividerProps, rootProps: ViewProps, hasContent: boolean): ViewProps {
const { vertical, ...props } = dividerProps;
let minHeight = 0;
if (isVertical) {
if (vertical) {
minHeight = hasContent ? 84 : globalTokens.size200;
}
return mergeStyles(rootStyle, { minHeight });
return mergeProps(props, rootProps, {
style: mergeStyles(rootProps.style, props.style, { minHeight }),
});
}

/**
* At the second render stage, if there is not content passed, we override the existing beforeLine style to make the line take up
* the entirity of root.
*/
export const getBeforeLineStyle = memoize(getBeforeLineStyleWorker);
function getBeforeLineStyleWorker(beforeLineStyle: StyleProp<ViewStyle>, hasContent: boolean): StyleProp<ViewStyle> {
export const getBeforeLineSlotProps = memoize(beforeLineSlotPropsWorker);
function beforeLineSlotPropsWorker(beforeLineProps: ViewProps, hasContent: boolean) {
if (!hasContent) {
return mergeStyles(beforeLineStyle, { flex: 1 });
return mergeProps(beforeLineProps, { style: mergeStyles(beforeLineProps.style, { flex: 1 }) });
}
return beforeLineStyle;
return beforeLineProps;
}
17 changes: 6 additions & 11 deletions packages/components/Divider/src/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import React from 'react';
import { View } from 'react-native';
import type { ViewProps } from 'react-native';

import { withSlots, compressible, useSlot, useFluentTheme, patchTokens } from '@fluentui-react-native/framework';
import { withSlots, compressible, useSlot, useFluentTheme, patchTokens, mergeProps } from '@fluentui-react-native/framework';
import type { UseTokens } from '@fluentui-react-native/framework';
import { IconV1 as Icon } from '@fluentui-react-native/icon';
import type { IconPropsV1 as IconProps } from '@fluentui-react-native/icon';
import { TextV1 as Text } from '@fluentui-react-native/text';
import type { TextProps } from '@fluentui-react-native/text';

import { colorsFromAppearance, getBeforeLineStyle, getRootStyle, useDividerSlotProps } from './Divider.styling';
import { colorsFromAppearance, getBeforeLineSlotProps, getRootSlotProps, useDividerSlotProps } from './Divider.styling';
import { dividerName } from './Divider.types';
import type { DividerProps, DividerTokens } from './Divider.types';
import { useDividerTokens } from './DividerTokens';
Expand Down Expand Up @@ -50,7 +50,7 @@ export const Divider = compressible<DividerProps, DividerTokens>((props: Divider
const IconSlot = useSlot<IconProps>(Icon, iconProps);

return (final: DividerProps, ...children: React.ReactNode[]) => {
final = { ...props, ...final };
final = mergeProps(props, final);
// change root style if there is a text child
let textContent: string;
React.Children.forEach(children, (child) => {
Expand All @@ -61,14 +61,9 @@ export const Divider = compressible<DividerProps, DividerTokens>((props: Divider

const hasContent = textContent !== undefined || props.icon !== undefined;

// This style must be set here because we need to know if text content is passed in the final render to set the height correctly
let finalRootProps = rootProps;
if (!tokens.minHeight) {
finalRootProps = { ...rootProps, style: getRootStyle(rootProps.style, final.vertical, hasContent) };
}

// We patch the beforeLine styling if no content is passed because it should always take up the full width / height of the root container (afterLine is not rendered).
const finalBeforeLineProps = { ...beforeLineProps, style: getBeforeLineStyle(beforeLineProps.style, hasContent) };
// Patch styling / props of root and beforeLine slots if there's content
const finalRootProps = getRootSlotProps(final, rootProps, hasContent);
const finalBeforeLineProps = getBeforeLineSlotProps(beforeLineProps, hasContent);

return (
<RootSlot {...finalRootProps}>
Expand Down
4 changes: 2 additions & 2 deletions packages/components/Divider/src/Divider.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type DividerInsetSize = (typeof DividerInsetSizes)[number];
export type DividerAlignment = 'start' | 'center' | 'end';
export type DividerAppearance = 'default' | 'subtle' | 'brand' | 'strong';

export type DividerProps = React.PropsWithChildren<{
export interface DividerProps extends ViewProps {
/**
* If a text or icon is passed, this dictates where content appears in the divider: at the start, centered, or towards the end.
* @default 'center'
Expand Down Expand Up @@ -41,7 +41,7 @@ export type DividerProps = React.PropsWithChildren<{
* Note: This prop is not supported on mobile platforms(Android & iOS).
*/
vertical?: boolean;
}>;
}

export interface DividerTokens extends LayoutTokens, Omit<FontTokens, 'fontDynamicTypeRamp' | 'fontMaximumSize'> {
/**
Expand Down
5 changes: 0 additions & 5 deletions packages/components/Divider/src/__tests__/Divider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';

import { checkReRender } from '@fluentui-react-native/test-tools';
import * as renderer from 'react-test-renderer';

import { Divider } from '../Divider';
Expand Down Expand Up @@ -95,8 +94,4 @@ describe('Divider component tests', () => {
const tree = renderer.create(<CustomDivider {...props}>Hello</CustomDivider>).toJSON();
expect(tree).toMatchSnapshot();
});

it('Divider re-renders correctly', () => {
checkReRender(() => <Divider />, 2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

exports[`Divider component tests Branded Divider 1`] = `
<View
alignContent="center"
appearance="brand"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -31,6 +34,9 @@ exports[`Divider component tests Branded Divider 1`] = `

exports[`Divider component tests Custom Divider 1`] = `
<View
alignContent="center"
appearance="default"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -60,6 +66,9 @@ exports[`Divider component tests Custom Divider 1`] = `

exports[`Divider component tests Divider default 1`] = `
<View
alignContent="center"
appearance="default"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -89,6 +98,18 @@ exports[`Divider component tests Divider default 1`] = `

exports[`Divider component tests Divider with all props + tokens set 1`] = `
<View
alignContent="start"
appearance="strong"
icon={
{
"fontSource": {
"codepoint": 9827,
"fontFamily": "Arial",
"fontSize": 32,
},
}
}
insetSize={16}
style={
{
"alignItems": "center",
Expand All @@ -98,7 +119,7 @@ exports[`Divider component tests Divider with all props + tokens set 1`] = `
"justifyContent": "center",
"maxHeight": 200,
"maxWidth": 200,
"minHeight": 40,
"minHeight": 84,
"minWidth": 10,
"padding": 10,
"paddingEnd": 10,
Expand Down Expand Up @@ -167,6 +188,18 @@ exports[`Divider component tests Divider with all props + tokens set 1`] = `

exports[`Divider component tests Divider with icon 1`] = `
<View
alignContent="center"
appearance="default"
icon={
{
"fontSource": {
"codepoint": 9827,
"fontFamily": "Arial",
"fontSize": 32,
},
}
}
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -229,6 +262,9 @@ exports[`Divider component tests Divider with icon 1`] = `

exports[`Divider component tests Divider with text 1`] = `
<View
alignContent="center"
appearance="default"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -296,6 +332,9 @@ exports[`Divider component tests Divider with text 1`] = `

exports[`Divider component tests Horizontal Divider with Inset 1`] = `
<View
alignContent="center"
appearance="default"
insetSize={16}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -325,6 +364,9 @@ exports[`Divider component tests Horizontal Divider with Inset 1`] = `

exports[`Divider component tests Strong Divider 1`] = `
<View
alignContent="center"
appearance="strong"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -354,6 +396,9 @@ exports[`Divider component tests Strong Divider 1`] = `

exports[`Divider component tests Subtle Divider 1`] = `
<View
alignContent="center"
appearance="subtle"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -383,6 +428,9 @@ exports[`Divider component tests Subtle Divider 1`] = `

exports[`Divider component tests Vertical Divider 1`] = `
<View
alignContent="center"
appearance="default"
insetSize={0}
style={
{
"alignItems": "center",
Expand Down Expand Up @@ -413,6 +461,9 @@ exports[`Divider component tests Vertical Divider 1`] = `

exports[`Divider component tests Vertical Divider with Inset 1`] = `
<View
alignContent="center"
appearance="default"
insetSize={16}
style={
{
"alignItems": "center",
Expand Down
Loading