@kennycorrea/ui 0.11.3 → 1.6.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/CHANGELOG.md +189 -0
- package/README.md +251 -1
- package/dist/atoms/ActionMenu/ActionMenu.d.ts +37 -0
- package/dist/atoms/ActionMenu/ActionMenu.js +28 -0
- package/dist/atoms/ActionMenu/index.d.ts +1 -0
- package/dist/atoms/ActionMenu/index.js +1 -0
- package/dist/atoms/ActionSheet/ActionSheet.d.ts +10 -4
- package/dist/atoms/ActionSheet/ActionSheet.js +6 -15
- package/dist/atoms/ActionSheet/confirm.d.ts +1 -1
- package/dist/atoms/ActionSheet/confirm.js +1 -1
- package/dist/atoms/Avatar/Avatar.d.ts +1 -1
- package/dist/atoms/Badge/Badge.js +4 -4
- package/dist/atoms/Button/Button.js +2 -3
- package/dist/atoms/Button/Button.types.d.ts +5 -8
- package/dist/atoms/Card/Card.d.ts +5 -3
- package/dist/atoms/Card/Card.js +21 -4
- package/dist/atoms/ContextMenu/ContextMenu.d.ts +1 -1
- package/dist/atoms/ContextMenu/ContextMenu.js +1 -1
- package/dist/atoms/Drawer/Drawer.js +1 -1
- package/dist/atoms/Icon/Icon.d.ts +7 -9
- package/dist/atoms/Icon/Icon.js +23 -8
- package/dist/atoms/Pill/Pill.d.ts +17 -0
- package/dist/atoms/Pill/Pill.js +12 -0
- package/dist/atoms/Pill/index.d.ts +1 -0
- package/dist/atoms/Pill/index.js +1 -0
- package/dist/atoms/ResponsiveDialog/ResponsiveDialog.d.ts +9 -2
- package/dist/atoms/ResponsiveDialog/ResponsiveDialog.js +6 -15
- package/dist/atoms/Sheet/Sheet.js +1 -1
- package/dist/atoms/StatusIndicator/StatusIndicator.d.ts +14 -0
- package/dist/atoms/StatusIndicator/StatusIndicator.js +8 -0
- package/dist/atoms/StatusIndicator/index.d.ts +1 -0
- package/dist/atoms/StatusIndicator/index.js +1 -0
- package/dist/atoms/TextLink/TextLink.d.ts +36 -0
- package/dist/atoms/TextLink/TextLink.js +17 -0
- package/dist/atoms/TextLink/index.d.ts +1 -0
- package/dist/atoms/TextLink/index.js +1 -0
- package/dist/atoms/Toast/Toast.d.ts +1 -1
- package/dist/atoms/Toast/Toast.js +1 -1
- package/dist/atoms/index.d.ts +4 -0
- package/dist/atoms/index.js +4 -0
- package/dist/hooks/breakpoints.d.ts +20 -0
- package/dist/hooks/breakpoints.js +13 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/useControllableState.d.ts +17 -0
- package/dist/hooks/useControllableState.js +22 -0
- package/dist/hooks/useElementWidth.d.ts +7 -0
- package/dist/hooks/useElementWidth.js +22 -0
- package/dist/hooks/useMediaQuery.d.ts +18 -0
- package/dist/hooks/useMediaQuery.js +51 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/molecules/AccentPicker/AccentPicker.d.ts +30 -0
- package/dist/molecules/AccentPicker/AccentPicker.js +27 -0
- package/dist/molecules/AccentPicker/index.d.ts +1 -0
- package/dist/molecules/AccentPicker/index.js +1 -0
- package/dist/molecules/Breadcrumbs/Breadcrumbs.d.ts +27 -0
- package/dist/molecules/Breadcrumbs/Breadcrumbs.js +40 -0
- package/dist/molecules/Breadcrumbs/index.d.ts +1 -0
- package/dist/molecules/Breadcrumbs/index.js +1 -0
- package/dist/molecules/Calendar/Calendar.d.ts +42 -0
- package/dist/molecules/Calendar/Calendar.js +111 -0
- package/dist/molecules/Calendar/index.d.ts +1 -0
- package/dist/molecules/Calendar/index.js +1 -0
- package/dist/molecules/DateInput/DateInput.d.ts +35 -0
- package/dist/molecules/DateInput/DateInput.js +41 -0
- package/dist/molecules/DateInput/index.d.ts +1 -0
- package/dist/molecules/DateInput/index.js +1 -0
- package/dist/molecules/EmptyState/EmptyState.d.ts +19 -0
- package/dist/molecules/EmptyState/EmptyState.js +7 -0
- package/dist/molecules/EmptyState/index.d.ts +1 -0
- package/dist/molecules/EmptyState/index.js +1 -0
- package/dist/molecules/ErrorState/ErrorState.d.ts +18 -0
- package/dist/molecules/ErrorState/ErrorState.js +12 -0
- package/dist/molecules/ErrorState/index.d.ts +1 -0
- package/dist/molecules/ErrorState/index.js +1 -0
- package/dist/molecules/ErrorSummary/ErrorSummary.d.ts +25 -0
- package/dist/molecules/ErrorSummary/ErrorSummary.js +32 -0
- package/dist/molecules/ErrorSummary/index.d.ts +1 -0
- package/dist/molecules/ErrorSummary/index.js +1 -0
- package/dist/molecules/FilterChips/FilterChips.d.ts +10 -0
- package/dist/molecules/FilterChips/FilterChips.js +13 -0
- package/dist/molecules/FilterChips/index.d.ts +1 -0
- package/dist/molecules/FilterChips/index.js +1 -0
- package/dist/molecules/FilterPopover/FilterPopover.d.ts +27 -0
- package/dist/molecules/FilterPopover/FilterPopover.js +32 -0
- package/dist/molecules/FilterPopover/index.d.ts +1 -0
- package/dist/molecules/FilterPopover/index.js +1 -0
- package/dist/molecules/FormActions/FormActions.d.ts +16 -0
- package/dist/molecules/FormActions/FormActions.js +5 -0
- package/dist/molecules/FormActions/index.d.ts +1 -0
- package/dist/molecules/FormActions/index.js +1 -0
- package/dist/molecules/FormField/FormField.d.ts +52 -0
- package/dist/molecules/FormField/FormField.js +63 -0
- package/dist/molecules/FormField/index.d.ts +1 -0
- package/dist/molecules/FormField/index.js +1 -0
- package/dist/molecules/FormSection/FormSection.d.ts +14 -0
- package/dist/molecules/FormSection/FormSection.js +10 -0
- package/dist/molecules/FormSection/index.d.ts +1 -0
- package/dist/molecules/FormSection/index.js +1 -0
- package/dist/molecules/KeyValueList/KeyValueList.d.ts +22 -0
- package/dist/molecules/KeyValueList/KeyValueList.js +9 -0
- package/dist/molecules/KeyValueList/index.d.ts +1 -0
- package/dist/molecules/KeyValueList/index.js +1 -0
- package/dist/molecules/LoadingState/LoadingState.d.ts +20 -0
- package/dist/molecules/LoadingState/LoadingState.js +22 -0
- package/dist/molecules/LoadingState/index.d.ts +1 -0
- package/dist/molecules/LoadingState/index.js +1 -0
- package/dist/molecules/NavItem/NavItem.d.ts +31 -0
- package/dist/molecules/NavItem/NavItem.js +72 -0
- package/dist/molecules/NavItem/context.d.ts +14 -0
- package/dist/molecules/NavItem/context.js +5 -0
- package/dist/molecules/NavItem/index.d.ts +1 -0
- package/dist/molecules/NavItem/index.js +1 -0
- package/dist/molecules/Pagination/Pagination.d.ts +32 -0
- package/dist/molecules/Pagination/Pagination.js +57 -0
- package/dist/molecules/Pagination/index.d.ts +1 -0
- package/dist/molecules/Pagination/index.js +1 -0
- package/dist/molecules/PasswordInput/PasswordInput.d.ts +14 -0
- package/dist/molecules/PasswordInput/PasswordInput.js +16 -0
- package/dist/molecules/PasswordInput/index.d.ts +1 -0
- package/dist/molecules/PasswordInput/index.js +1 -0
- package/dist/molecules/SearchField/SearchField.d.ts +24 -0
- package/dist/molecules/SearchField/SearchField.js +58 -0
- package/dist/molecules/SearchField/index.d.ts +1 -0
- package/dist/molecules/SearchField/index.js +1 -0
- package/dist/molecules/StatGroup/StatGroup.d.ts +21 -0
- package/dist/molecules/StatGroup/StatGroup.js +10 -0
- package/dist/molecules/StatGroup/index.d.ts +1 -0
- package/dist/molecules/StatGroup/index.js +1 -0
- package/dist/molecules/ThemeToggle/ThemeToggle.d.ts +23 -0
- package/dist/molecules/ThemeToggle/ThemeToggle.js +26 -0
- package/dist/molecules/ThemeToggle/index.d.ts +1 -0
- package/dist/molecules/ThemeToggle/index.js +1 -0
- package/dist/molecules/UserMenu/UserMenu.d.ts +20 -0
- package/dist/molecules/UserMenu/UserMenu.js +14 -0
- package/dist/molecules/UserMenu/index.d.ts +1 -0
- package/dist/molecules/UserMenu/index.js +1 -0
- package/dist/molecules/index.d.ts +21 -0
- package/dist/molecules/index.js +21 -0
- package/dist/organisms/AppShell/AppShell.d.ts +29 -0
- package/dist/organisms/AppShell/AppShell.js +34 -0
- package/dist/organisms/AppShell/context.d.ts +14 -0
- package/dist/organisms/AppShell/context.js +6 -0
- package/dist/organisms/AppShell/index.d.ts +1 -0
- package/dist/organisms/AppShell/index.js +1 -0
- package/dist/organisms/AuthForms/AuthForms.d.ts +83 -0
- package/dist/organisms/AuthForms/AuthForms.js +57 -0
- package/dist/organisms/AuthForms/index.d.ts +2 -0
- package/dist/organisms/AuthForms/index.js +1 -0
- package/dist/organisms/AuthForms/shared.d.ts +36 -0
- package/dist/organisms/AuthForms/shared.js +36 -0
- package/dist/organisms/BulkActionBar/BulkActionBar.d.ts +25 -0
- package/dist/organisms/BulkActionBar/BulkActionBar.js +18 -0
- package/dist/organisms/BulkActionBar/index.d.ts +1 -0
- package/dist/organisms/BulkActionBar/index.js +1 -0
- package/dist/organisms/Chart/CategoryCharts.d.ts +34 -0
- package/dist/organisms/Chart/CategoryCharts.js +93 -0
- package/dist/organisms/Chart/ChartFrame.d.ts +26 -0
- package/dist/organisms/Chart/ChartFrame.js +18 -0
- package/dist/organisms/Chart/DonutChart.d.ts +25 -0
- package/dist/organisms/Chart/DonutChart.js +53 -0
- package/dist/organisms/Chart/Sparkline.d.ts +15 -0
- package/dist/organisms/Chart/Sparkline.js +18 -0
- package/dist/organisms/Chart/index.d.ts +5 -0
- package/dist/organisms/Chart/index.js +5 -0
- package/dist/organisms/Chart/shared.d.ts +51 -0
- package/dist/organisms/Chart/shared.js +113 -0
- package/dist/organisms/DataTable/DataTable.d.ts +63 -0
- package/dist/organisms/DataTable/DataTable.js +119 -0
- package/dist/organisms/DataTable/index.d.ts +3 -0
- package/dist/organisms/DataTable/index.js +3 -0
- package/dist/organisms/DataTable/types.d.ts +39 -0
- package/dist/organisms/DataTable/types.js +1 -0
- package/dist/organisms/DataTable/useClientTable.d.ts +27 -0
- package/dist/organisms/DataTable/useClientTable.js +51 -0
- package/dist/organisms/DateRangePicker/DateRangePicker.d.ts +43 -0
- package/dist/organisms/DateRangePicker/DateRangePicker.js +54 -0
- package/dist/organisms/DateRangePicker/index.d.ts +1 -0
- package/dist/organisms/DateRangePicker/index.js +1 -0
- package/dist/organisms/FilterBar/FilterBar.d.ts +28 -0
- package/dist/organisms/FilterBar/FilterBar.js +16 -0
- package/dist/organisms/FilterBar/index.d.ts +1 -0
- package/dist/organisms/FilterBar/index.js +1 -0
- package/dist/organisms/PageHeader/PageHeader.d.ts +31 -0
- package/dist/organisms/PageHeader/PageHeader.js +19 -0
- package/dist/organisms/PageHeader/index.d.ts +1 -0
- package/dist/organisms/PageHeader/index.js +1 -0
- package/dist/organisms/PageTabs/PageTabs.d.ts +27 -0
- package/dist/organisms/PageTabs/PageTabs.js +31 -0
- package/dist/organisms/PageTabs/index.d.ts +1 -0
- package/dist/organisms/PageTabs/index.js +1 -0
- package/dist/organisms/Sidebar/Sidebar.d.ts +48 -0
- package/dist/organisms/Sidebar/Sidebar.js +61 -0
- package/dist/organisms/Sidebar/index.d.ts +1 -0
- package/dist/organisms/Sidebar/index.js +1 -0
- package/dist/organisms/Topbar/Topbar.d.ts +24 -0
- package/dist/organisms/Topbar/Topbar.js +18 -0
- package/dist/organisms/Topbar/index.d.ts +1 -0
- package/dist/organisms/Topbar/index.js +1 -0
- package/dist/organisms/index.d.ts +11 -0
- package/dist/organisms/index.js +11 -0
- package/dist/strings.d.ts +108 -15
- package/dist/strings.js +73 -7
- package/dist/templates/AdminLayout/AdminLayout.d.ts +14 -0
- package/dist/templates/AdminLayout/AdminLayout.js +9 -0
- package/dist/templates/AdminLayout/index.d.ts +1 -0
- package/dist/templates/AdminLayout/index.js +1 -0
- package/dist/templates/AuthLayout/AuthLayout.d.ts +28 -0
- package/dist/templates/AuthLayout/AuthLayout.js +11 -0
- package/dist/templates/AuthLayout/index.d.ts +1 -0
- package/dist/templates/AuthLayout/index.js +1 -0
- package/dist/templates/DashboardPage/DashboardPage.d.ts +25 -0
- package/dist/templates/DashboardPage/DashboardPage.js +12 -0
- package/dist/templates/DashboardPage/index.d.ts +1 -0
- package/dist/templates/DashboardPage/index.js +1 -0
- package/dist/templates/DetailPage/DetailPage.d.ts +20 -0
- package/dist/templates/DetailPage/DetailPage.js +11 -0
- package/dist/templates/DetailPage/index.d.ts +1 -0
- package/dist/templates/DetailPage/index.js +1 -0
- package/dist/templates/FormPage/FormPage.d.ts +26 -0
- package/dist/templates/FormPage/FormPage.js +11 -0
- package/dist/templates/FormPage/index.d.ts +1 -0
- package/dist/templates/FormPage/index.js +1 -0
- package/dist/templates/ListPage/ListPage.d.ts +17 -0
- package/dist/templates/ListPage/ListPage.js +8 -0
- package/dist/templates/ListPage/index.d.ts +1 -0
- package/dist/templates/ListPage/index.js +1 -0
- package/dist/templates/SettingsPage/SettingsPage.d.ts +32 -0
- package/dist/templates/SettingsPage/SettingsPage.js +13 -0
- package/dist/templates/SettingsPage/index.d.ts +1 -0
- package/dist/templates/SettingsPage/index.js +1 -0
- package/dist/templates/StatusPage/StatusPage.d.ts +18 -0
- package/dist/templates/StatusPage/StatusPage.js +8 -0
- package/dist/templates/StatusPage/index.d.ts +1 -0
- package/dist/templates/StatusPage/index.js +1 -0
- package/dist/templates/index.d.ts +8 -0
- package/dist/templates/index.js +8 -0
- package/dist/utils/dates.d.ts +67 -0
- package/dist/utils/dates.js +154 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/theme.d.ts +4 -0
- package/dist/utils/theme.js +7 -3
- package/package.json +4 -1
- package/tokens.css +513 -21
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type Breakpoint } from '../../hooks/breakpoints.js';
|
|
3
|
+
import { type NavItemProps } from '../../molecules/NavItem/NavItem.js';
|
|
4
|
+
export interface SidebarSection {
|
|
5
|
+
/** React key. Defaults to the label, then the index. */
|
|
6
|
+
id?: string;
|
|
7
|
+
/** A small heading over the section. Hidden (still read out) while collapsed. */
|
|
8
|
+
label?: string;
|
|
9
|
+
items: NavItemProps[];
|
|
10
|
+
}
|
|
11
|
+
export interface SidebarProps {
|
|
12
|
+
/** Top slot: a logo or workspace switcher. */
|
|
13
|
+
header?: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* What the header shows while the sidebar is an icon rail: a logo mark rather than the full
|
|
16
|
+
* wordmark, which would wrap in 64px. Default: `header`.
|
|
17
|
+
*/
|
|
18
|
+
collapsedHeader?: ReactNode;
|
|
19
|
+
sections: SidebarSection[];
|
|
20
|
+
/** Bottom slot, above the collapse toggle: help links, a user menu. */
|
|
21
|
+
footer?: ReactNode;
|
|
22
|
+
/** Controlled icon-rail state on wide screens. */
|
|
23
|
+
collapsed?: boolean;
|
|
24
|
+
defaultCollapsed?: boolean;
|
|
25
|
+
onCollapsedChange?: (collapsed: boolean) => void;
|
|
26
|
+
/** Shows the collapse toggle. Default `true`. */
|
|
27
|
+
collapsible?: boolean;
|
|
28
|
+
/** Overrides the landmark's name (otherwise the `mainNavigation` UI string). */
|
|
29
|
+
'aria-label'?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Outside an AppShell: the breakpoint from which the sidebar is persistent (default `md`), and
|
|
32
|
+
* the off-canvas panel's open state below it. Inside one, the shell provides all three.
|
|
33
|
+
*/
|
|
34
|
+
breakpoint?: Breakpoint;
|
|
35
|
+
open?: boolean;
|
|
36
|
+
onOpenChange?: (open: boolean) => void;
|
|
37
|
+
/** Where the off-canvas panel portals. Default: the nearest `<Theme>`. */
|
|
38
|
+
container?: HTMLElement | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The main navigation. From `breakpoint` up it is a persistent column that can collapse to an
|
|
42
|
+
* icon rail; below it, an off-canvas panel from the start edge with a scrim, a focus trap and
|
|
43
|
+
* Escape, which closes again when an item is chosen.
|
|
44
|
+
*
|
|
45
|
+
* Inside an `AppShell`, the shell decides which and the Topbar's menu button opens the panel.
|
|
46
|
+
* Without matchMedia (on the server) it renders the persistent column.
|
|
47
|
+
*/
|
|
48
|
+
export declare function Sidebar({ header, collapsedHeader, sections, footer, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, collapsible, 'aria-label': ariaLabel, breakpoint, open, onOpenChange, container, }: SidebarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import * as RadixDialog from '@radix-ui/react-dialog';
|
|
3
|
+
import { Cross1Icon, DoubleArrowLeftIcon, DoubleArrowRightIcon } from '@radix-ui/react-icons';
|
|
4
|
+
import { Theme } from '@radix-ui/themes';
|
|
5
|
+
import { useId, useState } from 'react';
|
|
6
|
+
import { Tooltip } from '../../atoms/Tooltip/Tooltip.js';
|
|
7
|
+
import { minWidth } from '../../hooks/breakpoints.js';
|
|
8
|
+
import { useControllableState } from '../../hooks/useControllableState.js';
|
|
9
|
+
import { useMediaQuery } from '../../hooks/useMediaQuery.js';
|
|
10
|
+
import { NavContext } from '../../molecules/NavItem/context.js';
|
|
11
|
+
import { NavItem } from '../../molecules/NavItem/NavItem.js';
|
|
12
|
+
import { useUiStrings } from '../../strings.js';
|
|
13
|
+
import { useThemePortalTarget } from '../../utils/themePortal.js';
|
|
14
|
+
import { useShell } from '../AppShell/context.js';
|
|
15
|
+
function Sections({ sections, label, id, }) {
|
|
16
|
+
return (_jsx("nav", { id: id, "aria-label": label, className: "ui-sidebar__nav", children: sections.map((section, i) => {
|
|
17
|
+
const headingId = `${id}-s${i}`;
|
|
18
|
+
return (_jsxs("div", { className: "ui-sidebar__section", children: [section.label ? (_jsx("h2", { id: headingId, className: "ui-sidebar__section-label", children: section.label })) : null, _jsx("ul", { className: "ui-sidebar__list", "aria-labelledby": section.label ? headingId : undefined, children: section.items.map((item) => (_jsx(NavItem, { ...item }, item.id ?? item.label))) })] }, section.id ?? section.label ?? i));
|
|
19
|
+
}) }));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The main navigation. From `breakpoint` up it is a persistent column that can collapse to an
|
|
23
|
+
* icon rail; below it, an off-canvas panel from the start edge with a scrim, a focus trap and
|
|
24
|
+
* Escape, which closes again when an item is chosen.
|
|
25
|
+
*
|
|
26
|
+
* Inside an `AppShell`, the shell decides which and the Topbar's menu button opens the panel.
|
|
27
|
+
* Without matchMedia (on the server) it renders the persistent column.
|
|
28
|
+
*/
|
|
29
|
+
export function Sidebar({ header, collapsedHeader, sections, footer, collapsed: collapsedProp, defaultCollapsed = false, onCollapsedChange, collapsible = true, 'aria-label': ariaLabel, breakpoint = 'md', open, onOpenChange, container, }) {
|
|
30
|
+
const strings = useUiStrings();
|
|
31
|
+
const shell = useShell();
|
|
32
|
+
const ownWide = useMediaQuery(minWidth(shell?.breakpoint ?? breakpoint));
|
|
33
|
+
const [ownOpen, setOwnOpen] = useState(false);
|
|
34
|
+
const [collapsed, setCollapsed] = useControllableState({
|
|
35
|
+
value: collapsedProp,
|
|
36
|
+
defaultValue: defaultCollapsed,
|
|
37
|
+
onChange: onCollapsedChange,
|
|
38
|
+
});
|
|
39
|
+
const { anchorRef, target, resolved } = useThemePortalTarget(container);
|
|
40
|
+
const navId = useId();
|
|
41
|
+
const wide = shell ? shell.wide : ownWide;
|
|
42
|
+
const panelOpen = shell ? shell.navOpen : (open ?? ownOpen);
|
|
43
|
+
const setPanelOpen = (next) => {
|
|
44
|
+
if (shell)
|
|
45
|
+
shell.setNavOpen(next);
|
|
46
|
+
else if (open === undefined)
|
|
47
|
+
setOwnOpen(next);
|
|
48
|
+
onOpenChange?.(next);
|
|
49
|
+
};
|
|
50
|
+
const label = ariaLabel ?? strings.mainNavigation;
|
|
51
|
+
if (wide) {
|
|
52
|
+
const toggleLabel = collapsed ? strings.expandSidebar : strings.collapseSidebar;
|
|
53
|
+
const railHeader = collapsed ? (collapsedHeader ?? header) : header;
|
|
54
|
+
return (_jsxs("div", { className: "ui-sidebar", "data-collapsed": collapsed ? '' : undefined, children: [railHeader ? _jsx("div", { className: "ui-sidebar__header", children: railHeader }) : null, _jsx(NavContext.Provider, { value: { collapsed }, children: _jsx(Sections, { sections: sections, label: label, id: navId }) }), footer || collapsible ? (_jsxs("div", { className: "ui-sidebar__footer", children: [footer, collapsible ? (_jsx(Tooltip, { label: collapsed ? toggleLabel : undefined, children: _jsxs("button", { type: "button", className: "ui-nav-item", "aria-expanded": !collapsed, "aria-controls": navId, onClick: () => setCollapsed(!collapsed), children: [_jsx("span", { className: "ui-nav-item__icon", "aria-hidden": "true", children: collapsed ? _jsx(DoubleArrowRightIcon, {}) : _jsx(DoubleArrowLeftIcon, {}) }), _jsx("span", { className: "ui-nav-item__label", children: toggleLabel })] }) })) : null] })) : null] }));
|
|
55
|
+
}
|
|
56
|
+
const panel = (_jsxs(_Fragment, { children: [_jsx(RadixDialog.Overlay, { className: "ui-sidebar-overlay" }), _jsxs(RadixDialog.Content, { className: "ui-sidebar-panel", "aria-describedby": undefined, children: [_jsx(RadixDialog.Title, { className: "ui-sr-only", children: label }), _jsxs("div", { className: "ui-sidebar__header", children: [_jsx("div", { className: "min-w-0 flex-1", children: header }), _jsxs(RadixDialog.Close, { className: "ui-nav-item ui-sidebar__close", children: [_jsx("span", { className: "ui-nav-item__icon", "aria-hidden": "true", children: _jsx(Cross1Icon, {}) }), _jsx("span", { className: "ui-sr-only", children: strings.closeNavigation })] })] }), _jsx(NavContext.Provider, { value: { collapsed: false, onNavigate: () => setPanelOpen(false) }, children: _jsx(Sections, { sections: sections, label: label, id: navId }) }), footer ? _jsx("div", { className: "ui-sidebar__footer", children: footer }) : null] })] }));
|
|
57
|
+
const anchor = _jsx("span", { ref: anchorRef, hidden: true });
|
|
58
|
+
if (!resolved)
|
|
59
|
+
return anchor;
|
|
60
|
+
return (_jsxs(RadixDialog.Root, { open: panelOpen, onOpenChange: setPanelOpen, children: [anchor, _jsx(RadixDialog.Portal, { container: target ?? undefined, children: target ? _jsx(Theme, { hasBackground: false, children: panel }) : panel })] }));
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Sidebar.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Sidebar.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface TopbarProps {
|
|
3
|
+
/** Before the title: breadcrumbs, a logo on narrow screens. */
|
|
4
|
+
leading?: ReactNode;
|
|
5
|
+
/** A short page or app title. Not a heading: the page's `h1` belongs to PageHeader. */
|
|
6
|
+
title?: ReactNode;
|
|
7
|
+
/** A search field. Sits between title and actions from 768px; on its own row below that. */
|
|
8
|
+
search?: ReactNode;
|
|
9
|
+
/** Icon buttons, a notification bell, a UserMenu. */
|
|
10
|
+
actions?: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* The button that opens the off-canvas Sidebar. Default: shown inside an AppShell whenever
|
|
13
|
+
* the sidebar is off-canvas. Pass `false` to hide it, or `true` with `onMenuClick` outside one.
|
|
14
|
+
*/
|
|
15
|
+
showMenuButton?: boolean;
|
|
16
|
+
onMenuClick?: () => void;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The bar across the top of the content column: a `header` landmark, sticky, on the bar
|
|
21
|
+
* material. Narrow screens get the menu button that opens the Sidebar, and the search moves to
|
|
22
|
+
* a second row so neither it nor the title is squeezed.
|
|
23
|
+
*/
|
|
24
|
+
export declare function Topbar({ leading, title, search, actions, showMenuButton, onMenuClick, className, }: TopbarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { HamburgerMenuIcon } from '@radix-ui/react-icons';
|
|
3
|
+
import { useUiStrings } from '../../strings.js';
|
|
4
|
+
import { useShell } from '../AppShell/context.js';
|
|
5
|
+
/**
|
|
6
|
+
* The bar across the top of the content column: a `header` landmark, sticky, on the bar
|
|
7
|
+
* material. Narrow screens get the menu button that opens the Sidebar, and the search moves to
|
|
8
|
+
* a second row so neither it nor the title is squeezed.
|
|
9
|
+
*/
|
|
10
|
+
export function Topbar({ leading, title, search, actions, showMenuButton, onMenuClick, className, }) {
|
|
11
|
+
const strings = useUiStrings();
|
|
12
|
+
const shell = useShell();
|
|
13
|
+
const menu = showMenuButton ?? (shell ? !shell.wide : false);
|
|
14
|
+
return (_jsxs("header", { className: ['ui-topbar', className].filter(Boolean).join(' '), children: [_jsxs("div", { className: "ui-topbar__lead", children: [menu ? (_jsx("button", { type: "button", className: "ui-nav-item ui-topbar__menu", "aria-label": strings.openNavigation, "aria-expanded": shell?.navOpen ?? false, onClick: () => {
|
|
15
|
+
shell?.setNavOpen(true);
|
|
16
|
+
onMenuClick?.();
|
|
17
|
+
}, children: _jsx("span", { className: "ui-nav-item__icon", "aria-hidden": "true", children: _jsx(HamburgerMenuIcon, {}) }) })) : null, leading] }), title ? _jsx("div", { className: "ui-topbar__title", children: title }) : _jsx("div", {}), search ? _jsx("div", { className: "ui-topbar__search", children: search }) : null, actions ? _jsx("div", { className: "ui-topbar__actions", children: actions }) : null] }));
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Topbar.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Topbar.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './AppShell/index.js';
|
|
2
|
+
export * from './AuthForms/index.js';
|
|
3
|
+
export * from './BulkActionBar/index.js';
|
|
4
|
+
export * from './Chart/index.js';
|
|
5
|
+
export * from './DataTable/index.js';
|
|
6
|
+
export * from './DateRangePicker/index.js';
|
|
7
|
+
export * from './FilterBar/index.js';
|
|
8
|
+
export * from './PageHeader/index.js';
|
|
9
|
+
export * from './PageTabs/index.js';
|
|
10
|
+
export * from './Sidebar/index.js';
|
|
11
|
+
export * from './Topbar/index.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './AppShell/index.js';
|
|
2
|
+
export * from './AuthForms/index.js';
|
|
3
|
+
export * from './BulkActionBar/index.js';
|
|
4
|
+
export * from './Chart/index.js';
|
|
5
|
+
export * from './DataTable/index.js';
|
|
6
|
+
export * from './DateRangePicker/index.js';
|
|
7
|
+
export * from './FilterBar/index.js';
|
|
8
|
+
export * from './PageHeader/index.js';
|
|
9
|
+
export * from './PageTabs/index.js';
|
|
10
|
+
export * from './Sidebar/index.js';
|
|
11
|
+
export * from './Topbar/index.js';
|
package/dist/strings.d.ts
CHANGED
|
@@ -2,16 +2,16 @@ import { type ReactNode } from 'react';
|
|
|
2
2
|
/**
|
|
3
3
|
* The handful of strings the atoms say on their own behalf.
|
|
4
4
|
*
|
|
5
|
-
* **The dictionaries stay in the apps, deliberately
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* placeholder has to say something in the trigger.
|
|
5
|
+
* **The dictionaries stay in the apps, deliberately.** A shared dictionary would make every
|
|
6
|
+
* string in every consuming app this library's business. But some components do have
|
|
7
|
+
* something to say without being told: a standing `Spinner` has to announce that a wait is in
|
|
8
|
+
* progress, and a `Select` with no placeholder has to say something in the trigger.
|
|
10
9
|
*
|
|
11
|
-
* So the package declares what it needs and the host supplies it.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* So the package declares what it needs and the host supplies it. The defaults are English, so
|
|
11
|
+
* an app that forgets to wrap gets something legible, and no translation lives in the package.
|
|
12
|
+
*
|
|
13
|
+
* Anything that carries a value is a function, not a template string, so a language can put
|
|
14
|
+
* the number where its grammar wants it ("3 selected", "3 seleccionados").
|
|
15
15
|
*/
|
|
16
16
|
export interface UiStrings {
|
|
17
17
|
/** Announced by a standing spinner. */
|
|
@@ -46,22 +46,115 @@ export interface UiStrings {
|
|
|
46
46
|
refreshing: string;
|
|
47
47
|
/** ScrollStrip: the accessible name of the scrollable region, when none is passed. */
|
|
48
48
|
scrollableRegion: string;
|
|
49
|
+
/** AppShell: the skip link that jumps past the navigation to the main content. */
|
|
50
|
+
skipToContent: string;
|
|
51
|
+
/** Sidebar: the navigation landmark's name. */
|
|
52
|
+
mainNavigation: string;
|
|
53
|
+
/** Topbar: the button that opens the navigation on small screens. */
|
|
54
|
+
openNavigation: string;
|
|
55
|
+
/** Sidebar: the close button of the navigation panel on small screens. */
|
|
56
|
+
closeNavigation: string;
|
|
57
|
+
/** Sidebar: the collapse toggle, while expanded. */
|
|
58
|
+
collapseSidebar: string;
|
|
59
|
+
/** Sidebar: the collapse toggle, while collapsed. */
|
|
60
|
+
expandSidebar: string;
|
|
61
|
+
/** Breadcrumbs: the landmark's name. */
|
|
62
|
+
breadcrumbs: string;
|
|
63
|
+
/** Breadcrumbs: the menu that holds the collapsed middle items. */
|
|
64
|
+
showMoreBreadcrumbs: string;
|
|
65
|
+
/** Link: appended, visually hidden, to links that open a new tab. */
|
|
66
|
+
opensInNewTab: string;
|
|
67
|
+
/** UserMenu: the trigger's name when the name itself is hidden. */
|
|
68
|
+
userMenu: string;
|
|
69
|
+
/** ThemeToggle: the group's name and its three options. */
|
|
70
|
+
appearance: string;
|
|
71
|
+
light: string;
|
|
72
|
+
dark: string;
|
|
73
|
+
system: string;
|
|
74
|
+
/** AccentPicker: the group's name. */
|
|
75
|
+
accent: string;
|
|
76
|
+
/** Pill: the remove button's name. */
|
|
77
|
+
remove: (label: string) => string;
|
|
78
|
+
/** EmptyState default inside DataTable when there are no rows. */
|
|
79
|
+
noResults: string;
|
|
80
|
+
/** ErrorState: the default title, the retry button, and the disclosure for details. */
|
|
81
|
+
somethingWentWrong: string;
|
|
82
|
+
retry: string;
|
|
83
|
+
showDetails: string;
|
|
84
|
+
/** Pagination: the landmark's name, the two step buttons, and the page-size label. */
|
|
85
|
+
pagination: string;
|
|
86
|
+
previousPage: string;
|
|
87
|
+
nextPage: string;
|
|
88
|
+
rowsPerPage: string;
|
|
89
|
+
/** Pagination: one page button's name. */
|
|
90
|
+
goToPage: (page: number) => string;
|
|
91
|
+
/** Pagination: the compact "page of" text. */
|
|
92
|
+
pageOf: (page: number, pageCount: number) => string;
|
|
93
|
+
/** Pagination: which rows are showing, e.g. "1–25 of 500". */
|
|
94
|
+
rangeOf: (from: number, to: number, total: number) => string;
|
|
95
|
+
/** DataTable: the header checkbox, and each row's. */
|
|
96
|
+
selectAll: string;
|
|
97
|
+
selectRow: (row: string) => string;
|
|
98
|
+
/** DataTable: the row-actions menu button's name. */
|
|
99
|
+
actionsFor: (row: string) => string;
|
|
100
|
+
/** BulkActionBar: the toolbar's name, the selection count, and the clear button. */
|
|
101
|
+
bulkActions: string;
|
|
102
|
+
selectedCount: (count: number) => string;
|
|
103
|
+
clearSelection: string;
|
|
104
|
+
/** SearchField: its accessible name when none is given, and the clear button. */
|
|
105
|
+
search: string;
|
|
106
|
+
clearSearch: string;
|
|
107
|
+
/** FilterPopover: the trigger's default label, and its footer. FilterBar: the clear-all. */
|
|
108
|
+
filters: string;
|
|
109
|
+
apply: string;
|
|
110
|
+
reset: string;
|
|
111
|
+
clearFilters: string;
|
|
112
|
+
/** FilterBar: names the group of active-filter pills. */
|
|
113
|
+
activeFilters: string;
|
|
114
|
+
/** FilterPopover: appended to the trigger's name when filters are active. */
|
|
115
|
+
activeCount: (count: number) => string;
|
|
116
|
+
/** ErrorSummary: its heading. */
|
|
117
|
+
fixErrors: (count: number) => string;
|
|
118
|
+
/** Calendar: the month step buttons. */
|
|
119
|
+
previousMonth: string;
|
|
120
|
+
nextMonth: string;
|
|
121
|
+
/** DateInput / DateRangePicker: the trigger text while nothing is chosen. */
|
|
122
|
+
chooseDate: string;
|
|
123
|
+
chooseDates: string;
|
|
124
|
+
/** DateRangePicker: names the list of preset ranges. */
|
|
125
|
+
datePresets: string;
|
|
126
|
+
/** ChartFrame: the toggle between the chart and its data table. */
|
|
127
|
+
viewAsTable: string;
|
|
128
|
+
viewAsChart: string;
|
|
129
|
+
/** PasswordInput: the visibility toggle's name. It is a toggle (`aria-pressed`), so one name. */
|
|
130
|
+
showPassword: string;
|
|
49
131
|
}
|
|
50
132
|
/**
|
|
51
|
-
* Feeds the
|
|
133
|
+
* Feeds the components their strings, once, near the root.
|
|
52
134
|
*
|
|
53
135
|
* Every app wraps its tree in this and passes its own dictionary's words through. It takes a
|
|
54
136
|
* partial so an app that only cares about one of them says only that.
|
|
137
|
+
*
|
|
138
|
+
* `locale` is the BCP 47 tag that dates, numbers and money are formatted in (through `Intl`).
|
|
139
|
+
* Formatting rather than translating: "21 de setembro" comes from the locale, not from a
|
|
140
|
+
* string. Left out, it inherits from an outer provider, and with none the runtime's default.
|
|
55
141
|
*/
|
|
56
|
-
export declare function UiStringsProvider({ strings, children, }: {
|
|
142
|
+
export declare function UiStringsProvider({ strings, locale, children, }: {
|
|
57
143
|
strings: Partial<UiStrings>;
|
|
144
|
+
locale?: string;
|
|
58
145
|
children: ReactNode;
|
|
59
146
|
}): import("react").JSX.Element;
|
|
60
147
|
/**
|
|
61
|
-
* No error when there is no provider
|
|
148
|
+
* No error when there is no provider.
|
|
62
149
|
*
|
|
63
|
-
* A
|
|
64
|
-
*
|
|
65
|
-
* throw in a component as ordinary as a spinner.
|
|
150
|
+
* A host that did not need to override anything is a legitimate way to use this package, and
|
|
151
|
+
* a component as ordinary as a spinner must not throw because of it.
|
|
66
152
|
*/
|
|
67
153
|
export declare function useUiStrings(): UiStrings;
|
|
154
|
+
/**
|
|
155
|
+
* The locale passed to the nearest `UiStringsProvider`, for `Intl` formatters.
|
|
156
|
+
*
|
|
157
|
+
* `undefined` means "the runtime's default", which is what `Intl` already does with
|
|
158
|
+
* `undefined`, so the value can be passed straight through.
|
|
159
|
+
*/
|
|
160
|
+
export declare function useUiLocale(): string | undefined;
|
package/dist/strings.js
CHANGED
|
@@ -20,24 +20,90 @@ const DEFAULTS = {
|
|
|
20
20
|
back: 'Back',
|
|
21
21
|
refreshing: 'Refreshing',
|
|
22
22
|
scrollableRegion: 'Scrollable content',
|
|
23
|
+
skipToContent: 'Skip to content',
|
|
24
|
+
mainNavigation: 'Main navigation',
|
|
25
|
+
openNavigation: 'Open navigation',
|
|
26
|
+
closeNavigation: 'Close navigation',
|
|
27
|
+
collapseSidebar: 'Collapse sidebar',
|
|
28
|
+
expandSidebar: 'Expand sidebar',
|
|
29
|
+
breadcrumbs: 'Breadcrumbs',
|
|
30
|
+
showMoreBreadcrumbs: 'Show hidden breadcrumbs',
|
|
31
|
+
opensInNewTab: '(opens in a new tab)',
|
|
32
|
+
userMenu: 'Account menu',
|
|
33
|
+
appearance: 'Appearance',
|
|
34
|
+
light: 'Light',
|
|
35
|
+
dark: 'Dark',
|
|
36
|
+
system: 'System',
|
|
37
|
+
accent: 'Accent colour',
|
|
38
|
+
remove: (label) => `Remove ${label}`,
|
|
39
|
+
noResults: 'No results',
|
|
40
|
+
somethingWentWrong: 'Something went wrong',
|
|
41
|
+
retry: 'Try again',
|
|
42
|
+
showDetails: 'Details',
|
|
43
|
+
pagination: 'Pagination',
|
|
44
|
+
previousPage: 'Previous page',
|
|
45
|
+
nextPage: 'Next page',
|
|
46
|
+
rowsPerPage: 'Rows per page',
|
|
47
|
+
goToPage: (page) => `Page ${page}`,
|
|
48
|
+
pageOf: (page, pageCount) => `Page ${page} of ${pageCount}`,
|
|
49
|
+
rangeOf: (from, to, total) => `${from}–${to} of ${total}`,
|
|
50
|
+
selectAll: 'Select all rows',
|
|
51
|
+
selectRow: (row) => `Select ${row}`,
|
|
52
|
+
actionsFor: (row) => `Actions for ${row}`,
|
|
53
|
+
bulkActions: 'Bulk actions',
|
|
54
|
+
selectedCount: (count) => `${count} selected`,
|
|
55
|
+
clearSelection: 'Clear selection',
|
|
56
|
+
search: 'Search',
|
|
57
|
+
clearSearch: 'Clear search',
|
|
58
|
+
filters: 'Filters',
|
|
59
|
+
apply: 'Apply',
|
|
60
|
+
reset: 'Reset',
|
|
61
|
+
clearFilters: 'Clear all',
|
|
62
|
+
activeFilters: 'Active filters',
|
|
63
|
+
activeCount: (count) => `${count} active`,
|
|
64
|
+
fixErrors: (count) => count === 1
|
|
65
|
+
? 'There is 1 problem with this form'
|
|
66
|
+
: `There are ${count} problems with this form`,
|
|
67
|
+
previousMonth: 'Previous month',
|
|
68
|
+
nextMonth: 'Next month',
|
|
69
|
+
chooseDate: 'Choose a date',
|
|
70
|
+
chooseDates: 'Choose dates',
|
|
71
|
+
datePresets: 'Quick ranges',
|
|
72
|
+
viewAsTable: 'View as table',
|
|
73
|
+
viewAsChart: 'View as chart',
|
|
74
|
+
showPassword: 'Show password',
|
|
23
75
|
};
|
|
24
76
|
const StringsContext = createContext(DEFAULTS);
|
|
77
|
+
const LocaleContext = createContext(undefined);
|
|
25
78
|
/**
|
|
26
|
-
* Feeds the
|
|
79
|
+
* Feeds the components their strings, once, near the root.
|
|
27
80
|
*
|
|
28
81
|
* Every app wraps its tree in this and passes its own dictionary's words through. It takes a
|
|
29
82
|
* partial so an app that only cares about one of them says only that.
|
|
83
|
+
*
|
|
84
|
+
* `locale` is the BCP 47 tag that dates, numbers and money are formatted in (through `Intl`).
|
|
85
|
+
* Formatting rather than translating: "21 de setembro" comes from the locale, not from a
|
|
86
|
+
* string. Left out, it inherits from an outer provider, and with none the runtime's default.
|
|
30
87
|
*/
|
|
31
|
-
export function UiStringsProvider({ strings, children, }) {
|
|
32
|
-
|
|
88
|
+
export function UiStringsProvider({ strings, locale, children, }) {
|
|
89
|
+
const outerLocale = useContext(LocaleContext);
|
|
90
|
+
return (_jsx(LocaleContext.Provider, { value: locale ?? outerLocale, children: _jsx(StringsContext.Provider, { value: { ...DEFAULTS, ...strings }, children: children }) }));
|
|
33
91
|
}
|
|
34
92
|
/**
|
|
35
|
-
* No error when there is no provider
|
|
93
|
+
* No error when there is no provider.
|
|
36
94
|
*
|
|
37
|
-
* A
|
|
38
|
-
*
|
|
39
|
-
* throw in a component as ordinary as a spinner.
|
|
95
|
+
* A host that did not need to override anything is a legitimate way to use this package, and
|
|
96
|
+
* a component as ordinary as a spinner must not throw because of it.
|
|
40
97
|
*/
|
|
41
98
|
export function useUiStrings() {
|
|
42
99
|
return useContext(StringsContext);
|
|
43
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* The locale passed to the nearest `UiStringsProvider`, for `Intl` formatters.
|
|
103
|
+
*
|
|
104
|
+
* `undefined` means "the runtime's default", which is what `Intl` already does with
|
|
105
|
+
* `undefined`, so the value can be passed straight through.
|
|
106
|
+
*/
|
|
107
|
+
export function useUiLocale() {
|
|
108
|
+
return useContext(LocaleContext);
|
|
109
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type AppShellProps } from '../../organisms/AppShell/AppShell.js';
|
|
3
|
+
export interface AdminLayoutProps extends Omit<AppShellProps, 'children'> {
|
|
4
|
+
/** A `PageHeader`, above the content and inside the same width. */
|
|
5
|
+
header?: ReactNode;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
/** `default` caps the content at `--content-max-width`; `full` uses the whole column. */
|
|
8
|
+
width?: 'default' | 'full';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* An AppShell with a page inside it: the header and content share one centred column, padded
|
|
12
|
+
* by `--page-gutter`. A slot layout only; routing, data and auth belong to the app.
|
|
13
|
+
*/
|
|
14
|
+
export declare function AdminLayout({ header, children, width, ...shell }: AdminLayoutProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AppShell } from '../../organisms/AppShell/AppShell.js';
|
|
3
|
+
/**
|
|
4
|
+
* An AppShell with a page inside it: the header and content share one centred column, padded
|
|
5
|
+
* by `--page-gutter`. A slot layout only; routing, data and auth belong to the app.
|
|
6
|
+
*/
|
|
7
|
+
export function AdminLayout({ header, children, width = 'default', ...shell }) {
|
|
8
|
+
return (_jsx(AppShell, { ...shell, children: _jsxs("div", { className: "ui-admin-content", "data-width": width, children: [header, children] }) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AdminLayout.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AdminLayout.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface AuthLayoutProps {
|
|
3
|
+
/** A logo, above the title. */
|
|
4
|
+
brand?: ReactNode;
|
|
5
|
+
/** The page's `h1`: "Sign in", "Create your account". */
|
|
6
|
+
title: ReactNode;
|
|
7
|
+
description?: ReactNode;
|
|
8
|
+
/** One of the auth forms, or your own. */
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
/** Under the card: links to the other auth pages, legal text. */
|
|
11
|
+
footer?: ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* A panel beside the card from 1024px: a product image, a quote. Decorative from a reader's
|
|
14
|
+
* point of view, so keep anything essential in the card. Hidden on smaller screens.
|
|
15
|
+
*/
|
|
16
|
+
aside?: ReactNode;
|
|
17
|
+
/** Top corner controls: a ThemeToggle, a language switch. */
|
|
18
|
+
toolbar?: ReactNode;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The frame for sign-in, sign-up and password pages, outside the app shell.
|
|
23
|
+
*
|
|
24
|
+
* A centred card on a canvas; from 1024px, an optional panel beside it. Below 520px the card
|
|
25
|
+
* loses its border and fills the screen, because a card inside a phone's edges only wastes
|
|
26
|
+
* width. The whole page is the `main` landmark, with the title as its `h1`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function AuthLayout({ brand, title, description, children, footer, aside, toolbar, className, }: AuthLayoutProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The frame for sign-in, sign-up and password pages, outside the app shell.
|
|
4
|
+
*
|
|
5
|
+
* A centred card on a canvas; from 1024px, an optional panel beside it. Below 520px the card
|
|
6
|
+
* loses its border and fills the screen, because a card inside a phone's edges only wastes
|
|
7
|
+
* width. The whole page is the `main` landmark, with the title as its `h1`.
|
|
8
|
+
*/
|
|
9
|
+
export function AuthLayout({ brand, title, description, children, footer, aside, toolbar, className, }) {
|
|
10
|
+
return (_jsxs("div", { className: ['ui-auth', className].filter(Boolean).join(' '), "data-has-aside": aside ? '' : undefined, children: [aside ? _jsx("div", { className: "ui-auth__aside", children: aside }) : null, _jsxs("main", { className: "ui-auth__main", children: [toolbar ? _jsx("div", { className: "ui-auth__toolbar", children: toolbar }) : null, _jsxs("div", { className: "ui-auth__card", children: [brand ? _jsx("div", { className: "ui-auth__brand", children: brand }) : null, _jsx("h1", { className: "ui-auth__title", children: title }), description ? _jsx("p", { className: "ui-auth__description", children: description }) : null, children] }), footer ? _jsx("div", { className: "ui-auth__footer", children: footer }) : null] })] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AuthLayout.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AuthLayout.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface DashboardPageProps {
|
|
3
|
+
/** A PageHeader. */
|
|
4
|
+
header?: ReactNode;
|
|
5
|
+
/** A StatGroup. */
|
|
6
|
+
stats?: ReactNode;
|
|
7
|
+
/** Widgets: ChartFrames, Cards, tables. Wrap one in `DashboardWidget` to make it wider. */
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
/** The most columns at full width. Default 3. */
|
|
10
|
+
columns?: 2 | 3 | 4;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A page of widgets. The grid follows the page's own width (a container query): one column
|
|
15
|
+
* below 640px, two from there, and `columns` from 1024px.
|
|
16
|
+
*/
|
|
17
|
+
export declare function DashboardPage({ header, stats, children, columns, className, }: DashboardPageProps): import("react").JSX.Element;
|
|
18
|
+
export interface DashboardWidgetProps {
|
|
19
|
+
/** Columns to span once there is more than one. `full` spans the row. Default 1. */
|
|
20
|
+
span?: 1 | 2 | 'full';
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
/** A grid cell in DashboardPage that spans more than one column on wide pages. */
|
|
25
|
+
export declare function DashboardWidget({ span, children, className }: DashboardWidgetProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* A page of widgets. The grid follows the page's own width (a container query): one column
|
|
4
|
+
* below 640px, two from there, and `columns` from 1024px.
|
|
5
|
+
*/
|
|
6
|
+
export function DashboardPage({ header, stats, children, columns = 3, className, }) {
|
|
7
|
+
return (_jsxs("div", { className: ['ui-dashboard ui-list-page', className].filter(Boolean).join(' '), children: [header, stats, _jsx("div", { className: "ui-dashboard__grid", "data-columns": columns, children: children })] }));
|
|
8
|
+
}
|
|
9
|
+
/** A grid cell in DashboardPage that spans more than one column on wide pages. */
|
|
10
|
+
export function DashboardWidget({ span = 1, children, className }) {
|
|
11
|
+
return (_jsx("div", { className: ['ui-dashboard__widget', className].filter(Boolean).join(' '), "data-span": span, children: children }));
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DashboardPage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DashboardPage.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface DetailPageProps {
|
|
3
|
+
/** A PageHeader (with PageTabs in its `tabs` slot, usually). */
|
|
4
|
+
header?: ReactNode;
|
|
5
|
+
/** The main content. */
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
/** A side column of facts: a KeyValueList in a Card, say. */
|
|
8
|
+
aside?: ReactNode;
|
|
9
|
+
/** Names the aside's `complementary` landmark. Required with `aside`. */
|
|
10
|
+
asideLabel?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* One record: header, main content and an optional side column.
|
|
15
|
+
*
|
|
16
|
+
* The side column sits beside the main content once the page is 960px wide (a container
|
|
17
|
+
* query, so a narrow panel counts as narrow), and below it otherwise. It comes after the main
|
|
18
|
+
* content in the DOM either way, so reading and tab order match what is primary.
|
|
19
|
+
*/
|
|
20
|
+
export declare function DetailPage({ header, children, aside, asideLabel, className }: DetailPageProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* One record: header, main content and an optional side column.
|
|
4
|
+
*
|
|
5
|
+
* The side column sits beside the main content once the page is 960px wide (a container
|
|
6
|
+
* query, so a narrow panel counts as narrow), and below it otherwise. It comes after the main
|
|
7
|
+
* content in the DOM either way, so reading and tab order match what is primary.
|
|
8
|
+
*/
|
|
9
|
+
export function DetailPage({ header, children, aside, asideLabel, className }) {
|
|
10
|
+
return (_jsxs("div", { className: ['ui-detail-page', className].filter(Boolean).join(' '), children: [header, _jsxs("div", { className: "ui-detail-page__body", "data-has-aside": aside ? '' : undefined, children: [_jsx("div", { className: "min-w-0", children: children }), aside ? _jsx("aside", { "aria-label": asideLabel, children: aside }) : null] })] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DetailPage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DetailPage.js';
|