diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2022-01-05 00:15:53 +0900 |
|---|---|---|
| committer | tamaina <tamaina@hotmail.co.jp> | 2022-01-05 00:15:53 +0900 |
| commit | 74f1090cb014a2b9f149da542089d0e667380df6 (patch) | |
| tree | 94910a37625b11a07c1a48bcdcb189d69f7a0ff6 /packages/client/src/components | |
| parent | return reset value (diff) | |
| parent | tweak ui (diff) | |
| download | misskey-74f1090cb014a2b9f149da542089d0e667380df6.tar.gz misskey-74f1090cb014a2b9f149da542089d0e667380df6.tar.bz2 misskey-74f1090cb014a2b9f149da542089d0e667380df6.zip | |
Merge branch 'develop' into pizzax-indexeddb
Diffstat (limited to 'packages/client/src/components')
28 files changed, 305 insertions, 1736 deletions
diff --git a/packages/client/src/components/chart.vue b/packages/client/src/components/chart.vue index c4d0eb85dd..1959271f5d 100644 --- a/packages/client/src/components/chart.vue +++ b/packages/client/src/components/chart.vue @@ -170,10 +170,10 @@ export default defineComponent({ aspectRatio: props.aspectRatio || 2.5, layout: { padding: { - left: 16, - right: 16, - top: 16, - bottom: 8, + left: 0, + right: 0, + top: 0, + bottom: 0, }, }, scales: { diff --git a/packages/client/src/components/debobigego/base.vue b/packages/client/src/components/debobigego/base.vue deleted file mode 100644 index 9ed59abc69..0000000000 --- a/packages/client/src/components/debobigego/base.vue +++ /dev/null @@ -1,65 +0,0 @@ -<template> -<div v-size="{ max: [400] }" class="rbusrurv" :class="{ wide: forceWide }"> - <slot></slot> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; - -export default defineComponent({ - props: { - forceWide: { - type: Boolean, - required: false, - default: false, - } - } -}); -</script> - -<style lang="scss" scoped> -.rbusrurv { - // 他のCSSからも参照されるので消さないように - --debobigegoXPadding: 32px; - --debobigegoYPadding: 32px; - - --debobigegoContentHMargin: 16px; - - font-size: 95%; - line-height: 1.3em; - background: var(--bg); - padding: var(--debobigegoYPadding) var(--debobigegoXPadding); - max-width: 750px; - margin: 0 auto; - - &:not(.wide).max-width_400px { - --debobigegoXPadding: 0px; - - > ::v-deep(*) { - ._debobigegoPanel { - border: solid 0.5px var(--divider); - border-radius: 0; - border-left: none; - border-right: none; - } - - ._debobigego_group { - > *:not(._debobigegoNoConcat) { - &:not(:last-child):not(._debobigegoNoConcatPrev) { - &._debobigegoPanel, ._debobigegoPanel { - border-bottom: solid 0.5px var(--divider); - } - } - - &:not(:first-child):not(._debobigegoNoConcatNext) { - &._debobigegoPanel, ._debobigegoPanel { - border-top: none; - } - } - } - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/button.vue b/packages/client/src/components/debobigego/button.vue deleted file mode 100644 index b883e817a4..0000000000 --- a/packages/client/src/components/debobigego/button.vue +++ /dev/null @@ -1,81 +0,0 @@ -<template> -<div class="yzpgjkxe _debobigegoItem"> - <div class="_debobigegoLabel"><slot name="label"></slot></div> - <button class="main _button _debobigegoPanel _debobigegoClickable" :class="{ center, primary, danger }"> - <slot></slot> - <div class="suffix"> - <slot name="suffix"></slot> - <div class="icon"> - <slot name="suffixIcon"></slot> - </div> - </div> - </button> - <div class="_debobigegoCaption"><slot name="desc"></slot></div> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; -import './debobigego.scss'; - -export default defineComponent({ - props: { - primary: { - type: Boolean, - required: false, - default: false, - }, - danger: { - type: Boolean, - required: false, - default: false, - }, - disabled: { - type: Boolean, - required: false, - default: false, - }, - center: { - type: Boolean, - required: false, - default: true, - } - }, -}); -</script> - -<style lang="scss" scoped> -.yzpgjkxe { - > .main { - display: flex; - width: 100%; - box-sizing: border-box; - padding: 14px 16px; - text-align: left; - align-items: center; - - &.center { - display: block; - text-align: center; - } - - &.primary { - color: var(--accent); - } - - &.danger { - color: #ff2a2a; - } - - > .suffix { - display: inline-flex; - margin-left: auto; - opacity: 0.7; - - > .icon { - margin-left: 1em; - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/debobigego.scss b/packages/client/src/components/debobigego/debobigego.scss deleted file mode 100644 index 833b656b66..0000000000 --- a/packages/client/src/components/debobigego/debobigego.scss +++ /dev/null @@ -1,52 +0,0 @@ -._debobigegoPanel { - background: var(--panel); - border-radius: var(--radius); - transition: background 0.2s ease; - - &._debobigegoClickable { - &:hover { - //background: var(--panelHighlight); - } - - &:active { - background: var(--panelHighlight); - transition: background 0s; - } - } -} - -._debobigegoLabel, -._debobigegoCaption { - font-size: 80%; - color: var(--fgTransparentWeak); - - &:empty { - display: none; - } -} - -._debobigegoLabel { - position: sticky; - top: var(--stickyTop, 0px); - z-index: 2; - margin: -8px calc(var(--debobigegoXPadding) * -1) 0 calc(var(--debobigegoXPadding) * -1); - padding: 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding)) 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding)); - background: var(--X17); - -webkit-backdrop-filter: var(--blur, blur(10px)); - backdrop-filter: var(--blur, blur(10px)); -} - -._themeChanging_ ._debobigegoLabel { - transition: none !important; - background: transparent; -} - -._debobigegoCaption { - padding: 8px var(--debobigegoContentHMargin) 0 var(--debobigegoContentHMargin); -} - -._debobigegoItem { - & + ._debobigegoItem { - margin-top: 24px; - } -} diff --git a/packages/client/src/components/debobigego/group.vue b/packages/client/src/components/debobigego/group.vue deleted file mode 100644 index 871d3c8dba..0000000000 --- a/packages/client/src/components/debobigego/group.vue +++ /dev/null @@ -1,78 +0,0 @@ -<template> -<div v-size="{ max: [500] }" v-sticky-container class="vrtktovg _debobigegoItem _debobigegoNoConcat"> - <div class="_debobigegoLabel"><slot name="label"></slot></div> - <div ref="child" class="main _debobigego_group"> - <slot></slot> - </div> - <div class="_debobigegoCaption"><slot name="caption"></slot></div> -</div> -</template> - -<script lang="ts"> -import { defineComponent, onMounted, ref } from 'vue'; - -export default defineComponent({ - setup(props, context) { - const child = ref<HTMLElement | null>(null); - - const scanChild = () => { - if (child.value == null) return; - const els = Array.from(child.value.children); - for (let i = 0; i < els.length; i++) { - const el = els[i]; - if (el.classList.contains('_debobigegoNoConcat')) { - if (els[i - 1]) els[i - 1].classList.add('_debobigegoNoConcatPrev'); - if (els[i + 1]) els[i + 1].classList.add('_debobigegoNoConcatNext'); - } - } - }; - - onMounted(() => { - scanChild(); - - const observer = new MutationObserver(records => { - scanChild(); - }); - - observer.observe(child.value, { - childList: true, - subtree: false, - attributes: false, - characterData: false, - }); - }); - - return { - child - }; - } -}); -</script> - -<style lang="scss" scoped> -.vrtktovg { - > .main { - > ::v-deep(*):not(._debobigegoNoConcat) { - &:not(._debobigegoNoConcatNext) { - margin: 0; - } - - &:not(:last-child):not(._debobigegoNoConcatPrev) { - &._debobigegoPanel, ._debobigegoPanel { - border-bottom: solid 0.5px var(--divider); - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - } - - &:not(:first-child):not(._debobigegoNoConcatNext) { - &._debobigegoPanel, ._debobigegoPanel { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/info.vue b/packages/client/src/components/debobigego/info.vue deleted file mode 100644 index 41afb03304..0000000000 --- a/packages/client/src/components/debobigego/info.vue +++ /dev/null @@ -1,47 +0,0 @@ -<template> -<div class="fzenkabp _debobigegoItem"> - <div class="_debobigegoPanel" :class="{ warn }"> - <i v-if="warn" class="fas fa-exclamation-triangle"></i> - <i v-else class="fas fa-info-circle"></i> - <slot></slot> - </div> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; - -export default defineComponent({ - props: { - warn: { - type: Boolean, - required: false, - default: false - }, - }, - data() { - return { - }; - } -}); -</script> - -<style lang="scss" scoped> -.fzenkabp { - > div { - padding: 14px 16px; - font-size: 90%; - background: var(--infoBg); - color: var(--infoFg); - - &.warn { - background: var(--infoWarnBg); - color: var(--infoWarnFg); - } - - > i { - margin-right: 4px; - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/input.vue b/packages/client/src/components/debobigego/input.vue deleted file mode 100644 index 6228a33fe4..0000000000 --- a/packages/client/src/components/debobigego/input.vue +++ /dev/null @@ -1,292 +0,0 @@ -<template> -<FormGroup class="_debobigegoItem"> - <template #label><slot></slot></template> - <div class="ztzhwixg _debobigegoItem" :class="{ inline, disabled }"> - <div ref="icon" class="icon"><slot name="icon"></slot></div> - <div class="input _debobigegoPanel"> - <div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div> - <input ref="inputEl" - v-model="v" - :type="type" - :disabled="disabled" - :required="required" - :readonly="readonly" - :placeholder="placeholder" - :pattern="pattern" - :autocomplete="autocomplete" - :spellcheck="spellcheck" - :step="step" - :list="id" - @focus="focused = true" - @blur="focused = false" - @keydown="onKeydown($event)" - @input="onInput" - > - <datalist v-if="datalist" :id="id"> - <option v-for="data in datalist" :value="data"/> - </datalist> - <div ref="suffixEl" class="suffix"><slot name="suffix"></slot></div> - </div> - </div> - <template #caption><slot name="desc"></slot></template> - - <FormButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> -</FormGroup> -</template> - -<script lang="ts"> -import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue'; -import './debobigego.scss'; -import FormButton from './button.vue'; -import FormGroup from './group.vue'; - -export default defineComponent({ - components: { - FormGroup, - FormButton, - }, - props: { - modelValue: { - required: false - }, - type: { - type: String, - required: false - }, - required: { - type: Boolean, - required: false - }, - readonly: { - type: Boolean, - required: false - }, - disabled: { - type: Boolean, - required: false - }, - pattern: { - type: String, - required: false - }, - placeholder: { - type: String, - required: false - }, - autofocus: { - type: Boolean, - required: false, - default: false - }, - autocomplete: { - required: false - }, - spellcheck: { - required: false - }, - step: { - required: false - }, - datalist: { - type: Array, - required: false, - }, - inline: { - type: Boolean, - required: false, - default: false - }, - manualSave: { - type: Boolean, - required: false, - default: false - }, - }, - emits: ['change', 'keydown', 'enter', 'update:modelValue'], - setup(props, context) { - const { modelValue, type, autofocus } = toRefs(props); - const v = ref(modelValue.value); - const id = Math.random().toString(); // TODO: uuid? - const focused = ref(false); - const changed = ref(false); - const invalid = ref(false); - const filled = computed(() => v.value !== '' && v.value != null); - const inputEl = ref(null); - const prefixEl = ref(null); - const suffixEl = ref(null); - - const focus = () => inputEl.value.focus(); - const onInput = (ev) => { - changed.value = true; - context.emit('change', ev); - }; - const onKeydown = (ev: KeyboardEvent) => { - context.emit('keydown', ev); - - if (ev.code === 'Enter') { - context.emit('enter'); - } - }; - - const updated = () => { - changed.value = false; - if (type?.value === 'number') { - context.emit('update:modelValue', parseFloat(v.value)); - } else { - context.emit('update:modelValue', v.value); - } - }; - - watch(modelValue.value, newValue => { - v.value = newValue; - }); - - watch(v, newValue => { - if (!props.manualSave) { - updated(); - } - - invalid.value = inputEl.value.validity.badInput; - }); - - onMounted(() => { - nextTick(() => { - if (autofocus.value) { - focus(); - } - - // このコンポーネントが作成された時、非表示状態である場合がある - // 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する - const clock = setInterval(() => { - if (prefixEl.value) { - if (prefixEl.value.offsetWidth) { - inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + 'px'; - } - } - if (suffixEl.value) { - if (suffixEl.value.offsetWidth) { - inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + 'px'; - } - } - }, 100); - - onUnmounted(() => { - clearInterval(clock); - }); - }); - }); - - return { - id, - v, - focused, - invalid, - changed, - filled, - inputEl, - prefixEl, - suffixEl, - focus, - onInput, - onKeydown, - updated, - }; - }, -}); -</script> - -<style lang="scss" scoped> -.ztzhwixg { - position: relative; - - > .icon { - position: absolute; - top: 0; - left: 0; - width: 24px; - text-align: center; - line-height: 32px; - - &:not(:empty) + .input { - margin-left: 28px; - } - } - - > .input { - $height: 48px; - position: relative; - - > input { - display: block; - height: $height; - width: 100%; - margin: 0; - padding: 0 16px; - font: inherit; - font-weight: normal; - font-size: 1em; - line-height: $height; - color: var(--inputText); - background: transparent; - border: none; - border-radius: 0; - outline: none; - box-shadow: none; - box-sizing: border-box; - - &[type='file'] { - display: none; - } - } - - > .prefix, - > .suffix { - display: block; - position: absolute; - z-index: 1; - top: 0; - padding: 0 16px; - font-size: 1em; - line-height: $height; - color: var(--inputLabel); - pointer-events: none; - - &:empty { - display: none; - } - - > * { - display: inline-block; - min-width: 16px; - max-width: 150px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - } - - > .prefix { - left: 0; - padding-right: 8px; - } - - > .suffix { - right: 0; - padding-left: 8px; - } - } - - &.inline { - display: inline-block; - margin: 0; - } - - &.disabled { - opacity: 0.7; - - &, * { - cursor: not-allowed !important; - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/key-value-view.vue b/packages/client/src/components/debobigego/key-value-view.vue deleted file mode 100644 index 0e034a2d54..0000000000 --- a/packages/client/src/components/debobigego/key-value-view.vue +++ /dev/null @@ -1,38 +0,0 @@ -<template> -<div class="_debobigegoItem"> - <div class="_debobigegoPanel anocepby"> - <span class="key"><slot name="key"></slot></span> - <span class="value"><slot name="value"></slot></span> - </div> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; -import './debobigego.scss'; - -export default defineComponent({ - -}); -</script> - -<style lang="scss" scoped> -.anocepby { - display: flex; - align-items: center; - padding: 14px var(--debobigegoContentHMargin); - - > .key { - margin-right: 12px; - white-space: nowrap; - } - - > .value { - margin-left: auto; - opacity: 0.7; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } -} -</style> diff --git a/packages/client/src/components/debobigego/link.vue b/packages/client/src/components/debobigego/link.vue deleted file mode 100644 index de463465d4..0000000000 --- a/packages/client/src/components/debobigego/link.vue +++ /dev/null @@ -1,103 +0,0 @@ -<template> -<div class="qmfkfnzi _debobigegoItem"> - <a v-if="external" class="main _button _debobigegoPanel _debobigegoClickable" :href="to" target="_blank"> - <span class="icon"><slot name="icon"></slot></span> - <span class="text"><slot></slot></span> - <span class="right"> - <span class="text"><slot name="suffix"></slot></span> - <i class="fas fa-external-link-alt icon"></i> - </span> - </a> - <MkA v-else class="main _button _debobigegoPanel _debobigegoClickable" :class="{ active }" :to="to" :behavior="behavior"> - <span class="icon"><slot name="icon"></slot></span> - <span class="text"><slot></slot></span> - <span class="right"> - <span class="text"><slot name="suffix"></slot></span> - <i class="fas fa-chevron-right icon"></i> - </span> - </MkA> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; -import './debobigego.scss'; - -export default defineComponent({ - props: { - to: { - type: String, - required: true - }, - active: { - type: Boolean, - required: false - }, - external: { - type: Boolean, - required: false - }, - behavior: { - type: String, - required: false, - }, - }, - data() { - return { - }; - } -}); -</script> - -<style lang="scss" scoped> -.qmfkfnzi { - > .main { - display: flex; - align-items: center; - width: 100%; - box-sizing: border-box; - padding: 14px 16px 14px 14px; - - &:hover { - text-decoration: none; - } - - &.active { - color: var(--accent); - background: var(--panelHighlight); - } - - > .icon { - width: 32px; - margin-right: 2px; - flex-shrink: 0; - text-align: center; - opacity: 0.8; - - &:empty { - display: none; - - & + .text { - padding-left: 4px; - } - } - } - - > .text { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - padding-right: 12px; - } - - > .right { - margin-left: auto; - opacity: 0.7; - - > .text:not(:empty) { - margin-right: 0.75em; - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/object-view.vue b/packages/client/src/components/debobigego/object-view.vue deleted file mode 100644 index 68be08560b..0000000000 --- a/packages/client/src/components/debobigego/object-view.vue +++ /dev/null @@ -1,102 +0,0 @@ -<template> -<FormGroup class="_debobigegoItem"> - <template #label><slot></slot></template> - <div class="drooglns _debobigegoItem" :class="{ tall }"> - <div class="input _debobigegoPanel"> - <textarea v-model="v" - class="_monospace" - readonly - :spellcheck="false" - ></textarea> - </div> - </div> - <template #caption><slot name="desc"></slot></template> -</FormGroup> -</template> - -<script lang="ts"> -import { defineComponent, ref, toRefs, watch } from 'vue'; -import * as JSON5 from 'json5'; -import './debobigego.scss'; -import FormGroup from './group.vue'; - -export default defineComponent({ - components: { - FormGroup, - }, - props: { - value: { - required: false - }, - tall: { - type: Boolean, - required: false, - default: false - }, - pre: { - type: Boolean, - required: false, - default: false - }, - manualSave: { - type: Boolean, - required: false, - default: false - }, - }, - setup(props, context) { - const { value } = toRefs(props); - const v = ref(''); - - watch(() => value, newValue => { - v.value = JSON5.stringify(newValue.value, null, '\t'); - }, { - immediate: true - }); - - return { - v, - }; - } -}); -</script> - -<style lang="scss" scoped> -.drooglns { - position: relative; - - > .input { - position: relative; - - > textarea { - display: block; - width: 100%; - min-width: 100%; - max-width: 100%; - min-height: 130px; - margin: 0; - padding: 16px var(--debobigegoContentHMargin); - box-sizing: border-box; - font: inherit; - font-weight: normal; - font-size: 1em; - background: transparent; - border: none; - border-radius: 0; - outline: none; - box-shadow: none; - color: var(--fg); - tab-size: 2; - white-space: pre; - } - } - - &.tall { - > .input { - > textarea { - min-height: 200px; - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/pagination.vue b/packages/client/src/components/debobigego/pagination.vue deleted file mode 100644 index 16779caa42..0000000000 --- a/packages/client/src/components/debobigego/pagination.vue +++ /dev/null @@ -1,42 +0,0 @@ -<template> -<FormGroup class="uljviswt _debobigegoItem"> - <template #label><slot name="label"></slot></template> - <slot :items="items"></slot> - <div v-if="empty" key="_empty_" class="empty"> - <slot name="empty"></slot> - </div> - <FormButton v-show="more" class="button" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary @click="fetchMore"> - <template v-if="!moreFetching">{{ $ts.loadMore }}</template> - <template v-if="moreFetching"><MkLoading inline/></template> - </FormButton> -</FormGroup> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; -import FormButton from './button.vue'; -import FormGroup from './group.vue'; -import paging from '@/scripts/paging'; - -export default defineComponent({ - components: { - FormButton, - FormGroup, - }, - - mixins: [ - paging({}), - ], - - props: { - pagination: { - required: true - }, - }, -}); -</script> - -<style lang="scss" scoped> -.uljviswt { -} -</style> diff --git a/packages/client/src/components/debobigego/radios.vue b/packages/client/src/components/debobigego/radios.vue deleted file mode 100644 index b4c5841337..0000000000 --- a/packages/client/src/components/debobigego/radios.vue +++ /dev/null @@ -1,112 +0,0 @@ -<script lang="ts"> -import { defineComponent, h } from 'vue'; -import MkRadio from '@/components/form/radio.vue'; -import './debobigego.scss'; - -export default defineComponent({ - components: { - MkRadio - }, - props: { - modelValue: { - required: false - }, - }, - data() { - return { - value: this.modelValue, - } - }, - watch: { - modelValue() { - this.value = this.modelValue; - }, - value() { - this.$emit('update:modelValue', this.value); - } - }, - render() { - const label = this.$slots.desc(); - let options = this.$slots.default(); - - // なぜかFragmentになることがあるため - if (options.length === 1 && options[0].props == null) options = options[0].children; - - return h('div', { - class: 'cnklmpwm _debobigegoItem' - }, [ - h('div', { - class: '_debobigegoLabel', - }, label), - ...options.map(option => h('button', { - class: '_button _debobigegoPanel _debobigegoClickable', - key: option.key, - onClick: () => this.value = option.props.value, - }, [h('span', { - class: ['check', { checked: this.value === option.props.value }], - }), option.children])) - ]); - } -}); -</script> - -<style lang="scss"> -.cnklmpwm { - > button { - display: block; - width: 100%; - box-sizing: border-box; - padding: 14px 18px; - text-align: left; - - &:not(:first-of-type) { - border-top: none !important; - border-top-left-radius: 0; - border-top-right-radius: 0; - } - - &:not(:last-of-type) { - border-bottom: solid 0.5px var(--divider); - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - - > .check { - display: inline-block; - vertical-align: bottom; - position: relative; - width: 16px; - height: 16px; - margin-right: 8px; - background: none; - border: 2px solid var(--inputBorder); - border-radius: 100%; - transition: inherit; - - &:after { - content: ""; - display: block; - position: absolute; - top: 3px; - right: 3px; - bottom: 3px; - left: 3px; - border-radius: 100%; - opacity: 0; - transform: scale(0); - transition: .4s cubic-bezier(.25,.8,.25,1); - } - - &.checked { - border-color: var(--accent); - - &:after { - background-color: var(--accent); - transform: scale(1); - opacity: 1; - } - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/range.vue b/packages/client/src/components/debobigego/range.vue deleted file mode 100644 index dc71f25d83..0000000000 --- a/packages/client/src/components/debobigego/range.vue +++ /dev/null @@ -1,122 +0,0 @@ -<template> -<div class="ifitouly _debobigegoItem" :class="{ focused, disabled }"> - <div class="_debobigegoLabel"><slot name="label"></slot></div> - <div class="_debobigegoPanel main"> - <input - ref="input" - v-model="v" - type="range" - :disabled="disabled" - :min="min" - :max="max" - :step="step" - @focus="focused = true" - @blur="focused = false" - @input="$emit('update:value', $event.target.value)" - /> - </div> - <div class="_debobigegoCaption"><slot name="caption"></slot></div> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; - -export default defineComponent({ - props: { - value: { - type: Number, - required: false, - default: 0 - }, - disabled: { - type: Boolean, - required: false, - default: false - }, - min: { - type: Number, - required: false, - default: 0 - }, - max: { - type: Number, - required: false, - default: 100 - }, - step: { - type: Number, - required: false, - default: 1 - }, - }, - data() { - return { - v: this.value, - focused: false - }; - }, - watch: { - value(v) { - this.v = parseFloat(v); - } - }, -}); -</script> - -<style lang="scss" scoped> -.ifitouly { - position: relative; - - > .main { - padding: 22px 16px; - - > input { - display: block; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background: var(--X10); - height: 4px; - width: 100%; - box-sizing: border-box; - margin: 0; - outline: 0; - border: 0; - border-radius: 7px; - - &.disabled { - opacity: 0.6; - cursor: not-allowed; - } - - &::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - cursor: pointer; - width: 20px; - height: 20px; - display: block; - border-radius: 50%; - border: none; - background: var(--accent); - box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); - box-sizing: content-box; - } - - &::-moz-range-thumb { - -moz-appearance: none; - appearance: none; - cursor: pointer; - width: 20px; - height: 20px; - display: block; - border-radius: 50%; - border: none; - background: var(--accent); - box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/select.vue b/packages/client/src/components/debobigego/select.vue deleted file mode 100644 index 081bbfe302..0000000000 --- a/packages/client/src/components/debobigego/select.vue +++ /dev/null @@ -1,145 +0,0 @@ -<template> -<div class="yrtfrpux _debobigegoItem" :class="{ disabled, inline }"> - <div class="_debobigegoLabel"><slot name="label"></slot></div> - <div ref="icon" class="icon"><slot name="icon"></slot></div> - <div class="input _debobigegoPanel _debobigegoClickable" @click="focus"> - <div ref="prefix" class="prefix"><slot name="prefix"></slot></div> - <select ref="input" - v-model="v" - :required="required" - :disabled="disabled" - @focus="focused = true" - @blur="focused = false" - > - <slot></slot> - </select> - <div class="suffix"> - <i class="fas fa-chevron-down"></i> - </div> - </div> - <div class="_debobigegoCaption"><slot name="caption"></slot></div> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; -import './debobigego.scss'; - -export default defineComponent({ - props: { - modelValue: { - required: false - }, - required: { - type: Boolean, - required: false - }, - disabled: { - type: Boolean, - required: false - }, - inline: { - type: Boolean, - required: false, - default: false - }, - }, - data() { - return { - }; - }, - computed: { - v: { - get() { - return this.modelValue; - }, - set(v) { - this.$emit('update:modelValue', v); - } - }, - }, - methods: { - focus() { - this.$refs.input.focus(); - } - } -}); -</script> - -<style lang="scss" scoped> -.yrtfrpux { - position: relative; - - > .icon { - position: absolute; - top: 0; - left: 0; - width: 24px; - text-align: center; - line-height: 32px; - - &:not(:empty) + .input { - margin-left: 28px; - } - } - - > .input { - display: flex; - position: relative; - - > select { - display: block; - flex: 1; - width: 100%; - padding: 0 16px; - font: inherit; - font-weight: normal; - font-size: 1em; - height: 48px; - background: none; - border: none; - border-radius: 0; - outline: none; - box-shadow: none; - appearance: none; - -webkit-appearance: none; - color: var(--fg); - - option, - optgroup { - color: var(--fg); - background: var(--bg); - } - } - - > .prefix, - > .suffix { - display: block; - align-self: center; - justify-self: center; - font-size: 1em; - line-height: 32px; - color: var(--inputLabel); - pointer-events: none; - - &:empty { - display: none; - } - - > * { - display: block; - min-width: 16px; - } - } - - > .prefix { - padding-right: 4px; - } - - > .suffix { - padding: 0 16px 0 0; - opacity: 0.7; - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/suspense.vue b/packages/client/src/components/debobigego/suspense.vue deleted file mode 100644 index acb0b64424..0000000000 --- a/packages/client/src/components/debobigego/suspense.vue +++ /dev/null @@ -1,101 +0,0 @@ -<template> -<transition name="fade" mode="out-in"> - <div v-if="pending" class="_debobigegoItem"> - <div class="_debobigegoPanel"> - <MkLoading/> - </div> - </div> - <div v-else-if="resolved" class="_debobigegoItem"> - <slot :result="result"></slot> - </div> - <div v-else class="_debobigegoItem"> - <div class="_debobigegoPanel eiurkvay"> - <div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div> - <MkButton inline class="retry" @click="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton> - </div> - </div> -</transition> -</template> - -<script lang="ts"> -import { defineComponent, PropType, ref, watch } from 'vue'; -import './debobigego.scss'; -import MkButton from '@/components/ui/button.vue'; - -export default defineComponent({ - components: { - MkButton - }, - - props: { - p: { - type: Function as PropType<() => Promise<any>>, - required: true, - } - }, - - setup(props, context) { - const pending = ref(true); - const resolved = ref(false); - const rejected = ref(false); - const result = ref(null); - - const process = () => { - if (props.p == null) { - return; - } - const promise = props.p(); - pending.value = true; - resolved.value = false; - rejected.value = false; - promise.then((_result) => { - pending.value = false; - resolved.value = true; - result.value = _result; - }); - promise.catch(() => { - pending.value = false; - rejected.value = true; - }); - }; - - watch(() => props.p, () => { - process(); - }, { - immediate: true - }); - - const retry = () => { - process(); - }; - - return { - pending, - resolved, - rejected, - result, - retry, - }; - } -}); -</script> - -<style lang="scss" scoped> -.fade-enter-active, -.fade-leave-active { - transition: opacity 0.125s ease; -} -.fade-enter-from, -.fade-leave-to { - opacity: 0; -} - -.eiurkvay { - padding: 16px; - text-align: center; - - > .retry { - margin-top: 16px; - } -} -</style> diff --git a/packages/client/src/components/debobigego/switch.vue b/packages/client/src/components/debobigego/switch.vue deleted file mode 100644 index 239140f730..0000000000 --- a/packages/client/src/components/debobigego/switch.vue +++ /dev/null @@ -1,132 +0,0 @@ -<template> -<div class="ijnpvmgr _debobigegoItem"> - <div class="main _debobigegoPanel _debobigegoClickable" - :class="{ disabled, checked }" - :aria-checked="checked" - :aria-disabled="disabled" - @click.prevent="toggle" - > - <input - ref="input" - type="checkbox" - :disabled="disabled" - @keydown.enter="toggle" - > - <span v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button"> - <span class="handle"></span> - </span> - <span class="label"> - <span><slot></slot></span> - </span> - </div> - <div class="_debobigegoCaption"><slot name="desc"></slot></div> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; -import './debobigego.scss'; - -export default defineComponent({ - props: { - modelValue: { - type: Boolean, - default: false - }, - disabled: { - type: Boolean, - default: false - } - }, - computed: { - checked(): boolean { - return this.modelValue; - } - }, - methods: { - toggle() { - if (this.disabled) return; - this.$emit('update:modelValue', !this.checked); - } - } -}); -</script> - -<style lang="scss" scoped> -.ijnpvmgr { - > .main { - position: relative; - display: flex; - padding: 14px 16px; - cursor: pointer; - - > * { - user-select: none; - } - - > input { - position: absolute; - width: 0; - height: 0; - opacity: 0; - margin: 0; - } - - > .button { - position: relative; - display: inline-block; - flex-shrink: 0; - margin: 0; - width: 34px; - height: 22px; - background: var(--switchBg); - outline: none; - border-radius: 999px; - transition: all 0.3s; - cursor: pointer; - - > .handle { - position: absolute; - top: 0; - left: 3px; - bottom: 0; - margin: auto 0; - border-radius: 100%; - transition: background-color 0.3s, transform 0.3s; - width: 16px; - height: 16px; - background-color: #fff; - pointer-events: none; - } - } - - > .label { - margin-left: 12px; - display: block; - transition: inherit; - color: var(--fg); - - > span { - display: block; - line-height: 20px; - transition: inherit; - } - } - - &.disabled { - opacity: 0.6; - cursor: not-allowed; - } - - &.checked { - > .button { - background-color: var(--accent); - - > .handle { - transform: translateX(12px); - } - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/textarea.vue b/packages/client/src/components/debobigego/textarea.vue deleted file mode 100644 index ca5b35c49e..0000000000 --- a/packages/client/src/components/debobigego/textarea.vue +++ /dev/null @@ -1,161 +0,0 @@ -<template> -<FormGroup class="_debobigegoItem"> - <template #label><slot></slot></template> - <div class="rivhosbp _debobigegoItem" :class="{ tall, pre }"> - <div class="input _debobigegoPanel"> - <textarea ref="input" v-model="v" - :class="{ code, _monospace: code }" - :required="required" - :readonly="readonly" - :pattern="pattern" - :autocomplete="autocomplete" - :spellcheck="!code" - @input="onInput" - @focus="focused = true" - @blur="focused = false" - ></textarea> - </div> - </div> - <template #caption><slot name="desc"></slot></template> - - <FormButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> -</FormGroup> -</template> - -<script lang="ts"> -import { defineComponent, ref, toRefs, watch } from 'vue'; -import './debobigego.scss'; -import FormButton from './button.vue'; -import FormGroup from './group.vue'; - -export default defineComponent({ - components: { - FormGroup, - FormButton, - }, - props: { - modelValue: { - required: false - }, - required: { - type: Boolean, - required: false - }, - readonly: { - type: Boolean, - required: false - }, - pattern: { - type: String, - required: false - }, - autocomplete: { - type: String, - required: false - }, - code: { - type: Boolean, - required: false - }, - tall: { - type: Boolean, - required: false, - default: false - }, - pre: { - type: Boolean, - required: false, - default: false - }, - manualSave: { - type: Boolean, - required: false, - default: false - }, - }, - setup(props, context) { - const { modelValue } = toRefs(props); - const v = ref(modelValue.value); - const changed = ref(false); - const inputEl = ref(null); - const focus = () => inputEl.value.focus(); - const onInput = (ev) => { - changed.value = true; - context.emit('change', ev); - }; - - const updated = () => { - changed.value = false; - context.emit('update:modelValue', v.value); - }; - - watch(modelValue.value, newValue => { - v.value = newValue; - }); - - watch(v, newValue => { - if (!props.manualSave) { - updated(); - } - }); - - return { - v, - updated, - changed, - focus, - onInput, - }; - } -}); -</script> - -<style lang="scss" scoped> -.rivhosbp { - position: relative; - - > .input { - position: relative; - - > textarea { - display: block; - width: 100%; - min-width: 100%; - max-width: 100%; - min-height: 130px; - margin: 0; - padding: 16px; - box-sizing: border-box; - font: inherit; - font-weight: normal; - font-size: 1em; - background: transparent; - border: none; - border-radius: 0; - outline: none; - box-shadow: none; - color: var(--fg); - - &.code { - tab-size: 2; - } - } - } - - &.tall { - > .input { - > textarea { - min-height: 200px; - } - } - } - - &.pre { - > .input { - > textarea { - white-space: pre; - } - } - } -} -</style> diff --git a/packages/client/src/components/debobigego/tuple.vue b/packages/client/src/components/debobigego/tuple.vue deleted file mode 100644 index 1d2a6cb55e..0000000000 --- a/packages/client/src/components/debobigego/tuple.vue +++ /dev/null @@ -1,36 +0,0 @@ -<template> -<div v-size="{ max: [500] }" class="wthhikgt _debobigegoItem"> - <slot></slot> -</div> -</template> - -<script lang="ts"> -import { defineComponent } from 'vue'; - -export default defineComponent({ -}); -</script> - -<style lang="scss" scoped> -.wthhikgt { - position: relative; - display: flex; - - > ::v-deep(*) { - flex: 1; - margin: 0; - - &:not(:last-child) { - margin-right: 16px; - } - } - - &.max-width_500px { - display: block; - - > ::v-deep(*) { - margin: inherit; - } - } -} -</style> diff --git a/packages/client/src/components/form/folder.vue b/packages/client/src/components/form/folder.vue new file mode 100644 index 0000000000..571afe50c0 --- /dev/null +++ b/packages/client/src/components/form/folder.vue @@ -0,0 +1,107 @@ +<template> +<div class="dwzlatin" :class="{ opened }"> + <div class="header _button" @click="toggle"> + <span class="icon"><slot name="icon"></slot></span> + <span class="text"><slot name="label"></slot></span> + <span class="right"> + <span class="text"><slot name="suffix"></slot></span> + <i v-if="opened" class="fas fa-angle-up icon"></i> + <i v-else class="fas fa-angle-down icon"></i> + </span> + </div> + <keep-alive> + <div v-if="openedAtLeastOnce" v-show="opened" class="body"> + <MkSpacer :margin-min="14" :margin-max="22"> + <slot></slot> + </MkSpacer> + </div> + </keep-alive> +</div> +</template> + +<script lang="ts" setup> +const props = withDefaults(defineProps<{ + defaultOpen: boolean; +}>(), { + defaultOpen: false, +}) + +let opened = $ref(props.defaultOpen); +let openedAtLeastOnce = $ref(props.defaultOpen); + +const toggle = () => { + opened = !opened; + if (opened) { + openedAtLeastOnce = true; + } +}; +</script> + +<style lang="scss" scoped> +.dwzlatin { + display: block; + + > .header { + display: flex; + align-items: center; + width: 100%; + box-sizing: border-box; + padding: 12px 14px 12px 14px; + background: var(--buttonBg); + border-radius: 6px; + + &:hover { + text-decoration: none; + background: var(--buttonHoverBg); + } + + &.active { + color: var(--accent); + background: var(--buttonHoverBg); + } + + > .icon { + margin-right: 0.75em; + flex-shrink: 0; + text-align: center; + opacity: 0.8; + + &:empty { + display: none; + + & + .text { + padding-left: 4px; + } + } + } + + > .text { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 12px; + } + + > .right { + margin-left: auto; + opacity: 0.7; + white-space: nowrap; + + > .text:not(:empty) { + margin-right: 0.75em; + } + } + } + + > .body { + background: var(--panel); + border-radius: 0 0 6px 6px; + } + + &.opened { + > .header { + border-radius: 6px 6px 0 0; + } + } +} +</style> diff --git a/packages/client/src/components/form/group.vue b/packages/client/src/components/form/group.vue index 2fc203f1b9..1e8376ca44 100644 --- a/packages/client/src/components/form/group.vue +++ b/packages/client/src/components/form/group.vue @@ -1,5 +1,5 @@ <template> -<div v-sticky-container v-panel class="adfeebaf _formBlock"> +<div v-sticky-container class="adfeebaf _formBlock"> <div class="label"><slot name="label"></slot></div> <div class="main _formRoot"> <slot></slot> @@ -17,6 +17,7 @@ export default defineComponent({ <style lang="scss" scoped> .adfeebaf { padding: 24px 24px; + border: solid 1px var(--divider); border-radius: var(--radius); > .label { diff --git a/packages/client/src/components/form/radio.vue b/packages/client/src/components/form/radio.vue index f0b8c71376..2becbec6f3 100644 --- a/packages/client/src/components/form/radio.vue +++ b/packages/client/src/components/form/radio.vue @@ -1,6 +1,6 @@ <template> <div - v-panel + v-adaptive-border class="novjtctn" :class="{ disabled, checked }" :aria-checked="checked" @@ -53,7 +53,10 @@ export default defineComponent({ display: inline-block; text-align: left; cursor: pointer; - padding: 11px 14px; + padding: 10px 12px; + background-color: var(--panel); + background-clip: padding-box !important; + border: solid 1px var(--panel); border-radius: 6px; transition: all 0.3s; @@ -69,9 +72,13 @@ export default defineComponent({ } } + &:hover { + border-color: var(--inputBorderHover) !important; + } + &.checked { - background: var(--accentedBg) !important; - border-color: var(--accent); + background-color: var(--accentedBg) !important; + border-color: var(--accentedBg) !important; color: var(--accent); &, * { @@ -89,11 +96,6 @@ export default defineComponent({ } } - &:hover { - border-color: var(--inputBorderHover); - color: var(--accent); - } - > input { position: absolute; width: 0; diff --git a/packages/client/src/components/form/section.vue b/packages/client/src/components/form/section.vue index ab9fbe5fcd..c6e34ef1cc 100644 --- a/packages/client/src/components/form/section.vue +++ b/packages/client/src/components/form/section.vue @@ -1,5 +1,5 @@ <template> -<div v-size="{ max: [500] }" v-sticky-container class="vrtktovh _formBlock"> +<div class="vrtktovh _formBlock"> <div class="label"><slot name="label"></slot></div> <div class="main _formRoot"> <slot></slot> @@ -12,10 +12,8 @@ <style lang="scss" scoped> .vrtktovh { - margin: 0; border-top: solid 0.5px var(--divider); border-bottom: solid 0.5px var(--divider); - padding: 24px 0; & + .vrtktovh { border-top: none; @@ -31,7 +29,7 @@ > .label { font-weight: bold; - padding: 0 0 16px 0; + margin: 1.5em 0 16px 0; &:empty { display: none; @@ -39,6 +37,7 @@ } > .main { + margin: 1.5em 0; } } </style> diff --git a/packages/client/src/components/form/switch.vue b/packages/client/src/components/form/switch.vue index ac3284e7da..f8a07b4caa 100644 --- a/packages/client/src/components/form/switch.vue +++ b/packages/client/src/components/form/switch.vue @@ -111,7 +111,7 @@ export default defineComponent({ } > .label { - margin-left: 16px; + margin-left: 12px; margin-top: 2px; display: block; transition: inherit; diff --git a/packages/client/src/components/global/spacer.vue b/packages/client/src/components/global/spacer.vue index e2f1d1aec7..8a1d7a4e8a 100644 --- a/packages/client/src/components/global/spacer.vue +++ b/packages/client/src/components/global/spacer.vue @@ -40,7 +40,7 @@ export default defineComponent({ return; } - if (rect.width > props.contentMax || rect.width > 500) { + if (rect.width > props.contentMax || (rect.width > 360 && window.innerWidth > 400)) { margin.value = props.marginMax; } else { margin.value = props.marginMin; diff --git a/packages/client/src/components/instance-stats.vue b/packages/client/src/components/instance-stats.vue index bc62998a4a..409c3a49ca 100644 --- a/packages/client/src/components/instance-stats.vue +++ b/packages/client/src/components/instance-stats.vue @@ -1,5 +1,5 @@ <template> -<div class="zbcjwnqg" style="margin-top: -8px;"> +<div class="zbcjwnqg"> <div class="selects" style="display: flex;"> <MkSelect v-model="chartSrc" style="margin: 0; flex: 1;"> <optgroup :label="$ts.federation"> @@ -29,16 +29,16 @@ <option value="day">{{ $ts.perDay }}</option> </MkSelect> </div> - <MkChart :src="chartSrc" :span="chartSpan" :limit="chartLimit" :detailed="detailed"></MkChart> + <div class="chart"> + <MkChart :src="chartSrc" :span="chartSpan" :limit="chartLimit" :detailed="detailed"></MkChart> + </div> </div> </template> <script lang="ts"> -import { defineComponent, onMounted, ref, watch } from 'vue'; +import { defineComponent, ref } from 'vue'; import MkSelect from '@/components/form/select.vue'; import MkChart from '@/components/chart.vue'; -import * as os from '@/os'; -import { defaultStore } from '@/store'; export default defineComponent({ components: { @@ -74,7 +74,10 @@ export default defineComponent({ <style lang="scss" scoped> .zbcjwnqg { > .selects { - padding: 8px 16px 0 16px; + } + + > .chart { + padding: 8px 0 0 0; } } </style> diff --git a/packages/client/src/components/key-value.vue b/packages/client/src/components/key-value.vue index 6a9a948ce9..da98abd77c 100644 --- a/packages/client/src/components/key-value.vue +++ b/packages/client/src/components/key-value.vue @@ -1,5 +1,5 @@ <template> -<div class="alqyeyti"> +<div class="alqyeyti" :class="{ oneline }"> <div class="key"> <slot name="key"></slot> </div> @@ -22,6 +22,11 @@ export default defineComponent({ required: false, default: null, }, + oneline: { + type: Boolean, + required: false, + default: false, + }, }, setup(props) { @@ -39,10 +44,30 @@ export default defineComponent({ <style lang="scss" scoped> .alqyeyti { + > .key, > .value { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + > .key { font-size: 0.85em; padding: 0 0 0.25em 0; opacity: 0.75; } + + &.oneline { + display: flex; + + > .key { + width: 30%; + font-size: 1em; + padding: 0 8px 0 0; + } + + > .value { + width: 70%; + } + } } </style> diff --git a/packages/client/src/components/object-view.value.vue b/packages/client/src/components/object-view.value.vue new file mode 100644 index 0000000000..6f388636dd --- /dev/null +++ b/packages/client/src/components/object-view.value.vue @@ -0,0 +1,108 @@ +<template> +<div class="igpposuu _monospace"> + <div v-if="value === null" class="null">null</div> + <div v-else-if="typeof value === 'boolean'" class="boolean">{{ value ? 'true' : 'false' }}</div> + <div v-else-if="typeof value === 'string'" class="string">"{{ value }}"</div> + <div v-else-if="typeof value === 'number'" class="number">{{ number(value) }}</div> + <div v-else-if="Array.isArray(value)" class="array"> + <button @click="collapsed_ = !collapsed_">[ {{ collapsed_ ? '+' : '-' }} ]</button> + <template v-if="!collapsed_"> + <div v-for="i in value.length" class="element"> + {{ i }}: <XValue :value="value[i - 1]" collapsed/> + </div> + </template> + </div> + <div v-else-if="typeof value === 'object'" class="object"> + <button @click="collapsed_ = !collapsed_">{ {{ collapsed_ ? '+' : '-' }} }</button> + <template v-if="!collapsed_"> + <div v-for="k in Object.keys(value)" class="kv"> + <div class="k">{{ k }}:</div> + <div class="v"><XValue :value="value[k]" collapsed/></div> + </div> + </template> + </div> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent, ref } from 'vue'; +import number from '@/filters/number'; + +export default defineComponent({ + name: 'XValue', + + props: { + value: { + type: Object, + required: true, + }, + collapsed: { + type: Boolean, + required: false, + default: false, + }, + }, + + setup(props) { + const collapsed_ = ref(props.collapsed); + + return { + number, + collapsed_, + }; + } +}); +</script> + +<style lang="scss" scoped> +.igpposuu { + display: inline; + + > .null { + display: inline; + opacity: 0.7; + } + + > .boolean { + display: inline; + color: var(--codeBoolean); + } + + > .string { + display: inline; + color: var(--codeString); + } + + > .number { + display: inline; + color: var(--codeNumber); + } + + > .array { + display: inline; + + > .element { + display: block; + padding-left: 16px; + } + } + + > .object { + display: inline; + + > .kv { + display: block; + padding-left: 16px; + + > .k { + display: inline; + margin-right: 8px; + } + + > .v { + display: inline; + } + } + } +} +</style> diff --git a/packages/client/src/components/object-view.vue b/packages/client/src/components/object-view.vue new file mode 100644 index 0000000000..e9db96de8c --- /dev/null +++ b/packages/client/src/components/object-view.vue @@ -0,0 +1,33 @@ +<template> +<div class="zhyxdalp"> + <XValue :value="value" :collapsed="false"/> +</div> +</template> + +<script lang="ts"> +import { computed, defineComponent } from 'vue'; +import XValue from './object-view.value.vue'; + +export default defineComponent({ + components: { + XValue + }, + + props: { + value: { + type: Object, + required: true, + }, + }, + + setup(props) { + + } +}); +</script> + +<style lang="scss" scoped> +.zhyxdalp { + +} +</style> |