summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-06-14 20:23:50 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-06-14 20:23:50 +0900
commitdec7d537dca22f60ddc595c7fc34eabaca2c13f1 (patch)
tree9bf23f4f1e0d259116805f3075d901a60d465e30 /src/client
parentwip (diff)
downloadsharkey-dec7d537dca22f60ddc595c7fc34eabaca2c13f1.tar.gz
sharkey-dec7d537dca22f60ddc595c7fc34eabaca2c13f1.tar.bz2
sharkey-dec7d537dca22f60ddc595c7fc34eabaca2c13f1.zip
wip
Diffstat (limited to 'src/client')
-rw-r--r--src/client/app/common/views/components/index.ts4
-rw-r--r--src/client/app/common/views/components/ui/radio.vue120
-rw-r--r--src/client/app/common/views/components/ui/select.vue212
-rw-r--r--src/client/app/common/views/components/ui/switch.vue2
-rw-r--r--src/client/app/mobile/views/pages/settings.vue22
5 files changed, 347 insertions, 13 deletions
diff --git a/src/client/app/common/views/components/index.ts b/src/client/app/common/views/components/index.ts
index 0e20e66f5a..b91008f718 100644
--- a/src/client/app/common/views/components/index.ts
+++ b/src/client/app/common/views/components/index.ts
@@ -35,6 +35,8 @@ import uiCard from './ui/card.vue';
import uiForm from './ui/form.vue';
import uiTextarea from './ui/textarea.vue';
import uiSwitch from './ui/switch.vue';
+import uiRadio from './ui/radio.vue';
+import uiSelect from './ui/select.vue';
Vue.component('mk-analog-clock', analogClock);
Vue.component('mk-menu', menu);
@@ -71,3 +73,5 @@ Vue.component('ui-card', uiCard);
Vue.component('ui-form', uiForm);
Vue.component('ui-textarea', uiTextarea);
Vue.component('ui-switch', uiSwitch);
+Vue.component('ui-radio', uiRadio);
+Vue.component('ui-select', uiSelect);
diff --git a/src/client/app/common/views/components/ui/radio.vue b/src/client/app/common/views/components/ui/radio.vue
new file mode 100644
index 0000000000..2b7f1d9dd4
--- /dev/null
+++ b/src/client/app/common/views/components/ui/radio.vue
@@ -0,0 +1,120 @@
+<template>
+<div
+ class="ui-radio"
+ :class="{ disabled, checked }"
+ :aria-checked="checked"
+ :aria-disabled="disabled"
+ @click="toggle"
+>
+ <input type="radio"
+ :disabled="disabled"
+ >
+ <span class="button">
+ <span></span>
+ </span>
+ <span class="label"><slot></slot></span>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+export default Vue.extend({
+ model: {
+ prop: 'model',
+ event: 'change'
+ },
+ props: {
+ model: {
+ type: String,
+ required: false
+ },
+ value: {
+ type: String,
+ required: false
+ },
+ disabled: {
+ type: Boolean,
+ default: false
+ }
+ },
+ computed: {
+ checked(): boolean {
+ return this.model === this.value;
+ }
+ },
+ methods: {
+ toggle() {
+ this.$emit('change', this.value);
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+root(isDark)
+ display inline-block
+ margin 32px 32px 32px 0
+ cursor pointer
+ transition all 0.3s
+
+ > *
+ user-select none
+
+ &.disabled
+ opacity 0.6
+ cursor not-allowed
+
+ &.checked
+ > .button
+ border-color $theme-color
+
+ &:after
+ background-color $theme-color
+ transform scale(1)
+ opacity 1
+
+ > input
+ position absolute
+ width 0
+ height 0
+ opacity 0
+ margin 0
+
+ > .button
+ position absolute
+ width 20px
+ height 20px
+ background none
+ border solid 2px rgba(#000, 0.54)
+ 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 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
+
+ > .label
+ margin-left 28px
+ display block
+ font-size 16px
+ line-height 20px
+ cursor pointer
+
+.ui-radio[data-darkmode]
+ root(true)
+
+.ui-radio:not([data-darkmode])
+ root(false)
+
+</style>
diff --git a/src/client/app/common/views/components/ui/select.vue b/src/client/app/common/views/components/ui/select.vue
new file mode 100644
index 0000000000..c56ae86159
--- /dev/null
+++ b/src/client/app/common/views/components/ui/select.vue
@@ -0,0 +1,212 @@
+<template>
+<div class="ui-select" :class="[{ focused, filled }, styl]">
+ <div class="icon" ref="icon"><slot name="icon"></slot></div>
+ <div class="input" @click="focus">
+ <span class="label" ref="label"><slot name="label"></slot></span>
+ <div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
+ <select ref="input"
+ :value="v"
+ :required="required"
+ @input="$emit('input', $event.target.value)"
+ @focus="focused = true"
+ @blur="focused = false">
+ <slot></slot>
+ </select>
+ <div class="suffix"><slot name="suffix"></slot></div>
+ </div>
+ <div class="text"><slot name="text"></slot></div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+
+export default Vue.extend({
+ props: {
+ value: {
+ required: false
+ },
+ required: {
+ type: Boolean,
+ required: false
+ }
+ },
+ data() {
+ return {
+ v: this.value,
+ focused: false,
+ styl: 'fill'
+ };
+ },
+ computed: {
+ filled(): boolean {
+ return this.v != '' && this.v != null;
+ }
+ },
+ watch: {
+ value(v) {
+ this.v = v;
+ }
+ },
+ inject: ['isCardChild'],
+ created() {
+ if (this.isCardChild) {
+ this.styl = 'line';
+ }
+ },
+ mounted() {
+ if (this.$refs.prefix) {
+ this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
+ }
+ },
+ methods: {
+ focus() {
+ this.$refs.input.focus();
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+root(isDark, fill)
+ margin 32px 0
+
+ > .icon
+ position absolute
+ top 0
+ left 0
+ width 24px
+ text-align center
+ line-height 32px
+ color rgba(#000, 0.54)
+
+ &:not(:empty) + .input
+ margin-left 28px
+
+ > .input
+ display flex
+
+ if fill
+ padding 6px 12px
+ background rgba(#000, 0.035)
+ border-radius 6px
+ else
+ &:before
+ content ''
+ display block
+ position absolute
+ bottom 0
+ left 0
+ right 0
+ height 1px
+ background rgba(#000, 0.42)
+
+ &:after
+ content ''
+ display block
+ position absolute
+ bottom 0
+ left 0
+ right 0
+ height 2px
+ background $theme-color
+ 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
+
+ > .label
+ position absolute
+ 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 rgba(#000, 0.54)
+ pointer-events none
+ //will-change transform
+ transform-origin top left
+ transform scale(1)
+
+ > select
+ display block
+ flex 1
+ width 100%
+ padding 0
+ font inherit
+ font-weight fill ? bold : normal
+ font-size 16px
+ height 32px
+ background transparent
+ border none
+ border-radius 0
+ outline none
+ box-shadow none
+
+ &[type='file']
+ display none
+
+ > .prefix
+ > .suffix
+ display block
+ align-self center
+ justify-self center
+ font-size 16px
+ line-height 32px
+ color rgba(#000, 0.54)
+ pointer-events none
+
+ > *
+ display block
+ min-width 16px
+
+ > .prefix
+ padding-right 4px
+
+ > .suffix
+ padding-left 4px
+
+ > .text
+ margin 6px 0
+ font-size 13px
+
+ *
+ margin 0
+
+ &.focused
+ > .input
+ if fill
+ background rgba(#000, 0.05)
+ else
+ &:after
+ opacity 1
+ transform scaleX(1)
+
+ > .label
+ color $theme-color
+
+ &.focused
+ &.filled
+ > .input
+ > .label
+ top fill ? -24px : -16px
+ left 0 !important
+ transform scale(0.8)
+
+.ui-select[data-darkmode]
+ &.fill
+ root(true, true)
+ &:not(.fill)
+ root(true, false)
+
+.ui-select:not([data-darkmode])
+ &.fill
+ root(false, true)
+ &:not(.fill)
+ root(false, false)
+
+</style>
diff --git a/src/client/app/common/views/components/ui/switch.vue b/src/client/app/common/views/components/ui/switch.vue
index f860309867..2431a76528 100644
--- a/src/client/app/common/views/components/ui/switch.vue
+++ b/src/client/app/common/views/components/ui/switch.vue
@@ -117,7 +117,7 @@ root(isDark)
margin 3px 0 0 0
width 34px
height 14px
- background isDark ? rgba(#fff, 0.1) : rgba(#000, 0.05)
+ background isDark ? rgba(#fff, 0.1) : rgba(#000, 0.07)
outline none
border-radius 14px
transition inherit
diff --git a/src/client/app/mobile/views/pages/settings.vue b/src/client/app/mobile/views/pages/settings.vue
index 25cfbf732b..beac788482 100644
--- a/src/client/app/mobile/views/pages/settings.vue
+++ b/src/client/app/mobile/views/pages/settings.vue
@@ -36,8 +36,8 @@
<div>
<div class="md-body-2">%i18n:@post-style%</div>
- <md-radio v-model="postStyle" value="standard">%i18n:@post-style-standard%</md-radio>
- <md-radio v-model="postStyle" value="smart">%i18n:@post-style-smart%</md-radio>
+ <ui-radio v-model="postStyle" value="standard">%i18n:@post-style-standard%</ui-radio>
+ <ui-radio v-model="postStyle" value="smart">%i18n:@post-style-smart%</ui-radio>
</div>
</ui-card>
@@ -68,17 +68,15 @@
<ui-card>
<div slot="title">%fa:language% %i18n:@lang%</div>
- <md-field>
- <md-select v-model="lang" placeholder="%i18n:@auto%">
- <md-optgroup label="%i18n:@recommended%">
- <md-option value="">%i18n:@auto%</md-option>
- </md-optgroup>
+ <ui-select v-model="lang" placeholder="%i18n:@auto%">
+ <optgroup label="%i18n:@recommended%">
+ <option value="">%i18n:@auto%</option>
+ </optgroup>
- <md-optgroup label="%i18n:@specify-language%">
- <md-option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</md-option>
- </md-optgroup>
- </md-select>
- </md-field>
+ <optgroup label="%i18n:@specify-language%">
+ <option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
+ </optgroup>
+ </ui-select>
<span class="md-helper-text">%fa:info-circle% %i18n:@lang-tip%</span>
</ui-card>