diff --git a/src/app/schema/renderHtml.tsx b/src/app/schema/renderHtml.tsx
index 11a67a53..b4cbe6d7 100644
--- a/src/app/schema/renderHtml.tsx
+++ b/src/app/schema/renderHtml.tsx
@@ -1,4 +1,4 @@
-import type { BooleanHookParams, EnumOption, Hook, INode, NodeChildren, NumberHookParams, StringHookParams, ValidationOption } from '@mcschema/core'
+import type { BooleanHookParams, EnumOption, Hook, INode, ListHookParams, NodeChildren, NumberHookParams, StringHookParams, ValidationOption } from '@mcschema/core'
import { DataModel, ListNode, MapNode, ModelPath, ObjectNode, Path, relativePath, StringNode } from '@mcschema/core'
import { Identifier, ItemStack } from 'deepslate/core'
import type { ComponentChildren, JSX } from 'preact'
@@ -94,10 +94,7 @@ const renderHtml: RenderHook = {
return [prefix, <>{inject}{suffix}>, body]
},
- list({ children, config }, path, value, lang, version, states, ctx) {
- const { expand, collapse, isToggled } = useToggles()
- const [maxShown, setMaxShown] = useState(50)
-
+ list({ children, config, node }, path, value, lang, version, states, ctx) {
const context = path.getContext().join('.')
if (fixedLists.includes(context)) {
const prefix = <>
@@ -117,87 +114,8 @@ const renderHtml: RenderHook = {
const node = DataModel.wrapLists(children.default())
path.model.set(path, [{ node, id: hexId() }, ...value])
}
- const onAddBottom = () => {
- if (!Array.isArray(value)) value = []
- const node = DataModel.wrapLists(children.default())
- path.model.set(path, [...value, { node, id: hexId() }])
- }
const suffix =
- const body = <>
- {(value && Array.isArray(value)) && value.map(({ node: cValue, id: cId }, index) => {
- if (index === maxShown) {
- return
- }
- if (index > maxShown) {
- return null
- }
- const pathWithContext = (config?.context) ? new ModelPath(path.getModel(), new Path(path.getArray(), [config.context])) : path
- const cPath = pathWithContext.push(index).contextPush('entry')
- const canToggle = children.type(cPath) === 'object'
- const toggle = isToggled(cId)
-
- let label: undefined | string | JSX.Element
- if (itemPreviewFields.includes(cPath.getContext().join('.'))) {
- if (isObject(cValue) && typeof cValue.type === 'string' && cValue.type.replace(/^minecraft:/, '') === 'item' && typeof cValue.name === 'string') {
- let itemStack: ItemStack | undefined
- try {
- itemStack = new ItemStack(Identifier.parse(cValue.name), 1)
- } catch (e) {}
- if (itemStack !== undefined) {
- label =
- }
- }
- }
-
- if (canToggle && (toggle === false || (toggle === undefined && value.length > 20))) {
- return
- }
-
- const onRemove = () => cPath.set(undefined)
- const onMoveUp = () => {
- const v = [...path.get()];
- [v[index - 1], v[index]] = [v[index], v[index - 1]]
- path.model.set(path, v)
- }
- const onMoveDown = () => {
- const v = [...path.get()];
- [v[index + 1], v[index]] = [v[index], v[index + 1]]
- path.model.set(path, v)
- }
- const actions: MenuAction[] = [
- {
- icon: 'duplicate',
- label: 'duplicate',
- onSelect: () => {
- const v = [...path.get()]
- v.splice(index, 0, { id: hexId(), node: deepClone(cValue) })
- path.model.set(path, v)
- },
- },
- ]
- return
- {canToggle && }
-
- {value.length > 1 &&
-
-
-
}
-
- })}
- {(value && value.length > 0 && value.length <= maxShown) && }
- >
- return [null, suffix, body]
+ return [null, suffix, ]
},
map({ children, keys, config }, path, value, lang, version, states, ctx) {
@@ -386,6 +304,90 @@ function useToggles() {
return { expand, collapse, isToggled }
}
+function ListBody({ path, value, lang, config, children, version, states, ctx }: NodeProps) {
+ const { expand, collapse, isToggled } = useToggles()
+ const [maxShown, setMaxShown] = useState(50)
+ const onAddBottom = () => {
+ if (!Array.isArray(value)) value = []
+ const node = DataModel.wrapLists(children.default())
+ path.model.set(path, [...value, { node, id: hexId() }])
+ }
+ return <>
+ {(value && Array.isArray(value)) && value.map(({ node: cValue, id: cId }, index) => {
+ if (index === maxShown) {
+ return
+ }
+ if (index > maxShown) {
+ return null
+ }
+ const pathWithContext = (config?.context) ? new ModelPath(path.getModel(), new Path(path.getArray(), [config.context])) : path
+ const cPath = pathWithContext.push(index).contextPush('entry')
+ const canToggle = children.type(cPath) === 'object'
+ const toggle = isToggled(cId)
+
+ let label: undefined | string | JSX.Element
+ if (itemPreviewFields.includes(cPath.getContext().join('.'))) {
+ if (isObject(cValue) && typeof cValue.type === 'string' && cValue.type.replace(/^minecraft:/, '') === 'item' && typeof cValue.name === 'string') {
+ let itemStack: ItemStack | undefined
+ try {
+ itemStack = new ItemStack(Identifier.parse(cValue.name), 1)
+ } catch (e) {}
+ if (itemStack !== undefined) {
+ label =
+ }
+ }
+ }
+
+ if (canToggle && (toggle === false || (toggle === undefined && value.length > 20))) {
+ return
+ }
+
+ const onRemove = () => cPath.set(undefined)
+ const onMoveUp = () => {
+ const v = [...path.get()];
+ [v[index - 1], v[index]] = [v[index], v[index - 1]]
+ path.model.set(path, v)
+ }
+ const onMoveDown = () => {
+ const v = [...path.get()];
+ [v[index + 1], v[index]] = [v[index], v[index + 1]]
+ path.model.set(path, v)
+ }
+ const actions: MenuAction[] = [
+ {
+ icon: 'duplicate',
+ label: 'duplicate',
+ onSelect: () => {
+ const v = [...path.get()]
+ v.splice(index, 0, { id: hexId(), node: deepClone(cValue) })
+ path.model.set(path, v)
+ },
+ },
+ ]
+ return
+ {canToggle && }
+
+ {value.length > 1 &&
+
+
+
}
+
+ })}
+ {(value && value.length > 0 && value.length <= maxShown) && }
+ >
+}
+
function BooleanSuffix({ path, node, value, lang }: NodeProps) {
const set = (target: boolean) => {
path.model.set(path, node.optional() && value === target ? undefined : target)