refactor components

This commit is contained in:
syuilo 2021-09-30 00:50:45 +09:00
parent 23995c44d5
commit 9f50312a59
179 changed files with 2611 additions and 2386 deletions

View File

@ -177,6 +177,10 @@ npx ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前
### JSONのimportに気を付けよう ### JSONのimportに気を付けよう
TypeScriptでjsonをimportすると、tscでコンパイルするときにそのjsonファイルも一緒にdistディレクトリに吐き出されてしまう。この挙動により、意図せずファイルの書き換えが発生することがあるので、jsonをimportするときは書き換えられても良いものかどうか確認すること。書き換えされて欲しくない場合は、importで読み込むのではなく、`fs.readFileSync`などの関数を使って読み込むようにすればよい。 TypeScriptでjsonをimportすると、tscでコンパイルするときにそのjsonファイルも一緒にdistディレクトリに吐き出されてしまう。この挙動により、意図せずファイルの書き換えが発生することがあるので、jsonをimportするときは書き換えられても良いものかどうか確認すること。書き換えされて欲しくない場合は、importで読み込むのではなく、`fs.readFileSync`などの関数を使って読み込むようにすればよい。
### コンポーネントのスタイル定義でmarginを持たせない
コンポーネント自身がmarginを設定するのは問題の元となることはよく知られている
marginはそのコンポーネントを使う側が設定する
## その他 ## その他
### HTMLのクラス名で follow という単語は使わない ### HTMLのクラス名で follow という単語は使わない
広告ブロッカーで誤ってブロックされる 広告ブロッカーで誤ってブロックされる

View File

@ -787,6 +787,8 @@ pubSub: "Pub/Subのアカウント"
lastCommunication: "直近の通信" lastCommunication: "直近の通信"
resolved: "解決済み" resolved: "解決済み"
unresolved: "未解決" unresolved: "未解決"
itsOn: "オンになっています"
itsOff: "オフになっています"
_accountDelete: _accountDelete:
accountDelete: "アカウントの削除" accountDelete: "アカウントの削除"

View File

@ -104,7 +104,7 @@
"@types/websocket": "1.0.4", "@types/websocket": "1.0.4",
"@types/ws": "7.4.7", "@types/ws": "7.4.7",
"@typescript-eslint/parser": "4.31.2", "@typescript-eslint/parser": "4.31.2",
"@vue/compiler-sfc": "3.2.13", "@vue/compiler-sfc": "3.2.19",
"abort-controller": "3.0.0", "abort-controller": "3.0.0",
"apexcharts": "3.28.3", "apexcharts": "3.28.3",
"autobind-decorator": "2.4.0", "autobind-decorator": "2.4.0",
@ -233,7 +233,7 @@
"uuid": "8.3.2", "uuid": "8.3.2",
"v-debounce": "0.1.2", "v-debounce": "0.1.2",
"vanilla-tilt": "1.7.2", "vanilla-tilt": "1.7.2",
"vue": "3.2.13", "vue": "3.2.19",
"vue-loader": "16.7.0", "vue-loader": "16.7.0",
"vue-prism-editor": "2.0.0-alpha.2", "vue-prism-editor": "2.0.0-alpha.2",
"vue-router": "4.0.5", "vue-router": "4.0.5",
@ -241,7 +241,7 @@
"vue-svg-loader": "0.17.0-beta.2", "vue-svg-loader": "0.17.0-beta.2",
"vuedraggable": "4.0.1", "vuedraggable": "4.0.1",
"web-push": "3.4.5", "web-push": "3.4.5",
"webpack": "5.53.0", "webpack": "5.54.0",
"webpack-cli": "4.8.0", "webpack-cli": "4.8.0",
"websocket": "1.0.34", "websocket": "1.0.34",
"ws": "8.2.2", "ws": "8.2.2",

View File

@ -25,7 +25,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, markRaw } from 'vue'; import { defineComponent, markRaw } from 'vue';
import XWindow from '@client/components/ui/window.vue'; import XWindow from '@client/components/ui/window.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -1,7 +1,7 @@
<template> <template>
<button class="nrvgflfu _button" @click="toggle"> <button class="nrvgflfu _button" @click="toggle">
<b>{{ value ? $ts._cw.hide : $ts._cw.show }}</b> <b>{{ modelValue ? $ts._cw.hide : $ts._cw.show }}</b>
<span v-if="!value">{{ label }}</span> <span v-if="!modelValue">{{ label }}</span>
</button> </button>
</template> </template>
@ -12,7 +12,7 @@ import { concat } from '../../prelude/array';
export default defineComponent({ export default defineComponent({
props: { props: {
value: { modelValue: {
type: Boolean, type: Boolean,
required: true required: true
}, },
@ -36,7 +36,7 @@ export default defineComponent({
length, length,
toggle() { toggle() {
this.$emit('update:value', !this.value); this.$emit('update:modelValue', !this.modelValue);
} }
} }
}); });

View File

@ -21,39 +21,39 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.rbusrurv { .rbusrurv {
// CSS // CSS
--formXPadding: 32px; --debobigegoXPadding: 32px;
--formYPadding: 32px; --debobigegoYPadding: 32px;
--formContentHMargin: 16px; --debobigegoContentHMargin: 16px;
font-size: 95%; font-size: 95%;
line-height: 1.3em; line-height: 1.3em;
background: var(--bg); background: var(--bg);
padding: var(--formYPadding) var(--formXPadding); padding: var(--debobigegoYPadding) var(--debobigegoXPadding);
max-width: 750px; max-width: 750px;
margin: 0 auto; margin: 0 auto;
&:not(.wide).max-width_400px { &:not(.wide).max-width_400px {
--formXPadding: 0px; --debobigegoXPadding: 0px;
> ::v-deep(*) { > ::v-deep(*) {
._formPanel { ._debobigegoPanel {
border: solid 0.5px var(--divider); border: solid 0.5px var(--divider);
border-radius: 0; border-radius: 0;
border-left: none; border-left: none;
border-right: none; border-right: none;
} }
._form_group { ._debobigego_group {
> *:not(._formNoConcat) { > *:not(._debobigegoNoConcat) {
&:not(:last-child):not(._formNoConcatPrev) { &:not(:last-child):not(._debobigegoNoConcatPrev) {
&._formPanel, ._formPanel { &._debobigegoPanel, ._debobigegoPanel {
border-bottom: solid 0.5px var(--divider); border-bottom: solid 0.5px var(--divider);
} }
} }
&:not(:first-child):not(._formNoConcatNext) { &:not(:first-child):not(._debobigegoNoConcatNext) {
&._formPanel, ._formPanel { &._debobigegoPanel, ._debobigegoPanel {
border-top: none; border-top: none;
} }
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="yzpgjkxe _formItem"> <div class="yzpgjkxe _debobigegoItem">
<div class="_formLabel"><slot name="label"></slot></div> <div class="_debobigegoLabel"><slot name="label"></slot></div>
<button class="main _button _formPanel _formClickable" :class="{ center, primary, danger }"> <button class="main _button _debobigegoPanel _debobigegoClickable" :class="{ center, primary, danger }">
<slot></slot> <slot></slot>
<div class="suffix"> <div class="suffix">
<slot name="suffix"></slot> <slot name="suffix"></slot>
@ -10,13 +10,13 @@
</div> </div>
</div> </div>
</button> </button>
<div class="_formCaption"><slot name="desc"></slot></div> <div class="_debobigegoCaption"><slot name="desc"></slot></div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import './form.scss'; import './debobigego.scss';
export default defineComponent({ export default defineComponent({
props: { props: {

View File

@ -1,9 +1,9 @@
._formPanel { ._debobigegoPanel {
background: var(--panel); background: var(--panel);
border-radius: var(--radius); border-radius: var(--radius);
transition: background 0.2s ease; transition: background 0.2s ease;
&._formClickable { &._debobigegoClickable {
&:hover { &:hover {
//background: var(--panelHighlight); //background: var(--panelHighlight);
} }
@ -15,8 +15,8 @@
} }
} }
._formLabel, ._debobigegoLabel,
._formCaption { ._debobigegoCaption {
font-size: 80%; font-size: 80%;
color: var(--fgTransparentWeak); color: var(--fgTransparentWeak);
@ -25,28 +25,28 @@
} }
} }
._formLabel { ._debobigegoLabel {
position: sticky; position: sticky;
top: var(--stickyTop, 0px); top: var(--stickyTop, 0px);
z-index: 2; z-index: 2;
margin: -8px calc(var(--formXPadding) * -1) 0 calc(var(--formXPadding) * -1); margin: -8px calc(var(--debobigegoXPadding) * -1) 0 calc(var(--debobigegoXPadding) * -1);
padding: 8px calc(var(--formContentHMargin) + var(--formXPadding)) 8px calc(var(--formContentHMargin) + var(--formXPadding)); padding: 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding)) 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding));
background: var(--X17); background: var(--X17);
-webkit-backdrop-filter: var(--blur, blur(10px)); -webkit-backdrop-filter: var(--blur, blur(10px));
backdrop-filter: var(--blur, blur(10px)); backdrop-filter: var(--blur, blur(10px));
} }
._themeChanging_ ._formLabel { ._themeChanging_ ._debobigegoLabel {
transition: none !important; transition: none !important;
background: transparent; background: transparent;
} }
._formCaption { ._debobigegoCaption {
padding: 8px var(--formContentHMargin) 0 var(--formContentHMargin); padding: 8px var(--debobigegoContentHMargin) 0 var(--debobigegoContentHMargin);
} }
._formItem { ._debobigegoItem {
& + ._formItem { & + ._debobigegoItem {
margin-top: 24px; margin-top: 24px;
} }
} }

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="vrtktovg _formItem _formNoConcat" v-size="{ max: [500] }" v-sticky-container> <div class="vrtktovg _debobigegoItem _debobigegoNoConcat" v-size="{ max: [500] }" v-sticky-container>
<div class="_formLabel"><slot name="label"></slot></div> <div class="_debobigegoLabel"><slot name="label"></slot></div>
<div class="main _form_group" ref="child"> <div class="main _debobigego_group" ref="child">
<slot></slot> <slot></slot>
</div> </div>
<div class="_formCaption"><slot name="caption"></slot></div> <div class="_debobigegoCaption"><slot name="caption"></slot></div>
</div> </div>
</template> </template>
@ -20,9 +20,9 @@ export default defineComponent({
const els = Array.from(child.value.children); const els = Array.from(child.value.children);
for (let i = 0; i < els.length; i++) { for (let i = 0; i < els.length; i++) {
const el = els[i]; const el = els[i];
if (el.classList.contains('_formNoConcat')) { if (el.classList.contains('_debobigegoNoConcat')) {
if (els[i - 1]) els[i - 1].classList.add('_formNoConcatPrev'); if (els[i - 1]) els[i - 1].classList.add('_debobigegoNoConcatPrev');
if (els[i + 1]) els[i + 1].classList.add('_formNoConcatNext'); if (els[i + 1]) els[i + 1].classList.add('_debobigegoNoConcatNext');
} }
} }
}; };
@ -52,21 +52,21 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.vrtktovg { .vrtktovg {
> .main { > .main {
> ::v-deep(*):not(._formNoConcat) { > ::v-deep(*):not(._debobigegoNoConcat) {
&:not(._formNoConcatNext) { &:not(._debobigegoNoConcatNext) {
margin: 0; margin: 0;
} }
&:not(:last-child):not(._formNoConcatPrev) { &:not(:last-child):not(._debobigegoNoConcatPrev) {
&._formPanel, ._formPanel { &._debobigegoPanel, ._debobigegoPanel {
border-bottom: solid 0.5px var(--divider); border-bottom: solid 0.5px var(--divider);
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
} }
&:not(:first-child):not(._formNoConcatNext) { &:not(:first-child):not(._debobigegoNoConcatNext) {
&._formPanel, ._formPanel { &._debobigegoPanel, ._debobigegoPanel {
border-top: none; border-top: none;
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="fzenkabp _formItem"> <div class="fzenkabp _debobigegoItem">
<div class="_formPanel" :class="{ warn }"> <div class="_debobigegoPanel" :class="{ warn }">
<i v-if="warn" class="fas fa-exclamation-triangle"></i> <i v-if="warn" class="fas fa-exclamation-triangle"></i>
<i v-else class="fas fa-info-circle"></i> <i v-else class="fas fa-info-circle"></i>
<slot></slot> <slot></slot>

View File

@ -1,49 +1,53 @@
<template> <template>
<div class="matxzzsk"> <FormGroup class="_debobigegoItem">
<div class="label" @click="focus"><slot name="label"></slot></div> <template #label><slot></slot></template>
<div class="input" :class="{ inline, disabled, focused }"> <div class="ztzhwixg _debobigegoItem" :class="{ inline, disabled }">
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> <div class="icon" ref="icon"><slot name="icon"></slot></div>
<input ref="inputEl" <div class="input _debobigegoPanel">
:type="type" <div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
v-model="v" <input ref="inputEl"
:disabled="disabled" :type="type"
:required="required" v-model="v"
:readonly="readonly" :disabled="disabled"
:placeholder="placeholder" :required="required"
:pattern="pattern" :readonly="readonly"
:autocomplete="autocomplete" :placeholder="placeholder"
:spellcheck="spellcheck" :pattern="pattern"
:step="step" :autocomplete="autocomplete"
@focus="focused = true" :spellcheck="spellcheck"
@blur="focused = false" :step="step"
@keydown="onKeydown($event)" @focus="focused = true"
@input="onInput" @blur="focused = false"
:list="id" @keydown="onKeydown($event)"
> @input="onInput"
<datalist :id="id" v-if="datalist"> :list="id"
<option v-for="data in datalist" :value="data"/> >
</datalist> <datalist :id="id" v-if="datalist">
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div> <option v-for="data in datalist" :value="data"/>
</datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</div>
</div> </div>
<div class="caption"><slot name="caption"></slot></div> <template #caption><slot name="desc"></slot></template>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton> <FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
</div> </FormGroup>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue'; import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import MkButton from './button.vue'; import './debobigego.scss';
import { debounce } from 'throttle-debounce'; import FormButton from './button.vue';
import FormGroup from './group.vue';
export default defineComponent({ export default defineComponent({
components: { components: {
MkButton, FormGroup,
FormButton,
}, },
props: { props: {
modelValue: { modelValue: {
required: true required: false
}, },
type: { type: {
type: String, type: String,
@ -92,20 +96,13 @@ export default defineComponent({
required: false, required: false,
default: false default: false
}, },
debounce: {
type: Boolean,
required: false,
default: false
},
manualSave: { manualSave: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false default: false
}, },
}, },
emits: ['change', 'keydown', 'enter', 'update:modelValue'], emits: ['change', 'keydown', 'enter', 'update:modelValue'],
setup(props, context) { setup(props, context) {
const { modelValue, type, autofocus } = toRefs(props); const { modelValue, type, autofocus } = toRefs(props);
const v = ref(modelValue.value); const v = ref(modelValue.value);
@ -140,19 +137,13 @@ export default defineComponent({
} }
}; };
const debouncedUpdated = debounce(1000, updated); watch(modelValue.value, newValue => {
watch(modelValue, newValue => {
v.value = newValue; v.value = newValue;
}); });
watch(v, newValue => { watch(v, newValue => {
if (!props.manualSave) { if (!props.manualSave) {
if (props.debounce) { updated();
debouncedUpdated();
} else {
updated();
}
} }
invalid.value = inputEl.value.validity.badInput; invalid.value = inputEl.value.validity.badInput;
@ -205,68 +196,59 @@ export default defineComponent({
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.matxzzsk { .ztzhwixg {
margin: 1.5em 0; position: relative;
> .label { > .icon {
font-size: 0.85em; position: absolute;
padding: 0 0 8px 12px; top: 0;
user-select: none; left: 0;
width: 24px;
text-align: center;
line-height: 32px;
&:empty { &:not(:empty) + .input {
display: none; margin-left: 28px;
}
}
> .caption {
font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
} }
} }
> .input { > .input {
$height: 42px; $height: 48px;
position: relative; position: relative;
> input { > input {
appearance: none;
-webkit-appearance: none;
display: block; display: block;
height: $height; height: $height;
width: 100%; width: 100%;
margin: 0; margin: 0;
padding: 0 12px; padding: 0 16px;
font: inherit; font: inherit;
font-weight: normal; font-weight: normal;
font-size: 1em; font-size: 1em;
color: var(--fg); line-height: $height;
background: var(--panel); color: var(--inputText);
border: solid 0.5px var(--inputBorder); background: transparent;
border-radius: 6px; border: none;
border-radius: 0;
outline: none; outline: none;
box-shadow: none; box-shadow: none;
box-sizing: border-box; box-sizing: border-box;
transition: border-color 0.1s ease-out;
&:hover { &[type='file'] {
border-color: var(--inputBorderHover); display: none;
} }
} }
> .prefix, > .prefix,
> .suffix { > .suffix {
display: flex; display: block;
align-items: center;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
top: 0; top: 0;
padding: 0 12px; padding: 0 16px;
font-size: 1em; font-size: 1em;
height: $height; line-height: $height;
color: var(--inputLabel);
pointer-events: none; pointer-events: none;
&:empty { &:empty {
@ -285,32 +267,25 @@ export default defineComponent({
> .prefix { > .prefix {
left: 0; left: 0;
padding-right: 6px; padding-right: 8px;
} }
> .suffix { > .suffix {
right: 0; right: 0;
padding-left: 6px; padding-left: 8px;
} }
}
&.inline { &.inline {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
} }
&.focused { &.disabled {
> input { opacity: 0.7;
border-color: var(--accent);
//box-shadow: 0 0 0 4px var(--focus);
}
}
&.disabled { &, * {
opacity: 0.7; cursor: not-allowed !important;
&, * {
cursor: not-allowed !important;
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formPanel anocepby"> <div class="_debobigegoPanel anocepby">
<span class="key"><slot name="key"></slot></span> <span class="key"><slot name="key"></slot></span>
<span class="value"><slot name="value"></slot></span> <span class="value"><slot name="value"></slot></span>
</div> </div>
@ -9,7 +9,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import './form.scss'; import './debobigego.scss';
export default defineComponent({ export default defineComponent({
@ -20,7 +20,7 @@ export default defineComponent({
.anocepby { .anocepby {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 14px var(--formContentHMargin); padding: 14px var(--debobigegoContentHMargin);
> .key { > .key {
margin-right: 12px; margin-right: 12px;

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="qmfkfnzi _formItem"> <div class="qmfkfnzi _debobigegoItem">
<a class="main _button _formPanel _formClickable" :href="to" target="_blank" v-if="external"> <a class="main _button _debobigegoPanel _debobigegoClickable" :href="to" target="_blank" v-if="external">
<span class="icon"><slot name="icon"></slot></span> <span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot></slot></span> <span class="text"><slot></slot></span>
<span class="right"> <span class="right">
@ -8,7 +8,7 @@
<i class="fas fa-external-link-alt icon"></i> <i class="fas fa-external-link-alt icon"></i>
</span> </span>
</a> </a>
<MkA class="main _button _formPanel _formClickable" :class="{ active }" :to="to" :behavior="behavior" v-else> <MkA class="main _button _debobigegoPanel _debobigegoClickable" :class="{ active }" :to="to" :behavior="behavior" v-else>
<span class="icon"><slot name="icon"></slot></span> <span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot></slot></span> <span class="text"><slot></slot></span>
<span class="right"> <span class="right">
@ -21,7 +21,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import './form.scss'; import './debobigego.scss';
export default defineComponent({ export default defineComponent({
props: { props: {

View File

@ -1,8 +1,8 @@
<template> <template>
<FormGroup class="_formItem"> <FormGroup class="_debobigegoItem">
<template #label><slot></slot></template> <template #label><slot></slot></template>
<div class="drooglns _formItem" :class="{ tall }"> <div class="drooglns _debobigegoItem" :class="{ tall }">
<div class="input _formPanel"> <div class="input _debobigegoPanel">
<textarea class="_monospace" <textarea class="_monospace"
v-model="v" v-model="v"
readonly readonly
@ -17,7 +17,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, toRefs, watch } from 'vue'; import { defineComponent, ref, toRefs, watch } from 'vue';
import * as JSON5 from 'json5'; import * as JSON5 from 'json5';
import './form.scss'; import './debobigego.scss';
import FormGroup from './group.vue'; import FormGroup from './group.vue';
export default defineComponent({ export default defineComponent({
@ -75,7 +75,7 @@ export default defineComponent({
max-width: 100%; max-width: 100%;
min-height: 130px; min-height: 130px;
margin: 0; margin: 0;
padding: 16px var(--formContentHMargin); padding: 16px var(--debobigegoContentHMargin);
box-sizing: border-box; box-sizing: border-box;
font: inherit; font: inherit;
font-weight: normal; font-weight: normal;

View File

@ -1,5 +1,5 @@
<template> <template>
<FormGroup class="uljviswt _formItem"> <FormGroup class="uljviswt _debobigegoItem">
<template #label><slot name="label"></slot></template> <template #label><slot name="label"></slot></template>
<slot :items="items"></slot> <slot :items="items"></slot>
<div class="empty" v-if="empty" key="_empty_"> <div class="empty" v-if="empty" key="_empty_">

View File

@ -0,0 +1,112 @@
<script lang="ts">
import { defineComponent, h } from 'vue';
import MkRadio from '@client/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>

View File

@ -0,0 +1,122 @@
<template>
<div class="ifitouly _debobigegoItem" :class="{ focused, disabled }">
<div class="_debobigegoLabel"><slot name="label"></slot></div>
<div class="_debobigegoPanel main">
<input
type="range"
ref="input"
v-model="v"
: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>

View File

@ -0,0 +1,145 @@
<template>
<div class="yrtfrpux _debobigegoItem" :class="{ disabled, inline }">
<div class="_debobigegoLabel"><slot name="label"></slot></div>
<div class="icon" ref="icon"><slot name="icon"></slot></div>
<div class="input _debobigegoPanel _debobigegoClickable" @click="focus">
<div class="prefix" ref="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>

View File

@ -1,15 +1,15 @@
<template> <template>
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div class="_formItem" v-if="pending"> <div class="_debobigegoItem" v-if="pending">
<div class="_formPanel"> <div class="_debobigegoPanel">
<MkLoading/> <MkLoading/>
</div> </div>
</div> </div>
<div v-else-if="resolved" class="_formItem"> <div v-else-if="resolved" class="_debobigegoItem">
<slot :result="result"></slot> <slot :result="result"></slot>
</div> </div>
<div class="_formItem" v-else> <div class="_debobigegoItem" v-else>
<div class="_formPanel eiurkvay"> <div class="_debobigegoPanel eiurkvay">
<div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div> <div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div>
<MkButton inline @click="retry" class="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton> <MkButton inline @click="retry" class="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton>
</div> </div>
@ -19,7 +19,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType, ref, watch } from 'vue'; import { defineComponent, PropType, ref, watch } from 'vue';
import './form.scss'; import './debobigego.scss';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
export default defineComponent({ export default defineComponent({

View File

@ -0,0 +1,132 @@
<template>
<div class="ijnpvmgr _debobigegoItem">
<div class="main _debobigegoPanel _debobigegoClickable"
:class="{ disabled, checked }"
:aria-checked="checked"
:aria-disabled="disabled"
@click.prevent="toggle"
>
<input
type="checkbox"
ref="input"
:disabled="disabled"
@keydown.enter="toggle"
>
<span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff">
<span></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;
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
&.checked {
> .button {
background-color: var(--X10);
border-color: var(--X10);
> * {
background-color: var(--accent);
transform: translateX(14px);
}
}
}
> input {
position: absolute;
width: 0;
height: 0;
opacity: 0;
margin: 0;
}
> .button {
position: relative;
display: inline-block;
flex-shrink: 0;
margin: 3px 0 0 0;
width: 34px;
height: 14px;
background: var(--X6);
outline: none;
border-radius: 14px;
transition: all 0.3s;
cursor: pointer;
> * {
position: absolute;
top: -3px;
left: 0;
border-radius: 100%;
transition: background-color 0.3s, transform 0.3s;
width: 20px;
height: 20px;
background-color: #fff;
box-shadow: 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12);
}
}
> .label {
margin-left: 12px;
display: block;
transition: inherit;
color: var(--fg);
> span {
display: block;
line-height: 20px;
transition: inherit;
}
}
}
}
</style>

View File

@ -0,0 +1,161 @@
<template>
<FormGroup class="_debobigegoItem">
<template #label><slot></slot></template>
<div class="rivhosbp _debobigegoItem" :class="{ tall, pre }">
<div class="input _debobigegoPanel">
<textarea ref="input" :class="{ code, _monospace: code }"
v-model="v"
: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" @click="updated" primary><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>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="wthhikgt _formItem" v-size="{ max: [500] }"> <div class="wthhikgt _debobigegoItem" v-size="{ max: [500] }">
<slot></slot> <slot></slot>
</div> </div>
</template> </template>

View File

@ -40,8 +40,8 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkModal from '@client/components/ui/modal.vue'; import MkModal from '@client/components/ui/modal.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
export default defineComponent({ export default defineComponent({
components: { components: {

View File

@ -35,7 +35,7 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import * as os from '@client/os'; import * as os from '@client/os';
export default defineComponent({ export default defineComponent({

View File

@ -14,23 +14,23 @@
</template> </template>
<FormBase class="xkpnjxcv"> <FormBase class="xkpnjxcv">
<template v-for="item in Object.keys(form).filter(item => !form[item].hidden)"> <template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
<FormInput v-if="form[item].type === 'number'" v-model:value="values[item]" type="number" :step="form[item].step || 1"> <FormInput v-if="form[item].type === 'number'" v-model="values[item]" type="number" :step="form[item].step || 1">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span> <span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template> <template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormInput> </FormInput>
<FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model:value="values[item]" type="text"> <FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model="values[item]" type="text">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span> <span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template> <template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormInput> </FormInput>
<FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model:value="values[item]"> <FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model="values[item]">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span> <span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template> <template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormTextarea> </FormTextarea>
<FormSwitch v-else-if="form[item].type === 'boolean'" v-model:value="values[item]"> <FormSwitch v-else-if="form[item].type === 'boolean'" v-model="values[item]">
<span v-text="form[item].label || item"></span> <span v-text="form[item].label || item"></span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template> <template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormSwitch> </FormSwitch>
<FormSelect v-else-if="form[item].type === 'enum'" v-model:value="values[item]"> <FormSelect v-else-if="form[item].type === 'enum'" v-model="values[item]">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option> <option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option>
</FormSelect> </FormSelect>
@ -38,7 +38,7 @@
<template #desc><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template #desc><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<option v-for="item in form[item].options" :value="item.value" :key="item.value">{{ item.label }}</option> <option v-for="item in form[item].options" :value="item.value" :key="item.value">{{ item.label }}</option>
</FormRadios> </FormRadios>
<FormRange v-else-if="form[item].type === 'range'" v-model:value="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step"> <FormRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template> <template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormRange> </FormRange>
@ -53,14 +53,14 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import FormBase from './form/base.vue'; import FormBase from './debobigego/base.vue';
import FormInput from './form/input.vue'; import FormInput from './debobigego/input.vue';
import FormTextarea from './form/textarea.vue'; import FormTextarea from './debobigego/textarea.vue';
import FormSwitch from './form/switch.vue'; import FormSwitch from './debobigego/switch.vue';
import FormSelect from './form/select.vue'; import FormSelect from './debobigego/select.vue';
import FormRange from './form/range.vue'; import FormRange from './debobigego/range.vue';
import FormButton from './form/button.vue'; import FormButton from './debobigego/button.vue';
import FormRadios from './form/radios.vue'; import FormRadios from './debobigego/radios.vue';
export default defineComponent({ export default defineComponent({
components: { components: {

View File

@ -1,53 +1,49 @@
<template> <template>
<FormGroup class="_formItem"> <div class="matxzzsk">
<template #label><slot></slot></template> <div class="label" @click="focus"><slot name="label"></slot></div>
<div class="ztzhwixg _formItem" :class="{ inline, disabled }"> <div class="input" :class="{ inline, disabled, focused }">
<div class="icon" ref="icon"><slot name="icon"></slot></div> <div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
<div class="input _formPanel"> <input ref="inputEl"
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> :type="type"
<input ref="inputEl" v-model="v"
:type="type" :disabled="disabled"
v-model="v" :required="required"
:disabled="disabled" :readonly="readonly"
:required="required" :placeholder="placeholder"
:readonly="readonly" :pattern="pattern"
:placeholder="placeholder" :autocomplete="autocomplete"
:pattern="pattern" :spellcheck="spellcheck"
:autocomplete="autocomplete" :step="step"
:spellcheck="spellcheck" @focus="focused = true"
:step="step" @blur="focused = false"
@focus="focused = true" @keydown="onKeydown($event)"
@blur="focused = false" @input="onInput"
@keydown="onKeydown($event)" :list="id"
@input="onInput" >
:list="id" <datalist :id="id" v-if="datalist">
> <option v-for="data in datalist" :value="data"/>
<datalist :id="id" v-if="datalist"> </datalist>
<option v-for="data in datalist" :value="data"/> <div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</div>
</div> </div>
<template #caption><slot name="desc"></slot></template> <div class="caption"><slot name="caption"></slot></div>
<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> <MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</FormGroup> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue'; import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import './form.scss'; import MkButton from '../ui/button.vue';
import FormButton from './button.vue'; import { debounce } from 'throttle-debounce';
import FormGroup from './group.vue';
export default defineComponent({ export default defineComponent({
components: { components: {
FormGroup, MkButton,
FormButton,
}, },
props: { props: {
value: { modelValue: {
required: false required: true
}, },
type: { type: {
type: String, type: String,
@ -96,16 +92,23 @@ export default defineComponent({
required: false, required: false,
default: false default: false
}, },
debounce: {
type: Boolean,
required: false,
default: false
},
manualSave: { manualSave: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false default: false
}, },
}, },
emits: ['change', 'keydown', 'enter'],
emits: ['change', 'keydown', 'enter', 'update:modelValue'],
setup(props, context) { setup(props, context) {
const { value, type, autofocus } = toRefs(props); const { modelValue, type, autofocus } = toRefs(props);
const v = ref(value.value); const v = ref(modelValue.value);
const id = Math.random().toString(); // TODO: uuid? const id = Math.random().toString(); // TODO: uuid?
const focused = ref(false); const focused = ref(false);
const changed = ref(false); const changed = ref(false);
@ -131,19 +134,25 @@ export default defineComponent({
const updated = () => { const updated = () => {
changed.value = false; changed.value = false;
if (type?.value === 'number') { if (type?.value === 'number') {
context.emit('update:value', parseFloat(v.value)); context.emit('update:modelValue', parseFloat(v.value));
} else { } else {
context.emit('update:value', v.value); context.emit('update:modelValue', v.value);
} }
}; };
watch(value, newValue => { const debouncedUpdated = debounce(1000, updated);
watch(modelValue, newValue => {
v.value = newValue; v.value = newValue;
}); });
watch(v, newValue => { watch(v, newValue => {
if (!props.manualSave) { if (!props.manualSave) {
updated(); if (props.debounce) {
debouncedUpdated();
} else {
updated();
}
} }
invalid.value = inputEl.value.validity.badInput; invalid.value = inputEl.value.validity.badInput;
@ -196,59 +205,66 @@ export default defineComponent({
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ztzhwixg { .matxzzsk {
position: relative; > .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
> .icon { &:empty {
position: absolute; display: none;
top: 0; }
left: 0; }
width: 24px;
text-align: center;
line-height: 32px;
&:not(:empty) + .input { > .caption {
margin-left: 28px; font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
} }
} }
> .input { > .input {
$height: 48px; $height: 42px;
position: relative; position: relative;
> input { > input {
appearance: none;
-webkit-appearance: none;
display: block; display: block;
height: $height; height: $height;
width: 100%; width: 100%;
margin: 0; margin: 0;
padding: 0 16px; padding: 0 12px;
font: inherit; font: inherit;
font-weight: normal; font-weight: normal;
font-size: 1em; font-size: 1em;
line-height: $height; color: var(--fg);
color: var(--inputText); background: var(--panel);
background: transparent; border: solid 0.5px var(--inputBorder);
border: none; border-radius: 6px;
border-radius: 0;
outline: none; outline: none;
box-shadow: none; box-shadow: none;
box-sizing: border-box; box-sizing: border-box;
transition: border-color 0.1s ease-out;
&[type='file'] { &:hover {
display: none; border-color: var(--inputBorderHover);
} }
} }
> .prefix, > .prefix,
> .suffix { > .suffix {
display: block; display: flex;
align-items: center;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
top: 0; top: 0;
padding: 0 16px; padding: 0 12px;
font-size: 1em; font-size: 1em;
line-height: $height; height: $height;
color: var(--inputLabel);
pointer-events: none; pointer-events: none;
&:empty { &:empty {
@ -267,25 +283,32 @@ export default defineComponent({
> .prefix { > .prefix {
left: 0; left: 0;
padding-right: 8px; padding-right: 6px;
} }
> .suffix { > .suffix {
right: 0; right: 0;
padding-left: 8px; padding-left: 6px;
} }
}
&.inline { &.inline {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
} }
&.disabled { &.focused {
opacity: 0.7; > input {
border-color: var(--accent);
//box-shadow: 0 0 0 4px var(--focus);
}
}
&, * { &.disabled {
cursor: not-allowed !important; opacity: 0.7;
&, * {
cursor: not-allowed !important;
}
} }
} }
} }

View File

@ -1,7 +1,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, h } from 'vue'; import { defineComponent, h } from 'vue';
import MkRadio from '@client/components/ui/radio.vue'; import MkRadio from './radio.vue';
import './form.scss';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -18,9 +17,6 @@ export default defineComponent({
} }
}, },
watch: { watch: {
modelValue() {
this.value = this.modelValue;
},
value() { value() {
this.$emit('update:modelValue', this.value); this.$emit('update:modelValue', this.value);
} }
@ -33,80 +29,38 @@ export default defineComponent({
if (options.length === 1 && options[0].props == null) options = options[0].children; if (options.length === 1 && options[0].props == null) options = options[0].children;
return h('div', { return h('div', {
class: 'cnklmpwm _formItem' class: 'novjtcto'
}, [ }, [
h('div', { h('div', { class: 'label' }, label),
class: '_formLabel', ...options.map(option => h(MkRadio, {
}, label),
...options.map(option => h('button', {
class: '_button _formPanel _formClickable',
key: option.key, key: option.key,
onClick: () => this.value = option.props.value, value: option.props.value,
}, [h('span', { modelValue: this.value,
class: ['check', { checked: this.value === option.props.value }], 'onUpdate:modelValue': value => this.value = value,
}), option.children])) }, option.children))
]); ]);
} }
}); });
</script> </script>
<style lang="scss"> <style lang="scss">
.cnklmpwm { .novjtcto {
> button { > .label {
display: block; font-size: 0.85em;
width: 100%; padding: 0 0 8px 12px;
box-sizing: border-box; user-select: none;
padding: 14px 18px;
text-align: left;
&:not(:first-of-type) { &:empty {
border-top: none !important; display: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
} }
}
&:not(:last-of-type) { &:first-child {
border-bottom: solid 0.5px var(--divider); margin-top: 0;
border-bottom-left-radius: 0; }
border-bottom-right-radius: 0;
}
> .check { &:last-child {
display: inline-block; margin-bottom: 0;
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> </style>

View File

@ -1,21 +1,20 @@
<template> <template>
<div class="ifitouly _formItem" :class="{ focused, disabled }"> <div class="timctyfi" :class="{ focused, disabled }">
<div class="_formLabel"><slot name="label"></slot></div> <div class="icon"><slot name="icon"></slot></div>
<div class="_formPanel main"> <span class="label"><slot name="label"></slot></span>
<input <input
type="range" type="range"
ref="input" ref="input"
v-model="v" v-model="v"
:disabled="disabled" :disabled="disabled"
:min="min" :min="min"
:max="max" :max="max"
:step="step" :step="step"
@focus="focused = true" :autofocus="autofocus"
@blur="focused = false" @focus="focused = true"
@input="$emit('update:value', $event.target.value)" @blur="focused = false"
/> @input="$emit('update:value', $event.target.value)"
</div> />
<div class="_formCaption"><slot name="caption"></slot></div>
</div> </div>
</template> </template>
@ -49,6 +48,10 @@ export default defineComponent({
required: false, required: false,
default: 1 default: 1
}, },
autofocus: {
type: Boolean,
required: false
}
}, },
data() { data() {
return { return {
@ -61,61 +64,75 @@ export default defineComponent({
this.v = parseFloat(v); this.v = parseFloat(v);
} }
}, },
mounted() {
if (this.autofocus) {
this.$nextTick(() => {
this.$refs.input.focus();
});
}
}
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ifitouly { .timctyfi {
position: relative; position: relative;
margin: 8px;
> .main { > .icon {
padding: 22px 16px; display: inline-block;
width: 24px;
text-align: center;
}
> input { > .title {
display: block; pointer-events: none;
font-size: 16px;
color: var(--inputLabel);
overflow: hidden;
}
> input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: var(--X10);
height: 7px;
margin: 0 8px;
outline: 0;
border: 0;
border-radius: 7px;
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
&::-webkit-slider-thumb {
-webkit-appearance: none; -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; -moz-appearance: none;
appearance: none; appearance: none;
background: var(--X10); cursor: pointer;
height: 4px; width: 20px;
width: 100%; height: 20px;
box-sizing: border-box; display: block;
margin: 0; border-radius: 50%;
outline: 0; border: none;
border: 0; background: var(--accent);
border-radius: 7px; box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
&.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);
}
} }
} }
} }

View File

@ -0,0 +1,31 @@
<template>
<div class="vrtktovh" v-size="{ max: [500] }" v-sticky-container>
<div class="label"><slot name="label"></slot></div>
<div class="main">
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
});
</script>
<style lang="scss" scoped>
.vrtktovh {
border-top: solid 0.5px var(--divider);
> .label {
font-weight: bold;
padding: 24px 0 16px 0;
}
> .main {
margin-bottom: 32px;
}
}
</style>

View File

@ -1,125 +1,216 @@
<template> <template>
<div class="yrtfrpux _formItem" :class="{ disabled, inline }"> <div class="vblkjoeq">
<div class="_formLabel"><slot name="label"></slot></div> <div class="label" @click="focus"><slot name="label"></slot></div>
<div class="icon" ref="icon"><slot name="icon"></slot></div> <div class="input" :class="{ inline, disabled, focused }">
<div class="input _formPanel _formClickable" @click="focus"> <div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div> <select ref="inputEl"
<select ref="input"
v-model="v" v-model="v"
:required="required"
:disabled="disabled" :disabled="disabled"
:required="required"
:readonly="readonly"
:placeholder="placeholder"
@focus="focused = true" @focus="focused = true"
@blur="focused = false" @blur="focused = false"
@input="onInput"
> >
<slot></slot> <slot></slot>
</select> </select>
<div class="suffix"> <div class="suffix" ref="suffixEl"><i class="fas fa-chevron-down"></i></div>
<i class="fas fa-chevron-down"></i>
</div>
</div> </div>
<div class="_formCaption"><slot name="caption"></slot></div> <div class="caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import './form.scss'; import MkButton from '../ui/button.vue';
export default defineComponent({ export default defineComponent({
components: {
MkButton,
},
props: { props: {
value: { modelValue: {
required: false required: true
}, },
required: { required: {
type: Boolean, type: Boolean,
required: false required: false
}, },
readonly: {
type: Boolean,
required: false
},
disabled: { disabled: {
type: Boolean, type: Boolean,
required: false required: false
}, },
placeholder: {
type: String,
required: false
},
autofocus: {
type: Boolean,
required: false,
default: false
},
inline: { inline: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false default: false
}, },
}, manualSave: {
data() { type: Boolean,
return { required: false,
}; default: false
},
computed: {
v: {
get() {
return this.value;
},
set(v) {
this.$emit('update:value', v);
}
}, },
}, },
methods: {
focus() { emits: ['change', 'update:modelValue'],
this.$refs.input.focus();
} setup(props, context) {
} const { modelValue, autofocus } = toRefs(props);
const v = ref(modelValue.value);
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 updated = () => {
changed.value = false;
context.emit('update:modelValue', v.value);
};
watch(modelValue, 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 {
v,
focused,
invalid,
changed,
filled,
inputEl,
prefixEl,
suffixEl,
focus,
onInput,
updated,
};
},
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.yrtfrpux { .vblkjoeq {
position: relative; > .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
> .icon { &:empty {
position: absolute; display: none;
top: 0; }
left: 0; }
width: 24px;
text-align: center;
line-height: 32px;
&:not(:empty) + .input { > .caption {
margin-left: 28px; font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
} }
} }
> .input { > .input {
display: flex; $height: 42px;
position: relative; position: relative;
> select { > select {
appearance: none;
-webkit-appearance: none;
display: block; display: block;
flex: 1; height: $height;
width: 100%; width: 100%;
padding: 0 16px; margin: 0;
padding: 0 12px;
font: inherit; font: inherit;
font-weight: normal; font-weight: normal;
font-size: 1em; font-size: 1em;
height: 48px; color: var(--fg);
background: none; background: var(--panel);
border: none; border: solid 1px var(--inputBorder);
border-radius: 0; border-radius: 6px;
outline: none; outline: none;
box-shadow: none; box-shadow: none;
appearance: none; box-sizing: border-box;
-webkit-appearance: none; cursor: pointer;
color: var(--fg); transition: border-color 0.1s ease-out;
option, &:hover {
optgroup { border-color: var(--inputBorderHover);
color: var(--fg);
background: var(--bg);
} }
} }
> .prefix, > .prefix,
> .suffix { > .suffix {
display: block; display: flex;
align-self: center; align-items: center;
justify-self: center; position: absolute;
z-index: 1;
top: 0;
padding: 0 12px;
font-size: 1em; font-size: 1em;
line-height: 32px; height: $height;
color: var(--inputLabel);
pointer-events: none; pointer-events: none;
&:empty { &:empty {
@ -127,18 +218,42 @@ export default defineComponent({
} }
> * { > * {
display: block; display: inline-block;
min-width: 16px; min-width: 16px;
max-width: 150px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} }
} }
> .prefix { > .prefix {
padding-right: 4px; left: 0;
padding-right: 6px;
} }
> .suffix { > .suffix {
padding: 0 16px 0 0; right: 0;
padding-left: 6px;
}
&.inline {
display: inline-block;
margin: 0;
}
&.focused {
> select {
border-color: var(--accent);
}
}
&.disabled {
opacity: 0.7; opacity: 0.7;
&, * {
cursor: not-allowed !important;
}
} }
} }
} }

View File

@ -0,0 +1,50 @@
<template>
<div class="adhpbeou">
<div class="label" @click="focus"><slot name="label"></slot></div>
<div class="content">
<slot></slot>
</div>
<div class="caption"><slot name="caption"></slot></div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
});
</script>
<style lang="scss" scoped>
.adhpbeou {
margin: 1.5em 0;
> .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
&:empty {
display: none;
}
}
> .caption {
font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
}
}
> .content {
position: relative;
background: var(--panel);
border: solid 0.5px var(--inputBorder);
border-radius: 6px;
}
}
</style>

View File

@ -1,35 +1,34 @@
<template> <template>
<div class="ijnpvmgr _formItem"> <div
<div class="main _formPanel _formClickable" class="ziffeoms"
:class="{ disabled, checked }" :class="{ disabled, checked }"
:aria-checked="checked" role="switch"
:aria-disabled="disabled" :aria-checked="checked"
@click.prevent="toggle" :aria-disabled="disabled"
@click.prevent="toggle"
>
<input
type="checkbox"
ref="input"
:disabled="disabled"
@keydown.enter="toggle"
> >
<input <span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff">
type="checkbox" <span class="handle"></span>
ref="input" </span>
:disabled="disabled" <span class="label">
@keydown.enter="toggle" <span><slot></slot></span>
> <p><slot name="caption"></slot></p>
<span class="button"> </span>
<span></span>
</span>
<span class="label">
<span><slot></slot></span>
</span>
</div>
<div class="_formCaption"><slot name="desc"></slot></div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import './form.scss';
export default defineComponent({ export default defineComponent({
props: { props: {
value: { modelValue: {
type: Boolean, type: Boolean,
default: false default: false
}, },
@ -40,91 +39,110 @@ export default defineComponent({
}, },
computed: { computed: {
checked(): boolean { checked(): boolean {
return this.value; return this.modelValue;
} }
}, },
methods: { methods: {
toggle() { toggle() {
if (this.disabled) return; if (this.disabled) return;
this.$emit('update:value', !this.checked); this.$emit('update:modelValue', !this.checked);
} }
} }
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ijnpvmgr { .ziffeoms {
> .main { position: relative;
display: flex;
cursor: pointer;
transition: all 0.3s;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
> * {
user-select: none;
}
> input {
position: absolute;
width: 0;
height: 0;
opacity: 0;
margin: 0;
}
> .button {
position: relative; position: relative;
display: flex; display: inline-block;
padding: 14px 16px; flex-shrink: 0;
cursor: pointer; margin: 0;
width: 36px;
height: 26px;
background: var(--switchBg);
outline: none;
border-radius: 999px;
transition: inherit;
> * { > .handle {
user-select: none;
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
&.checked {
> .button {
background-color: var(--X10);
border-color: var(--X10);
> * {
background-color: var(--accent);
transform: translateX(14px);
}
}
}
> input {
position: absolute; position: absolute;
width: 0; top: 0;
height: 0; bottom: 0;
opacity: 0; left: 5px;
margin: 0; margin: auto 0;
border-radius: 100%;
transition: background-color 0.3s, transform 0.3s;
width: 16px;
height: 16px;
background-color: #fff;
} }
}
> .button { > .label {
position: relative; margin-left: 16px;
display: inline-block; margin-top: 2px;
flex-shrink: 0; display: block;
margin: 3px 0 0 0; cursor: pointer;
width: 34px; transition: inherit;
height: 14px; color: var(--fg);
background: var(--X6);
outline: none;
border-radius: 14px;
transition: all 0.3s;
cursor: pointer;
> * { > span {
position: absolute;
top: -3px;
left: 0;
border-radius: 100%;
transition: background-color 0.3s, transform 0.3s;
width: 20px;
height: 20px;
background-color: #fff;
box-shadow: 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12);
}
}
> .label {
margin-left: 12px;
display: block; display: block;
line-height: 20px;
transition: inherit; transition: inherit;
color: var(--fg); }
> span { > p {
display: block; margin: 0;
line-height: 20px; color: var(--fgTransparentWeak);
transition: inherit; font-size: 90%;
}
}
&:hover {
> .button {
background-color: var(--accentedBg);
}
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
&.checked {
> .button {
background-color: var(--accent);
border-color: var(--accent);
> .handle {
transform: translateX(10px);
} }
} }
} }

View File

@ -1,40 +1,45 @@
<template> <template>
<FormGroup class="_formItem"> <div class="adhpbeos">
<template #label><slot></slot></template> <div class="label" @click="focus"><slot name="label"></slot></div>
<div class="rivhosbp _formItem" :class="{ tall, pre }"> <div class="input" :class="{ disabled, focused, tall, pre }">
<div class="input _formPanel"> <textarea ref="inputEl"
<textarea ref="input" :class="{ code, _monospace: code }" :class="{ code, _monospace: code }"
v-model="v" v-model="v"
:required="required" :disabled="disabled"
:readonly="readonly" :required="required"
:pattern="pattern" :readonly="readonly"
:autocomplete="autocomplete" :placeholder="placeholder"
:spellcheck="!code" :pattern="pattern"
@input="onInput" :autocomplete="autocomplete"
@focus="focused = true" :spellcheck="spellcheck"
@blur="focused = false" @focus="focused = true"
></textarea> @blur="focused = false"
</div> @keydown="onKeydown($event)"
@input="onInput"
></textarea>
</div> </div>
<template #caption><slot name="desc"></slot></template> <div class="caption"><slot name="caption"></slot></div>
<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> <MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</FormGroup> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, toRefs, watch } from 'vue'; import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import './form.scss'; import MkButton from '../ui/button.vue';
import FormButton from './button.vue'; import { debounce } from 'throttle-debounce';
import FormGroup from './group.vue';
export default defineComponent({ export default defineComponent({
components: { components: {
FormGroup, MkButton,
FormButton,
}, },
props: { props: {
value: { modelValue: {
required: true
},
type: {
type: String,
required: false required: false
}, },
required: { required: {
@ -45,14 +50,29 @@ export default defineComponent({
type: Boolean, type: Boolean,
required: false required: false
}, },
disabled: {
type: Boolean,
required: false
},
pattern: { pattern: {
type: String, type: String,
required: false required: false
}, },
autocomplete: { placeholder: {
type: String, type: String,
required: false required: false
}, },
autofocus: {
type: Boolean,
required: false,
default: false
},
autocomplete: {
required: false
},
spellcheck: {
required: false
},
code: { code: {
type: Boolean, type: Boolean,
required: false required: false
@ -67,91 +87,162 @@ export default defineComponent({
required: false, required: false,
default: false default: false
}, },
debounce: {
type: Boolean,
required: false,
default: false
},
manualSave: { manualSave: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false default: false
}, },
}, },
emits: ['change', 'keydown', 'enter', 'update:modelValue'],
setup(props, context) { setup(props, context) {
const { value } = toRefs(props); const { modelValue, autofocus } = toRefs(props);
const v = ref(value.value); const v = ref(modelValue.value);
const focused = ref(false);
const changed = ref(false); const changed = ref(false);
const invalid = ref(false);
const filled = computed(() => v.value !== '' && v.value != null);
const inputEl = ref(null); const inputEl = ref(null);
const focus = () => inputEl.value.focus(); const focus = () => inputEl.value.focus();
const onInput = (ev) => { const onInput = (ev) => {
changed.value = true; changed.value = true;
context.emit('change', ev); context.emit('change', ev);
}; };
const onKeydown = (ev: KeyboardEvent) => {
context.emit('keydown', ev);
if (ev.code === 'Enter') {
context.emit('enter');
}
};
const updated = () => { const updated = () => {
changed.value = false; changed.value = false;
context.emit('update:value', v.value); context.emit('update:modelValue', v.value);
}; };
watch(value, newValue => { const debouncedUpdated = debounce(1000, updated);
watch(modelValue, newValue => {
v.value = newValue; v.value = newValue;
}); });
watch(v, newValue => { watch(v, newValue => {
if (!props.manualSave) { if (!props.manualSave) {
updated(); if (props.debounce) {
debouncedUpdated();
} else {
updated();
}
} }
invalid.value = inputEl.value.validity.badInput;
});
onMounted(() => {
nextTick(() => {
if (autofocus.value) {
focus();
}
});
}); });
return { return {
v, v,
updated, focused,
invalid,
changed, changed,
filled,
inputEl,
focus, focus,
onInput, onInput,
onKeydown,
updated,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.rivhosbp { .adhpbeos {
position: relative; > .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
&:empty {
display: none;
}
}
> .caption {
font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
}
}
> .input { > .input {
position: relative; position: relative;
> textarea { > textarea {
appearance: none;
-webkit-appearance: none;
display: block; display: block;
width: 100%; width: 100%;
min-width: 100%; min-width: 100%;
max-width: 100%; max-width: 100%;
min-height: 130px; min-height: 130px;
margin: 0; margin: 0;
padding: 16px; padding: 12px;
box-sizing: border-box;
font: inherit; font: inherit;
font-weight: normal; font-weight: normal;
font-size: 1em; font-size: 1em;
background: transparent; color: var(--fg);
border: none; background: var(--panel);
border-radius: 0; border: solid 0.5px var(--inputBorder);
border-radius: 6px;
outline: none; outline: none;
box-shadow: none; box-shadow: none;
color: var(--fg); box-sizing: border-box;
transition: border-color 0.1s ease-out;
&.code { &:hover {
tab-size: 2; border-color: var(--inputBorderHover);
} }
} }
}
&.tall { &.focused {
> .input { > textarea {
border-color: var(--accent);
}
}
&.disabled {
opacity: 0.7;
&, * {
cursor: not-allowed !important;
}
}
&.tall {
> textarea { > textarea {
min-height: 200px; min-height: 200px;
} }
} }
}
&.pre { &.pre {
> .input {
> textarea { > textarea {
white-space: pre; white-space: pre;
} }

View File

@ -36,7 +36,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, markRaw } from 'vue'; import { defineComponent, markRaw } from 'vue';
import Chart from 'chart.js'; import Chart from 'chart.js';
import MkSelect from './ui/select.vue'; import MkSelect from './form/select.vue';
import number from '@client/filters/number'; import number from '@client/filters/number';
const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b)); const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));

View File

@ -59,7 +59,7 @@
<div class="body"> <div class="body">
<p v-if="appearNote.cw != null" class="cw"> <p v-if="appearNote.cw != null" class="cw">
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/> <Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<XCwButton v-model:value="showContent" :note="appearNote"/> <XCwButton v-model="showContent" :note="appearNote"/>
</p> </p>
<div class="content" v-show="appearNote.cw == null || showContent"> <div class="content" v-show="appearNote.cw == null || showContent">
<div class="text"> <div class="text">

View File

@ -6,7 +6,7 @@
<div class="body"> <div class="body">
<p v-if="note.cw != null" class="cw"> <p v-if="note.cw != null" class="cw">
<span class="text" v-if="note.cw != ''">{{ note.cw }}</span> <span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
<XCwButton v-model:value="showContent" :note="note"/> <XCwButton v-model="showContent" :note="note"/>
</p> </p>
<div class="content" v-show="note.cw == null || showContent"> <div class="content" v-show="note.cw == null || showContent">
<XSubNote-content class="text" :note="note"/> <XSubNote-content class="text" :note="note"/>

View File

@ -7,7 +7,7 @@
<div class="body"> <div class="body">
<p v-if="note.cw != null" class="cw"> <p v-if="note.cw != null" class="cw">
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" /> <Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" />
<XCwButton v-model:value="showContent" :note="note"/> <XCwButton v-model="showContent" :note="note"/>
</p> </p>
<div class="content" v-show="note.cw == null || showContent"> <div class="content" v-show="note.cw == null || showContent">
<XSubNote-content class="text" :note="note"/> <XSubNote-content class="text" :note="note"/>

View File

@ -43,7 +43,7 @@
<div class="body"> <div class="body">
<p v-if="appearNote.cw != null" class="cw"> <p v-if="appearNote.cw != null" class="cw">
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/> <Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<XCwButton v-model:value="showContent" :note="appearNote"/> <XCwButton v-model="showContent" :note="appearNote"/>
</p> </p>
<div class="content" :class="{ collapsed }" v-show="appearNote.cw == null || showContent"> <div class="content" :class="{ collapsed }" v-show="appearNote.cw == null || showContent">
<div class="text"> <div class="text">

View File

@ -29,7 +29,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType } from 'vue'; import { defineComponent, PropType } from 'vue';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import MkSwitch from './ui/switch.vue'; import MkSwitch from './form/switch.vue';
import MkInfo from './ui/info.vue'; import MkInfo from './ui/info.vue';
import MkButton from './ui/button.vue'; import MkButton from './ui/button.vue';
import { notificationTypes } from '../../types'; import { notificationTypes } from '../../types';

View File

@ -8,7 +8,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import MkInput from '../ui/input.vue'; import MkInput from '../form/input.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { Hpml } from '@client/scripts/hpml/evaluator'; import { Hpml } from '@client/scripts/hpml/evaluator';
import { NumberInputVarBlock } from '@client/scripts/hpml/block'; import { NumberInputVarBlock } from '@client/scripts/hpml/block';

View File

@ -10,7 +10,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType } from 'vue'; import { defineComponent, PropType } from 'vue';
import MkTextarea from '../ui/textarea.vue'; import MkTextarea from '../form/textarea.vue';
import MkButton from '../ui/button.vue'; import MkButton from '../ui/button.vue';
import { apiUrl } from '@client/config'; import { apiUrl } from '@client/config';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -7,7 +7,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import MkRadio from '../ui/radio.vue'; import MkRadio from '../form/radio.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { Hpml } from '@client/scripts/hpml/evaluator'; import { Hpml } from '@client/scripts/hpml/evaluator';
import { RadioButtonVarBlock } from '@client/scripts/hpml/block'; import { RadioButtonVarBlock } from '@client/scripts/hpml/block';

View File

@ -6,7 +6,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import MkSwitch from '../ui/switch.vue'; import MkSwitch from '../form/switch.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { Hpml } from '@client/scripts/hpml/evaluator'; import { Hpml } from '@client/scripts/hpml/evaluator';
import { SwitchVarBlock } from '@client/scripts/hpml/block'; import { SwitchVarBlock } from '@client/scripts/hpml/block';

View File

@ -8,7 +8,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import MkInput from '../ui/input.vue'; import MkInput from '../form/input.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { Hpml } from '@client/scripts/hpml/evaluator'; import { Hpml } from '@client/scripts/hpml/evaluator';
import { TextInputVarBlock } from '@client/scripts/hpml/block'; import { TextInputVarBlock } from '@client/scripts/hpml/block';

View File

@ -8,7 +8,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import MkTextarea from '../ui/textarea.vue'; import MkTextarea from '../form/textarea.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { Hpml } from '@client/scripts/hpml/evaluator'; import { Hpml } from '@client/scripts/hpml/evaluator';
import { HpmlTextInput } from '@client/scripts/hpml'; import { HpmlTextInput } from '@client/scripts/hpml';

View File

@ -6,7 +6,7 @@
import { TextBlock } from '@client/scripts/hpml/block'; import { TextBlock } from '@client/scripts/hpml/block';
import { Hpml } from '@client/scripts/hpml/evaluator'; import { Hpml } from '@client/scripts/hpml/evaluator';
import { defineComponent, PropType } from 'vue'; import { defineComponent, PropType } from 'vue';
import MkTextarea from '../ui/textarea.vue'; import MkTextarea from '../form/textarea.vue';
export default defineComponent({ export default defineComponent({
components: { components: {

View File

@ -51,9 +51,9 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { addTime } from '../../prelude/time'; import { addTime } from '../../prelude/time';
import { formatDateTimeString } from '@/misc/format-time-string'; import { formatDateTimeString } from '@/misc/format-time-string';
import MkInput from './ui/input.vue'; import MkInput from './form/input.vue';
import MkSelect from './ui/select.vue'; import MkSelect from './form/select.vue';
import MkSwitch from './ui/switch.vue'; import MkSwitch from './form/switch.vue';
import MkButton from './ui/button.vue'; import MkButton from './ui/button.vue';
export default defineComponent({ export default defineComponent({

View File

@ -30,10 +30,10 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSwitch from '@client/components/ui/switch.vue'; import MkSwitch from '@client/components/form/switch.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import MkRadio from '@client/components/ui/radio.vue'; import MkRadio from '@client/components/form/radio.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as config from '@client/config'; import * as config from '@client/config';

View File

@ -1,17 +1,17 @@
<template> <template>
<form class="eppvobhk _monolithic_" :class="{ signing, totpLogin }" @submit.prevent="onSubmit"> <form class="eppvobhk _monolithic_" :class="{ signing, totpLogin }" @submit.prevent="onSubmit">
<div class="auth _section"> <div class="auth _section _formRoot">
<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div> <div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
<div class="normal-signin" v-if="!totpLogin"> <div class="normal-signin" v-if="!totpLogin">
<MkInput v-model="username" :placeholder="$ts.username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:modelValue="onUsernameChange" data-cy-signin-username> <MkInput class="_formBlock" v-model="username" :placeholder="$ts.username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:modelValue="onUsernameChange" data-cy-signin-username>
<template #prefix>@</template> <template #prefix>@</template>
<template #suffix>@{{ host }}</template> <template #suffix>@{{ host }}</template>
</MkInput> </MkInput>
<MkInput v-model="password" :placeholder="$ts.password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required data-cy-signin-password> <MkInput class="_formBlock" v-model="password" :placeholder="$ts.password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required data-cy-signin-password>
<template #prefix><i class="fas fa-lock"></i></template> <template #prefix><i class="fas fa-lock"></i></template>
<template #caption><button class="_textButton" @click="resetPassword" type="button">{{ $ts.forgotPassword }}</button></template> <template #caption><button class="_textButton" @click="resetPassword" type="button">{{ $ts.forgotPassword }}</button></template>
</MkInput> </MkInput>
<MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton> <MkButton class="_formBlock" type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
</div> </div>
<div class="2fa-signin" v-if="totpLogin" :class="{ securityKeys: user && user.securityKeys }"> <div class="2fa-signin" v-if="totpLogin" :class="{ securityKeys: user && user.securityKeys }">
<div v-if="user && user.securityKeys" class="twofa-group tap-group"> <div v-if="user && user.securityKeys" class="twofa-group tap-group">
@ -49,7 +49,7 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { toUnicode } from 'punycode/'; import { toUnicode } from 'punycode/';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import { apiUrl, host } from '@client/config'; import { apiUrl, host } from '@client/config';
import { byteify, hexify } from '@client/scripts/2fa'; import { byteify, hexify } from '@client/scripts/2fa';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -1,11 +1,11 @@
<template> <template>
<form class="qlvuhzng" @submit.prevent="onSubmit" :autocomplete="Math.random()"> <form class="qlvuhzng _formRoot" @submit.prevent="onSubmit" :autocomplete="Math.random()">
<template v-if="meta"> <template v-if="meta">
<MkInput class="_inputNoTopMargin" v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required> <MkInput class="_formBlock" v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
<template #label>{{ $ts.invitationCode }}</template> <template #label>{{ $ts.invitationCode }}</template>
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
</MkInput> </MkInput>
<MkInput class="_inputNoTopMargin" v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeUsername" data-cy-signup-username> <MkInput class="_formBlock" v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeUsername" data-cy-signup-username>
<template #label>{{ $ts.username }} <div class="_button _help" v-tooltip:dialog="$ts.usernameInfo"><i class="far fa-question-circle"></i></div></template> <template #label>{{ $ts.username }} <div class="_button _help" v-tooltip:dialog="$ts.usernameInfo"><i class="far fa-question-circle"></i></div></template>
<template #prefix>@</template> <template #prefix>@</template>
<template #suffix>@{{ host }}</template> <template #suffix>@{{ host }}</template>
@ -19,7 +19,7 @@
<span v-if="usernameState == 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.tooLong }}</span> <span v-if="usernameState == 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.tooLong }}</span>
</template> </template>
</MkInput> </MkInput>
<MkInput v-model="password" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePassword" data-cy-signup-password> <MkInput class="_formBlock" v-model="password" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePassword" data-cy-signup-password>
<template #label>{{ $ts.password }}</template> <template #label>{{ $ts.password }}</template>
<template #prefix><i class="fas fa-lock"></i></template> <template #prefix><i class="fas fa-lock"></i></template>
<template #caption> <template #caption>
@ -28,7 +28,7 @@
<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ $ts.strongPassword }}</span> <span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ $ts.strongPassword }}</span>
</template> </template>
</MkInput> </MkInput>
<MkInput v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePasswordRetype" data-cy-signup-password-retype> <MkInput class="_formBlock" v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePasswordRetype" data-cy-signup-password-retype>
<template #label>{{ $ts.password }} ({{ $ts.retype }})</template> <template #label>{{ $ts.password }} ({{ $ts.retype }})</template>
<template #prefix><i class="fas fa-lock"></i></template> <template #prefix><i class="fas fa-lock"></i></template>
<template #caption> <template #caption>
@ -36,7 +36,7 @@
<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.passwordNotMatched }}</span> <span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.passwordNotMatched }}</span>
</template> </template>
</MkInput> </MkInput>
<label v-if="meta.tosUrl" class="tou"> <label v-if="meta.tosUrl" class="_formBlock tou">
<input type="checkbox" v-model="ToSAgreement"> <input type="checkbox" v-model="ToSAgreement">
<I18n :src="$ts.agreeTo"> <I18n :src="$ts.agreeTo">
<template #0> <template #0>
@ -44,9 +44,9 @@
</template> </template>
</I18n> </I18n>
</label> </label>
<captcha v-if="meta.enableHcaptcha" class="captcha" provider="hcaptcha" ref="hcaptcha" v-model:value="hCaptchaResponse" :sitekey="meta.hcaptchaSiteKey"/> <captcha v-if="meta.enableHcaptcha" class="_formBlock captcha" provider="hcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :sitekey="meta.hcaptchaSiteKey"/>
<captcha v-if="meta.enableRecaptcha" class="captcha" provider="recaptcha" ref="recaptcha" v-model:value="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/> <captcha v-if="meta.enableRecaptcha" class="_formBlock captcha" provider="recaptcha" ref="recaptcha" v-model="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary data-cy-signup-submit>{{ $ts.start }}</MkButton> <MkButton class="_formBlock" type="submit" :disabled="shouldDisableSubmitting" primary data-cy-signup-submit>{{ $ts.start }}</MkButton>
</template> </template>
</form> </form>
</template> </template>
@ -57,8 +57,8 @@ const getPasswordStrength = require('syuilo-password-strength');
import { toUnicode } from 'punycode/'; import { toUnicode } from 'punycode/';
import { host, url } from '@client/config'; import { host, url } from '@client/config';
import MkButton from './ui/button.vue'; import MkButton from './ui/button.vue';
import MkInput from './ui/input.vue'; import MkInput from './form/input.vue';
import MkSwitch from './ui/switch.vue'; import MkSwitch from './form/switch.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { login } from '@client/account'; import { login } from '@client/account';

View File

@ -3,7 +3,7 @@ import { defineComponent, h, resolveDirective, withDirectives } from 'vue';
export default defineComponent({ export default defineComponent({
props: { props: {
value: { modelValue: {
required: true, required: true,
}, },
}, },
@ -13,11 +13,11 @@ export default defineComponent({
return withDirectives(h('div', { return withDirectives(h('div', {
class: 'pxhvhrfw', class: 'pxhvhrfw',
}, options.map(option => withDirectives(h('button', { }, options.map(option => withDirectives(h('button', {
class: ['_button', { active: this.value === option.props.value }], class: ['_button', { active: this.modelValue === option.props.modelValue }],
key: option.key, key: option.key,
disabled: this.value === option.props.value, disabled: this.modelValue === option.props.modelValue,
onClick: () => { onClick: () => {
this.$emit('update:value', option.props.value); this.$emit('update:modelValue', option.props.modelValue);
} }
}, option.children), [ }, option.children), [
[resolveDirective('click-anime')] [resolveDirective('click-anime')]

View File

@ -9,7 +9,7 @@
<template #header>Req Viewer</template> <template #header>Req Viewer</template>
<div class="rlkneywz"> <div class="rlkneywz">
<MkTab v-model:value="tab" style="border-bottom: solid 0.5px var(--divider);"> <MkTab v-model="tab" style="border-bottom: solid 0.5px var(--divider);">
<option value="req">Request</option> <option value="req">Request</option>
<option value="res">Response</option> <option value="res">Response</option>
</MkTab> </MkTab>

View File

@ -4,7 +4,7 @@
<i class="fas fa-terminal" style="margin-right: 0.5em;"></i>Task Manager <i class="fas fa-terminal" style="margin-right: 0.5em;"></i>Task Manager
</template> </template>
<div class="qljqmnzj _monospace"> <div class="qljqmnzj _monospace">
<MkTab v-model:value="tab" style="border-bottom: solid 0.5px var(--divider);"> <MkTab v-model="tab" style="border-bottom: solid 0.5px var(--divider);">
<option value="windows">Windows</option> <option value="windows">Windows</option>
<option value="stream">Stream</option> <option value="stream">Stream</option>
<option value="streamPool">Stream (Pool)</option> <option value="streamPool">Stream (Pool)</option>

View File

@ -31,9 +31,9 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { kinds } from '@/misc/api-permissions'; import { kinds } from '@/misc/api-permissions';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import MkInput from './ui/input.vue'; import MkInput from './form/input.vue';
import MkTextarea from './ui/textarea.vue'; import MkTextarea from './form/textarea.vue';
import MkSwitch from './ui/switch.vue'; import MkSwitch from './form/switch.vue';
import MkButton from './ui/button.vue'; import MkButton from './ui/button.vue';
import MkInfo from './ui/info.vue'; import MkInfo from './ui/info.vue';

View File

@ -181,14 +181,6 @@ export default defineComponent({
outline-offset: 2px; outline-offset: 2px;
} }
&.inline + .bghgjjyj {
margin-left: 12px;
}
&:not(.inline) + .bghgjjyj {
margin-top: 16px;
}
&.inline { &.inline {
display: inline-block; display: inline-block;
width: auto; width: auto;

View File

@ -1,58 +0,0 @@
<script lang="ts">
import { defineComponent, h } from 'vue';
import MkRadio from '@client/components/ui/radio.vue';
export default defineComponent({
components: {
MkRadio
},
props: {
modelValue: {
required: false
},
},
data() {
return {
value: this.modelValue,
}
},
watch: {
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: 'novjtcto'
}, [
h('div', label),
...options.map(option => h(MkRadio, {
key: option.key,
value: option.props.value,
modelValue: this.value,
'onUpdate:modelValue': value => this.value = value,
}, option.children))
]);
}
});
</script>
<style lang="scss">
.novjtcto {
margin: 32px 0;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
</style>

View File

@ -1,139 +0,0 @@
<template>
<div class="timctyfi" :class="{ focused, disabled }">
<div class="icon"><slot name="icon"></slot></div>
<span class="label"><slot name="label"></slot></span>
<input
type="range"
ref="input"
v-model="v"
:disabled="disabled"
:min="min"
:max="max"
:step="step"
:autofocus="autofocus"
@focus="focused = true"
@blur="focused = false"
@input="$emit('update:value', $event.target.value)"
/>
</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
},
autofocus: {
type: Boolean,
required: false
}
},
data() {
return {
v: this.value,
focused: false
};
},
watch: {
value(v) {
this.v = parseFloat(v);
}
},
mounted() {
if (this.autofocus) {
this.$nextTick(() => {
this.$refs.input.focus();
});
}
}
});
</script>
<style lang="scss" scoped>
.timctyfi {
position: relative;
margin: 8px;
> .icon {
display: inline-block;
width: 24px;
text-align: center;
}
> .title {
pointer-events: none;
font-size: 16px;
color: var(--inputLabel);
overflow: hidden;
}
> input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: var(--X10);
height: 7px;
margin: 0 8px;
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>

View File

@ -1,262 +0,0 @@
<template>
<div class="vblkjoeq">
<div class="label" @click="focus"><slot name="label"></slot></div>
<div class="input" :class="{ inline, disabled, focused }">
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
<select ref="inputEl"
v-model="v"
:disabled="disabled"
:required="required"
:readonly="readonly"
:placeholder="placeholder"
@focus="focused = true"
@blur="focused = false"
@input="onInput"
>
<slot></slot>
</select>
<div class="suffix" ref="suffixEl"><i class="fas fa-chevron-down"></i></div>
</div>
<div class="caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import MkButton from './button.vue';
export default defineComponent({
components: {
MkButton,
},
props: {
modelValue: {
required: true
},
required: {
type: Boolean,
required: false
},
readonly: {
type: Boolean,
required: false
},
disabled: {
type: Boolean,
required: false
},
placeholder: {
type: String,
required: false
},
autofocus: {
type: Boolean,
required: false,
default: false
},
inline: {
type: Boolean,
required: false,
default: false
},
manualSave: {
type: Boolean,
required: false,
default: false
},
},
emits: ['change', 'update:modelValue'],
setup(props, context) {
const { modelValue, autofocus } = toRefs(props);
const v = ref(modelValue.value);
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 updated = () => {
changed.value = false;
context.emit('update:modelValue', v.value);
};
watch(modelValue, 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 {
v,
focused,
invalid,
changed,
filled,
inputEl,
prefixEl,
suffixEl,
focus,
onInput,
updated,
};
},
});
</script>
<style lang="scss" scoped>
.vblkjoeq {
margin: 1.5em 0;
> .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
&:empty {
display: none;
}
}
> .caption {
font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
}
}
> .input {
$height: 42px;
position: relative;
> select {
appearance: none;
-webkit-appearance: none;
display: block;
height: $height;
width: 100%;
margin: 0;
padding: 0 12px;
font: inherit;
font-weight: normal;
font-size: 1em;
color: var(--fg);
background: var(--panel);
border: solid 1px var(--inputBorder);
border-radius: 6px;
outline: none;
box-shadow: none;
box-sizing: border-box;
cursor: pointer;
transition: border-color 0.1s ease-out;
&:hover {
border-color: var(--inputBorderHover);
}
}
> .prefix,
> .suffix {
display: flex;
align-items: center;
position: absolute;
z-index: 1;
top: 0;
padding: 0 12px;
font-size: 1em;
height: $height;
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: 6px;
}
> .suffix {
right: 0;
padding-left: 6px;
}
&.inline {
display: inline-block;
margin: 0;
}
&.focused {
> select {
border-color: var(--accent);
}
}
&.disabled {
opacity: 0.7;
&, * {
cursor: not-allowed !important;
}
}
}
}
</style>

View File

@ -1,144 +0,0 @@
<template>
<div
class="ziffeoms"
:class="{ disabled, checked }"
role="switch"
:aria-checked="checked"
:aria-disabled="disabled"
@click.prevent="toggle"
>
<input
type="checkbox"
ref="input"
:disabled="disabled"
@keydown.enter="toggle"
>
<span class="button">
<span></span>
</span>
<span class="label">
<span><slot></slot></span>
<p><slot name="caption"></slot></p>
</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
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>
.ziffeoms {
position: relative;
display: flex;
margin: 32px 0;
cursor: pointer;
transition: all 0.3s;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
> * {
user-select: none;
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
&.checked {
> .button {
background-color: var(--X10);
border-color: var(--X10);
> * {
background-color: var(--accent);
transform: translateX(14px);
}
}
}
> input {
position: absolute;
width: 0;
height: 0;
opacity: 0;
margin: 0;
}
> .button {
position: relative;
display: inline-block;
flex-shrink: 0;
margin: 3px 0 0 0;
width: 34px;
height: 14px;
background: var(--X6);
outline: none;
border-radius: 14px;
transition: inherit;
> * {
position: absolute;
top: -3px;
left: 0;
border-radius: 100%;
transition: background-color 0.3s, transform 0.3s;
width: 20px;
height: 20px;
background-color: #fff;
box-shadow: 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12);
}
}
> .label {
margin-left: 8px;
display: block;
cursor: pointer;
transition: inherit;
color: var(--fg);
> span {
display: block;
line-height: 20px;
transition: inherit;
}
> p {
margin: 0;
color: var(--fgTransparentWeak);
font-size: 90%;
}
}
}
</style>

View File

@ -1,254 +0,0 @@
<template>
<div class="adhpbeos">
<div class="label" @click="focus"><slot name="label"></slot></div>
<div class="input" :class="{ disabled, focused, tall, pre }">
<textarea ref="inputEl"
:class="{ code, _monospace: code }"
v-model="v"
:disabled="disabled"
:required="required"
:readonly="readonly"
:placeholder="placeholder"
:pattern="pattern"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
@focus="focused = true"
@blur="focused = false"
@keydown="onKeydown($event)"
@input="onInput"
></textarea>
</div>
<div class="caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import MkButton from './button.vue';
import { debounce } from 'throttle-debounce';
export default defineComponent({
components: {
MkButton,
},
props: {
modelValue: {
required: true
},
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
},
code: {
type: Boolean,
required: false
},
tall: {
type: Boolean,
required: false,
default: false
},
pre: {
type: Boolean,
required: false,
default: false
},
debounce: {
type: Boolean,
required: false,
default: false
},
manualSave: {
type: Boolean,
required: false,
default: false
},
},
emits: ['change', 'keydown', 'enter', 'update:modelValue'],
setup(props, context) {
const { modelValue, autofocus } = toRefs(props);
const v = ref(modelValue.value);
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 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;
context.emit('update:modelValue', v.value);
};
const debouncedUpdated = debounce(1000, updated);
watch(modelValue, newValue => {
v.value = newValue;
});
watch(v, newValue => {
if (!props.manualSave) {
if (props.debounce) {
debouncedUpdated();
} else {
updated();
}
}
invalid.value = inputEl.value.validity.badInput;
});
onMounted(() => {
nextTick(() => {
if (autofocus.value) {
focus();
}
});
});
return {
v,
focused,
invalid,
changed,
filled,
inputEl,
focus,
onInput,
onKeydown,
updated,
};
},
});
</script>
<style lang="scss" scoped>
.adhpbeos {
margin: 1.5em 0;
> .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
&:empty {
display: none;
}
}
> .caption {
font-size: 0.8em;
padding: 8px 0 0 12px;
color: var(--fgTransparentWeak);
&:empty {
display: none;
}
}
> .input {
position: relative;
> textarea {
appearance: none;
-webkit-appearance: none;
display: block;
width: 100%;
min-width: 100%;
max-width: 100%;
min-height: 130px;
margin: 0;
padding: 12px;
font: inherit;
font-weight: normal;
font-size: 1em;
color: var(--fg);
background: var(--panel);
border: solid 0.5px var(--inputBorder);
border-radius: 6px;
outline: none;
box-shadow: none;
box-sizing: border-box;
transition: border-color 0.1s ease-out;
&:hover {
border-color: var(--inputBorderHover);
}
}
&.focused {
> textarea {
border-color: var(--accent);
}
}
&.disabled {
opacity: 0.7;
&, * {
cursor: not-allowed !important;
}
}
&.tall {
> textarea {
min-height: 200px;
}
}
&.pre {
> textarea {
white-space: pre;
}
}
}
}
</style>

View File

@ -10,7 +10,7 @@
<template #header>{{ $ts.selectUser }}</template> <template #header>{{ $ts.selectUser }}</template>
<div class="tbhwbxda _monolithic_"> <div class="tbhwbxda _monolithic_">
<div class="_section"> <div class="_section">
<div class="_inputSplit _inputNoTopMargin _inputNoBottomMargin"> <div class="_inputSplit">
<MkInput v-model="username" class="input" @update:modelValue="search" ref="username"> <MkInput v-model="username" class="input" @update:modelValue="search" ref="username">
<template #label>{{ $ts.username }}</template> <template #label>{{ $ts.username }}</template>
<template #prefix>@</template> <template #prefix>@</template>
@ -52,7 +52,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkInput from './ui/input.vue'; import MkInput from './form/input.vue';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -30,7 +30,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue'; import { defineComponent, defineAsyncComponent } from 'vue';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import { widgets as widgetDefs } from '@client/widgets'; import { widgets as widgetDefs } from '@client/widgets';

View File

@ -2,15 +2,15 @@
<div style="overflow: clip;"> <div style="overflow: clip;">
<FormBase class="znqjceqz"> <FormBase class="znqjceqz">
<div id="debug"></div> <div id="debug"></div>
<section class="_formItem about"> <section class="_debobigegoItem about">
<div class="_formPanel panel" :class="{ playing: easterEggEngine != null }" ref="about"> <div class="_debobigegoPanel panel" :class="{ playing: easterEggEngine != null }" ref="about">
<img src="/static-assets/client/about-icon.png" alt="" class="icon" @load="iconLoaded" draggable="false" @click="gravity"/> <img src="/static-assets/client/about-icon.png" alt="" class="icon" @load="iconLoaded" draggable="false" @click="gravity"/>
<div class="misskey">Misskey</div> <div class="misskey">Misskey</div>
<div class="version">v{{ version }}</div> <div class="version">v{{ version }}</div>
<span class="emoji" v-for="emoji in easterEggEmojis" :key="emoji.id" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }"><MkEmoji class="emoji" :emoji="emoji.emoji" :custom-emojis="$instance.emojis" :is-reaction="false" :normal="true" :no-style="true"/></span> <span class="emoji" v-for="emoji in easterEggEmojis" :key="emoji.id" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }"><MkEmoji class="emoji" :emoji="emoji.emoji" :custom-emojis="$instance.emojis" :is-reaction="false" :normal="true" :no-style="true"/></span>
</div> </div>
</section> </section>
<section class="_formItem" style="text-align: center; padding: 0 16px;"> <section class="_debobigegoItem" style="text-align: center; padding: 0 16px;">
{{ $ts._aboutMisskey.about }}<br><MkA class="_link" to="/docs/general/misskey">{{ $ts.learnMore }}</MkA> {{ $ts._aboutMisskey.about }}<br><MkA class="_link" to="/docs/general/misskey">{{ $ts.learnMore }}</MkA>
</section> </section>
<FormGroup> <FormGroup>
@ -55,10 +55,10 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { version } from '@client/config'; import { version } from '@client/config';
import FormLink from '@client/components/form/link.vue'; import FormLink from '@client/components/debobigego/link.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue'; import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
import MkLink from '@client/components/link.vue'; import MkLink from '@client/components/link.vue';
import { physics } from '@client/scripts/physics'; import { physics } from '@client/scripts/physics';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -1,7 +1,7 @@
<template> <template>
<FormBase> <FormBase>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formPanel fwhjspax"> <div class="_debobigegoPanel fwhjspax">
<img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/> <img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
<span class="name">{{ $instance.name || host }}</span> <span class="name">{{ $instance.name || host }}</span>
</div> </div>
@ -59,12 +59,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { version, instanceName } from '@client/config'; import { version, instanceName } from '@client/config';
import FormLink from '@client/components/form/link.vue'; import FormLink from '@client/components/debobigego/link.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue'; import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import number from '@client/filters/number'; import number from '@client/filters/number';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -4,7 +4,7 @@
<div class="_content"> <div class="_content">
<details> <details>
<summary>{{ $ts.import }}</summary> <summary>{{ $ts.import }}</summary>
<MkTextarea v-model:value="themeToImport"> <MkTextarea v-model="themeToImport">
{{ $ts._theme.importInfo }} {{ $ts._theme.importInfo }}
</MkTextarea> </MkTextarea>
<MkButton :disabled="!themeToImport.trim()" @click="importTheme">{{ $ts.import }}</MkButton> <MkButton :disabled="!themeToImport.trim()" @click="importTheme">{{ $ts.import }}</MkButton>
@ -14,9 +14,9 @@
<section class="_section"> <section class="_section">
<div class="_content _card _gap"> <div class="_content _card _gap">
<div class="_content"> <div class="_content">
<MkInput v-model:value="name" required><span>{{ $ts.name }}</span></MkInput> <MkInput v-model="name" required><span>{{ $ts.name }}</span></MkInput>
<MkInput v-model:value="author" required><span>{{ $ts.author }}</span></MkInput> <MkInput v-model="author" required><span>{{ $ts.author }}</span></MkInput>
<MkTextarea v-model:value="description"><span>{{ $ts.description }}</span></MkTextarea> <MkTextarea v-model="description"><span>{{ $ts.description }}</span></MkTextarea>
<div class="_inputs"> <div class="_inputs">
<div v-text="$ts._theme.base" /> <div v-text="$ts._theme.base" />
<MkRadio v-model="baseTheme" value="light">{{ $ts.light }}</MkRadio> <MkRadio v-model="baseTheme" value="light">{{ $ts.light }}</MkRadio>
@ -41,31 +41,31 @@
<!-- color --> <!-- color -->
<div v-else-if="typeof v === 'string'" class="color"> <div v-else-if="typeof v === 'string'" class="color">
<input type="color" :value="v" @input="colorChanged($event.target.value, i)"/> <input type="color" :value="v" @input="colorChanged($event.target.value, i)"/>
<MkInput class="select" :value="v" @update:value="colorChanged($event, i)"/> <MkInput class="select" :value="v" @update:modelValue="colorChanged($event, i)"/>
</div> </div>
<!-- ref const --> <!-- ref const -->
<MkInput v-else-if="v.type === 'refConst'" v-model:value="v.key"> <MkInput v-else-if="v.type === 'refConst'" v-model="v.key">
<template #prefix>$</template> <template #prefix>$</template>
<span>{{ $ts.name }}</span> <span>{{ $ts.name }}</span>
</MkInput> </MkInput>
<!-- ref props --> <!-- ref props -->
<MkSelect class="select" v-else-if="v.type === 'refProp'" v-model:value="v.key"> <MkSelect class="select" v-else-if="v.type === 'refProp'" v-model="v.key">
<option v-for="key in themeProps" :value="key" :key="key">{{ $t('_theme.keys.' + key) }}</option> <option v-for="key in themeProps" :value="key" :key="key">{{ $t('_theme.keys.' + key) }}</option>
</MkSelect> </MkSelect>
<!-- func --> <!-- func -->
<template v-else-if="v.type === 'func'"> <template v-else-if="v.type === 'func'">
<MkSelect class="select" v-model:value="v.name"> <MkSelect class="select" v-model="v.name">
<template #label>{{ $ts._theme.funcKind }}</template> <template #label>{{ $ts._theme.funcKind }}</template>
<option v-for="n in ['alpha', 'darken', 'lighten']" :value="n" :key="n">{{ $t('_theme.' + n) }}</option> <option v-for="n in ['alpha', 'darken', 'lighten']" :value="n" :key="n">{{ $t('_theme.' + n) }}</option>
</MkSelect> </MkSelect>
<MkInput type="number" v-model:value="v.arg"><span>{{ $ts._theme.argument }}</span></MkInput> <MkInput type="number" v-model="v.arg"><span>{{ $ts._theme.argument }}</span></MkInput>
<MkSelect class="select" v-model:value="v.value"> <MkSelect class="select" v-model="v.value">
<template #label>{{ $ts._theme.basedProp }}</template> <template #label>{{ $ts._theme.basedProp }}</template>
<option v-for="key in themeProps" :value="key" :key="key">{{ $t('_theme.keys.' + key) }}</option> <option v-for="key in themeProps" :value="key" :key="key">{{ $t('_theme.keys.' + key) }}</option>
</MkSelect> </MkSelect>
</template> </template>
<!-- CSS --> <!-- CSS -->
<MkInput v-else-if="v.type === 'css'" v-model:value="v.value"> <MkInput v-else-if="v.type === 'css'" v-model="v.value">
<span>CSS</span> <span>CSS</span>
</MkInput> </MkInput>
</div> </div>
@ -95,11 +95,11 @@ import { defineComponent } from 'vue';
import * as JSON5 from 'json5'; import * as JSON5 from 'json5';
import { toUnicode } from 'punycode/'; import { toUnicode } from 'punycode/';
import MkRadio from '@client/components/ui/radio.vue'; import MkRadio from '@client/components/form/radio.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkSample from '@client/components/sample.vue'; import MkSample from '@client/components/sample.vue';
import { convertToMisskeyTheme, ThemeValue, convertToViewModel, ThemeViewModel } from '@client/scripts/theme-editor'; import { convertToMisskeyTheme, ThemeValue, convertToViewModel, ThemeViewModel } from '@client/scripts/theme-editor';

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="_root"> <div class="_root">
<div class="_block" style="padding: 24px;"> <div class="_block" style="padding: 24px;">
<MkInput v-model="endpoint" :datalist="endpoints" @update:modelValue="onEndpointChange()" class="_inputNoTopMargin"> <MkInput v-model="endpoint" :datalist="endpoints" @update:modelValue="onEndpointChange()" class="">
<template #label>Endpoint</template> <template #label>Endpoint</template>
</MkInput> </MkInput>
<MkTextarea v-model="body" code> <MkTextarea v-model="body" code>
@ -27,9 +27,9 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import * as JSON5 from 'json5'; import * as JSON5 from 'json5';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import MkSwitch from '@client/components/ui/switch.vue'; import MkSwitch from '@client/components/form/switch.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -27,9 +27,9 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import { selectFile } from '@client/scripts/select-file'; import { selectFile } from '@client/scripts/select-file';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="_section" style="padding: 0;" v-if="$i"> <div class="_section" style="padding: 0;" v-if="$i">
<MkTab class="_content" v-model:value="tab"> <MkTab class="_content" v-model="tab">
<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._channel.featured }}</option> <option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._channel.featured }}</option>
<option value="following"><i class="fas fa-heart"></i> {{ $ts._channel.following }}</option> <option value="following"><i class="fas fa-heart"></i> {{ $ts._channel.following }}</option>
<option value="owned"><i class="fas fa-edit"></i> {{ $ts._channel.owned }}</option> <option value="owned"><i class="fas fa-edit"></i> {{ $ts._channel.owned }}</option>

View File

@ -2,7 +2,7 @@
<div class="vtaihdtm"> <div class="vtaihdtm">
<div class="body"> <div class="body">
<div class="search"> <div class="search">
<MkInput v-model="query" :debounce="true" type="search" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search"> <MkInput v-model="query" :debounce="true" type="search" class="" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template> <template #prefix><i class="fas fa-search"></i></template>
</MkInput> </MkInput>
</div> </div>
@ -57,7 +57,7 @@ import { defineComponent } from 'vue';
import { url, lang } from '@client/config'; import { url, lang } from '@client/config';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
export default defineComponent({ export default defineComponent({
components: { components: {

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="driuhtrh"> <div class="driuhtrh">
<div class="query"> <div class="query">
<MkInput v-model="q" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search"> <MkInput v-model="q" class="" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template> <template #prefix><i class="fas fa-search"></i></template>
</MkInput> </MkInput>
@ -31,8 +31,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import MkTab from '@client/components/tab.vue'; import MkTab from '@client/components/tab.vue';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -75,7 +75,7 @@
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import XUserList from '@client/components/user-list.vue'; import XUserList from '@client/components/user-list.vue';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import number from '@client/filters/number'; import number from '@client/filters/number';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="taeiyria"> <div class="taeiyria">
<div class="query"> <div class="query">
<MkInput v-model="host" :debounce="true" class="_inputNoTopMargin"> <MkInput v-model="host" :debounce="true" class="">
<template #prefix><i class="fas fa-search"></i></template> <template #prefix><i class="fas fa-search"></i></template>
<template #label>{{ $ts.host }}</template> <template #label>{{ $ts.host }}</template>
</MkInput> </MkInput>
<div class="_inputSplit _inputNoBottomMargin"> <div class="_inputSplit">
<MkSelect v-model="state"> <MkSelect v-model="state">
<template #label>{{ $ts.state }}</template> <template #label>{{ $ts.state }}</template>
<option value="all">{{ $ts.all }}</option> <option value="all">{{ $ts.all }}</option>
@ -96,8 +96,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -1,23 +1,23 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormInput v-model:value="title"> <FormInput v-model="title">
<span>{{ $ts.title }}</span> <span>{{ $ts.title }}</span>
</FormInput> </FormInput>
<FormTextarea v-model:value="description" :max="500"> <FormTextarea v-model="description" :max="500">
<span>{{ $ts.description }}</span> <span>{{ $ts.description }}</span>
</FormTextarea> </FormTextarea>
<FormGroup> <FormGroup>
<div v-for="file in files" :key="file.id" class="_formItem _formPanel wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }"> <div v-for="file in files" :key="file.id" class="_debobigegoItem _debobigegoPanel wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }">
<div class="name">{{ file.name }}</div> <div class="name">{{ file.name }}</div>
<button class="remove _button" @click="remove(file)" v-tooltip="$ts.remove"><i class="fas fa-times"></i></button> <button class="remove _button" @click="remove(file)" v-tooltip="$ts.remove"><i class="fas fa-times"></i></button>
</div> </div>
<FormButton @click="selectFile" primary><i class="fas fa-plus"></i> {{ $ts.attachFile }}</FormButton> <FormButton @click="selectFile" primary><i class="fas fa-plus"></i> {{ $ts.attachFile }}</FormButton>
</FormGroup> </FormGroup>
<FormSwitch v-model:value="isSensitive">{{ $ts.markAsSensitive }}</FormSwitch> <FormSwitch v-model="isSensitive">{{ $ts.markAsSensitive }}</FormSwitch>
<FormButton v-if="postId" @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> <FormButton v-if="postId" @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
<FormButton v-else @click="save" primary><i class="fas fa-save"></i> {{ $ts.publish }}</FormButton> <FormButton v-else @click="save" primary><i class="fas fa-save"></i> {{ $ts.publish }}</FormButton>
@ -29,14 +29,14 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormTuple from '@client/components/form/tuple.vue'; import FormTuple from '@client/components/debobigego/tuple.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import { selectFile } from '@client/scripts/select-file'; import { selectFile } from '@client/scripts/select-file';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="xprsixdl _root"> <div class="xprsixdl _root">
<MkTab v-model:value="tab" v-if="$i"> <MkTab v-model="tab" v-if="$i">
<option value="explore"><i class="fas fa-icons"></i> {{ $ts.gallery }}</option> <option value="explore"><i class="fas fa-icons"></i> {{ $ts.gallery }}</option>
<option value="liked"><i class="fas fa-heart"></i> {{ $ts._gallery.liked }}</option> <option value="liked"><i class="fas fa-heart"></i> {{ $ts._gallery.liked }}</option>
<option value="my"><i class="fas fa-edit"></i> {{ $ts._gallery.my }}</option> <option value="my"><i class="fas fa-edit"></i> {{ $ts._gallery.my }}</option>
@ -46,7 +46,7 @@
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import XUserList from '@client/components/user-list.vue'; import XUserList from '@client/components/user-list.vue';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkTab from '@client/components/tab.vue'; import MkTab from '@client/components/tab.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';

View File

@ -3,8 +3,8 @@
<FormGroup v-if="instance"> <FormGroup v-if="instance">
<template #label>{{ instance.host }}</template> <template #label>{{ instance.host }}</template>
<FormGroup> <FormGroup>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formPanel fnfelxur"> <div class="_debobigegoPanel fnfelxur">
<img :src="instance.iconUrl || instance.faviconUrl" alt="" class="icon"/> <img :src="instance.iconUrl || instance.faviconUrl" alt="" class="icon"/>
</div> </div>
</div> </div>
@ -60,9 +60,9 @@
<template #value>{{ instance.openRegistrations ? $ts.yes : $ts.no }}</template> <template #value>{{ instance.openRegistrations ? $ts.yes : $ts.no }}</template>
</FormKeyValueView> </FormKeyValueView>
</FormGroup> </FormGroup>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formLabel">{{ $ts.statistics }}</div> <div class="_debobigegoLabel">{{ $ts.statistics }}</div>
<div class="_formPanel cmhjzshl"> <div class="_debobigegoPanel cmhjzshl">
<div class="selects"> <div class="selects">
<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;"> <MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
<option value="requests">{{ $ts._instanceCharts.requests }}</option> <option value="requests">{{ $ts._instanceCharts.requests }}</option>
@ -136,15 +136,15 @@
<script lang="ts"> <script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue'; import { defineAsyncComponent, defineComponent } from 'vue';
import Chart from 'chart.js'; import Chart from 'chart.js';
import FormObjectView from '@client/components/form/object-view.vue'; import FormObjectView from '@client/components/debobigego/object-view.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormLink from '@client/components/form/link.vue'; import FormLink from '@client/components/debobigego/link.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue'; import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import number from '@client/filters/number'; import number from '@client/filters/number';
import bytes from '@client/filters/bytes'; import bytes from '@client/filters/bytes';

View File

@ -24,10 +24,10 @@
</div> </div>
<!-- TODO <!-- TODO
<div class="inputs" style="display: flex; padding-top: 1.2em;"> <div class="inputs" style="display: flex; padding-top: 1.2em;">
<MkInput v-model:value="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.reports.reload()"> <MkInput v-model="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.reports.reload()">
<span>{{ $ts.username }}</span> <span>{{ $ts.username }}</span>
</MkInput> </MkInput>
<MkInput v-model:value="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.reports.reload()" :disabled="pagination.params().origin === 'local'"> <MkInput v-model="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.reports.reload()" :disabled="pagination.params().origin === 'local'">
<span>{{ $ts.host }}</span> <span>{{ $ts.host }}</span>
</MkInput> </MkInput>
</div> </div>
@ -65,8 +65,8 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { parseAcct } from '@/misc/acct'; import { parseAcct } from '@/misc/acct';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import { acct } from '@client/filters/user'; import { acct } from '@client/filters/user';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -44,9 +44,9 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import MkRadio from '@client/components/ui/radio.vue'; import MkRadio from '@client/components/form/radio.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -25,8 +25,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -9,43 +9,43 @@
</FormRadios> </FormRadios>
<template v-if="provider === 'hcaptcha'"> <template v-if="provider === 'hcaptcha'">
<div class="_formItem _formNoConcat" v-sticky-container> <div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
<div class="_formLabel">hCaptcha</div> <div class="_debobigegoLabel">hCaptcha</div>
<div class="main"> <div class="main">
<FormInput v-model:value="hcaptchaSiteKey"> <FormInput v-model="hcaptchaSiteKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
<span>{{ $ts.hcaptchaSiteKey }}</span> <span>{{ $ts.hcaptchaSiteKey }}</span>
</FormInput> </FormInput>
<FormInput v-model:value="hcaptchaSecretKey"> <FormInput v-model="hcaptchaSecretKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
<span>{{ $ts.hcaptchaSecretKey }}</span> <span>{{ $ts.hcaptchaSecretKey }}</span>
</FormInput> </FormInput>
</div> </div>
</div> </div>
<div class="_formItem _formNoConcat" v-sticky-container> <div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
<div class="_formLabel">{{ $ts.preview }}</div> <div class="_debobigegoLabel">{{ $ts.preview }}</div>
<div class="_formPanel" style="padding: var(--formContentHMargin);"> <div class="_debobigegoPanel" style="padding: var(--debobigegoContentHMargin);">
<MkCaptcha provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/> <MkCaptcha provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/>
</div> </div>
</div> </div>
</template> </template>
<template v-else-if="provider === 'recaptcha'"> <template v-else-if="provider === 'recaptcha'">
<div class="_formItem _formNoConcat" v-sticky-container> <div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
<div class="_formLabel">reCAPTCHA</div> <div class="_debobigegoLabel">reCAPTCHA</div>
<div class="main"> <div class="main">
<FormInput v-model:value="recaptchaSiteKey"> <FormInput v-model="recaptchaSiteKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
<span>{{ $ts.recaptchaSiteKey }}</span> <span>{{ $ts.recaptchaSiteKey }}</span>
</FormInput> </FormInput>
<FormInput v-model:value="recaptchaSecretKey"> <FormInput v-model="recaptchaSecretKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
<span>{{ $ts.recaptchaSecretKey }}</span> <span>{{ $ts.recaptchaSecretKey }}</span>
</FormInput> </FormInput>
</div> </div>
</div> </div>
<div v-if="recaptchaSiteKey" class="_formItem _formNoConcat" v-sticky-container> <div v-if="recaptchaSiteKey" class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
<div class="_formLabel">{{ $ts.preview }}</div> <div class="_debobigegoLabel">{{ $ts.preview }}</div>
<div class="_formPanel" style="padding: var(--formContentHMargin);"> <div class="_debobigegoPanel" style="padding: var(--debobigegoContentHMargin);">
<MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/> <MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/>
</div> </div>
</div> </div>
@ -58,13 +58,13 @@
<script lang="ts"> <script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue'; import { defineAsyncComponent, defineComponent } from 'vue';
import FormRadios from '@client/components/form/radios.vue'; import FormRadios from '@client/components/debobigego/radios.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -18,11 +18,11 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue'; import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
import FormLink from '@client/components/form/link.vue'; import FormLink from '@client/components/debobigego/link.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import bytes from '@client/filters/bytes'; import bytes from '@client/filters/bytes';

View File

@ -1,30 +1,30 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormSwitch v-model:value="enableEmail">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></FormSwitch> <FormSwitch v-model="enableEmail">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></FormSwitch>
<template v-if="enableEmail"> <template v-if="enableEmail">
<FormInput v-model:value="email" type="email"> <FormInput v-model="email" type="email">
<span>{{ $ts.emailAddress }}</span> <span>{{ $ts.emailAddress }}</span>
</FormInput> </FormInput>
<div class="_formItem _formNoConcat" v-sticky-container> <div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
<div class="_formLabel">{{ $ts.smtpConfig }}</div> <div class="_debobigegoLabel">{{ $ts.smtpConfig }}</div>
<div class="main"> <div class="main">
<FormInput v-model:value="smtpHost"> <FormInput v-model="smtpHost">
<span>{{ $ts.smtpHost }}</span> <span>{{ $ts.smtpHost }}</span>
</FormInput> </FormInput>
<FormInput v-model:value="smtpPort" type="number"> <FormInput v-model="smtpPort" type="number">
<span>{{ $ts.smtpPort }}</span> <span>{{ $ts.smtpPort }}</span>
</FormInput> </FormInput>
<FormInput v-model:value="smtpUser"> <FormInput v-model="smtpUser">
<span>{{ $ts.smtpUser }}</span> <span>{{ $ts.smtpUser }}</span>
</FormInput> </FormInput>
<FormInput v-model:value="smtpPass" type="password"> <FormInput v-model="smtpPass" type="password">
<span>{{ $ts.smtpPass }}</span> <span>{{ $ts.smtpPass }}</span>
</FormInput> </FormInput>
<FormInfo>{{ $ts.emptyToDisableSmtpAuth }}</FormInfo> <FormInfo>{{ $ts.emptyToDisableSmtpAuth }}</FormInfo>
<FormSwitch v-model:value="smtpSecure">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></FormSwitch> <FormSwitch v-model="smtpSecure">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></FormSwitch>
</div> </div>
</div> </div>
@ -38,13 +38,13 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -31,7 +31,7 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import { unique } from '../../../prelude/array'; import { unique } from '../../../prelude/array';

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="ogwlenmc"> <div class="ogwlenmc">
<MkTab v-model:value="tab"> <MkTab v-model="tab">
<option value="local">{{ $ts.local }}</option> <option value="local">{{ $ts.local }}</option>
<option value="remote">{{ $ts.remote }}</option> <option value="remote">{{ $ts.remote }}</option>
</MkTab> </MkTab>
@ -56,7 +56,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import MkTab from '@client/components/tab.vue'; import MkTab from '@client/components/tab.vue';
import { selectFile } from '@client/scripts/select-file'; import { selectFile } from '@client/scripts/select-file';

View File

@ -37,7 +37,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkSwitch from '@client/components/ui/switch.vue'; import MkSwitch from '@client/components/form/switch.vue';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue'; import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue';
import Progress from '@client/scripts/loading'; import Progress from '@client/scripts/loading';

View File

@ -1,23 +1,23 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormSwitch v-model:value="cacheRemoteFiles"> <FormSwitch v-model="cacheRemoteFiles">
{{ $ts.cacheRemoteFiles }} {{ $ts.cacheRemoteFiles }}
<template #desc>{{ $ts.cacheRemoteFilesDescription }}</template> <template #desc>{{ $ts.cacheRemoteFilesDescription }}</template>
</FormSwitch> </FormSwitch>
<FormSwitch v-model:value="proxyRemoteFiles"> <FormSwitch v-model="proxyRemoteFiles">
{{ $ts.proxyRemoteFiles }} {{ $ts.proxyRemoteFiles }}
<template #desc>{{ $ts.proxyRemoteFilesDescription }}</template> <template #desc>{{ $ts.proxyRemoteFilesDescription }}</template>
</FormSwitch> </FormSwitch>
<FormInput v-model:value="localDriveCapacityMb" type="number"> <FormInput v-model="localDriveCapacityMb" type="number">
<span>{{ $ts.driveCapacityPerLocalAccount }}</span> <span>{{ $ts.driveCapacityPerLocalAccount }}</span>
<template #suffix>MB</template> <template #suffix>MB</template>
<template #desc>{{ $ts.inMb }}</template> <template #desc>{{ $ts.inMb }}</template>
</FormInput> </FormInput>
<FormInput v-model:value="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles"> <FormInput v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">
<span>{{ $ts.driveCapacityPerRemoteAccount }}</span> <span>{{ $ts.driveCapacityPerRemoteAccount }}</span>
<template #suffix>MB</template> <template #suffix>MB</template>
<template #desc>{{ $ts.inMb }}</template> <template #desc>{{ $ts.inMb }}</template>
@ -30,12 +30,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -63,8 +63,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue'; import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue';
import bytes from '@client/filters/bytes'; import bytes from '@client/filters/bytes';

View File

@ -3,8 +3,8 @@
<div class="nav" v-if="!narrow || page == null"> <div class="nav" v-if="!narrow || page == null">
<FormBase> <FormBase>
<FormGroup> <FormGroup>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formPanel lxpfedzu"> <div class="_debobigegoPanel lxpfedzu">
<img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/> <img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
</div> </div>
</div> </div>
@ -56,10 +56,10 @@
<script lang="ts"> <script lang="ts">
import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue'; import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { i18n } from '@client/i18n'; import { i18n } from '@client/i18n';
import FormLink from '@client/components/form/link.vue'; import FormLink from '@client/components/debobigego/link.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import { scroll } from '@client/scripts/scroll'; import { scroll } from '@client/scripts/scroll';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import * as os from '@client/os'; import * as os from '@client/os';

View File

@ -1,7 +1,7 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormTextarea v-model:value="blockedHosts"> <FormTextarea v-model="blockedHosts">
<span>{{ $ts.blockedInstances }}</span> <span>{{ $ts.blockedInstances }}</span>
<template #desc>{{ $ts.blockedInstancesDescription }}</template> <template #desc>{{ $ts.blockedInstancesDescription }}</template>
</FormTextarea> </FormTextarea>
@ -13,14 +13,14 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -127,9 +127,9 @@ import { defineComponent, markRaw } from 'vue';
import Chart from 'chart.js'; import Chart from 'chart.js';
import XModalWindow from '@client/components/ui/modal-window.vue'; import XModalWindow from '@client/components/ui/modal-window.vue';
import MkUsersDialog from '@client/components/users-dialog.vue'; import MkUsersDialog from '@client/components/users-dialog.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkSwitch from '@client/components/ui/switch.vue'; import MkSwitch from '@client/components/form/switch.vue';
import MkInfo from '@client/components/ui/info.vue'; import MkInfo from '@client/components/ui/info.vue';
import bytes from '@client/filters/bytes'; import bytes from '@client/filters/bytes';
import number from '@client/filters/number'; import number from '@client/filters/number';

View File

@ -1,19 +1,19 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormSwitch v-model:value="enableDiscordIntegration"> <FormSwitch v-model="enableDiscordIntegration">
{{ $ts.enable }} {{ $ts.enable }}
</FormSwitch> </FormSwitch>
<template v-if="enableDiscordIntegration"> <template v-if="enableDiscordIntegration">
<FormInfo>Callback URL: {{ `${url}/api/dc/cb` }}</FormInfo> <FormInfo>Callback URL: {{ `${url}/api/dc/cb` }}</FormInfo>
<FormInput v-model:value="discordClientId"> <FormInput v-model="discordClientId">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
Client ID Client ID
</FormInput> </FormInput>
<FormInput v-model:value="discordClientSecret"> <FormInput v-model="discordClientSecret">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
Client Secret Client Secret
</FormInput> </FormInput>
@ -26,12 +26,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -1,19 +1,19 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormSwitch v-model:value="enableGithubIntegration"> <FormSwitch v-model="enableGithubIntegration">
{{ $ts.enable }} {{ $ts.enable }}
</FormSwitch> </FormSwitch>
<template v-if="enableGithubIntegration"> <template v-if="enableGithubIntegration">
<FormInfo>Callback URL: {{ `${url}/api/gh/cb` }}</FormInfo> <FormInfo>Callback URL: {{ `${url}/api/gh/cb` }}</FormInfo>
<FormInput v-model:value="githubClientId"> <FormInput v-model="githubClientId">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
Client ID Client ID
</FormInput> </FormInput>
<FormInput v-model:value="githubClientSecret"> <FormInput v-model="githubClientSecret">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
Client Secret Client Secret
</FormInput> </FormInput>
@ -26,12 +26,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -1,19 +1,19 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormSwitch v-model:value="enableTwitterIntegration"> <FormSwitch v-model="enableTwitterIntegration">
{{ $ts.enable }} {{ $ts.enable }}
</FormSwitch> </FormSwitch>
<template v-if="enableTwitterIntegration"> <template v-if="enableTwitterIntegration">
<FormInfo>Callback URL: {{ `${url}/api/tw/cb` }}</FormInfo> <FormInfo>Callback URL: {{ `${url}/api/tw/cb` }}</FormInfo>
<FormInput v-model:value="twitterConsumerKey"> <FormInput v-model="twitterConsumerKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
Consumer Key Consumer Key
</FormInput> </FormInput>
<FormInput v-model:value="twitterConsumerSecret"> <FormInput v-model="twitterConsumerSecret">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
Consumer Secret Consumer Secret
</FormInput> </FormInput>
@ -26,12 +26,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -19,14 +19,14 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormLink from '@client/components/form/link.vue'; import FormLink from '@client/components/debobigego/link.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -31,9 +31,9 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkTextarea from '@client/components/ui/textarea.vue'; import MkTextarea from '@client/components/form/textarea.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formLabel"><i class="fas fa-microchip"></i> {{ $ts.cpuAndMemory }}</div> <div class="_debobigegoLabel"><i class="fas fa-microchip"></i> {{ $ts.cpuAndMemory }}</div>
<div class="_formPanel xhexznfu"> <div class="_debobigegoPanel xhexznfu">
<div> <div>
<canvas :ref="cpumem"></canvas> <canvas :ref="cpumem"></canvas>
</div> </div>
@ -16,9 +16,9 @@
</div> </div>
</div> </div>
</div> </div>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formLabel"><i class="fas fa-hdd"></i> {{ $ts.disk }}</div> <div class="_debobigegoLabel"><i class="fas fa-hdd"></i> {{ $ts.disk }}</div>
<div class="_formPanel xhexznfu"> <div class="_debobigegoPanel xhexznfu">
<div> <div>
<canvas :ref="disk"></canvas> <canvas :ref="disk"></canvas>
</div> </div>
@ -33,9 +33,9 @@
</div> </div>
</div> </div>
</div> </div>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formLabel"><i class="fas fa-exchange-alt"></i> {{ $ts.network }}</div> <div class="_debobigegoLabel"><i class="fas fa-exchange-alt"></i> {{ $ts.network }}</div>
<div class="_formPanel xhexznfu"> <div class="_debobigegoPanel xhexznfu">
<div> <div>
<canvas :ref="net"></canvas> <canvas :ref="net"></canvas>
</div> </div>
@ -54,8 +54,8 @@
import { defineComponent, markRaw } from 'vue'; import { defineComponent, markRaw } from 'vue';
import Chart from 'chart.js'; import Chart from 'chart.js';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkContainer from '@client/components/ui/container.vue'; import MkContainer from '@client/components/ui/container.vue';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import MkwFederation from '../../widgets/federation.vue'; import MkwFederation from '../../widgets/federation.vue';

View File

@ -1,59 +1,59 @@
<template> <template>
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormSwitch v-model:value="useObjectStorage">{{ $ts.useObjectStorage }}</FormSwitch> <FormSwitch v-model="useObjectStorage">{{ $ts.useObjectStorage }}</FormSwitch>
<template v-if="useObjectStorage"> <template v-if="useObjectStorage">
<FormInput v-model:value="objectStorageBaseUrl"> <FormInput v-model="objectStorageBaseUrl">
<span>{{ $ts.objectStorageBaseUrl }}</span> <span>{{ $ts.objectStorageBaseUrl }}</span>
<template #desc>{{ $ts.objectStorageBaseUrlDesc }}</template> <template #desc>{{ $ts.objectStorageBaseUrlDesc }}</template>
</FormInput> </FormInput>
<FormInput v-model:value="objectStorageBucket"> <FormInput v-model="objectStorageBucket">
<span>{{ $ts.objectStorageBucket }}</span> <span>{{ $ts.objectStorageBucket }}</span>
<template #desc>{{ $ts.objectStorageBucketDesc }}</template> <template #desc>{{ $ts.objectStorageBucketDesc }}</template>
</FormInput> </FormInput>
<FormInput v-model:value="objectStoragePrefix"> <FormInput v-model="objectStoragePrefix">
<span>{{ $ts.objectStoragePrefix }}</span> <span>{{ $ts.objectStoragePrefix }}</span>
<template #desc>{{ $ts.objectStoragePrefixDesc }}</template> <template #desc>{{ $ts.objectStoragePrefixDesc }}</template>
</FormInput> </FormInput>
<FormInput v-model:value="objectStorageEndpoint"> <FormInput v-model="objectStorageEndpoint">
<span>{{ $ts.objectStorageEndpoint }}</span> <span>{{ $ts.objectStorageEndpoint }}</span>
<template #desc>{{ $ts.objectStorageEndpointDesc }}</template> <template #desc>{{ $ts.objectStorageEndpointDesc }}</template>
</FormInput> </FormInput>
<FormInput v-model:value="objectStorageRegion"> <FormInput v-model="objectStorageRegion">
<span>{{ $ts.objectStorageRegion }}</span> <span>{{ $ts.objectStorageRegion }}</span>
<template #desc>{{ $ts.objectStorageRegionDesc }}</template> <template #desc>{{ $ts.objectStorageRegionDesc }}</template>
</FormInput> </FormInput>
<FormInput v-model:value="objectStorageAccessKey"> <FormInput v-model="objectStorageAccessKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
<span>Access key</span> <span>Access key</span>
</FormInput> </FormInput>
<FormInput v-model:value="objectStorageSecretKey"> <FormInput v-model="objectStorageSecretKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
<span>Secret key</span> <span>Secret key</span>
</FormInput> </FormInput>
<FormSwitch v-model:value="objectStorageUseSSL"> <FormSwitch v-model="objectStorageUseSSL">
{{ $ts.objectStorageUseSSL }} {{ $ts.objectStorageUseSSL }}
<template #desc>{{ $ts.objectStorageUseSSLDesc }}</template> <template #desc>{{ $ts.objectStorageUseSSLDesc }}</template>
</FormSwitch> </FormSwitch>
<FormSwitch v-model:value="objectStorageUseProxy"> <FormSwitch v-model="objectStorageUseProxy">
{{ $ts.objectStorageUseProxy }} {{ $ts.objectStorageUseProxy }}
<template #desc>{{ $ts.objectStorageUseProxyDesc }}</template> <template #desc>{{ $ts.objectStorageUseProxyDesc }}</template>
</FormSwitch> </FormSwitch>
<FormSwitch v-model:value="objectStorageSetPublicRead"> <FormSwitch v-model="objectStorageSetPublicRead">
{{ $ts.objectStorageSetPublicRead }} {{ $ts.objectStorageSetPublicRead }}
</FormSwitch> </FormSwitch>
<FormSwitch v-model:value="objectStorageS3ForcePathStyle"> <FormSwitch v-model="objectStorageS3ForcePathStyle">
s3ForcePathStyle s3ForcePathStyle
</FormSwitch> </FormSwitch>
</template> </template>
@ -65,12 +65,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -2,17 +2,17 @@
<FormBase> <FormBase>
<FormSuspense :p="init"> <FormSuspense :p="init">
<FormGroup> <FormGroup>
<FormInput v-model:value="summalyProxy"> <FormInput v-model="summalyProxy">
<template #prefix><i class="fas fa-link"></i></template> <template #prefix><i class="fas fa-link"></i></template>
Summaly Proxy URL Summaly Proxy URL
</FormInput> </FormInput>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormInput v-model:value="deeplAuthKey"> <FormInput v-model="deeplAuthKey">
<template #prefix><i class="fas fa-key"></i></template> <template #prefix><i class="fas fa-key"></i></template>
DeepL Auth Key DeepL Auth Key
</FormInput> </FormInput>
<FormSwitch v-model:value="deeplIsPro"> <FormSwitch v-model="deeplIsPro">
Pro account Pro account
</FormSwitch> </FormSwitch>
</FormGroup> </FormGroup>
@ -23,12 +23,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormSwitch from '@client/components/form/switch.vue'; import FormSwitch from '@client/components/debobigego/switch.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

View File

@ -17,8 +17,8 @@
</FormGroup> </FormGroup>
</FormSuspense> </FormSuspense>
<div class="_formItem"> <div class="_debobigegoItem">
<div class="_formPanel"> <div class="_debobigegoPanel">
<MkInstanceStats :chart-limit="300" :detailed="true"/> <MkInstanceStats :chart-limit="300" :detailed="true"/>
</div> </div>
</div> </div>
@ -47,18 +47,18 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, markRaw } from 'vue'; import { computed, defineComponent, markRaw } from 'vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue'; import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import MkInstanceStats from '@client/components/instance-stats.vue'; import MkInstanceStats from '@client/components/instance-stats.vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';
import MkSelect from '@client/components/ui/select.vue'; import MkSelect from '@client/components/form/select.vue';
import MkInput from '@client/components/ui/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkContainer from '@client/components/ui/container.vue'; import MkContainer from '@client/components/ui/container.vue';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import { version, url } from '@client/config'; import { version, url } from '@client/config';

View File

@ -16,14 +16,14 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue'; import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/form/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import FormBase from '@client/components/form/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/form/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormInfo from '@client/components/form/info.vue'; import FormInfo from '@client/components/debobigego/info.vue';
import FormSuspense from '@client/components/form/suspense.vue'; import FormSuspense from '@client/components/debobigego/suspense.vue';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import { fetchInstance } from '@client/instance'; import { fetchInstance } from '@client/instance';

Some files were not shown because too many files have changed in this diff Show More