@fiestaboard/ui 2.0.3 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/board/board-display.d.ts +66 -3
- package/dist/components/board/board-display.js +296 -246
- package/dist/components/board/board-display.js.map +1 -1
- package/dist/components/board/board-surfaces.d.ts +66 -0
- package/dist/components/board/board-surfaces.js +18 -0
- package/dist/components/board/board-surfaces.js.map +1 -0
- package/dist/components/board/board-teaser.js +59 -52
- package/dist/components/board/board-teaser.js.map +1 -1
- package/dist/components/board/reduced-motion.d.ts +2 -0
- package/dist/components/board/reduced-motion.js +16 -0
- package/dist/components/board/reduced-motion.js.map +1 -0
- package/dist/components/board/static-board-display.js +71 -64
- package/dist/components/board/static-board-display.js.map +1 -1
- package/dist/components/chrome/board-selector.js +2 -2
- package/dist/components/chrome/board-selector.js.map +1 -1
- package/dist/components/chrome/sidebar.js +2 -2
- package/dist/components/chrome/sidebar.js.map +1 -1
- package/dist/components/plugin/plugin-card.js +1 -1
- package/dist/components/plugin/plugin-card.js.map +1 -1
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/accordion.js.map +1 -1
- package/dist/components/ui/button.d.ts +12 -1
- package/dist/components/ui/button.js +59 -22
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/card.js +1 -1
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/scroll-area.js +1 -1
- package/dist/components/ui/scroll-area.js.map +1 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/skeleton.d.ts +12 -0
- package/dist/components/ui/skeleton.js +1 -1
- package/dist/components/ui/skeleton.js.map +1 -1
- package/dist/components/ui/spinner.d.ts +42 -0
- package/dist/components/ui/spinner.js +44 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/table.js +1 -1
- package/dist/components/ui/table.js.map +1 -1
- package/dist/components/ui/tabs.js +1 -1
- package/dist/components/ui/tabs.js.map +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +62 -61
- package/dist/lib/board-metrics.d.ts +116 -13
- package/dist/lib/board-metrics.js +97 -14
- package/dist/lib/board-metrics.js.map +1 -1
- package/dist/theme.css +101 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,64 +1,65 @@
|
|
|
1
1
|
import { cn as e } from "./lib/utils.js";
|
|
2
2
|
import { Accordion as t, AccordionContent as n, AccordionItem as r, AccordionTrigger as i } from "./components/ui/accordion.js";
|
|
3
3
|
import { Alert as a, AlertDescription as o, AlertTitle as s, alertVariants as c } from "./components/ui/alert.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import xe from "./components/ui/
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
|
|
4
|
+
import { Spinner as l, spinnerVariants as u } from "./components/ui/spinner.js";
|
|
5
|
+
import { Button as d, buttonVariants as f } from "./components/ui/button.js";
|
|
6
|
+
import { AlertDialog as p, AlertDialogAction as m, AlertDialogCancel as h, AlertDialogContent as g, AlertDialogDescription as _, AlertDialogFooter as v, AlertDialogHeader as y, AlertDialogOverlay as b, AlertDialogPortal as x, AlertDialogTitle as S, AlertDialogTrigger as C } from "./components/ui/alert-dialog.js";
|
|
7
|
+
import { Aurora as w } from "./components/ui/aurora.js";
|
|
8
|
+
import { Badge as T, badgeVariants as E } from "./components/ui/badge.js";
|
|
9
|
+
import { Box as D } from "./components/ui/box.js";
|
|
10
|
+
import { Card as O, CardAction as k, CardContent as A, CardDescription as j, CardFooter as M, CardHeader as N, CardTitle as P } from "./components/ui/card.js";
|
|
11
|
+
import { Checkbox as F } from "./components/ui/checkbox.js";
|
|
12
|
+
import { Code as I } from "./components/ui/code.js";
|
|
13
|
+
import { Collapsible as L, CollapsibleContent as R, CollapsibleTrigger as z } from "./components/ui/collapsible.js";
|
|
14
|
+
import { Dialog as B, DialogClose as V, DialogContent as H, DialogDescription as U, DialogFooter as W, DialogHeader as G, DialogOverlay as K, DialogPortal as q, DialogTitle as J, DialogTrigger as Y } from "./components/ui/dialog.js";
|
|
15
|
+
import { DropdownMenu as X, DropdownMenuCheckboxItem as Z, DropdownMenuContent as Q, DropdownMenuGroup as $, DropdownMenuItem as ee, DropdownMenuLabel as te, DropdownMenuPortal as ne, DropdownMenuRadioGroup as re, DropdownMenuRadioItem as ie, DropdownMenuSeparator as ae, DropdownMenuShortcut as oe, DropdownMenuSub as se, DropdownMenuSubContent as ce, DropdownMenuSubTrigger as le, DropdownMenuTrigger as ue } from "./components/ui/dropdown-menu.js";
|
|
16
|
+
import { EmptyState as de } from "./components/ui/empty-state.js";
|
|
17
|
+
import { Flex as fe, flexVariants as pe } from "./components/ui/flex.js";
|
|
18
|
+
import { Grid as me, gridVariants as he } from "./components/ui/grid.js";
|
|
19
|
+
import { Heading as ge, headingVariants as _e } from "./components/ui/heading.js";
|
|
20
|
+
import { Input as ve } from "./components/ui/input.js";
|
|
21
|
+
import { Label as ye } from "./components/ui/label.js";
|
|
22
|
+
import { List as be, ListItem as xe, listVariants as Se } from "./components/ui/list.js";
|
|
23
|
+
import Ce from "./components/ui/react-bits/decrypted-text.js";
|
|
24
|
+
import we from "./components/ui/react-bits/fade-content.js";
|
|
25
|
+
import { ScrollArea as Te, ScrollBar as Ee } from "./components/ui/scroll-area.js";
|
|
26
|
+
import { Select as De, SelectContent as Oe, SelectGroup as ke, SelectItem as Ae, SelectLabel as je, SelectScrollDownButton as Me, SelectScrollUpButton as Ne, SelectSeparator as Pe, SelectTrigger as Fe, SelectValue as Ie } from "./components/ui/select.js";
|
|
27
|
+
import { Sheet as Le, SheetClose as Re, SheetContent as ze, SheetDescription as Be, SheetFooter as Ve, SheetHeader as He, SheetOverlay as Ue, SheetPortal as We, SheetTitle as Ge, SheetTrigger as Ke } from "./components/ui/sheet.js";
|
|
28
|
+
import { Skeleton as qe } from "./components/ui/skeleton.js";
|
|
29
|
+
import { Slider as Je } from "./components/ui/slider.js";
|
|
30
|
+
import { Stack as Ye, stackVariants as Xe } from "./components/ui/stack.js";
|
|
31
|
+
import { Switch as Ze } from "./components/ui/switch.js";
|
|
32
|
+
import { Table as Qe, TableBody as $e, TableCell as et, TableHead as tt, TableHeader as nt, TableRow as rt } from "./components/ui/table.js";
|
|
33
|
+
import { Tabs as it, TabsContent as at, TabsList as ot, TabsTrigger as st } from "./components/ui/tabs.js";
|
|
34
|
+
import { Text as ct, textVariants as lt } from "./components/ui/text.js";
|
|
35
|
+
import { TextLink as ut } from "./components/ui/text-link.js";
|
|
36
|
+
import { Textarea as dt } from "./components/ui/textarea.js";
|
|
37
|
+
import { Tooltip as ft, TooltipContent as pt, TooltipProvider as mt, TooltipTrigger as ht } from "./components/ui/tooltip.js";
|
|
38
|
+
import { BoardIcon as gt } from "./components/chrome/board-icon.js";
|
|
39
|
+
import { BoardSelector as _t } from "./components/chrome/board-selector.js";
|
|
40
|
+
import { FIESTA_ICON_DATA_URI as vt, FIESTA_ICON_PALETTE as yt, FIESTA_ICON_SVG as bt, FiestaIcon as xt } from "./components/chrome/fiesta-icon.js";
|
|
41
|
+
import { FiestaLogo as St } from "./components/chrome/fiesta-logo.js";
|
|
42
|
+
import { LanguageSelector as Ct } from "./components/chrome/language-selector.js";
|
|
43
|
+
import { MainContent as wt } from "./components/chrome/main-content.js";
|
|
44
|
+
import { PageHeader as Tt, PageIconGradientDefs as Et } from "./components/chrome/page-header.js";
|
|
45
|
+
import { PageLayout as Dt } from "./components/chrome/page-layout.js";
|
|
46
|
+
import { PageToolbar as Ot } from "./components/chrome/page-toolbar.js";
|
|
47
|
+
import { SidebarAurora as kt } from "./components/seasons/sidebar-aurora.js";
|
|
48
|
+
import { SidebarAuroraHorizontal as At } from "./components/seasons/sidebar-aurora-horizontal.js";
|
|
49
|
+
import { Sidebar as jt } from "./components/chrome/sidebar.js";
|
|
50
|
+
import { SkipToContent as Mt } from "./components/chrome/skip-to-content.js";
|
|
51
|
+
import { ThemeToggle as Nt } from "./components/chrome/theme-toggle.js";
|
|
52
|
+
import { HIDE_FESTIVE_COOKIE as Pt, PRIDE_SEASON as Ft, SEASONS as It, fireSeasonBurst as Lt, getActiveSeason as Rt, readCookieString as zt, shouldShowPride as Bt, useActiveSeason as Vt, usePrideActive as Ht } from "./lib/seasons.js";
|
|
53
|
+
import { ALL_COLOR_CODES as Ut, AVAILABLE_COLORS as Wt, BOARD_COLORS as Gt, COLOR_CODE_MAP as Kt, COLOR_DISPLAY as qt, getBoardColor as Jt, isValidBoardColor as Yt, resolveColorCode as Xt } from "./lib/board-colors.js";
|
|
54
|
+
import { BOARD_CHARS as Zt, EXTRA_CHARS as Qt, getCharFromToken as $t, getCharIndex as en, isColorTile as tn, messageToGrid as nn, parseLine as rn, tokensEqual as an } from "./lib/board-characters.js";
|
|
55
|
+
import { DEVICE_DIMENSIONS as on, MAX_NOTES_PER_AXIS as sn, NOTE_COLS as cn, NOTE_ROWS as ln, isNoteArray as un, noteArrayDimensions as dn, resolveDimensions as fn } from "./lib/board-dimensions.js";
|
|
56
|
+
import { BoardDisplay as pn, FLAP_SPEED_PRESETS as mn, deriveFlapTiming as hn, resolveFlapSpeed as gn } from "./components/board/board-display.js";
|
|
57
|
+
import { BoardTeaser as _n } from "./components/board/board-teaser.js";
|
|
58
|
+
import { ScaledBoardDisplay as vn } from "./components/board/scaled-board-display.js";
|
|
59
|
+
import { StaticBoardDisplay as yn } from "./components/board/static-board-display.js";
|
|
60
|
+
import { DEFAULT_SHAPE_LABELS as bn, previewLabel as xn, previewLabels as Sn, previewMessage as Cn } from "./lib/board-previews.js";
|
|
61
|
+
import { BoardShowcase as wn, DEFAULT_SHOWCASE_LABELS as Tn } from "./components/plugin/board-showcase.js";
|
|
62
|
+
import { PLUGIN_CATEGORIES as En, PluginCategoryBadge as Dn } from "./components/plugin/plugin-category-badge.js";
|
|
63
|
+
import { ScaledBoardTeaser as On } from "./components/plugin/scaled-board-teaser.js";
|
|
64
|
+
import { PluginCard as kn } from "./components/plugin/plugin-card.js";
|
|
65
|
+
export { Ut as ALL_COLOR_CODES, Wt as AVAILABLE_COLORS, t as Accordion, n as AccordionContent, r as AccordionItem, i as AccordionTrigger, a as Alert, o as AlertDescription, p as AlertDialog, m as AlertDialogAction, h as AlertDialogCancel, g as AlertDialogContent, _ as AlertDialogDescription, v as AlertDialogFooter, y as AlertDialogHeader, b as AlertDialogOverlay, x as AlertDialogPortal, S as AlertDialogTitle, C as AlertDialogTrigger, s as AlertTitle, w as Aurora, Zt as BOARD_CHARS, Gt as BOARD_COLORS, T as Badge, pn as BoardDisplay, gt as BoardIcon, _t as BoardSelector, wn as BoardShowcase, _n as BoardTeaser, D as Box, d as Button, Kt as COLOR_CODE_MAP, qt as COLOR_DISPLAY, O as Card, k as CardAction, A as CardContent, j as CardDescription, M as CardFooter, N as CardHeader, P as CardTitle, F as Checkbox, I as Code, L as Collapsible, R as CollapsibleContent, z as CollapsibleTrigger, bn as DEFAULT_SHAPE_LABELS, Tn as DEFAULT_SHOWCASE_LABELS, on as DEVICE_DIMENSIONS, Ce as DecryptedText, B as Dialog, V as DialogClose, H as DialogContent, U as DialogDescription, W as DialogFooter, G as DialogHeader, K as DialogOverlay, q as DialogPortal, J as DialogTitle, Y as DialogTrigger, X as DropdownMenu, Z as DropdownMenuCheckboxItem, Q as DropdownMenuContent, $ as DropdownMenuGroup, ee as DropdownMenuItem, te as DropdownMenuLabel, ne as DropdownMenuPortal, re as DropdownMenuRadioGroup, ie as DropdownMenuRadioItem, ae as DropdownMenuSeparator, oe as DropdownMenuShortcut, se as DropdownMenuSub, ce as DropdownMenuSubContent, le as DropdownMenuSubTrigger, ue as DropdownMenuTrigger, Qt as EXTRA_CHARS, de as EmptyState, vt as FIESTA_ICON_DATA_URI, yt as FIESTA_ICON_PALETTE, bt as FIESTA_ICON_SVG, mn as FLAP_SPEED_PRESETS, we as FadeContent, xt as FiestaIcon, St as FiestaLogo, fe as Flex, me as Grid, Pt as HIDE_FESTIVE_COOKIE, ge as Heading, ve as Input, ye as Label, Ct as LanguageSelector, be as List, xe as ListItem, sn as MAX_NOTES_PER_AXIS, wt as MainContent, cn as NOTE_COLS, ln as NOTE_ROWS, En as PLUGIN_CATEGORIES, Ft as PRIDE_SEASON, Tt as PageHeader, Et as PageIconGradientDefs, Dt as PageLayout, Ot as PageToolbar, kn as PluginCard, Dn as PluginCategoryBadge, It as SEASONS, vn as ScaledBoardDisplay, On as ScaledBoardTeaser, Te as ScrollArea, Ee as ScrollBar, De as Select, Oe as SelectContent, ke as SelectGroup, Ae as SelectItem, je as SelectLabel, Me as SelectScrollDownButton, Ne as SelectScrollUpButton, Pe as SelectSeparator, Fe as SelectTrigger, Ie as SelectValue, Le as Sheet, Re as SheetClose, ze as SheetContent, Be as SheetDescription, Ve as SheetFooter, He as SheetHeader, Ue as SheetOverlay, We as SheetPortal, Ge as SheetTitle, Ke as SheetTrigger, jt as Sidebar, kt as SidebarAurora, At as SidebarAuroraHorizontal, qe as Skeleton, Mt as SkipToContent, Je as Slider, l as Spinner, Ye as Stack, yn as StaticBoardDisplay, Ze as Switch, Qe as Table, $e as TableBody, et as TableCell, tt as TableHead, nt as TableHeader, rt as TableRow, it as Tabs, at as TabsContent, ot as TabsList, st as TabsTrigger, ct as Text, ut as TextLink, dt as Textarea, Nt as ThemeToggle, ft as Tooltip, pt as TooltipContent, mt as TooltipProvider, ht as TooltipTrigger, c as alertVariants, E as badgeVariants, f as buttonVariants, e as cn, hn as deriveFlapTiming, Lt as fireSeasonBurst, pe as flexVariants, Rt as getActiveSeason, Jt as getBoardColor, $t as getCharFromToken, en as getCharIndex, he as gridVariants, _e as headingVariants, tn as isColorTile, un as isNoteArray, Yt as isValidBoardColor, Se as listVariants, nn as messageToGrid, dn as noteArrayDimensions, rn as parseLine, xn as previewLabel, Sn as previewLabels, Cn as previewMessage, zt as readCookieString, Xt as resolveColorCode, fn as resolveDimensions, gn as resolveFlapSpeed, Bt as shouldShowPride, u as spinnerVariants, Xe as stackVariants, lt as textVariants, an as tokensEqual, Vt as useActiveSeason, Ht as usePrideActive };
|
|
@@ -1,19 +1,122 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
2
|
+
* Board tile geometry — one free variable, everything else derived from it.
|
|
3
|
+
*
|
|
4
|
+
* A split-flap module is a physical object, so its proportions have to be
|
|
5
|
+
* invariant: the same tile rendered at any scale keeps one aspect ratio, one
|
|
6
|
+
* gutter-to-tile ratio, one glyph-to-tile ratio, and a corner radius that
|
|
7
|
+
* scales with it. Before issue #176 this file kept four independent class maps
|
|
8
|
+
* and they had drifted apart (aspect spread 12.3%, gutter/tile 53.1%,
|
|
9
|
+
* glyph/tile 24.2%, corner radius a flat 3px from a 18px tile to a 46px one —
|
|
10
|
+
* and `gapClasses.md` had silently lost its `lg:` step, so at ≥1024px an
|
|
11
|
+
* `md` board grew its tiles and kept its gutter).
|
|
12
|
+
*
|
|
13
|
+
* Now there is exactly one free variable per size/breakpoint — the tile
|
|
14
|
+
* **height** — and every other dimension comes out of {@link TILE_RATIOS}:
|
|
15
|
+
*
|
|
16
|
+
* width = round(h × 0.70) aspect, matching the md/lg cluster
|
|
17
|
+
* gutter = round(h × 0.145) ≈ 0.207 of width, the old md/lg centre
|
|
18
|
+
* glyph = round(h × 0.39) font-size
|
|
19
|
+
* radius = h × 0.075 corner radius (see note below)
|
|
20
|
+
*
|
|
21
|
+
* Resulting ratios across all 12 size × breakpoint steps:
|
|
22
|
+
*
|
|
23
|
+
* aspect 0.692 … 0.722 spread 4.3% (was 12.3%)
|
|
24
|
+
* gutter/tile 0.200 … 0.231 spread 15.4% (was 53.1%)
|
|
25
|
+
* glyph/tile 0.382 … 0.400 spread 4.6% (was 24.2%)
|
|
26
|
+
* radius/tile 0.075 spread 0.0% (was 155.6%)
|
|
27
|
+
*
|
|
28
|
+
* The residual spread is entirely integer-pixel quantisation: no dimension is
|
|
29
|
+
* more than 0.5px from its ideal value, and the relative error looks large
|
|
30
|
+
* only because a 3px gutter cannot be expressed more precisely than ±0.5px.
|
|
31
|
+
* That is a rendering limit, not drift — there is no per-size fudge factor
|
|
32
|
+
* left in this file. Corner radius is the one exception to integer rounding:
|
|
33
|
+
* it is paint-only (never affects layout) and antialiases cleanly, so it is
|
|
34
|
+
* kept fractional and the ratio is exactly invariant.
|
|
35
|
+
*
|
|
36
|
+
* Steps are declared for every breakpoint, and a breakpoint that intentionally
|
|
37
|
+
* inherits the previous step must say so with an explicit `null`. That makes
|
|
38
|
+
* the "gapClasses.md forgot its lg: step" bug a type error rather than
|
|
39
|
+
* something you have to notice by eye.
|
|
40
|
+
*
|
|
41
|
+
* These maps are a single shared source for BoardDisplay, StaticBoardDisplay,
|
|
42
|
+
* and BoardTeaser so a teaser strip and a static preview match a full animated
|
|
43
|
+
* board row rendered at the same size. They live at module scope (built once at
|
|
44
|
+
* import) rather than inside a component body, because during loading each of
|
|
45
|
+
* the ~132 tiles of a flagship board re-renders every flap step and
|
|
46
|
+
* re-allocating these per render churned continuously across the grid
|
|
47
|
+
* (PR #31 / issue #24; consolidated here in issue #68).
|
|
14
48
|
*/
|
|
15
49
|
export type BoardSize = "sm" | "md" | "lg";
|
|
50
|
+
/** Tailwind's responsive steps, in cascade order. `base` is the unprefixed one. */
|
|
51
|
+
export declare const BOARD_STEPS: readonly ["base", "sm", "md", "lg"];
|
|
52
|
+
export type BoardStep = (typeof BOARD_STEPS)[number];
|
|
53
|
+
/** Fixed tile proportions, all expressed against the tile height. */
|
|
54
|
+
export declare const TILE_RATIOS: {
|
|
55
|
+
/** Tile width ÷ tile height. */
|
|
56
|
+
readonly width: 0.7;
|
|
57
|
+
/** Gutter between tiles ÷ tile height (≈ 0.207 of the tile width). */
|
|
58
|
+
readonly gutter: 0.145;
|
|
59
|
+
/** Glyph font-size ÷ tile height. */
|
|
60
|
+
readonly glyph: 0.39;
|
|
61
|
+
/** Corner radius ÷ tile height. */
|
|
62
|
+
readonly radius: 0.075;
|
|
63
|
+
};
|
|
64
|
+
export interface TileMetrics {
|
|
65
|
+
height: number;
|
|
66
|
+
width: number;
|
|
67
|
+
gutter: number;
|
|
68
|
+
glyph: number;
|
|
69
|
+
radius: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The whole tile scale, derived from a single tile height.
|
|
73
|
+
*
|
|
74
|
+
* Layout dimensions are rounded to whole pixels (fractional tile widths make
|
|
75
|
+
* the grid seams blurry and the glyph centring uneven); the corner radius is
|
|
76
|
+
* paint-only and is kept fractional so the ratio stays exact.
|
|
77
|
+
*/
|
|
78
|
+
export declare function deriveTileMetrics(height: number): TileMetrics;
|
|
79
|
+
/** Tile width + height. */
|
|
16
80
|
export declare const sizeClasses: Record<BoardSize, string>;
|
|
81
|
+
/** Glyph font-size. */
|
|
17
82
|
export declare const textSizeClasses: Record<BoardSize, string>;
|
|
18
|
-
|
|
83
|
+
/** Gutter between tiles (also the row gap — the grid is square-pitched). */
|
|
19
84
|
export declare const gapClasses: Record<BoardSize, string>;
|
|
85
|
+
/** Tile (and leaf) corner radius. Scales with the tile — see issue #176. */
|
|
86
|
+
export declare const radiusClasses: Record<BoardSize, string>;
|
|
87
|
+
/**
|
|
88
|
+
* Bezel padding around the grid.
|
|
89
|
+
*
|
|
90
|
+
* Deliberately *not* derived from the tile height: this is the frame the tiles
|
|
91
|
+
* sit in, not a property of a tile, and the physical bezel does not scale with
|
|
92
|
+
* the module. It is authored per step and left at the values the boards have
|
|
93
|
+
* always shipped with, so deriving the tile scale does not resize every board.
|
|
94
|
+
* It is declared here alongside the tile maps only so all board metrics stay in
|
|
95
|
+
* one file.
|
|
96
|
+
*/
|
|
97
|
+
export declare const paddingClasses: Record<BoardSize, string>;
|
|
98
|
+
export interface TileScaleRow extends TileMetrics {
|
|
99
|
+
size: BoardSize;
|
|
100
|
+
step: BoardStep;
|
|
101
|
+
/** Ratios as rendered, i.e. after integer-pixel rounding. */
|
|
102
|
+
aspect: number;
|
|
103
|
+
gutterRatio: number;
|
|
104
|
+
glyphRatio: number;
|
|
105
|
+
radiusRatio: number;
|
|
106
|
+
}
|
|
107
|
+
/** Every authored step, with the ratios it actually renders at. */
|
|
108
|
+
export declare function tileScaleRows(): TileScaleRow[];
|
|
109
|
+
export interface TileScaleIssue {
|
|
110
|
+
size: BoardSize;
|
|
111
|
+
step: BoardStep;
|
|
112
|
+
field: "size" | "gap" | "text" | "radius";
|
|
113
|
+
expected: string;
|
|
114
|
+
actual: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Re-derive every authored class string from its tile height and report any
|
|
118
|
+
* that no longer matches. The class strings have to be literals for Tailwind's
|
|
119
|
+
* scanner (see {@link TileStep}), so this is what keeps them honest; the
|
|
120
|
+
* "Tile geometry" story calls it.
|
|
121
|
+
*/
|
|
122
|
+
export declare function verifyTileScale(): TileScaleIssue[];
|
|
@@ -1,22 +1,105 @@
|
|
|
1
1
|
//#region src/lib/board-metrics.ts
|
|
2
|
-
var e =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
var e = [
|
|
3
|
+
"base",
|
|
4
|
+
"sm",
|
|
5
|
+
"md",
|
|
6
|
+
"lg"
|
|
7
|
+
], t = {
|
|
8
|
+
sm: {
|
|
9
|
+
base: {
|
|
10
|
+
h: 18,
|
|
11
|
+
size: "w-[13px] h-[18px]",
|
|
12
|
+
gap: "gap-[3px]",
|
|
13
|
+
text: "text-[7px]",
|
|
14
|
+
radius: "rounded-[1.35px]"
|
|
15
|
+
},
|
|
16
|
+
sm: null,
|
|
17
|
+
md: null,
|
|
18
|
+
lg: null
|
|
19
|
+
},
|
|
20
|
+
md: {
|
|
21
|
+
base: {
|
|
22
|
+
h: 20,
|
|
23
|
+
size: "w-[14px] h-[20px]",
|
|
24
|
+
gap: "gap-[3px]",
|
|
25
|
+
text: "text-[8px]",
|
|
26
|
+
radius: "rounded-[1.5px]"
|
|
27
|
+
},
|
|
28
|
+
sm: {
|
|
29
|
+
h: 28,
|
|
30
|
+
size: "sm:w-[20px] sm:h-[28px]",
|
|
31
|
+
gap: "sm:gap-[4px]",
|
|
32
|
+
text: "sm:text-[11px]",
|
|
33
|
+
radius: "sm:rounded-[2.1px]"
|
|
34
|
+
},
|
|
35
|
+
md: {
|
|
36
|
+
h: 34,
|
|
37
|
+
size: "md:w-[24px] md:h-[34px]",
|
|
38
|
+
gap: "md:gap-[5px]",
|
|
39
|
+
text: "md:text-[13px]",
|
|
40
|
+
radius: "md:rounded-[2.55px]"
|
|
41
|
+
},
|
|
42
|
+
lg: {
|
|
43
|
+
h: 40,
|
|
44
|
+
size: "lg:w-[28px] lg:h-[40px]",
|
|
45
|
+
gap: "lg:gap-[6px]",
|
|
46
|
+
text: "lg:text-[16px]",
|
|
47
|
+
radius: "lg:rounded-[3px]"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
lg: {
|
|
51
|
+
base: {
|
|
52
|
+
h: 26,
|
|
53
|
+
size: "w-[18px] h-[26px]",
|
|
54
|
+
gap: "gap-[4px]",
|
|
55
|
+
text: "text-[10px]",
|
|
56
|
+
radius: "rounded-[1.95px]"
|
|
57
|
+
},
|
|
58
|
+
sm: {
|
|
59
|
+
h: 34,
|
|
60
|
+
size: "sm:w-[24px] sm:h-[34px]",
|
|
61
|
+
gap: "sm:gap-[5px]",
|
|
62
|
+
text: "sm:text-[13px]",
|
|
63
|
+
radius: "sm:rounded-[2.55px]"
|
|
64
|
+
},
|
|
65
|
+
md: {
|
|
66
|
+
h: 40,
|
|
67
|
+
size: "md:w-[28px] md:h-[40px]",
|
|
68
|
+
gap: "md:gap-[6px]",
|
|
69
|
+
text: "md:text-[16px]",
|
|
70
|
+
radius: "md:rounded-[3px]"
|
|
71
|
+
},
|
|
72
|
+
lg: {
|
|
73
|
+
h: 46,
|
|
74
|
+
size: "lg:w-[32px] lg:h-[46px]",
|
|
75
|
+
gap: "lg:gap-[7px]",
|
|
76
|
+
text: "lg:text-[18px]",
|
|
77
|
+
radius: "lg:rounded-[3.45px]"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, n = [
|
|
81
|
+
"sm",
|
|
82
|
+
"md",
|
|
83
|
+
"lg"
|
|
84
|
+
];
|
|
85
|
+
function r(r) {
|
|
86
|
+
let i = {};
|
|
87
|
+
for (let a of n) {
|
|
88
|
+
let n = [];
|
|
89
|
+
for (let i of e) {
|
|
90
|
+
let e = t[a][i];
|
|
91
|
+
e && n.push(r(e));
|
|
92
|
+
}
|
|
93
|
+
i[a] = n.join(" ");
|
|
94
|
+
}
|
|
95
|
+
return i;
|
|
96
|
+
}
|
|
97
|
+
var i = r((e) => e.size), a = r((e) => e.text), o = r((e) => e.gap), s = r((e) => e.radius), c = {
|
|
11
98
|
sm: "px-3 py-4",
|
|
12
99
|
md: "px-2 py-3 sm:px-4 sm:py-6 md:px-5 md:py-8 lg:px-6 lg:py-10",
|
|
13
100
|
lg: "px-3 py-4 sm:px-5 sm:py-7 md:px-6 md:py-9 lg:px-8 lg:py-12"
|
|
14
|
-
}, r = {
|
|
15
|
-
sm: "gap-[3px]",
|
|
16
|
-
md: "gap-[2px] sm:gap-[4px] md:gap-[5px]",
|
|
17
|
-
lg: "gap-[3px] sm:gap-[5px] md:gap-[6px] lg:gap-[7px]"
|
|
18
101
|
};
|
|
19
102
|
//#endregion
|
|
20
|
-
export {
|
|
103
|
+
export { e as BOARD_STEPS, o as gapClasses, c as paddingClasses, s as radiusClasses, i as sizeClasses, a as textSizeClasses };
|
|
21
104
|
|
|
22
105
|
//# sourceMappingURL=board-metrics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-metrics.js","names":[],"sources":["../../src/lib/board-metrics.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"board-metrics.js","names":[],"sources":["../../src/lib/board-metrics.ts"],"mappings":";AAoDA,IAAa,IAAc;CAAC;CAAQ;CAAM;CAAM;AAAI,GAgE9C,IAAoE;CAExE,IAAI;EACF,MAAM;GAAE,GAAG;GAAI,MAAM;GAAqB,KAAK;GAAa,MAAM;GAAc,QAAQ;EAAmB;EAC3G,IAAI;EACJ,IAAI;EACJ,IAAI;CACN;CACA,IAAI;EACF,MAAM;GAAE,GAAG;GAAI,MAAM;GAAqB,KAAK;GAAa,MAAM;GAAc,QAAQ;EAAkB;EAC1G,IAAI;GACF,GAAG;GACH,MAAM;GACN,KAAK;GACL,MAAM;GACN,QAAQ;EACV;EACA,IAAI;GACF,GAAG;GACH,MAAM;GACN,KAAK;GACL,MAAM;GACN,QAAQ;EACV;EACA,IAAI;GACF,GAAG;GACH,MAAM;GACN,KAAK;GACL,MAAM;GACN,QAAQ;EACV;CACF;CACA,IAAI;EACF,MAAM;GAAE,GAAG;GAAI,MAAM;GAAqB,KAAK;GAAa,MAAM;GAAe,QAAQ;EAAmB;EAC5G,IAAI;GACF,GAAG;GACH,MAAM;GACN,KAAK;GACL,MAAM;GACN,QAAQ;EACV;EACA,IAAI;GACF,GAAG;GACH,MAAM;GACN,KAAK;GACL,MAAM;GACN,QAAQ;EACV;EACA,IAAI;GACF,GAAG;GACH,MAAM;GACN,KAAK;GACL,MAAM;GACN,QAAQ;EACV;CACF;AACF,GAEM,IAAoC;CAAC;CAAM;CAAM;AAAI;AAE3D,SAAS,EAAU,GAA6D;CAC9E,IAAM,IAAM,CAAC;CACb,KAAK,IAAM,KAAQ,GAAa;EAC9B,IAAM,IAAkB,CAAC;EACzB,KAAK,IAAM,KAAQ,GAAa;GAC9B,IAAM,IAAQ,EAAW,EAAK,CAAC;GAC/B,AAAI,KAAO,EAAM,KAAK,EAAK,CAAK,CAAC;EACnC;EACA,EAAI,KAAQ,EAAM,KAAK,GAAG;CAC5B;CACA,OAAO;AACT;AAGA,IAAa,IAAyC,GAAW,MAAS,EAAK,IAAI,GAGtE,IAA6C,GAAW,MAAS,EAAK,IAAI,GAG1E,IAAwC,GAAW,MAAS,EAAK,GAAG,GAGpE,IAA2C,GAAW,MAAS,EAAK,MAAM,GAY1E,IAA4C;CACvD,IAAI;CACJ,IAAI;CACJ,IAAI;AACN"}
|
package/dist/theme.css
CHANGED
|
@@ -151,6 +151,42 @@
|
|
|
151
151
|
--shadow-card: var(--elevation-card);
|
|
152
152
|
--shadow-card-hover: var(--elevation-card-hover);
|
|
153
153
|
--shadow-modal: var(--elevation-modal);
|
|
154
|
+
|
|
155
|
+
/* ============================================================
|
|
156
|
+
* Motion scale → Tailwind utilities (issue #182).
|
|
157
|
+
*
|
|
158
|
+
* The `duration-*` utility resolves through the `--transition-duration-*`
|
|
159
|
+
* namespace and `ease-*` through `--ease-*` (Tailwind v4). Exporting the
|
|
160
|
+
* motion tokens here is what makes `duration-base` in a component and
|
|
161
|
+
* `var(--motion-duration-base)` in this file the SAME number — retuning a
|
|
162
|
+
* token in :root now moves the component layer with it, instead of the two
|
|
163
|
+
* silently drifting apart (which raw `duration-200` allowed).
|
|
164
|
+
*
|
|
165
|
+
* Declared inside `@theme inline`, so a utility emits
|
|
166
|
+
* `transition-duration: var(--motion-duration-base)` rather than a baked
|
|
167
|
+
* copy of `200ms` — the indirection is what carries a retune through.
|
|
168
|
+
*
|
|
169
|
+
* Bare numeric durations (`duration-200`) still compile; they are banned in
|
|
170
|
+
* src/components by scripts/ci/tests/no-bare-duration-utility.test.mjs.
|
|
171
|
+
*
|
|
172
|
+
* Not exported on purpose:
|
|
173
|
+
* --motion-ease-out (`ease-out`) — Tailwind already ships `--ease-out`
|
|
174
|
+
* with a DIFFERENT curve (cubic-bezier(0, 0, 0.2, 1)). Overriding it
|
|
175
|
+
* would silently retime every existing `ease-out` utility, so the
|
|
176
|
+
* keyword stays a CSS-only token.
|
|
177
|
+
* --motion-ease-in — identical to Tailwind's stock `--ease-in`
|
|
178
|
+
* (cubic-bezier(0.4, 0, 1, 1)), so `ease-in` is already on-scale.
|
|
179
|
+
* ============================================================ */
|
|
180
|
+
--transition-duration-fast: var(--motion-duration-fast);
|
|
181
|
+
--transition-duration-control: var(--motion-duration-control);
|
|
182
|
+
--transition-duration-base: var(--motion-duration-base);
|
|
183
|
+
--transition-duration-exit: var(--motion-duration-exit);
|
|
184
|
+
--transition-duration-slow: var(--motion-duration-slow);
|
|
185
|
+
--transition-duration-slower: var(--motion-duration-slower);
|
|
186
|
+
--transition-duration-slowest: var(--motion-duration-slowest);
|
|
187
|
+
--ease-spring: var(--motion-ease-spring);
|
|
188
|
+
--ease-out-cubic: var(--motion-ease-out-cubic);
|
|
189
|
+
--ease-standard: var(--motion-ease-standard);
|
|
154
190
|
}
|
|
155
191
|
|
|
156
192
|
:root {
|
|
@@ -313,6 +349,10 @@
|
|
|
313
349
|
* Deliberately left inline (true one-offs): 117s sidebar gradient
|
|
314
350
|
* flow, 220ms board-switch exits, 0.8s pride-burst, 1s card-fade-in,
|
|
315
351
|
* 50ms page-toolbar stagger delay.
|
|
352
|
+
*
|
|
353
|
+
* The component layer reaches these through Tailwind utilities
|
|
354
|
+
* (`duration-base`, `ease-spring`, …), not raw `duration-200` — see the
|
|
355
|
+
* motion export block in `@theme inline` at the top of this file.
|
|
316
356
|
* ============================================================ */
|
|
317
357
|
--motion-duration-fast: 100ms;
|
|
318
358
|
--motion-duration-control: 150ms;
|
|
@@ -1300,3 +1340,64 @@ html[data-board-switch="backward"]::view-transition-new(board-page) {
|
|
|
1300
1340
|
transition: none !important;
|
|
1301
1341
|
}
|
|
1302
1342
|
}
|
|
1343
|
+
|
|
1344
|
+
/* ============================================================
|
|
1345
|
+
* Reduced-motion backstop (issue #180)
|
|
1346
|
+
*
|
|
1347
|
+
* The blocks above gate the animations this file OWNS. Three sources of
|
|
1348
|
+
* motion are structurally out of their reach, and all three shipped
|
|
1349
|
+
* running under `prefers-reduced-motion: reduce`:
|
|
1350
|
+
*
|
|
1351
|
+
* 1. Tailwind utilities — `animate-pulse` (Skeleton) and `animate-spin`
|
|
1352
|
+
* carry no motion gate, and both are INFINITE, which also engages
|
|
1353
|
+
* WCAG 2.2.2 (Pause, Stop, Hide).
|
|
1354
|
+
* 2. tw-animate-css — its `enter`/`exit` keyframes (Dialog, AlertDialog,
|
|
1355
|
+
* Select, Tooltip …) contain no `prefers-reduced-motion` rule at all.
|
|
1356
|
+
* 3. Inline `style` animations — `sheet.tsx` sets `animation` as an
|
|
1357
|
+
* element style, which no ordinary CSS rule can reach. `!important`
|
|
1358
|
+
* can: it outranks the style attribute.
|
|
1359
|
+
*
|
|
1360
|
+
* Hence the universal rule. 1ms rather than 0s on purpose: a zero-length
|
|
1361
|
+
* animation/transition is skipped entirely by some engines, which would
|
|
1362
|
+
* silently drop the `animationend`/`transitionend` that Base UI waits on
|
|
1363
|
+
* before unmounting an exiting popup. 1ms still fires the event on the
|
|
1364
|
+
* next frame, so anything gated on completion still completes; anything
|
|
1365
|
+
* animating in from `opacity: 0` still lands at `opacity: 1`.
|
|
1366
|
+
*
|
|
1367
|
+
* This is a BACKSTOP, not the whole answer. Where a frozen frame is worse
|
|
1368
|
+
* than a bespoke pose, the component states it itself and wins by being
|
|
1369
|
+
* more specific — Skeleton uses `motion-reduce:animate-none` for a static
|
|
1370
|
+
* `bg-accent` placeholder rather than an arbitrary mid-pulse frame, and
|
|
1371
|
+
* Spinner swaps its rotating arc for a static complete ring.
|
|
1372
|
+
* ============================================================ */
|
|
1373
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1374
|
+
*,
|
|
1375
|
+
*::before,
|
|
1376
|
+
*::after {
|
|
1377
|
+
animation-duration: 1ms !important;
|
|
1378
|
+
animation-iteration-count: 1 !important;
|
|
1379
|
+
transition-duration: 1ms !important;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
/* Exemption: these two must read back EXACTLY 0s.
|
|
1383
|
+
`main-content.tsx` gates its FLIP slide on
|
|
1384
|
+
`parseFloat(getComputedStyle(shift).transitionDuration) === 0`, then —
|
|
1385
|
+
once past that gate — pins `overflow-x: clip` on <main> until a
|
|
1386
|
+
`transitionend` for `transform` clears it. The reduced-motion rule
|
|
1387
|
+
above keeps `transition-property: none`, so that event never arrives;
|
|
1388
|
+
leaving the universal 1ms in place would push the computed duration to
|
|
1389
|
+
0.001s, defeat the `=== 0` early return, and strand the clip. Keeping
|
|
1390
|
+
the shorthand (specificity 0,1,0 beats `*`) restores 0s. */
|
|
1391
|
+
.sidebar-transition,
|
|
1392
|
+
.content-shift {
|
|
1393
|
+
transition: none !important;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
/* Same exemption for the app's `.reduce-motion` class: when the OS
|
|
1398
|
+
preference and the class are both set the universal rule above applies,
|
|
1399
|
+
so the class-based freeze needs `!important` too. */
|
|
1400
|
+
.reduce-motion .sidebar-transition,
|
|
1401
|
+
.reduce-motion .content-shift {
|
|
1402
|
+
transition: none !important;
|
|
1403
|
+
}
|