@blakesteve/roster 3.0.0 → 4.1.0

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.
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { eyebrowVariants } from './eyebrow-variants';
4
+ export interface EyebrowProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof eyebrowVariants> {
5
+ children: React.ReactNode;
6
+ /**
7
+ * Element to render. Defaults to `span` so it stays inline and carries no
8
+ * heading semantics: an eyebrow labels a section, it is not the heading.
9
+ */
10
+ as?: React.ElementType;
11
+ }
12
+ declare const Eyebrow: React.ForwardRefExoticComponent<EyebrowProps & React.RefAttributes<HTMLElement>>;
13
+ export { Eyebrow };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The small uppercase label that sits above a heading, beside a rule, or as a
3
+ * column head. Extracted from blakeb.dev, where it was hand-rolled as a CSS
4
+ * class and used 26 times before anyone noticed it was a component.
5
+ *
6
+ * Monospace on purpose: at this size, tracked-out uppercase reads as chrome
7
+ * rather than prose, which is the whole job.
8
+ */
9
+ export declare const eyebrowVariants: (props?: ({
10
+ size?: "xs" | "sm" | "md" | null | undefined;
11
+ tone?: "primary" | "strong" | "default" | "faint" | null | undefined;
12
+ weight?: "medium" | "normal" | "semibold" | null | undefined;
13
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { inlineCodeVariants } from './inline-code-variants';
4
+ export interface InlineCodeProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof inlineCodeVariants> {
5
+ children: React.ReactNode;
6
+ }
7
+ /** Inline `<code>` for identifiers in running prose. Not for code blocks. */
8
+ declare const InlineCode: React.ForwardRefExoticComponent<InlineCodeProps & React.RefAttributes<HTMLElement>>;
9
+ export { InlineCode };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Inline `<code>` for identifiers in running prose.
3
+ *
4
+ * Sized at 0.8125rem rather than 1em on purpose: a monospace face at the same
5
+ * nominal size as the surrounding text always reads a notch too large.
6
+ */
7
+ export declare const inlineCodeVariants: (props?: ({
8
+ colorScheme?: "primary" | "neutral" | "current" | null | undefined;
9
+ surface?: "none" | "soft" | null | undefined;
10
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+ export interface LabeledDividerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
3
+ /** Sits before the rule. */
4
+ label: React.ReactNode;
5
+ /** Sits after the rule. Use for a count, a total, a date. */
6
+ trailing?: React.ReactNode;
7
+ /** Puts the label on the right instead, with the rule leading. */
8
+ align?: "start" | "end";
9
+ }
10
+ /**
11
+ * A horizontal rule that carries a label, and optionally something on the far
12
+ * side of it. Reads as a section marker rather than a heading, so it suits
13
+ * lists whose contents already have their own headings.
14
+ *
15
+ * `role="presentation"` because the rule is decoration; the label is real text
16
+ * and stays in the accessibility tree on its own.
17
+ */
18
+ declare const LabeledDivider: React.ForwardRefExoticComponent<LabeledDividerProps & React.RefAttributes<HTMLDivElement>>;
19
+ export { LabeledDivider };
@@ -0,0 +1,21 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { statValueVariants } from './stat-variants';
4
+ export interface StatProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">, VariantProps<typeof statValueVariants> {
5
+ /** The figure itself. A string, so you control formatting and units. */
6
+ value: React.ReactNode;
7
+ /** What the figure counts. */
8
+ label: React.ReactNode;
9
+ /**
10
+ * Where the number came from: "live", "GitHub API", "at build time". Small
11
+ * and quiet by design, but worth having — a figure whose provenance is
12
+ * stated reads very differently from one that is merely asserted.
13
+ */
14
+ source?: React.ReactNode;
15
+ }
16
+ /**
17
+ * Renders as a `<div>` wrapping a definition pair, so a row of Stats can sit
18
+ * inside a `<dl>` and stay semantically honest.
19
+ */
20
+ declare const Stat: React.ForwardRefExoticComponent<StatProps & React.RefAttributes<HTMLDivElement>>;
21
+ export { Stat };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A single figure with its label. Distinct from Badge and Pill: those carry a
3
+ * word, a Stat carries a magnitude and is meant to be scanned in a row of
4
+ * siblings. Digits are tabular so a row of them lines up on the decimal.
5
+ */
6
+ export declare const statValueVariants: (props?: ({
7
+ size?: "sm" | "md" | "lg" | null | undefined;
8
+ colorScheme?: "primary" | "amber" | "success" | "error" | "neutral" | "current" | null | undefined;
9
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1,16 @@
1
+ import { default as React } from 'react';
2
+ import { ButtonProps } from '../Button/Button';
3
+ export interface ThemeToggleProps extends Omit<ButtonProps, "onClick" | "children" | "aria-label"> {
4
+ /** localStorage key. Match it to your blocking script. */
5
+ storageKey?: string;
6
+ /** Fires after the theme changes, with the new mode. */
7
+ onThemeChange?: (mode: "light" | "dark") => void;
8
+ /** Renders the current mode beside the icon. */
9
+ showLabel?: boolean;
10
+ /** Accessible label offering to switch to dark. */
11
+ toDarkLabel?: string;
12
+ /** Accessible label offering to switch back to light. */
13
+ toLightLabel?: string;
14
+ }
15
+ declare const ThemeToggle: React.ForwardRefExoticComponent<ThemeToggleProps & React.RefAttributes<HTMLButtonElement>>;
16
+ export { ThemeToggle };
@@ -0,0 +1,24 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { descriptionListVariants } from './description-list-variants';
4
+ export type DescriptionListItem = {
5
+ term: React.ReactNode;
6
+ description: React.ReactNode;
7
+ };
8
+ export interface DescriptionListProps extends Omit<React.HTMLAttributes<HTMLDListElement>, "children">, VariantProps<typeof descriptionListVariants> {
9
+ items: DescriptionListItem[];
10
+ /** Adds a hairline under every row but the last. */
11
+ dividers?: boolean;
12
+ }
13
+ /**
14
+ * Label and value pairs: a spec sheet, a metadata panel, a props table.
15
+ *
16
+ * Renders a real `<dl>` with `<dt>`/`<dd>`, which matters more than it looks —
17
+ * screen readers announce the pairing, so "Framework, Next.js 16" arrives as
18
+ * one fact rather than two loose strings.
19
+ *
20
+ * The `contents` display on each row wrapper is what lets a grid layout treat
21
+ * the dt and dd as direct grid children while keeping them grouped in markup.
22
+ */
23
+ declare const DescriptionList: React.ForwardRefExoticComponent<DescriptionListProps & React.RefAttributes<HTMLDListElement>>;
24
+ export { DescriptionList };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Label and value pairs: a spec sheet, a metadata panel, a case study sidebar.
3
+ *
4
+ * `sm` is the default because this component's usual home is a sidebar panel,
5
+ * where the list is reference material rather than reading material.
6
+ */
7
+ export declare const descriptionListVariants: (props?: ({
8
+ layout?: "split" | "inline" | "stacked" | null | undefined;
9
+ size?: "sm" | "md" | null | undefined;
10
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1,22 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { pullquoteVariants } from './pullquote-variants';
4
+ export interface PullquoteProps extends Omit<React.HTMLAttributes<HTMLElement>, "cite">, VariantProps<typeof pullquoteVariants> {
5
+ children: React.ReactNode;
6
+ /**
7
+ * Attribution, rendered beneath the quote. Works as a source ("Why it took a
8
+ * while to spot") as well as a speaker.
9
+ */
10
+ cite?: React.ReactNode;
11
+ /** URL for the quote's source, passed to the underlying blockquote. */
12
+ citeUrl?: string;
13
+ }
14
+ /**
15
+ * A line lifted out of running prose and given room.
16
+ *
17
+ * Uses `<figure>` + `<blockquote>` + `<figcaption>` rather than a styled div:
18
+ * that is the pairing the HTML spec has for quote-with-attribution, and it
19
+ * keeps the citation associated with the quote for assistive tech.
20
+ */
21
+ declare const Pullquote: React.ForwardRefExoticComponent<PullquoteProps & React.RefAttributes<HTMLElement>>;
22
+ export { Pullquote };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A line lifted out of running prose and given room.
3
+ *
4
+ * The scheme colors the rule only; the quote text stays at full contrast in
5
+ * every case. A pullquote is body copy that has been promoted, and tinting it
6
+ * would demote it again.
7
+ */
8
+ export declare const pullquoteVariants: (props?: ({
9
+ variant?: "rule" | "plain" | "centered" | null | undefined;
10
+ colorScheme?: "primary" | "amber" | "success" | "error" | "neutral" | "current" | null | undefined;
11
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Table-DN9b_g1N.cjs"),j=require("react"),n=require("@tanstack/react-table"),p=n.tableFeatures({rowSortingFeature:n.rowSortingFeature,rowPaginationFeature:n.rowPaginationFeature,sortedRowModel:n.createSortedRowModel(),paginatedRowModel:n.createPaginatedRowModel(),sortFns:n.sortFns});function R({columns:a,data:r,className:i,tableClassName:l,paginationClassName:x,variant:c="default",size:u="md",hoverable:g=!1}){const[m,d]=j.useState([]),t=n.useTable({features:p,data:r,columns:a,onSortingChange:d,state:{sorting:m},initialState:{pagination:{pageIndex:0,pageSize:10}}});return e.jsxRuntimeExports.jsxs("div",{className:e.cn("flex flex-col gap-4",i),children:[e.jsxRuntimeExports.jsxs(e.Table,{variant:c,size:u,hoverable:g,className:l,children:[e.jsxRuntimeExports.jsx(e.TableHeader,{children:t.getHeaderGroups().map(o=>e.jsxRuntimeExports.jsx(e.TableRow,{children:o.headers.map(s=>e.jsxRuntimeExports.jsx(e.TableHead,{children:s.isPlaceholder?null:e.jsxRuntimeExports.jsxs("div",{className:e.cn("flex items-center gap-2 transition-opacity",s.column.getCanSort()&&"cursor-pointer select-none opacity-80 hover:opacity-100"),onClick:s.column.getToggleSortingHandler(),children:[n.flexRender(s.column.columnDef.header,s.getContext()),s.column.getCanSort()&&e.jsxRuntimeExports.jsx("span",{className:"w-4 flex justify-center text-primary-500",children:s.column.getIsSorted()==="asc"?e.jsxRuntimeExports.jsx(e.FontAwesomeIcon,{icon:e.faCaretUp}):s.column.getIsSorted()==="desc"?e.jsxRuntimeExports.jsx(e.FontAwesomeIcon,{icon:e.faCaretDown}):null})]})},s.id))},o.id))}),e.jsxRuntimeExports.jsx(e.TableBody,{children:t.getRowModel().rows?.length?t.getRowModel().rows.map(o=>e.jsxRuntimeExports.jsx(e.TableRow,{children:o.getAllCells().map(s=>e.jsxRuntimeExports.jsx(e.TableCell,{children:n.flexRender(s.column.columnDef.cell,s.getContext())},s.id))},o.id)):e.jsxRuntimeExports.jsx(e.TableRow,{children:e.jsxRuntimeExports.jsx(e.TableCell,{colSpan:a.length,className:"h-24 text-center text-gray-500 dark:text-gray-400 italic",children:"No results found."})})})]}),e.jsxRuntimeExports.jsxs("div",{className:e.cn("flex flex-col sm:flex-row items-center justify-between gap-4 px-2",x),children:[e.jsxRuntimeExports.jsxs("div",{className:"text-sm font-medium text-gray-500 dark:text-gray-400",children:["Page"," ",e.jsxRuntimeExports.jsx("strong",{className:"text-gray-900 dark:text-gray-100",children:t.state.pagination.pageIndex+1})," ","of"," ",e.jsxRuntimeExports.jsx("strong",{className:"text-gray-900 dark:text-gray-100",children:t.getPageCount()})]}),e.jsxRuntimeExports.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsxRuntimeExports.jsx(e.Button,{variant:"outline",colorScheme:"neutral",size:"sm",onClick:()=>t.setPageIndex(0),disabled:!t.getCanPreviousPage(),"aria-label":"Go to first page",children:e.jsxRuntimeExports.jsx(e.FontAwesomeIcon,{icon:e.faAnglesLeft})}),e.jsxRuntimeExports.jsx(e.Button,{variant:"outline",colorScheme:"neutral",size:"sm",onClick:()=>t.previousPage(),disabled:!t.getCanPreviousPage(),"aria-label":"Go to previous page",children:e.jsxRuntimeExports.jsx(e.FontAwesomeIcon,{icon:e.faAngleLeft})}),e.jsxRuntimeExports.jsx(e.Button,{variant:"outline",colorScheme:"neutral",size:"sm",onClick:()=>t.nextPage(),disabled:!t.getCanNextPage(),"aria-label":"Go to next page",children:e.jsxRuntimeExports.jsx(e.FontAwesomeIcon,{icon:e.faAngleRight})}),e.jsxRuntimeExports.jsx(e.Button,{variant:"outline",colorScheme:"neutral",size:"sm",onClick:()=>t.setPageIndex(t.getPageCount()-1),disabled:!t.getCanNextPage(),"aria-label":"Go to last page",children:e.jsxRuntimeExports.jsx(e.FontAwesomeIcon,{icon:e.faAnglesRight})})]})]})]})}exports.DataTable=R;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * DataTable lives behind its own entry point: `@blakesteve/roster/data-table`.
3
+ *
4
+ * It is the only component that needs TanStack Table, which Roster declares as
5
+ * an optional peer dependency. A static re-export from the main entry would
6
+ * make that peer mandatory in practice — a consumer's bundler resolves imports
7
+ * before it tree-shakes, so `import { Button } from "@blakesteve/roster"` would
8
+ * fail with "Cannot resolve '@tanstack/react-table'" in an app that has no
9
+ * tables at all. Splitting the entry keeps the cost with the component.
10
+ *
11
+ * Consumers of DataTable install the peer themselves:
12
+ *
13
+ * ```bash
14
+ * npm install @tanstack/react-table
15
+ * ```
16
+ *
17
+ * ```tsx
18
+ * import { DataTable, type RosterTableFeatures } from "@blakesteve/roster/data-table";
19
+ * ```
20
+ */
21
+ export * from './components/organisms/DataTable/DataTable';
@@ -0,0 +1,155 @@
1
+ "use client";
2
+ import { q as e, U as C, a1 as S, a2 as o, a0 as P, F as s, aa as v, ab as w, v as i, W as y, Z as c, G as l, ac as N, ad as R, ae as T, af as k } from "./Table-DNbzjCZM.js";
3
+ import { useState as F } from "react";
4
+ import { tableFeatures as I, sortFns as A, rowPaginationFeature as M, rowSortingFeature as z, createPaginatedRowModel as G, createSortedRowModel as D, useTable as H, flexRender as g } from "@tanstack/react-table";
5
+ const B = I({
6
+ rowSortingFeature: z,
7
+ rowPaginationFeature: M,
8
+ sortedRowModel: D(),
9
+ paginatedRowModel: G(),
10
+ // The whole built-in registry, not a subset: DataTable is generic over
11
+ // consumer data, so auto sort detection has to be able to reach any of them.
12
+ sortFns: A
13
+ });
14
+ function E({
15
+ columns: r,
16
+ data: d,
17
+ className: x,
18
+ tableClassName: m,
19
+ paginationClassName: u,
20
+ variant: p = "default",
21
+ size: f = "md",
22
+ hoverable: j = !1
23
+ }) {
24
+ const [h, b] = F([]), a = H({
25
+ features: B,
26
+ data: d,
27
+ columns: r,
28
+ onSortingChange: b,
29
+ state: {
30
+ sorting: h
31
+ },
32
+ initialState: {
33
+ pagination: {
34
+ pageIndex: 0,
35
+ pageSize: 10
36
+ }
37
+ }
38
+ });
39
+ return /* @__PURE__ */ e.jsxs("div", { className: i("flex flex-col gap-4", x), children: [
40
+ /* @__PURE__ */ e.jsxs(
41
+ C,
42
+ {
43
+ variant: p,
44
+ size: f,
45
+ hoverable: j,
46
+ className: m,
47
+ children: [
48
+ /* @__PURE__ */ e.jsx(S, { children: a.getHeaderGroups().map((n) => /* @__PURE__ */ e.jsx(o, { children: n.headers.map((t) => /* @__PURE__ */ e.jsx(P, { children: t.isPlaceholder ? null : /* @__PURE__ */ e.jsxs(
49
+ "div",
50
+ {
51
+ className: i(
52
+ "flex items-center gap-2 transition-opacity",
53
+ t.column.getCanSort() && "cursor-pointer select-none opacity-80 hover:opacity-100"
54
+ ),
55
+ onClick: t.column.getToggleSortingHandler(),
56
+ children: [
57
+ g(
58
+ t.column.columnDef.header,
59
+ t.getContext()
60
+ ),
61
+ t.column.getCanSort() && /* @__PURE__ */ e.jsx("span", { className: "w-4 flex justify-center text-primary-500", children: t.column.getIsSorted() === "asc" ? /* @__PURE__ */ e.jsx(s, { icon: v }) : t.column.getIsSorted() === "desc" ? /* @__PURE__ */ e.jsx(s, { icon: w }) : null })
62
+ ]
63
+ }
64
+ ) }, t.id)) }, n.id)) }),
65
+ /* @__PURE__ */ e.jsx(y, { children: a.getRowModel().rows?.length ? (
66
+ // No data-state on the row: row selection is not one of the
67
+ // registered features, and v8's getIsSelected() was always false
68
+ // here, so React omitted the attribute anyway.
69
+ a.getRowModel().rows.map((n) => /* @__PURE__ */ e.jsx(o, { children: n.getAllCells().map((t) => /* @__PURE__ */ e.jsx(c, { children: g(t.column.columnDef.cell, t.getContext()) }, t.id)) }, n.id))
70
+ ) : /* @__PURE__ */ e.jsx(o, { children: /* @__PURE__ */ e.jsx(
71
+ c,
72
+ {
73
+ colSpan: r.length,
74
+ className: "h-24 text-center text-gray-500 dark:text-gray-400 italic",
75
+ children: "No results found."
76
+ }
77
+ ) }) })
78
+ ]
79
+ }
80
+ ),
81
+ /* @__PURE__ */ e.jsxs(
82
+ "div",
83
+ {
84
+ className: i(
85
+ "flex flex-col sm:flex-row items-center justify-between gap-4 px-2",
86
+ u
87
+ ),
88
+ children: [
89
+ /* @__PURE__ */ e.jsxs("div", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: [
90
+ "Page",
91
+ " ",
92
+ /* @__PURE__ */ e.jsx("strong", { className: "text-gray-900 dark:text-gray-100", children: a.state.pagination.pageIndex + 1 }),
93
+ " ",
94
+ "of",
95
+ " ",
96
+ /* @__PURE__ */ e.jsx("strong", { className: "text-gray-900 dark:text-gray-100", children: a.getPageCount() })
97
+ ] }),
98
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center space-x-2", children: [
99
+ /* @__PURE__ */ e.jsx(
100
+ l,
101
+ {
102
+ variant: "outline",
103
+ colorScheme: "neutral",
104
+ size: "sm",
105
+ onClick: () => a.setPageIndex(0),
106
+ disabled: !a.getCanPreviousPage(),
107
+ "aria-label": "Go to first page",
108
+ children: /* @__PURE__ */ e.jsx(s, { icon: N })
109
+ }
110
+ ),
111
+ /* @__PURE__ */ e.jsx(
112
+ l,
113
+ {
114
+ variant: "outline",
115
+ colorScheme: "neutral",
116
+ size: "sm",
117
+ onClick: () => a.previousPage(),
118
+ disabled: !a.getCanPreviousPage(),
119
+ "aria-label": "Go to previous page",
120
+ children: /* @__PURE__ */ e.jsx(s, { icon: R })
121
+ }
122
+ ),
123
+ /* @__PURE__ */ e.jsx(
124
+ l,
125
+ {
126
+ variant: "outline",
127
+ colorScheme: "neutral",
128
+ size: "sm",
129
+ onClick: () => a.nextPage(),
130
+ disabled: !a.getCanNextPage(),
131
+ "aria-label": "Go to next page",
132
+ children: /* @__PURE__ */ e.jsx(s, { icon: T })
133
+ }
134
+ ),
135
+ /* @__PURE__ */ e.jsx(
136
+ l,
137
+ {
138
+ variant: "outline",
139
+ colorScheme: "neutral",
140
+ size: "sm",
141
+ onClick: () => a.setPageIndex(a.getPageCount() - 1),
142
+ disabled: !a.getCanNextPage(),
143
+ "aria-label": "Go to last page",
144
+ children: /* @__PURE__ */ e.jsx(s, { icon: k })
145
+ }
146
+ )
147
+ ] })
148
+ ]
149
+ }
150
+ )
151
+ ] });
152
+ }
153
+ export {
154
+ E as DataTable
155
+ };
@@ -0,0 +1,39 @@
1
+ export interface UseKeySequenceOptions {
2
+ /**
3
+ * Milliseconds allowed between keys before progress resets. Without this a
4
+ * sequence can be completed across an arbitrarily long span, which is rarely
5
+ * what anyone means. Set to 0 to disable the timeout entirely.
6
+ */
7
+ timeout?: number;
8
+ /** Match keys case-insensitively. On by default: users hold shift by accident. */
9
+ ignoreCase?: boolean;
10
+ /** Calls preventDefault on keys that advance the sequence. */
11
+ preventDefault?: boolean;
12
+ /** Turns the listener off without unmounting the component. */
13
+ enabled?: boolean;
14
+ /**
15
+ * Ignore keystrokes typed into inputs, textareas, and contenteditable.
16
+ * On by default: a shortcut that fires while someone is filling in a form is
17
+ * a bug, not a feature.
18
+ */
19
+ ignoreWhenTyping?: boolean;
20
+ }
21
+ /** The Konami code, for the one time in your life you need it. */
22
+ export declare const KONAMI_CODE: readonly ["ArrowUp", "ArrowUp", "ArrowDown", "ArrowDown", "ArrowLeft", "ArrowRight", "ArrowLeft", "ArrowRight", "b", "a", "Enter"];
23
+ /**
24
+ * Fires `onMatch` when a sequence of `KeyboardEvent.key` values is typed in
25
+ * order.
26
+ *
27
+ * Useful for keyboard navigation chords (`g` then `i`), debug shortcuts, and
28
+ * easter eggs. Call it more than once to register more than one sequence.
29
+ *
30
+ * ```tsx
31
+ * useKeySequence(["g", "i"], () => router.push("/inbox"));
32
+ * useKeySequence(KONAMI_CODE, () => setPartyMode(true));
33
+ * ```
34
+ *
35
+ * A wrong key resets progress, except when that key is itself the start of the
36
+ * sequence, which begins a fresh attempt rather than costing one. That is what
37
+ * makes a doubled first key ("g g i") still work.
38
+ */
39
+ export declare function useKeySequence(sequence: readonly string[], onMatch: () => void, options?: UseKeySequenceOptions): void;
package/dist/index.d.ts CHANGED
@@ -17,6 +17,14 @@ export * from './components/atoms/Link/link-variants';
17
17
  export * from './components/atoms/PasswordInput/PasswordInput';
18
18
  export * from './components/atoms/Pill/Pill';
19
19
  export * from './components/atoms/Pill/pill-variants';
20
+ export * from './components/atoms/Eyebrow/Eyebrow';
21
+ export * from './components/atoms/Eyebrow/eyebrow-variants';
22
+ export * from './components/atoms/InlineCode/InlineCode';
23
+ export * from './components/atoms/InlineCode/inline-code-variants';
24
+ export * from './components/atoms/LabeledDivider/LabeledDivider';
25
+ export * from './components/atoms/Stat/Stat';
26
+ export * from './components/atoms/Stat/stat-variants';
27
+ export * from './components/atoms/ThemeToggle/ThemeToggle';
20
28
  export * from './components/atoms/Select/Select';
21
29
  export * from './components/atoms/Select/select-variants';
22
30
  export * from './components/atoms/Spinner/Spinner';
@@ -32,6 +40,10 @@ export * from './components/atoms/SegmentBar/SegmentBar';
32
40
  export * from './components/molecules/Alert/Alert';
33
41
  export * from './components/molecules/Alert/alert-variants';
34
42
  export * from './components/molecules/Accordion/Accordion';
43
+ export * from './components/molecules/DescriptionList/DescriptionList';
44
+ export * from './components/molecules/DescriptionList/description-list-variants';
45
+ export * from './components/molecules/Pullquote/Pullquote';
46
+ export * from './components/molecules/Pullquote/pullquote-variants';
35
47
  export * from './components/molecules/Breadcrumbs/Breadcrumbs';
36
48
  export * from './components/molecules/Breadcrumbs/breadcrumb-variants';
37
49
  export * from './components/molecules/CallToAction/CallToAction';
@@ -50,6 +62,6 @@ export * from './components/organisms/Navbar/Navbar';
50
62
  export * from './components/organisms/Navbar/navbar-variants';
51
63
  export * from './components/organisms/Table/Table';
52
64
  export * from './components/organisms/Table/table-variants';
53
- export * from './components/organisms/DataTable/DataTable';
54
65
  export * from './hooks/useCountdown';
66
+ export * from './hooks/useKeySequence';
55
67
  export * from './lib/utils';
@@ -1 +1 @@
1
- @layer roster-preflight{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer roster;
1
+ @layer roster-preflight{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer theme,base,components,roster,utilities;