Skip to content

Commit

Permalink
feat: add colors page
Browse files Browse the repository at this point in the history
  • Loading branch information
adrian-ub committed Jul 25, 2024
1 parent 6047b47 commit b25c24c
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 45 deletions.
84 changes: 84 additions & 0 deletions apps/www/src/app/pages/colors.page.ts
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();
}
53 changes: 23 additions & 30 deletions apps/www/src/app/shared/header/header.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { Component } from '@angular/core';
import { MainNavComponent } from './main-nav.component';
import { Component } from "@angular/core";

import { NgIconComponent, provideIcons } from "@ng-icons/core";
import { radixGithubLogo, radixTwitterLogo } from "@ng-icons/radix-icons";

import { UbButtonDirective } from "@/registry/new-york/ui/button.directive";

import { MainNavComponent } from "./main-nav.component";

@Component({
standalone: true,
imports: [MainNavComponent],
selector: 'www-header',
imports: [MainNavComponent, UbButtonDirective, NgIconComponent],
viewProviders: [provideIcons({ radixGithubLogo, radixTwitterLogo })],
selector: "www-header",
template: `
<header
class="sticky top-0 z-50 w-full border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"
Expand All @@ -19,40 +26,26 @@ import { MainNavComponent } from './main-nav.component';
<!-- <CommandMenu /> -->
</div>
<nav class="flex items-center">
<!-- <Link
href={siteConfig.links.github}
<a
href="https://github.com/adrian-ub/shadcn-ng"
target="_blank"
rel="noreferrer"
>
<div
class={cn(
buttonVariants({
variant: "ghost",
}),
"h-8 w-8 px-0"
)}
>
<Icons.gitHub class="h-4 w-4" />
<button ubButton variant="ghost" class="h-8 w-8 px-0">
<!-- <ng-icon name="radixGithubLogo" class="h-4 w-4" /> -->
<span class="sr-only">GitHub</span>
</div>
</Link> -->
<!-- <Link
href={siteConfig.links.twitter}
</button>
</a>
<a
href="https://twitter.com/adrianub"
target="_blank"
rel="noreferrer"
>
<div
class={cn(
buttonVariants({
variant: "ghost",
}),
"h-8 w-8 px-0"
)}
>
<Icons.twitter class="h-3 w-3 fill-current" />
<button ubButton variant="ghost" class="h-8 w-8 px-0">
<!-- <ng-icon name="radixTwitterLogo" class="h-3 w-3 fill-current" /> -->
<span class="sr-only">Twitter</span>
</div>
</Link> -->
</button>
</a>
<!-- <ModeToggle /> -->
</nav>
</div>
Expand Down
30 changes: 15 additions & 15 deletions apps/www/src/app/shared/header/main-nav.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { NgClass } from '@angular/common';
import { Component } from '@angular/core';
import { NgClass } from "@angular/common";
import { Component } from "@angular/core";

import { RouterLink, RouterLinkActive } from '@angular/router';
import { RouterLink, RouterLinkActive } from "@angular/router";

@Component({
standalone: true,
imports: [RouterLink, RouterLinkActive, NgClass],
selector: 'MainNav',
selector: "MainNav",
template: `
<div class="mr-4 hidden md:flex">
<a routerLink="/" class="mr-4 flex items-center space-x-2 lg:mr-6">
Expand All @@ -20,7 +20,7 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
#rla="routerLinkActive"
[ngClass]="[
'transition-colors hover:text-foreground/80',
rla.isActive ? 'text-foreground' : 'text-foreground/60',
rla.isActive ? 'text-foreground' : 'text-foreground/60'
]"
>
Docs
Expand All @@ -31,7 +31,7 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
#rla="routerLinkActive"
[ngClass]="[
'transition-colors hover:text-foreground/80',
rla.isActive ? 'text-foreground' : 'text-foreground/60',
rla.isActive ? 'text-foreground' : 'text-foreground/60'
]"
>
Components
Expand Down Expand Up @@ -81,17 +81,17 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
>
Examples
</Link> -->
<!-- <Link
href="/colors"
class={cn(
"transition-colors hover:text-foreground/80",
pathname?.startsWith("/colors")
? "text-foreground"
: "text-foreground/60"
)}
<a
routerLink="/colors"
routerLinkActive
#rla="routerLinkActive"
[ngClass]="[
'transition-colors hover:text-foreground/80',
rla.isActive ? 'text-foreground' : 'text-foreground/60'
]"
>
Colors
</Link> -->
</a>
</nav>
</div>
`,
Expand Down
87 changes: 87 additions & 0 deletions apps/www/src/lib/colors.ts
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";
}

0 comments on commit b25c24c

Please sign in to comment.