Colour Table

Colour Table — Notes — Danny White

Published on: 2026-02-06

Make a Postgres table with a bunch of mock data

U.S. spelling for all you otherwise-confused Americans.

-- colors seed table (Postgres / Supabase)
-- Creates a reusable `public.colors` table and inserts a basic palette.
-- Safe to re-run: uses IF NOT EXISTS and ON CONFLICT.

BEGIN;

CREATE TABLE IF NOT EXISTS public.colors (
  id           bigserial PRIMARY KEY,
  name         text        NOT NULL,
  slug         text        NOT NULL,
  hex          char(7)     NOT NULL, -- e.g. '#1a2b3c'
  rgb          int[]       NOT NULL, -- e.g. '{26,43,60}'
  is_named     boolean     NOT NULL DEFAULT true,
  created_at   timestamptz NOT NULL DEFAULT now(),
  updated_at   timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT colors_hex_format CHECK (hex ~* '^#[0-9a-f]{6}$'),
  CONSTRAINT colors_rgb_len CHECK (array_length(rgb, 1) = 3),
  CONSTRAINT colors_rgb_range CHECK (
    rgb[1] BETWEEN 0 AND 255 AND
    rgb[2] BETWEEN 0 AND 255 AND
    rgb[3] BETWEEN 0 AND 255
  ),
  CONSTRAINT colors_slug_unique UNIQUE (slug),
  CONSTRAINT colors_hex_unique UNIQUE (hex)
);

-- Optional: keep updated_at fresh on updates (works in plain Postgres).
-- In Supabase, this is fine too. Comment out if you don't want triggers.
CREATE OR REPLACE FUNCTION public.set_updated_at()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
  NEW.updated_at = now();
  RETURN NEW;
END;
$$;

DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1
    FROM pg_trigger
    WHERE tgname = 'trg_colors_set_updated_at'
  ) THEN
    CREATE TRIGGER trg_colors_set_updated_at
    BEFORE UPDATE ON public.colors
    FOR EACH ROW
    EXECUTE FUNCTION public.set_updated_at();
  END IF;
END
$$;

-- Seed data
INSERT INTO public.colors (name, slug, hex, rgb, is_named) VALUES
  ('Black',        'black',        '#000000', ARRAY[0,0,0], true),
  ('White',        'white',        '#FFFFFF', ARRAY[255,255,255], true),

  ('Red',          'red',          '#FF0000', ARRAY[255,0,0], true),
  ('Green',        'green',        '#00FF00', ARRAY[0,255,0], true),
  ('Blue',         'blue',         '#0000FF', ARRAY[0,0,255], true),

  ('Cyan',         'cyan',         '#00FFFF', ARRAY[0,255,255], true),
  ('Magenta',      'magenta',      '#FF00FF', ARRAY[255,0,255], true),
  ('Yellow',       'yellow',       '#FFFF00', ARRAY[255,255,0], true),

  ('Orange',       'orange',       '#FFA500', ARRAY[255,165,0], true),
  ('Purple',       'purple',       '#800080', ARRAY[128,0,128], true),
  ('Pink',         'pink',         '#FFC0CB', ARRAY[255,192,203], true),
  ('Brown',        'brown',        '#A52A2A', ARRAY[165,42,42], true),

  ('Slate 50',     'slate-50',     '#F8FAFC', ARRAY[248,250,252], true),
  ('Slate 200',    'slate-200',    '#E2E8F0', ARRAY[226,232,240], true),
  ('Slate 500',    'slate-500',    '#64748B', ARRAY[100,116,139], true),
  ('Slate 900',    'slate-900',    '#0F172A', ARRAY[15,23,42], true),

  ('Sky 300',      'sky-300',      '#7DD3FC', ARRAY[125,211,252], true),
  ('Sky 500',      'sky-500',      '#0EA5E9', ARRAY[14,165,233], true),
  ('Indigo 500',   'indigo-500',   '#6366F1', ARRAY[99,102,241], true),
  ('Violet 600',   'violet-600',   '#7C3AED', ARRAY[124,58,237], true),

  ('Emerald 400',  'emerald-400',  '#34D399', ARRAY[52,211,153], true),
  ('Emerald 600',  'emerald-600',  '#059669', ARRAY[5,150,105], true),
  ('Teal 500',     'teal-500',     '#14B8A6', ARRAY[20,184,166], true),

  ('Amber 300',    'amber-300',    '#FCD34D', ARRAY[252,211,77], true),
  ('Amber 500',    'amber-500',    '#F59E0B', ARRAY[245,158,11], true),
  ('Rose 500',     'rose-500',     '#F43F5E', ARRAY[244,63,94], true),
  ('Rose 700',     'rose-700',     '#BE123C', ARRAY[190,18,60], true),

  ('Midnight',     'midnight',     '#0B1026', ARRAY[11,16,38], false),
  ('Steel',        'steel',        '#3A4A5E', ARRAY[58,74,94], false),
  ('Sand',         'sand',         '#D8C3A5', ARRAY[216,195,165], false),
  ('Forest',       'forest',       '#0B3D2E', ARRAY[11,61,46], false),
  ('Ocean',        'ocean',        '#005377', ARRAY[0,83,119], false),
  ('Lavender',     'lavender',     '#B8A1FF', ARRAY[184,161,255], false),
  ('Coral',        'coral',        '#FF6B6B', ARRAY[255,107,107], false)
ON CONFLICT (slug) DO UPDATE
SET
  name     = EXCLUDED.name,
  hex      = EXCLUDED.hex,
  rgb      = EXCLUDED.rgb,
  is_named = EXCLUDED.is_named;

COMMIT;

-- Example usage:
-- SELECT * FROM public.colors ORDER BY name;
-- SELECT * FROM public.colors WHERE hex = '#0EA5E9';