Skip to content

Commit b0d7d73

Browse files
authored
[DIT-4820] Rich Text for Text Items (#37)
* Add rich text to text items * Update rich text to use new variable format
1 parent 4122302 commit b0d7d73

File tree

8 files changed

+66
-22
lines changed

8 files changed

+66
-22
lines changed

README.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ output === "You are owner in this workspace."
194194

195195
`ditto-react` integrates with Ditto Plurals to support pluralized text. Learn how to create and configure Ditto Plurals here: https://www.dittowords.com/docs/pluralization.
196196

197-
*Note: Pluralization will only work if the source file is in the `structured` format.*
197+
_Note: Pluralization will only work if the source file is in the `structured` format._
198198

199199
When a text item has plural forms, the default plural form will be used when that text item is rendered normally:
200200

@@ -245,13 +245,22 @@ To see a working React app utilizing the [Ditto CLI](https://github.com/dittowor
245245

246246
## Rich Text
247247

248-
Ditto's [rich text](https://www.dittowords.com/docs/rich-text) functionality is currently available for Ditto Components in `ditto-react`. By using the `richText` property on `<Ditto />` or `<DittoComponent />`, `ditto-react` will automatically render the rich text versions of the components.
248+
Ditto's [rich text](https://www.dittowords.com/docs/rich-text) functionality can be enabled on `<Ditto />`, `<DittoText />` or `<DittoComponent />` via the `richText` property. Once enabled, `ditto-react` will automatically render the rich text versions of the text item/component.
249+
250+
### Examples
249251

250-
### Example
251252
```
252253
<Ditto componentId="shopping-cart" richText />
253254
```
254255

256+
```
257+
<DittoText textId="text_61e7238bbae5dc00fb66de15" variables={{ itemCount: 5 }} richText/>
258+
```
259+
260+
```
261+
<DittoComponent componentId="shopping-cart" count={5} variables={{ itemCount: 5 }} richText />
262+
```
263+
255264
---
256265

257266
## Reference
@@ -287,11 +296,12 @@ Which method you use depends on how you've configured your CLI options. Please r
287296

288297
#### Component Library (recommended)
289298

290-
| Prop | Type | Description |
291-
| ------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
292-
| `componentId` | string | The API ID of a component in your component library. If a `variant` prop is passed to an ancestor `DittoProvider`, will attempt to display the specified variant's value for the passed `componentId`; otherwise, will default to displaying base text. |
293-
| `variables` | object (optional) | A map of variable key-value pairs to interpolate in your text. |
294-
| `count` | number (optional) | This value is used to specify which plural case you wish to use |
299+
| Prop | Type | Description |
300+
| ------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
301+
| `componentId` | string | The API ID of a component in your component library. If a `variant` prop is passed to an ancestor `DittoProvider`, will attempt to display the specified variant's value for the passed `componentId`; otherwise, will default to displaying base text. |
302+
| `variables` | object (optional) | A map of variable key-value pairs to interpolate in your text. |
303+
| `count` | number (optional) | This value is used to specify which plural case you wish to use |
304+
| `richText` | boolean (optional) | This value is used to enable rich text rendering |
295305

296306
##### Example
297307

@@ -314,6 +324,7 @@ Which method you use depends on how you've configured your CLI options. Please r
314324
| `filters` | object (optional) | object of filters for text items returned. Currently supports a single parameter: tags, an array of tag strings | { tags: ["SELECTS"]} |
315325
| `variables` | object (optional) | A map of variable key-value pairs to interpolate in your text. | { email: "support@dittowords.com" } |
316326
| `count` | number (optional) | This value is used to specify which plural case you wish to use | 1 |
327+
| `richText` | boolean (optional) | This value is used to enable rich text rendering |
317328

318329
##### Examples
319330

example/src/App.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ const App = (props: AppProps) => {
155155
richText
156156
/>
157157
</div>
158+
<div className="dittoItem">
159+
<pre>{`<DittoComponent componentId="shopping-cart" count={5} variables={{ itemCount: 5 }} richText />`}</pre>
160+
<DittoComponent
161+
componentId="shopping-cart"
162+
count={5}
163+
variables={{ itemCount: 5 }}
164+
richText
165+
/>
166+
</div>
158167
</div>
159168
</div>
160169
<div>
@@ -215,10 +224,26 @@ const App = (props: AppProps) => {
215224
variables={{ itemCount: 5 }}
216225
/>
217226
</div>
227+
<div className="dittoItem">
228+
<pre>{`<DittoText textId="text_61e7238bbae5dc00fb66de15" variables={{ itemCount: 5 }} richText/>`}</pre>
229+
<DittoText
230+
textId="text_61e7238bbae5dc00fb66de15"
231+
variables={{ itemCount: 5 }}
232+
richText
233+
/>
234+
</div>
218235
<div className="dittoItem">
219236
<pre>{`<DittoText textId="text_61e7238bbae5dc00fb66ddff"/>`}</pre>
220237
<DittoText textId="text_61e7238bbae5dc00fb66ddff" />
221238
</div>
239+
<div className="dittoItem">
240+
<pre>{`<Ditto textId="text_61e7238bbae5dc00fb66de15" variables={{ itemCount: 5 }} richText/>`}</pre>
241+
<Ditto
242+
textId="text_61e7238bbae5dc00fb66de15"
243+
variables={{ itemCount: 5 }}
244+
richText
245+
/>
246+
</div>
222247
</div>
223248
</div>
224249
</div>

example/src/ditto/ditto-component-library__base.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"role": {
33
"name": "Role DO NOT MODIFY",
44
"text": "You are {{role}} in this workspace.",
5-
"rich_text": "<p>You are <span data-type=\"variable\" data-grammarly-skip class=\"\" data-variable-id=\"64e52580e5120107e7d21260\" data-name=\"role\" data-text=\"an administrator\" data-variable-type=\"map\">an administrator</span> in this workspace.</p>",
5+
"rich_text": "<p>You are {{role}} in this workspace.</p>",
66
"status": "NONE",
77
"folder": null,
88
"variables": {
@@ -17,7 +17,7 @@
1717
"shopping-cart-2": {
1818
"name": "Shopping Cart 2 DO NOT MODIFY",
1919
"text": "The cart is filled with {{item}}.",
20-
"rich_text": "<p>The <strong>cart is filled</strong> with <span data-type=\"variable\" data-grammarly-skip class=\"\" data-variable-id=\"64e5250c4f28ef74fe4fd2b4\" data-name=\"item\" data-text=\"oranges\" data-variable-type=\"list\">oranges</span>.</p>",
20+
"rich_text": "<p>The <strong>cart is filled</strong> with {{item}}.</p>",
2121
"status": "NONE",
2222
"folder": null,
2323
"variables": {
@@ -31,7 +31,7 @@
3131
"shopping-cart": {
3232
"name": "Shopping Cart DO NOT MODIFY",
3333
"text": "There are {{itemCount}} items in the cart",
34-
"rich_text": "<p>There are <span data-type=\"variable\" data-grammarly-skip class=\"\" data-variable-id=\"61e72483efde2400db6ac3cb\" data-name=\"itemCount\" data-text=\"10\" data-variable-type=\"number\">10</span> items <b>in the cart</b></p>",
34+
"rich_text": "<p>There are {{itemCount}} items <b>in the cart</b></p>",
3535
"status": "NONE",
3636
"folder": null,
3737
"variables": {
@@ -42,9 +42,9 @@
4242
},
4343
"plurals": {
4444
"other": "There are {{itemCount}} items in the cart",
45-
"other_rich_text": "<p>There are <span data-type=\"variable\" data-grammarly-skip class=\"\" data-variable-id=\"61e72483efde2400db6ac3cb\" data-name=\"itemCount\" data-text=\"10\" data-variable-type=\"number\">10</span> items <b>in the cart</b></p>",
45+
"other_rich_text": "<p>There are {{itemCount}} items <b>in the cart</b></p>",
4646
"one": "There is {{itemCount}} item in the cart",
47-
"one_rich_text": "<p>There is <span data-type=\"variable\" data-grammarly-skip class=\"\" data-variable-id=\"61e72483efde2400db6ac3cb\" data-name=\"itemCount\" data-text=\"10\" data-variable-type=\"number\">10</span> item in the cart</p>",
47+
"one_rich_text": "<p>There is {{itemCount}} item in the cart</p>",
4848
"zero": "The cart is empty",
4949
"zero_rich_text": "<p>The cart is empty</p>"
5050
},

example/src/ditto/onboarding-flow__base.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
},
6464
"text_61e7238bbae5dc00fb66de15": {
6565
"text": "There are {{itemCount}} puppies",
66+
"rich_text": "<p><strong><em>There are</em></strong> {{itemCount}} <u>puppies</u></p>",
6667
"variables": {
6768
"itemCount": {
6869
"example": 10,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ditto-react",
3-
"version": "1.5.0",
3+
"version": "1.6.0",
44
"description": "React SDK for using product copy from Ditto in development.",
55
"author": "Ditto Tech Inc.",
66
"license": "MIT",

src/components/Ditto.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export interface DittoTextProps {
5050
textId: string;
5151
variables?: VariablesInput;
5252
count?: number;
53+
richText?: boolean;
5354
children?: (text: string) => React.ReactNode;
5455
}
5556

@@ -86,7 +87,7 @@ export function Ditto(props: DittoProps) {
8687
const projectId = props.projectId || dittoContext.projectId;
8788
if (!projectId) {
8889
return fragmentError(
89-
"No Project ID was provided to the <DittoProvider /> or <Ditto /> components.",
90+
"No Project ID was provided to the <DittoProvider /> or <Ditto /> components."
9091
);
9192
}
9293

@@ -102,6 +103,6 @@ export function Ditto(props: DittoProps) {
102103
}
103104

104105
return fragmentError(
105-
'Invalid props provided to Ditto component; please provide "componentId", "textId" or "frameId"',
106+
'Invalid props provided to Ditto component; please provide "componentId", "textId" or "frameId"'
106107
);
107108
}

src/components/DittoText.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ export const DittoText = (props: DittoTextProps) => {
1111
textId,
1212
variables: variables || {},
1313
count,
14+
richText: props.richText === true,
1415
});
1516

1617
if (typeof text === "string" && typeof children === "function") {
1718
return <>{children(text)}</>;
1819
}
1920

21+
if (props.richText) {
22+
return <span dangerouslySetInnerHTML={{ __html: text || "" }}></span>;
23+
}
24+
2025
return <>{text}</>;
2126
};

src/hooks/useDittoSingleText.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ interface useDittoSingleTextProps {
1212
textId: string;
1313
variables?: VariablesInput;
1414
count?: Count;
15+
richText?: boolean;
1516
}
1617

1718
export const useDittoSingleText = (
18-
props: useDittoSingleTextProps,
19+
props: useDittoSingleTextProps
1920
): string | null => {
2021
const { textId, variables, count } = props;
2122
const { source, variant } = useContext(DittoContext);
@@ -31,7 +32,7 @@ export const useDittoSingleText = (
3132
data[textId],
3233
variables || {},
3334
count,
34-
false,
35+
Boolean(props.richText)
3536
).text;
3637
}
3738

@@ -47,7 +48,7 @@ export const useDittoSingleText = (
4748
block[textId],
4849
variables || {},
4950
count,
50-
false,
51+
Boolean(props.richText)
5152
).text;
5253
}
5354

@@ -56,7 +57,7 @@ export const useDittoSingleText = (
5657
frame.otherText[textId],
5758
variables || {},
5859
count,
59-
false,
60+
Boolean(props.richText)
6061
).text;
6162
}
6263
}
@@ -85,7 +86,7 @@ export const useDittoSingleText = (
8586
block[textId],
8687
variables || {},
8788
count,
88-
false,
89+
Boolean(props.richText)
8990
).text;
9091
}
9192

@@ -94,7 +95,7 @@ export const useDittoSingleText = (
9495
frame.otherText[textId],
9596
variables || {},
9697
count,
97-
false,
98+
Boolean(props.richText)
9899
).text;
99100
}
100101
}

0 commit comments

Comments
 (0)