From d890383a008b542c46819a1ce98a2646725a10e7 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Thu, 5 Jan 2023 17:09:36 +0900 Subject: [PATCH] add Ui:C:folder for AiScript --- packages/frontend/src/components/MkAsUi.vue | 7 +++++ packages/frontend/src/scripts/aiscript/ui.ts | 33 +++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkAsUi.vue b/packages/frontend/src/components/MkAsUi.vue index bc1e25957..ec214f039 100644 --- a/packages/frontend/src/components/MkAsUi.vue +++ b/packages/frontend/src/components/MkAsUi.vue @@ -33,6 +33,12 @@ <option v-for="item in c.items" :key="item.value" :value="item.value">{{ item.text }}</option> </MkSelect> <MkButton v-else-if="c.type === 'postFormButton'" :primary="c.primary" :rounded="c.rounded" :small="size === 'small'" @click="openPostForm">{{ c.text }}</MkButton> + <FormFolder v-else-if="c.type === 'folder'" :default-open="c.opened"> + <template #label>{{ c.title }}</template> + <template v-for="child in c.children" :key="child"> + <MkAsUi v-if="!g(child).hidden" :component="g(child)" :components="props.components" :size="size"/> + </template> + </FormFolder> <div v-else-if="c.type === 'container'" :class="[$style.container, { [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace', [$style.containerCenter]: c.align === 'center' }]" :style="{ backgroundColor: c.bgColor ?? null, color: c.fgColor ?? null, borderWidth: c.borderWidth ? `${c.borderWidth}px` : 0, borderColor: c.borderColor ?? 'var(--divider)', padding: c.padding ? `${c.padding}px` : 0, borderRadius: c.rounded ? '8px' : 0 }"> <template v-for="child in c.children" :key="child"> <MkAsUi v-if="!g(child).hidden" :component="g(child)" :components="props.components" :size="size"/> @@ -50,6 +56,7 @@ import MkSwitch from '@/components/form/switch.vue'; import MkTextarea from '@/components/form/textarea.vue'; import MkSelect from '@/components/form/select.vue'; import { AsUiComponent } from '@/scripts/aiscript/ui'; +import FormFolder from '@/components/form/folder.vue'; const props = withDefaults(defineProps<{ component: AsUiComponent; diff --git a/packages/frontend/src/scripts/aiscript/ui.ts b/packages/frontend/src/scripts/aiscript/ui.ts index f4c89b827..6e0e31211 100644 --- a/packages/frontend/src/scripts/aiscript/ui.ts +++ b/packages/frontend/src/scripts/aiscript/ui.ts @@ -100,6 +100,13 @@ export type AsUiSelect = AsUiComponentBase & { caption?: string; }; +export type AsUiFolder = AsUiComponentBase & { + type: 'folder'; + children?: AsUiComponent['id'][]; + title?: string; + opened?: boolean; +}; + export type AsUiPostFormButton = AsUiComponentBase & { type: 'postFormButton'; text?: string; @@ -110,7 +117,7 @@ export type AsUiPostFormButton = AsUiComponentBase & { }; }; -export type AsUiComponent = AsUiRoot | AsUiContainer | AsUiText | AsUiMfm | AsUiButton | AsUiButtons | AsUiSwitch | AsUiTextarea | AsUiTextInput | AsUiNumberInput | AsUiSelect | AsUiPostFormButton; +export type AsUiComponent = AsUiRoot | AsUiContainer | AsUiText | AsUiMfm | AsUiButton | AsUiButtons | AsUiSwitch | AsUiTextarea | AsUiTextInput | AsUiNumberInput | AsUiSelect | AsUiFolder | AsUiPostFormButton; export function patch(id: string, def: values.Value, call: (fn: values.VFn, args: values.Value[]) => Promise<values.Value>) { // TODO @@ -389,6 +396,26 @@ function getSelectOptions(def: values.Value | undefined, call: (fn: values.VFn, }; } +function getFolderOptions(def: values.Value | undefined): Omit<AsUiFolder, 'id' | 'type'> { + utils.assertObject(def); + + const children = def.value.get('children'); + if (children) utils.assertArray(children); + const title = def.value.get('title'); + if (title) utils.assertString(title); + const opened = def.value.get('opened'); + if (opened) utils.assertBoolean(opened); + + return { + children: children ? children.value.map(v => { + utils.assertObject(v); + return v.value.get('id').value; + }) : [], + title: title?.value ?? '', + opened: opened?.value ?? true, + }; +} + function getPostFormButtonOptions(def: values.Value | undefined, call: (fn: values.VFn, args: values.Value[]) => Promise<values.Value>): Omit<AsUiPostFormButton, 'id' | 'type'> { utils.assertObject(def); @@ -519,6 +546,10 @@ export function registerAsUiLib(components: Ref<AsUiComponent>[], done: (root: R return createComponentInstance('select', def, id, getSelectOptions, opts.call); }), + 'Ui:C:folder': values.FN_NATIVE(async ([def, id], opts) => { + return createComponentInstance('folder', def, id, getFolderOptions, opts.call); + }), + 'Ui:C:postFormButton': values.FN_NATIVE(async ([def, id], opts) => { return createComponentInstance('postFormButton', def, id, getPostFormButtonOptions, opts.call); }),