From ace3865fdfeafc29a1330f17597d1bb740855ca3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adri=C3=A1n=20UB?=
<22903142+adrian-ub@users.noreply.github.com>
Date: Thu, 7 Nov 2024 17:46:54 -0500
Subject: [PATCH] docs: add colors page
---
docs/src/components/Color.astro | 74 +++++++
docs/src/components/ColorFormatSelector.astro | 186 ++++++++++++++++++
docs/src/components/ColorPalette.astro | 29 +++
docs/src/config/docs.ts | 4 +
docs/src/lib/colors.ts | 87 ++++++++
docs/src/pages/colors/_colors.astro | 10 +
docs/src/pages/colors/index.astro | 47 +++++
7 files changed, 437 insertions(+)
create mode 100644 docs/src/components/Color.astro
create mode 100644 docs/src/components/ColorFormatSelector.astro
create mode 100644 docs/src/components/ColorPalette.astro
create mode 100644 docs/src/lib/colors.ts
create mode 100644 docs/src/pages/colors/_colors.astro
create mode 100644 docs/src/pages/colors/index.astro
diff --git a/docs/src/components/Color.astro b/docs/src/components/Color.astro
new file mode 100644
index 0000000..3a99361
--- /dev/null
+++ b/docs/src/components/Color.astro
@@ -0,0 +1,74 @@
+---
+import { type Color } from '@/lib/colors'
+
+export interface Props {
+ color: Color
+}
+const { color } = Astro.props
+---
+
+
diff --git a/docs/src/components/ColorFormatSelector.astro b/docs/src/components/ColorFormatSelector.astro
new file mode 100644
index 0000000..ec23abb
--- /dev/null
+++ b/docs/src/components/ColorFormatSelector.astro
@@ -0,0 +1,186 @@
+---
+import { getColorFormat, type Color } from '@/lib/colors'
+import { cn } from '@/lib/utils'
+
+export interface Props {
+ class?: string
+ color: Color
+}
+
+const { color, class: className } = Astro.props
+
+const formats = getColorFormat(color)
+
+const options = Object.entries(formats).map(([format, title]) => ({ value: format, title, format }))
+---
+
+
a.value).indexOf(this.selectableItemActive);
+ if(index < this.selectableItems.length-1){
+ this.selectableItemActive = this.selectableItems[index+1].value;
+ this.selectScrollToActiveItem();
+ }
+ },
+ selectableItemActivePrevious(){
+ let index = this.selectableItems.map(a=>a.value).indexOf(this.selectableItemActive);
+ if(index > 0){
+ this.selectableItemActive = this.selectableItems[index-1].value;
+ this.selectScrollToActiveItem();
+ }
+ },
+ selectScrollToActiveItem(){
+ if(this.selectableItemActive){
+ activeElement = document.getElementById(this.selectableItemActive + '-' + this.selectId)
+ newScrollPos = (activeElement.offsetTop + activeElement.offsetHeight) - this.$refs.selectableItemsList.offsetHeight;
+ if(newScrollPos > 0){
+ this.$refs.selectableItemsList.scrollTop=newScrollPos;
+ } else {
+ this.$refs.selectableItemsList.scrollTop=0;
+ }
+ }
+ },
+ selectKeydown(event){
+ if (event.keyCode >= 65 && event.keyCode <= 90) {
+
+ this.selectKeydownValue += event.key;
+ selectedItemBestMatch = this.selectItemsFindBestMatch();
+ if(selectedItemBestMatch){
+ if(this.selectOpen){
+ this.selectableItemActive = selectedItemBestMatch;
+ this.selectScrollToActiveItem();
+ } else {
+ this.selectedItem = this.selectableItemActive = selectedItemBestMatch;
+ }
+ }
+
+ if(this.selectKeydownValue != ''){
+ clearTimeout(this.selectKeydownClearTimeout);
+ this.selectKeydownClearTimeout = setTimeout(() => {
+ this.selectKeydownValue = '';
+ }, this.selectKeydownTimeout);
+ }
+ }
+ },
+ selectItemsFindBestMatch(){
+ typedValue = this.selectKeydownValue.toLowerCase();
+ var bestMatch = null;
+ var bestMatchIndex = -1;
+ for (var i = 0; i < this.selectableItems.length; i++) {
+ var title = this.selectableItems[i].title.toLowerCase();
+ var index = title.indexOf(typedValue);
+ if (index > -1 && (bestMatchIndex == -1 || index < bestMatchIndex) && !this.selectableItems[i].disabled) {
+ bestMatch = this.selectableItems[i].value;
+ bestMatchIndex = index;
+ }
+ }
+ return bestMatch;
+ },
+ selectPositionUpdate(){
+ selectDropdownBottomPos = this.$refs.selectButton.getBoundingClientRect().top + this.$refs.selectButton.offsetHeight + parseInt(window.getComputedStyle(this.$refs.selectableItemsList).maxHeight);
+ if(window.innerHeight < selectDropdownBottomPos){
+ this.selectDropdownPosition = 'top';
+ } else {
+ this.selectDropdownPosition = 'bottom';
+ }
+ }
+}`
+ x-init="
+ $watch('selectOpen', function(){
+ if(!selectedItem){
+ selectableItemActive=selectableItems[0].value;
+ } else {
+ selectableItemActive=selectedItem;
+ }
+ setTimeout(function(){
+ selectScrollToActiveItem();
+ }, 10);
+ selectPositionUpdate();
+ window.addEventListener('resize', (event) => { selectPositionUpdate(); });
+ });
+"
+ x-effect="selectedItem = $store.format;"
+ @keydown.escape="if(selectOpen){ selectOpen=false; }"
+ @keydown.down="if(selectOpen){ selectableItemActiveNext(); } else { selectOpen=true; } event.preventDefault();"
+ @keydown.up="if(selectOpen){ selectableItemActivePrevious(); } else { selectOpen=true; } event.preventDefault();"
+ @keydown.enter="$store.format=selectableItemActive; selectOpen=false;"
+ @keydown="selectKeydown($event);"
+>
+
+
+
+
diff --git a/docs/src/components/ColorPalette.astro b/docs/src/components/ColorPalette.astro
new file mode 100644
index 0000000..b5aa2b2
--- /dev/null
+++ b/docs/src/components/ColorPalette.astro
@@ -0,0 +1,29 @@
+---
+import type { ColorPalette } from '@/lib/colors'
+import Color from './Color.astro'
+import ColorFormatSelector from './ColorFormatSelector.astro'
+
+export interface Props {
+ colorPalette: ColorPalette
+}
+
+const { colorPalette } = Astro.props
+---
+
+
+
+
+
{colorPalette.name}
+
+
+
+
+ {colorPalette.colors.map((color) => )}
+
+
+
+
diff --git a/docs/src/config/docs.ts b/docs/src/config/docs.ts
index a72be01..22d8b2d 100644
--- a/docs/src/config/docs.ts
+++ b/docs/src/config/docs.ts
@@ -32,6 +32,10 @@ export const docsConfig: TDocsConfig = {
title: 'Examples',
href: '/examples/authentication',
},
+ {
+ title: 'Colors',
+ href: '/colors',
+ },
],
sidebarNav: [
{
diff --git a/docs/src/lib/colors.ts b/docs/src/lib/colors.ts
new file mode 100644
index 0000000..40a3040
--- /dev/null
+++ b/docs/src/lib/colors.ts
@@ -0,0 +1,87 @@
+import { colors } from '@/registry/registry-colors'
+
+import { z } from 'zod'
+
+const colorSchema = z.object({
+ name: z.string(),
+ id: z.string(),
+ scale: z.number(),
+ class: 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
+
+export function getColorFormat(color: Color): { class: string, hex: string, rgb: string, hsl: string } {
+ return {
+ class: `bg-${color.name}-100`,
+ hex: color.hex,
+ rgb: color.rgb,
+ hsl: color.hsl,
+ }
+}
+
+export type ColorFormat = keyof ReturnType
+
+export function getColors(): ColorPalette[] {
+ 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}`,
+ class: `${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[number]['colors'][number]
+
+function toLinear(number: number): number {
+ const base = number / 255
+ return base <= 0.04045
+ ? base / 12.92
+ : ((base + 0.055) / 1.055) ** 2.4
+}
+
+function getForegroundFromBackground(rgb: string): string {
+ const [r, g, b] = rgb.split(' ').map(Number)
+
+ const luminance
+ = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b)
+
+ return luminance > 0.179 ? '#000' : '#fff'
+}
diff --git a/docs/src/pages/colors/_colors.astro b/docs/src/pages/colors/_colors.astro
new file mode 100644
index 0000000..aca9460
--- /dev/null
+++ b/docs/src/pages/colors/_colors.astro
@@ -0,0 +1,10 @@
+---
+import { getColors } from '@/lib/colors'
+import ColorPalette from '@/components/ColorPalette.astro'
+
+const colors = getColors()
+---
+
+
+ {colors.map((colorPalette) => )}
+
diff --git a/docs/src/pages/colors/index.astro b/docs/src/pages/colors/index.astro
new file mode 100644
index 0000000..1e670cc
--- /dev/null
+++ b/docs/src/pages/colors/index.astro
@@ -0,0 +1,47 @@
+---
+import Announcement from '@/components/Announcement.astro'
+import { PageActions, PageHeader, PageHeaderDescription, PageHeaderHeading } from '@/components/page-header'
+import RootLayout from '@/layouts/RootLayout.astro'
+import { buttonVariants } from '@/registry/new-york/ui/button'
+
+import Colors from './_colors.astro'
+import { siteConfig } from '@/config/site'
+---
+
+
+
+