sanity-plugin-seofields 1.6.0 → 1.6.1
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/SeoHealthDashboard-FZTP4GS7.cjs +10 -0
- package/dist/{SeoHealthDashboard-7XMPVJRX.cjs.map → SeoHealthDashboard-FZTP4GS7.cjs.map} +1 -1
- package/dist/SeoHealthDashboard-PY5MKJCZ.js +4 -0
- package/dist/{SeoHealthDashboard-UWPLB5DM.js.map → SeoHealthDashboard-PY5MKJCZ.js.map} +1 -1
- package/dist/{SeoHealthTool-XCXINAQI.js → SeoHealthTool-SKY7FAKK.js} +3 -3
- package/dist/{SeoHealthTool-XCXINAQI.js.map → SeoHealthTool-SKY7FAKK.js.map} +1 -1
- package/dist/{SeoHealthTool-2H4XZR4I.cjs → SeoHealthTool-Z3O6NEKF.cjs} +4 -4
- package/dist/{SeoHealthTool-2H4XZR4I.cjs.map → SeoHealthTool-Z3O6NEKF.cjs.map} +1 -1
- package/dist/{SeoPreview-F6GGPZWI.js → SeoPreview-BQBKMYSG.js} +43 -8
- package/dist/SeoPreview-BQBKMYSG.js.map +1 -0
- package/dist/{SeoPreview-JDROKZLP.cjs → SeoPreview-LWSWTIF5.cjs} +41 -6
- package/dist/SeoPreview-LWSWTIF5.cjs.map +1 -0
- package/dist/{chunk-Z74QPO75.cjs → chunk-77U7CMJP.cjs} +12 -4
- package/dist/chunk-77U7CMJP.cjs.map +1 -0
- package/dist/{chunk-6NIHHOVS.js → chunk-IQG5JWVT.js} +2 -2
- package/dist/{chunk-6NIHHOVS.js.map → chunk-IQG5JWVT.js.map} +1 -1
- package/dist/{chunk-NHJBEV3A.js → chunk-KFFDQX22.js} +12 -4
- package/dist/chunk-KFFDQX22.js.map +1 -0
- package/dist/{chunk-KWUITSHS.js → chunk-ULFY5STC.js} +14 -14
- package/dist/chunk-ULFY5STC.js.map +1 -0
- package/dist/{chunk-WCLEWFAJ.cjs → chunk-XXQURVNE.cjs} +120 -120
- package/dist/chunk-XXQURVNE.cjs.map +1 -0
- package/dist/{chunk-7HCP5O62.cjs → chunk-YM3ZZ2HU.cjs} +2 -2
- package/dist/{chunk-7HCP5O62.cjs.map → chunk-YM3ZZ2HU.cjs.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/{component-7rqDvuy2.d.ts → component-CWZ0tlsq.d.ts} +7 -7
- package/dist/{component-J2nEQkOw.d.cts → component-DS-Ve_nw.d.cts} +7 -7
- package/dist/index.cjs +48 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -8
- package/dist/index.d.ts +55 -8
- package/dist/index.js +31 -20
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +87 -88
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +4 -4
- package/dist/next.d.ts +4 -4
- package/dist/next.js +12 -9
- package/dist/next.js.map +1 -1
- package/dist/schema/next.cjs +80 -80
- package/dist/schema/next.d.cts +3 -3
- package/dist/schema/next.d.ts +3 -3
- package/dist/schema/next.js +3 -3
- package/dist/schema.cjs +153 -153
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +6 -6
- package/dist/schema.d.ts +6 -6
- package/dist/schema.js +2 -2
- package/dist/schema.js.map +1 -1
- package/dist/{types-BSgolLj3.d.cts → types-BjVpmBAX.d.cts} +1 -1
- package/dist/{types-BRn3hfQb.d.ts → types-Dy7r5det.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/SeoHealthDashboard-7XMPVJRX.cjs +0 -10
- package/dist/SeoHealthDashboard-UWPLB5DM.js +0 -4
- package/dist/SeoPreview-F6GGPZWI.js.map +0 -1
- package/dist/SeoPreview-JDROKZLP.cjs.map +0 -1
- package/dist/chunk-KWUITSHS.js.map +0 -1
- package/dist/chunk-NHJBEV3A.js.map +0 -1
- package/dist/chunk-WCLEWFAJ.cjs.map +0 -1
- package/dist/chunk-Z74QPO75.cjs.map +0 -1
- package/dist/{types-DoUYMRVf.d.cts → types-BdaGoGQE.d.cts} +30 -30
- package/dist/{types-DnVvOp3o.d.ts → types-BwmZmt9I.d.ts} +30 -30
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk77U7CMJP_cjs = require('./chunk-77U7CMJP.cjs');
|
|
4
|
+
require('./chunk-S367Y35J.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
module.exports = chunk77U7CMJP_cjs.SeoHealthDashboard_default;
|
|
9
|
+
//# sourceMappingURL=SeoHealthDashboard-FZTP4GS7.cjs.map
|
|
10
|
+
//# sourceMappingURL=SeoHealthDashboard-FZTP4GS7.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-FZTP4GS7.cjs"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-PY5MKJCZ.js"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SeoHealthDashboard_default } from './chunk-
|
|
1
|
+
import { SeoHealthDashboard_default } from './chunk-KFFDQX22.js';
|
|
2
2
|
import { __spreadValues } from './chunk-2NMEKWO5.js';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -8,5 +8,5 @@ var SeoHealthTool = (props) => {
|
|
|
8
8
|
var SeoHealthTool_default = SeoHealthTool;
|
|
9
9
|
|
|
10
10
|
export { SeoHealthTool_default as default };
|
|
11
|
-
//# sourceMappingURL=SeoHealthTool-
|
|
12
|
-
//# sourceMappingURL=SeoHealthTool-
|
|
11
|
+
//# sourceMappingURL=SeoHealthTool-SKY7FAKK.js.map
|
|
12
|
+
//# sourceMappingURL=SeoHealthTool-SKY7FAKK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":[],"mappings":";;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAO,GAAA,CAAC,+CAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-
|
|
1
|
+
{"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":[],"mappings":";;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAO,GAAA,CAAC,+CAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-SKY7FAKK.js","sourcesContent":["import SeoHealthDashboard, {SeoHealthDashboardProps} from './SeoHealthDashboard'\n\n/**\n * Sanity Tool component for the SEO Health Dashboard\n * This component wraps the SeoHealthDashboard for use as a custom tool in Sanity Studio\n */\nconst SeoHealthTool = (props: SeoHealthDashboardProps) => {\n return <SeoHealthDashboard {...props} />\n}\n\nexport default SeoHealthTool\n"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk77U7CMJP_cjs = require('./chunk-77U7CMJP.cjs');
|
|
4
4
|
var chunkS367Y35J_cjs = require('./chunk-S367Y35J.cjs');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
7
7
|
var SeoHealthTool = (props) => {
|
|
8
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunk77U7CMJP_cjs.SeoHealthDashboard_default, chunkS367Y35J_cjs.__spreadValues({}, props));
|
|
9
9
|
};
|
|
10
10
|
var SeoHealthTool_default = SeoHealthTool;
|
|
11
11
|
|
|
12
12
|
module.exports = SeoHealthTool_default;
|
|
13
|
-
//# sourceMappingURL=SeoHealthTool-
|
|
14
|
-
//# sourceMappingURL=SeoHealthTool-
|
|
13
|
+
//# sourceMappingURL=SeoHealthTool-Z3O6NEKF.cjs.map
|
|
14
|
+
//# sourceMappingURL=SeoHealthTool-Z3O6NEKF.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":["jsx","SeoHealthDashboard_default"],"mappings":";;;;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAOA,cAAA,CAACC,mFAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-
|
|
1
|
+
{"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":["jsx","SeoHealthDashboard_default"],"mappings":";;;;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAOA,cAAA,CAACC,mFAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-Z3O6NEKF.cjs","sourcesContent":["import SeoHealthDashboard, {SeoHealthDashboardProps} from './SeoHealthDashboard'\n\n/**\n * Sanity Tool component for the SEO Health Dashboard\n * This component wraps the SeoHealthDashboard for use as a custom tool in Sanity Studio\n */\nconst SeoHealthTool = (props: SeoHealthDashboardProps) => {\n return <SeoHealthDashboard {...props} />\n}\n\nexport default SeoHealthTool\n"]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { truncate } from './chunk-25JLWVEU.js';
|
|
2
2
|
import './chunk-2NMEKWO5.js';
|
|
3
3
|
import { Box } from '@sanity/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { useState, useEffect } from 'react';
|
|
5
|
+
import { useClient, useFormValue } from 'sanity';
|
|
5
6
|
import styled from 'styled-components';
|
|
6
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
8
|
|
|
8
9
|
var PreviewContainer = styled.div`
|
|
9
10
|
max-width: 600px;
|
|
@@ -69,11 +70,24 @@ var LiveIndicator = styled.span`
|
|
|
69
70
|
border-radius: 4px;
|
|
70
71
|
`;
|
|
71
72
|
var SeoPreview = (props) => {
|
|
72
|
-
var _a, _b;
|
|
73
|
+
var _a, _b, _c, _d;
|
|
73
74
|
const { path, schemaType } = props;
|
|
74
75
|
const { options } = schemaType;
|
|
75
76
|
const baseUrl = (options == null ? void 0 : options.baseUrl) || "https://www.example.com";
|
|
76
77
|
const prefixFunction = options == null ? void 0 : options.prefix;
|
|
78
|
+
const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
|
|
79
|
+
const titleSuffixInheritColor = (_a = options == null ? void 0 : options.titleSuffixInheritColor) != null ? _a : false;
|
|
80
|
+
const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
|
|
81
|
+
const client = useClient({ apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
|
|
82
|
+
const [groqTitleSuffix, setGroqTitleSuffix] = useState("");
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!titleSuffixQuery) return;
|
|
85
|
+
client.fetch(titleSuffixQuery).then((result) => {
|
|
86
|
+
setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
|
|
87
|
+
}).catch(() => {
|
|
88
|
+
setGroqTitleSuffix("");
|
|
89
|
+
});
|
|
90
|
+
}, [titleSuffixQuery, client]);
|
|
77
91
|
const parent = useFormValue([path[0]]) || {
|
|
78
92
|
title: "",
|
|
79
93
|
description: "",
|
|
@@ -82,13 +96,22 @@ var SeoPreview = (props) => {
|
|
|
82
96
|
const rootDoc = useFormValue([]) || {
|
|
83
97
|
slug: { current: "" }
|
|
84
98
|
};
|
|
85
|
-
const slug = ((
|
|
99
|
+
const slug = ((_c = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _c.current) || "";
|
|
86
100
|
const {
|
|
87
101
|
title,
|
|
88
102
|
description,
|
|
89
103
|
canonicalUrl: url
|
|
90
104
|
} = parent;
|
|
91
|
-
const
|
|
105
|
+
const getTitleSuffix = () => {
|
|
106
|
+
if (titleSuffixQuery) return groqTitleSuffix;
|
|
107
|
+
if (!titleSuffixOption) return "";
|
|
108
|
+
if (typeof titleSuffixOption === "function") {
|
|
109
|
+
return titleSuffixOption(rootDoc);
|
|
110
|
+
}
|
|
111
|
+
return titleSuffixOption;
|
|
112
|
+
};
|
|
113
|
+
const titleSuffix = getTitleSuffix();
|
|
114
|
+
const base = (_d = url || baseUrl) == null ? void 0 : _d.replace(/\/+$/, "");
|
|
92
115
|
const slugStr = String(slug || "").replace(/^\/+/, "");
|
|
93
116
|
const pref = String(
|
|
94
117
|
prefixFunction ? prefixFunction(rootDoc) : ""
|
|
@@ -136,7 +159,19 @@ var SeoPreview = (props) => {
|
|
|
136
159
|
] }),
|
|
137
160
|
/* @__PURE__ */ jsxs(PreviewBody, { children: [
|
|
138
161
|
/* @__PURE__ */ jsx(SerpUrl, { children: finalUrl ? urlDisplay : "example.com \u203A page-url" }),
|
|
139
|
-
/* @__PURE__ */ jsx(SerpTitle, { children: title && title.length > 0 ?
|
|
162
|
+
/* @__PURE__ */ jsx(SerpTitle, { children: title && title.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
163
|
+
truncate(title, Math.max(1, 60 - titleSuffix.length)),
|
|
164
|
+
titleSuffix && /* @__PURE__ */ jsxs(
|
|
165
|
+
"span",
|
|
166
|
+
{
|
|
167
|
+
style: titleSuffixInheritColor ? void 0 : { color: "#70757a", fontWeight: 400 },
|
|
168
|
+
children: [
|
|
169
|
+
"| ",
|
|
170
|
+
titleSuffix
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
] }) : "Your SEO Title will appear here" }),
|
|
140
175
|
/* @__PURE__ */ jsx(SerpDescription, { children: description && description.length > 0 ? truncate(description, 160) : "Your meta description will show up here. Make it compelling!" })
|
|
141
176
|
] })
|
|
142
177
|
] }) });
|
|
@@ -144,5 +179,5 @@ var SeoPreview = (props) => {
|
|
|
144
179
|
var SeoPreview_default = SeoPreview;
|
|
145
180
|
|
|
146
181
|
export { SeoPreview_default as default };
|
|
147
|
-
//# sourceMappingURL=SeoPreview-
|
|
148
|
-
//# sourceMappingURL=SeoPreview-
|
|
182
|
+
//# sourceMappingURL=SeoPreview-BQBKMYSG.js.map
|
|
183
|
+
//# sourceMappingURL=SeoPreview-BQBKMYSG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/SeoPreview.tsx"],"names":[],"mappings":";;;;;;;;AAOA,IAAM,mBAAmB,MAAA,CAAO,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAShC,IAAM,gBAAgB,MAAA,CAAO,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAU7B,IAAM,cAAc,MAAA,CAAO,GAAA;AAAA;AAAA,CAAA;AAI3B,IAAM,UAAU,MAAA,CAAO,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAQvB,IAAM,YAAY,MAAA,CAAO,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAazB,IAAM,kBAAkB,MAAA,CAAO,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAY/B,IAAM,gBAAgB,MAAA,CAAO,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAc7B,IAAM,UAAA,GAAa,CAAC,KAAA,KAA0C;AA7E9D,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA8EE,EAAA,MAAM,EAAC,IAAA,EAAM,UAAA,EAAU,GAAI,KAAA;AAC3B,EAAA,MAAM,EAAC,SAAO,GAAI,UAAA;AAUlB,EAAA,MAAM,OAAA,GAAA,CAAU,mCAAS,OAAA,KAAW,yBAAA;AACpC,EAAA,MAAM,iBAAiB,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,MAAA;AAGhC,EAAA,MAAM,oBAAoB,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,WAAA;AACnC,EAAA,MAAM,uBAAA,GAAA,CAA0B,EAAA,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,uBAAA,KAAT,IAAA,GAAA,EAAA,GAAoC,KAAA;AACpE,EAAA,MAAM,mBAAmB,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,gBAAA;AAElC,EAAA,MAAM,MAAA,GAAS,UAAU,EAAC,UAAA,EAAA,CAAY,wCAAS,UAAA,KAAT,IAAA,GAAA,EAAA,GAAuB,cAAa,CAAA;AAC1E,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,SAAiB,EAAE,CAAA;AAEjE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,gBAAA,EAAkB;AACvB,IAAA,MAAA,CACG,KAAA,CAAc,gBAAgB,CAAA,CAC9B,IAAA,CAAK,CAAC,MAAA,KAAW;AAChB,MAAA,kBAAA,CAAmB,WAAW,IAAA,IAAQ,MAAA,KAAW,SAAY,EAAA,GAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,IAClF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,kBAAA,CAAmB,EAAE,CAAA;AAAA,IACvB,CAAC,CAAA;AAAA,EACL,CAAA,EAAG,CAAC,gBAAA,EAAkB,MAAM,CAAC,CAAA;AAC7B,EAAA,MAAM,SAAS,YAAA,CAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA,IAAK;AAAA,IACxC,KAAA,EAAO,EAAA;AAAA,IACP,WAAA,EAAa,EAAA;AAAA,IACb,YAAA,EAAc;AAAA,GAChB;AACA,EAAA,MAAM,OAAA,GAEF,YAAA,CAAa,EAAE,CAAA,IAAK;AAAA,IACtB,IAAA,EAAM,EAAC,OAAA,EAAS,EAAA;AAAE,GACpB;AACA,EAAA,MAAM,IAAA,GAAA,CAAA,CAAe,EAAA,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,IAAA,KAAT,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,OAAA,KAAW,EAAA;AAE/C,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA,EAAc;AAAA,GAChB,GAAI,MAAA;AAMJ,EAAA,MAAM,iBAAiB,MAAc;AACnC,IAAA,IAAI,kBAAkB,OAAO,eAAA;AAC7B,IAAA,IAAI,CAAC,mBAAmB,OAAO,EAAA;AAC/B,IAAA,IAAI,OAAO,sBAAsB,UAAA,EAAY;AAC3C,MAAA,OAAO,kBAAkB,OAAqD,CAAA;AAAA,IAChF;AACA,IAAA,OAAO,iBAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,cAAsB,cAAA,EAAe;AAG3C,EAAA,MAAM,IAAA,GAAA,CAAQ,EAAA,GAAA,GAAA,IAAO,OAAA,KAAP,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiB,QAAQ,MAAA,EAAQ,EAAA,CAAA;AAC/C,EAAA,MAAM,UAAU,MAAA,CAAO,IAAA,IAAQ,EAAE,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACrD,EAAA,MAAM,IAAA,GAAO,MAAA;AAAA,IACX,cAAA,GAAiB,cAAA,CAAe,OAAqC,CAAA,GAAI;AAAA,GAC3E,CAAE,OAAA,CAAQ,YAAA,EAAc,EAAE,CAAA;AAC1B,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,EAAM,OAAO,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AACxD,EAAA,MAAM,WAAW,OAAA,GAAU,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,GAAK,IAAA;AAGlD,EAAA,MAAM,UAAU,MAAM;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,QAAA,IAAY,IAAI,CAAA;AAClC,MAAA,OAAO,CAAA,CAAE,QAAA;AAAA,IACX,CAAA,CAAA,OAAQ,CAAA,EAAA;AACN,MAAA,OAAO,aAAA;AAAA,IACT;AAAA,EACF,CAAA,GAAG;AAGH,EAAA,MAAM,aAAa,CAAA,EAAG,MAAM,CAAA,EAAG,OAAA,GAAU,WAAM,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,MAAM,EAAE,CAAA,CAAE,CAAC,CAAC,KAAK,EAAE,CAAA,CAAA;AAErF,EAAA,uBACE,GAAA,CAAC,GAAA,EAAA,EAAI,OAAA,EAAS,CAAA,EACZ,+BAAC,gBAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,aAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO;AAAA,YACL,QAAA,EAAU,MAAA;AAAA,YACV,KAAA,EAAO,SAAA;AAAA,YACP,aAAA,EAAe,WAAA;AAAA,YACf,aAAA,EAAe;AAAA,WACjB;AAAA,UACD,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,2BACC,aAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO;AAAA,cACL,KAAA,EAAO,KAAA;AAAA,cACP,MAAA,EAAQ,KAAA;AAAA,cACR,YAAA,EAAc,KAAA;AAAA,cACd,eAAA,EAAiB,SAAA;AAAA,cACjB,OAAA,EAAS;AAAA;AACX;AAAA,SACF;AAAA,QAAE;AAAA,OAAA,EAEJ;AAAA,KAAA,EACF,CAAA;AAAA,yBAEC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAA,EAAA,EAAS,QAAA,EAAA,QAAA,GAAW,UAAA,GAAa,6BAAA,EAAyB,CAAA;AAAA,0BAC1D,SAAA,EAAA,EACE,QAAA,EAAA,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,oBACvB,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,QAAA,QAAA,CAAS,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,EAAA,GAAK,WAAA,CAAY,MAAM,CAAC,CAAA;AAAA,QACpD,WAAA,oBACC,IAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OACE,uBAAA,GAA0B,MAAA,GAAY,EAAC,KAAA,EAAO,SAAA,EAAW,YAAY,GAAA,EAAG;AAAA,YAE3E,QAAA,EAAA;AAAA,cAAA,IAAA;AAAA,cACI;AAAA;AAAA;AAAA;AACL,OAAA,EAEJ,IAEA,iCAAA,EAEJ,CAAA;AAAA,sBACA,GAAA,CAAC,eAAA,EAAA,EACE,QAAA,EAAA,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,IACjC,QAAA,CAAS,WAAA,EAAa,GAAG,CAAA,GACzB,8DAAA,EACN;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,IAAO,kBAAA,GAAQ","file":"SeoPreview-BQBKMYSG.js","sourcesContent":["import {Box} from '@sanity/ui'\nimport {type ReactElement, useEffect, useState} from 'react'\nimport {StringInputProps, useClient, useFormValue} from 'sanity'\nimport styled from 'styled-components'\n\nimport {truncate} from '../utils/seoUtils'\n\nconst PreviewContainer = styled.div`\n max-width: 600px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: #ffffff;\n border: 1px solid #dadce0;\n border-radius: 8px;\n overflow: hidden;\n`\n\nconst PreviewHeader = styled.div`\n background: #f8f9fa;\n padding: 12px 16px;\n border-bottom: 1px solid #dadce0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n`\n\nconst PreviewBody = styled.div`\n padding: 16px;\n`\n\nconst SerpUrl = styled.p`\n margin: 0 0 4px;\n color: #006621;\n font-size: 13px;\n line-height: 1.4;\n word-break: break-word;\n`\n\nconst SerpTitle = styled.h3`\n margin: 0 0 8px;\n color: #1a0dab;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.4;\n word-break: break-word;\n\n &:hover {\n text-decoration: underline;\n }\n`\n\nconst SerpDescription = styled.p`\n margin: 0;\n color: #545454;\n font-size: 14px;\n line-height: 1.6;\n word-break: break-word;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n`\n\nconst LiveIndicator = styled.span`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #4f46e5;\n background: #f0f4ff;\n padding: 4px 8px;\n border-radius: 4px;\n`\n\nconst SeoPreview = (props: StringInputProps): ReactElement => {\n const {path, schemaType} = props\n const {options} = schemaType as {\n options?: {\n baseUrl?: string\n apiVersion?: string\n prefix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffixInheritColor?: boolean\n titleSuffixQuery?: string\n }\n }\n const baseUrl = options?.baseUrl || 'https://www.example.com'\n const prefixFunction = options?.prefix as\n | ((doc: {_type?: string} & Record<string, unknown>) => string)\n | undefined\n const titleSuffixOption = options?.titleSuffix\n const titleSuffixInheritColor = options?.titleSuffixInheritColor ?? false\n const titleSuffixQuery = options?.titleSuffixQuery\n\n const client = useClient({apiVersion: options?.apiVersion ?? '2024-01-01'})\n const [groqTitleSuffix, setGroqTitleSuffix] = useState<string>('')\n\n useEffect(() => {\n if (!titleSuffixQuery) return\n client\n .fetch<string>(titleSuffixQuery)\n .then((result) => {\n setGroqTitleSuffix(result === null || result === undefined ? '' : String(result))\n })\n .catch(() => {\n setGroqTitleSuffix('')\n })\n }, [titleSuffixQuery, client])\n const parent = useFormValue([path[0]]) || {\n title: '',\n description: '',\n canonicalUrl: '',\n }\n const rootDoc: {\n slug?: {current: string}\n } = useFormValue([]) || {\n slug: {current: ''},\n }\n const slug: string = rootDoc?.slug?.current || ''\n\n const {\n title,\n description,\n canonicalUrl: url,\n } = parent as {\n title?: string\n description?: string\n canonicalUrl?: string\n }\n\n const getTitleSuffix = (): string => {\n if (titleSuffixQuery) return groqTitleSuffix\n if (!titleSuffixOption) return ''\n if (typeof titleSuffixOption === 'function') {\n return titleSuffixOption(rootDoc as {_type?: string} & Record<string, unknown>)\n }\n return titleSuffixOption\n }\n const titleSuffix: string = getTitleSuffix()\n\n // Build full URL\n const base = (url || baseUrl)?.replace(/\\/+$/, '')\n const slugStr = String(slug || '').replace(/^\\/+/, '')\n const pref = String(\n prefixFunction ? prefixFunction(rootDoc as {slug?: {current: string}}) : '',\n ).replace(/^\\/+|\\/+$/g, '')\n const urlPath = [pref, slugStr].filter(Boolean).join('/')\n const finalUrl = urlPath ? `${base}/${urlPath}` : base\n\n // Extract domain for display\n const domain = (() => {\n try {\n const u = new URL(finalUrl || base)\n return u.hostname\n } catch {\n return 'example.com'\n }\n })()\n\n // Format URL display with › separator\n const urlDisplay = `${domain}${urlPath ? ` › ${urlPath.split('/').slice(-1)[0]}` : ''}`\n\n return (\n <Box padding={3}>\n <PreviewContainer>\n <PreviewHeader>\n <span\n style={{\n fontSize: '11px',\n color: '#5f6368',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Search Preview\n </span>\n <LiveIndicator>\n <span\n style={{\n width: '4px',\n height: '4px',\n borderRadius: '50%',\n backgroundColor: '#4f46e5',\n display: 'inline-block',\n }}\n />\n Live\n </LiveIndicator>\n </PreviewHeader>\n\n <PreviewBody>\n <SerpUrl>{finalUrl ? urlDisplay : 'example.com › page-url'}</SerpUrl>\n <SerpTitle>\n {title && title.length > 0 ? (\n <>\n {truncate(title, Math.max(1, 60 - titleSuffix.length))}\n {titleSuffix && (\n <span\n style={\n titleSuffixInheritColor ? undefined : {color: '#70757a', fontWeight: 400}\n }\n >\n | {titleSuffix}\n </span>\n )}\n </>\n ) : (\n 'Your SEO Title will appear here'\n )}\n </SerpTitle>\n <SerpDescription>\n {description && description.length > 0\n ? truncate(description, 160)\n : 'Your meta description will show up here. Make it compelling!'}\n </SerpDescription>\n </PreviewBody>\n </PreviewContainer>\n </Box>\n )\n}\n\nexport default SeoPreview\n"]}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var chunkIFDLKZET_cjs = require('./chunk-IFDLKZET.cjs');
|
|
4
4
|
require('./chunk-S367Y35J.cjs');
|
|
5
5
|
var ui = require('@sanity/ui');
|
|
6
|
+
var react = require('react');
|
|
6
7
|
var sanity = require('sanity');
|
|
7
8
|
var styled = require('styled-components');
|
|
8
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -75,11 +76,24 @@ var LiveIndicator = styled__default.default.span`
|
|
|
75
76
|
border-radius: 4px;
|
|
76
77
|
`;
|
|
77
78
|
var SeoPreview = (props) => {
|
|
78
|
-
var _a, _b;
|
|
79
|
+
var _a, _b, _c, _d;
|
|
79
80
|
const { path, schemaType } = props;
|
|
80
81
|
const { options } = schemaType;
|
|
81
82
|
const baseUrl = (options == null ? void 0 : options.baseUrl) || "https://www.example.com";
|
|
82
83
|
const prefixFunction = options == null ? void 0 : options.prefix;
|
|
84
|
+
const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
|
|
85
|
+
const titleSuffixInheritColor = (_a = options == null ? void 0 : options.titleSuffixInheritColor) != null ? _a : false;
|
|
86
|
+
const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
|
|
87
|
+
const client = sanity.useClient({ apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
|
|
88
|
+
const [groqTitleSuffix, setGroqTitleSuffix] = react.useState("");
|
|
89
|
+
react.useEffect(() => {
|
|
90
|
+
if (!titleSuffixQuery) return;
|
|
91
|
+
client.fetch(titleSuffixQuery).then((result) => {
|
|
92
|
+
setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
|
|
93
|
+
}).catch(() => {
|
|
94
|
+
setGroqTitleSuffix("");
|
|
95
|
+
});
|
|
96
|
+
}, [titleSuffixQuery, client]);
|
|
83
97
|
const parent = sanity.useFormValue([path[0]]) || {
|
|
84
98
|
title: "",
|
|
85
99
|
description: "",
|
|
@@ -88,13 +102,22 @@ var SeoPreview = (props) => {
|
|
|
88
102
|
const rootDoc = sanity.useFormValue([]) || {
|
|
89
103
|
slug: { current: "" }
|
|
90
104
|
};
|
|
91
|
-
const slug = ((
|
|
105
|
+
const slug = ((_c = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _c.current) || "";
|
|
92
106
|
const {
|
|
93
107
|
title,
|
|
94
108
|
description,
|
|
95
109
|
canonicalUrl: url
|
|
96
110
|
} = parent;
|
|
97
|
-
const
|
|
111
|
+
const getTitleSuffix = () => {
|
|
112
|
+
if (titleSuffixQuery) return groqTitleSuffix;
|
|
113
|
+
if (!titleSuffixOption) return "";
|
|
114
|
+
if (typeof titleSuffixOption === "function") {
|
|
115
|
+
return titleSuffixOption(rootDoc);
|
|
116
|
+
}
|
|
117
|
+
return titleSuffixOption;
|
|
118
|
+
};
|
|
119
|
+
const titleSuffix = getTitleSuffix();
|
|
120
|
+
const base = (_d = url || baseUrl) == null ? void 0 : _d.replace(/\/+$/, "");
|
|
98
121
|
const slugStr = String(slug || "").replace(/^\/+/, "");
|
|
99
122
|
const pref = String(
|
|
100
123
|
prefixFunction ? prefixFunction(rootDoc) : ""
|
|
@@ -142,7 +165,19 @@ var SeoPreview = (props) => {
|
|
|
142
165
|
] }),
|
|
143
166
|
/* @__PURE__ */ jsxRuntime.jsxs(PreviewBody, { children: [
|
|
144
167
|
/* @__PURE__ */ jsxRuntime.jsx(SerpUrl, { children: finalUrl ? urlDisplay : "example.com \u203A page-url" }),
|
|
145
|
-
/* @__PURE__ */ jsxRuntime.jsx(SerpTitle, { children: title && title.length > 0 ?
|
|
168
|
+
/* @__PURE__ */ jsxRuntime.jsx(SerpTitle, { children: title && title.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
169
|
+
chunkIFDLKZET_cjs.truncate(title, Math.max(1, 60 - titleSuffix.length)),
|
|
170
|
+
titleSuffix && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
171
|
+
"span",
|
|
172
|
+
{
|
|
173
|
+
style: titleSuffixInheritColor ? void 0 : { color: "#70757a", fontWeight: 400 },
|
|
174
|
+
children: [
|
|
175
|
+
"| ",
|
|
176
|
+
titleSuffix
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
] }) : "Your SEO Title will appear here" }),
|
|
146
181
|
/* @__PURE__ */ jsxRuntime.jsx(SerpDescription, { children: description && description.length > 0 ? chunkIFDLKZET_cjs.truncate(description, 160) : "Your meta description will show up here. Make it compelling!" })
|
|
147
182
|
] })
|
|
148
183
|
] }) });
|
|
@@ -150,5 +185,5 @@ var SeoPreview = (props) => {
|
|
|
150
185
|
var SeoPreview_default = SeoPreview;
|
|
151
186
|
|
|
152
187
|
module.exports = SeoPreview_default;
|
|
153
|
-
//# sourceMappingURL=SeoPreview-
|
|
154
|
-
//# sourceMappingURL=SeoPreview-
|
|
188
|
+
//# sourceMappingURL=SeoPreview-LWSWTIF5.cjs.map
|
|
189
|
+
//# sourceMappingURL=SeoPreview-LWSWTIF5.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/SeoPreview.tsx"],"names":["styled","useClient","useState","useEffect","useFormValue","jsx","Box","jsxs","Fragment","truncate"],"mappings":"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","file":"SeoPreview-LWSWTIF5.cjs","sourcesContent":["import {Box} from '@sanity/ui'\nimport {type ReactElement, useEffect, useState} from 'react'\nimport {StringInputProps, useClient, useFormValue} from 'sanity'\nimport styled from 'styled-components'\n\nimport {truncate} from '../utils/seoUtils'\n\nconst PreviewContainer = styled.div`\n max-width: 600px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: #ffffff;\n border: 1px solid #dadce0;\n border-radius: 8px;\n overflow: hidden;\n`\n\nconst PreviewHeader = styled.div`\n background: #f8f9fa;\n padding: 12px 16px;\n border-bottom: 1px solid #dadce0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n`\n\nconst PreviewBody = styled.div`\n padding: 16px;\n`\n\nconst SerpUrl = styled.p`\n margin: 0 0 4px;\n color: #006621;\n font-size: 13px;\n line-height: 1.4;\n word-break: break-word;\n`\n\nconst SerpTitle = styled.h3`\n margin: 0 0 8px;\n color: #1a0dab;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.4;\n word-break: break-word;\n\n &:hover {\n text-decoration: underline;\n }\n`\n\nconst SerpDescription = styled.p`\n margin: 0;\n color: #545454;\n font-size: 14px;\n line-height: 1.6;\n word-break: break-word;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n`\n\nconst LiveIndicator = styled.span`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #4f46e5;\n background: #f0f4ff;\n padding: 4px 8px;\n border-radius: 4px;\n`\n\nconst SeoPreview = (props: StringInputProps): ReactElement => {\n const {path, schemaType} = props\n const {options} = schemaType as {\n options?: {\n baseUrl?: string\n apiVersion?: string\n prefix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffixInheritColor?: boolean\n titleSuffixQuery?: string\n }\n }\n const baseUrl = options?.baseUrl || 'https://www.example.com'\n const prefixFunction = options?.prefix as\n | ((doc: {_type?: string} & Record<string, unknown>) => string)\n | undefined\n const titleSuffixOption = options?.titleSuffix\n const titleSuffixInheritColor = options?.titleSuffixInheritColor ?? false\n const titleSuffixQuery = options?.titleSuffixQuery\n\n const client = useClient({apiVersion: options?.apiVersion ?? '2024-01-01'})\n const [groqTitleSuffix, setGroqTitleSuffix] = useState<string>('')\n\n useEffect(() => {\n if (!titleSuffixQuery) return\n client\n .fetch<string>(titleSuffixQuery)\n .then((result) => {\n setGroqTitleSuffix(result === null || result === undefined ? '' : String(result))\n })\n .catch(() => {\n setGroqTitleSuffix('')\n })\n }, [titleSuffixQuery, client])\n const parent = useFormValue([path[0]]) || {\n title: '',\n description: '',\n canonicalUrl: '',\n }\n const rootDoc: {\n slug?: {current: string}\n } = useFormValue([]) || {\n slug: {current: ''},\n }\n const slug: string = rootDoc?.slug?.current || ''\n\n const {\n title,\n description,\n canonicalUrl: url,\n } = parent as {\n title?: string\n description?: string\n canonicalUrl?: string\n }\n\n const getTitleSuffix = (): string => {\n if (titleSuffixQuery) return groqTitleSuffix\n if (!titleSuffixOption) return ''\n if (typeof titleSuffixOption === 'function') {\n return titleSuffixOption(rootDoc as {_type?: string} & Record<string, unknown>)\n }\n return titleSuffixOption\n }\n const titleSuffix: string = getTitleSuffix()\n\n // Build full URL\n const base = (url || baseUrl)?.replace(/\\/+$/, '')\n const slugStr = String(slug || '').replace(/^\\/+/, '')\n const pref = String(\n prefixFunction ? prefixFunction(rootDoc as {slug?: {current: string}}) : '',\n ).replace(/^\\/+|\\/+$/g, '')\n const urlPath = [pref, slugStr].filter(Boolean).join('/')\n const finalUrl = urlPath ? `${base}/${urlPath}` : base\n\n // Extract domain for display\n const domain = (() => {\n try {\n const u = new URL(finalUrl || base)\n return u.hostname\n } catch {\n return 'example.com'\n }\n })()\n\n // Format URL display with › separator\n const urlDisplay = `${domain}${urlPath ? ` › ${urlPath.split('/').slice(-1)[0]}` : ''}`\n\n return (\n <Box padding={3}>\n <PreviewContainer>\n <PreviewHeader>\n <span\n style={{\n fontSize: '11px',\n color: '#5f6368',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Search Preview\n </span>\n <LiveIndicator>\n <span\n style={{\n width: '4px',\n height: '4px',\n borderRadius: '50%',\n backgroundColor: '#4f46e5',\n display: 'inline-block',\n }}\n />\n Live\n </LiveIndicator>\n </PreviewHeader>\n\n <PreviewBody>\n <SerpUrl>{finalUrl ? urlDisplay : 'example.com › page-url'}</SerpUrl>\n <SerpTitle>\n {title && title.length > 0 ? (\n <>\n {truncate(title, Math.max(1, 60 - titleSuffix.length))}\n {titleSuffix && (\n <span\n style={\n titleSuffixInheritColor ? undefined : {color: '#70757a', fontWeight: 400}\n }\n >\n | {titleSuffix}\n </span>\n )}\n </>\n ) : (\n 'Your SEO Title will appear here'\n )}\n </SerpTitle>\n <SerpDescription>\n {description && description.length > 0\n ? truncate(description, 160)\n : 'Your meta description will show up here. Make it compelling!'}\n </SerpDescription>\n </PreviewBody>\n </PreviewContainer>\n </Box>\n )\n}\n\nexport default SeoPreview\n"]}
|
|
@@ -769,7 +769,12 @@ var MonitorIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
|
769
769
|
]
|
|
770
770
|
}
|
|
771
771
|
);
|
|
772
|
-
var DocTitleAnchor = ({
|
|
772
|
+
var DocTitleAnchor = ({
|
|
773
|
+
id,
|
|
774
|
+
type,
|
|
775
|
+
structureTool,
|
|
776
|
+
children
|
|
777
|
+
}) => {
|
|
773
778
|
const { basePath } = sanity.useWorkspace();
|
|
774
779
|
const { onClick: intentOnClick, href: intentHref } = router.useIntentLink({
|
|
775
780
|
intent: "edit",
|
|
@@ -809,7 +814,10 @@ var DocTitleAnchorPane = ({
|
|
|
809
814
|
const { ChildLink } = structure.usePaneRouter();
|
|
810
815
|
return /* @__PURE__ */ jsxRuntime.jsx(PaneLinkWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(ChildLink, { childId: id, childParameters: { type }, children }) });
|
|
811
816
|
};
|
|
812
|
-
var DocBadgeRenderer = ({
|
|
817
|
+
var DocBadgeRenderer = ({
|
|
818
|
+
doc,
|
|
819
|
+
docBadge
|
|
820
|
+
}) => {
|
|
813
821
|
const badge = docBadge(doc);
|
|
814
822
|
if (!badge) return null;
|
|
815
823
|
return /* @__PURE__ */ jsxRuntime.jsx(CustomBadge, { $bgColor: badge.bgColor, $textColor: badge.textColor, $fontSize: badge.fontSize, children: badge.label });
|
|
@@ -2039,5 +2047,5 @@ var SeoHealthDashboard = ({
|
|
|
2039
2047
|
var SeoHealthDashboard_default = SeoHealthDashboard;
|
|
2040
2048
|
|
|
2041
2049
|
exports.SeoHealthDashboard_default = SeoHealthDashboard_default;
|
|
2042
|
-
//# sourceMappingURL=chunk-
|
|
2043
|
-
//# sourceMappingURL=chunk-
|
|
2050
|
+
//# sourceMappingURL=chunk-77U7CMJP.cjs.map
|
|
2051
|
+
//# sourceMappingURL=chunk-77U7CMJP.cjs.map
|