@apliteni/apliteni-ui 0.49.2 → 0.51.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/package.json +1 -1
- package/react/README.md +25 -1
- package/react/dist/index.css +68 -0
- package/react/dist/index.d.ts +48 -1
- package/react/dist/index.js +184 -0
package/package.json
CHANGED
package/react/README.md
CHANGED
|
@@ -28,7 +28,7 @@ import '@apliteni/apliteni-ui/react/css'; // React components' shell styles (mo
|
|
|
28
28
|
import { DataTable, Modal, Button } from '@apliteni/apliteni-ui/react';
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Components: `DataTable`, `Pagination`, `StatBand`, `Modal`, `Confirm`, `Drawer`, `CommandPalette`, `Dropdown`, `BackLink`, `Snippet`, `Tabs`, `Button`, `Badge`, `Card`, `Callout`, `Icon`.
|
|
31
|
+
Components: `EmptyState`, `DataTable`, `Pagination`, `StatBand`, `Modal`, `Confirm`, `Drawer`, `CommandPalette`, `Dropdown`, `BackLink`, `Snippet`, `Tabs`, `Button`, `Badge`, `Card`, `Callout`, `Icon`.
|
|
32
32
|
|
|
33
33
|
`Snippet` accepts `label`, `code`, `reveal`, and `copyLabel` props. It treats `code`
|
|
34
34
|
as plain text and copies it exactly as provided. After a successful clipboard write,
|
|
@@ -77,6 +77,13 @@ vanilla factory where the steps have to be real links. `PAGE_SIZES` and
|
|
|
77
77
|
either number. They are declared in this package's own types, and `PAGE_SIZES` is a
|
|
78
78
|
`readonly number[]`: pass it to `pageSizes`, but do not add sizes to it.
|
|
79
79
|
|
|
80
|
+
## EmptyState
|
|
81
|
+
|
|
82
|
+
`EmptyState` uses the vanilla layout. `variant` selects `first-run`, `no-matches`,
|
|
83
|
+
`not-found`, or `not-yet-built` copy; `title`, `sub`, and `icon` override it.
|
|
84
|
+
`art` accepts a vanilla illustration name, trusted SVG string, or React node; `actions` accepts React nodes. Use at most one primary action and one ghost
|
|
85
|
+
action. The page supplies its own h1; EmptyState uses vanilla’s div title.
|
|
86
|
+
|
|
80
87
|
## What the Modal does with focus
|
|
81
88
|
|
|
82
89
|
Opening moves focus to the first eligible control in the body, in DOM order, or to
|
|
@@ -433,3 +440,20 @@ function SaveButton() {
|
|
|
433
440
|
|
|
434
441
|
<Toast><SaveButton /></Toast>
|
|
435
442
|
```
|
|
443
|
+
|
|
444
|
+
## AppShell
|
|
445
|
+
|
|
446
|
+
AppShell includes the kit’s rail and top band. Pass the current router pathname so the longest matching section path becomes active. Spread the props from `renderLink` onto your router link. The rail’s folded state is saved in a shared cookie. On phones, the bar shows up to four sections. If there are more, it shows three sections and a More sheet. Provide no more than one primary page action. The palette defaults to section links; pass `palette` to add custom commands. Import both the kit CSS and React CSS.
|
|
447
|
+
|
|
448
|
+
```tsx
|
|
449
|
+
<AppShell
|
|
450
|
+
pathname={location.pathname}
|
|
451
|
+
sections={[{ href: '/reports', label: 'Reports', icon: 'chart' }]}
|
|
452
|
+
title="Reports"
|
|
453
|
+
account={{ name: 'Demo User', email: 'demo@example.com' }}
|
|
454
|
+
onSignOut={signOut}
|
|
455
|
+
renderLink={(section, { href, ...props }) => <Link to={section.href} {...props} />}
|
|
456
|
+
>
|
|
457
|
+
<Reports />
|
|
458
|
+
</AppShell>
|
|
459
|
+
```
|
package/react/dist/index.css
CHANGED
|
@@ -525,3 +525,71 @@
|
|
|
525
525
|
.rx-toast-stack > .ui-toast {
|
|
526
526
|
pointer-events: auto;
|
|
527
527
|
}
|
|
528
|
+
|
|
529
|
+
/* src/AppShell.css */
|
|
530
|
+
.ui-react-app__bottom {
|
|
531
|
+
display: none;
|
|
532
|
+
}
|
|
533
|
+
.ui-react-app__actions {
|
|
534
|
+
display: flex;
|
|
535
|
+
flex-wrap: wrap;
|
|
536
|
+
gap: var(--space-3);
|
|
537
|
+
margin-bottom: var(--space-5);
|
|
538
|
+
}
|
|
539
|
+
.ui-react-app .ui-app__brand .ui-react-app__mark {
|
|
540
|
+
display: inline-flex;
|
|
541
|
+
opacity: 1;
|
|
542
|
+
}
|
|
543
|
+
.ui-react-app__bottom .ui-nav__item {
|
|
544
|
+
min-height: 48px;
|
|
545
|
+
}
|
|
546
|
+
@media (max-width: 560px) {
|
|
547
|
+
.ui-react-app {
|
|
548
|
+
display: block;
|
|
549
|
+
}
|
|
550
|
+
.ui-react-app > .ui-app__rail {
|
|
551
|
+
display: none;
|
|
552
|
+
}
|
|
553
|
+
.ui-react-app .ui-app__main {
|
|
554
|
+
padding-bottom: calc(96px + env(safe-area-inset-bottom));
|
|
555
|
+
}
|
|
556
|
+
.ui-react-app .ui-app__bar {
|
|
557
|
+
padding-inline: var(--space-4);
|
|
558
|
+
}
|
|
559
|
+
.ui-react-app .ui-app__search {
|
|
560
|
+
min-width: 0;
|
|
561
|
+
}
|
|
562
|
+
.ui-react-app .ui-app__search kbd {
|
|
563
|
+
display: none;
|
|
564
|
+
}
|
|
565
|
+
.ui-react-app__bottom {
|
|
566
|
+
display: block;
|
|
567
|
+
position: fixed;
|
|
568
|
+
inset: auto 0 0;
|
|
569
|
+
z-index: var(--z-sticky);
|
|
570
|
+
padding: var(--space-2) var(--space-2) calc(var(--space-2) + env(safe-area-inset-bottom));
|
|
571
|
+
background: var(--bg);
|
|
572
|
+
border-top: 1px solid var(--border);
|
|
573
|
+
}
|
|
574
|
+
.ui-react-app__bottom .ui-nav__list {
|
|
575
|
+
display: flex;
|
|
576
|
+
flex-direction: row;
|
|
577
|
+
}
|
|
578
|
+
.ui-react-app__bottom li {
|
|
579
|
+
flex: 1;
|
|
580
|
+
min-width: 0;
|
|
581
|
+
}
|
|
582
|
+
.ui-react-app__bottom .ui-nav__item {
|
|
583
|
+
justify-content: center;
|
|
584
|
+
flex-direction: column;
|
|
585
|
+
gap: var(--space-1);
|
|
586
|
+
padding-inline: var(--space-1);
|
|
587
|
+
}
|
|
588
|
+
.ui-react-app__bottom .ui-nav__label {
|
|
589
|
+
flex: none;
|
|
590
|
+
font-size: var(--text-xs);
|
|
591
|
+
}
|
|
592
|
+
.ui-react-app__bottom .ui-nav__badge {
|
|
593
|
+
display: none;
|
|
594
|
+
}
|
|
595
|
+
}
|
package/react/dist/index.d.ts
CHANGED
|
@@ -550,7 +550,54 @@ type ToastProps = {
|
|
|
550
550
|
declare function useToast(): (notice: ToastNotice) => void;
|
|
551
551
|
declare function Toast({ children }: ToastProps): react.JSX.Element;
|
|
552
552
|
|
|
553
|
+
type AppShellSection = {
|
|
554
|
+
href: string;
|
|
555
|
+
label: string;
|
|
556
|
+
icon: string;
|
|
557
|
+
count?: number;
|
|
558
|
+
};
|
|
559
|
+
type AppShellProps = {
|
|
560
|
+
sections: AppShellSection[];
|
|
561
|
+
/** Current router pathname; the longest matching section wins. */
|
|
562
|
+
pathname: string;
|
|
563
|
+
title: string;
|
|
564
|
+
children?: ReactNode;
|
|
565
|
+
word?: string;
|
|
566
|
+
brand?: ReactNode;
|
|
567
|
+
brandHref?: string;
|
|
568
|
+
width?: 'centered' | 'wide';
|
|
569
|
+
back?: {
|
|
570
|
+
href: string;
|
|
571
|
+
label: string;
|
|
572
|
+
};
|
|
573
|
+
lede?: string;
|
|
574
|
+
actions?: ReactNode;
|
|
575
|
+
bandControl?: ReactNode;
|
|
576
|
+
account: {
|
|
577
|
+
name: string;
|
|
578
|
+
email: string;
|
|
579
|
+
};
|
|
580
|
+
onSignOut: () => void;
|
|
581
|
+
/** Server-read fold preference. The browser restores the shared rail cookie. */
|
|
582
|
+
defaultCollapsed?: boolean;
|
|
583
|
+
palette?: Omit<CommandPaletteProps, 'open' | 'onClose'>;
|
|
584
|
+
/** Spread linkProps onto the router link, including children and onClick. */
|
|
585
|
+
renderLink?: (section: AppShellSection, linkProps: ComponentPropsWithoutRef<'a'>) => ReactNode;
|
|
586
|
+
};
|
|
587
|
+
declare function AppShell({ sections, pathname, title, children, word, brand, brandHref, width, back, lede, actions, bandControl, account, onSignOut, defaultCollapsed, palette, renderLink }: AppShellProps): react.JSX.Element;
|
|
588
|
+
|
|
589
|
+
type EmptyStateVariant = 'first-run' | 'no-matches' | 'not-found' | 'not-yet-built';
|
|
590
|
+
type EmptyStateProps = {
|
|
591
|
+
variant?: EmptyStateVariant;
|
|
592
|
+
title?: string;
|
|
593
|
+
sub?: string;
|
|
594
|
+
icon?: string;
|
|
595
|
+
art?: ReactNode;
|
|
596
|
+
actions?: ReactNode;
|
|
597
|
+
};
|
|
598
|
+
declare function EmptyState({ variant, title, sub, icon, art, actions }: EmptyStateProps): react.JSX.Element;
|
|
599
|
+
|
|
553
600
|
declare const PAGE_SIZES: readonly number[];
|
|
554
601
|
declare const DEFAULT_PAGE_SIZE: number;
|
|
555
602
|
|
|
556
|
-
export { BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, BusyRegion, type BusyRegionProps, Button, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, RowIdentity, type RowIdentityProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, Timeline, type TimelineEvent, type TimelineProps, Toast, type ToastNotice, type ToastProps, sortTableRows, useToast };
|
|
603
|
+
export { AppShell, type AppShellProps, type AppShellSection, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, BusyRegion, type BusyRegionProps, Button, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, RowIdentity, type RowIdentityProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, Timeline, type TimelineEvent, type TimelineProps, Toast, type ToastNotice, type ToastProps, sortTableRows, useToast };
|
package/react/dist/index.js
CHANGED
|
@@ -2152,10 +2152,193 @@ function Toast({ children }) {
|
|
|
2152
2152
|
] });
|
|
2153
2153
|
}
|
|
2154
2154
|
|
|
2155
|
+
// src/AppShell.tsx
|
|
2156
|
+
import { useEffect as useEffect9, useId as useId9, useState as useState9 } from "react";
|
|
2157
|
+
import { applyTheme, paletteHotkey, prism, railCollapsed, themeIcon, themeName } from "@apliteni/apliteni-ui";
|
|
2158
|
+
import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2159
|
+
var path = (value) => value.split(/[?#]/)[0].replace(/\/+$/, "") || "/";
|
|
2160
|
+
function AppShell({
|
|
2161
|
+
sections,
|
|
2162
|
+
pathname,
|
|
2163
|
+
title,
|
|
2164
|
+
children,
|
|
2165
|
+
word = "apliteni-ui",
|
|
2166
|
+
brand,
|
|
2167
|
+
brandHref = "/",
|
|
2168
|
+
width = "centered",
|
|
2169
|
+
back,
|
|
2170
|
+
lede,
|
|
2171
|
+
actions,
|
|
2172
|
+
bandControl,
|
|
2173
|
+
account,
|
|
2174
|
+
onSignOut,
|
|
2175
|
+
defaultCollapsed = false,
|
|
2176
|
+
palette,
|
|
2177
|
+
renderLink
|
|
2178
|
+
}) {
|
|
2179
|
+
const uid = useId9();
|
|
2180
|
+
const [collapsed, setCollapsed] = useState9(defaultCollapsed);
|
|
2181
|
+
const [search, setSearch] = useState9(false);
|
|
2182
|
+
const [more, setMore] = useState9(false);
|
|
2183
|
+
const [theme, setTheme] = useState9("dark");
|
|
2184
|
+
const current = path(pathname);
|
|
2185
|
+
const active = sections.filter((section) => current === path(section.href) || path(section.href) !== "/" && current.startsWith(`${path(section.href)}/`)).sort((a, b) => path(b.href).length - path(a.href).length)[0];
|
|
2186
|
+
useEffect9(() => {
|
|
2187
|
+
setCollapsed(railCollapsed() ?? defaultCollapsed);
|
|
2188
|
+
}, [defaultCollapsed]);
|
|
2189
|
+
useEffect9(() => {
|
|
2190
|
+
setMore(false);
|
|
2191
|
+
setSearch(false);
|
|
2192
|
+
}, [pathname]);
|
|
2193
|
+
useEffect9(() => {
|
|
2194
|
+
const root = document.documentElement;
|
|
2195
|
+
const sync2 = () => setTheme(root.getAttribute("data-theme") === "light" ? "light" : "dark");
|
|
2196
|
+
sync2();
|
|
2197
|
+
const observer = new MutationObserver(sync2);
|
|
2198
|
+
observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
|
|
2199
|
+
return () => observer.disconnect();
|
|
2200
|
+
}, []);
|
|
2201
|
+
useEffect9(() => {
|
|
2202
|
+
const hotkey = (event) => {
|
|
2203
|
+
if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey || event.key.toLowerCase() !== "k") return;
|
|
2204
|
+
const target = event.target;
|
|
2205
|
+
if (target?.closest?.('input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="dialog"]')) return;
|
|
2206
|
+
event.preventDefault();
|
|
2207
|
+
setSearch(true);
|
|
2208
|
+
};
|
|
2209
|
+
document.addEventListener("keydown", hotkey);
|
|
2210
|
+
return () => document.removeEventListener("keydown", hotkey);
|
|
2211
|
+
}, []);
|
|
2212
|
+
const fold = () => {
|
|
2213
|
+
const next = !collapsed;
|
|
2214
|
+
setCollapsed(next);
|
|
2215
|
+
try {
|
|
2216
|
+
document.cookie = `apliteni-ui-rail=${next ? "collapsed" : "expanded"}; Max-Age=31536000; Path=/; SameSite=Lax`;
|
|
2217
|
+
} catch {
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
2220
|
+
const links = (items) => items.map((section) => {
|
|
2221
|
+
const linkProps = {
|
|
2222
|
+
href: section.href,
|
|
2223
|
+
className: `ui-nav__item${section === active ? " is-active" : ""}`,
|
|
2224
|
+
"aria-current": section === active ? "page" : void 0,
|
|
2225
|
+
"aria-label": `${section.label}${section.count == null ? "" : ` ${section.count}`}`,
|
|
2226
|
+
onClick: (event) => {
|
|
2227
|
+
if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) setMore(false);
|
|
2228
|
+
},
|
|
2229
|
+
children: /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
2230
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx25(Icon, { name: section.icon }) }),
|
|
2231
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-nav__label", children: section.label }),
|
|
2232
|
+
section.count != null && /* @__PURE__ */ jsx25("span", { className: "ui-nav__badge", children: section.count })
|
|
2233
|
+
] })
|
|
2234
|
+
};
|
|
2235
|
+
return /* @__PURE__ */ jsx25("li", { children: renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx25("a", { ...linkProps }) }, section.href);
|
|
2236
|
+
});
|
|
2237
|
+
const foldLabel = collapsed ? "Expand sidebar" : "Collapse sidebar";
|
|
2238
|
+
const visible = sections.length > 4 ? sections.slice(0, 3) : sections;
|
|
2239
|
+
const remaining = sections.slice(visible.length);
|
|
2240
|
+
const initials = account.name.trim().split(/\s+/).map((part) => part[0]).slice(0, 2).join("");
|
|
2241
|
+
return /* @__PURE__ */ jsxs21("div", { className: `ui-app ui-app--topbar ui-react-app${collapsed ? " is-collapsed" : ""}`, children: [
|
|
2242
|
+
/* @__PURE__ */ jsxs21("div", { className: "ui-app__rail", children: [
|
|
2243
|
+
/* @__PURE__ */ jsx25("div", { className: "ui-app__head", children: /* @__PURE__ */ jsxs21("a", { className: "ui-app__brand", href: brandHref, "aria-label": word, children: [
|
|
2244
|
+
brand ?? /* @__PURE__ */ jsx25("i", { "aria-hidden": "true", className: "ui-react-app__mark", dangerouslySetInnerHTML: { __html: prism(uid, 24) } }),
|
|
2245
|
+
/* @__PURE__ */ jsx25("span", { children: word })
|
|
2246
|
+
] }) }),
|
|
2247
|
+
/* @__PURE__ */ jsx25("nav", { className: "ui-nav ui-nav--side", "aria-label": "Sections", children: /* @__PURE__ */ jsx25("ul", { className: "ui-nav__list", children: links(sections) }) }),
|
|
2248
|
+
/* @__PURE__ */ jsx25("div", { className: "ui-app__foot", children: /* @__PURE__ */ jsx25("div", { className: "ui-app__fold-row", children: /* @__PURE__ */ jsxs21("button", { type: "button", className: "ui-nav__item ui-app__fold", "aria-expanded": !collapsed, "aria-label": foldLabel, onClick: fold, children: [
|
|
2249
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsxs21("svg", { className: "ui-icon", viewBox: "0 0 24 24", "aria-hidden": "true", children: [
|
|
2250
|
+
/* @__PURE__ */ jsx25("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
2251
|
+
/* @__PURE__ */ jsx25("path", { className: "ui-app__fold-seam", d: "M9 3v18" })
|
|
2252
|
+
] }) }),
|
|
2253
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-nav__label", children: foldLabel })
|
|
2254
|
+
] }) }) })
|
|
2255
|
+
] }),
|
|
2256
|
+
/* @__PURE__ */ jsxs21("div", { className: "ui-app__well", children: [
|
|
2257
|
+
/* @__PURE__ */ jsxs21("header", { className: "ui-app__bar", children: [
|
|
2258
|
+
/* @__PURE__ */ jsxs21("button", { type: "button", className: "ui-app__search", "aria-haspopup": "dialog", onClick: () => setSearch(true), children: [
|
|
2259
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-app__search-ic", children: /* @__PURE__ */ jsx25(Icon, { name: "search" }) }),
|
|
2260
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-app__search-txt", children: "Search or run a command\u2026" }),
|
|
2261
|
+
/* @__PURE__ */ jsx25("kbd", { className: "ui-cmdk__key", children: paletteHotkey() })
|
|
2262
|
+
] }),
|
|
2263
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-app__bar-gap" }),
|
|
2264
|
+
bandControl,
|
|
2265
|
+
/* @__PURE__ */ jsx25("button", { type: "button", className: "toggle", "aria-label": themeName(theme), title: themeName(theme), onClick: () => applyTheme(theme === "light" ? "dark" : "light"), children: /* @__PURE__ */ jsx25("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: themeIcon(theme) } }) }),
|
|
2266
|
+
/* @__PURE__ */ jsx25("div", { className: "ui-app__user ui-app__user--bar", children: /* @__PURE__ */ jsx25(
|
|
2267
|
+
Dropdown,
|
|
2268
|
+
{
|
|
2269
|
+
variant: "menu",
|
|
2270
|
+
align: "end",
|
|
2271
|
+
chevron: false,
|
|
2272
|
+
ariaLabel: `Signed in as ${account.name}, ${account.email}`,
|
|
2273
|
+
triggerClass: "ui-app__user-trigger",
|
|
2274
|
+
panelClass: "ui-app__user-panel",
|
|
2275
|
+
triggerContent: /* @__PURE__ */ jsx25("span", { className: "ui-app__av", "aria-hidden": "true", children: initials }),
|
|
2276
|
+
header: /* @__PURE__ */ jsxs21("div", { className: "ui-dropdown__head", children: [
|
|
2277
|
+
/* @__PURE__ */ jsx25("b", { children: account.name }),
|
|
2278
|
+
/* @__PURE__ */ jsx25("span", { children: account.email })
|
|
2279
|
+
] }),
|
|
2280
|
+
items: [{ label: "Sign out", icon: "logout", danger: true }],
|
|
2281
|
+
onSelect: onSignOut
|
|
2282
|
+
}
|
|
2283
|
+
) })
|
|
2284
|
+
] }),
|
|
2285
|
+
/* @__PURE__ */ jsxs21("main", { className: `ui-app__main${width === "wide" ? " ui-app__main--wide" : ""}`, children: [
|
|
2286
|
+
back && /* @__PURE__ */ jsx25(BackLink, { ...back }),
|
|
2287
|
+
/* @__PURE__ */ jsx25("h1", { children: title }),
|
|
2288
|
+
lede && /* @__PURE__ */ jsx25("p", { className: "ui-app__sub", children: lede }),
|
|
2289
|
+
actions && /* @__PURE__ */ jsx25("div", { className: "ui-react-app__actions", children: actions }),
|
|
2290
|
+
/* @__PURE__ */ jsx25("div", { className: "ui-app__body", children })
|
|
2291
|
+
] })
|
|
2292
|
+
] }),
|
|
2293
|
+
/* @__PURE__ */ jsx25("nav", { className: "ui-nav ui-react-app__bottom", "aria-label": "Sections on mobile", children: /* @__PURE__ */ jsxs21("ul", { className: "ui-nav__list", children: [
|
|
2294
|
+
links(visible),
|
|
2295
|
+
remaining.length > 0 && /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsxs21(
|
|
2296
|
+
"button",
|
|
2297
|
+
{
|
|
2298
|
+
type: "button",
|
|
2299
|
+
className: `ui-nav__item${active && remaining.includes(active) ? " is-active" : ""}`,
|
|
2300
|
+
"aria-haspopup": "dialog",
|
|
2301
|
+
"aria-expanded": more,
|
|
2302
|
+
onClick: () => setMore(true),
|
|
2303
|
+
children: [
|
|
2304
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx25(Icon, { name: "moreHorizontal" }) }),
|
|
2305
|
+
/* @__PURE__ */ jsx25("span", { className: "ui-nav__label", children: "More" })
|
|
2306
|
+
]
|
|
2307
|
+
}
|
|
2308
|
+
) })
|
|
2309
|
+
] }) }),
|
|
2310
|
+
/* @__PURE__ */ jsx25(Drawer, { open: more, onClose: () => setMore(false), title: "More sections", side: "bottom", children: /* @__PURE__ */ jsx25("nav", { className: "ui-nav ui-nav--side", "aria-label": "More sections", children: /* @__PURE__ */ jsx25("ul", { className: "ui-nav__list", children: links(remaining) }) }) }),
|
|
2311
|
+
/* @__PURE__ */ jsx25(CommandPalette, { ...palette ?? { groups: [{ items: sections.map((section) => ({ id: section.href, ...section })) }] }, open: search, onClose: () => setSearch(false) })
|
|
2312
|
+
] });
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
// src/EmptyState.tsx
|
|
2316
|
+
import { icon as kitIcon2, illo } from "@apliteni/apliteni-ui";
|
|
2317
|
+
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2318
|
+
var cases = {
|
|
2319
|
+
"first-run": { title: "Nothing needs you yet", sub: "New items will appear here when they need your attention.", icon: "check" },
|
|
2320
|
+
"no-matches": { title: "No results in this view", sub: "Try another search or clear your filters.", icon: "search" },
|
|
2321
|
+
"not-found": { title: "We can't find that page", sub: "Check the address or return to the home page.", icon: "folder" },
|
|
2322
|
+
"not-yet-built": { title: "This ships later", sub: "This screen is not available yet. Check back later.", icon: "clock" }
|
|
2323
|
+
};
|
|
2324
|
+
function EmptyState({ variant = "first-run", title, sub, icon: icon5, art, actions }) {
|
|
2325
|
+
const preset = cases[variant];
|
|
2326
|
+
const heading = title ?? preset.title;
|
|
2327
|
+
const guidance = sub ?? preset.sub;
|
|
2328
|
+
const glyph = icon5 ?? preset.icon;
|
|
2329
|
+
return /* @__PURE__ */ jsxs22("div", { className: "ui-empty", children: [
|
|
2330
|
+
art ? typeof art === "string" ? /* @__PURE__ */ jsx26("div", { className: "ui-empty__art", dangerouslySetInnerHTML: { __html: /<svg/.test(art) ? art : illo(art) } }) : /* @__PURE__ */ jsx26("div", { className: "ui-empty__art", "aria-hidden": "true", children: art }) : glyph ? /* @__PURE__ */ jsx26("div", { className: "ui-empty__icon", dangerouslySetInnerHTML: { __html: kitIcon2(glyph) } }) : null,
|
|
2331
|
+
heading && /* @__PURE__ */ jsx26("div", { className: "ui-empty__title", children: heading }),
|
|
2332
|
+
guidance && /* @__PURE__ */ jsx26("div", { className: "ui-empty__sub", children: guidance }),
|
|
2333
|
+
actions && /* @__PURE__ */ jsx26("div", { className: "ui-empty__actions", children: actions })
|
|
2334
|
+
] });
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2155
2337
|
// src/index.ts
|
|
2156
2338
|
var PAGE_SIZES = KIT_PAGE_SIZES;
|
|
2157
2339
|
var DEFAULT_PAGE_SIZE3 = KIT_DEFAULT_PAGE_SIZE;
|
|
2158
2340
|
export {
|
|
2341
|
+
AppShell,
|
|
2159
2342
|
BackLink,
|
|
2160
2343
|
Badge,
|
|
2161
2344
|
BusyRegion,
|
|
@@ -2171,6 +2354,7 @@ export {
|
|
|
2171
2354
|
Drawer,
|
|
2172
2355
|
DrawerSection,
|
|
2173
2356
|
Dropdown,
|
|
2357
|
+
EmptyState,
|
|
2174
2358
|
FileField,
|
|
2175
2359
|
FilterBar,
|
|
2176
2360
|
Icon,
|