master
1---
2type ReplaceOption =
3 | {
4 /**
5 * The pattern to match in the HTML content.
6 * It can be a string, a regular expression, or null.
7 * - If null, the replacer function will be called with the entire HTML content,
8 * and the replaceValue will be used as the result.
9 * - If a string or RegExp, it will be used to find matches in the HTML content.
10 */
11 pattern: string | RegExp | null;
12 replaceValue: string;
13 }
14 | {
15 pattern: string | RegExp;
16 // eslint-disable-next-line @typescript-eslint/no-explicit-any
17 replacer: (match: string, ...args: any[]) => string;
18 }
19 | {
20 pattern: null;
21 replacer: (match: string) => string | Promise<string>;
22 };
23
24export type Props = { option: ReplaceOption } | { options: ReplaceOption[] };
25
26const raw = await Astro.slots.render('default');
27
28const replace = async function (html: string, option: ReplaceOption): Promise<string> {
29 if (option.pattern === null) {
30 return 'replacer' in option ? await option.replacer(html) : option.replaceValue;
31 }
32 return 'replacer' in option
33 ? html.replaceAll(option.pattern, option.replacer)
34 : html.replaceAll(option.pattern, option.replaceValue);
35};
36
37let html: string | undefined = undefined;
38if ('options' in Astro.props) {
39 for (const option of Astro.props.options) {
40 html = await replace(html || raw, option);
41 }
42} else if ('option' in Astro.props) html = await replace(raw, Astro.props.option);
43else html = raw;
44---
45
46<Fragment set:html={html} />