From f7bcea17aa83dfbbb91ff472ad1c27221584b756 Mon Sep 17 00:00:00 2001 From: Oliver Pan <2216991777@qq.com> Date: Mon, 24 Jun 2024 00:28:32 -0500 Subject: [PATCH] feat: added redability hover card --- .../palette/base-color-palettes.tsx | 341 +++++++++++++----- 1 file changed, 253 insertions(+), 88 deletions(-) diff --git a/apps/web/components/palette/base-color-palettes.tsx b/apps/web/components/palette/base-color-palettes.tsx index 955a218..8073f95 100644 --- a/apps/web/components/palette/base-color-palettes.tsx +++ b/apps/web/components/palette/base-color-palettes.tsx @@ -1,116 +1,281 @@ -import { colorStepMap } from "@/lib/colorStepMap"; -import { useColorStore } from "@/store/store"; -import { BaseColorTypes } from "@/types/app"; -import { cn } from "@ui/lib/utils"; -import React from "react"; +'use client' -import PaletteButton from "./base-palette-button"; -import ColorString from "./color-string"; -import ReadabilityString from "./readability-string"; +import { useColorStore } from '@/context/color-store-provider' + +import { useToolStore } from '@/store/toolStore' +import { BaseColorTypes } from '@/types/app' +import { cn } from '@ui/lib/utils' + +import { ColorStep, colorStepMap } from '@/lib/colorStepMap' +import { Separator } from '@ui/components/ui/separator' +import PaletteButton from './base-palette-button' +import ColorString from './color-string' +import ReadabilityString from './readability-string' + +import { HoverCard, HoverCardContent, HoverCardTrigger } from '@ui/components/ui/hover-card' +import { AArrowUp, X } from 'lucide-react' +import { useState } from 'react' + +const ReadabilityBadge = ({ score }: { score?: number }) => { + if (!score) return null + const eligibleText = `WCAG compliance level ${score >= 7 ? 'AAA' : 'AA'} with a score of ${score}` + const eligibleConditionalText = `Eligible for WCAG compliance when text size is over 18px bold or 24px regular, with a score of ${score}` + const ineligibleText = `Ineligible for WCAG compliance with a score of ${score}` + const badgeClassName = cn( + ' z-[9] flex w-6 items-center justify-center rounded-full border py-2 text-sm font-semibold text-foreground shadow-lg', + { 'bg-white dark:bg-zinc-900': score >= 4.5 }, + { 'bg-amber-200 dark:bg-amber-900': score < 4.5 && score >= 3.1 }, + { 'bg-rose-200 dark:bg-rose-950': score < 3.1 } + ) + return ( + <> +
= 4.5 ? eligibleText : score >= 3.1 ? eligibleConditionalText : ineligibleText} + > + {score >= 4.5 ? ( +
+ + {eligibleText} +
+ ) : score >= 3.1 ? ( + <> + + {eligibleConditionalText} + + ) : ( + <> + + {ineligibleText} + + )} +
+
+
+ = 4.5 }, + { 'text-amber-700 dark:text-amber-200': score < 4.5 && score >= 3.1 }, + { 'text-rose-700 dark:text-rose-200': score < 3.1 } + )} + > + {score.toFixed(1)} + +
+
+ + ) +} + +const PreviewText = ({ + backgroundColor, + color, + cursorX = 51, + index = 0, +}: { + backgroundColor?: string + color: string + cursorX?: number + index?: number +}) => { + const shift = 2 // 2% shift + const clipPathWidth = Math.min(95, Math.max(5, cursorX)) + return ( +
+

+ The five boxing wizards jump quickly. +

+
+ ) +} function BaseColorPalettes() { - const { colorPalettes, colorMode, showReadability } = - useColorStore.getState(); - const animation = (i, type) => { - let baseDelay = 0.12; + const { colorPalettes } = useColorStore((s) => s.colors) + const { colorMode, showReadability } = useToolStore() + const [cursorX, setCusorX] = useState(51) + const [cursorY, setCusorY] = useState(50) + const animation = (i: number, type: BaseColorTypes) => { + let baseDelay = 0.12 switch (type) { - case "primary": - baseDelay += 0; - break; - case "secondary": - baseDelay += 0.06; - break; - case "accent": - baseDelay += 0.12; - break; - case "gray": - baseDelay += 0.18; - break; + case 'primary': + baseDelay += 0 + break + case 'secondary': + baseDelay += 0.06 + break + case 'accent': + baseDelay += 0.12 + break + case 'gray': + baseDelay += 0.18 + break default: - baseDelay += 0; - break; + baseDelay += 0 + break } - let springDelay = Math.round((Math.pow(1.2, i) - 0.8) * 100) / 100; - return baseDelay + springDelay * 0.06; - }; + let springDelay = Math.round((Math.pow(1.2, i) - 0.8) * 100) / 100 + return baseDelay + springDelay * 0.06 + } + const colorPaletteNames: BaseColorTypes[] = ['primary', 'secondary', 'accent', 'gray'] + const handleDragClipPath = (e: React.MouseEvent) => { + const { clientX, clientY } = e + const { left, right, top, bottom } = e.currentTarget.getBoundingClientRect() + const width = right - left + const cursorX = ((clientX - left) / width) * 100 + const cursorY = ((clientY - top) / (bottom - top)) * 100 + setCusorX(cursorX) + setCusorY(cursorY) + } return (
- {Object.keys(colorPalettes).map((type: BaseColorTypes) => { + {colorPaletteNames.map((type: BaseColorTypes) => { return (
{colorPalettes[type].map((color, i) => { - const step = i; + const step: ColorStep = i as any return ( -
- -
-
- {colorStepMap[i]} -
-
+ + +
+ +
- {showReadability ? ( - - ) : ( - - )} +
{colorStepMap[step]}
+
+
+ {showReadability ? ( + + ) : ( + + )} +
+
+
+
+
+ +
{ + setTimeout(() => { + setCusorX(51) + setCusorY(50) + }, 500) + }} + > +
+
+
+ +
+ + + +
+
+ +
+ +
+ +
-
-
- ); + + + ) })}
- ); + ) })}
- ); + ) } -export default BaseColorPalettes; +export default BaseColorPalettes