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 ? (
+
+ {score >= 7 ? 'AAA' : 'AA'}
+ {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