Colour sheet
Pick a colour on a phone.
Built with
Teams
Design team
The team colour marks Design on the leave calendar, the org chart and in reports.
Appearance
Team name
Design
Team colourBlue
colour-sheet.tsx
"use client";
import { useState } from "react";
import { LuChevronRight } from "react-icons/lu";
import {
BottomSheet,
Button,
ListItem,
Segment,
SegmentedControl,
Swatch,
SwatchPicker,
TopAppBar,
} from "@nexera-ui/react";
// Team colours are user data (they label calendars and charts), so they are plain values with names.
const PALETTES = {
bold: [
{ hex: "#04855D", name: "Emerald" },
{ hex: "#2563EB", name: "Blue" },
{ hex: "#D97706", name: "Amber" },
{ hex: "#7C3AED", name: "Violet" },
{ hex: "#0E7490", name: "Cyan" },
{ hex: "#DB2777", name: "Pink" },
{ hex: "#DC2626", name: "Red" },
{ hex: "#4B5563", name: "Slate" },
],
soft: [
{ hex: "#86EFAC", name: "Mint" },
{ hex: "#93C5FD", name: "Sky" },
{ hex: "#FCD34D", name: "Sand" },
{ hex: "#C4B5FD", name: "Lilac" },
{ hex: "#67E8F9", name: "Ice" },
{ hex: "#F9A8D4", name: "Rose" },
{ hex: "#FCA5A5", name: "Coral" },
{ hex: "#CBD5E1", name: "Fog" },
],
} as const;
type PaletteKey = keyof typeof PALETTES;
const ALL = [...PALETTES.bold, ...PALETTES.soft];
/** Colour sheet: pick a team colour on a phone from a bottom sheet with bold and soft palettes. */
export default function ColourSheet() {
const [hex, setHex] = useState<string>("#2563EB");
const [palette, setPalette] = useState<PaletteKey>("bold");
const current = ALL.find((entry) => entry.hex === hex) ?? PALETTES.bold[1];
return (
<div className="@container bg-page px-4 py-8">
<div className="mx-auto flex w-full max-w-sm flex-col overflow-hidden rounded-xl border border-default bg-page shadow-md">
<TopAppBar
title="Design team"
headingLevel={2}
platform="ios"
leadingLabel="Teams"
leadingHref="#teams"
/>
<div className="grid gap-4 px-4 pt-2 pb-6">
<p className="text-body-default text-secondary">
The team colour marks Design on the leave calendar, the org chart and in reports.
</p>
<section aria-labelledby="colour-sheet-appearance" className="grid gap-2">
<h3 id="colour-sheet-appearance" className="text-body-strong text-primary">
Appearance
</h3>
<div className="overflow-hidden rounded-lg border border-default bg-surface">
<ListItem title="Team name" subtitle="Design" />
<div className="flex items-center gap-3 border-t border-subtle px-4 py-3">
<Swatch color={hex} colorName={current.name} size="md" />
<div className="grid min-w-0 flex-1">
<span className="text-body-default text-primary">Team colour</span>
<span className="text-body-small text-secondary">{current.name}</span>
</div>
<BottomSheet
title="Team colour"
platform="ios"
trigger={
<Button platform="ios" variant="ghost" trailingIcon={<LuChevronRight />}>
Change
</Button>
}
footer={
<Button platform="ios" size="lg" slot="close" className="w-full">
Use {current.name}
</Button>
}
>
<div className="grid gap-5">
<SegmentedControl
aria-label="Palette"
selectedKeys={[palette]}
onSelectionChange={(keys) => {
setPalette(([...keys][0] as PaletteKey | undefined) ?? palette);
}}
>
<Segment id="bold" label="Bold" />
<Segment id="soft" label="Soft" />
</SegmentedControl>
<SwatchPicker
aria-label={`${palette === "bold" ? "Bold" : "Soft"} colours`}
value={hex}
onChange={(colour) => {
setHex(colour.toString("hex"));
}}
className="flex flex-wrap gap-3"
>
{PALETTES[palette].map((entry) => (
<Swatch
key={entry.hex}
color={entry.hex}
colorName={entry.name}
size="lg"
/>
))}
</SwatchPicker>
<p className="text-body-small text-secondary" aria-live="polite">
Selected: {current.name}
</p>
</div>
</BottomSheet>
</div>
</div>
</section>
</div>
</div>
</div>
);
}