mirror of
https://github.com/lights0123/n-link.git
synced 2026-08-07 18:23:28 +00:00
feat(ui): restyle DeviceSelect with Popover, Icon, and Slate tokens
Also add a `declare module "feather-icons"` ambient shim in desktop/src/vite-env.d.ts: Icon.vue (Task 6) imports the untyped feather-icons package, and DeviceSelect is the first production component to pull Icon.vue into vue-tsc's reachable graph, which surfaced a pre-existing missing type declaration that broke `npm run build`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
25fddd2afe
commit
c38b99d7c8
2
desktop/src/vite-env.d.ts
vendored
2
desktop/src/vite-env.d.ts
vendored
|
|
@ -5,3 +5,5 @@ declare module "*.vue" {
|
|||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
|
||||
declare module "feather-icons";
|
||||
|
|
|
|||
|
|
@ -1,55 +1,53 @@
|
|||
<template>
|
||||
<div class="header border-b px-2 py-2 flex w-full">
|
||||
<button @click="$devices.enumerate()" class="flex-shrink-0 mr-2 focus:outline-none"
|
||||
<div class="header border-b border-edge px-2 py-2 flex w-full bg-raised">
|
||||
<button @click="$devices.enumerate()" class="flex-shrink-0 mr-2 focus:outline-none text-fg"
|
||||
:class="$devices.enumerating && 'cursor-not-allowed opacity-25'" :disabled="$devices.enumerating">
|
||||
<img :src="refreshCw" class="w-5"/>
|
||||
<icon name="refresh-cw" :size="20"/>
|
||||
<div v-if="scanHint && Object.keys($devices.devices).length === 0" class="p-4 refresh-popup">
|
||||
Click to connect a device
|
||||
</div>
|
||||
</button>
|
||||
<el-popover width="239" :show-arrow="false" popper-class="focus:outline-none dev-select-pop" v-model:visible="active"
|
||||
class="w-full overflow-hidden">
|
||||
<template #reference>
|
||||
<popover v-model:visible="active" :width="239" class="w-full">
|
||||
<template #trigger>
|
||||
<div class="relative w-full focus:outline-none">
|
||||
<div
|
||||
class="block w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-3/2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline h-8 truncate">
|
||||
<div class="block w-full bg-surface border border-edge hover:border-muted px-4 py-3/2 pr-8
|
||||
rounded leading-tight focus:outline-none h-8 truncate text-fg">
|
||||
<span v-if="selectedCalculator">
|
||||
<small class="tabular-nums">{{ selectedCalculator }}</small>
|
||||
<span v-if="calc && calc.info"> {{ calc.info.name }}</span>
|
||||
<span v-else> {{ calc!.name }}</span>
|
||||
</span>
|
||||
<span v-else class="text-gray-700 text-sm">
|
||||
<span v-else class="text-muted text-sm">
|
||||
Select a device...
|
||||
</span>
|
||||
</div>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-muted">
|
||||
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<ul>
|
||||
<ul class="-m-3">
|
||||
<li v-for="(device, id) in $devices.devices" :key="id"
|
||||
class="p-2 hover:bg-blue-500 hover:text-white w-full cursor-pointer" @click="select(id)">
|
||||
class="p-2 hover:bg-accent hover:text-accent-fg w-full cursor-pointer text-fg" @click="select(id)">
|
||||
<small class="tabular-nums">{{ id }}</small>
|
||||
<span v-if="device.info"> {{ device.info.name }}</span>
|
||||
<span v-else> {{ device.name }}</span>
|
||||
</li>
|
||||
<div v-if="!anyCalcs" class="p-2 w-full">
|
||||
<div v-if="!anyCalcs" class="p-2 w-full text-muted">
|
||||
No calculators found
|
||||
</div>
|
||||
</ul>
|
||||
</el-popover>
|
||||
</popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, inject, ref} from 'vue';
|
||||
import {ElPopover} from 'element-plus';
|
||||
import 'element-plus/es/components/popover/style/css';
|
||||
import {DEVICES_KEY, type GenericDevices} from './devices';
|
||||
import refreshCw from 'feather-icons/dist/icons/refresh-cw.svg';
|
||||
import Popover from './Popover.vue';
|
||||
import Icon from './Icon.vue';
|
||||
|
||||
withDefaults(defineProps<{
|
||||
scanHint?: boolean;
|
||||
|
|
@ -86,7 +84,7 @@ const anyCalcs = computed(() => !!Object.keys(devices.devices).length);
|
|||
$size: 9px;
|
||||
margin-left: -4.5px;
|
||||
margin-top: 10px;
|
||||
@apply absolute bg-blue-600 text-white;
|
||||
@apply absolute bg-accent text-accent-fg;
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
|
@ -94,16 +92,8 @@ const anyCalcs = computed(() => !!Object.keys(devices.devices).length);
|
|||
top: $size * -2;
|
||||
border-top: $size solid transparent;
|
||||
border-right: $size solid transparent;
|
||||
border-bottom: $size solid theme('colors.blue.600');
|
||||
|
||||
border-bottom: $size solid var(--accent);
|
||||
border-left: $size solid transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.dev-select-pop {
|
||||
margin-top: 0 !important;
|
||||
@apply p-0 overflow-hidden;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in a new issue