Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1b8191b
Regenerate package
Jun 15, 2021
ce22d98
Change files
Jun 15, 2021
617dc75
Migrate package to new converged DX
Jun 15, 2021
21b7d69
Make package private
Jun 16, 2021
2da22fc
Add Text component
Jun 16, 2021
9f91bd0
Merge branch 'master' into text-implementation
Jun 18, 2021
9f35426
Add as, wrap and truncate tests
Jun 18, 2021
d97b9e8
Added block styling prop
tringakrasniqi Jun 21, 2021
f415622
Added italic style prop
tringakrasniqi Jun 21, 2021
c0a327d
Added underline style prop
tringakrasniqi Jun 21, 2021
19fd891
Added strikethrough style prop
tringakrasniqi Jun 21, 2021
c4fe9d9
Added test for multiple style props
tringakrasniqi Jun 21, 2021
817d4ee
Add strikethrough + underline styling
Jun 22, 2021
01a372a
Add size prop
Jun 22, 2021
89d134a
Add font prop
Jun 22, 2021
ac4226a
Add font prop
Jun 22, 2021
d2d9d91
Add align prop
Jun 22, 2021
80e440b
Update types
Jun 22, 2021
d57740d
Fix base story
Jun 22, 2021
79c469d
Added storybook stories for Text props
tringakrasniqi Jun 26, 2021
1c85eba
Changed storybook story with arg controls
tringakrasniqi Jun 27, 2021
f73f6c0
Add documentation for props
Jun 29, 2021
31b5d3c
Limit as prop to specific semantic elements
Jun 29, 2021
27f7cb5
Update API doc
Jun 29, 2021
30b790e
Move default of as prop to the hook
Jul 1, 2021
549cd3a
Remove as prop test
Jul 1, 2021
0d871f0
Update packages/react-text/src/components/Text/useTextStyles.ts
Jul 1, 2021
d1db833
Merge branch 'master' into text-implementation
Jul 1, 2021
f059503
Update API docs
Jul 1, 2021
e6d24b0
Remove as prop test
Jul 1, 2021
94c2c1c
Remove useless comments
Jul 1, 2021
85dac23
Fix API docs (again)
Jul 2, 2021
2f5cd4e
Merge branch 'master' into text-implementation
Jul 2, 2021
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
2 changes: 2 additions & 0 deletions packages/react-text/config/tests.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/** Jest test setup file. */

require('@testing-library/jest-dom');

const { configure } = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');

Expand Down
11 changes: 11 additions & 0 deletions packages/react-text/etc/react-text.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ export type TextDefaultedProps = never;

// @public
export interface TextProps extends ComponentPropsCompat, React_2.HTMLAttributes<HTMLElement> {
align?: 'start' | 'center' | 'end' | 'justify';
as?: 'span' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'pre';
block?: boolean;
font?: 'base' | 'monospace' | 'numeric';
italic?: boolean;
size?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000;
strikethrough?: boolean;
truncate?: boolean;
underline?: boolean;
weight?: 'regular' | 'medium' | 'semibold';
wrap?: boolean;
}

// @public
Expand Down
83 changes: 83 additions & 0 deletions packages/react-text/src/components/Text/Text.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { makeStyles } from '@fluentui/react-make-styles';
import * as React from 'react';
import { Text } from './Text';
import { TextProps } from './Text.types';

const useStyles = makeStyles({
container: {
width: '100px',
},
});

export const TextStory = (props: TextProps) => {
const styles = useStyles();
return (
<div className={styles.container}>
<Text {...props}>This is an example of the Text component's usage.</Text>
</div>
);
};

TextStory.argTypes = {
wrap: {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the controls should be generated from types, or did I not understand smth @Hotell ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK this needs to be duplicated for compatibility reasons.

defaultValue: true,
control: 'boolean',
},
truncate: {
defaultValue: false,
control: 'boolean',
},
underline: {
defaultValue: false,
control: 'boolean',
},
block: {
defaultValue: false,
control: 'boolean',
},
italic: {
defaultValue: false,
control: 'boolean',
},
strikethrough: {
defaultValue: false,
control: 'boolean',
},
size: {
defaultValue: 300,
type: { name: 'number', required: false },
control: {
type: 'select',
options: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
},
},
font: {
defaultValue: 'base',
type: { name: 'string', required: false },
control: {
type: 'select',
options: ['base', 'monospace', 'numeric'],
},
},
weight: {
defaultValue: 'regular',
type: { name: 'string', required: false },
control: {
type: 'select',
options: ['regular', 'medium', 'semibold'],
},
},
align: {
defaultValue: 'start',
type: { name: 'string', required: false },
control: {
type: 'select',
options: ['start', 'center', 'end', 'justify'],
},
},
};

export default {
title: 'Components/Text',
component: Text,
};
153 changes: 153 additions & 0 deletions packages/react-text/src/components/Text/Text.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// For non-exported types
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as React from 'react';
import { render } from '@testing-library/react';
import { Text } from './Text';
import { isConformant } from '../../common/isConformant';

Expand All @@ -6,4 +10,153 @@ describe('Text', () => {
Component: Text,
displayName: 'Text',
});

it('renders a default state', () => {
Comment thread
theerebuss marked this conversation as resolved.
const { container, getByText } = render(<Text>Test</Text>);

expect(container).toMatchSnapshot();

const textElement = getByText('Test');
expect(textElement.nodeName).toBe('SPAN');
expect(textElement).toHaveStyle(`
font-family: var(--global-type-fontFamilies-base);
font-size: var(--global-type-fontSizes-base-300);
line-height: var(--global-type-lineHeights-base-300);
font-weight: var(--global-type-fontWeights-regular);
display: inline;
text-align: start;
white-space: normal;
overflow: visible;
text-overflow: clip;
`);
});

it('applies the no wrap styles', () => {
const { getByText } = render(<Text wrap={false}>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
white-space: nowrap;
overflow: hidden;
`);
});

it('applies the truncate style', () => {
const { getByText } = render(<Text truncate>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
text-overflow: ellipsis;
`);
});

it('applies the block style', () => {
const { getByText } = render(<Text block>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
display: block;
`);
});

it('applies the italic style', () => {
const { getByText } = render(<Text italic>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
font-style: italic;
`);
});

it('applies the underline style', () => {
const { getByText } = render(<Text underline>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
text-decoration: underline;
`);
});

it('applies the strikethrough style', () => {
const { getByText } = render(<Text strikethrough>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
text-decoration: line-through;
`);
});

it('applies both strikethrough and underline styles', () => {
const { getByText } = render(
<Text strikethrough underline>
Test
</Text>,
);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
text-decoration: line-through underline;
`);
});

it.each([
[100, 'base', '100'],
[200, 'base', '200'],
[300, 'base', '300'],
[400, 'base', '400'],
[500, 'base', '500'],
[600, 'base', '600'],
[700, 'hero', '700'],
[800, 'hero', '800'],
[900, 'hero', '900'],
[1000, 'hero', '1000'],
])('applies the %s token sizing styles', (sizeToken: any, expectedPrefix, expectedValue) => {
const { getByText } = render(<Text size={sizeToken}>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
font-size: var(--global-type-fontSizes-${expectedPrefix}-${expectedValue});
line-height: var(--global-type-lineHeights-${expectedPrefix}-${expectedValue});
`);
});

it.each([
['base', 'base'],
['monospace', 'monospace'],
['numeric', 'numeric'],
])('applies %s font', (input: any, expectedValue) => {
const { getByText } = render(<Text font={input}>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
font-family: var(--global-type-fontFamilies-${expectedValue});
`);
});

it.each([
['regular', 'regular'],
['medium', 'medium'],
['semibold', 'semibold'],
])('applies %s weight', (input: any, expectedValue) => {
const { getByText } = render(<Text weight={input}>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
font-weight: var(--global-type-fontWeights-${expectedValue});
`);
});

it.each([
['start', 'start'],
['center', 'center'],
['end', 'end'],
['justify', 'justify'],
])('applies a %s alignment', (input: any, expectedValue) => {
const { getByText } = render(<Text align={input}>Test</Text>);

const textElement = getByText('Test');
expect(textElement).toHaveStyle(`
text-align: ${expectedValue};
`);
});
});
81 changes: 76 additions & 5 deletions packages/react-text/src/components/Text/Text.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,88 @@ import { ComponentPropsCompat, ComponentStateCompat } from '@fluentui/react-util
* Text Props
*/
export interface TextProps extends ComponentPropsCompat, React.HTMLAttributes<HTMLElement> {
/*
* TODO Add props and slots here
* Any slot property should be listed in the textShorthandProps array below
* Any property that has a default value should be listed in TextDefaultedProps as e.g. 'size' | 'icon'
/**
* Wraps the text content on white spaces.
*
* @defaultValue true
*/
wrap?: boolean;

/**
* Truncate overflowing text for block displays.
*
* @defaultValue false
*/
truncate?: boolean;

/**
* Applies a block display for the content.
*
* @defaultValue false
*/
block?: boolean;

/**
* Applies the italic font style to the content.
*
* @defaultValue false
*/
italic?: boolean;

/**
* Applies the underline text decoration to the content.
*
* @defaultValue false
*/
underline?: boolean;

/**
* Applies the strikethrough text decoration to the content.
*
* @defaultValue false
*/
strikethrough?: boolean;

/**
* Applies font size and line height based on the theme tokens.
*
* @defaultValue 300
*/
size?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000;

/**
* Applies the font family to the content.
*
* @defaultValue base
*/
font?: 'base' | 'monospace' | 'numeric';

/**
* Applies font weight to the content.
*
* @defaultValue regular
*/
weight?: 'regular' | 'medium' | 'semibold';

/**
* Aligns text based on the parent container.
*
* @defaultValue start
*/
align?: 'start' | 'center' | 'end' | 'justify';

/**
* Component to be rendered as.
*
* @defaultValue span
*/
as?: 'span' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'pre';
}

/**
* Names of TextProps that have a default value in useText
*/
export type TextDefaultedProps = never; // TODO add names of properties with default values
export type TextDefaultedProps = never;

/**
* State used in rendering Text
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Text renders a default state 1`] = `
<div>
<span
class=""
>
Test
</span>
</div>
`;
7 changes: 1 addition & 6 deletions packages/react-text/src/components/Text/renderText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,5 @@ import { TextState } from './Text.types';
export const renderText = (state: TextState) => {
const { slots, slotProps } = getSlotsCompat(state);

return (
<slots.root {...slotProps.root}>
{/* TODO Add additional slots in the appropriate place */}
{state.children}
</slots.root>
);
return <slots.root {...slotProps.root}>{state.children}</slots.root>;
};
1 change: 1 addition & 0 deletions packages/react-text/src/components/Text/useText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const useText = (props: TextProps, ref: React.Ref<HTMLElement>, defaultPr
const state = mergeProps(
{
ref,
as: 'span',
},
defaultProps,
props,
Expand Down
Loading