11<script setup lang="ts">
2- import type { ColorType , ThemeMetas } from ' magic-color'
32import { mc } from ' magic-color'
43import Button from ' primevue/button'
54import Column from ' primevue/column'
65import DataTable from ' primevue/datatable'
6+ import Popover from ' primevue/popover'
7+ import Select from ' primevue/select'
78import Extension from ' ./extension/index.vue'
89
9- const props = withDefaults (defineProps <{
10- name: string
11- colors: ThemeMetas
12- type? : ColorType
13- showArrow? : boolean
14- ext? : boolean
15- }>(), {
16- type: ' hex' ,
17- showArrow: false ,
18- ext: false ,
19- })
10+ const {
11+ color,
12+ alpha,
13+ exportType,
14+ colors,
15+ name,
16+ getReadable,
17+ formatColor,
18+ channelHeaders,
19+ tableData,
20+ copyColor,
21+ copied,
22+ copiedColor,
23+ } = useTheme ()
2024
21- function getReadable( v : string ) {
22- return mc . readable ( {
23- bgColor: v ,
24- textColor: props . colors [ 100 ] ,
25- fallbackTextColor: props . colors [ 900 ] ,
26- })
27- }
25+ const op = ref ()
26+ const {
27+ onMouseEnter ,
28+ onMouseLeave ,
29+ onContentMouseEnter ,
30+ onContentMouseLeave,
31+ } = usePopoverHover ( op )
2832
29- const { copy, copied } = useClipboard ()
30- const copiedColor = ref <string | null >(null )
31- const exportType = ref <ColorType >(props .type )
32-
33- function formatColor(v : string ) {
34- return mc (v ).to (exportType .value ).css ().toUpperCase ()
35- }
36-
37- function copyColor(v : string ) {
38- copy (formatColor (v ))
39- copiedColor .value = v
40- }
41-
42- function handleExportTypeChange(e : Event ) {
43- const target = e .target as HTMLInputElement
44- exportType .value = target .value as ColorType
45- }
46-
47- const shades = computed (() => {
48- return Object .keys (props .colors ).sort ((a , b ) => Number (a ) - Number (b ))
49- })
50-
51- const tableData = computed (() => {
52- return [
53- { ... props .colors , rowType: ' color' },
54- { ... props .colors , rowType: ' value' },
55- ]
56- })
33+ const options = mc .supports .map (type => ({ label: type .toUpperCase (), value: type }))
5734 </script >
5835
5936<template >
6037 <div pt-4 pb-6 px-6 rd-3 transition max-h-min >
38+ <Popover ref =" op" >
39+ <div @mouseenter =" onContentMouseEnter" @mouseleave =" onContentMouseLeave" >
40+ <Palette v-model:color =" color" v-model:alpha =" alpha" v-model:type =" exportType" />
41+ </div >
42+ </Popover >
6143 <DataTable
6244 :value =" tableData"
6345 class =" w-full !bg-transparent"
@@ -71,69 +53,76 @@ const tableData = computed(() => {
7153 >
7254 <template #header >
7355 <div fbc >
74- <h3 text-xl fw-700 >
75- {{ name }}
56+ <h3
57+ flex items-center gap-2
58+ @mouseenter =" onMouseEnter"
59+ @mouseleave =" onMouseLeave"
60+ >
61+ <div >
62+ <div
63+ class =" size-6 rounded shadow cursor-pointer border border-gray:10 hover:scale-110 transition"
64+ :style =" { backgroundColor: color }"
65+ />
66+ </div >
67+ <span class =" text-xl fw-700" >{{ name }}</span >
7668 </h3 >
7769 <div fsc gap-2 >
7870 <span text-sm >
7971 Type as:
8072 </span >
81- <div fcc gap-3 >
82- <div v-for =" type in mc.supports" :key =" type" class =" inline-flex items-center" >
83- <label class =" relative flex items-center cursor-pointer" :for =" type" >
84- <input
85- :id =" type" :value =" type" name =" exportType" type =" radio" :checked =" exportType === type"
86- class =" peer h-4 w-4 cursor-pointer appearance-none rounded-full border border-slate-300:50 checked:border-purple:30 transition-all"
87- @change =" handleExportTypeChange"
88- >
89- <span
90- class =" absolute bg-yellow size-0 rounded-full peer-checked:size-2.2 transition-all duration-200 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
91- />
92- </label >
93- <label class =" ml-1 text-primary:80 cursor-pointer text-sm" :for =" type" fcc gap-1 >
94- {{ type.toUpperCase() }}
95- </label >
96- </div >
97- </div >
73+ <Select
74+ v-model =" exportType"
75+ :options =" options"
76+ option-label =" label"
77+ option-value =" value"
78+ size =" small"
79+ class =" !h-7 flex items-center important:[& >span]:text-12.5px"
80+ :pt =" {
81+ label: 'py-0',
82+ option: '!text-xs !py-1',
83+ }"
84+ />
9885 </div >
9986 </div >
10087 </template >
88+ <Column field =" shade" header =" Shade" style =" width : 10% " >
89+ <template #body =" { data } " >
90+ <span font-bold >{{ data.shade }}</span >
91+ </template >
92+ </Column >
93+ <Column header =" Color" style =" width : 40% " >
94+ <template #body =" { data } " >
95+ <Button
96+ class =" w-full h-10 rd fcc relative cursor-pointer group transition hover:scale-105"
97+ :style =" { backgroundColor: formatColor(data.color), color: getReadable(data.color) }"
98+ unstyled
99+ @click =" copyColor(data.color)"
100+ >
101+ <i
102+ :class =" [
103+ copied && copiedColor === data.color ? 'i-carbon-checkmark opacity-100' : 'i-carbon-copy opacity-0 group-hover:opacity-100',
104+ ]"
105+ transition-opacity duration-200
106+ />
107+ </Button >
108+ </template >
109+ </Column >
110+ <Column header =" Value" style =" width : 20% " >
111+ <template #body =" { data } " >
112+ <span text-sm font-mono op-80 >{{ formatColor(data.color) }}</span >
113+ </template >
114+ </Column >
101115 <Column
102- v-for =" shade in shades"
103- :key =" shade"
104- :field =" String(shade)"
105- :header =" String(shade)"
106- style =" min-width : 6rem "
107- header-class =" [& >div]:w-full [& >div]:justify-center"
116+ v-for =" (header, index) in channelHeaders"
117+ :key =" header"
118+ :header =" header"
119+ style =" width : 10% "
108120 >
109121 <template #body =" { data } " >
110- <div flex justify-center >
111- <template v-if =" data .rowType === ' color' " >
112- <Button
113- class =" w-1 h-15 rd fcc relative cursor-pointer group transition hover:scale-110"
114- :style =" { backgroundColor: data[shade], color: getReadable(data[shade]) }"
115- unstyled
116- @click =" copyColor(data[shade])"
117- >
118- <i
119- :class =" [
120- copied && copiedColor === data[shade] ? 'i-carbon-checkmark opacity-100' : 'i-carbon-copy opacity-0 group-hover:opacity-100',
121- ]"
122- transition-opacity duration-200
123- />
124- </Button >
125- </template >
126- <template v-else >
127- <span text-sm uppercase font-mono >{{ formatColor(data[shade]) }}</span >
128- </template >
129- </div >
122+ <span font-mono text-sm :class =" ['text-red', 'text-green', 'text-blue'][index]" >{{ data.channelValues[index] }}</span >
130123 </template >
131124 </Column >
132125 </DataTable >
133- <KeepAlive >
134- <Extension mt-8 :colors :name >
135- <slot name =" ext" />
136- </Extension >
137- </KeepAlive >
126+ <Extension mt-8 :colors :name :type =" exportType" />
138127 </div >
139128</template >
0 commit comments