summaryrefslogtreecommitdiff
path: root/src/client/app/common/views/components/ui/input.vue
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2020-01-30 04:37:25 +0900
committerGitHub <noreply@github.com>2020-01-30 04:37:25 +0900
commitf6154dc0af1a0d65819e87240f4385f9573095cb (patch)
tree699a5ca07d6727b7f8497d4769f25d6d62f94b5a /src/client/app/common/views/components/ui/input.vue
parentAdd Event activity-type support (#5785) (diff)
downloadmisskey-f6154dc0af1a0d65819e87240f4385f9573095cb.tar.gz
misskey-f6154dc0af1a0d65819e87240f4385f9573095cb.tar.bz2
misskey-f6154dc0af1a0d65819e87240f4385f9573095cb.zip
v12 (#5712)
Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> Co-authored-by: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>
Diffstat (limited to 'src/client/app/common/views/components/ui/input.vue')
-rw-r--r--src/client/app/common/views/components/ui/input.vue503
1 files changed, 0 insertions, 503 deletions
diff --git a/src/client/app/common/views/components/ui/input.vue b/src/client/app/common/views/components/ui/input.vue
deleted file mode 100644
index 1b339a9ae0..0000000000
--- a/src/client/app/common/views/components/ui/input.vue
+++ /dev/null
@@ -1,503 +0,0 @@
-<template>
-<div class="ui-input" :class="[{ focused, filled, inline, disabled }, styl]">
- <div class="icon" ref="icon"><slot name="icon"></slot></div>
- <div class="input">
- <div class="password-meter" v-if="withPasswordMeter" v-show="passwordStrength != ''" :data-strength="passwordStrength">
- <div class="value" ref="passwordMetar"></div>
- </div>
- <span class="label" ref="label"><slot></slot></span>
- <span class="title" ref="title">
- <slot name="title"></slot>
- <span class="warning" v-if="invalid"><fa :icon="['fa', 'exclamation-circle']"/>{{ $refs.input.validationMessage }}</span>
- </span>
- <div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
- <template v-if="type != 'file'">
- <input v-if="debounce" ref="input"
- v-debounce="500"
- :type="type"
- v-model.lazy="v"
- :disabled="disabled"
- :required="required"
- :readonly="readonly"
- :placeholder="placeholder"
- :pattern="pattern"
- :autocomplete="autocomplete"
- :spellcheck="spellcheck"
- @focus="focused = true"
- @blur="focused = false"
- @keydown="$emit('keydown', $event)"
- @change="$emit('change', $event)"
- :list="id"
- >
- <input v-else ref="input"
- :type="type"
- v-model="v"
- :disabled="disabled"
- :required="required"
- :readonly="readonly"
- :placeholder="placeholder"
- :pattern="pattern"
- :autocomplete="autocomplete"
- :spellcheck="spellcheck"
- @focus="focused = true"
- @blur="focused = false"
- @keydown="$emit('keydown', $event)"
- @change="$emit('change', $event)"
- :list="id"
- >
- <datalist :id="id" v-if="datalist">
- <option v-for="data in datalist" :value="data"/>
- </datalist>
- </template>
- <template v-else>
- <input ref="input"
- type="text"
- :value="filePlaceholder"
- readonly
- @click="chooseFile"
- >
- <input ref="file"
- type="file"
- :value="value"
- @change="onChangeFile"
- >
- </template>
- <div class="suffix" ref="suffix"><slot name="suffix"></slot></div>
- </div>
- <div class="toggle" v-if="withPasswordToggle">
- <a @click="togglePassword">
- <span v-if="type == 'password'"><fa :icon="['fa', 'eye']"/> {{ $t('@.show-password') }}</span>
- <span v-if="type != 'password'"><fa :icon="['far', 'eye-slash']"/> {{ $t('@.hide-password') }}</span>
- </a>
- </div>
- <div class="desc"><slot name="desc"></slot></div>
-</div>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-import debounce from 'v-debounce';
-const getPasswordStrength = require('syuilo-password-strength');
-
-export default Vue.extend({
- directives: {
- debounce
- },
- inject: {
- horizonGrouped: {
- default: false
- }
- },
- props: {
- value: {
- required: false
- },
- type: {
- type: String,
- required: false
- },
- required: {
- type: Boolean,
- required: false
- },
- readonly: {
- type: Boolean,
- required: false
- },
- disabled: {
- type: Boolean,
- required: false
- },
- pattern: {
- type: String,
- required: false
- },
- placeholder: {
- type: String,
- required: false
- },
- autofocus: {
- type: Boolean,
- required: false,
- default: false
- },
- autocomplete: {
- required: false
- },
- spellcheck: {
- required: false
- },
- debounce: {
- required: false
- },
- withPasswordMeter: {
- type: Boolean,
- required: false,
- default: false
- },
- withPasswordToggle: {
- type: Boolean,
- required: false,
- default: false
- },
- datalist: {
- type: Array,
- required: false,
- },
- inline: {
- type: Boolean,
- required: false,
- default(): boolean {
- return this.horizonGrouped;
- }
- },
- styl: {
- type: String,
- required: false,
- default: 'line'
- }
- },
- data() {
- return {
- v: this.value,
- focused: false,
- invalid: false,
- passwordStrength: '',
- id: Math.random().toString()
- };
- },
- computed: {
- filled(): boolean {
- return this.v != '' && this.v != null;
- },
- filePlaceholder(): string {
- if (this.type != 'file') return null;
- if (this.v == null) return null;
-
- if (typeof this.v == 'string') return this.v;
-
- if (Array.isArray(this.v)) {
- return this.v.map(file => file.name).join(', ');
- } else {
- return this.v.name;
- }
- }
- },
- watch: {
- value(v) {
- this.v = v;
- },
- v(v) {
- if (this.type === 'number') {
- this.$emit('input', parseInt(v, 10));
- } else {
- this.$emit('input', v);
- }
-
- if (this.withPasswordMeter) {
- if (v == '') {
- this.passwordStrength = '';
- return;
- }
-
- const strength = getPasswordStrength(v);
- this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
- (this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
- }
-
- this.invalid = this.$refs.input.validity.badInput;
- }
- },
- mounted() {
- if (this.autofocus) {
- this.$nextTick(() => {
- this.$refs.input.focus();
- });
- }
-
- this.$nextTick(() => {
- // このコンポーネントが作成された時、非表示状態である場合がある
- // 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する
- const clock = setInterval(() => {
- if (this.$refs.prefix) {
- this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
- if (this.$refs.prefix.offsetWidth) {
- this.$refs.input.style.paddingLeft = this.$refs.prefix.offsetWidth + 'px';
- }
- }
- if (this.$refs.suffix) {
- if (this.$refs.suffix.offsetWidth) {
- this.$refs.input.style.paddingRight = this.$refs.suffix.offsetWidth + 'px';
- }
- }
- }, 100);
-
- this.$once('hook:beforeDestroy', () => {
- clearInterval(clock);
- });
- });
-
- this.$on('keydown', (e: KeyboardEvent) => {
- if (e.code == 'Enter') {
- this.$emit('enter');
- }
- });
- },
- methods: {
- focus() {
- this.$refs.input.focus();
- },
- togglePassword() {
- if (this.type == 'password') {
- this.type = 'text'
- } else {
- this.type = 'password'
- }
- },
- chooseFile() {
- this.$refs.file.click();
- },
- onChangeFile() {
- this.v = Array.from((this.$refs.file as any).files);
- this.$emit('input', this.v);
- this.$emit('change', this.v);
- }
- }
-});
-</script>
-
-<style lang="stylus" scoped>
-root(fill)
- margin 32px 0
-
- > .icon
- position absolute
- top 0
- left 0
- width 24px
- text-align center
- line-height 32px
- color var(--inputLabel)
-
- &:not(:empty) + .input
- margin-left 28px
-
- > .input
-
- if !fill
- &:before
- content ''
- display block
- position absolute
- bottom 0
- left 0
- right 0
- height 1px
- background var(--inputBorder)
-
- &:after
- content ''
- display block
- position absolute
- bottom 0
- left 0
- right 0
- height 2px
- background var(--primary)
- opacity 0
- transform scaleX(0.12)
- transition border 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)
- will-change border opacity transform
-
- > .password-meter
- position absolute
- top 0
- left 0
- width 100%
- height 100%
- border-radius 6px
- overflow hidden
- opacity 0.3
-
- &[data-strength='']
- display none
-
- &[data-strength='low']
- > .value
- background #d73612
-
- &[data-strength='medium']
- > .value
- background #d7ca12
-
- &[data-strength='high']
- > .value
- background #61bb22
-
- > .value
- display block
- width 0
- height 100%
- background transparent
- border-radius 6px
- transition all 0.1s ease
-
- > .label
- position absolute
- z-index 1
- top fill ? 6px : 0
- left 0
- pointer-events none
- transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
- transition-duration 0.3s
- font-size 16px
- line-height 32px
- color var(--inputLabel)
- pointer-events none
- //will-change transform
- transform-origin top left
- transform scale(1)
-
- > .title
- position absolute
- z-index 1
- top fill ? -24px : -17px
- left 0 !important
- pointer-events none
- font-size 16px
- line-height 32px
- color var(--inputLabel)
- pointer-events none
- //will-change transform
- transform-origin top left
- transform scale(.75)
- white-space nowrap
- width 133%
- overflow hidden
- text-overflow ellipsis
-
- > .warning
- margin-left 0.5em
- color var(--infoWarnFg)
-
- > svg
- margin-right 0.1em
-
- > input
- display block
- width 100%
- margin 0
- padding 0
- font inherit
- font-weight fill ? bold : normal
- font-size 16px
- line-height 32px
- color var(--inputText)
- background transparent
- border none
- border-radius 0
- outline none
- box-shadow none
-
- if fill
- padding 6px 12px
- background rgba(#000, 0.035)
- border-radius 6px
-
- &[type='file']
- display none
-
- > .prefix
- > .suffix
- display block
- position absolute
- z-index 1
- top 0
- font-size 16px
- line-height fill ? 44px : 32px
- color var(--inputLabel)
- pointer-events none
-
- &:empty
- display none
-
- > *
- display inline-block
- min-width 16px
- max-width 150px
- overflow hidden
- white-space nowrap
- text-overflow ellipsis
-
- > .prefix
- left 0
- padding-right 4px
-
- if fill
- padding-left 12px
-
- > .suffix
- right 0
- padding-left 4px
-
- if fill
- padding-right 12px
-
- > .toggle
- cursor pointer
- padding-left 0.5em
- font-size 0.7em
- opacity 0.7
- text-align left
-
- > a
- color var(--inputLabel)
- text-decoration none
-
- > .desc
- margin 6px 0
- font-size 13px
-
- &:empty
- display none
-
- *
- margin 0
-
- &.focused
- > .input
- if fill
- background rgba(#000, 0.05)
- else
- &:after
- opacity 1
- transform scaleX(1)
-
- > .label
- color var(--primary)
-
- &.focused
- &.filled
- > .input
- > .label
- top fill ? -24px : -17px
- left 0 !important
- transform scale(0.75)
-
-.ui-input
- &.fill
- root(true)
- &:not(.fill)
- root(false)
-
- &.inline
- display inline-block
- margin 0
-
- &.disabled
- opacity 0.7
-
- &, *
- cursor not-allowed !important
-
-</style>