-
{instance.type}
-
- {instance.ast?.children.map((child) => (
-
- ))}
-
+
+
+ {collapsed && (
+
+ {instance.ast?.children.map((child) => (
+
+ ))}
+
+ )}
);
};
interface TemplateTreeNodeProps {
instance: TemplateChildNode;
+ depth?: number;
}
-const TemplateTreeNode = ({ instance }: TemplateTreeNodeProps) => {
+const TemplateTreeNode = ({ instance, depth = 2 }: TemplateTreeNodeProps) => {
// COMPOUND_EXPRESSION is a node that is only generated when the compiler optimizes.
// Impossible to appear in the use case. It's excluded here just to eliminate TSC warning.
const hasChildren = instance.type !== NodeTypes.COMPOUND_EXPRESSION && "children" in instance;
+ const [collapsed, setCollapsed] = useState(depth <= 3);
return (
-
-
{NodeTypes[instance.type]}
- {hasChildren && (
-
- {instance.children.map((child) => (
-
- ))}
-
+
+ {hasChildren ? (
+
+
{NodeTypes[instance.type]}
+ {instance.type === NodeTypes.ELEMENT && (
+
{`<${instance.tag}>`}
+ )}
+
+ {collapsed && hasChildren && (
+
+ {instance.children.map((child) => (
+
+ ))}
+
+ )}
);
};
diff --git a/app/components/global-options.tsx b/app/components/global-options.tsx
deleted file mode 100644
index 508d72e..0000000
--- a/app/components/global-options.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { useGlobalOptionsStore } from "~/lib/store";
-
-const GlobalOptions = () => {
- const { view, updateView } = useGlobalOptionsStore();
-
- const handleChangeView = (value: typeof view) => {
- if (value !== view) {
- updateView(value);
- }
- };
-
- return (
-
- {/* biome-ignore lint/security/noDangerouslySetInnerHtml: Shiki has escaped html. */}
-
+
+
+
+ {/* biome-ignore lint/security/noDangerouslySetInnerHtml: Shiki has escaped html. */}
+
+
);
};
export default SelectedNodeView;
+
+const CopyTextButton = ({ text, className }: { text: string; className: string }) => {
+ const [copied, setCopied] = useState(false);
+ return (
+
+ );
+};
diff --git a/app/components/ui/input.tsx b/app/components/ui/input.tsx
deleted file mode 100644
index 5f92edd..0000000
--- a/app/components/ui/input.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as React from "react";
-
-import { cn } from "~/lib/utils";
-
-export interface InputProps extends React.InputHTMLAttributes
{}
-
-const Input = React.forwardRef(
- ({ className, type, ...props }, ref) => {
- return (
-
- );
- },
-);
-Input.displayName = "Input";
-
-export { Input };
diff --git a/app/components/ui/label.tsx b/app/components/ui/label.tsx
deleted file mode 100644
index b4c77ea..0000000
--- a/app/components/ui/label.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import * as LabelPrimitive from "@radix-ui/react-label";
-import { type VariantProps, cva } from "class-variance-authority";
-import * as React from "react";
-
-import { cn } from "~/lib/utils";
-
-const labelVariants = cva(
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
-);
-
-const Label = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & VariantProps
->(({ className, ...props }, ref) => (
-
-));
-Label.displayName = LabelPrimitive.Root.displayName;
-
-export { Label };
diff --git a/app/components/ui/popover.tsx b/app/components/ui/popover.tsx
deleted file mode 100644
index 0faf72a..0000000
--- a/app/components/ui/popover.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import * as PopoverPrimitive from "@radix-ui/react-popover";
-import * as React from "react";
-
-import { cn } from "~/lib/utils";
-
-const Popover = PopoverPrimitive.Root;
-
-const PopoverTrigger = PopoverPrimitive.Trigger;
-
-const PopoverAnchor = PopoverPrimitive.Anchor;
-
-const PopoverContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
-
-
-
-));
-PopoverContent.displayName = PopoverPrimitive.Content.displayName;
-
-export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
diff --git a/app/components/ui/radio-group.tsx b/app/components/ui/radio-group.tsx
deleted file mode 100644
index 595fea5..0000000
--- a/app/components/ui/radio-group.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
-import * as React from "react";
-
-import { cn } from "~/lib/utils";
-
-const RadioGroup = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => {
- return ;
-});
-RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
-
-const RadioGroupItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => {
- return (
-
-
-
-
-
- );
-});
-RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
-
-export { RadioGroup, RadioGroupItem };
diff --git a/app/lib/store.ts b/app/lib/store.ts
index 63a618b..8da88f4 100644
--- a/app/lib/store.ts
+++ b/app/lib/store.ts
@@ -1,45 +1,18 @@
import type { Node } from "@vue/compiler-core";
import type { SFCBlock } from "@vue/compiler-sfc";
import { create } from "zustand";
-import { persist } from "zustand/middleware";
-
-type GlobalOptionsState = {
- view: "JSON" | "tree";
-};
-
-type GlobalOptionsAction = {
- updateView: (view: GlobalOptionsState["view"]) => void;
-};
-
-type GlobalOptionsStore = GlobalOptionsState & GlobalOptionsAction;
-
-export const useGlobalOptionsStore = create()(
- persist(
- (set) => ({
- view: "tree",
- updateView: (view) => set({ view }),
- }),
- {
- name: "zustand-global-options",
- },
- ),
-);
type SelectedNodeState = {
node: Node | SFCBlock | null;
- valid: boolean;
};
type SelectedNodeAction = {
updateSelectedNode: (node: SelectedNodeState["node"]) => void;
- updateValid: (valid: SelectedNodeState["valid"]) => void;
};
type SelectedNodeStore = SelectedNodeState & SelectedNodeAction;
export const useSelectedNodeStore = create((set) => ({
node: null,
- valid: true,
updateSelectedNode: (node) => set(() => ({ node })),
- updateValid: (valid) => set(() => ({ valid })),
}));
diff --git a/app/lib/utils.tsx b/app/lib/utils.tsx
index 050b7ca..aa55f07 100644
--- a/app/lib/utils.tsx
+++ b/app/lib/utils.tsx
@@ -10,10 +10,6 @@ function subscribe() {
return () => {};
}
-export function useMount(fn: () => void) {
- useEffect(fn, []);
-}
-
/**
* Return a boolean indicating if the JS has been hydrated already.
* When doing Server-Side Rendering, the result will always be false.
diff --git a/package.json b/package.json
index d4d139c..0dd3bf3 100644
--- a/package.json
+++ b/package.json
@@ -35,10 +35,7 @@
"@netlify/edge-functions": "^2.11.0",
"@netlify/remix-edge-adapter": "^3.4.2",
"@netlify/remix-runtime": "^2.3.1",
- "@radix-ui/react-context-menu": "^2.2.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",
- "@radix-ui/react-label": "^2.1.0",
- "@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-radio-group": "^1.2.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 94ac3bd..ec78d76 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,18 +23,9 @@ importers:
'@netlify/remix-runtime':
specifier: ^2.3.1
version: 2.3.1(@remix-run/server-runtime@2.13.1(typescript@5.6.3))
- '@radix-ui/react-context-menu':
- specifier: ^2.2.2
- version: 2.2.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
'@radix-ui/react-dropdown-menu':
specifier: ^2.1.2
version: 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-label':
- specifier: ^2.1.0
- version: 2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-popover':
- specifier: ^1.1.2
- version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
'@radix-ui/react-radio-group':
specifier: ^1.2.1
version: 1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
@@ -927,19 +918,6 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-context-menu@2.2.2':
- resolution: {integrity: sha512-99EatSTpW+hRYHt7m8wdDlLtkmTovEe8Z/hnxUPV+SKuuNL5HWNhQI4QSdjZqNSgXHay2z4M3Dym73j9p2Gx5Q==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-context@1.1.0':
resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==}
peerDependencies:
@@ -1024,19 +1002,6 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-label@2.1.0':
- resolution: {integrity: sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-menu@2.1.2':
resolution: {integrity: sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==}
peerDependencies:
@@ -1050,19 +1015,6 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-popover@1.1.2':
- resolution: {integrity: sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-popper@1.2.0':
resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==}
peerDependencies:
@@ -4869,20 +4821,6 @@ snapshots:
optionalDependencies:
'@types/react': 18.3.11
- '@radix-ui/react-context-menu@2.2.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)':
- dependencies:
- '@radix-ui/primitive': 1.1.0
- '@radix-ui/react-context': 1.1.1(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-menu': 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- react: 19.0.0-rc-6cf85185-20241014
- react-dom: 19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014)
- optionalDependencies:
- '@types/react': 18.3.11
- '@types/react-dom': 18.3.1
-
'@radix-ui/react-context@1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)':
dependencies:
react: 19.0.0-rc-6cf85185-20241014
@@ -4953,15 +4891,6 @@ snapshots:
optionalDependencies:
'@types/react': 18.3.11
- '@radix-ui/react-label@2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)':
- dependencies:
- '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- react: 19.0.0-rc-6cf85185-20241014
- react-dom: 19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014)
- optionalDependencies:
- '@types/react': 18.3.11
- '@types/react-dom': 18.3.1
-
'@radix-ui/react-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)':
dependencies:
'@radix-ui/primitive': 1.1.0
@@ -4988,29 +4917,6 @@ snapshots:
'@types/react': 18.3.11
'@types/react-dom': 18.3.1
- '@radix-ui/react-popover@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)':
- dependencies:
- '@radix-ui/primitive': 1.1.0
- '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-context': 1.1.1(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-id': 1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-slot': 1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- aria-hidden: 1.2.4
- react: 19.0.0-rc-6cf85185-20241014
- react-dom: 19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014)
- react-remove-scroll: 2.6.0(@types/react@18.3.11)(react@19.0.0-rc-6cf85185-20241014)
- optionalDependencies:
- '@types/react': 18.3.11
- '@types/react-dom': 18.3.1
-
'@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)':
dependencies:
'@floating-ui/react-dom': 2.1.2(react-dom@19.0.0-rc-6cf85185-20241014(react@19.0.0-rc-6cf85185-20241014))(react@19.0.0-rc-6cf85185-20241014)
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..b047eb0
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,14 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": [":semanticCommitTypeAll(chore)", "group:allNonMajor"],
+ "packageRules": [
+ {
+ "matchPackageNames": ["@vue/compiler-core", "@vue/compiler-sfc"],
+ "enabled": true
+ },
+ {
+ "matchPackagePatterns": ["*"],
+ "enabled": false
+ }
+ ]
+}