Skip to content

Commit 2fc48c5

Browse files
authored
Merge pull request #4626 from Ivy-Interactive/tendril/00549-TextWidgetThreadIdPropThroughAllNonheadingVariants
[00549] Text widget: thread id prop through all non-heading variants
2 parents 7f667f8 + b41006c commit 2fc48c5

2 files changed

Lines changed: 95 additions & 28 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React from "react";
2+
import { describe, it, expect } from "vitest";
3+
import { renderToString } from "react-dom/server";
4+
import { TextBlockWidget } from "./TextBlockWidget";
5+
6+
describe("TextBlockWidget id attribute", () => {
7+
const variants = [
8+
"Literal",
9+
"Block",
10+
"P",
11+
"Inline",
12+
"Blockquote",
13+
"Monospaced",
14+
"Lead",
15+
"Muted",
16+
"Danger",
17+
"Warning",
18+
"Success",
19+
"Label",
20+
"Strong",
21+
"Display",
22+
] as const;
23+
24+
variants.forEach((variant) => {
25+
it(`${variant} variant renders id attribute`, () => {
26+
const testId = `test-anchor-${variant.toLowerCase()}`;
27+
const html = renderToString(
28+
<TextBlockWidget
29+
id="test-widget"
30+
content="Test content"
31+
variant={variant}
32+
anchor={testId}
33+
/>,
34+
);
35+
36+
expect(html).toContain(`id="${testId}"`);
37+
});
38+
});
39+
40+
it("heading variants render id attribute", () => {
41+
const headingVariants = ["H1", "H2", "H3", "H4", "H5", "H6"] as const;
42+
43+
headingVariants.forEach((variant) => {
44+
const testId = `test-anchor-${variant.toLowerCase()}`;
45+
const html = renderToString(
46+
<TextBlockWidget
47+
id="test-widget"
48+
content="Test heading"
49+
variant={variant}
50+
anchor={testId}
51+
/>,
52+
);
53+
54+
expect(html).toContain(`id="${testId}"`);
55+
});
56+
});
57+
58+
it("no id attribute when anchor is not provided", () => {
59+
const html = renderToString(
60+
<TextBlockWidget id="test-widget" content="Test content" variant="P" />,
61+
);
62+
63+
const paragraph = html.match(/<p[^>]*>/)?.[0];
64+
expect(paragraph).toBeDefined();
65+
expect(paragraph).not.toContain('id="');
66+
});
67+
});

src/frontend/src/widgets/primitives/TextBlockWidget.tsx

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ interface VariantMap {
5656
}>;
5757
}
5858
const variantMap: VariantMap = {
59-
Literal: ({ children, className, style }) => (
60-
<span className={className} style={style}>
59+
Literal: ({ children, className, style, id }) => (
60+
<span id={id} className={className} style={style}>
6161
{children}
6262
</span>
6363
),
@@ -91,7 +91,7 @@ const variantMap: VariantMap = {
9191
{children}
9292
</h6>
9393
),
94-
Block: ({ children, className, style }) => {
94+
Block: ({ children, className, style, id }) => {
9595
const spanRef = React.useRef<HTMLSpanElement>(null);
9696
const [isTruncated, setIsTruncated] = React.useState(false);
9797
const [showTooltip, setShowTooltip] = React.useState(false);
@@ -105,7 +105,7 @@ const variantMap: VariantMap = {
105105
};
106106

107107
return (
108-
<div className={cn(typography.block, className)} style={style}>
108+
<div id={id} className={cn(typography.block, className)} style={style}>
109109
<TooltipProvider>
110110
<Tooltip>
111111
<TooltipTrigger asChild>
@@ -128,63 +128,63 @@ const variantMap: VariantMap = {
128128
</div>
129129
);
130130
},
131-
P: ({ children, className, style }) => (
132-
<p className={cn(typography.p, className)} style={style}>
131+
P: ({ children, className, style, id }) => (
132+
<p id={id} className={cn(typography.p, className)} style={style}>
133133
{children}
134134
</p>
135135
),
136-
Inline: ({ children, className, style }) => (
137-
<span className={cn(className)} style={style}>
136+
Inline: ({ children, className, style, id }) => (
137+
<span id={id} className={cn(className)} style={style}>
138138
{children}
139139
</span>
140140
),
141-
Blockquote: ({ children, className, style }) => (
142-
<blockquote className={cn(typography.blockquote, className)} style={style}>
141+
Blockquote: ({ children, className, style, id }) => (
142+
<blockquote id={id} className={cn(typography.blockquote, className)} style={style}>
143143
{children}
144144
</blockquote>
145145
),
146-
Monospaced: ({ children, className, style }) => (
147-
<code className={cn(typography.code, className)} style={style}>
146+
Monospaced: ({ children, className, style, id }) => (
147+
<code id={id} className={cn(typography.code, className)} style={style}>
148148
{children}
149149
</code>
150150
),
151-
Lead: ({ children, className, style }) => (
152-
<div className={cn(typography.lead, className)} style={style}>
151+
Lead: ({ children, className, style, id }) => (
152+
<div id={id} className={cn(typography.lead, className)} style={style}>
153153
<MarkdownRenderer content={children} />
154154
</div>
155155
),
156-
Muted: ({ children, className, style }) => (
157-
<div className={cn(typography.muted, className)} style={style}>
156+
Muted: ({ children, className, style, id }) => (
157+
<div id={id} className={cn(typography.muted, className)} style={style}>
158158
{children}
159159
</div>
160160
),
161-
Danger: ({ children, className, style }) => (
162-
<div className={cn(typography.danger, className)} style={style}>
161+
Danger: ({ children, className, style, id }) => (
162+
<div id={id} className={cn(typography.danger, className)} style={style}>
163163
{children}
164164
</div>
165165
),
166-
Warning: ({ children, className, style }) => (
167-
<div className={cn(typography.warning, className)} style={style}>
166+
Warning: ({ children, className, style, id }) => (
167+
<div id={id} className={cn(typography.warning, className)} style={style}>
168168
{children}
169169
</div>
170170
),
171-
Success: ({ children, className, style }) => (
172-
<div className={cn(typography.success, className)} style={style}>
171+
Success: ({ children, className, style, id }) => (
172+
<div id={id} className={cn(typography.success, className)} style={style}>
173173
{children}
174174
</div>
175175
),
176-
Label: ({ children, className, style }) => (
177-
<div className={cn(typography.label, className)} style={style}>
176+
Label: ({ children, className, style, id }) => (
177+
<div id={id} className={cn(typography.label, className)} style={style}>
178178
{children}
179179
</div>
180180
),
181-
Strong: ({ children, className, style }) => (
182-
<strong className={cn(typography.strong, className)} style={style}>
181+
Strong: ({ children, className, style, id }) => (
182+
<strong id={id} className={cn(typography.strong, className)} style={style}>
183183
{children}
184184
</strong>
185185
),
186-
Display: ({ children, className, style }) => (
187-
<div className={cn(typography.display, className)} style={style}>
186+
Display: ({ children, className, style, id }) => (
187+
<div id={id} className={cn(typography.display, className)} style={style}>
188188
{children}
189189
</div>
190190
),

0 commit comments

Comments
 (0)