@blakesteve/roster 2.9.5 → 4.0.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.
- package/README.md +113 -14
- package/dist/Table-CG6Z6c1A.js +7711 -0
- package/dist/Table-CPAcmkIV.cjs +566 -0
- package/dist/components/atoms/Button/Button.d.ts +10 -0
- package/dist/components/atoms/PasswordInput/PasswordInput.d.ts +30 -0
- package/dist/components/atoms/Pill/Pill.d.ts +22 -0
- package/dist/components/atoms/Pill/pill-variants.d.ts +25 -0
- package/dist/components/molecules/Alert/Alert.d.ts +25 -0
- package/dist/components/molecules/Alert/alert-variants.d.ts +11 -0
- package/dist/components/organisms/DataTable/DataTable.d.ts +39 -4
- package/dist/components/organisms/Navbar/Navbar.d.ts +46 -7
- package/dist/data-table.cjs.js +1 -0
- package/dist/data-table.d.ts +21 -0
- package/dist/data-table.es.js +155 -0
- package/dist/index.d.ts +5 -1
- package/dist/preflight.cjs.js +1 -0
- package/dist/preflight.css +1 -0
- package/dist/preflight.d.ts +0 -0
- package/dist/preflight.es.js +1 -0
- package/dist/roster.cjs.js +2 -570
- package/dist/roster.css +1 -1
- package/dist/roster.es.js +5987 -15192
- package/package.json +20 -4
|
@@ -5,6 +5,16 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
|
|
|
5
5
|
isLoading?: boolean;
|
|
6
6
|
startIcon?: React.ReactNode;
|
|
7
7
|
endIcon?: React.ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Which surface the button sits on.
|
|
10
|
+
*
|
|
11
|
+
* Roster's dark styling keys off an ancestor carrying `.dark`, so a button
|
|
12
|
+
* placed on a hard-coded dark panel that never carries that class (a
|
|
13
|
+
* campfire overlay, a lantern-night backdrop) falls back to the LIGHT
|
|
14
|
+
* styles and flashes a near-white hover. Pass `surface="dark"` to force the
|
|
15
|
+
* dark treatment regardless of the app's theme.
|
|
16
|
+
*/
|
|
17
|
+
surface?: "auto" | "dark";
|
|
8
18
|
}
|
|
9
19
|
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
10
20
|
export { Button };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { InputProps } from '../Input/Input';
|
|
3
|
+
export interface PasswordInputProps extends Omit<InputProps, "type" | "endIcon"> {
|
|
4
|
+
/**
|
|
5
|
+
* Whether to render the reveal toggle at all. Turn it off where policy
|
|
6
|
+
* forbids showing the value on screen.
|
|
7
|
+
*/
|
|
8
|
+
revealable?: boolean;
|
|
9
|
+
/** Starts revealed. Uncontrolled; pair with `onRevealChange` to observe. */
|
|
10
|
+
defaultRevealed?: boolean;
|
|
11
|
+
/** Controls the reveal state. Pass with `onRevealChange` for a controlled field. */
|
|
12
|
+
revealed?: boolean;
|
|
13
|
+
/** Fires whenever the reveal state changes, controlled or not. */
|
|
14
|
+
onRevealChange?: (revealed: boolean) => void;
|
|
15
|
+
/** Accessible label for the toggle while the value is hidden. */
|
|
16
|
+
showLabel?: string;
|
|
17
|
+
/** Accessible label for the toggle while the value is visible. */
|
|
18
|
+
hideLabel?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A password field with a reveal toggle: the pattern every sign-in form needs
|
|
22
|
+
* and nobody should rewrite.
|
|
23
|
+
*
|
|
24
|
+
* Wraps `Input`, so labels, helper and error text, and every variant behave
|
|
25
|
+
* exactly as they do everywhere else. The toggle is a real button: keyboard
|
|
26
|
+
* reachable, `type="button"` so it never submits the form, and disabled
|
|
27
|
+
* alongside the field.
|
|
28
|
+
*/
|
|
29
|
+
declare const PasswordInput: React.ForwardRefExoticComponent<PasswordInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
30
|
+
export { PasswordInput };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { pillVariants } from './pill-variants';
|
|
4
|
+
export interface PillProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof pillVariants> {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
/** Leading status dot, in the pill's color scheme. */
|
|
7
|
+
dot?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Animates the dot for genuinely live state: "Live now", "12 watching".
|
|
10
|
+
* Requires `dot`. Honors `prefers-reduced-motion`, in which case the dot
|
|
11
|
+
* still renders, it just stops moving.
|
|
12
|
+
*/
|
|
13
|
+
pulse?: boolean;
|
|
14
|
+
/** Leading icon or avatar. Ignored when `dot` is set. */
|
|
15
|
+
leadingIcon?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Inline chrome for a short phrase: social proof, live state, an applied
|
|
19
|
+
* filter. See pill-variants.ts for how this differs from Badge.
|
|
20
|
+
*/
|
|
21
|
+
declare const Pill: React.ForwardRefExoticComponent<PillProps & React.RefAttributes<HTMLSpanElement>>;
|
|
22
|
+
export { Pill };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pill vs Badge.
|
|
3
|
+
*
|
|
4
|
+
* Badge is a compact label attached to something else: a count on an avatar,
|
|
5
|
+
* a status on a table row. It is sized to sit in a corner.
|
|
6
|
+
*
|
|
7
|
+
* Pill is standalone inline chrome carrying a short phrase: social proof
|
|
8
|
+
* ("3 friends voted"), live state ("Live now"), or a filter that reads as a
|
|
9
|
+
* sentence fragment. It is always fully rounded, has roomier horizontal
|
|
10
|
+
* padding so words breathe, and can lead with a status dot.
|
|
11
|
+
*/
|
|
12
|
+
export declare const pillVariants: (props?: ({
|
|
13
|
+
colorScheme?: "primary" | "amber" | "success" | "error" | "neutral" | "info" | null | undefined;
|
|
14
|
+
variant?: "soft" | "solid" | "outline" | null | undefined;
|
|
15
|
+
size?: "sm" | "md" | null | undefined;
|
|
16
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
17
|
+
/**
|
|
18
|
+
* The leading status dot. On solid pills it borrows the text color so it
|
|
19
|
+
* stays legible against the filled background; elsewhere it takes the scheme.
|
|
20
|
+
*/
|
|
21
|
+
export declare const pillDotVariants: (props?: ({
|
|
22
|
+
colorScheme?: "primary" | "amber" | "success" | "error" | "neutral" | "info" | null | undefined;
|
|
23
|
+
variant?: "soft" | "solid" | "outline" | null | undefined;
|
|
24
|
+
size?: "sm" | "md" | null | undefined;
|
|
25
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { alertVariants } from './alert-variants';
|
|
4
|
+
export interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">, VariantProps<typeof alertVariants> {
|
|
5
|
+
/** Optional bolded first line above the message. */
|
|
6
|
+
title?: React.ReactNode;
|
|
7
|
+
/** The message itself. */
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** Replaces the icon chosen for the color scheme. Pass `null` for none. */
|
|
10
|
+
icon?: React.ReactNode;
|
|
11
|
+
/** Renders a dismiss button when provided. */
|
|
12
|
+
onDismiss?: () => void;
|
|
13
|
+
/** Accessible label for the dismiss button. */
|
|
14
|
+
dismissLabel?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Inline notice strip for feedback in the flow of a page: "this action
|
|
18
|
+
* failed", "changes saved". For a full zero-data panel reach for EmptyState or
|
|
19
|
+
* ErrorState instead.
|
|
20
|
+
*
|
|
21
|
+
* Errors announce themselves assertively; every other scheme is polite, so a
|
|
22
|
+
* success note does not interrupt whatever a screen reader is currently saying.
|
|
23
|
+
*/
|
|
24
|
+
declare const Alert: React.ForwardRefExoticComponent<AlertProps & React.RefAttributes<HTMLDivElement>>;
|
|
25
|
+
export { Alert };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline notice strip. Deliberately lighter than ErrorState, which is a full
|
|
3
|
+
* empty-state panel. Alert is for "this action failed" feedback sitting in
|
|
4
|
+
* the flow of a page or a form.
|
|
5
|
+
*
|
|
6
|
+
* The left stripe carries the color weight so the fill can stay quiet enough
|
|
7
|
+
* to sit inside a form without shouting.
|
|
8
|
+
*/
|
|
9
|
+
export declare const alertVariants: (props?: ({
|
|
10
|
+
colorScheme?: "primary" | "amber" | "success" | "error" | "neutral" | "info" | null | undefined;
|
|
11
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
@@ -1,7 +1,41 @@
|
|
|
1
|
-
import { ColumnDef } from '@tanstack/react-table';
|
|
1
|
+
import { ColumnDef, RowData } from '@tanstack/react-table';
|
|
2
2
|
import { TableProps } from '../Table/Table';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The feature set DataTable registers: sorting and pagination, plus the row
|
|
5
|
+
* models each one needs. v9 requires features to be declared up front, and it
|
|
6
|
+
* types column definitions against them, so consumers need this type to write
|
|
7
|
+
* their columns:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const columns: ColumnDef<RosterTableFeatures, Person>[] = [...]
|
|
11
|
+
* // or
|
|
12
|
+
* const helper = createColumnHelper<RosterTableFeatures, Person>()
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Built statically at module scope, as v9 requires.
|
|
16
|
+
*/
|
|
17
|
+
declare const dataTableFeatures: {
|
|
18
|
+
rowSortingFeature: import('@tanstack/table-core').TableFeature;
|
|
19
|
+
rowPaginationFeature: import('@tanstack/table-core').TableFeature;
|
|
20
|
+
sortedRowModel: (table: import('@tanstack/table-core').Table<any, any>) => () => import('@tanstack/table-core').RowModel<any, any>;
|
|
21
|
+
paginatedRowModel: (table: import('@tanstack/table-core').Table<any, any>) => () => import('@tanstack/table-core').RowModel<any, any>;
|
|
22
|
+
sortFns: {
|
|
23
|
+
alphanumeric: import('@tanstack/table-core').CreatedSortFn<any, any>;
|
|
24
|
+
alphanumericCaseSensitive: import('@tanstack/table-core').CreatedSortFn<any, any>;
|
|
25
|
+
basic: import('@tanstack/table-core').CreatedSortFn<any, any>;
|
|
26
|
+
datetime: import('@tanstack/table-core').CreatedSortFn<any, any>;
|
|
27
|
+
text: import('@tanstack/table-core').CreatedSortFn<any, any>;
|
|
28
|
+
textCaseSensitive: import('@tanstack/table-core').CreatedSortFn<any, any>;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export type RosterTableFeatures = typeof dataTableFeatures;
|
|
32
|
+
/**
|
|
33
|
+
* `TValue` is gone from v8's `DataTableProps<TData, TValue>`: a columns array
|
|
34
|
+
* is heterogeneous, so v9 types each entry's value as `unknown` and recovers
|
|
35
|
+
* the real type per column through `createColumnHelper`.
|
|
36
|
+
*/
|
|
37
|
+
export interface DataTableProps<TData extends RowData> {
|
|
38
|
+
columns: ColumnDef<RosterTableFeatures, TData>[];
|
|
5
39
|
data: TData[];
|
|
6
40
|
className?: string;
|
|
7
41
|
tableClassName?: string;
|
|
@@ -10,4 +44,5 @@ export interface DataTableProps<TData, TValue> {
|
|
|
10
44
|
size?: TableProps["size"];
|
|
11
45
|
hoverable?: boolean;
|
|
12
46
|
}
|
|
13
|
-
export declare function DataTable<TData
|
|
47
|
+
export declare function DataTable<TData extends RowData>({ columns, data, className, tableClassName, paginationClassName, variant, size, hoverable, }: DataTableProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
export {};
|
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { VariantProps } from 'class-variance-authority';
|
|
3
3
|
import { navbarVariants } from './navbar-variants';
|
|
4
|
+
/**
|
|
5
|
+
* Content for a consumer-supplied slot. Pass a plain node, or a function that
|
|
6
|
+
* receives `close` so anything inside the slot can dismiss the mobile panel —
|
|
7
|
+
* needed when the slot holds a link, since the nav has no way to know a click
|
|
8
|
+
* on arbitrary content was a navigation.
|
|
9
|
+
*/
|
|
10
|
+
export type NavbarSlot = React.ReactNode | ((props: {
|
|
11
|
+
close: () => void;
|
|
12
|
+
}) => React.ReactNode);
|
|
4
13
|
export interface NavItem {
|
|
5
14
|
label: string;
|
|
6
15
|
path: string;
|
|
7
|
-
/** Optional badge rendered inline after the link label
|
|
16
|
+
/** Optional badge rendered inline after the link label. Any ReactNode.
|
|
8
17
|
* Use for "New" labels, notification counts, or status indicators.
|
|
9
18
|
* Appears in both the desktop nav and the mobile slide-out panel. */
|
|
10
19
|
badge?: React.ReactNode;
|
|
11
20
|
}
|
|
12
21
|
export interface NavbarProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof navbarVariants> {
|
|
13
22
|
logoSrc: string;
|
|
23
|
+
/**
|
|
24
|
+
* Size of the logo image. Accepts any CSS length (`"2.75rem"`, `44`).
|
|
25
|
+
* Defaults to `2rem`, the previous hard-coded `h-8 w-8`.
|
|
26
|
+
*/
|
|
27
|
+
logoSize?: string | number;
|
|
28
|
+
/**
|
|
29
|
+
* Classes applied to the logo image. Replaces the default rounding, so a
|
|
30
|
+
* circular mark can pass `"rounded-full"` and a square one `""`.
|
|
31
|
+
*/
|
|
32
|
+
logoClassName?: string;
|
|
14
33
|
brandName: string;
|
|
15
34
|
items: NavItem[];
|
|
16
35
|
activePath?: string;
|
|
@@ -25,17 +44,34 @@ export interface NavbarProps extends React.HTMLAttributes<HTMLElement>, VariantP
|
|
|
25
44
|
onLogout?: () => void;
|
|
26
45
|
onInboxClick?: () => void;
|
|
27
46
|
onThemeToggle?: () => void;
|
|
28
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Which palette the nav paints itself with.
|
|
49
|
+
*
|
|
50
|
+
* `"auto"` follows the nearest ancestor carrying the `.dark` class, matching
|
|
51
|
+
* how the rest of Roster handles dark mode. Use it in class-based dark apps
|
|
52
|
+
* so the nav does not need wiring into your theme state. Omit the prop
|
|
53
|
+
* entirely and the mode is inferred from `variant`, as before.
|
|
54
|
+
*/
|
|
55
|
+
themeMode?: "light" | "dark" | "auto";
|
|
29
56
|
notificationVariant?: "primary" | "error" | "amber" | "success" | "neutral" | "orange" | "teal" | "purple";
|
|
57
|
+
/**
|
|
58
|
+
* Fill style of the notification count badge. Defaults to `"solid"`, which
|
|
59
|
+
* is what the nav rendered before this was configurable. Use `"soft"` or
|
|
60
|
+
* `"outline"` where a solid dot competes with a busy or colored nav surface.
|
|
61
|
+
*/
|
|
62
|
+
notificationFill?: "soft" | "light" | "solid" | "outline";
|
|
30
63
|
/**
|
|
31
64
|
* Custom content rendered in the right-side action area. When provided it
|
|
32
65
|
* replaces the built-in user menu / "Log In" button on desktop and the user
|
|
33
66
|
* section in the mobile panel, giving you full control over auth UI.
|
|
67
|
+
*
|
|
68
|
+
* Pass a function to receive `close` and dismiss the mobile panel from
|
|
69
|
+
* inside the slot: `actions={({ close }) => <Link onClick={close} … />}`.
|
|
34
70
|
*/
|
|
35
|
-
actions?:
|
|
71
|
+
actions?: NavbarSlot;
|
|
36
72
|
/**
|
|
37
73
|
* Replaces the default brand name `<span>` with arbitrary markup. Use this
|
|
38
|
-
* when you need mixed weights,
|
|
74
|
+
* when you need mixed weights, colors, or other rich styling that a plain
|
|
39
75
|
* string cannot express (e.g. bold "GAME" + thin "VERDICT").
|
|
40
76
|
* The logo image is always rendered; this only affects the text element.
|
|
41
77
|
*/
|
|
@@ -44,10 +80,13 @@ export interface NavbarProps extends React.HTMLAttributes<HTMLElement>, VariantP
|
|
|
44
80
|
* Extra content rendered between the nav link list and the user menu / Log In
|
|
45
81
|
* button on desktop, and above the nav links in the mobile slide-out panel.
|
|
46
82
|
* Use this for persistent nav-level controls like a search toggle that should
|
|
47
|
-
* coexist with the built-in user menu. Does not replace the user menu
|
|
83
|
+
* coexist with the built-in user menu. Does not replace the user menu;
|
|
48
84
|
* see `actions` for full replacement.
|
|
85
|
+
*
|
|
86
|
+
* Pass a function to receive `close` and dismiss the mobile panel from
|
|
87
|
+
* inside the slot: `navActions={({ close }) => <Link onClick={close} … />}`.
|
|
49
88
|
*/
|
|
50
|
-
navActions?:
|
|
89
|
+
navActions?: NavbarSlot;
|
|
51
90
|
/**
|
|
52
91
|
* Auth-gated navigation items appended to the built-in user avatar dropdown
|
|
53
92
|
* on desktop and to the nav section of the mobile slide-out panel. Only
|
|
@@ -55,5 +94,5 @@ export interface NavbarProps extends React.HTMLAttributes<HTMLElement>, VariantP
|
|
|
55
94
|
*/
|
|
56
95
|
userMenuItems?: NavItem[];
|
|
57
96
|
}
|
|
58
|
-
declare const Navbar: ({ logoSrc, brandName, items, activePath, routerElement, user, onLogin, onLogout, onInboxClick, onThemeToggle, actions, brandElement, navActions, userMenuItems, className, variant, position, themeMode, notificationVariant, ...props }: NavbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
97
|
+
declare const Navbar: ({ logoSrc, logoSize, logoClassName, brandName, items, activePath, routerElement, user, onLogin, onLogout, onInboxClick, onThemeToggle, actions, brandElement, navActions, userMenuItems, className, variant, position, themeMode, notificationVariant, notificationFill, ...props }: NavbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
59
98
|
export { Navbar };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Table-CPAcmkIV.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, T as C, a0 as S, a1 as o, _ as P, F as s, a9 as v, aa as w, v as i, U as y, X as c, N as l, ab as N, ac as R, ad as T, ae as k } from "./Table-CG6Z6c1A.js";
|
|
3
|
+
import { useState as F } from "react";
|
|
4
|
+
import { tableFeatures as I, sortFns as A, rowPaginationFeature as M, rowSortingFeature as z, createPaginatedRowModel as D, createSortedRowModel as G, useTable as H, flexRender as g } from "@tanstack/react-table";
|
|
5
|
+
const B = I({
|
|
6
|
+
rowSortingFeature: z,
|
|
7
|
+
rowPaginationFeature: M,
|
|
8
|
+
sortedRowModel: G(),
|
|
9
|
+
paginatedRowModel: D(),
|
|
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
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ export * from './components/atoms/Input/Input';
|
|
|
14
14
|
export * from './components/atoms/Input/input-variants';
|
|
15
15
|
export * from './components/atoms/Link/Link';
|
|
16
16
|
export * from './components/atoms/Link/link-variants';
|
|
17
|
+
export * from './components/atoms/PasswordInput/PasswordInput';
|
|
18
|
+
export * from './components/atoms/Pill/Pill';
|
|
19
|
+
export * from './components/atoms/Pill/pill-variants';
|
|
17
20
|
export * from './components/atoms/Select/Select';
|
|
18
21
|
export * from './components/atoms/Select/select-variants';
|
|
19
22
|
export * from './components/atoms/Spinner/Spinner';
|
|
@@ -26,6 +29,8 @@ export * from './components/atoms/LiquidTabs/LiquidTabs';
|
|
|
26
29
|
export * from './components/atoms/Tooltip/Tooltip';
|
|
27
30
|
export * from './components/atoms/CollapsibleSection/CollapsibleSection';
|
|
28
31
|
export * from './components/atoms/SegmentBar/SegmentBar';
|
|
32
|
+
export * from './components/molecules/Alert/Alert';
|
|
33
|
+
export * from './components/molecules/Alert/alert-variants';
|
|
29
34
|
export * from './components/molecules/Accordion/Accordion';
|
|
30
35
|
export * from './components/molecules/Breadcrumbs/Breadcrumbs';
|
|
31
36
|
export * from './components/molecules/Breadcrumbs/breadcrumb-variants';
|
|
@@ -45,6 +50,5 @@ export * from './components/organisms/Navbar/Navbar';
|
|
|
45
50
|
export * from './components/organisms/Navbar/navbar-variants';
|
|
46
51
|
export * from './components/organisms/Table/Table';
|
|
47
52
|
export * from './components/organisms/Table/table-variants';
|
|
48
|
-
export * from './components/organisms/DataTable/DataTable';
|
|
49
53
|
export * from './hooks/useCountdown';
|
|
50
54
|
export * from './lib/utils';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";
|
|
@@ -0,0 +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 theme,base,components,roster,utilities;
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";
|