refactor components
This commit is contained in:
		
							parent
							
								
									0d3a36e519
								
							
						
					
					
						commit
						1ac1a968b9
					
				
					 179 changed files with 2611 additions and 2386 deletions
				
			
		|  | @ -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 という単語は使わない | ||||||
| 広告ブロッカーで誤ってブロックされる | 広告ブロッカーで誤ってブロックされる | ||||||
|  |  | ||||||
|  | @ -787,6 +787,8 @@ pubSub: "Pub/Subのアカウント" | ||||||
| lastCommunication: "直近の通信" | lastCommunication: "直近の通信" | ||||||
| resolved: "解決済み" | resolved: "解決済み" | ||||||
| unresolved: "未解決" | unresolved: "未解決" | ||||||
|  | itsOn: "オンになっています" | ||||||
|  | itsOff: "オフになっています" | ||||||
| 
 | 
 | ||||||
| _accountDelete: | _accountDelete: | ||||||
|   accountDelete: "アカウントの削除" |   accountDelete: "アカウントの削除" | ||||||
|  |  | ||||||
|  | @ -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", | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | @ -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: { | ||||||
|  | @ -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; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -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; | ||||||
|  | @ -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> | ||||||
|  | @ -1,7 +1,9 @@ | ||||||
| <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="icon" ref="icon"><slot name="icon"></slot></div> | ||||||
|  | 		<div class="input _debobigegoPanel"> | ||||||
| 			<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> | 			<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> | ||||||
| 			<input ref="inputEl" | 			<input ref="inputEl" | ||||||
| 				:type="type" | 				:type="type" | ||||||
|  | @ -25,25 +27,27 @@ | ||||||
| 			</datalist> | 			</datalist> | ||||||
| 			<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div> | 			<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div> | ||||||
| 		</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> | 	</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> | </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,20 +137,14 @@ 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) { |  | ||||||
| 					debouncedUpdated(); |  | ||||||
| 				} else { |  | ||||||
| 				updated(); | 				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,12 +267,13 @@ 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 { | ||||||
|  | @ -298,13 +281,6 @@ export default defineComponent({ | ||||||
| 		margin: 0; | 		margin: 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 		&.focused { |  | ||||||
| 			> input { |  | ||||||
| 				border-color: var(--accent); |  | ||||||
| 				//box-shadow: 0 0 0 4px var(--focus); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	&.disabled { | 	&.disabled { | ||||||
| 		opacity: 0.7; | 		opacity: 0.7; | ||||||
| 
 | 
 | ||||||
|  | @ -313,5 +289,4 @@ export default defineComponent({ | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| } |  | ||||||
| </style> | </style> | ||||||
|  | @ -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; | ||||||
|  | @ -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: { | ||||||
|  | @ -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; | ||||||
|  | @ -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_"> | ||||||
							
								
								
									
										112
									
								
								src/client/components/debobigego/radios.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/client/components/debobigego/radios.vue
									
										
									
									
									
										Normal 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> | ||||||
							
								
								
									
										122
									
								
								src/client/components/debobigego/range.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								src/client/components/debobigego/range.vue
									
										
									
									
									
										Normal 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> | ||||||
							
								
								
									
										145
									
								
								src/client/components/debobigego/select.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/client/components/debobigego/select.vue
									
										
									
									
									
										Normal 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> | ||||||
|  | @ -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({ | ||||||
							
								
								
									
										132
									
								
								src/client/components/debobigego/switch.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/client/components/debobigego/switch.vue
									
										
									
									
									
										Normal 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> | ||||||
							
								
								
									
										161
									
								
								src/client/components/debobigego/textarea.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/client/components/debobigego/textarea.vue
									
										
									
									
									
										Normal 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> | ||||||
|  | @ -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> | ||||||
|  | @ -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: { | ||||||
|  |  | ||||||
|  | @ -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({ | ||||||
|  |  | ||||||
|  | @ -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: { | ||||||
|  |  | ||||||
|  | @ -1,9 +1,7 @@ | ||||||
| <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="input _formPanel"> |  | ||||||
| 		<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> | 		<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> | ||||||
| 		<input ref="inputEl" | 		<input ref="inputEl" | ||||||
| 			:type="type" | 			:type="type" | ||||||
|  | @ -27,27 +25,25 @@ | ||||||
| 		</datalist> | 		</datalist> | ||||||
| 		<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div> | 		<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> |  | ||||||
| 
 | 
 | ||||||
| 	<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,20 +134,26 @@ 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) { | ||||||
|  | 				if (props.debounce) { | ||||||
|  | 					debouncedUpdated(); | ||||||
|  | 				} else { | ||||||
| 					updated(); | 					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,13 +283,12 @@ 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 { | ||||||
|  | @ -281,6 +296,13 @@ export default defineComponent({ | ||||||
| 			margin: 0; | 			margin: 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		&.focused { | ||||||
|  | 			> input { | ||||||
|  | 				border-color: var(--accent); | ||||||
|  | 				//box-shadow: 0 0 0 4px var(--focus); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		&.disabled { | 		&.disabled { | ||||||
| 			opacity: 0.7; | 			opacity: 0.7; | ||||||
| 
 | 
 | ||||||
|  | @ -289,4 +311,5 @@ export default defineComponent({ | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
|  | @ -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) { |  | ||||||
| 			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; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	&:first-child { | ||||||
|  | 		margin-top: 0; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	&:last-child { | ||||||
|  | 		margin-bottom: 0; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| <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" | ||||||
|  | @ -10,13 +10,12 @@ | ||||||
| 		:min="min" | 		:min="min" | ||||||
| 		:max="max" | 		:max="max" | ||||||
| 		:step="step" | 		:step="step" | ||||||
|  | 		:autofocus="autofocus" | ||||||
| 		@focus="focused = true" | 		@focus="focused = true" | ||||||
| 		@blur="focused = false" | 		@blur="focused = false" | ||||||
| 		@input="$emit('update:value', $event.target.value)" | 		@input="$emit('update:value', $event.target.value)" | ||||||
| 	/> | 	/> | ||||||
| </div> | </div> | ||||||
| 	<div class="_formCaption"><slot name="caption"></slot></div> |  | ||||||
| </div> |  | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|  | @ -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,26 +64,41 @@ 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; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	> .title { | ||||||
|  | 		pointer-events: none; | ||||||
|  | 		font-size: 16px; | ||||||
|  | 		color: var(--inputLabel); | ||||||
|  | 		overflow: hidden; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	> input { | 	> input { | ||||||
| 			display: block; |  | ||||||
| 		-webkit-appearance: none; | 		-webkit-appearance: none; | ||||||
| 		-moz-appearance: none; | 		-moz-appearance: none; | ||||||
| 		appearance: none; | 		appearance: none; | ||||||
| 		background: var(--X10); | 		background: var(--X10); | ||||||
| 			height: 4px; | 		height: 7px; | ||||||
| 			width: 100%; | 		margin: 0 8px; | ||||||
| 			box-sizing: border-box; |  | ||||||
| 			margin: 0; |  | ||||||
| 		outline: 0; | 		outline: 0; | ||||||
| 		border: 0; | 		border: 0; | ||||||
| 		border-radius: 7px; | 		border-radius: 7px; | ||||||
|  | @ -118,5 +136,4 @@ export default defineComponent({ | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| } |  | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								src/client/components/form/section.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/client/components/form/section.vue
									
										
									
									
									
										Normal 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> | ||||||
|  | @ -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="caption"><slot name="caption"></slot></div> | ||||||
| 	<div class="_formCaption"><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: { | ||||||
|  | 			type: Boolean, | ||||||
|  | 			required: false, | ||||||
|  | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 	data() { | 	}, | ||||||
|  | 
 | ||||||
|  | 	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 { | 		return { | ||||||
|  | 			v, | ||||||
|  | 			focused, | ||||||
|  | 			invalid, | ||||||
|  | 			changed, | ||||||
|  | 			filled, | ||||||
|  | 			inputEl, | ||||||
|  | 			prefixEl, | ||||||
|  | 			suffixEl, | ||||||
|  | 			focus, | ||||||
|  | 			onInput, | ||||||
|  | 			updated, | ||||||
| 		}; | 		}; | ||||||
| 	}, | 	}, | ||||||
| 	computed: { |  | ||||||
| 		v: { |  | ||||||
| 			get() { |  | ||||||
| 				return this.value; |  | ||||||
| 			}, |  | ||||||
| 			set(v) { |  | ||||||
| 				this.$emit('update:value', v); |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	methods: { |  | ||||||
| 		focus() { |  | ||||||
| 			this.$refs.input.focus(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| }); | }); | ||||||
| </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; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								src/client/components/form/slot.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/client/components/form/slot.vue
									
										
									
									
									
										Normal 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> | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| <template> | <template> | ||||||
| <div class="ijnpvmgr _formItem"> | <div | ||||||
| 	<div class="main _formPanel _formClickable" | 	class="ziffeoms" | ||||||
| 	:class="{ disabled, checked }" | 	:class="{ disabled, checked }" | ||||||
|  | 	role="switch" | ||||||
| 	:aria-checked="checked" | 	:aria-checked="checked" | ||||||
| 	:aria-disabled="disabled" | 	:aria-disabled="disabled" | ||||||
| 	@click.prevent="toggle" | 	@click.prevent="toggle" | ||||||
|  | @ -12,24 +13,22 @@ | ||||||
| 		:disabled="disabled" | 		:disabled="disabled" | ||||||
| 		@keydown.enter="toggle" | 		@keydown.enter="toggle" | ||||||
| 	> | 	> | ||||||
| 		<span class="button"> | 	<span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff"> | ||||||
| 			<span></span> | 		<span class="handle"></span> | ||||||
| 	</span> | 	</span> | ||||||
| 	<span class="label"> | 	<span class="label"> | ||||||
| 		<span><slot></slot></span> | 		<span><slot></slot></span> | ||||||
|  | 		<p><slot name="caption"></slot></p> | ||||||
| 	</span> | 	</span> | ||||||
| </div> | </div> | ||||||
| 	<div class="_formCaption"><slot name="desc"></slot></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,47 +39,37 @@ 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; | 	position: relative; | ||||||
| 	display: flex; | 	display: flex; | ||||||
| 		padding: 14px 16px; |  | ||||||
| 	cursor: pointer; | 	cursor: pointer; | ||||||
|  | 	transition: all 0.3s; | ||||||
|  | 
 | ||||||
|  | 	&:first-child { | ||||||
|  | 		margin-top: 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	&:last-child { | ||||||
|  | 		margin-bottom: 0; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	> * { | 	> * { | ||||||
| 		user-select: none; | 		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 { | 	> input { | ||||||
| 		position: absolute; | 		position: absolute; | ||||||
| 		width: 0; | 		width: 0; | ||||||
|  | @ -93,31 +82,33 @@ export default defineComponent({ | ||||||
| 		position: relative; | 		position: relative; | ||||||
| 		display: inline-block; | 		display: inline-block; | ||||||
| 		flex-shrink: 0; | 		flex-shrink: 0; | ||||||
| 			margin: 3px 0 0 0; | 		margin: 0; | ||||||
| 			width: 34px; | 		width: 36px; | ||||||
| 			height: 14px; | 		height: 26px; | ||||||
| 			background: var(--X6); | 		background: var(--switchBg); | ||||||
| 		outline: none; | 		outline: none; | ||||||
| 			border-radius: 14px; | 		border-radius: 999px; | ||||||
| 			transition: all 0.3s; | 		transition: inherit; | ||||||
| 			cursor: pointer; |  | ||||||
| 
 | 
 | ||||||
| 			> * { | 		> .handle { | ||||||
| 			position: absolute; | 			position: absolute; | ||||||
| 				top: -3px; | 			top: 0; | ||||||
| 				left: 0; | 			bottom: 0; | ||||||
|  | 			left: 5px; | ||||||
|  | 			margin: auto 0; | ||||||
| 			border-radius: 100%; | 			border-radius: 100%; | ||||||
| 			transition: background-color 0.3s, transform 0.3s; | 			transition: background-color 0.3s, transform 0.3s; | ||||||
| 				width: 20px; | 			width: 16px; | ||||||
| 				height: 20px; | 			height: 16px; | ||||||
| 			background-color: #fff; | 			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 { | 	> .label { | ||||||
| 			margin-left: 12px; | 		margin-left: 16px; | ||||||
|  | 		margin-top: 2px; | ||||||
| 		display: block; | 		display: block; | ||||||
|  | 		cursor: pointer; | ||||||
| 		transition: inherit; | 		transition: inherit; | ||||||
| 		color: var(--fg); | 		color: var(--fg); | ||||||
| 
 | 
 | ||||||
|  | @ -126,6 +117,33 @@ export default defineComponent({ | ||||||
| 			line-height: 20px; | 			line-height: 20px; | ||||||
| 			transition: inherit; | 			transition: inherit; | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		> p { | ||||||
|  | 			margin: 0; | ||||||
|  | 			color: var(--fgTransparentWeak); | ||||||
|  | 			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); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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" | ||||||
|  | 			:disabled="disabled" | ||||||
| 			:required="required" | 			:required="required" | ||||||
| 			:readonly="readonly" | 			:readonly="readonly" | ||||||
|  | 			:placeholder="placeholder" | ||||||
| 			:pattern="pattern" | 			:pattern="pattern" | ||||||
| 			:autocomplete="autocomplete" | 			:autocomplete="autocomplete" | ||||||
| 				:spellcheck="!code" | 			:spellcheck="spellcheck" | ||||||
| 				@input="onInput" |  | ||||||
| 			@focus="focused = true" | 			@focus="focused = true" | ||||||
| 			@blur="focused = false" | 			@blur="focused = false" | ||||||
|  | 			@keydown="onKeydown($event)" | ||||||
|  | 			@input="onInput" | ||||||
| 		></textarea> | 		></textarea> | ||||||
| 	</div> | 	</div> | ||||||
| 	</div> | 	<div class="caption"><slot name="caption"></slot></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> | 	<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) { | ||||||
|  | 				if (props.debounce) { | ||||||
|  | 					debouncedUpdated(); | ||||||
|  | 				} else { | ||||||
| 					updated(); | 					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); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		&.focused { | ||||||
|  | 			> textarea { | ||||||
|  | 				border-color: var(--accent); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		&.disabled { | ||||||
|  | 			opacity: 0.7; | ||||||
|  | 
 | ||||||
|  | 			&, * { | ||||||
|  | 				cursor: not-allowed !important; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		&.tall { | 		&.tall { | ||||||
| 		> .input { |  | ||||||
| 			> textarea { | 			> textarea { | ||||||
| 				min-height: 200px; | 				min-height: 200px; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 		&.pre { | 		&.pre { | ||||||
| 		> .input { |  | ||||||
| 			> textarea { | 			> textarea { | ||||||
| 				white-space: pre; | 				white-space: pre; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -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)); | ||||||
|  |  | ||||||
|  | @ -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"> | ||||||
|  |  | ||||||
|  | @ -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"/> | ||||||
|  |  | ||||||
|  | @ -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"/> | ||||||
|  |  | ||||||
|  | @ -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"> | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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: { | ||||||
|  |  | ||||||
|  | @ -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({ | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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')] | ||||||
|  |  | ||||||
|  | @ -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> | ||||||
|  |  | ||||||
|  | @ -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> | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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> |  | ||||||
|  | @ -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> |  | ||||||
|  | @ -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> |  | ||||||
|  | @ -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> |  | ||||||
|  | @ -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> |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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> | ||||||
|  |  | ||||||
|  | @ -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: { | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue