ADD: TabSelect component
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<button
|
||||
class="flex-1 flex flex-col items-center py-2"
|
||||
:class="{'text-black bg-zinc-200 hover:bg-zinc-100': selected,
|
||||
'hover:bg-zinc-800 text-muted-foreground' : !selected}"
|
||||
@click="$emit('select'); $refs.title.scramble()">
|
||||
<img
|
||||
draggable="false"
|
||||
:src="icon" alt="connection-type-icon"
|
||||
class="w-16 py-2"
|
||||
:class="{'invert': selected}">
|
||||
<ScrambleText ref="title" :resize="false" class="text-xs text-wrap py-1 px-3" :text="title" />
|
||||
</button>
|
||||
</template>
|
||||
<script setup>
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
|
||||
defineEmits(['select'])
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
icon: {
|
||||
type: [String, Object, Function],
|
||||
default: '',
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
33
src/components/config/TabSelect.vue
Normal file
33
src/components/config/TabSelect.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="flex font-heading">
|
||||
<TabSelectButton
|
||||
v-for="(option, key) in options" :key="key"
|
||||
:title="$t(option.titleKey)"
|
||||
:icon="option.icon" :selected="model===key"
|
||||
@select="model=key">
|
||||
<template v-if="$slots[key]" #replace>
|
||||
<slot :name="key" />
|
||||
</template>
|
||||
</TabSelectButton>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CircleDot } from 'lucide-vue-next'
|
||||
import TabSelectButton from '@/components/config/TabSelectButton.vue'
|
||||
|
||||
const model = defineModel({
|
||||
type: String,
|
||||
default: 'a',
|
||||
})
|
||||
|
||||
defineProps({
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
a: { titleKey: 'Option A', icon: CircleDot },
|
||||
b: { titleKey: 'Option B', icon: CircleDot },
|
||||
c: { titleKey: 'Option C', icon: CircleDot },
|
||||
}),
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -1,15 +1,18 @@
|
||||
<template>
|
||||
<button
|
||||
class="flex-1 flex flex-col justify-center items-center py-4"
|
||||
class="flex-1 flex flex-col items-center rounded-xl my-1 mx-0.5 p-1 gap-2"
|
||||
:class="{'text-black bg-zinc-200 hover:bg-zinc-100': selected,
|
||||
'hover:bg-zinc-800 text-muted-foreground' : !selected}"
|
||||
@click="$emit('select'); $refs.title.scramble()">
|
||||
<img
|
||||
draggable="false"
|
||||
:src="icon" alt="connection-type-icon"
|
||||
class="w-24 size-w mb-2"
|
||||
:class="{'invert': selected}">
|
||||
<ScrambleText ref="title" :resize="false" class="text-xs text-wrap" :text="title" />
|
||||
<slot v-if="$slots['replace']" name="replace" />
|
||||
<template v-else>
|
||||
<img
|
||||
draggable="false"
|
||||
:src="icon" alt="connection-type-icon"
|
||||
class="h-16"
|
||||
:class="{'invert': selected}">
|
||||
<ScrambleText ref="title" :resize="false" class="text-xs text-wrap" :text="title" />
|
||||
</template>
|
||||
</button>
|
||||
</template>
|
||||
<script setup>
|
||||
@@ -2,11 +2,7 @@
|
||||
<ConfigSection
|
||||
:title="$t('config_options.feedback_designer.feedback_type.title')"
|
||||
:icon-component="GaugeCircle">
|
||||
<div class="flex font-heading">
|
||||
<FeedbackTypeButton
|
||||
v-for="(option, key) in feedbackTypeOptions" :key="key" :title="$t(option.titleKey)"
|
||||
:icon="option.icon" :selected="feedbackType===key" @select="feedbackType=key" />
|
||||
</div>
|
||||
<TabSelect v-model="feedbackType" :options="feedbackTypeOptions" />
|
||||
</ConfigSection>
|
||||
<ConfigSection
|
||||
:title="$t('config_options.feedback_designer.haptic_response.title')"
|
||||
@@ -51,7 +47,7 @@ import FdIcon from '@/assets/icons/iconFineDetents.svg'
|
||||
import CdIcon from '@/assets/icons/iconCoarseDetents.svg'
|
||||
import VfIcon from '@/assets/icons/iconViscousRotation.svg'
|
||||
import RcIcon from '@/assets/icons/iconReturnToCenter.svg'
|
||||
import FeedbackTypeButton from '@/components/config/FeedbackTypeButton.vue'
|
||||
import TabSelect from '@/components/config/TabSelect.vue'
|
||||
|
||||
const feedbackType = ref('fineDetents') // TODO: replace with actual value
|
||||
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
<WIP />
|
||||
</ConfigSection>
|
||||
<ConfigSection :title="$t('config_options.profile_settings.connection_type.title')" :icon-component="Cable">
|
||||
<div class="flex font-heading">
|
||||
<ConnectionTypeButton
|
||||
v-for="(option, key) in connectionTypeOptions" :key="key" :title="$t(option.titleKey)"
|
||||
:icon="option.icon" :selected="connectionType===key" @select="connectionType=key" />
|
||||
</div>
|
||||
<TabSelect v-model="connectionType" :options="connectionTypeOptions" />
|
||||
</ConfigSection>
|
||||
|
||||
<ConfigSection
|
||||
@@ -26,17 +22,15 @@
|
||||
</ConfigSection>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Label } from '@/components/ui/label/index.js'
|
||||
import { Switch } from '@/components/ui/switch/index.js'
|
||||
import { Cable, Replace, Type } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import { Separator } from '@/components/ui/separator/index.js'
|
||||
import { ref } from 'vue'
|
||||
import UsbIcon from '@/assets/logos/logoUsb.svg'
|
||||
import MidiIcon from '@/assets/logos/logoMidi.svg'
|
||||
import ConnectionTypeButton from '@/components/config/ConnectionTypeButton.vue'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import WIP from '@/components/WIP.vue'
|
||||
import TabSelect from '@/components/config/TabSelect.vue'
|
||||
|
||||
const connectionType = ref('usb') // TODO: replace with actual value
|
||||
|
||||
|
||||
@@ -44,8 +44,6 @@ let anim = null
|
||||
let step = null
|
||||
|
||||
onMounted(() => {
|
||||
console.log(step)
|
||||
console.log(anim)
|
||||
anim = setInterval(() => {
|
||||
clearInterval(step)
|
||||
const target = Math.floor(Math.random() * 127)
|
||||
|
||||
Reference in New Issue
Block a user