diff --git a/src/page/json-viewer/index.tsx b/src/page/json-viewer/index.tsx
index 0604347..b5ee6f6 100644
--- a/src/page/json-viewer/index.tsx
+++ b/src/page/json-viewer/index.tsx
@@ -5,6 +5,43 @@ import JsonTreeNode from "@/components/json-tree-node"
import JsonCodeEditor from "@/components/json-code-editor"
import Seo from "@/components/seo"
+const jsonPathTokenRegex = /(\$)|(\.\.)|(\.)|(\[\*\])|(\[\d+\])|(\[(?:'[^']*'|"[^"]*")\])|(\*)|(@)|(\?)|(\(|\))|([A-Za-z_][\w-]*)/g
+
+function escapeHtml(input: string): string {
+ return input
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+}
+
+function getJsonPathTokenClass(token: string): string {
+ if (token === "$" || token === "@") return "text-indigo-600"
+ if (token === "." || token === "..") return "text-slate-400"
+ if (token === "*" || token === "[*]") return "text-violet-600"
+ if (token.startsWith("[") && token.endsWith("]")) return "text-amber-600"
+ if (token === "?" || token === "(" || token === ")") return "text-rose-600"
+ return "text-emerald-600"
+}
+
+function highlightJsonPath(input: string): string {
+ if (!input) return " "
+
+ let result = ""
+ let lastIndex = 0
+
+ for (const match of input.matchAll(jsonPathTokenRegex)) {
+ const token = match[0]
+ const index = match.index ?? 0
+
+ result += escapeHtml(input.slice(lastIndex, index))
+ result += `${escapeHtml(token)}`
+ lastIndex = index + token.length
+ }
+
+ result += escapeHtml(input.slice(lastIndex))
+ return result
+}
+
/**
* JSON Viewer page component that displays the JSON visualisation tool in DevLab.
*/
@@ -29,6 +66,7 @@ export default function JsonViewer() {
const [query, setQuery] = useState("$.staff_members[*].name")
const [copiedCsv, setCopiedCsv] = useState(false)
const [copiedRawJson, setCopiedRawJson] = useState(false)
+ const highlightedQuery = useMemo(() => highlightJsonPath(query), [query])
const isPlainObject = (value: unknown): value is Record => {
return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -147,17 +185,28 @@ export default function JsonViewer() {
{t("jsonViewer.invalidSyntax")}
)}
- setQuery(e.target.value)}
- placeholder={t("jsonViewer.placeholder")}
- />
+ >
+
+
+
+ setQuery(e.target.value)}
+ placeholder={t("jsonViewer.placeholder")}
+ spellCheck={false}
+ />
+