添加网址导航-自定义网址导航-文字和背景选择样式优化(参考备注)

This commit is contained in:
expdsn 2024-11-15 18:11:24 +08:00
parent c8be06730d
commit cc46aafb3b
3 changed files with 157 additions and 143 deletions

View File

@ -15,6 +15,7 @@ import { AddToToken } from './AdderPage'
import DefaultImg from '/tab/icons/bgGameCloud.png' import DefaultImg from '/tab/icons/bgGameCloud.png'
import useAdderPageStore, { type EditBlockItemType } from './useAdderPageStore' import useAdderPageStore, { type EditBlockItemType } from './useAdderPageStore'
import useRouterStore from '@/useRouterStore' import useRouterStore from '@/useRouterStore'
import NativeColorPicker from '@/utils/NativeColorPicker'
addIcons(MdUpload, MdImage, MdCheck) addIcons(MdUpload, MdImage, MdCheck)
const TypeSelector = defineComponent({ const TypeSelector = defineComponent({
@ -171,6 +172,20 @@ export default defineComponent(() => {
if (val.name) form.name = val.name if (val.name) form.name = val.name
if (val.icon) form.icon = val.icon if (val.icon) form.icon = val.icon
}) })
watch(
() => form.type,
(cur, pre) => {
if (cur === 1) {
if (!form.name) {
globalToast.error('文字图标请至少填写文字或者名称')
form.type = pre
return
} else {
form.text = form.name.substring(0, 2).toLocaleUpperCase()
}
}
}
)
const addTo = inject(AddToToken) const addTo = inject(AddToToken)
return () => ( return () => (
<div <div
@ -179,25 +194,24 @@ export default defineComponent(() => {
(isGame.value ? 'bg-white/20' : 'bg-white/70') (isGame.value ? 'bg-white/20' : 'bg-white/70')
} }
> >
<Form labelCol={{ span: 4 }} labelAlign="left"> <Form>
<Form.Item label="地址"> <Form.Item label="地址" class={'relative'}>
<InputGroup compact style="display:flex"> <Input
<Input v-model:value={form.link}
v-model:value={form.link} placeholder="搜索想要添加的网址导航"
placeholder="搜索想要添加的网址导航" class={isGame?.value ? '' : ' bg-black/10 '}
class="w-0 flex-grow" />
/> <span
<Button class={'absolute right-[-70px] top-1/2 -translate-y-1/2 cursor-pointer'}
onClick={() => { onClick={() => {
debounced.value = debounced.value + ' ' debounced.value = debounced.value + ' '
}} }}
> >
</Button> </span>
</InputGroup>
</Form.Item> </Form.Item>
<Form.Item label="名称"> <Form.Item label="名称">
<Input v-model:value={form.name} /> <Input v-model:value={form.name} class={isGame?.value ? '' : ' bg-black/10 '} />
</Form.Item> </Form.Item>
<Form.Item label="图标"> <Form.Item label="图标">
<TypeSelector <TypeSelector
@ -211,38 +225,29 @@ export default defineComponent(() => {
</Form.Item> </Form.Item>
{form.type === 1 && ( {form.type === 1 && (
<> <>
<div class="flex"> <Form.Item label="图标背景">
<Form.Item <NativeColorPicker
label="文字颜色" size={30}
class="w-0 flex-grow" colorList={[
labelCol={{ 'rgb(227, 127, 53)',
span: 8 'rgb(239, 195, 57)',
'rgb(65, 201, 117)',
'rgb(67, 195, 195)',
'rgb(97, 182, 255)',
'rgb(153, 91, 179)'
]}
value={form.background}
onUpdate:value={(e) => {
form.background = e
}} }}
> ></NativeColorPicker>
<ColorPicker </Form.Item>
class="shadow-lg"
format="rgb"
shape="square"
v-model:pureColor={form.color}
/>
</Form.Item>
<Form.Item
label="图标背景"
class="w-0 flex-grow"
labelCol={{
span: 8
}}
>
<ColorPicker
class="shadow-lg"
format="rgb"
shape="square"
v-model:pureColor={form.background}
/>
</Form.Item>
</div>
<Form.Item label="图标文字"> <Form.Item label="图标文字">
<Input v-model:value={form.text} maxlength={2} /> <Input
v-model:value={form.text}
maxlength={2}
class={isGame?.value ? '' : ' bg-black/10 '}
/>
</Form.Item> </Form.Item>
</> </>
)} )}

View File

@ -1,76 +1,82 @@
import clsx from "clsx"; import clsx from 'clsx'
import { computed } from "vue"; import { computed } from 'vue'
import { defineComponent } from "vue"; import { defineComponent } from 'vue'
import { MdCheck } from "oh-vue-icons/icons"; import { MdCheck } from 'oh-vue-icons/icons'
import { addIcons, OhVueIcon } from "oh-vue-icons"; import { addIcons, OhVueIcon } from 'oh-vue-icons'
addIcons(MdCheck) addIcons(MdCheck)
export default defineComponent({ export default defineComponent({
name: "NativeColorPicker", name: 'NativeColorPicker',
props: { props: {
value: { value: {
type: String, type: String,
default: '' default: ''
},
colorList: {
type: Array<string>
},
class: {
type: String,
},
transparent: {
type: Boolean,
},
firstColor: {
type: String,
}
}, },
emits: { colorList: {
"update:value": (_value: string) => true, type: Array<string>
}, },
setup(props, context) { class: {
const firstColor = props.value type: String
const colorList = computed(() => { },
let list = [ transparent: {
'#ffffff', type: Boolean
'#000000', },
'#FA9B3F', firstColor: {
'#333333', type: String
'#6D7278', },
'#D8D8D8', size: {
'#0091FF', type: Number,
'#B620E0', default: 20
'#F31260' }
] },
if (props.colorList) { emits: {
list = props.colorList 'update:value': (_value: string) => true
} },
if (props.transparent) { setup(props, context) {
list.push('transparent') const firstColor = props.value
} const colorList = computed(() => {
if (!list.includes(firstColor)) { let list = [
list.unshift(firstColor) '#ffffff',
} '#000000',
return list '#FA9B3F',
}) '#333333',
return () => <div class={clsx("flex items-center gap-x-2 ", props.class)}> '#6D7278',
{ '#D8D8D8',
colorList.value.map((item, index) => < div '#0091FF',
key={index} '#B620E0',
onClick={() => context.emit('update:value', item)} '#F31260'
class="text-[12px] cursor-pointer w-[20px] h-[20px] shadow-[0_0_2px_#999] rounded-full" ]
style={{ if (props.colorList) {
backgroundColor: item === 'transparent' ? '' : item, list = props.colorList
backgroundImage: }
item === 'transparent' if (props.transparent) {
? `linear-gradient(45deg, rgba(0, 0, 0, 0.4) 25%, white 25%, transparent 75%,rgba(0, 0, 0, 0.4) 75%), list.push('transparent')
}
if (!list.includes(firstColor)) {
list.unshift(firstColor)
}
return list
})
return () => (
<div class={clsx('flex items-center gap-x-2 ', props.class)}>
{colorList.value.map((item, index) => (
<div
key={index}
onClick={() => context.emit('update:value', item)}
class="text-[12px] cursor-pointer w-[20px] h-[20px] flex items-center justify-center shadow-[0_0_2px_#999] rounded-full"
style={{
width: props.size + 'px',
height: props.size + 'px',
backgroundColor: item === 'transparent' ? '' : item,
backgroundImage:
item === 'transparent'
? `linear-gradient(45deg, rgba(0, 0, 0, 0.4) 25%, white 25%, transparent 75%,rgba(0, 0, 0, 0.4) 75%),
linear-gradient(45deg,rgba(0, 0, 0, 0.4) 25%, white 25%, transparent 75%, rgba(0, 0, 0, 0.4) 75%)` linear-gradient(45deg,rgba(0, 0, 0, 0.4) 25%, white 25%, transparent 75%, rgba(0, 0, 0, 0.4) 75%)`
: '', : '',
backgroundPosition: item === 'transparent' ? '0 0, 2px 2px' : '', backgroundPosition: item === 'transparent' ? '0 0, 2px 2px' : '',
backgroundSize: item === 'transparent' ? '4px 4px' : '' backgroundSize: item === 'transparent' ? '4px 4px' : ''
}} }}
> >
{/* <Checkmark16Filled {/* <Checkmark16Filled
class="text-[#888]" class="text-[#888]"
: class="props.modelValue === item ? '' : 'hidden'" : class="props.modelValue === item ? '' : 'hidden'"
: style="{ : style="{
@ -78,32 +84,34 @@ export default defineComponent({
}" }"
> >
</Checkmark16Filled> */} </Checkmark16Filled> */}
{ {props.value === item && (
props.value === item && <OhVueIcon class="text-[#888]" name={MdCheck.name}></OhVueIcon>
<OhVueIcon class="text-[#888]" name={MdCheck.name} ></OhVueIcon> )}
</div>
))}
} <div
</div >) class="text-[12px] cursor-pointer shadow-[0_0_2px_#999] rounded-full relative"
} style={{
width: props.size + 'px',
<div height: props.size + 'px'
class="text-[12px] cursor-pointer w-[20px] h-[20px] shadow-[0_0_2px_#999] rounded-full relative" }}
> >
<div <div
class="w-full h-full rounded-full cursor-pointer" class="w-full h-full rounded-full cursor-pointer"
style="background: conic-gradient(#dd0010, yellow, green, #0091ff, red)" style="background: conic-gradient(#dd0010, yellow, green, #0091ff, red)"
> >
<input <input
onInput={(e: any) => {
onInput={(e: any)=> { context.emit('update:value', e?.target.value)
context.emit('update:value', e?.target.value) }}
}} ref="inputRef"
ref="inputRef" type="color"
type="color" style="opacity: 0"
style="opacity: 0" />
/> </div>
</div> </div>
</div> </div>
</div > )
} }
}) })

View File

@ -21,6 +21,7 @@ export default defineComponent({
}, },
components: { components: {
Slider: { Slider: {
railSize: 6 railSize: 6
}, },