Files
ComfyUI_frontend/src/components/load3d/controls/RecordingControls.vue
Johnpaul Chiwetelu 9e434a1002 fix: replace text-white with theme-aware color tokens (#7908)
## Summary
- Replace hardcoded `text-white` class with theme-aware alternatives to
fix invisible text on light themes
- Update Load3D control backgrounds to use semantic tokens
- Update dropdown menus to use `bg-interface-menu-surface`
- Update overlay backgrounds to use `bg-backdrop` with opacity

## Changes
| Component | Old | New |
|-----------|-----|-----|
| Text on primary bg | `text-white` | `text-base-foreground` |
| Dropdown menus | `bg-black/50` | `bg-interface-menu-surface` |
| Control panels | `bg-smoke-700/30` | `bg-backdrop/30` |
| Loading overlays | `bg-black bg-opacity-50` | `bg-backdrop/50` |
| Selected states | `bg-smoke-600` | `bg-button-active-surface` |

## Files Modified (14)
- `src/components/TopMenuSection.vue`
- `src/components/input/MultiSelect.vue`
- `src/components/load3d/*.vue` (12 files)
- `src/renderer/extensions/vueNodes/VideoPreview.vue`

## Test plan
- [ ] Verify text visibility in light theme
- [ ] Verify text visibility in dark theme
- [ ] Test Load3D viewer controls functionality
- [ ] Test MultiSelect dropdown checkbox visibility

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7908-fix-replace-text-white-with-theme-aware-color-tokens-2e26d73d36508107bb01d1d6e3b74f6a)
by [Unito](https://www.unito.io)
2026-01-09 02:40:15 +01:00

126 lines
3.0 KiB
Vue

<template>
<div class="relative rounded-lg bg-backdrop/30">
<div class="flex flex-col gap-2">
<Button
v-tooltip.right="{
value: isRecording
? $t('load3d.stopRecording')
: $t('load3d.startRecording'),
showDelay: 300
}"
size="icon"
variant="textonly"
:class="
cn(
'rounded-full',
isRecording && 'text-red-500 recording-button-blink'
)
"
:aria-label="
isRecording ? $t('load3d.stopRecording') : $t('load3d.startRecording')
"
@click="toggleRecording"
>
<i
:class="[
'pi',
isRecording ? 'pi-circle-fill' : 'pi-video',
'text-lg text-base-foreground'
]"
/>
</Button>
<Button
v-if="hasRecording && !isRecording"
v-tooltip.right="{
value: $t('load3d.exportRecording'),
showDelay: 300
}"
size="icon"
variant="textonly"
class="rounded-full"
:aria-label="$t('load3d.exportRecording')"
@click="handleExportRecording"
>
<i class="pi pi-download text-lg text-base-foreground" />
</Button>
<Button
v-if="hasRecording && !isRecording"
v-tooltip.right="{
value: $t('load3d.clearRecording'),
showDelay: 300
}"
size="icon"
variant="textonly"
class="rounded-full"
:aria-label="$t('load3d.clearRecording')"
@click="handleClearRecording"
>
<i class="pi pi-trash text-lg text-base-foreground" />
</Button>
<div
v-if="recordingDuration && recordingDuration > 0 && !isRecording"
class="mt-1 text-center text-xs text-base-foreground"
>
{{ formatDuration(recordingDuration) }}
</div>
</div>
</div>
</template>
<script setup lang="ts">
import Button from '@/components/ui/button/Button.vue'
import { cn } from '@/utils/tailwindUtil'
const hasRecording = defineModel<boolean>('hasRecording')
const isRecording = defineModel<boolean>('isRecording')
const recordingDuration = defineModel<number>('recordingDuration')
const emit = defineEmits<{
(e: 'startRecording'): void
(e: 'stopRecording'): void
(e: 'exportRecording'): void
(e: 'clearRecording'): void
}>()
function toggleRecording() {
if (isRecording.value) {
emit('stopRecording')
} else {
emit('startRecording')
}
}
function handleExportRecording() {
emit('exportRecording')
}
function handleClearRecording() {
emit('clearRecording')
}
function formatDuration(seconds: number): string {
const minutes = Math.floor(seconds / 60)
const remainingSeconds = Math.floor(seconds % 60)
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
}
</script>
<style scoped>
.recording-button-blink {
animation: blink 1s infinite;
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
</style>