summaryrefslogtreecommitdiff
path: root/packages/client/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-01-04 22:42:04 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2022-01-04 22:42:04 +0900
commit69d7cfc5ce2ec9892290403cdc353e7ea3bd6a96 (patch)
tree640d987389f3d56ab9270ca150c0e5e213d92947 /packages/client/src
parenttweak ui (diff)
downloadsharkey-69d7cfc5ce2ec9892290403cdc353e7ea3bd6a96.tar.gz
sharkey-69d7cfc5ce2ec9892290403cdc353e7ea3bd6a96.tar.bz2
sharkey-69d7cfc5ce2ec9892290403cdc353e7ea3bd6a96.zip
tweak ui
Diffstat (limited to 'packages/client/src')
-rw-r--r--packages/client/src/components/debobigego/base.vue65
-rw-r--r--packages/client/src/components/debobigego/button.vue81
-rw-r--r--packages/client/src/components/debobigego/debobigego.scss52
-rw-r--r--packages/client/src/components/debobigego/group.vue78
-rw-r--r--packages/client/src/components/debobigego/info.vue47
-rw-r--r--packages/client/src/components/debobigego/input.vue292
-rw-r--r--packages/client/src/components/debobigego/key-value-view.vue38
-rw-r--r--packages/client/src/components/debobigego/link.vue103
-rw-r--r--packages/client/src/components/debobigego/object-view.vue102
-rw-r--r--packages/client/src/components/debobigego/pagination.vue42
-rw-r--r--packages/client/src/components/debobigego/radios.vue112
-rw-r--r--packages/client/src/components/debobigego/range.vue122
-rw-r--r--packages/client/src/components/debobigego/select.vue145
-rw-r--r--packages/client/src/components/debobigego/suspense.vue101
-rw-r--r--packages/client/src/components/debobigego/switch.vue132
-rw-r--r--packages/client/src/components/debobigego/textarea.vue161
-rw-r--r--packages/client/src/components/debobigego/tuple.vue36
-rw-r--r--packages/client/src/components/form/folder.vue10
-rw-r--r--packages/client/src/components/object-view.vue29
-rw-r--r--packages/client/src/pages/admin/database.vue2
-rw-r--r--packages/client/src/pages/gallery/edit.vue23
-rw-r--r--packages/client/src/pages/instance-info.vue9
-rw-r--r--packages/client/src/pages/theme-editor.vue208
-rw-r--r--packages/client/src/pages/user-info.vue9
24 files changed, 164 insertions, 1835 deletions
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
index fe12202014..571afe50c0 100644
--- a/packages/client/src/components/form/folder.vue
+++ b/packages/client/src/components/form/folder.vue
@@ -20,8 +20,14 @@
</template>
<script lang="ts" setup>
-let opened = $ref(false);
-let openedAtLeastOnce = $ref(false);
+const props = withDefaults(defineProps<{
+ defaultOpen: boolean;
+}>(), {
+ defaultOpen: false,
+})
+
+let opened = $ref(props.defaultOpen);
+let openedAtLeastOnce = $ref(props.defaultOpen);
const toggle = () => {
opened = !opened;
diff --git a/packages/client/src/components/object-view.vue b/packages/client/src/components/object-view.vue
new file mode 100644
index 0000000000..4334917e6b
--- /dev/null
+++ b/packages/client/src/components/object-view.vue
@@ -0,0 +1,29 @@
+<template>
+<div class="zhyxdalp">
+
+</div>
+</template>
+
+<script lang="ts">
+import { computed, defineComponent } from 'vue';
+import number from '@/filters/number';
+
+export default defineComponent({
+ props: {
+ value: {
+ type: Object,
+ required: true,
+ },
+ },
+
+ setup(props) {
+
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.zhyxdalp {
+
+}
+</style>
diff --git a/packages/client/src/pages/admin/database.vue b/packages/client/src/pages/admin/database.vue
index fc9a3e9690..c1088afd77 100644
--- a/packages/client/src/pages/admin/database.vue
+++ b/packages/client/src/pages/admin/database.vue
@@ -1,5 +1,5 @@
<template>
-<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
+<MkSpacer :content-max="800" :margin-min="16" :margin-max="32">
<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
<template #key>{{ table[0] }}</template>
diff --git a/packages/client/src/pages/gallery/edit.vue b/packages/client/src/pages/gallery/edit.vue
index caca6aed4b..d317da038f 100644
--- a/packages/client/src/pages/gallery/edit.vue
+++ b/packages/client/src/pages/gallery/edit.vue
@@ -1,12 +1,12 @@
<template>
-<FormBase>
+<div>
<FormSuspense :p="init">
<FormInput v-model="title">
- <span>{{ $ts.title }}</span>
+ <template #label>{{ $ts.title }}</template>
</FormInput>
<FormTextarea v-model="description" :max="500">
- <span>{{ $ts.description }}</span>
+ <template #label>{{ $ts.description }}</template>
</FormTextarea>
<FormGroup>
@@ -24,19 +24,17 @@
<FormButton v-if="postId" danger @click="del"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</FormButton>
</FormSuspense>
-</FormBase>
+</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import FormButton from '@/components/debobigego/button.vue';
-import FormInput from '@/components/debobigego/input.vue';
-import FormTextarea from '@/components/debobigego/textarea.vue';
-import FormSwitch from '@/components/debobigego/switch.vue';
-import FormTuple from '@/components/debobigego/tuple.vue';
-import FormBase from '@/components/debobigego/base.vue';
-import FormGroup from '@/components/debobigego/group.vue';
-import FormSuspense from '@/components/debobigego/suspense.vue';
+import FormButton from '@/components/ui/button.vue';
+import FormInput from '@/components/form/input.vue';
+import FormTextarea from '@/components/form/textarea.vue';
+import FormSwitch from '@/components/form/switch.vue';
+import FormGroup from '@/components/form/group.vue';
+import FormSuspense from '@/components/form/suspense.vue';
import { selectFiles } from '@/scripts/select-file';
import * as os from '@/os';
import * as symbols from '@/symbols';
@@ -47,7 +45,6 @@ export default defineComponent({
FormInput,
FormTextarea,
FormSwitch,
- FormBase,
FormGroup,
FormSuspense,
},
diff --git a/packages/client/src/pages/instance-info.vue b/packages/client/src/pages/instance-info.vue
index d6d72f6601..475107ab6d 100644
--- a/packages/client/src/pages/instance-info.vue
+++ b/packages/client/src/pages/instance-info.vue
@@ -89,9 +89,8 @@
</div>
</FormSection>
- <FormObjectView tall :value="instance">
- <span>Raw</span>
- </FormObjectView>
+ <MkObjectView tall :value="instance">
+ </MkObjectView>
<FormSection>
<template #label>Well-known resources</template>
@@ -108,7 +107,7 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
import MkChart from '@/components/chart.vue';
-import FormObjectView from '@/components/debobigego/object-view.vue';
+import MkObjectView from '@/components/object-view.vue';
import FormTextarea from '@/components/form/textarea.vue';
import FormLink from '@/components/form/link.vue';
import MkLink from '@/components/link.vue';
@@ -125,7 +124,7 @@ import * as symbols from '@/symbols';
export default defineComponent({
components: {
FormTextarea,
- FormObjectView,
+ MkObjectView,
FormButton,
FormLink,
FormSection,
diff --git a/packages/client/src/pages/theme-editor.vue b/packages/client/src/pages/theme-editor.vue
index f023653425..c4917e2270 100644
--- a/packages/client/src/pages/theme-editor.vue
+++ b/packages/client/src/pages/theme-editor.vue
@@ -1,61 +1,67 @@
<template>
-<FormBase class="cwepdizn">
- <div class="_debobigegoItem colorPicker">
- <div class="_debobigegoLabel">{{ $ts.backgroundColor }}</div>
- <div class="_debobigegoPanel colors">
- <div class="row">
- <button v-for="color in bgColors.filter(x => x.kind === 'light')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
- <div class="preview" :style="{ background: color.forPreview }"></div>
- </button>
+<MkSpacer :content-max="800" :margin-min="16" :margin-max="32">
+ <div class="cwepdizn _formRoot">
+ <FormFolder :default-open="true" class="_formBlock">
+ <template #label>{{ $ts.backgroundColor }}</template>
+ <div class="cwepdizn-colors">
+ <div class="row">
+ <button v-for="color in bgColors.filter(x => x.kind === 'light')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
+ <div class="preview" :style="{ background: color.forPreview }"></div>
+ </button>
+ </div>
+ <div class="row">
+ <button v-for="color in bgColors.filter(x => x.kind === 'dark')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
+ <div class="preview" :style="{ background: color.forPreview }"></div>
+ </button>
+ </div>
</div>
- <div class="row">
- <button v-for="color in bgColors.filter(x => x.kind === 'dark')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
- <div class="preview" :style="{ background: color.forPreview }"></div>
- </button>
- </div>
- </div>
- </div>
- <div class="_debobigegoItem colorPicker">
- <div class="_debobigegoLabel">{{ $ts.accentColor }}</div>
- <div class="_debobigegoPanel colors">
- <div class="row">
- <button v-for="color in accentColors" :key="color" class="color rounded _button" :class="{ active: theme.props.accent === color }" @click="setAccentColor(color)">
- <div class="preview" :style="{ background: color }"></div>
- </button>
+ </FormFolder>
+
+ <FormFolder :default-open="true" class="_formBlock">
+ <template #label>{{ $ts.accentColor }}</template>
+ <div class="cwepdizn-colors">
+ <div class="row">
+ <button v-for="color in accentColors" :key="color" class="color rounded _button" :class="{ active: theme.props.accent === color }" @click="setAccentColor(color)">
+ <div class="preview" :style="{ background: color }"></div>
+ </button>
+ </div>
</div>
- </div>
- </div>
- <div class="_debobigegoItem colorPicker">
- <div class="_debobigegoLabel">{{ $ts.textColor }}</div>
- <div class="_debobigegoPanel colors">
- <div class="row">
- <button v-for="color in fgColors" :key="color" class="color char _button" :class="{ active: (theme.props.fg === color.forLight) || (theme.props.fg === color.forDark) }" @click="setFgColor(color)">
- <div class="preview" :style="{ color: color.forPreview ? color.forPreview : theme.base === 'light' ? '#5f5f5f' : '#dadada' }">A</div>
- </button>
+ </FormFolder>
+
+ <FormFolder :default-open="true" class="_formBlock">
+ <template #label>{{ $ts.textColor }}</template>
+ <div class="cwepdizn-colors">
+ <div class="row">
+ <button v-for="color in fgColors" :key="color" class="color char _button" :class="{ active: (theme.props.fg === color.forLight) || (theme.props.fg === color.forDark) }" @click="setFgColor(color)">
+ <div class="preview" :style="{ color: color.forPreview ? color.forPreview : theme.base === 'light' ? '#5f5f5f' : '#dadada' }">A</div>
+ </button>
+ </div>
</div>
- </div>
- </div>
+ </FormFolder>
+
+ <FormFolder :default-open="false" class="_formBlock">
+ <template #icon><i class="fas fa-code"></i></template>
+ <template #label>{{ $ts.editCode }}</template>
- <FormGroup v-if="codeEnabled">
- <FormTextarea v-model="themeCode" tall>
- <span>{{ $ts._theme.code }}</span>
- </FormTextarea>
- <FormButton primary @click="applyThemeCode">{{ $ts.apply }}</FormButton>
- </FormGroup>
- <FormButton v-else @click="codeEnabled = true"><i class="fas fa-code"></i> {{ $ts.editCode }}</FormButton>
+ <div class="_formRoot">
+ <FormTextarea v-model="themeCode" tall class="_formBlock">
+ <template #label>{{ $ts._theme.code }}</template>
+ </FormTextarea>
+ <FormButton primary class="_formBlock" @click="applyThemeCode">{{ $ts.apply }}</FormButton>
+ </div>
+ </FormFolder>
- <FormGroup v-if="descriptionEnabled">
- <FormTextarea v-model="description">
- <span>{{ $ts._theme.description }}</span>
- </FormTextarea>
- </FormGroup>
- <FormButton v-else @click="descriptionEnabled = true">{{ $ts.addDescription }}</FormButton>
+ <FormFolder :default-open="false" class="_formBlock">
+ <template #label>{{ $ts.addDescription }}</template>
- <FormGroup>
- <FormButton @click="showPreview"><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
- <FormButton primary @click="saveAs"><i class="fas fa-save"></i> {{ $ts.saveAs }}</FormButton>
- </FormGroup>
-</FormBase>
+ <div class="_formRoot">
+ <FormTextarea v-model="description">
+ <template #label>{{ $ts._theme.description }}</template>
+ </FormTextarea>
+ </div>
+ </FormFolder>
+ </div>
+</MkSpacer>
</template>
<script lang="ts">
@@ -65,12 +71,11 @@ import * as tinycolor from 'tinycolor2';
import { v4 as uuid} from 'uuid';
import * as JSON5 from 'json5';
-import FormBase from '@/components/debobigego/base.vue';
-import FormButton from '@/components/debobigego/button.vue';
-import FormTextarea from '@/components/debobigego/textarea.vue';
-import FormGroup from '@/components/debobigego/group.vue';
+import FormButton from '@/components/ui/button.vue';
+import FormTextarea from '@/components/form/textarea.vue';
+import FormFolder from '@/components/form/folder.vue';
-import { Theme, applyTheme, validateTheme, darkTheme, lightTheme } from '@/scripts/theme';
+import { Theme, applyTheme, darkTheme, lightTheme } from '@/scripts/theme';
import { host } from '@/config';
import * as os from '@/os';
import { ColdDeviceStorage } from '@/store';
@@ -79,10 +84,9 @@ import * as symbols from '@/symbols';
export default defineComponent({
components: {
- FormBase,
FormButton,
FormTextarea,
- FormGroup,
+ FormFolder,
},
async beforeRouteLeave(to, from) {
@@ -96,13 +100,23 @@ export default defineComponent({
[symbols.PAGE_INFO]: {
title: this.$ts.themeEditor,
icon: 'fas fa-palette',
+ bg: 'var(--bg)',
+ actions: [{
+ asFullButton: true,
+ icon: 'fas fa-eye',
+ text: this.$ts.preview,
+ handler: this.showPreview,
+ }, {
+ asFullButton: true,
+ icon: 'fas fa-check',
+ text: this.$ts.saveAs,
+ handler: this.saveAs,
+ }],
},
theme: {
base: 'light',
props: lightTheme.props
} as Theme,
- codeEnabled: false,
- descriptionEnabled: false,
description: null,
themeCode: null,
bgColors: [
@@ -244,57 +258,51 @@ export default defineComponent({
<style lang="scss" scoped>
.cwepdizn {
- max-width: 800px;
- margin: 0 auto;
+ ::v-deep(.cwepdizn-colors) {
+ text-align: center;
- > .colorPicker {
- > .colors {
- padding: 32px;
- text-align: center;
+ > .row {
+ > .color {
+ display: inline-block;
+ position: relative;
+ width: 64px;
+ height: 64px;
+ border-radius: 8px;
- > .row {
- > .color {
- display: inline-block;
- position: relative;
- width: 64px;
- height: 64px;
- border-radius: 8px;
+ > .preview {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: auto;
+ width: 42px;
+ height: 42px;
+ border-radius: 4px;
+ box-shadow: 0 2px 4px rgb(0 0 0 / 30%);
+ transition: transform 0.15s ease;
+ }
+ &:hover {
> .preview {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- margin: auto;
- width: 42px;
- height: 42px;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgb(0 0 0 / 30%);
- transition: transform 0.15s ease;
+ transform: scale(1.1);
}
+ }
- &:hover {
- > .preview {
- transform: scale(1.1);
- }
- }
+ &.active {
+ box-shadow: 0 0 0 2px var(--divider) inset;
+ }
- &.active {
- box-shadow: 0 0 0 2px var(--divider) inset;
- }
+ &.rounded {
+ border-radius: 999px;
- &.rounded {
+ > .preview {
border-radius: 999px;
-
- > .preview {
- border-radius: 999px;
- }
}
+ }
- &.char {
- line-height: 42px;
- }
+ &.char {
+ line-height: 42px;
}
}
}
diff --git a/packages/client/src/pages/user-info.vue b/packages/client/src/pages/user-info.vue
index e3c10c6df9..4bdc82f601 100644
--- a/packages/client/src/pages/user-info.vue
+++ b/packages/client/src/pages/user-info.vue
@@ -53,9 +53,8 @@
<FormButton v-if="user.host != null" class="_formBlock" @click="updateRemoteUser"><i class="fas fa-sync"></i> {{ $ts.updateRemoteUser }}</FormButton>
</FormSection>
- <FormObjectView tall :value="user">
- <span>Raw</span>
- </FormObjectView>
+ <MkObjectView tall :value="user">
+ </MkObjectView>
</div>
</FormSuspense>
</MkSpacer>
@@ -63,7 +62,7 @@
<script lang="ts">
import { computed, defineAsyncComponent, defineComponent } from 'vue';
-import FormObjectView from '@/components/debobigego/object-view.vue';
+import MkObjectView from '@/components/object-view.vue';
import FormTextarea from '@/components/form/textarea.vue';
import FormSwitch from '@/components/form/switch.vue';
import FormLink from '@/components/form/link.vue';
@@ -83,7 +82,7 @@ export default defineComponent({
FormSection,
FormTextarea,
FormSwitch,
- FormObjectView,
+ MkObjectView,
FormButton,
FormLink,
MkKeyValue,