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>
|
<template>
|
||||||
<button
|
<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,
|
:class="{'text-black bg-zinc-200 hover:bg-zinc-100': selected,
|
||||||
'hover:bg-zinc-800 text-muted-foreground' : !selected}"
|
'hover:bg-zinc-800 text-muted-foreground' : !selected}"
|
||||||
@click="$emit('select'); $refs.title.scramble()">
|
@click="$emit('select'); $refs.title.scramble()">
|
||||||
<img
|
<slot v-if="$slots['replace']" name="replace" />
|
||||||
draggable="false"
|
<template v-else>
|
||||||
:src="icon" alt="connection-type-icon"
|
<img
|
||||||
class="w-24 size-w mb-2"
|
draggable="false"
|
||||||
:class="{'invert': selected}">
|
:src="icon" alt="connection-type-icon"
|
||||||
<ScrambleText ref="title" :resize="false" class="text-xs text-wrap" :text="title" />
|
class="h-16"
|
||||||
|
:class="{'invert': selected}">
|
||||||
|
<ScrambleText ref="title" :resize="false" class="text-xs text-wrap" :text="title" />
|
||||||
|
</template>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -2,11 +2,7 @@
|
|||||||
<ConfigSection
|
<ConfigSection
|
||||||
:title="$t('config_options.feedback_designer.feedback_type.title')"
|
:title="$t('config_options.feedback_designer.feedback_type.title')"
|
||||||
:icon-component="GaugeCircle">
|
:icon-component="GaugeCircle">
|
||||||
<div class="flex font-heading">
|
<TabSelect v-model="feedbackType" :options="feedbackTypeOptions" />
|
||||||
<FeedbackTypeButton
|
|
||||||
v-for="(option, key) in feedbackTypeOptions" :key="key" :title="$t(option.titleKey)"
|
|
||||||
:icon="option.icon" :selected="feedbackType===key" @select="feedbackType=key" />
|
|
||||||
</div>
|
|
||||||
</ConfigSection>
|
</ConfigSection>
|
||||||
<ConfigSection
|
<ConfigSection
|
||||||
:title="$t('config_options.feedback_designer.haptic_response.title')"
|
: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 CdIcon from '@/assets/icons/iconCoarseDetents.svg'
|
||||||
import VfIcon from '@/assets/icons/iconViscousRotation.svg'
|
import VfIcon from '@/assets/icons/iconViscousRotation.svg'
|
||||||
import RcIcon from '@/assets/icons/iconReturnToCenter.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
|
const feedbackType = ref('fineDetents') // TODO: replace with actual value
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,7 @@
|
|||||||
<WIP />
|
<WIP />
|
||||||
</ConfigSection>
|
</ConfigSection>
|
||||||
<ConfigSection :title="$t('config_options.profile_settings.connection_type.title')" :icon-component="Cable">
|
<ConfigSection :title="$t('config_options.profile_settings.connection_type.title')" :icon-component="Cable">
|
||||||
<div class="flex font-heading">
|
<TabSelect v-model="connectionType" :options="connectionTypeOptions" />
|
||||||
<ConnectionTypeButton
|
|
||||||
v-for="(option, key) in connectionTypeOptions" :key="key" :title="$t(option.titleKey)"
|
|
||||||
:icon="option.icon" :selected="connectionType===key" @select="connectionType=key" />
|
|
||||||
</div>
|
|
||||||
</ConfigSection>
|
</ConfigSection>
|
||||||
|
|
||||||
<ConfigSection
|
<ConfigSection
|
||||||
@@ -26,17 +22,15 @@
|
|||||||
</ConfigSection>
|
</ConfigSection>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<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 { Cable, Replace, Type } from 'lucide-vue-next'
|
||||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||||
import { Separator } from '@/components/ui/separator/index.js'
|
import { Separator } from '@/components/ui/separator/index.js'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import UsbIcon from '@/assets/logos/logoUsb.svg'
|
import UsbIcon from '@/assets/logos/logoUsb.svg'
|
||||||
import MidiIcon from '@/assets/logos/logoMidi.svg'
|
import MidiIcon from '@/assets/logos/logoMidi.svg'
|
||||||
import ConnectionTypeButton from '@/components/config/ConnectionTypeButton.vue'
|
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import WIP from '@/components/WIP.vue'
|
import WIP from '@/components/WIP.vue'
|
||||||
|
import TabSelect from '@/components/config/TabSelect.vue'
|
||||||
|
|
||||||
const connectionType = ref('usb') // TODO: replace with actual value
|
const connectionType = ref('usb') // TODO: replace with actual value
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ let anim = null
|
|||||||
let step = null
|
let step = null
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(step)
|
|
||||||
console.log(anim)
|
|
||||||
anim = setInterval(() => {
|
anim = setInterval(() => {
|
||||||
clearInterval(step)
|
clearInterval(step)
|
||||||
const target = Math.floor(Math.random() * 127)
|
const target = Math.floor(Math.random() * 127)
|
||||||
|
|||||||
Reference in New Issue
Block a user