-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
209 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Component } from "@angular/core"; | ||
import { RouterLink } from "@angular/router"; | ||
import { | ||
PageActionsDirective, | ||
PageHeaderDescriptionDirective, | ||
PageHeaderDirective, | ||
PageHeaderHeadingDirective, | ||
} from "@/app/shared/page-header.directive"; | ||
|
||
import { UbButtonDirective } from "@/registry/new-york/ui/button.directive"; | ||
import { getColors } from "@/lib/colors"; | ||
|
||
@Component({ | ||
selector: "www-colors", | ||
standalone: true, | ||
imports: [ | ||
RouterLink, | ||
PageHeaderDirective, | ||
PageHeaderHeadingDirective, | ||
PageHeaderDescriptionDirective, | ||
PageActionsDirective, | ||
UbButtonDirective, | ||
], | ||
template: ` <div class="container relative"> | ||
<section pageHeader> | ||
<h1 pageHeaderHeading>Tailwind Colors</h1> | ||
<p pageHeaderDescription> | ||
Tailwind CSS colors in HSL, RGB, and HEX formats. | ||
</p> | ||
<div pageActions> | ||
<a routerLink="#colors" ubButton size="sm"> Browse Colors </a> | ||
<a routerLink="/docs/theming" ubButton variant="ghost" size="sm"> | ||
Documentation | ||
</a> | ||
</div> | ||
</section> | ||
<section class="scroll-mt-20"> | ||
<div id="colors" class="grid scroll-mt-20 gap-8"> | ||
@for (colorPalette of colors; track $index) { | ||
<div class="rounded-lg shadow-sm ring-1 ring-border"> | ||
<div class="flex items-center p-2 pb-0"> | ||
<div class="flex-1 pl-1 text-sm font-medium"> | ||
<h2 class="capitalize">{{ colorPalette.name }}</h2> | ||
</div> | ||
</div> | ||
<div class="flex flex-col gap-1 p-2 sm:flex-row sm:gap-2"> | ||
@for (color of colorPalette.colors;track $index) { | ||
<button | ||
class="group relative flex aspect-[3/1] w-full flex-1 flex-col gap-2 text-[--text] sm:aspect-[2/3] sm:h-auto sm:w-auto [&>svg]:absolute [&>svg]:right-4 [&>svg]:top-4 [&>svg]:h-3.5 [&>svg]:w-3.5 [&>svg]:opacity-0 [&>svg]:transition-opacity" | ||
[style]="{ | ||
'--bg': 'hsl('+color.hsl+')', | ||
'--text': color.foreground, | ||
}" | ||
> | ||
<div | ||
class="w-full flex-1 rounded-md bg-[--bg] md:rounded-lg" | ||
></div> | ||
<div | ||
class="flex w-full flex-col items-center justify-center gap-1" | ||
> | ||
<span | ||
class="hidden font-mono text-xs tabular-nums text-muted-foreground transition-colors group-hover:text-foreground lg:flex" | ||
> | ||
{{ color.className }} | ||
</span> | ||
<span | ||
class="font-mono text-xs tabular-nums text-muted-foreground transition-colors group-hover:text-foreground lg:hidden" | ||
> | ||
{{ color.scale }} | ||
</span> | ||
</div> | ||
</button> | ||
} | ||
</div> | ||
</div> | ||
} | ||
</div> | ||
</section> | ||
</div>`, | ||
}) | ||
export default class HomeComponent { | ||
protected readonly colors = getColors(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { z } from "zod"; | ||
|
||
import { colors } from "@/registry/colors"; | ||
|
||
const colorSchema = z.object({ | ||
name: z.string(), | ||
id: z.string(), | ||
scale: z.number(), | ||
className: z.string(), | ||
hex: z.string(), | ||
rgb: z.string(), | ||
hsl: z.string(), | ||
foreground: z.string(), | ||
}); | ||
|
||
const colorPaletteSchema = z.object({ | ||
name: z.string(), | ||
colors: z.array(colorSchema), | ||
}); | ||
|
||
export type ColorPalette = z.infer<typeof colorPaletteSchema>; | ||
|
||
export function getColorFormat(color: Color) { | ||
return { | ||
className: `bg-${color.name}-100`, | ||
hex: color.hex, | ||
rgb: color.rgb, | ||
hsl: color.hsl, | ||
}; | ||
} | ||
|
||
export type ColorFormat = keyof ReturnType<typeof getColorFormat>; | ||
|
||
export function getColors() { | ||
const tailwindColors = colorPaletteSchema.array().parse( | ||
Object.entries(colors) | ||
.map(([name, color]) => { | ||
if (!Array.isArray(color)) { | ||
return null; | ||
} | ||
|
||
return { | ||
name, | ||
colors: color.map((color) => { | ||
const rgb = color.rgb.replace( | ||
/^rgb\((\d+),(\d+),(\d+)\)$/, | ||
"$1 $2 $3" | ||
); | ||
|
||
return { | ||
...color, | ||
name, | ||
id: `${name}-${color.scale}`, | ||
className: `${name}-${color.scale}`, | ||
rgb, | ||
hsl: color.hsl.replace( | ||
/^hsl\(([\d.]+),([\d.]+%),([\d.]+%)\)$/, | ||
"$1 $2 $3" | ||
), | ||
foreground: getForegroundFromBackground(rgb), | ||
}; | ||
}), | ||
}; | ||
}) | ||
.filter(Boolean) | ||
); | ||
|
||
return tailwindColors; | ||
} | ||
|
||
export type Color = ReturnType<typeof getColors>[number]["colors"][number]; | ||
|
||
function getForegroundFromBackground(rgb: string) { | ||
const [r, g, b] = rgb.split(" ").map(Number); | ||
|
||
function toLinear(number: number): number { | ||
const base = number / 255; | ||
return base <= 0.04045 | ||
? base / 12.92 | ||
: Math.pow((base + 0.055) / 1.055, 2.4); | ||
} | ||
|
||
const luminance = | ||
0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b); | ||
|
||
return luminance > 0.179 ? "#000" : "#fff"; | ||
} |