Skip to content

Commit

Permalink
fix(jsoneditor): support any input
Browse files Browse the repository at this point in the history
  • Loading branch information
morlay committed Nov 15, 2024
1 parent e9fb0bd commit 7fa8fd3
Show file tree
Hide file tree
Showing 22 changed files with 394 additions and 241 deletions.
Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions nodedevpkg/vue-vite-presets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
"@innoai-tech/vuecomponentcompleter": "^0.1.3",
"@mapbox/rehype-prism": "^0.9.0",
"@mdx-js/rollup": "^3.1.0",
"@swc/core": "^1.8.0",
"@vitejs/plugin-vue": "^5.1.4",
"@swc/core": "^1.9.2",
"@vitejs/plugin-vue": "^5.2.0",
"hastscript": "^9.0.0",
"unist-util-visit": "^5.0.0",
"vite": "^5.4.10",
"vite": "^5.4.11",
"vite-plugin-pages": "^0.32.3",
"vite-tsconfig-paths": "^5.1.0"
"vite-tsconfig-paths": "^5.1.2"
},
"peerDependencies": {},
"exports": {
Expand Down
16 changes: 12 additions & 4 deletions nodepkg/jsoneditor/example/jsoneditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class JSONSchema {
@t.nativeEnum(Kind)
kind!: Kind;

@t.annotate({ title: "名称" })
@t.annotate({ title: "名称", description: "详细描述" })
@t.string()
name!: string;

Expand All @@ -44,17 +44,25 @@ class JSONSchema {
@t.annotate({ title: "端口" })
@t.array(t.object(Port))
ports!: Port[];

@t.annotate({ title: "其他配置" })
@t.record(t.string(), t.any())
@t.optional()
manifests!: Record<string, any>;
}

export default component(() => {
const x = t.object(JSONSchema);

const editor$ = JSONEditor.of(x, {
name: "name",
annotations: {
text: "name",
longtext: new Array(100).fill("longtext").join(""),
longtext: new Array(100).fill("longtext").join("")
},
ports: [],
manifests: {
"x": {}
}
});

rx(
Expand All @@ -68,7 +76,7 @@ export default component(() => {
}
console.log(JSON.stringify(v, null, 2));
}),
subscribeUntilUnmount(),
subscribeUntilUnmount()
);

return () => (
Expand Down
3 changes: 2 additions & 1 deletion nodepkg/jsoneditor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@innoai-tech/jsoneditor",
"version": "0.3.2",
"version": "0.3.4",
"monobundle": {
"build": {
"clean": true
Expand All @@ -11,6 +11,7 @@
},
"dependencies": {
"@innoai-tech/vuekit": "workspace:^",
"@innoai-tech/vuemarkdown": "workspace:^",
"@innoai-tech/vuematerial": "workspace:^",
"@innoai-tech/vueuikit": "workspace:^",
"@mdi/js": "^7.4.47",
Expand Down
34 changes: 12 additions & 22 deletions nodepkg/jsoneditor/src/JSONEditorView.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
import {
component$,
type Context,
EmptyContext,
rx,
Schema,
type Type,
} from "@innoai-tech/vuekit";
import { component$, type Context, EmptyContext, rx, Schema, type Type } from "@innoai-tech/vuekit";
import { JSONEditorProvider, JSONEditorSlotsProvider } from "./models";
import {
ArrayInput,
LayoutContextProvider,
Line,
ObjectInput,
OneEditingProvider,
RecordInput,
ValueInput,
} from "./views";
import { LayoutContextProvider, Line } from "./views";
import { styled } from "@innoai-tech/vueuikit";
import { ref } from "vue";
import { isUndefined } from "@innoai-tech/lodash";
import { AnyInput, ArrayInput, ObjectInput, OneEditingProvider, RecordInput, ValueInput } from "./inputs";

export const defaultValueRender = (typedef: Type, value: any, ctx: Context) => {
if (
Expand All @@ -44,6 +30,10 @@ export const defaultValueRender = (typedef: Type, value: any, ctx: Context) => {
return <ArrayInput typedef={typedef} value={value} ctx={ctx} />;
}

if (typedef.type == "any" || typedef.type == "unknown") {
return <AnyInput typedef={typedef} value={value} ctx={ctx} />;
}

return <ValueInput typedef={typedef} value={value} ctx={ctx} />;
};

Expand All @@ -62,7 +52,7 @@ export const JSONEditorView = component$(({}, { render }) => {
<OneEditingProvider>
<JSONEditorSlotsProvider
value={{
$value: slots.$value ?? defaultValueRender,
$value: slots.$value ?? defaultValueRender
}}
>
<JSONEditorContainer>
Expand All @@ -71,7 +61,7 @@ export const JSONEditorView = component$(({}, { render }) => {
<LayoutContextProvider
value={{
indent: 0,
$container: $container,
$container: $container
}}
>
<Line path={[]} viewOnly>
Expand All @@ -83,7 +73,7 @@ export const JSONEditorView = component$(({}, { render }) => {
</JSONEditorSlotsProvider>
</OneEditingProvider>
);
}),
})
);
});

Expand All @@ -95,6 +85,6 @@ const JSONEditorContainer = styled("div")({
section: {
display: "flex",
flexDirection: "column",
minWidth: "max-content",
},
minWidth: "max-content"
}
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { component$ } from "@innoai-tech/vuekit";
import { Icon } from "@innoai-tech/vuematerial";
import { ActionBtn } from "./Actions.tsx";
import copyToClipboard from "copy-to-clipboard";
import { mdiContentCopy } from "@mdi/js";
import { Tooltip } from "./Tooltip.tsx";
import { ActionBtn, Tooltip } from "../views";

export const CopyAsJSONIconBtn = component$<{
value?: any;
Expand Down
1 change: 1 addition & 0 deletions nodepkg/jsoneditor/src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./JSONRaw.tsx"
1 change: 1 addition & 0 deletions nodepkg/jsoneditor/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./inputs";
export * from "./models";
export * from "./views";
export * from "./JSONEditorView.tsx";
26 changes: 26 additions & 0 deletions nodepkg/jsoneditor/src/inputs/AnyInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { component$, type Context, rx, t, type Type } from "@innoai-tech/vuekit";
import { isArray, isObject } from "@innoai-tech/lodash";
import { ArrayInput } from "./ArrayInput.tsx";
import { RecordInput } from "./RecordInput.tsx";
import { ValueInput } from "./ValueInput.tsx";

export const AnyInput = component$<{
typedef: Type;
ctx: Context;
value: string | boolean | number | null | undefined;
}>((props, { render }) => {
return rx(
props.value$,
render((value) => {
if (isArray(value)) {
return <ArrayInput value={value} typedef={t.any()} ctx={props.ctx} />;
}

if (isObject(value)) {
return <RecordInput value={value} typedef={t.record(t.string(), t.any())} ctx={props.ctx} />;
}

return <ValueInput value={value} typedef={t.any()} ctx={props.ctx} allowRawJSON/>;
})
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,16 @@ import {
Schema,
subscribeUntilUnmount,
type Type,
type VNodeChild,
type VNodeChild
} from "@innoai-tech/vuekit";
import { Icon } from "@innoai-tech/vuematerial";
import { mdiCancel, mdiCheckBold, mdiMinusBoxOutline } from "@mdi/js";
import { Block, Line, PropName } from "./TokenView.tsx";
import { JSONEditorProvider, JSONEditorSlotsProvider } from "../models";
import { ActionBtn, Actions } from "./Actions.tsx";
import { CopyAsJSONIconBtn } from "./JSONRaw.tsx";
import { Tooltip } from "./Tooltip.tsx";
import { Box, Popper } from "@innoai-tech/vueuikit";
import {
InputActionSubject,
InputText,
ValueContainer,
ValueInputActions,
} from "./ValueInput.tsx";
import { InputActionSubject, InputText, ValueContainer, ValueInputActions } from "./ValueInput.tsx";
import { tap } from "rxjs";
import { PopupStatus } from "./Menu.tsx";
import { CopyAsJSONIconBtn } from "../actions";
import { ActionBtn, Actions, Block, Line, PopupStatus, PropName, Tooltip } from "../views";

export const ArrayInput = component$<{
ctx: Context;
Expand Down Expand Up @@ -55,7 +47,7 @@ export const ArrayInput = component$<{
(values: any) => {
values.push(value);
},
[],
[]
);
}}
/>
Expand All @@ -81,15 +73,15 @@ export const ArrayInput = component$<{
{slots.$value?.(propSchema, itemValue, {
...props.ctx,
path: path,
branch: [...props.ctx.branch, itemValue],
branch: [...props.ctx.branch, itemValue]
})}
</Line>
);
},
}
)}
</Block>
);
}),
})
);
});

Expand Down Expand Up @@ -121,12 +113,10 @@ const AddItemIconBtn = component$<{
const items = Schema.schemaProp(props.typedef, "items") as Type;

const [err, value] = items.validate(inputValue, { coerce: true });

if (!!err) {
editor$.setError(props.ctx.path, err);
return;
}

emit("add", value);
} else {
emit("add", undefined);
Expand All @@ -137,17 +127,27 @@ const AddItemIconBtn = component$<{
rx(
inputText$,
tap((input) => {
if (input.trim().startsWith("[")) {
const raw = input.trim();

if (raw.startsWith("[") && raw.endsWith("]")) {
try {
const v = JSON.parse(input);
const v = JSON.parse(raw);
editor$.update(props.ctx.path, v);
reset();
} catch (err) {
editor$.setError(props.ctx.path, "无效的 JSON 字符串");
}
}

if (raw.startsWith("{") && raw.endsWith("}")) {
try {
commit(JSON.parse(raw));
} catch (err) {
editor$.setError(props.ctx.path, "无效的 JSON 字符串");
}
}
}),
subscribeUntilUnmount(),
subscribeUntilUnmount()
);

rx(
Expand All @@ -162,7 +162,7 @@ const AddItemIconBtn = component$<{
break;
}
}),
subscribeUntilUnmount(),
subscribeUntilUnmount()
);

const $input = rx(
Expand Down Expand Up @@ -196,7 +196,7 @@ const AddItemIconBtn = component$<{
/>
</Popper>
);
}),
})
);

return () => (
Expand Down
Loading

0 comments on commit 7fa8fd3

Please sign in to comment.