Skip to content

Commit

Permalink
Add text decoration.
Browse files Browse the repository at this point in the history
  • Loading branch information
jameswilddev committed Aug 13, 2024
1 parent fb3ad45 commit 9dfe31a
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 14 deletions.
29 changes: 27 additions & 2 deletions react-native/components/createTextComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,36 @@ import type { TextProps } from '../../types/TextProps'
* @param multiLine When true, text will wrap across multiple lines when it does
* not fit within the available width. When false, text will
* be truncated with an ellipsis.
* @param decoration When null, the text is not decorated. Otherwise, a
* description of the decoration to apply.
* @returns A new React component which can be used to render text.
*/
export const createTextComponent = (
fontFamily: string,
fontSize: number,
color: ColorValue,
alignment: 'left' | 'center' | 'right',
multiLine: boolean
multiLine: boolean,
decoration: null | (({
readonly underline: true
readonly strikethrough: true
} | {
readonly underline: false
readonly strikethrough: true
} | {
readonly underline: true
readonly strikethrough: false
}) & {
/**
* The style of the text decoration to apply.
*/
readonly style: 'solid' | 'double' | 'dotted' | 'dashed'

/**
* The color of hte xt d
*/
readonly color: ColorValue
})
): React.FunctionComponent<TextProps> => {
const styles = StyleSheet.create({
text: {
Expand All @@ -28,7 +50,10 @@ export const createTextComponent = (
lineHeight: fontSize * 1.4,
color,
textAlign: alignment,
flexShrink: 1
flexShrink: 1,
textDecorationLine: decoration === null ? 'none' : (decoration.strikethrough ? (decoration.underline ? 'underline line-through' : 'line-through') : 'underline'),
textDecorationColor: decoration === null ? undefined : decoration.color,
textDecorationStyle: decoration === null ? undefined : decoration.style
}
})

Expand Down
21 changes: 19 additions & 2 deletions react-native/components/createTextComponent/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Creates a new React component which can be used to render text.
```tsx
import { createTextComponent } from "react-native-app-helpers";

const ExampleText = createTextComponent(`example`, `red`, 12, `left`, false);
const ExampleText = createTextComponent(`example`, `red`, 12, `left`, false, null);

const ExampleScreen = () => (
<ExampleText>
Expand All @@ -25,7 +25,7 @@ const ExampleScreen = () => (
```tsx
import { createTextComponent } from "react-native-app-helpers";

const ExampleText = createTextComponent(`example`, `red`, 12, `left`, true);
const ExampleText = createTextComponent(`example`, `red`, 12, `left`, true, null);

const ExampleScreen = () => (
<ExampleText>
Expand All @@ -39,3 +39,20 @@ const ExampleScreen = () => (
</ExampleText>
);
```

```tsx
import { createTextComponent } from "react-native-app-helpers";

const ExampleText = createTextComponent(`example`, `red`, 12, `left`, false, {
underline: true,
strikethrough: false,
style: `solid`, // Also: double, dotted, dashed.
color: `blue`,
});

const ExampleScreen = () => (
<ExampleText>
This has text decorations applied to it as described above.
</ExampleText>
);
```
230 changes: 220 additions & 10 deletions react-native/components/createTextComponent/unit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ test('renders single-line', () => {
37,
'#34AE17',
'left',
false
false,
null
)

const rendered = <Component>Test Content</Component>
Expand All @@ -22,7 +23,10 @@ test('renders single-line', () => {
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1
flexShrink: 1,
textDecorationLine: 'none',
textDecorationStyle: undefined,
textDecorationColor: undefined
}}
numberOfLines={1}
>
Expand All @@ -37,7 +41,8 @@ test('renders multi-line', () => {
37,
'#34AE17',
'left',
true
true,
null
)

const rendered = <Component>Test Content</Component>
Expand All @@ -50,7 +55,10 @@ test('renders multi-line', () => {
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1
flexShrink: 1,
textDecorationLine: 'none',
textDecorationStyle: undefined,
textDecorationColor: undefined
}}
numberOfLines={0}
>
Expand All @@ -59,13 +67,206 @@ test('renders multi-line', () => {
)
})

test('renders underlined', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false,
{ underline: true, strikethrough: false, style: 'solid', color: 'blue' }
)

const rendered = <Component>Test Content</Component>

expect(unwrapRenderedFunctionComponent(rendered)).toEqual(
<Text
style={{
fontFamily: 'Test Font Family',
fontSize: 37,
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1,
textDecorationLine: 'underline',
textDecorationStyle: 'solid',
textDecorationColor: 'blue'
}}
numberOfLines={1}
>
Test Content
</Text>
)
})

test('renders strikethrough', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false,
{ underline: false, strikethrough: true, style: 'solid', color: 'blue' }
)

const rendered = <Component>Test Content</Component>

expect(unwrapRenderedFunctionComponent(rendered)).toEqual(
<Text
style={{
fontFamily: 'Test Font Family',
fontSize: 37,
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1,
textDecorationLine: 'line-through',
textDecorationStyle: 'solid',
textDecorationColor: 'blue'
}}
numberOfLines={1}
>
Test Content
</Text>
)
})

test('renders underlined strikethrough', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false,
{ underline: true, strikethrough: true, style: 'solid', color: 'blue' }
)

const rendered = <Component>Test Content</Component>

expect(unwrapRenderedFunctionComponent(rendered)).toEqual(
<Text
style={{
fontFamily: 'Test Font Family',
fontSize: 37,
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1,
textDecorationLine: 'underline line-through',
textDecorationStyle: 'solid',
textDecorationColor: 'blue'
}}
numberOfLines={1}
>
Test Content
</Text>
)
})

test('renders double', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false,
{ underline: true, strikethrough: false, style: 'double', color: 'blue' }
)

const rendered = <Component>Test Content</Component>

expect(unwrapRenderedFunctionComponent(rendered)).toEqual(
<Text
style={{
fontFamily: 'Test Font Family',
fontSize: 37,
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1,
textDecorationLine: 'underline',
textDecorationStyle: 'double',
textDecorationColor: 'blue'
}}
numberOfLines={1}
>
Test Content
</Text>
)
})

test('renders dotted', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false,
{ underline: true, strikethrough: false, style: 'dotted', color: 'blue' }
)

const rendered = <Component>Test Content</Component>

expect(unwrapRenderedFunctionComponent(rendered)).toEqual(
<Text
style={{
fontFamily: 'Test Font Family',
fontSize: 37,
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1,
textDecorationLine: 'underline',
textDecorationStyle: 'dotted',
textDecorationColor: 'blue'
}}
numberOfLines={1}
>
Test Content
</Text>
)
})

test('renders dashed', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false,
{ underline: true, strikethrough: false, style: 'dashed', color: 'blue' }
)

const rendered = <Component>Test Content</Component>

expect(unwrapRenderedFunctionComponent(rendered)).toEqual(
<Text
style={{
fontFamily: 'Test Font Family',
fontSize: 37,
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1,
textDecorationLine: 'underline',
textDecorationStyle: 'dashed',
textDecorationColor: 'blue'
}}
numberOfLines={1}
>
Test Content
</Text>
)
})

test('renders with onPress undefined', () => {
const Component = createTextComponent(
'Test Font Family',
37,
'#34AE17',
'left',
false
false,
null
)

const rendered = <Component onPress={undefined}>Test Content</Component>
Expand All @@ -78,7 +279,10 @@ test('renders with onPress undefined', () => {
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1
flexShrink: 1,
textDecorationLine: 'none',
textDecorationStyle: undefined,
textDecorationColor: undefined
}}
numberOfLines={1}
>
Expand All @@ -93,7 +297,8 @@ test('renders with onPress set', () => {
37,
'#34AE17',
'left',
false
false,
null
)
const onPress = jest.fn()

Expand All @@ -107,7 +312,10 @@ test('renders with onPress set', () => {
lineHeight: 51.8,
color: '#34AE17',
textAlign: 'left',
flexShrink: 1
flexShrink: 1,
textDecorationLine: 'none',
textDecorationStyle: undefined,
textDecorationColor: undefined
}}
numberOfLines={1}
onPress={expect.any(Function)}
Expand All @@ -125,7 +333,8 @@ test('executes the press callback once when hitboxes are enabled', () => {
37,
'#34AE17',
'left',
false
false,
null
)
const onPress = jest.fn()

Expand All @@ -149,7 +358,8 @@ test('does not execute the press callback when hitboxes are disabled', () => {
37,
'#34AE17',
'left',
false
false,
null
)
const onPress = jest.fn()

Expand Down

0 comments on commit 9dfe31a

Please sign in to comment.