refactor(stage-ui): drop Tabs component
This commit is contained in:
@@ -1,143 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
type ThemeVariant = 'primary' | 'violet' | 'lime' | 'orange'
|
||||
|
||||
export interface TabItem {
|
||||
value: string
|
||||
label: string
|
||||
icon?: string | { active: string, idle: string }
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
modelValue: string
|
||||
tabs: TabItem[]
|
||||
theme?: ThemeVariant
|
||||
size?: 'xs' | 'sm' | 'md'
|
||||
label?: string
|
||||
}>(), {
|
||||
theme: 'primary',
|
||||
size: 'sm',
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', v: string): void
|
||||
(e: 'change', v: string): void
|
||||
}>()
|
||||
|
||||
const commonThemeClasses = {
|
||||
tabActive: [
|
||||
'bg-white shadow-sm font-bold text-primary-600 dark:text-primary-400 text-xs',
|
||||
'ring-2 ring-primary-500',
|
||||
'dark:bg-neutral-700',
|
||||
'ring-1 ring-black/5 dark:ring-white/10',
|
||||
],
|
||||
tabIdle: [
|
||||
'text-neutral-600 hover:bg-white/70',
|
||||
'dark:text-neutral-300 dark:hover:bg-white/10',
|
||||
'text-xs',
|
||||
],
|
||||
}
|
||||
|
||||
const themeClasses: Record<ThemeVariant, {
|
||||
container: string[]
|
||||
tabActive: string[]
|
||||
tabIdle: string[]
|
||||
label?: string[]
|
||||
}> = {
|
||||
primary: {
|
||||
container: [
|
||||
'bg-primary-50/60 dark:bg-primary-900/25 backdrop-blur-md',
|
||||
'text-neutral-700/80 dark:text-neutral-300/80',
|
||||
],
|
||||
label: ['text-primary-500 dark:text-primary-400 font-semibold'],
|
||||
...commonThemeClasses,
|
||||
},
|
||||
violet: {
|
||||
container: [
|
||||
'bg-violet-50/60 dark:bg-violet-900/25 backdrop-blur-md',
|
||||
'text-neutral-700/80 dark:text-neutral-300/80',
|
||||
],
|
||||
label: ['text-violet-500 dark:text-violet-400 font-semibold'],
|
||||
...commonThemeClasses,
|
||||
},
|
||||
lime: {
|
||||
container: [
|
||||
'bg-lime-50/60 dark:bg-lime-900/25 backdrop-blur-md',
|
||||
'text-neutral-700/80 dark:text-neutral-300/80',
|
||||
],
|
||||
label: ['text-lime-500 dark:text-lime-400 font-semibold'],
|
||||
...commonThemeClasses,
|
||||
},
|
||||
orange: {
|
||||
container: [
|
||||
'bg-orange-50/70 dark:bg-orange-900/25 backdrop-blur-md',
|
||||
'text-neutral-700/80 dark:text-neutral-300/80',
|
||||
],
|
||||
label: ['text-orange-500 dark:text-orange-400 font-semibold'],
|
||||
...commonThemeClasses,
|
||||
},
|
||||
}
|
||||
|
||||
const sizeCls = computed(() => ({
|
||||
xs: 'px-2 py-1 text-xs',
|
||||
sm: 'px-3 py-1.5 text-sm',
|
||||
md: 'px-4 py-2 text-sm',
|
||||
})[props.size])
|
||||
|
||||
function onClick(v: string, disabled?: boolean) {
|
||||
if (disabled)
|
||||
return
|
||||
if (v === props.modelValue)
|
||||
return
|
||||
emit('update:modelValue', v)
|
||||
emit('change', v)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="relative overflow-hidden rounded-lg p-2"
|
||||
:class="themeClasses[theme].container"
|
||||
>
|
||||
<div v-if="label" class="mb-1 text-sm" :class="themeClasses[theme].label">
|
||||
{{ label }}
|
||||
</div>
|
||||
<div class="flex select-none items-center gap-1" role="tablist">
|
||||
<button
|
||||
v-for="t in tabs"
|
||||
:key="t.value"
|
||||
type="button"
|
||||
role="tab"
|
||||
:aria-selected="modelValue === t.value"
|
||||
:disabled="t.disabled"
|
||||
:class="[
|
||||
'inline-flex items-center gap-1 rounded-md transition-all',
|
||||
sizeCls,
|
||||
t.disabled ? 'opacity-40 cursor-not-allowed' : '',
|
||||
modelValue === t.value ? themeClasses[theme].tabActive : themeClasses[theme].tabIdle,
|
||||
'focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-primary-200 focus-visible:outline-offset-2',
|
||||
]"
|
||||
@click="onClick(t.value, t.disabled)"
|
||||
>
|
||||
<span
|
||||
v-if="t.icon"
|
||||
:class="[
|
||||
typeof t.icon === 'string'
|
||||
? t.icon
|
||||
: (t.value === modelValue ? t.icon.active : t.icon.idle),
|
||||
'text-base',
|
||||
]"
|
||||
/>
|
||||
<span class="whitespace-nowrap">{{ t.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="mt-2">
|
||||
<!-- Pass active value to consumer -->
|
||||
<slot name="default" :active="modelValue" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { useModelStore } from '@proj-airi/stage-ui-three'
|
||||
import { Button } from '@proj-airi/ui'
|
||||
import { Button, SelectTab } from '@proj-airi/ui'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { Container, PropertyColor, PropertyNumber, PropertyPoint } from '../../../data-pane'
|
||||
import { Callout, Tabs } from '../../../layouts'
|
||||
import { Callout } from '../../../layouts'
|
||||
import { ColorPalette } from '../../../widgets'
|
||||
|
||||
defineProps<{
|
||||
@@ -49,24 +49,22 @@ const trackingOptions = computed(() => [
|
||||
])
|
||||
|
||||
// switch between hemisphere light and sky box
|
||||
const tabList = [
|
||||
const envOptions = computed(() => [
|
||||
{
|
||||
value: 'hemisphere',
|
||||
label: 'Hemisphere',
|
||||
icon: {
|
||||
idle: 'i-solar:forbidden-circle-linear rotate-45',
|
||||
active: 'i-solar:forbidden-circle-bold rotate-45',
|
||||
},
|
||||
icon: envSelect.value === 'hemisphere'
|
||||
? 'i-solar:forbidden-circle-bold rotate-45'
|
||||
: 'i-solar:forbidden-circle-linear rotate-45',
|
||||
},
|
||||
{
|
||||
value: 'skyBox',
|
||||
label: 'SkyBox',
|
||||
icon: {
|
||||
idle: 'i-solar:gallery-circle-linear',
|
||||
active: 'i-solar:gallery-circle-bold',
|
||||
},
|
||||
icon: envSelect.value === 'skyBox'
|
||||
? 'i-solar:gallery-circle-bold'
|
||||
: 'i-solar:gallery-circle-linear',
|
||||
},
|
||||
]
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -157,38 +155,48 @@ const tabList = [
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Tabs v-model="envSelect" :tabs="tabList" label="Environment">
|
||||
<template #default>
|
||||
<div v-if="envSelect === 'hemisphere'">
|
||||
<!-- hemisphere settings -->
|
||||
<div grid="~ cols-5 gap-1" p-2>
|
||||
<PropertyNumber
|
||||
v-model="hemisphereLightIntensity"
|
||||
:config="{ min: 0, max: 10, step: 0.01, label: 'Intensity' }"
|
||||
label="Hemisphere Light Intensity"
|
||||
/>
|
||||
<PropertyColor
|
||||
v-model="hemisphereSkyColor"
|
||||
label="Hemisphere Sky Color"
|
||||
/>
|
||||
<PropertyColor
|
||||
v-model="hemisphereGroundColor"
|
||||
label="Hemisphere Ground Color"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- skybox settings -->
|
||||
<div grid="~ cols-5 gap-1" p-2>
|
||||
<PropertyNumber
|
||||
v-model="skyBoxIntensity"
|
||||
:config="{ min: 0, max: 1, step: 0.01, label: 'Intensity' }"
|
||||
:label="t('settings.vrm.skybox.skybox-intensity')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Tabs>
|
||||
<div
|
||||
:class="[
|
||||
'px-2',
|
||||
'pt-2',
|
||||
'text-xs',
|
||||
'text-neutral-500',
|
||||
'dark:text-neutral-400',
|
||||
]"
|
||||
>
|
||||
Environment
|
||||
</div>
|
||||
<div :class="['p-2']">
|
||||
<SelectTab v-model="envSelect" :options="envOptions" size="sm" />
|
||||
</div>
|
||||
<div v-if="envSelect === 'hemisphere'">
|
||||
<!-- hemisphere settings -->
|
||||
<div grid="~ cols-5 gap-1" p-2>
|
||||
<PropertyNumber
|
||||
v-model="hemisphereLightIntensity"
|
||||
:config="{ min: 0, max: 10, step: 0.01, label: 'Intensity' }"
|
||||
label="Hemisphere Light Intensity"
|
||||
/>
|
||||
<PropertyColor
|
||||
v-model="hemisphereSkyColor"
|
||||
label="Hemisphere Sky Color"
|
||||
/>
|
||||
<PropertyColor
|
||||
v-model="hemisphereGroundColor"
|
||||
label="Hemisphere Ground Color"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- skybox settings -->
|
||||
<div grid="~ cols-5 gap-1" p-2>
|
||||
<PropertyNumber
|
||||
v-model="skyBoxIntensity"
|
||||
:config="{ min: 0, max: 1, step: 0.01, label: 'Intensity' }"
|
||||
:label="t('settings.vrm.skybox.skybox-intensity')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
<Container
|
||||
|
||||
Reference in New Issue
Block a user