Made Select component to make using styled selects easier

This commit is contained in:
Henry Jameson 2021-03-11 16:11:44 +02:00
parent 6281241b92
commit c6d4c20982
19 changed files with 240 additions and 317 deletions

View file

@ -187,7 +187,7 @@ a {
} }
} }
input, textarea, .select, .input { input, textarea, .input {
&.unstyled { &.unstyled {
border-radius: 0; border-radius: 0;
@ -217,11 +217,7 @@ input, textarea, .select, .input {
hyphens: none; hyphens: none;
padding: 8px .5em; padding: 8px .5em;
&.select { &:disabled, &[disabled=disabled], &.disabled {
padding: 0;
}
&:disabled, &[disabled=disabled] {
cursor: not-allowed; cursor: not-allowed;
opacity: 0.5; opacity: 0.5;
} }
@ -239,25 +235,6 @@ input, textarea, .select, .input {
pointer-events: none; pointer-events: none;
} }
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: transparent;
border: none;
color: $fallback--text;
color: var(--inputText, --text, $fallback--text);
margin: 0;
padding: 0 2em 0 .2em;
font-family: sans-serif;
font-family: var(--inputFont, sans-serif);
font-size: 14px;
width: 100%;
z-index: 1;
height: 28px;
line-height: 16px;
}
&[type=range] { &[type=range] {
background: none; background: none;
border: none; border: none;
@ -809,13 +786,6 @@ nav {
} }
} }
.select-multiple {
display: flex;
.option-list {
margin: 0;
padding-left: .5em;
}
}
.setting-list, .setting-list,
.option-list{ .option-list{
list-style-type: none; list-style-type: none;

View file

@ -1,14 +1,10 @@
import { set } from 'vue' import { set } from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core' import Select from '../select/select.vue'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronDown
)
export default { export default {
components: {
Select
},
props: [ props: [
'name', 'label', 'value', 'fallback', 'options', 'no-inherit' 'name', 'label', 'value', 'fallback', 'options', 'no-inherit'
], ],

View file

@ -22,30 +22,20 @@
class="opt-l" class="opt-l"
:for="name + '-o'" :for="name + '-o'"
/> />
<label <Select
:for="name + '-font-switcher'" :id="name + '-font-switcher'"
class="select" v-model="preset"
:disabled="!present" :disabled="!present"
class="font-switcher"
> >
<select <option
:id="name + '-font-switcher'" v-for="option in availableOptions"
v-model="preset" :key="option"
:disabled="!present" :value="option"
class="font-switcher"
> >
<option {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }}
v-for="option in availableOptions" </option>
:key="option" </Select>
:value="option"
>
{{ option === 'custom' ? $t('settings.style.fonts.custom') : option }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
<input <input
v-if="isCustom" v-if="isCustom"
:id="name" :id="name"

View file

@ -3,27 +3,18 @@
<label for="interface-language-switcher"> <label for="interface-language-switcher">
{{ $t('settings.interfaceLanguage') }} {{ $t('settings.interfaceLanguage') }}
</label> </label>
<label <Select
for="interface-language-switcher" id="interface-language-switcher"
class="select" v-model="language"
> >
<select <option
id="interface-language-switcher" v-for="lang in languages"
v-model="language" :key="lang.code"
:value="lang.code"
> >
<option {{ lang.name }}
v-for="lang in languages" </option>
:key="lang.code" </Select>
:value="lang.code"
>
{{ lang.name }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
</template> </template>
@ -32,16 +23,12 @@ import languagesObject from '../../i18n/messages'
import localeService from '../../services/locale/locale.service.js' import localeService from '../../services/locale/locale.service.js'
import ISO6391 from 'iso-639-1' import ISO6391 from 'iso-639-1'
import _ from 'lodash' import _ from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core' import Select from '../select/select.vue'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronDown
)
export default { export default {
components: {
Select
},
computed: { computed: {
languages () { languages () {
return _.map(languagesObject.languages, (code) => ({ code: code, name: this.getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name)) return _.map(languagesObject.languages, (code) => ({ code: code, name: this.getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name))

View file

@ -1,19 +1,21 @@
import * as DateUtils from 'src/services/date_utils/date_utils.js' import * as DateUtils from 'src/services/date_utils/date_utils.js'
import { uniq } from 'lodash' import { uniq } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import Select from '../select/select.vue'
import { import {
faTimes, faTimes,
faChevronDown,
faPlus faPlus
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
faTimes, faTimes,
faChevronDown,
faPlus faPlus
) )
export default { export default {
components: {
Select
},
name: 'PollForm', name: 'PollForm',
props: ['visible'], props: ['visible'],
data: () => ({ data: () => ({

View file

@ -46,23 +46,13 @@
class="poll-type" class="poll-type"
:title="$t('polls.type')" :title="$t('polls.type')"
> >
<label <Select
for="poll-type-selector" v-model="pollType"
class="select" @change="updatePollToParent"
> >
<select <option value="single">{{ $t('polls.single_choice') }}</option>
v-model="pollType" <option value="multiple">{{ $t('polls.multiple_choices') }}</option>
class="select" </Select>
@change="updatePollToParent"
>
<option value="single">{{ $t('polls.single_choice') }}</option>
<option value="multiple">{{ $t('polls.multiple_choices') }}</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
<div <div
class="poll-expiry" class="poll-expiry"
@ -76,24 +66,19 @@
:max="maxExpirationInCurrentUnit" :max="maxExpirationInCurrentUnit"
@change="expiryAmountChange" @change="expiryAmountChange"
> >
<label class="expiry-unit select"> <Select
<select v-model="expiryUnit"
v-model="expiryUnit" class="expiry-unit"
@change="expiryAmountChange" @change="expiryAmountChange"
>
<option
v-for="unit in expiryUnits"
:key="unit"
:value="unit"
> >
<option {{ $t(`time.${unit}_short`, ['']) }}
v-for="unit in expiryUnits" </option>
:key="unit" </Select>
:value="unit"
>
{{ $t(`time.${unit}_short`, ['']) }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
</div> </div>
</div> </div>

View file

@ -11,10 +11,10 @@ import { reject, map, uniqBy, debounce } from 'lodash'
import suggestor from '../emoji_input/suggestor.js' import suggestor from '../emoji_input/suggestor.js'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
import Checkbox from '../checkbox/checkbox.vue' import Checkbox from '../checkbox/checkbox.vue'
import Select from '../select/select.vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faChevronDown,
faSmileBeam, faSmileBeam,
faPollH, faPollH,
faUpload, faUpload,
@ -24,7 +24,6 @@ import {
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
faChevronDown,
faSmileBeam, faSmileBeam,
faPollH, faPollH,
faUpload, faUpload,
@ -84,6 +83,7 @@ const PostStatusForm = {
PollForm, PollForm,
ScopeSelector, ScopeSelector,
Checkbox, Checkbox,
Select,
Attachment, Attachment,
StatusContent StatusContent
}, },

View file

@ -189,28 +189,19 @@
v-if="postFormats.length > 1" v-if="postFormats.length > 1"
class="text-format" class="text-format"
> >
<label <Select
for="post-content-type" id="post-content-type"
class="select" v-model="newStatus.contentType"
class="form-control"
> >
<select <option
id="post-content-type" v-for="postFormat in postFormats"
v-model="newStatus.contentType" :key="postFormat"
class="form-control" :value="postFormat"
> >
<option {{ $t(`post_status.content_type["${postFormat}"]`) }}
v-for="postFormat in postFormats" </option>
:key="postFormat" </Select>
:value="postFormat"
>
{{ $t(`post_status.content_type["${postFormat}"]`) }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
<div <div
v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'" v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'"

View file

@ -0,0 +1,67 @@
<template>
<label
class="Select input"
:class="{ disabled }"
>
<select
:disabled="disabled"
:value="value"
@change="$emit('change', $event.target.value)"
>
<slot />
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</template>
<script>
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronDown
)
export default {
model: {
prop: 'value',
event: 'change'
},
props: [
'value',
'disabled'
]
}
</script>
<style lang="scss">
@import '../../_variables.scss';
.Select {
padding: 0;
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: transparent;
border: none;
color: $fallback--text;
color: var(--inputText, --text, $fallback--text);
margin: 0;
padding: 0 2em 0 .2em;
font-family: sans-serif;
font-family: var(--inputFont, sans-serif);
font-size: 14px;
width: 100%;
z-index: 1;
height: 28px;
line-height: 16px;
}
}
</style>

View file

@ -1,15 +1,8 @@
import { filter, trim } from 'lodash' import { filter, trim } from 'lodash'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import Select from '../../select/select.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronDown
)
const FilteringTab = { const FilteringTab = {
data () { data () {
@ -18,7 +11,8 @@ const FilteringTab = {
} }
}, },
components: { components: {
BooleanSetting BooleanSetting,
Select
}, },
computed: { computed: {
...SharedComputedObject(), ...SharedComputedObject(),

View file

@ -38,26 +38,17 @@
</div> </div>
<div> <div>
{{ $t('settings.replies_in_timeline') }} {{ $t('settings.replies_in_timeline') }}
<label <Select
for="replyVisibility" id="replyVisibility"
class="select" v-model="replyVisibility"
> >
<select <option
id="replyVisibility" value="all"
v-model="replyVisibility" selected
> >{{ $t('settings.reply_visibility_all') }}</option>
<option <option value="following">{{ $t('settings.reply_visibility_following') }}</option>
value="all" <option value="self">{{ $t('settings.reply_visibility_self') }}</option>
selected </Select>
>{{ $t('settings.reply_visibility_all') }}</option>
<option value="following">{{ $t('settings.reply_visibility_following') }}</option>
<option value="self">{{ $t('settings.reply_visibility_self') }}</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
<div> <div>
<BooleanSetting path="hidePostStats"> <BooleanSetting path="hidePostStats">
@ -88,3 +79,12 @@
</div> </div>
</template> </template>
<script src="./filtering_tab.js"></script> <script src="./filtering_tab.js"></script>
<style lang="scss">
.select-multiple {
display: flex;
.option-list {
margin: 0;
padding-left: .5em;
}
}
</style>

View file

@ -1,15 +1,14 @@
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import Select from '../../select/select.vue'
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faChevronDown,
faGlobe faGlobe
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
faChevronDown,
faGlobe faGlobe
) )
@ -27,7 +26,8 @@ const GeneralTab = {
}, },
components: { components: {
BooleanSetting, BooleanSetting,
InterfaceLanguageSwitcher InterfaceLanguageSwitcher,
Select
}, },
computed: { computed: {
postFormats () { postFormats () {

View file

@ -87,59 +87,41 @@
<li> <li>
<div> <div>
{{ $t('settings.subject_line_behavior') }} {{ $t('settings.subject_line_behavior') }}
<label <Select
for="subjectLineBehavior" id="subjectLineBehavior"
class="select" v-model="subjectLineBehavior"
> >
<select <option value="email">
id="subjectLineBehavior" {{ $t('settings.subject_line_email') }}
v-model="subjectLineBehavior" {{ subjectLineBehaviorDefaultValue == 'email' ? $t('settings.instance_default_simple') : '' }}
> </option>
<option value="email"> <option value="masto">
{{ $t('settings.subject_line_email') }} {{ $t('settings.subject_line_mastodon') }}
{{ subjectLineBehaviorDefaultValue == 'email' ? $t('settings.instance_default_simple') : '' }} {{ subjectLineBehaviorDefaultValue == 'mastodon' ? $t('settings.instance_default_simple') : '' }}
</option> </option>
<option value="masto"> <option value="noop">
{{ $t('settings.subject_line_mastodon') }} {{ $t('settings.subject_line_noop') }}
{{ subjectLineBehaviorDefaultValue == 'mastodon' ? $t('settings.instance_default_simple') : '' }} {{ subjectLineBehaviorDefaultValue == 'noop' ? $t('settings.instance_default_simple') : '' }}
</option> </option>
<option value="noop"> </Select>
{{ $t('settings.subject_line_noop') }}
{{ subjectLineBehaviorDefaultValue == 'noop' ? $t('settings.instance_default_simple') : '' }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
</li> </li>
<li v-if="postFormats.length > 0"> <li v-if="postFormats.length > 0">
<div> <div>
{{ $t('settings.post_status_content_type') }} {{ $t('settings.post_status_content_type') }}
<label <Select
for="postContentType" id="postContentType"
class="select" v-model="postContentType"
> >
<select <option
id="postContentType" v-for="postFormat in postFormats"
v-model="postContentType" :key="postFormat"
:value="postFormat"
> >
<option {{ $t(`post_status.content_type["${postFormat}"]`) }}
v-for="postFormat in postFormats" {{ postContentTypeDefaultValue === postFormat ? $t('settings.instance_default_simple') : '' }}
:key="postFormat" </option>
:value="postFormat" </Select>
>
{{ $t(`post_status.content_type["${postFormat}"]`) }}
{{ postContentTypeDefaultValue === postFormat ? $t('settings.instance_default_simple') : '' }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
</li> </li>
<li> <li>

View file

@ -33,16 +33,9 @@ import ContrastRatio from 'src/components/contrast_ratio/contrast_ratio.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js'
import ExportImport from 'src/components/export_import/export_import.vue' import ExportImport from 'src/components/export_import/export_import.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import Select from 'src/components/select/select.vue'
import Preview from './preview.vue' import Preview from './preview.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronDown
)
// List of color values used in v1 // List of color values used in v1
const v1OnlyNames = [ const v1OnlyNames = [
@ -384,7 +377,8 @@ export default {
TabSwitcher, TabSwitcher,
Preview, Preview,
ExportImport, ExportImport,
Checkbox Checkbox,
Select
}, },
methods: { methods: {
loadTheme ( loadTheme (

View file

@ -59,32 +59,23 @@
<template slot="before"> <template slot="before">
<div class="presets"> <div class="presets">
{{ $t('settings.presets') }} {{ $t('settings.presets') }}
<label <Select
for="preset-switcher" id="preset-switcher"
class="select" v-model="selected"
class="preset-switcher"
> >
<select <option
id="preset-switcher" v-for="style in availableStyles"
v-model="selected" :key="style.name"
class="preset-switcher" :value="style"
:style="{
backgroundColor: style[1] || (style.theme || style.source).colors.bg,
color: style[3] || (style.theme || style.source).colors.text
}"
> >
<option {{ style[0] || style.name }}
v-for="style in availableStyles" </option>
:key="style.name" </Select>
:value="style"
:style="{
backgroundColor: style[1] || (style.theme || style.source).colors.bg,
color: style[3] || (style.theme || style.source).colors.text
}"
>
{{ style[0] || style.name }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
</template> </template>
</ExportImport> </ExportImport>
@ -902,28 +893,19 @@
<div class="tab-header shadow-selector"> <div class="tab-header shadow-selector">
<div class="select-container"> <div class="select-container">
{{ $t('settings.style.shadows.component') }} {{ $t('settings.style.shadows.component') }}
<label <Select
for="shadow-switcher" id="shadow-switcher"
class="select" v-model="shadowSelected"
class="shadow-switcher"
> >
<select <option
id="shadow-switcher" v-for="shadow in shadowsAvailable"
v-model="shadowSelected" :key="shadow"
class="shadow-switcher" :value="shadow"
> >
<option {{ $t('settings.style.shadows.components.' + shadow) }}
v-for="shadow in shadowsAvailable" </option>
:key="shadow" </Select>
:value="shadow"
>
{{ $t('settings.style.shadows.components.' + shadow) }}
</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
<div class="override"> <div class="override">
<label <label

View file

@ -1,5 +1,6 @@
import ColorInput from '../color_input/color_input.vue' import ColorInput from '../color_input/color_input.vue'
import OpacityInput from '../opacity_input/opacity_input.vue' import OpacityInput from '../opacity_input/opacity_input.vue'
import Select from '../select/select.vue'
import { getCssShadow } from '../../services/style_setter/style_setter.js' import { getCssShadow } from '../../services/style_setter/style_setter.js'
import { hex2rgb } from '../../services/color_convert/color_convert.js' import { hex2rgb } from '../../services/color_convert/color_convert.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -45,7 +46,8 @@ export default {
}, },
components: { components: {
ColorInput, ColorInput,
OpacityInput OpacityInput,
Select
}, },
methods: { methods: {
add () { add () {

View file

@ -59,30 +59,20 @@
:disabled="usingFallback" :disabled="usingFallback"
class="id-control style-control" class="id-control style-control"
> >
<label <Select
for="shadow-switcher" id="shadow-switcher"
class="select" v-model="selectedId"
class="shadow-switcher"
:disabled="!ready || usingFallback" :disabled="!ready || usingFallback"
> >
<select <option
id="shadow-switcher" v-for="(shadow, index) in cValue"
v-model="selectedId" :key="index"
class="shadow-switcher" :value="index"
:disabled="!ready || usingFallback"
> >
<option {{ $t('settings.style.shadows.shadow_id', { value: index }) }}
v-for="(shadow, index) in cValue" </option>
:key="index" </Select>
:value="index"
>
{{ $t('settings.style.shadows.shadow_id', { value: index }) }}
</option>
</select>
<FAIcon
icon="chevron-down"
class="select-down-icon"
/>
</label>
<button <button
class="btn button-default" class="btn button-default"
:disabled="!ready || !present" :disabled="!ready || !present"

View file

@ -4,13 +4,13 @@ import ProgressButton from '../progress_button/progress_button.vue'
import FollowButton from '../follow_button/follow_button.vue' import FollowButton from '../follow_button/follow_button.vue'
import ModerationTools from '../moderation_tools/moderation_tools.vue' import ModerationTools from '../moderation_tools/moderation_tools.vue'
import AccountActions from '../account_actions/account_actions.vue' import AccountActions from '../account_actions/account_actions.vue'
import Select from '../select/select.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faBell, faBell,
faRss, faRss,
faChevronDown,
faSearchPlus, faSearchPlus,
faExternalLinkAlt faExternalLinkAlt
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
@ -18,7 +18,6 @@ import {
library.add( library.add(
faRss, faRss,
faBell, faBell,
faChevronDown,
faSearchPlus, faSearchPlus,
faExternalLinkAlt faExternalLinkAlt
) )
@ -118,7 +117,8 @@ export default {
ModerationTools, ModerationTools,
AccountActions, AccountActions,
ProgressButton, ProgressButton,
FollowButton FollowButton,
Select
}, },
methods: { methods: {
muteUser () { muteUser () {

View file

@ -132,25 +132,16 @@
class="userHighlightCl" class="userHighlightCl"
type="color" type="color"
> >
<label <Select
for="theme_tab" :id="'userHighlightSel'+user.id"
class="userHighlightSel select" v-model="userHighlightType"
class="userHighlightSel"
> >
<select <option value="disabled">{{ $t('user_card.highlight.disabled') }}</option>
:id="'userHighlightSel'+user.id" <option value="solid">{{ $t('user_card.highlight.solid') }}</option>
v-model="userHighlightType" <option value="striped">{{ $t('user_card.highlight.striped') }}</option>
class="userHighlightSel" <option value="side">{{ $t('user_card.highlight.side') }}</option>
> </Select>
<option value="disabled">{{ $t('user_card.highlight.disabled') }}</option>
<option value="solid">{{ $t('user_card.highlight.solid') }}</option>
<option value="striped">{{ $t('user_card.highlight.striped') }}</option>
<option value="side">{{ $t('user_card.highlight.side') }}</option>
</select>
<FAIcon
class="select-down-icon"
icon="chevron-down"
/>
</label>
</div> </div>
</div> </div>
<div <div