Skip to content

Commit

Permalink
✨fix by @vanling: Add some color magic for light text colors
Browse files Browse the repository at this point in the history
  • Loading branch information
ThijmenGThN authored Jan 24, 2023
2 parents 3dee37a + f7c9b30 commit 63affeb
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
9 changes: 7 additions & 2 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Content from '@/components/Content'

export default function Index({ git }: any) {
const [hex, setHex] = useState('#6644FF')
const [hexText, setHexText] = useState('#6644FF')
const [content, setContent] = useState('')

// Interface element states.
Expand All @@ -31,6 +32,10 @@ export default function Index({ git }: any) {
// Ensure hex starts with a "#".
!hex.startsWith('#') && setHex('#' + hex)

// Ensures that any given hex color can be seen infront of a white background.
// -->> Implementation by https://github.com/vanling - Thanks!
setHexText(shade.contrast(hex, hex, '#000'))

// Update the css object.
setContent(shade.wrap(hex))
}, [hex])
Expand Down Expand Up @@ -74,7 +79,7 @@ export default function Index({ git }: any) {
className="p-4 font-semibold border-2 outline-0 border-neutral-300 rounded-lg w-full hover:border-violet-500 hover:border-3"
onMouseOver={({ target }) => borderHover.in(target)}
onMouseOut={({ target }) => borderHover.out(target)}
onChange={({ target }) => { setHex(target.value.trim()) }} style={{ color: hex }}
onChange={({ target }) => { setHex(target.value.trim()) }} style={{ color: hexText }}
/>

<a href="https://github.com/ThijmenGThN/directus-themebuilder/stargazers" target="_blank" rel="noreferrer"
Expand All @@ -89,7 +94,7 @@ export default function Index({ git }: any) {
</div>

{/* ----- SECTION: Custom CSS ----- */}
<Content hex={hex} content={content} />
<Content hex={hex} hexText={hexText} content={content} />

{/* ----- SECTION: Stargazers ----- */}
<div className='mt-10 flex flex-col gap-2'>
Expand Down
4 changes: 2 additions & 2 deletions source/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { BiCopy } from 'react-icons/bi'
import { FaCheck } from 'react-icons/fa'


export default function Content({ content, hex }: { content: string, hex: string }) {
export default function Content({ content, hex, hexText }: { content: string, hex: string, hexText: string }) {
const [copied, setCopied] = useState(false)

// Dynamically change the theme based on the hex.
Expand All @@ -18,7 +18,7 @@ export default function Content({ content, hex }: { content: string, hex: string
<p className='font-semibold'>Custom CSS</p>
<div className='flex min-h-[502px] relative overflow-hidden rounded-lg border-2 border-neutral-300 hover:border-3' onMouseOver={({ target }) => borderHover.in(target)} onMouseOut={({ target }) => borderHover.out(target)}>
<div className='bg-slate-100 w-14 border-r-2 pointer-events-none'></div>
<textarea readOnly className='w-full font-semibold outline-0 resize-none p-2 pointer-events-none' style={{ color: hex }} value={content} />
<textarea readOnly className='w-full font-semibold outline-0 resize-none p-2 pointer-events-none' style={{ color: hexText }} value={content} />
{
copied ? (
<button className='absolute top-4 right-4 bg-slate-100 p-3 hover:bg-slate-200 rounded m-1.5 border-2' style={{ color: hex, borderColor: hex }}>
Expand Down
26 changes: 24 additions & 2 deletions source/resources/shade.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

// This function returns a shade based on a give hex and a corresponding percentage, a value may range between -1 and 1. (a higher value means a lighter color)
export const parse = (color: string, percent: number) => {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
let f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1)
}

// Converts a hex color to the required css object format.
export const wrap = (hex: string) => `
#app, #main-content, body {
--primary-alt: ${parse(hex, 0.90)} !important;
Expand All @@ -26,3 +28,23 @@ export const wrap = (hex: string) => `
--sidebar-detail-color-active: ${parse(hex, -0.10)} !important;
}
`.trim()

// Ensures that any given hex color can be seen infront of a white background.
// -->> Implementation by https://github.com/vanling - Thanks!
export const contrast = (bgColor: any, lightColor: any, darkColor: any) => {
const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor

let r = parseInt(color.substring(0, 2), 16)
let g = parseInt(color.substring(2, 4), 16)
let b = parseInt(color.substring(4, 6), 16)

let uicolors = [r / 255, g / 255, b / 255]
let c = uicolors.map((col) =>
col <= 0.03928
? col / 12.92
: Math.pow((col + 0.055) / 1.055, 2.4)
)

let L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2])
return (L > 0.179) ? darkColor : lightColor
}

0 comments on commit 63affeb

Please sign in to comment.