@windstream/react-shared-components 0.2.62 → 0.2.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contentful/index.d.ts +1 -1
- package/dist/contentful/index.esm.js +1 -1
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +4 -4
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.esm.js +1 -1
- package/dist/utils/index.esm.js.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/video-link/vimeo-embed.tsx +19 -10
- package/src/contentful/blocks/image-promo-bar/index.tsx +2 -2
- package/src/hooks/contentful/use-contentful-rich-text.test.tsx +12 -0
- package/src/hooks/contentful/use-contentful-rich-text.tsx +17 -2
package/package.json
CHANGED
|
@@ -5,18 +5,27 @@ import Player from "@vimeo/player";
|
|
|
5
5
|
import { cx } from "@shared/utils/cx";
|
|
6
6
|
|
|
7
7
|
const extractVimeoIdandHash = (href: string) => {
|
|
8
|
-
// Strip query parameters and fragments
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
cleanHref.match(/vimeo\.com\/(?:.*\/)?(\d{6,})/) ||
|
|
12
|
-
cleanHref.match(/player\.vimeo\.com\/video\/(\d{6,})/);
|
|
8
|
+
// Strip query parameters and fragments without a backtracking-prone regex
|
|
9
|
+
let cleanHref = href.split(/[?#]/)[0];
|
|
10
|
+
while (cleanHref.endsWith("/")) cleanHref = cleanHref.slice(0, -1);
|
|
13
11
|
|
|
14
|
-
const parts = cleanHref.split("/");
|
|
15
|
-
|
|
12
|
+
const parts = cleanHref.split("/").filter(Boolean);
|
|
13
|
+
|
|
14
|
+
// Locate the vimeo domain segment (vimeo.com or player.vimeo.com) manually
|
|
15
|
+
// instead of a backtracking regex like `(?:.*\/)?(\d{6,})`
|
|
16
|
+
const domainIndex = parts.findIndex(
|
|
17
|
+
part => part === "vimeo.com" || part === "player.vimeo.com"
|
|
18
|
+
);
|
|
19
|
+
if (domainIndex === -1) return "";
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
const id = parts.find(
|
|
22
|
+
(part, i) => i > domainIndex && /^\d{6,}$/.test(part)
|
|
23
|
+
);
|
|
24
|
+
if (!id) return "";
|
|
25
|
+
|
|
26
|
+
const hash = parts[parts.length - 1];
|
|
27
|
+
if (id === hash) return id;
|
|
28
|
+
return `${id}/${hash}`;
|
|
20
29
|
};
|
|
21
30
|
|
|
22
31
|
export const getVimeoEmbedId = (link?: string): string => {
|
|
@@ -164,7 +164,7 @@ export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
|
164
164
|
</div>
|
|
165
165
|
)}
|
|
166
166
|
</div>
|
|
167
|
-
<
|
|
167
|
+
<div className="flex w-full flex-1 shrink-0 items-center justify-center lg:w-auto">
|
|
168
168
|
{/* Media Section: only when no Video Link is attached at all */}
|
|
169
169
|
{image && !hasVideoLink && (
|
|
170
170
|
<div
|
|
@@ -203,7 +203,7 @@ export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
|
203
203
|
isAboveTheFold={isAboveTheFold}
|
|
204
204
|
onVideoEvent={onVideoEvent}
|
|
205
205
|
/>
|
|
206
|
-
</
|
|
206
|
+
</div>
|
|
207
207
|
</div>
|
|
208
208
|
</div>
|
|
209
209
|
|
|
@@ -276,6 +276,18 @@ describe("renderContentfulRichText", () => {
|
|
|
276
276
|
const a = container.querySelector("a")!;
|
|
277
277
|
expect(a).toHaveClass("custom-link");
|
|
278
278
|
});
|
|
279
|
+
|
|
280
|
+
it("uses a separate class for links inside list items", () => {
|
|
281
|
+
const list = makeList(false, ["List link"]);
|
|
282
|
+
list.content[0].content = [makeHyperlink("/list-link", "List link")];
|
|
283
|
+
const doc = makeDoc(makeHyperlink("/paragraph-link", "Paragraph link"), list);
|
|
284
|
+
|
|
285
|
+
const { container } = render(<>{renderContentfulRichText(doc)}</>);
|
|
286
|
+
const links = container.querySelectorAll("a");
|
|
287
|
+
|
|
288
|
+
expect(links[0]).toHaveClass("body1", "font-bold");
|
|
289
|
+
expect(links[1]).toHaveClass("body2");
|
|
290
|
+
});
|
|
279
291
|
});
|
|
280
292
|
|
|
281
293
|
describe("Custom options merge", () => {
|
|
@@ -267,10 +267,23 @@ export function renderContentfulRichText(
|
|
|
267
267
|
className: string = "body1",
|
|
268
268
|
linkClassName: string = "body1 font-bold",
|
|
269
269
|
options?: Options,
|
|
270
|
-
links?: any
|
|
270
|
+
links?: any,
|
|
271
|
+
listLinkClassName: string = "body2"
|
|
271
272
|
): ReactNode | null {
|
|
272
273
|
if (!doc || !Array.isArray(doc.content)) return null;
|
|
273
274
|
|
|
275
|
+
const listItemHyperlinks = new WeakSet<object>();
|
|
276
|
+
const collectListItemHyperlinks = (node: any, isInListItem = false) => {
|
|
277
|
+
const isListItem = isInListItem || node?.nodeType === BLOCKS.LIST_ITEM;
|
|
278
|
+
if (isListItem && node?.nodeType === INLINES.HYPERLINK) {
|
|
279
|
+
listItemHyperlinks.add(node);
|
|
280
|
+
}
|
|
281
|
+
node?.content?.forEach((child: any) =>
|
|
282
|
+
collectListItemHyperlinks(child, isListItem)
|
|
283
|
+
);
|
|
284
|
+
};
|
|
285
|
+
collectListItemHyperlinks(doc);
|
|
286
|
+
|
|
274
287
|
const defaultOptions = getDefaultOptions(links);
|
|
275
288
|
const merged: Options = {
|
|
276
289
|
...defaultOptions,
|
|
@@ -301,7 +314,9 @@ export function renderContentfulRichText(
|
|
|
301
314
|
target={shouldOpenBlank ? "_blank" : undefined}
|
|
302
315
|
rel={shouldOpenBlank ? "noopener" : undefined}
|
|
303
316
|
variant="default"
|
|
304
|
-
className={
|
|
317
|
+
className={
|
|
318
|
+
listItemHyperlinks.has(node) ? listLinkClassName : linkClassName
|
|
319
|
+
}
|
|
305
320
|
>
|
|
306
321
|
{children}
|
|
307
322
|
</Link>
|