@apliteni/apliteni-ui 0.136.0 → 0.138.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 +38 -0
- package/react/dist/index.d.ts +82 -3
- package/react/dist/index.js +291 -126
- package/src/components/topbar.js +3 -3
- package/src/styles/table.css +28 -24
- package/src/styles/topbar.css +24 -9
- package/src/tokens/tokens.css +8 -7
package/package.json
CHANGED
package/react/README.md
CHANGED
|
@@ -232,6 +232,8 @@ finds its rows by `data-dd-item`, which is in the props you spread.
|
|
|
232
232
|
leave `open` out and the component keeps its own, starting from `defaultOpen`. `onSelect`
|
|
233
233
|
reports the item's `value` and the item. Pass `ariaLabel` to a `select` dropdown: a listbox
|
|
234
234
|
needs a name, and axe says so — the same reason every vanilla dropdown story passes one.
|
|
235
|
+
Pass `selectedValue` when the caller owns the selected row. Its tick stays on that value after
|
|
236
|
+
`onSelect` until the caller changes it.
|
|
235
237
|
|
|
236
238
|
**`search` puts a field over the rows**, the same one the factory draws, and Guidelines /
|
|
237
239
|
Component choice makes it a rule at ten options or any list fed by data:
|
|
@@ -307,6 +309,19 @@ once installed. In the repo there is no copy to resolve to, so `kit-alias.ts` po
|
|
|
307
309
|
vitest and Storybook straight at `../src/` — which is why the class-name parity tests
|
|
308
310
|
now compare against the working tree rather than the last published release.
|
|
309
311
|
|
|
312
|
+
### Table appearance
|
|
313
|
+
|
|
314
|
+
`DataTable` takes the vanilla table hooks as props. `zebra`, `hover` (on unless `false`), `stack`,
|
|
315
|
+
`density`, `stickyHeader` and `pinnedIdentity` set the table modifiers. `rowState={(row) => 'target' | 'dead' | undefined}`
|
|
316
|
+
marks a row, `footer` takes totals rows, and `caption` names the table for assistive technology. A column takes
|
|
317
|
+
`rowHeader` and `cell` (`'title' | 'code' | 'long' | 'strong' | 'act'`). A `dead` row is muted, so put the word
|
|
318
|
+
that names its state in one of its cells.
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
<DataTable columns={columns} rows={rows} selectable={false} pager={false}
|
|
322
|
+
density="dense" zebra stack rowState={(r) => (r.id === landedOn ? 'target' : undefined)} />
|
|
323
|
+
```
|
|
324
|
+
|
|
310
325
|
### Tables with another presentation of the same rows
|
|
311
326
|
|
|
312
327
|
Pass `selectable={false}` to omit selection controls and their callbacks. Existing callers
|
|
@@ -963,6 +978,29 @@ instead of 32, with the same line drawn in the middle of it.
|
|
|
963
978
|
]} />
|
|
964
979
|
```
|
|
965
980
|
|
|
981
|
+
## TopBar
|
|
982
|
+
|
|
983
|
+
`TopBar` is the band: the brand first, then your slots after the spacer. Fill `view`, `version`,
|
|
984
|
+
`theme` and `account` with `ViewSwitch`, `VersionSwitcher`, `ThemeToggle` and `AccountMenu`, or
|
|
985
|
+
leave one out. Leave out `account` for the signed-out bar. The brand is the Apliteni mark and
|
|
986
|
+
`word`, or pass your own `brand`. Put it above `AppShell` or on its own.
|
|
987
|
+
|
|
988
|
+
```tsx
|
|
989
|
+
<TopBar
|
|
990
|
+
view={<ViewSwitch items={[{ id: 'deck', label: 'Deck' }, { id: 'text', label: 'Text' }]} active="deck" />}
|
|
991
|
+
version={<VersionSwitcher versions={versions} value={version} onChange={setVersion} />}
|
|
992
|
+
theme={<ThemeToggle />}
|
|
993
|
+
account={<AccountMenu name="Ada Lovelace" email="ada@apliteni.com" current="prefs" onSignOut={signOut} />} />
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
`ViewSwitch` is a group of links, so it takes `renderLink` like `NavTabs`. The current view is
|
|
997
|
+
filled with the same accent fill as a `Segmented` choice and has `aria-current="page"`.
|
|
998
|
+
`VersionSwitcher` takes `{ value, label, badge }` versions. The button shows only the chosen
|
|
999
|
+
name. Each row shows a name, a badge and the selected tick. `AccountMenu` shows the
|
|
1000
|
+
avatar mark, the reader's name and address, the rows in `items` and Sign out. Both menus are the
|
|
1001
|
+
kit's `Dropdown`, so they share its keyboard and placement. `current` marks one account page in
|
|
1002
|
+
accent ink and defaults to `prefs`.
|
|
1003
|
+
|
|
966
1004
|
## NavTabs and Breadcrumbs
|
|
967
1005
|
|
|
968
1006
|
`NavTabs` renders route links with the kit’s underline or pill presentation. Pass
|
package/react/dist/index.d.ts
CHANGED
|
@@ -281,6 +281,10 @@ type Column<T> = {
|
|
|
281
281
|
* why: docs/components.md#dense-financial-tables
|
|
282
282
|
*/
|
|
283
283
|
linked?: boolean;
|
|
284
|
+
/** Renders this column's body cells as row headers (`th scope="row"`), as the kit's compact table does. */
|
|
285
|
+
rowHeader?: boolean;
|
|
286
|
+
/** `title` gives the column the remaining width, `code` sets a handle or id in the table's small text, `long` is running text that gets its own line in a stacked row, `strong` bolds a figure, `act` right-aligns a row action. */
|
|
287
|
+
cell?: 'title' | 'code' | 'long' | 'strong' | 'act';
|
|
284
288
|
};
|
|
285
289
|
type TableSort<T> = {
|
|
286
290
|
key: (keyof T & string) | undefined;
|
|
@@ -316,6 +320,16 @@ type PagerProps = {
|
|
|
316
320
|
type DataTableProps<T> = {
|
|
317
321
|
columns: Column<T>[];
|
|
318
322
|
rows: T[];
|
|
323
|
+
/** The kit's `--zebra`, `--hover` (on unless `false`) and `--stack` hooks. A stacked table lays each row out as a block below the phone step, so no column scrolls out of reach. */
|
|
324
|
+
zebra?: boolean;
|
|
325
|
+
hover?: boolean;
|
|
326
|
+
stack?: boolean;
|
|
327
|
+
/** Marks a row the reader landed on (`target`) or a revoked one (`dead`). A dead row is muted, so put the word that names its state in one of its cells. */
|
|
328
|
+
rowState?: (row: T) => 'target' | 'dead' | undefined;
|
|
329
|
+
/** Table footer rows, such as totals: `<tr>` elements with a `th scope="row"` label. */
|
|
330
|
+
footer?: ReactNode;
|
|
331
|
+
/** A caption read by assistive technology only. */
|
|
332
|
+
caption?: string;
|
|
319
333
|
dense?: boolean;
|
|
320
334
|
density?: 'default' | 'dense' | 'compact';
|
|
321
335
|
stickyHeader?: boolean;
|
|
@@ -345,7 +359,7 @@ type DataTableProps<T> = {
|
|
|
345
359
|
declare function sortTableRows<T>(rows: T[], sort: TableSort<T>): T[];
|
|
346
360
|
declare function DataTable<T extends {
|
|
347
361
|
name: string;
|
|
348
|
-
}>({ columns, rows, dense, density, stickyHeader, pinnedIdentity, scrollLabel, empty, pageSize, pageSizes, onPageSizeChange, pager, pagerLabel, loading, selectable, selected, onToggle, onTogglePage, sort: controlledSort, onSortChange, page: controlledPage, onPageChange, total, hasMore, }: DataTableProps<T>): react.JSX.Element;
|
|
362
|
+
}>({ columns, rows, zebra, hover, stack, rowState, footer, caption, dense, density, stickyHeader, pinnedIdentity, scrollLabel, empty, pageSize, pageSizes, onPageSizeChange, pager, pagerLabel, loading, selectable, selected, onToggle, onTogglePage, sort: controlledSort, onSortChange, page: controlledPage, onPageChange, total, hasMore, }: DataTableProps<T>): react.JSX.Element;
|
|
349
363
|
|
|
350
364
|
type PaginationProps = {
|
|
351
365
|
page?: number;
|
|
@@ -546,6 +560,8 @@ type DropdownProps = {
|
|
|
546
560
|
label?: string;
|
|
547
561
|
/** What the trigger shows. Given one, the trigger is yours to update. */
|
|
548
562
|
value?: string;
|
|
563
|
+
/** When given, the caller owns the selected row, including after a pick. */
|
|
564
|
+
selectedValue?: string | number;
|
|
549
565
|
placeholder?: string;
|
|
550
566
|
/** Inferred from the items when it is left out, exactly as the factory infers it. */
|
|
551
567
|
variant?: 'select' | 'menu';
|
|
@@ -584,7 +600,7 @@ type DropdownProps = {
|
|
|
584
600
|
/** Draw the row yourself. `props` is everything the row needs; spread it. */
|
|
585
601
|
row?: (item: DropdownItem, props: DropdownRowProps) => ReactNode;
|
|
586
602
|
};
|
|
587
|
-
declare function Dropdown({ label, value, placeholder, variant, items, sections, header, footer, triggerContent, triggerClass, disabled, chevron, align, direction, scroll, search, ariaLabel, id, panelClass, 'aria-describedby': describedBy, 'aria-invalid': invalid, open: openProp, defaultOpen, onOpenChange, onSelect, row, }: DropdownProps): react.JSX.Element;
|
|
603
|
+
declare function Dropdown({ label, value, selectedValue, placeholder, variant, items, sections, header, footer, triggerContent, triggerClass, disabled, chevron, align, direction, scroll, search, ariaLabel, id, panelClass, 'aria-describedby': describedBy, 'aria-invalid': invalid, open: openProp, defaultOpen, onOpenChange, onSelect, row, }: DropdownProps): react.JSX.Element;
|
|
588
604
|
|
|
589
605
|
type BackLinkOwnProps = {
|
|
590
606
|
/** The address. No address, or a `javascript:` one, and nothing is rendered. */
|
|
@@ -1187,6 +1203,69 @@ declare const AccentPicker: react.ForwardRefExoticComponent<Omit<HTMLAttributes<
|
|
|
1187
1203
|
options?: readonly Accent[];
|
|
1188
1204
|
} & react.RefAttributes<HTMLDivElement>>;
|
|
1189
1205
|
|
|
1206
|
+
type TopBarProps = Omit<ComponentPropsWithoutRef<'header'>, 'children'> & {
|
|
1207
|
+
/** The lockup. Left out, the bar draws the Apliteni mark and `word`. */
|
|
1208
|
+
brand?: ReactNode;
|
|
1209
|
+
/** The product word beside the mark, when `brand` is left out. */
|
|
1210
|
+
word?: string;
|
|
1211
|
+
brandHref?: string;
|
|
1212
|
+
/** A `ViewSwitch`, or nothing. */
|
|
1213
|
+
view?: ReactNode;
|
|
1214
|
+
/** A `VersionSwitcher`, or nothing. */
|
|
1215
|
+
version?: ReactNode;
|
|
1216
|
+
/** A `ThemeToggle`, or nothing. */
|
|
1217
|
+
theme?: ReactNode;
|
|
1218
|
+
/** An `AccountMenu`. Left out, the bar is the signed-out bar. */
|
|
1219
|
+
account?: ReactNode;
|
|
1220
|
+
};
|
|
1221
|
+
/** The band: brand first, the controls after the spacer. Each control is a slot. */
|
|
1222
|
+
declare function TopBar({ brand, word, brandHref, view, version, theme, account, className, ...rest }: TopBarProps): react.JSX.Element;
|
|
1223
|
+
type ViewSwitchItem = {
|
|
1224
|
+
id: string;
|
|
1225
|
+
label: string;
|
|
1226
|
+
href?: string;
|
|
1227
|
+
target?: string;
|
|
1228
|
+
};
|
|
1229
|
+
type ViewSwitchProps = {
|
|
1230
|
+
items: readonly ViewSwitchItem[];
|
|
1231
|
+
active: string;
|
|
1232
|
+
/** Names the group. */
|
|
1233
|
+
label?: string;
|
|
1234
|
+
/** Spread linkProps onto the router link, including children. */
|
|
1235
|
+
renderLink?: (item: ViewSwitchItem, linkProps: ComponentPropsWithoutRef<'a'>) => ReactNode;
|
|
1236
|
+
};
|
|
1237
|
+
/** The Deck and Text switch: links between views of one page, the current one filled. */
|
|
1238
|
+
declare function ViewSwitch({ items, active, label, renderLink }: ViewSwitchProps): react.JSX.Element;
|
|
1239
|
+
type Version = {
|
|
1240
|
+
value: string;
|
|
1241
|
+
label: string;
|
|
1242
|
+
badge?: 'live' | 'archive';
|
|
1243
|
+
};
|
|
1244
|
+
type VersionSwitcherProps = {
|
|
1245
|
+
versions: readonly Version[];
|
|
1246
|
+
value: string;
|
|
1247
|
+
onChange?: (value: string) => void;
|
|
1248
|
+
/** Names the list and the button. */
|
|
1249
|
+
label?: string;
|
|
1250
|
+
defaultOpen?: boolean;
|
|
1251
|
+
};
|
|
1252
|
+
/** The version menu: the button shows the chosen name, the open list ticks it. */
|
|
1253
|
+
declare function VersionSwitcher({ versions, value, onChange, label, defaultOpen }: VersionSwitcherProps): react.JSX.Element;
|
|
1254
|
+
type AccountMenuProps = {
|
|
1255
|
+
name: string;
|
|
1256
|
+
email: string;
|
|
1257
|
+
/** The rows above Sign out. Left out, the kit's account pages. */
|
|
1258
|
+
items?: DropdownEntry[];
|
|
1259
|
+
/** The current account page. One menu row takes the accent ink. */
|
|
1260
|
+
current?: string;
|
|
1261
|
+
signOutHref?: string;
|
|
1262
|
+
onSignOut?: () => void;
|
|
1263
|
+
onSelect?: (value: string | number | undefined) => void;
|
|
1264
|
+
defaultOpen?: boolean;
|
|
1265
|
+
};
|
|
1266
|
+
/** The avatar and its menu. */
|
|
1267
|
+
declare function AccountMenu({ name, email, items, current, signOutHref, onSignOut, onSelect, defaultOpen, }: AccountMenuProps): react.JSX.Element;
|
|
1268
|
+
|
|
1190
1269
|
type NavTabBadge = string | number | {
|
|
1191
1270
|
text: string | number;
|
|
1192
1271
|
tone?: 'neutral' | 'accent' | 'live' | 'danger';
|
|
@@ -1234,4 +1313,4 @@ declare const Breadcrumbs: react.ForwardRefExoticComponent<Omit<Omit<react.Detai
|
|
|
1234
1313
|
declare const PAGE_SIZES: readonly number[];
|
|
1235
1314
|
declare const DEFAULT_PAGE_SIZE: number;
|
|
1236
1315
|
|
|
1237
|
-
export { type Accent, AccentPicker, type AccentPickerProps, type AddFilter, AppShell, type AppShellProps, type AppShellSection, Avatar, type AvatarProps, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, BusyRegion, type BusyRegionProps, Button, type ButtonLinkProps, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, Chart, type ChartBridgeStep, type ChartBridgeTones, type ChartPeriod, type ChartProps, type ChartSeries, type ChartTone, CheckList, type CheckListProps, Checkbox, type CheckboxProps, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DatePicker, type DatePickerMode, type DatePickerPreset, type DatePickerProps, type DatePickerRange, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownAvatar, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, Feedback, type FeedbackPayload, type FeedbackProps, type FeedbackResult, type FeedbackSection, Field, type FieldControlProps, type FieldProps, FileDrop, type FileDropFile, type FileDropProps, type FileDropStatus, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Footer, type FooterColumn, type FooterLink, type FooterProps, type FooterSocial, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, type NativeButtonProps, type NavTabBadge, type NavTabItem, NavTabs, type NavTabsProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, Pill, type PillProps, RowIdentity, type RowIdentityProps, SearchField, type SearchFieldProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, SidebarNav, type SidebarNavBadge, type SidebarNavItem, type SidebarNavLeaf, type SidebarNavProps, type SidebarNavSection, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, StatusDot, type StatusDotProps, Success, SuccessCheck, type SuccessCheckProps, type SuccessCountdown, SuccessPanel, type SuccessPanelProps, type SuccessProps, Switch, type SwitchProps, THEME_INIT_SCRIPT, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineEvent, type TimelineEventKind, type TimelineProps, Toast, type ToastNotice, type ToastProps, Tooltip, type TooltipProps, sortTableRows, useToast };
|
|
1316
|
+
export { type Accent, AccentPicker, type AccentPickerProps, AccountMenu, type AccountMenuProps, type AddFilter, AppShell, type AppShellProps, type AppShellSection, Avatar, type AvatarProps, BackLink, type BackLinkOwnProps, type BackLinkProps, Badge, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, BusyRegion, type BusyRegionProps, Button, type ButtonLinkProps, type ButtonProps, Callout, type CalloutProps, type CalloutVariant, Card, Chart, type ChartBridgeStep, type ChartBridgeTones, type ChartPeriod, type ChartProps, type ChartSeries, type ChartTone, CheckList, type CheckListProps, Checkbox, type CheckboxProps, type Column, type CommandGroup, type CommandItem, CommandPalette, type CommandPaletteProps, Confirm, type ConfirmProps, DEFAULT_PAGE_SIZE, DataTable, type DataTableProps, DatePicker, type DatePickerMode, type DatePickerPreset, type DatePickerProps, type DatePickerRange, DeltaValue, type DeltaValueProps, Denied, type DeniedProps, Drawer, type DrawerProps, DrawerSection, type DrawerSectionProps, Dropdown, type DropdownAvatar, type DropdownBadge, type DropdownEntry, type DropdownItem, type DropdownProps, type DropdownRowProps, type DropdownSearch, type DropdownSection, type DropdownSeparator, EmptyState, type EmptyStateProps, type EmptyStateVariant, Feedback, type FeedbackPayload, type FeedbackProps, type FeedbackResult, type FeedbackSection, Field, type FieldControlProps, type FieldProps, FileDrop, type FileDropFile, type FileDropProps, type FileDropStatus, FileField, type FileFieldProps, type Filter, FilterBar, type FilterBarProps, Footer, type FooterColumn, type FooterLink, type FooterProps, type FooterSocial, Icon, KeyValueList, type KeyValueListProps, type KeyValueRow, Modal, type ModalProps, type NativeButtonProps, type NavTabBadge, type NavTabItem, NavTabs, type NavTabsProps, NumericValue, type NumericValueProps, PAGE_SIZES, Pagination, type PaginationProps, Pill, type PillProps, RowIdentity, type RowIdentityProps, SearchField, type SearchFieldProps, type SegmentOption, Segmented, type SegmentedProps, SelectField, type SelectFieldProps, SidebarNav, type SidebarNavBadge, type SidebarNavItem, type SidebarNavLeaf, type SidebarNavProps, type SidebarNavSection, Skeleton, type SkeletonProps, SkeletonTable, type SkeletonTableProps, Snippet, type SnippetProps, StatBand, type StatBandProps, type StatDelta, type StatFigure, type StatTone, type StatVariant, StatusDot, type StatusDotProps, Success, SuccessCheck, type SuccessCheckProps, type SuccessCountdown, SuccessPanel, type SuccessPanelProps, type SuccessProps, Switch, type SwitchProps, THEME_INIT_SCRIPT, type TabItem, type TableSort, Tabs, type TabsProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineEvent, type TimelineEventKind, type TimelineProps, Toast, type ToastNotice, type ToastProps, Tooltip, type TooltipProps, TopBar, type TopBarProps, type Version, VersionSwitcher, type VersionSwitcherProps, ViewSwitch, type ViewSwitchItem, type ViewSwitchProps, sortTableRows, useToast };
|
package/react/dist/index.js
CHANGED
|
@@ -94,7 +94,7 @@ var cx = (...a) => a.filter(Boolean).join(" ");
|
|
|
94
94
|
var Button = forwardRef3(function Button2({
|
|
95
95
|
variant = "secondary",
|
|
96
96
|
size = "md",
|
|
97
|
-
icon:
|
|
97
|
+
icon: icon9,
|
|
98
98
|
leading,
|
|
99
99
|
iconRight,
|
|
100
100
|
iconOnly,
|
|
@@ -158,7 +158,7 @@ var Button = forwardRef3(function Button2({
|
|
|
158
158
|
className
|
|
159
159
|
);
|
|
160
160
|
const labelled = rest["aria-label"] != null || rest["aria-labelledby"] != null;
|
|
161
|
-
const fallback = typeof children === "string" && children.trim() ? children.trim() :
|
|
161
|
+
const fallback = typeof children === "string" && children.trim() ? children.trim() : icon9;
|
|
162
162
|
const named = iconOnly && !labelled && fallback ? { "aria-label": fallback, title: rest.title ?? fallback } : {};
|
|
163
163
|
const Root = href === void 0 ? "button" : "a";
|
|
164
164
|
return /* @__PURE__ */ jsxs3(
|
|
@@ -203,7 +203,7 @@ var Button = forwardRef3(function Button2({
|
|
|
203
203
|
if (!blockKey(event)) onKeyUp?.(event);
|
|
204
204
|
},
|
|
205
205
|
children: [
|
|
206
|
-
leading != null ? /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", style: { display: "inline-flex" }, children: leading }) :
|
|
206
|
+
leading != null ? /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", style: { display: "inline-flex" }, children: leading }) : icon9 && /* @__PURE__ */ jsx4(Icon, { name: icon9 }),
|
|
207
207
|
!iconOnly && renderedChildren != null && /* @__PURE__ */ jsx4("span", { className: "ui-btn__label-slot", children: /* @__PURE__ */ jsx4("span", { className: "ui-btn__label", ref: labelRef, children: renderedChildren }) }),
|
|
208
208
|
iconRight && /* @__PURE__ */ jsx4(Icon, { name: iconRight }),
|
|
209
209
|
busy && /* @__PURE__ */ jsxs3("span", { className: "ui-btn__dots", "aria-hidden": "true", children: [
|
|
@@ -284,14 +284,14 @@ var StatusDot = forwardRef5(function StatusDot2({
|
|
|
284
284
|
// src/primitives/Card.tsx
|
|
285
285
|
import { icon as kitIcon, safeUrl } from "@apliteni/apliteni-ui";
|
|
286
286
|
import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
287
|
-
function Card({ title, sub, level = 2, variant, pad: pad2, icon:
|
|
287
|
+
function Card({ title, sub, level = 2, variant, pad: pad2, icon: icon9, href, className, children }) {
|
|
288
288
|
const n = Number(level);
|
|
289
289
|
const Heading = href != null ? "div" : `h${[2, 3, 4, 5, 6].includes(n) ? n : 2}`;
|
|
290
290
|
const titled = title != null && title !== false && title !== "";
|
|
291
291
|
const classes = ["ui-card", variant && `ui-card--${variant}`, pad2 && `ui-card--pad-${pad2}`, href != null && "ui-card--interactive", className].filter(Boolean).join(" ");
|
|
292
292
|
const inner = /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
293
293
|
titled && /* @__PURE__ */ jsxs5(Heading, { className: "ui-card__title", children: [
|
|
294
|
-
|
|
294
|
+
icon9 && /* @__PURE__ */ jsx9("span", { className: "ui-card__icon", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: kitIcon(icon9) } }),
|
|
295
295
|
title
|
|
296
296
|
] }),
|
|
297
297
|
sub != null && /* @__PURE__ */ jsx9("div", { className: "ui-card__sub", children: sub }),
|
|
@@ -303,9 +303,9 @@ function Card({ title, sub, level = 2, variant, pad: pad2, icon: icon8, href, cl
|
|
|
303
303
|
// src/primitives/Callout.tsx
|
|
304
304
|
import { calloutIcons, icon as kitIcon2 } from "@apliteni/apliteni-ui";
|
|
305
305
|
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
306
|
-
function Callout({ variant, icon:
|
|
306
|
+
function Callout({ variant, icon: icon9 = calloutIcons[variant ?? "neutral"], children, actions }) {
|
|
307
307
|
return /* @__PURE__ */ jsxs6("div", { className: `ui-callout${variant && variant !== "neutral" ? ` ui-callout--${variant}` : ""}`, role: variant === "danger" ? "alert" : void 0, children: [
|
|
308
|
-
/* @__PURE__ */ jsx10("span", { className: "ui-callout__icon", dangerouslySetInnerHTML: { __html: kitIcon2(
|
|
308
|
+
/* @__PURE__ */ jsx10("span", { className: "ui-callout__icon", dangerouslySetInnerHTML: { __html: kitIcon2(icon9) } }),
|
|
309
309
|
/* @__PURE__ */ jsxs6("div", { className: "ui-callout__body", children: [
|
|
310
310
|
children,
|
|
311
311
|
actions != null && /* @__PURE__ */ jsx10("div", { className: "ui-toolbar ui-callout__actions", children: actions })
|
|
@@ -1351,7 +1351,7 @@ function rowId(uid, groups, item) {
|
|
|
1351
1351
|
}
|
|
1352
1352
|
|
|
1353
1353
|
// src/DataTable.tsx
|
|
1354
|
-
import { useCallback as useCallback3, useEffect as useEffect6, useMemo as useMemo2, useRef as useRef10, useState as useState7 } from "react";
|
|
1354
|
+
import { Fragment as Fragment6, useCallback as useCallback3, useEffect as useEffect6, useMemo as useMemo2, useRef as useRef10, useState as useState7 } from "react";
|
|
1355
1355
|
import { DEFAULT_PAGE_SIZE as DEFAULT_PAGE_SIZE2 } from "@apliteni/apliteni-ui";
|
|
1356
1356
|
|
|
1357
1357
|
// src/Pagination.tsx
|
|
@@ -1579,7 +1579,8 @@ function Pagination({
|
|
|
1579
1579
|
}
|
|
1580
1580
|
|
|
1581
1581
|
// src/DataTable.tsx
|
|
1582
|
-
import { Fragment as
|
|
1582
|
+
import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1583
|
+
var CELL_CLASS = { title: "ui-table__title", code: "ui-table__code", long: "ui-table__long", strong: "ui-table__num--strong", act: "ui-table__act" };
|
|
1583
1584
|
var NO_SORT = { key: void 0, dir: -1 };
|
|
1584
1585
|
function sortTableRows(rows, sort) {
|
|
1585
1586
|
if (sort.key === void 0) return [...rows];
|
|
@@ -1589,6 +1590,12 @@ function sortTableRows(rows, sort) {
|
|
|
1589
1590
|
function DataTable({
|
|
1590
1591
|
columns,
|
|
1591
1592
|
rows,
|
|
1593
|
+
zebra = false,
|
|
1594
|
+
hover = true,
|
|
1595
|
+
stack: stack2 = false,
|
|
1596
|
+
rowState,
|
|
1597
|
+
footer,
|
|
1598
|
+
caption,
|
|
1592
1599
|
dense = false,
|
|
1593
1600
|
density,
|
|
1594
1601
|
stickyHeader = false,
|
|
@@ -1686,70 +1693,72 @@ function DataTable({
|
|
|
1686
1693
|
strokeLinejoin: "round",
|
|
1687
1694
|
"aria-hidden": "true",
|
|
1688
1695
|
focusable: "false",
|
|
1689
|
-
children: sort.key === k ? /* @__PURE__ */ jsx19("path", { d: "m8 10 4 4 4-4" }) : /* @__PURE__ */ jsxs15(
|
|
1696
|
+
children: sort.key === k ? /* @__PURE__ */ jsx19("path", { d: "m8 10 4 4 4-4" }) : /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
1690
1697
|
/* @__PURE__ */ jsx19("path", { d: "m8 9 4-4 4 4" }),
|
|
1691
1698
|
/* @__PURE__ */ jsx19("path", { d: "m8 15 4 4 4-4" })
|
|
1692
1699
|
] })
|
|
1693
1700
|
}
|
|
1694
1701
|
);
|
|
1702
|
+
const Wrap = scrollable ? "div" : Fragment6;
|
|
1695
1703
|
const pageAllOn = selectable && slice.length > 0 && slice.every((r) => selected.has(r.name));
|
|
1696
1704
|
const pageSomeOn = selectable && !pageAllOn && slice.some((r) => selected.has(r.name));
|
|
1697
|
-
return /* @__PURE__ */ jsxs15(
|
|
1698
|
-
/* @__PURE__ */ jsx19(
|
|
1699
|
-
"
|
|
1705
|
+
return /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
1706
|
+
/* @__PURE__ */ jsx19(Wrap, { ...scrollable ? { className: "ui-table-scroll", role: "region", "aria-label": scrollLabel, tabIndex: 0 } : {}, children: /* @__PURE__ */ jsxs15(
|
|
1707
|
+
"table",
|
|
1700
1708
|
{
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
"aria-
|
|
1704
|
-
|
|
1705
|
-
children:
|
|
1706
|
-
"
|
|
1707
|
-
{
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1709
|
+
ref: table,
|
|
1710
|
+
className: ["ui-table", hover && "ui-table--hover", zebra && "ui-table--zebra", stack2 && "ui-table--stack", (density === "dense" || !density && dense) && "ui-table--dense", density === "compact" && "ui-table--compact", stickyHeader && "ui-table--sticky", pinnedIdentity && "ui-table--pinned"].filter(Boolean).join(" "),
|
|
1711
|
+
"aria-busy": loading || void 0,
|
|
1712
|
+
role: stack2 ? "table" : void 0,
|
|
1713
|
+
children: [
|
|
1714
|
+
caption ? /* @__PURE__ */ jsx19("caption", { className: "ui-sr", children: caption }) : null,
|
|
1715
|
+
/* @__PURE__ */ jsx19("thead", { role: stack2 ? "rowgroup" : void 0, children: /* @__PURE__ */ jsxs15("tr", { role: stack2 ? "row" : void 0, children: [
|
|
1716
|
+
selectable ? /* @__PURE__ */ jsx19("th", { scope: "col", role: stack2 ? "columnheader" : void 0, className: "ui-table__selection", children: /* @__PURE__ */ jsx19(
|
|
1717
|
+
"input",
|
|
1718
|
+
{
|
|
1719
|
+
type: "checkbox",
|
|
1720
|
+
checked: pageAllOn,
|
|
1721
|
+
"aria-label": "Select all rows on this page",
|
|
1722
|
+
ref: (input) => {
|
|
1723
|
+
if (input) input.indeterminate = pageSomeOn;
|
|
1724
|
+
},
|
|
1725
|
+
onChange: () => onTogglePage(slice.map((r) => r.name))
|
|
1726
|
+
}
|
|
1727
|
+
) }) : null,
|
|
1728
|
+
columns.map((c, columnIndex) => (
|
|
1729
|
+
// The sort control is a real <button> inside the header cell. It used to be
|
|
1730
|
+
// role="button" ON the <th>, which threw away the columnheader role and put
|
|
1731
|
+
// aria-sort on a role that forbids it.
|
|
1732
|
+
/* @__PURE__ */ jsx19(
|
|
1733
|
+
"th",
|
|
1734
|
+
{
|
|
1735
|
+
scope: "col",
|
|
1736
|
+
role: stack2 ? "columnheader" : void 0,
|
|
1737
|
+
className: [pinnedIdentity && columnIndex === 0 && "ui-table__identity", c.num && "ui-table__num", c.sortable && "rx-sortable"].filter(Boolean).join(" "),
|
|
1738
|
+
"aria-sort": sort.key === c.key ? sort.dir === 1 ? "ascending" : "descending" : c.sortable && sortIsKnown ? "none" : void 0,
|
|
1739
|
+
children: c.sortable ? (
|
|
1740
|
+
// The label is its own box so it can truncate: in a pinned
|
|
1741
|
+
// identity column on a phone the header is capped, and a bare
|
|
1742
|
+
// text node would push the caret out of the cell instead.
|
|
1743
|
+
/* @__PURE__ */ jsxs15("button", { type: "button", className: "rx-sort", onClick: () => onSort(c.key), children: [
|
|
1744
|
+
/* @__PURE__ */ jsx19("span", { className: "rx-sort__label", children: c.label }),
|
|
1745
|
+
caret(c.key)
|
|
1746
|
+
] })
|
|
1747
|
+
) : c.label
|
|
1748
|
+
},
|
|
1749
|
+
c.key
|
|
1750
|
+
)
|
|
1751
|
+
))
|
|
1752
|
+
] }) }),
|
|
1753
|
+
/* @__PURE__ */ jsxs15("tbody", { role: stack2 ? "rowgroup" : void 0, children: [
|
|
1754
|
+
!slice.length && /* @__PURE__ */ jsx19("tr", { role: stack2 ? "row" : void 0, children: /* @__PURE__ */ jsx19("td", { role: stack2 ? "cell" : void 0, colSpan: columns.length + (selectable ? 1 : 0), children: loading ? "Loading rows\u2026" : empty }) }),
|
|
1755
|
+
slice.map((r) => /* @__PURE__ */ jsxs15(
|
|
1756
|
+
"tr",
|
|
1757
|
+
{
|
|
1758
|
+
role: stack2 ? "row" : void 0,
|
|
1759
|
+
className: rowState?.(r) ? `is-${rowState(r)}` : void 0,
|
|
1760
|
+
children: [
|
|
1761
|
+
selectable ? /* @__PURE__ */ jsx19("td", { role: stack2 ? "cell" : void 0, className: "ui-table__selection", children: /* @__PURE__ */ jsx19(
|
|
1753
1762
|
"input",
|
|
1754
1763
|
{
|
|
1755
1764
|
type: "checkbox",
|
|
@@ -1758,14 +1767,29 @@ function DataTable({
|
|
|
1758
1767
|
onChange: () => onToggle(r.name)
|
|
1759
1768
|
}
|
|
1760
1769
|
) }) : null,
|
|
1761
|
-
columns.map((c, columnIndex) =>
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1770
|
+
columns.map((c, columnIndex) => {
|
|
1771
|
+
const Cell = c.rowHeader ? "th" : "td";
|
|
1772
|
+
return /* @__PURE__ */ jsx19(
|
|
1773
|
+
Cell,
|
|
1774
|
+
{
|
|
1775
|
+
scope: c.rowHeader ? "row" : void 0,
|
|
1776
|
+
role: stack2 ? c.rowHeader ? "rowheader" : "cell" : void 0,
|
|
1777
|
+
"data-label": stack2 && c.num && typeof c.label === "string" ? c.label : void 0,
|
|
1778
|
+
className: [c.num && "ui-table__num", c.cell && CELL_CLASS[c.cell], pinnedIdentity && columnIndex === 0 && "ui-table__identity", c.linked && "ui-table__linked"].filter(Boolean).join(" ") || void 0,
|
|
1779
|
+
children: c.render ? c.render(r) : String(r[c.key])
|
|
1780
|
+
},
|
|
1781
|
+
c.key
|
|
1782
|
+
);
|
|
1783
|
+
})
|
|
1784
|
+
]
|
|
1785
|
+
},
|
|
1786
|
+
r.name
|
|
1787
|
+
))
|
|
1788
|
+
] }),
|
|
1789
|
+
footer ? /* @__PURE__ */ jsx19("tfoot", { role: stack2 ? "rowgroup" : void 0, children: footer }) : null
|
|
1790
|
+
]
|
|
1767
1791
|
}
|
|
1768
|
-
),
|
|
1792
|
+
) }),
|
|
1769
1793
|
pager ? (
|
|
1770
1794
|
// The strip that pages a table may not be wider than the rows it pages (#504).
|
|
1771
1795
|
// The two are siblings, and no selector sizes one to the other, so the width is
|
|
@@ -1858,12 +1882,12 @@ function Denied({
|
|
|
1858
1882
|
title = "You don\u2019t have access",
|
|
1859
1883
|
sub,
|
|
1860
1884
|
need,
|
|
1861
|
-
icon:
|
|
1885
|
+
icon: icon9 = "lock",
|
|
1862
1886
|
className,
|
|
1863
1887
|
children
|
|
1864
1888
|
}) {
|
|
1865
1889
|
return /* @__PURE__ */ jsxs16("div", { className: cx4("ui-denied", className), children: [
|
|
1866
|
-
/* @__PURE__ */ jsx20("div", { className: "ui-denied__seal", children: /* @__PURE__ */ jsx20(Icon, { name:
|
|
1890
|
+
/* @__PURE__ */ jsx20("div", { className: "ui-denied__seal", children: /* @__PURE__ */ jsx20(Icon, { name: icon9 }) }),
|
|
1867
1891
|
/* @__PURE__ */ jsx20("div", { className: "ui-denied__title", children: title }),
|
|
1868
1892
|
sub && /* @__PURE__ */ jsx20("div", { className: "ui-denied__sub", children: sub }),
|
|
1869
1893
|
need && /* @__PURE__ */ jsxs16("div", { className: "ui-denied__need", children: [
|
|
@@ -2347,7 +2371,7 @@ function DatePicker({
|
|
|
2347
2371
|
|
|
2348
2372
|
// src/Dropdown.tsx
|
|
2349
2373
|
import {
|
|
2350
|
-
Fragment as
|
|
2374
|
+
Fragment as Fragment8,
|
|
2351
2375
|
useCallback as useCallback5,
|
|
2352
2376
|
useContext as useContext2,
|
|
2353
2377
|
useEffect as useEffect8,
|
|
@@ -2375,7 +2399,7 @@ import { createContext as createContext2 } from "react";
|
|
|
2375
2399
|
var FieldContext = createContext2(null);
|
|
2376
2400
|
|
|
2377
2401
|
// src/Dropdown.tsx
|
|
2378
|
-
import { Fragment as
|
|
2402
|
+
import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2379
2403
|
var EXIT_SLACK_MS2 = 50;
|
|
2380
2404
|
var SETTLE_MS = 450;
|
|
2381
2405
|
var inPanel = (node) => {
|
|
@@ -2416,6 +2440,7 @@ var SEARCH_DEFAULTS = {
|
|
|
2416
2440
|
function Dropdown({
|
|
2417
2441
|
label,
|
|
2418
2442
|
value,
|
|
2443
|
+
selectedValue,
|
|
2419
2444
|
placeholder = "Select\u2026",
|
|
2420
2445
|
variant,
|
|
2421
2446
|
items,
|
|
@@ -2560,15 +2585,16 @@ function Dropdown({
|
|
|
2560
2585
|
const name = ariaLabel || (label ? String(label).replace(/:\s*$/, "") : "") || "Options";
|
|
2561
2586
|
const given = rows.find((it) => it.selected);
|
|
2562
2587
|
const givenKey = given ? keyOf(given) : null;
|
|
2563
|
-
const pickedKey = pick && pick.against === givenKey ? pick.key : null;
|
|
2588
|
+
const pickedKey = selectedValue === void 0 && pick && pick.against === givenKey ? pick.key : null;
|
|
2564
2589
|
useEffect8(() => {
|
|
2565
2590
|
if (pick && pick.against !== givenKey) setPick(null);
|
|
2566
2591
|
}, [givenKey, pick]);
|
|
2567
2592
|
const picked = pickedKey != null ? rows.find((it) => keyOf(it) === pickedKey) : void 0;
|
|
2568
|
-
const
|
|
2593
|
+
const controlled = selectedValue !== void 0 ? rows.find((it) => it.value === selectedValue) : void 0;
|
|
2594
|
+
const shown = value != null ? value : isSelect ? selectedValue !== void 0 ? controlled?.label : picked?.label ?? given?.label : null;
|
|
2569
2595
|
const marked2 = isSelect && rows.some((it) => it.avatar);
|
|
2570
|
-
const chosen = marked2 ? value != null ? rows.find((it) => it.label === value) : picked ?? given : void 0;
|
|
2571
|
-
const selectedOf = (it) => pickedKey != null ? it.disabled ? !!it.selected : keyOf(it) === pickedKey : !!it.selected;
|
|
2596
|
+
const chosen = marked2 ? value != null ? rows.find((it) => it.label === value) : selectedValue !== void 0 ? controlled : picked ?? given : void 0;
|
|
2597
|
+
const selectedOf = (it) => selectedValue !== void 0 ? it.value === selectedValue : pickedKey != null ? it.disabled ? !!it.selected : keyOf(it) === pickedKey : !!it.selected;
|
|
2572
2598
|
const hiddenBy = (it) => Boolean(sx) && !dropdownMatch(it.label, query);
|
|
2573
2599
|
const filtering = Boolean(sx) && dropdownFiltering(query);
|
|
2574
2600
|
const visible = rows.filter((it) => !hiddenBy(it));
|
|
@@ -2746,7 +2772,7 @@ function Dropdown({
|
|
|
2746
2772
|
e.preventDefault();
|
|
2747
2773
|
return;
|
|
2748
2774
|
}
|
|
2749
|
-
if (isSelect) setPick({ key: keyOf(item), against: givenKey });
|
|
2775
|
+
if (isSelect && selectedValue === void 0) setPick({ key: keyOf(item), against: givenKey });
|
|
2750
2776
|
onSelect?.(item.value, item);
|
|
2751
2777
|
setOpen(false);
|
|
2752
2778
|
trigger.current?.focus();
|
|
@@ -2838,7 +2864,7 @@ function Dropdown({
|
|
|
2838
2864
|
...asLink ? { href: entry.href, ...entry.target ? { target: entry.target } : null } : null,
|
|
2839
2865
|
...sx ? { id: rowIds.get(entry), hidden: hiddenBy(entry) || void 0 } : null,
|
|
2840
2866
|
onClick: (e) => choose(entry, e),
|
|
2841
|
-
children: /* @__PURE__ */ jsxs18(
|
|
2867
|
+
children: /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
2842
2868
|
entry.avatar ? /* @__PURE__ */ jsx22(Avatar, { personKey: entry.avatar.key, name: entry.avatar.name, src: entry.avatar.src, empty: entry.avatar.empty }) : entry.icon && /* @__PURE__ */ jsx22(Glyph2, { name: entry.icon, className: "ui-dropdown__ic" }),
|
|
2843
2869
|
/* @__PURE__ */ jsxs18("span", { className: "ui-dropdown__main", children: [
|
|
2844
2870
|
/* @__PURE__ */ jsx22("span", { className: "ui-dropdown__label", children: entry.label }),
|
|
@@ -2848,7 +2874,7 @@ function Dropdown({
|
|
|
2848
2874
|
asOption && /* @__PURE__ */ jsx22(Glyph2, { name: "check", className: "ui-dropdown__tick", hidden: true })
|
|
2849
2875
|
] })
|
|
2850
2876
|
};
|
|
2851
|
-
if (row) return /* @__PURE__ */ jsx22(
|
|
2877
|
+
if (row) return /* @__PURE__ */ jsx22(Fragment8, { children: row(entry, props) }, key);
|
|
2852
2878
|
const Tag = asLink ? "a" : "div";
|
|
2853
2879
|
return /* @__PURE__ */ jsx22(Tag, { ...props }, key);
|
|
2854
2880
|
}
|
|
@@ -2870,7 +2896,7 @@ function Dropdown({
|
|
|
2870
2896
|
);
|
|
2871
2897
|
}) : (items || []).map((entry, i) => renderRow(entry, `i${i}`));
|
|
2872
2898
|
const cap = scroll && scroll !== true ? { "--ui-dropdown-cap": typeof scroll === "number" ? `${scroll}px` : scroll } : void 0;
|
|
2873
|
-
const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs18(
|
|
2899
|
+
const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
2874
2900
|
/* @__PURE__ */ jsx22("span", { className: "ui-dropdown__none-title", children: sx.empty.replace("{q}", () => query.trim()) }),
|
|
2875
2901
|
/* @__PURE__ */ jsx22("span", { className: "ui-dropdown__none-hint", children: sx.hint })
|
|
2876
2902
|
] }) : null;
|
|
@@ -2895,7 +2921,7 @@ function Dropdown({
|
|
|
2895
2921
|
setOpen(!open);
|
|
2896
2922
|
},
|
|
2897
2923
|
children: [
|
|
2898
|
-
triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs18(
|
|
2924
|
+
triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
2899
2925
|
marked2 && (chosen?.avatar ? /* @__PURE__ */ jsx22(Avatar, { personKey: chosen.avatar.key, name: chosen.avatar.name, src: chosen.avatar.src, empty: chosen.avatar.empty }) : /* @__PURE__ */ jsx22(Avatar, { empty: true })),
|
|
2900
2926
|
label && /* @__PURE__ */ jsx22("span", { className: "ui-dropdown__pre", children: label }),
|
|
2901
2927
|
/* @__PURE__ */ jsx22("span", { className: cx6("ui-dropdown__value", marked2 && !chosen && "is-placeholder"), children: shown != null ? shown : placeholder })
|
|
@@ -2925,7 +2951,7 @@ function Dropdown({
|
|
|
2925
2951
|
onMouseMove,
|
|
2926
2952
|
children: [
|
|
2927
2953
|
header,
|
|
2928
|
-
sx ? /* @__PURE__ */ jsxs18(
|
|
2954
|
+
sx ? /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
2929
2955
|
/* @__PURE__ */ jsxs18("div", { className: "ui-dropdown__search", children: [
|
|
2930
2956
|
/* @__PURE__ */ jsx22(Glyph2, { name: "search", className: "ui-dropdown__search-ic", hidden: true }),
|
|
2931
2957
|
/* @__PURE__ */ jsx22(
|
|
@@ -3076,7 +3102,7 @@ function Segmented({ options, value, onChange, label, appearance = "pill", size,
|
|
|
3076
3102
|
// src/FilterBar.tsx
|
|
3077
3103
|
import { useRef as useRef13, useState as useState10 } from "react";
|
|
3078
3104
|
import { filterChipText, filterChipName, filterChipUnset, filterChipItems, focusNextStop } from "@apliteni/apliteni-ui";
|
|
3079
|
-
import { Fragment as
|
|
3105
|
+
import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3080
3106
|
var SEARCH_AT = 10;
|
|
3081
3107
|
var isRow2 = (entry) => entry !== "---" && !entry.separator;
|
|
3082
3108
|
function FilterBar({ filters, label = "Filters", clearLabel = "Clear all", clearVariant = "ghost", add, addLabel = "Filter", disabled = false, busy = false, onRemove, onClear, onChange, onAdd }) {
|
|
@@ -3183,7 +3209,7 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all", clear
|
|
|
3183
3209
|
variant: "menu",
|
|
3184
3210
|
sections,
|
|
3185
3211
|
ariaLabel: addLabel,
|
|
3186
|
-
triggerContent: /* @__PURE__ */ jsxs21(
|
|
3212
|
+
triggerContent: /* @__PURE__ */ jsxs21(Fragment10, { children: [
|
|
3187
3213
|
/* @__PURE__ */ jsx26(Icon, { name: "plus" }),
|
|
3188
3214
|
addLabel
|
|
3189
3215
|
] }),
|
|
@@ -3234,7 +3260,7 @@ function DrawerSection({ title, headingLevel = 3, className, children, ...rest }
|
|
|
3234
3260
|
|
|
3235
3261
|
// src/Snippet.tsx
|
|
3236
3262
|
import { useEffect as useEffect9, useRef as useRef14, useState as useState11 } from "react";
|
|
3237
|
-
import { Fragment as
|
|
3263
|
+
import { Fragment as Fragment11, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3238
3264
|
function Snippet({ label = "shell", code = "", children, copy = true, reveal = false, copyLabel = "Copy code" }) {
|
|
3239
3265
|
const [status, setStatus] = useState11("idle");
|
|
3240
3266
|
const request = useRef14(0);
|
|
@@ -3262,7 +3288,7 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
|
|
|
3262
3288
|
return /* @__PURE__ */ jsxs23("div", { className: reveal ? "ui-snippet ui-snippet--reveal" : "ui-snippet", children: [
|
|
3263
3289
|
/* @__PURE__ */ jsxs23("div", { className: "ui-snippet__bar", children: [
|
|
3264
3290
|
/* @__PURE__ */ jsx28("span", { children: label }),
|
|
3265
|
-
copy && /* @__PURE__ */ jsxs23(
|
|
3291
|
+
copy && /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
3266
3292
|
/* @__PURE__ */ jsx28(
|
|
3267
3293
|
"button",
|
|
3268
3294
|
{
|
|
@@ -3284,7 +3310,7 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
|
|
|
3284
3310
|
// src/Tabs.tsx
|
|
3285
3311
|
import { useEffect as useEffect10, useId as useId9, useRef as useRef15 } from "react";
|
|
3286
3312
|
import { playEntrance } from "@apliteni/apliteni-ui/motion";
|
|
3287
|
-
import { Fragment as
|
|
3313
|
+
import { Fragment as Fragment12, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3288
3314
|
function Tabs({ items, value, onChange, label }) {
|
|
3289
3315
|
const id = useId9();
|
|
3290
3316
|
const previous = useRef15(value);
|
|
@@ -3333,7 +3359,7 @@ function Tabs({ items, value, onChange, label }) {
|
|
|
3333
3359
|
},
|
|
3334
3360
|
children: [
|
|
3335
3361
|
item.label,
|
|
3336
|
-
item.count != null && /* @__PURE__ */ jsxs24(
|
|
3362
|
+
item.count != null && /* @__PURE__ */ jsxs24(Fragment12, { children: [
|
|
3337
3363
|
" ",
|
|
3338
3364
|
item.count
|
|
3339
3365
|
] })
|
|
@@ -3571,11 +3597,11 @@ var cases = {
|
|
|
3571
3597
|
"not-found": { title: "We can't find that page", sub: "Check the address or return to the home page.", icon: "folder" },
|
|
3572
3598
|
"not-yet-built": { title: "This ships later", sub: "This screen is not available yet. Check back later.", icon: "clock" }
|
|
3573
3599
|
};
|
|
3574
|
-
function EmptyState({ variant = "first-run", title, sub, icon:
|
|
3600
|
+
function EmptyState({ variant = "first-run", title, sub, icon: icon9, art, actions }) {
|
|
3575
3601
|
const preset = cases[variant];
|
|
3576
3602
|
const heading = title ?? preset.title;
|
|
3577
3603
|
const guidance = sub ?? preset.sub;
|
|
3578
|
-
const glyph =
|
|
3604
|
+
const glyph = icon9 ?? preset.icon;
|
|
3579
3605
|
return /* @__PURE__ */ jsxs27("div", { className: "ui-empty", children: [
|
|
3580
3606
|
art ? typeof art === "string" ? /* @__PURE__ */ jsx32("div", { className: "ui-empty__art", dangerouslySetInnerHTML: { __html: /<svg/.test(art) ? art : illo(art) } }) : /* @__PURE__ */ jsx32("div", { className: "ui-empty__art", "aria-hidden": "true", children: art }) : glyph ? /* @__PURE__ */ jsx32("div", { className: "ui-empty__icon", dangerouslySetInnerHTML: { __html: kitIcon3(glyph) } }) : null,
|
|
3581
3607
|
heading && /* @__PURE__ */ jsx32("div", { className: "ui-empty__title", children: heading }),
|
|
@@ -3585,7 +3611,7 @@ function EmptyState({ variant = "first-run", title, sub, icon: icon8, art, actio
|
|
|
3585
3611
|
}
|
|
3586
3612
|
|
|
3587
3613
|
// src/FileDrop.tsx
|
|
3588
|
-
import { Fragment as
|
|
3614
|
+
import { Fragment as Fragment13, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
3589
3615
|
var MARKS = {
|
|
3590
3616
|
uploading: "clock",
|
|
3591
3617
|
done: "circleCheck",
|
|
@@ -3753,7 +3779,7 @@ function FileDrop({
|
|
|
3753
3779
|
children: /* @__PURE__ */ jsx33("span", { style: { width: `${file.progress}%` } })
|
|
3754
3780
|
}
|
|
3755
3781
|
)
|
|
3756
|
-
] }) : /* @__PURE__ */ jsxs28(
|
|
3782
|
+
] }) : /* @__PURE__ */ jsxs28(Fragment13, { children: [
|
|
3757
3783
|
/* @__PURE__ */ jsx33(
|
|
3758
3784
|
Button,
|
|
3759
3785
|
{
|
|
@@ -3936,7 +3962,7 @@ import { paletteHotkey, prism, railCollapsed } from "@apliteni/apliteni-ui";
|
|
|
3936
3962
|
// src/SidebarNav.tsx
|
|
3937
3963
|
import { forwardRef as forwardRef8, useEffect as useEffect14, useId as useId11, useState as useState15 } from "react";
|
|
3938
3964
|
import { ENTRANCE_FALLBACK_MS } from "@apliteni/apliteni-ui/motion";
|
|
3939
|
-
import { Fragment as
|
|
3965
|
+
import { Fragment as Fragment14, jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3940
3966
|
var badgeText = (badge) => typeof badge === "object" ? badge.text : badge;
|
|
3941
3967
|
function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
|
|
3942
3968
|
const uid = useId11();
|
|
@@ -3962,7 +3988,7 @@ function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
|
|
|
3962
3988
|
item.disabled && "is-disabled",
|
|
3963
3989
|
item.danger && "is-danger"
|
|
3964
3990
|
].filter(Boolean).join(" ");
|
|
3965
|
-
const children = /* @__PURE__ */ jsxs31(
|
|
3991
|
+
const children = /* @__PURE__ */ jsxs31(Fragment14, { children: [
|
|
3966
3992
|
(item.leading ?? item.icon) && /* @__PURE__ */ jsx36("span", { className: "ui-nav__ic", children: item.leading ?? /* @__PURE__ */ jsx36(Icon, { name: item.icon }) }),
|
|
3967
3993
|
/* @__PURE__ */ jsx36("span", { className: "ui-nav__label", children: item.label }),
|
|
3968
3994
|
count != null && count !== "" && /* @__PURE__ */ jsx36("span", { className: `ui-nav__badge is-${typeof item.badge === "object" ? item.badge.tone ?? "neutral" : "neutral"}`, children: count }),
|
|
@@ -4102,7 +4128,7 @@ function ThemeToggle({ labelled = false }) {
|
|
|
4102
4128
|
}
|
|
4103
4129
|
|
|
4104
4130
|
// src/AppShell.tsx
|
|
4105
|
-
import { Fragment as
|
|
4131
|
+
import { Fragment as Fragment15, jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
4106
4132
|
var path = (value) => value.split(/[?#]/)[0].replace(/\/+$/, "") || "/";
|
|
4107
4133
|
function AppShell({
|
|
4108
4134
|
sections,
|
|
@@ -4204,7 +4230,7 @@ function AppShell({
|
|
|
4204
4230
|
] }),
|
|
4205
4231
|
/* @__PURE__ */ jsxs33("div", { className: "ui-app__well", children: [
|
|
4206
4232
|
/* @__PURE__ */ jsxs33("header", { className: "ui-app__bar", children: [
|
|
4207
|
-
navigable && /* @__PURE__ */ jsxs33(
|
|
4233
|
+
navigable && /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
4208
4234
|
/* @__PURE__ */ jsx38(
|
|
4209
4235
|
Button,
|
|
4210
4236
|
{
|
|
@@ -4317,10 +4343,10 @@ function Footer({
|
|
|
4317
4343
|
brand !== false && /* @__PURE__ */ jsxs34("div", { className: "ui-footer__brand", children: [
|
|
4318
4344
|
lockup,
|
|
4319
4345
|
tagline && /* @__PURE__ */ jsx39("p", { className: "ui-footer__tagline", children: tagline }),
|
|
4320
|
-
social.length > 0 && /* @__PURE__ */ jsx39("div", { className: "ui-footer__socials", children: social.map(({ label, href: to, icon:
|
|
4321
|
-
const markup = SOCIAL_GLYPHS[
|
|
4322
|
-
const fill =
|
|
4323
|
-
const viewBox =
|
|
4346
|
+
social.length > 0 && /* @__PURE__ */ jsx39("div", { className: "ui-footer__socials", children: social.map(({ label, href: to, icon: icon9 = "github" }) => {
|
|
4347
|
+
const markup = SOCIAL_GLYPHS[icon9];
|
|
4348
|
+
const fill = icon9 === "mail" ? "none" : "currentColor";
|
|
4349
|
+
const viewBox = icon9 === "linkedin" ? "0 0 448 512" : "0 0 24 24";
|
|
4324
4350
|
return /* @__PURE__ */ jsx39("a", { className: "ui-footer__social", href: safeUrl2(to ?? "#"), "aria-label": label, children: /* @__PURE__ */ jsx39("svg", { viewBox, fill, "aria-hidden": "true", dangerouslySetInnerHTML: { __html: markup } }) }, label);
|
|
4325
4351
|
}) })
|
|
4326
4352
|
] }),
|
|
@@ -4467,7 +4493,7 @@ import {
|
|
|
4467
4493
|
useState as useState18
|
|
4468
4494
|
} from "react";
|
|
4469
4495
|
import { CHART_FLOOR, bridgeWalk, chartScale, pointTarget } from "@apliteni/apliteni-ui";
|
|
4470
|
-
import { Fragment as
|
|
4496
|
+
import { Fragment as Fragment16, jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
4471
4497
|
var HEIGHT = { months: 216, bridge: 216, spark: 32 };
|
|
4472
4498
|
var PAD = 2;
|
|
4473
4499
|
var ZERO_INSET = 1.5;
|
|
@@ -5097,7 +5123,7 @@ function Chart(props) {
|
|
|
5097
5123
|
`${column.label}-${i}`
|
|
5098
5124
|
)) })
|
|
5099
5125
|
] }) }),
|
|
5100
|
-
/* @__PURE__ */ jsx41("span", { ref: tipEl, className: cx8("ui-tip", openId && "is-open"), role: open ? "tooltip" : void 0, children: open && /* @__PURE__ */ jsxs36(
|
|
5126
|
+
/* @__PURE__ */ jsx41("span", { ref: tipEl, className: cx8("ui-tip", openId && "is-open"), role: open ? "tooltip" : void 0, children: open && /* @__PURE__ */ jsxs36(Fragment16, { children: [
|
|
5101
5127
|
/* @__PURE__ */ jsx41("span", { className: "ui-tip__label", children: spark ? columns[open.column]?.label : `${open.name}, ${columns[open.column]?.label}` }),
|
|
5102
5128
|
/* @__PURE__ */ jsx41("span", { className: "ui-tip__value", children: format(open.value) }),
|
|
5103
5129
|
(stateOf(columns[open.column]) || open.detail) && /* @__PURE__ */ jsx41("span", { className: "ui-tip__detail", children: stateOf(columns[open.column]) || open.detail })
|
|
@@ -5120,7 +5146,7 @@ function Chart(props) {
|
|
|
5120
5146
|
/* @__PURE__ */ jsx41("tbody", { children: tableRows.map((row, i) => /* @__PURE__ */ jsxs36("tr", { "aria-current": pick === i ? true : void 0, children: [
|
|
5121
5147
|
/* @__PURE__ */ jsxs36("th", { scope: "row", children: [
|
|
5122
5148
|
row.column.label,
|
|
5123
|
-
row.column.estimated && /* @__PURE__ */ jsxs36(
|
|
5149
|
+
row.column.estimated && /* @__PURE__ */ jsxs36(Fragment16, { children: [
|
|
5124
5150
|
" ",
|
|
5125
5151
|
/* @__PURE__ */ jsx41("span", { className: "ui-chart__state", children: stateOf(row.column) })
|
|
5126
5152
|
] })
|
|
@@ -5177,10 +5203,145 @@ var AccentPicker = forwardRef10(function AccentPicker2({
|
|
|
5177
5203
|
);
|
|
5178
5204
|
});
|
|
5179
5205
|
|
|
5206
|
+
// src/TopBar.tsx
|
|
5207
|
+
import { Fragment as Fragment17 } from "react";
|
|
5208
|
+
import { prism as prism3, safeUrl as safeUrl3, icon as icon7, ACCOUNT_NAV } from "@apliteni/apliteni-ui";
|
|
5209
|
+
import { Fragment as Fragment18, jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
5210
|
+
function TopBar({
|
|
5211
|
+
brand,
|
|
5212
|
+
word = "Strategy",
|
|
5213
|
+
brandHref = "/",
|
|
5214
|
+
view,
|
|
5215
|
+
version,
|
|
5216
|
+
theme,
|
|
5217
|
+
account,
|
|
5218
|
+
className,
|
|
5219
|
+
...rest
|
|
5220
|
+
}) {
|
|
5221
|
+
return /* @__PURE__ */ jsx43("header", { ...rest, className: ["topbar", className].filter(Boolean).join(" "), children: /* @__PURE__ */ jsxs37("div", { className: "topbar__in", children: [
|
|
5222
|
+
brand ?? /* @__PURE__ */ jsxs37("a", { className: "brand", href: safeUrl3(brandHref), "aria-label": `Apliteni ${word}`, children: [
|
|
5223
|
+
/* @__PURE__ */ jsx43("span", { "aria-hidden": "true", dangerouslySetInnerHTML: { __html: prism3("tb-mark", 22) } }),
|
|
5224
|
+
/* @__PURE__ */ jsx43("span", { children: word })
|
|
5225
|
+
] }),
|
|
5226
|
+
view,
|
|
5227
|
+
/* @__PURE__ */ jsx43("span", { className: "spacer" }),
|
|
5228
|
+
version,
|
|
5229
|
+
theme,
|
|
5230
|
+
account
|
|
5231
|
+
] }) });
|
|
5232
|
+
}
|
|
5233
|
+
function ViewSwitch({ items, active, label = "View", renderLink }) {
|
|
5234
|
+
return /* @__PURE__ */ jsx43("div", { className: "dtsw on", role: "group", "aria-label": label, children: items.map((item) => {
|
|
5235
|
+
const current = item.id === active;
|
|
5236
|
+
const linkProps = {
|
|
5237
|
+
className: current ? "cur" : void 0,
|
|
5238
|
+
href: safeUrl3(item.href || `#${item.id}`),
|
|
5239
|
+
target: item.target,
|
|
5240
|
+
"aria-current": current ? "page" : void 0,
|
|
5241
|
+
children: item.label
|
|
5242
|
+
};
|
|
5243
|
+
return /* @__PURE__ */ jsx43(Fragment17, { children: renderLink ? renderLink(item, linkProps) : /* @__PURE__ */ jsx43("a", { ...linkProps }) }, item.id);
|
|
5244
|
+
}) });
|
|
5245
|
+
}
|
|
5246
|
+
var BADGE = { live: "Live", archive: "Archive" };
|
|
5247
|
+
function VersionSwitcher({ versions, value, onChange, label = "Version", defaultOpen }) {
|
|
5248
|
+
const current = versions.find((v) => v.value === value);
|
|
5249
|
+
return /* @__PURE__ */ jsx43("div", { className: "vsw", children: /* @__PURE__ */ jsx43(
|
|
5250
|
+
Dropdown,
|
|
5251
|
+
{
|
|
5252
|
+
variant: "select",
|
|
5253
|
+
align: "start",
|
|
5254
|
+
triggerClass: "vsw__btn",
|
|
5255
|
+
panelClass: "vsw__menu",
|
|
5256
|
+
selectedValue: value,
|
|
5257
|
+
chevron: false,
|
|
5258
|
+
defaultOpen,
|
|
5259
|
+
ariaLabel: `${label} \u2014 ${current?.label ?? ""}`,
|
|
5260
|
+
triggerContent: /* @__PURE__ */ jsxs37(Fragment18, { children: [
|
|
5261
|
+
/* @__PURE__ */ jsx43("span", { className: "cur", children: current?.label }),
|
|
5262
|
+
/* @__PURE__ */ jsx43("span", { className: "car", "aria-hidden": "true" })
|
|
5263
|
+
] }),
|
|
5264
|
+
items: versions.map((v) => ({
|
|
5265
|
+
label: v.label,
|
|
5266
|
+
value: v.value,
|
|
5267
|
+
badge: BADGE[v.badge ?? "archive"],
|
|
5268
|
+
selected: v.value === value
|
|
5269
|
+
})),
|
|
5270
|
+
row: (item, props) => /* @__PURE__ */ jsxs37("div", { ...props, className: `${props.className} vopt`, children: [
|
|
5271
|
+
/* @__PURE__ */ jsx43("span", { className: "vname", children: item.label }),
|
|
5272
|
+
/* @__PURE__ */ jsx43("span", { className: `vbadge ${item.badge === "Live" ? "live" : "arch"}`, children: String(item.badge) }),
|
|
5273
|
+
/* @__PURE__ */ jsx43("span", { className: "vtick", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon7("check") } })
|
|
5274
|
+
] }),
|
|
5275
|
+
onSelect: (picked) => {
|
|
5276
|
+
if (picked != null) onChange?.(String(picked));
|
|
5277
|
+
}
|
|
5278
|
+
}
|
|
5279
|
+
) });
|
|
5280
|
+
}
|
|
5281
|
+
var initialsOf = (name, email) => {
|
|
5282
|
+
const from = name.trim() || email.split("@")[0] || "";
|
|
5283
|
+
return (from.split(/[\s._-]+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("") || "?").toUpperCase();
|
|
5284
|
+
};
|
|
5285
|
+
var ACCOUNT_ITEMS = ACCOUNT_NAV.map((item) => ({
|
|
5286
|
+
label: item.label,
|
|
5287
|
+
icon: item.icon,
|
|
5288
|
+
value: item.id,
|
|
5289
|
+
href: `#${item.id}`
|
|
5290
|
+
}));
|
|
5291
|
+
function AccountMenu({
|
|
5292
|
+
name,
|
|
5293
|
+
email,
|
|
5294
|
+
items = ACCOUNT_ITEMS,
|
|
5295
|
+
current = "prefs",
|
|
5296
|
+
signOutHref,
|
|
5297
|
+
onSignOut,
|
|
5298
|
+
onSelect,
|
|
5299
|
+
defaultOpen
|
|
5300
|
+
}) {
|
|
5301
|
+
const mark = initialsOf(name, email);
|
|
5302
|
+
return /* @__PURE__ */ jsx43("div", { className: "acct on", children: /* @__PURE__ */ jsx43(
|
|
5303
|
+
Dropdown,
|
|
5304
|
+
{
|
|
5305
|
+
variant: "menu",
|
|
5306
|
+
align: "end",
|
|
5307
|
+
chevron: false,
|
|
5308
|
+
triggerClass: "avatar",
|
|
5309
|
+
panelClass: "amenu",
|
|
5310
|
+
defaultOpen,
|
|
5311
|
+
ariaLabel: "Account",
|
|
5312
|
+
triggerContent: mark,
|
|
5313
|
+
header: /* @__PURE__ */ jsxs37("div", { className: "ahead", children: [
|
|
5314
|
+
/* @__PURE__ */ jsx43("span", { className: "avatar", children: mark }),
|
|
5315
|
+
/* @__PURE__ */ jsxs37("span", { className: "aw", children: [
|
|
5316
|
+
/* @__PURE__ */ jsx43("span", { className: "anm", children: name }),
|
|
5317
|
+
/* @__PURE__ */ jsx43("span", { className: "aem", title: email, children: email })
|
|
5318
|
+
] })
|
|
5319
|
+
] }),
|
|
5320
|
+
items: [...items, "---", { label: "Sign out", icon: "logout", value: "sign-out", href: signOutHref }],
|
|
5321
|
+
row: (item, props) => /* @__PURE__ */ jsxs37(
|
|
5322
|
+
"a",
|
|
5323
|
+
{
|
|
5324
|
+
...props,
|
|
5325
|
+
href: item.disabled ? void 0 : item.href ? safeUrl3(item.href) : item.value === "sign-out" && onSignOut ? void 0 : safeUrl3(item.value === "sign-out" ? "#logout" : `#${item.value}`),
|
|
5326
|
+
className: [props.className.replace(/\bui-dropdown__item\b/, "").trim(), !item.disabled && item.value === current && "cur", item.value === "sign-out" && "aout"].filter(Boolean).join(" "),
|
|
5327
|
+
children: [
|
|
5328
|
+
item.icon && /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon7(item.icon) } }),
|
|
5329
|
+
item.label
|
|
5330
|
+
]
|
|
5331
|
+
}
|
|
5332
|
+
),
|
|
5333
|
+
onSelect: (value, item) => {
|
|
5334
|
+
if (item.value === "sign-out") onSignOut?.();
|
|
5335
|
+
else onSelect?.(value);
|
|
5336
|
+
}
|
|
5337
|
+
}
|
|
5338
|
+
) });
|
|
5339
|
+
}
|
|
5340
|
+
|
|
5180
5341
|
// src/NavTabs.tsx
|
|
5181
|
-
import { Fragment as
|
|
5182
|
-
import { safeUrl as
|
|
5183
|
-
import { Fragment as
|
|
5342
|
+
import { Fragment as Fragment19, forwardRef as forwardRef11, useEffect as useEffect18, useRef as useRef23, useImperativeHandle as useImperativeHandle2 } from "react";
|
|
5343
|
+
import { safeUrl as safeUrl4, observeNavFit, revealCurrentNav, revealFocusedNav } from "@apliteni/apliteni-ui";
|
|
5344
|
+
import { Fragment as Fragment20, jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
5184
5345
|
var NavTabs = forwardRef11(function NavTabs2({
|
|
5185
5346
|
items,
|
|
5186
5347
|
active,
|
|
@@ -5198,7 +5359,7 @@ var NavTabs = forwardRef11(function NavTabs2({
|
|
|
5198
5359
|
useEffect18(() => {
|
|
5199
5360
|
if (navRef.current) revealCurrentNav(navRef.current);
|
|
5200
5361
|
}, [active, signature]);
|
|
5201
|
-
return /* @__PURE__ */
|
|
5362
|
+
return /* @__PURE__ */ jsx44(
|
|
5202
5363
|
"nav",
|
|
5203
5364
|
{
|
|
5204
5365
|
...rest,
|
|
@@ -5211,20 +5372,20 @@ var NavTabs = forwardRef11(function NavTabs2({
|
|
|
5211
5372
|
},
|
|
5212
5373
|
children: items.map((item) => {
|
|
5213
5374
|
const badge = item.badge != null && typeof item.badge === "object" ? item.badge : { text: item.badge, tone: void 0 };
|
|
5214
|
-
const inner = /* @__PURE__ */
|
|
5215
|
-
/* @__PURE__ */
|
|
5216
|
-
badge.text != null && badge.text !== "" && /* @__PURE__ */
|
|
5375
|
+
const inner = /* @__PURE__ */ jsxs38(Fragment20, { children: [
|
|
5376
|
+
/* @__PURE__ */ jsx44("span", { className: "ui-nav__tab-label", children: item.label }),
|
|
5377
|
+
badge.text != null && badge.text !== "" && /* @__PURE__ */ jsx44("span", { className: `ui-nav__badge is-${badge.tone || "neutral"}`, children: badge.text })
|
|
5217
5378
|
] });
|
|
5218
|
-
if (item.disabled) return /* @__PURE__ */
|
|
5379
|
+
if (item.disabled) return /* @__PURE__ */ jsx44("span", { className: "ui-nav__tab is-disabled", "aria-disabled": "true", children: inner }, item.id);
|
|
5219
5380
|
const current = item.id === active;
|
|
5220
5381
|
const linkProps = {
|
|
5221
5382
|
className: ["ui-nav__tab", current && "is-active"].filter(Boolean).join(" "),
|
|
5222
|
-
href:
|
|
5383
|
+
href: safeUrl4(item.href || `#${item.id}`),
|
|
5223
5384
|
target: item.target,
|
|
5224
5385
|
"aria-current": current ? "page" : void 0,
|
|
5225
5386
|
children: inner
|
|
5226
5387
|
};
|
|
5227
|
-
return /* @__PURE__ */
|
|
5388
|
+
return /* @__PURE__ */ jsx44(Fragment19, { children: renderLink ? renderLink(item, linkProps) : /* @__PURE__ */ jsx44("a", { ...linkProps }) }, item.id);
|
|
5228
5389
|
})
|
|
5229
5390
|
}
|
|
5230
5391
|
);
|
|
@@ -5232,8 +5393,8 @@ var NavTabs = forwardRef11(function NavTabs2({
|
|
|
5232
5393
|
|
|
5233
5394
|
// src/Breadcrumbs.tsx
|
|
5234
5395
|
import { forwardRef as forwardRef12 } from "react";
|
|
5235
|
-
import { icon as
|
|
5236
|
-
import { Fragment as
|
|
5396
|
+
import { icon as icon8, safeUrl as safeUrl5 } from "@apliteni/apliteni-ui";
|
|
5397
|
+
import { Fragment as Fragment21, jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
5237
5398
|
var Breadcrumbs = forwardRef12(function Breadcrumbs2({
|
|
5238
5399
|
items,
|
|
5239
5400
|
renderLink,
|
|
@@ -5241,21 +5402,21 @@ var Breadcrumbs = forwardRef12(function Breadcrumbs2({
|
|
|
5241
5402
|
"aria-label": ariaLabel = "Breadcrumb",
|
|
5242
5403
|
...rest
|
|
5243
5404
|
}, ref) {
|
|
5244
|
-
return /* @__PURE__ */
|
|
5405
|
+
return /* @__PURE__ */ jsx45(
|
|
5245
5406
|
"nav",
|
|
5246
5407
|
{
|
|
5247
5408
|
...rest,
|
|
5248
5409
|
ref,
|
|
5249
5410
|
className: ["ui-nav", "ui-nav--crumbs", className].filter(Boolean).join(" "),
|
|
5250
5411
|
"aria-label": ariaLabel,
|
|
5251
|
-
children: /* @__PURE__ */
|
|
5412
|
+
children: /* @__PURE__ */ jsx45("ol", { className: "ui-nav__crumbs", children: items.map((item, index) => {
|
|
5252
5413
|
const current = index === items.length - 1;
|
|
5253
|
-
const inner = /* @__PURE__ */
|
|
5254
|
-
item.icon && /* @__PURE__ */
|
|
5255
|
-
/* @__PURE__ */
|
|
5414
|
+
const inner = /* @__PURE__ */ jsxs39(Fragment21, { children: [
|
|
5415
|
+
item.icon && /* @__PURE__ */ jsx45("span", { className: "ui-nav__ic", dangerouslySetInnerHTML: { __html: icon8(item.icon) } }),
|
|
5416
|
+
/* @__PURE__ */ jsx45("span", { className: "ui-nav__crumb-label", children: item.label })
|
|
5256
5417
|
] });
|
|
5257
|
-
const linkProps = !current && item.href ? { className: "ui-nav__crumb", href:
|
|
5258
|
-
return /* @__PURE__ */
|
|
5418
|
+
const linkProps = !current && item.href ? { className: "ui-nav__crumb", href: safeUrl5(item.href), target: item.target, children: inner } : null;
|
|
5419
|
+
return /* @__PURE__ */ jsx45("li", { className: "ui-nav__crumb-item", children: linkProps ? renderLink ? renderLink(item, linkProps) : /* @__PURE__ */ jsx45("a", { ...linkProps }) : /* @__PURE__ */ jsx45(
|
|
5259
5420
|
"span",
|
|
5260
5421
|
{
|
|
5261
5422
|
className: ["ui-nav__crumb", current && "is-current"].filter(Boolean).join(" "),
|
|
@@ -5273,6 +5434,7 @@ var PAGE_SIZES = KIT_PAGE_SIZES;
|
|
|
5273
5434
|
var DEFAULT_PAGE_SIZE3 = KIT_DEFAULT_PAGE_SIZE;
|
|
5274
5435
|
export {
|
|
5275
5436
|
AccentPicker,
|
|
5437
|
+
AccountMenu,
|
|
5276
5438
|
AppShell,
|
|
5277
5439
|
Avatar,
|
|
5278
5440
|
BackLink,
|
|
@@ -5332,6 +5494,9 @@ export {
|
|
|
5332
5494
|
Timeline,
|
|
5333
5495
|
Toast,
|
|
5334
5496
|
Tooltip,
|
|
5497
|
+
TopBar,
|
|
5498
|
+
VersionSwitcher,
|
|
5499
|
+
ViewSwitch,
|
|
5335
5500
|
sortTableRows,
|
|
5336
5501
|
useToast
|
|
5337
5502
|
};
|
package/src/components/topbar.js
CHANGED
|
@@ -38,11 +38,11 @@ export function versionSwitcher(versions = [], activeIdx = 0) {
|
|
|
38
38
|
const opts = versions.map((v, i) => {
|
|
39
39
|
const key = String(v.badge || 'archive').toLowerCase();
|
|
40
40
|
return `<div class="vopt" role="option" data-dd-item tabindex="-1" aria-selected="${i === activeIdx}" data-active="${i === activeIdx ? '1' : '0'}">` +
|
|
41
|
-
`<span
|
|
42
|
-
`<span class="vbadge ${key === 'live' ? 'live' : 'arch'}">${Object.hasOwn(VBADGE, key) ? VBADGE[key] : v.badge}</span></div>`;
|
|
41
|
+
`<span class="vname">${v.label}</span>` +
|
|
42
|
+
`<span class="vbadge ${key === 'live' ? 'live' : 'arch'}">${Object.hasOwn(VBADGE, key) ? VBADGE[key] : v.badge}</span><span class="vtick" aria-hidden="true">${icon('check')}</span></div>`;
|
|
43
43
|
}).join('');
|
|
44
44
|
return `<div class="vsw" data-dropdown><button type="button" class="vsw__btn" data-dropdown-trigger aria-haspopup="listbox" aria-expanded="false" aria-label="Version — ${esc(cur)}">` +
|
|
45
|
-
`<span class="
|
|
45
|
+
`<span class="cur">${cur}</span><span class="car"></span></button>` +
|
|
46
46
|
`<div class="vsw__menu" data-dropdown-panel role="listbox" aria-label="Version">${opts}</div></div>`;
|
|
47
47
|
}
|
|
48
48
|
|
package/src/styles/table.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
2
|
* Table — .ui-table (hairline rows, opaque base surface)
|
|
3
|
-
* Row modifiers: .is-dead (revoked
|
|
3
|
+
* Row modifiers: .is-dead (revoked, shown by its muted ink and a word), .is-target (landed on), right-aligned .ui-table__act
|
|
4
4
|
* ========================================================================== */
|
|
5
5
|
|
|
6
6
|
.ui-table {
|
|
@@ -52,14 +52,6 @@
|
|
|
52
52
|
.ui-table th:last-child { padding-right: 0; }
|
|
53
53
|
.ui-table td.ui-table__act { padding-right: 0; text-align: right; }
|
|
54
54
|
.ui-table tr.is-dead td { /* muted-ink: state — revoked row */ color: var(--muted); }
|
|
55
|
-
.ui-table tr.is-dead td.ui-table__title { text-decoration: line-through; }
|
|
56
|
-
/* The strike is painted by the cell across its in-flow inline descendants, and an atomic
|
|
57
|
-
inline-level box is not one — so a linked name in a revoked row needs it struck itself.
|
|
58
|
-
On hover it carries both lines: the cell-link hover rule below is a whole `text-decoration`,
|
|
59
|
-
which would otherwise replace the strike with the underline.
|
|
60
|
-
held by: src/styles/table-focus.test.js */
|
|
61
|
-
.ui-table tr.is-dead td.ui-table__title a { text-decoration: line-through; }
|
|
62
|
-
.ui-table tr.is-dead td.ui-table__title a:hover { text-decoration-line: underline line-through; }
|
|
63
55
|
.ui-table tbody tr { transition: background var(--dur-fast) var(--ease); }
|
|
64
56
|
|
|
65
57
|
/* Row hover: an inset, rounded fill so the highlight never sits flush against a
|
|
@@ -72,7 +64,6 @@
|
|
|
72
64
|
border-spacing: 0;
|
|
73
65
|
padding: 0 var(--space-2);
|
|
74
66
|
}
|
|
75
|
-
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td { background: var(--surface-2); }
|
|
76
67
|
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td:first-child {
|
|
77
68
|
border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); }
|
|
78
69
|
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td:last-child {
|
|
@@ -106,8 +97,6 @@
|
|
|
106
97
|
.ui-table--zebra td:first-child { padding-left: var(--space-3); }
|
|
107
98
|
.ui-table--zebra th:last-child,
|
|
108
99
|
.ui-table--zebra td:last-child { padding-right: var(--space-3); }
|
|
109
|
-
.ui-table--zebra.ui-table--hover tbody tr:hover td,
|
|
110
|
-
.ui-table--zebra tbody tr:hover td { background: color-mix(in srgb, var(--accent) 8%, transparent); /* code-bg: inherit — a wash paints over a ground and behind a chip, so the opaque ground below it is the step. */ }
|
|
111
100
|
|
|
112
101
|
/* A link in a cell is a value that happens to open something: the row's ink, underlined
|
|
113
102
|
on hover — what .ui-identity below has always done. Without it, base.css's bare
|
|
@@ -213,7 +202,7 @@
|
|
|
213
202
|
* bold only in the figure. Scoped to the table, the helper wins on either cell and the
|
|
214
203
|
* row reads as one row. */
|
|
215
204
|
.ui-table :is(th, td).ui-table__num--strong { color: var(--strong); font-weight: var(--weight-semibold); }
|
|
216
|
-
.ui-table__code { font-
|
|
205
|
+
.ui-table__code { font-size: var(--text-sm); color: var(--text); }
|
|
217
206
|
/* Two things in one cell — a row's own name and the state of it — side by side
|
|
218
207
|
* while the column has room and stacked when it does not. The wrap comes from flex
|
|
219
208
|
* because a dense cell is nowrap, and the column is then only as wide as the wider
|
|
@@ -234,13 +223,13 @@
|
|
|
234
223
|
|
|
235
224
|
/* White in light, base canvas in dark; never a grey or tinted data surface. */
|
|
236
225
|
.ui-table { background: var(--table-bg); }
|
|
237
|
-
.ui-table--zebra tbody tr:nth-child(even) td
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
.ui-table--
|
|
241
|
-
|
|
226
|
+
.ui-table--zebra tbody tr:nth-child(even) td { background: var(--table-bg); }
|
|
227
|
+
/* A row hover is a quiet neutral step. The row paints under transparent cells in a
|
|
228
|
+
scroll region, while ordinary cells cover the row without breaking its fill. */
|
|
229
|
+
.ui-table--hover tbody tr:hover:not(.is-target),
|
|
230
|
+
.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
231
|
+
background: var(--surface-2);
|
|
242
232
|
}
|
|
243
|
-
.ui-table tbody tr:hover { outline: 1px solid var(--border-strong); outline-offset: -1px; }
|
|
244
233
|
|
|
245
234
|
/* The row a reference landed a reader on. The mark is a GROUND, not a line: an outline
|
|
246
235
|
says the keyboard is here (Artur, r34), and this one persists — it answers which row the
|
|
@@ -332,6 +321,9 @@
|
|
|
332
321
|
beneath them. */
|
|
333
322
|
.ui-table-scroll > .ui-table,
|
|
334
323
|
.ui-table-scroll > .ui-table tbody td:not(.ui-table__identity, .ui-table__selection) { background-color: transparent; }
|
|
324
|
+
.ui-table-scroll > .ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
325
|
+
background: var(--surface-2);
|
|
326
|
+
}
|
|
335
327
|
/* The kit's first ringed scroller, and a scroll region inside a card like the rest, so
|
|
336
328
|
it draws the band inward too rather than spending a halo across the card around it.
|
|
337
329
|
It had no room of its own to draw in — the padding above is horizontal — which is the
|
|
@@ -387,7 +379,7 @@
|
|
|
387
379
|
.ui-delta--success { color: var(--chip-success-ink); }
|
|
388
380
|
.ui-delta--danger { color: var(--chip-danger-ink); }
|
|
389
381
|
.ui-identity { min-height: 24px; display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text); text-decoration: none; }
|
|
390
|
-
.ui-identity__symbol { font-
|
|
382
|
+
.ui-identity__symbol { font-weight: var(--weight-semibold); }
|
|
391
383
|
.ui-identity__name { white-space: normal; max-width: var(--panel-sm); }
|
|
392
384
|
.ui-identity__logo { width: 24px; height: 24px; flex: 0 0 24px; position: relative; display: grid; place-items: center; border: 1px solid var(--border); border-radius: var(--radius-xs); font-size: var(--text-xs); }
|
|
393
385
|
.ui-identity__logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
|
|
@@ -500,10 +492,8 @@ a.ui-identity:hover { text-decoration: underline; }
|
|
|
500
492
|
.ui-table.ui-table--stack > tbody > tr {
|
|
501
493
|
display: flex; flex-wrap: wrap; align-items: baseline;
|
|
502
494
|
column-gap: var(--space-3); row-gap: var(--space-1);
|
|
503
|
-
/* The inset is on the row, not the table
|
|
504
|
-
|
|
505
|
-
the step a dense cell already pays sideways, so the outline and the row separator keep
|
|
506
|
-
the clearance they had at the width above this one. */
|
|
495
|
+
/* The inset is on the row, not the table, so its hover fill and separator keep
|
|
496
|
+
their clearance at the width above this one. */
|
|
507
497
|
padding: var(--space-3); border-bottom: 1px solid var(--border);
|
|
508
498
|
}
|
|
509
499
|
.ui-table.ui-table--stack > tbody > tr:last-child { border-bottom: 0; }
|
|
@@ -515,7 +505,21 @@ a.ui-identity:hover { text-decoration: underline; }
|
|
|
515
505
|
display: block; width: auto; min-width: 0; max-width: 100%; height: auto;
|
|
516
506
|
padding: 0; border-bottom: 0; white-space: normal; overflow-wrap: break-word;
|
|
517
507
|
}
|
|
508
|
+
.ui-table.ui-table--stack.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
509
|
+
background: transparent;
|
|
510
|
+
}
|
|
518
511
|
.ui-table.ui-table--stack > tbody > tr > td.ui-table__long { flex: 0 0 100%; text-align: left; }
|
|
512
|
+
/* The head is gone, so an amount that names its column in `data-label` says it in front of
|
|
513
|
+
the figure, in the unit's size and body ink. */
|
|
514
|
+
.ui-table.ui-table--stack > tbody > tr > td[data-label]::before {
|
|
515
|
+
content: attr(data-label) / ""; margin-right: var(--space-1); font-size: var(--text-xs);
|
|
516
|
+
}
|
|
517
|
+
/* The cells of a stacked row are separate boxes with gaps between them, so a tint on each
|
|
518
|
+
would paint patches. The row paints one tint and the cells let it through. */
|
|
519
|
+
.ui-table.ui-table--stack tbody tr.is-target:is(*, :hover) {
|
|
520
|
+
background: color-mix(in srgb, var(--accent) 12%, transparent); /* code-bg: inherit — this translucent wash leaves the chip on its opaque ground. */
|
|
521
|
+
}
|
|
522
|
+
.ui-table.ui-table--stack tbody tr.is-target:is(*, :hover) > :is(td, th) { background: transparent; }
|
|
519
523
|
/* A stacked row has no columns left to pin, stick or inset, and the identity's name is
|
|
520
524
|
what the row is about — the fold hides it only because a pinned column is narrow. */
|
|
521
525
|
.ui-table.ui-table--stack.ui-table--pinned > :where(thead, tbody) > tr > :where(.ui-table__identity, .ui-table__selection) {
|
package/src/styles/topbar.css
CHANGED
|
@@ -69,7 +69,11 @@
|
|
|
69
69
|
transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
|
|
70
70
|
}
|
|
71
71
|
.dtsw a:hover { color: var(--strong); }
|
|
72
|
-
.dtsw a.cur { color: var(--
|
|
72
|
+
.dtsw a.cur { color: var(--accent-contrast); background: var(--accent); }
|
|
73
|
+
:where(:root[data-theme="dark"]) .dtsw a.cur { color: var(--signal-contrast); }
|
|
74
|
+
@media (forced-colors: active) {
|
|
75
|
+
.dtsw a.cur { forced-color-adjust: none; background: Highlight; color: HighlightText; --ring: var(--ring-width) solid CanvasText; }
|
|
76
|
+
}
|
|
73
77
|
.dtsw a:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
74
78
|
|
|
75
79
|
/* Theme toggle — a single icon-only switch (no label). */
|
|
@@ -96,6 +100,7 @@
|
|
|
96
100
|
|
|
97
101
|
/* Version switcher */
|
|
98
102
|
.vsw { position: relative; }
|
|
103
|
+
.vsw > .ui-dropdown { max-width: 100%; min-width: 0; }
|
|
99
104
|
.vsw__btn {
|
|
100
105
|
display: inline-flex;
|
|
101
106
|
align-items: center;
|
|
@@ -117,16 +122,16 @@
|
|
|
117
122
|
what the kit's rows already chose. why: docs/foundations.md#the-focus-ring */
|
|
118
123
|
.vsw__btn:hover:not(:focus-visible) { border-color: var(--accent); }
|
|
119
124
|
.vsw__btn:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
120
|
-
.vsw__btn .lbl { color: var(--text); }
|
|
121
125
|
.vsw__btn .cur { color: var(--strong); font-weight: 600; letter-spacing: 0.01em; }
|
|
122
126
|
.vsw__btn .car {
|
|
123
127
|
width: 8px; height: 8px;
|
|
124
128
|
border-right: 1.6px solid var(--muted);
|
|
125
129
|
border-bottom: 1.6px solid var(--muted);
|
|
126
|
-
transform:
|
|
130
|
+
transform: translateY(-2px) rotate(45deg);
|
|
127
131
|
transition: transform var(--dur-fast) var(--ease);
|
|
128
132
|
}
|
|
129
|
-
.vsw.open .vsw__btn .car
|
|
133
|
+
.vsw.open .vsw__btn .car,
|
|
134
|
+
.vsw .ui-dropdown.open .vsw__btn .car { transform: translateY(2px) rotate(-135deg); }
|
|
130
135
|
.vsw__menu {
|
|
131
136
|
position: absolute;
|
|
132
137
|
top: calc(100% + 9px);
|
|
@@ -214,8 +219,12 @@
|
|
|
214
219
|
the arrow keys, and this is one. It takes the ring on its own 10px radius, the
|
|
215
220
|
same way `.amenu a` above does. #482 */
|
|
216
221
|
.vopt:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
222
|
+
/* The selected version carries the kit's menu tick, as `.ui-dropdown__tick` does for
|
|
223
|
+
every other menu; the badge keeps its own place beside it. */
|
|
224
|
+
.vopt .vtick { margin-left: 8px; flex: none; display: none; color: var(--accent); margin-top: 1px; }
|
|
225
|
+
.vopt .vtick svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2.4; }
|
|
226
|
+
.vopt[aria-selected="true"] .vtick { display: inline-flex; }
|
|
217
227
|
.vopt .vname { font-family: var(--font-sans); font-size: calc(var(--text-sm) - 0.5px); color: var(--strong); font-weight: 600; letter-spacing: 0.01em; }
|
|
218
|
-
.vopt .vmeta { font-size: var(--text-xs); color: var(--text); margin-top: 2px; }
|
|
219
228
|
.vopt .vbadge {
|
|
220
229
|
/* rank: chip */
|
|
221
230
|
font-size: var(--text-xs);
|
|
@@ -231,10 +240,8 @@
|
|
|
231
240
|
the same neutral chip fill rather than the card surface — which, inside a panel that
|
|
232
241
|
is itself lighter than a card, was darker than the ground it sat on. #453 */
|
|
233
242
|
.vbadge.arch { /* muted-ink: state — archived version */ color: var(--muted); background: var(--chip-neutral-fill); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
|
|
234
|
-
/*
|
|
235
|
-
Anchor the menu to its right edge so a closed panel cannot widen the page. */
|
|
243
|
+
/* Anchor the menu to its right edge so a closed panel cannot widen the page. */
|
|
236
244
|
@media (max-width: 720px) {
|
|
237
|
-
.vsw__btn .lbl { display: none; }
|
|
238
245
|
.vsw__menu { left: auto; right: 0; }
|
|
239
246
|
}
|
|
240
247
|
|
|
@@ -273,7 +280,7 @@
|
|
|
273
280
|
end inset. A long label gives way to an ellipsis, and 8px always stays between the
|
|
274
281
|
two controls. */
|
|
275
282
|
.topbar__in > .vsw { grid-area: 2 / 2 / 3 / -1; justify-self: end; min-width: 0; max-width: calc(100% - var(--space-2)); margin-left: var(--space-2); }
|
|
276
|
-
.vsw__btn { max-width: 100%; }
|
|
283
|
+
.vsw__btn { max-width: 100%; min-width: 0; }
|
|
277
284
|
.vsw__btn .cur { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
278
285
|
.vsw__btn .car { flex: none; }
|
|
279
286
|
/* Two 44px rows, an 8px gap, the 4px and 3px insets and the bottom border. */
|
|
@@ -304,6 +311,8 @@
|
|
|
304
311
|
accent band is the second band #578 round r34 took off the focus rules, and a
|
|
305
312
|
pointer resting on a focused control would put it back. One indicator, which is
|
|
306
313
|
what the kit's rows already chose. why: docs/foundations.md#the-focus-ring */
|
|
314
|
+
/* The React menu puts the dropdown trigger's pill padding and flex row on the avatar. */
|
|
315
|
+
.acct .avatar { display: grid; padding: 0; }
|
|
307
316
|
.acct .avatar:hover:not(:focus-visible) { border-color: var(--accent); }
|
|
308
317
|
.avatar:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
|
|
309
318
|
/* The account button holding an Avatar: the part paints the circle in the reader's hue and
|
|
@@ -376,6 +385,8 @@
|
|
|
376
385
|
border-radius: 14px 14px 0 0;
|
|
377
386
|
display: flex; align-items: center; gap: 11px;
|
|
378
387
|
}
|
|
388
|
+
.amenu .ui-dropdown__sep { margin: 5px 0; }
|
|
389
|
+
.amenu .ahead .avatar { cursor: default; }
|
|
379
390
|
.amenu .ahead .aw { min-width: 0; display: flex; flex-direction: column; gap: 1px; line-height: 1.35; }
|
|
380
391
|
.amenu .ahead .anm { color: var(--strong); font-size: var(--text-sm); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
381
392
|
.amenu .ahead .aem { color: var(--text); font-size: calc(var(--text-xs) + 0.5px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -388,6 +399,10 @@
|
|
|
388
399
|
.amenu a:hover { outline: 1px solid var(--control-edge); outline-offset: -1px; background: var(--surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */ }
|
|
389
400
|
.amenu a:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); border-radius: var(--radius-xs); }
|
|
390
401
|
.amenu a.cur { color: var(--accent); }
|
|
402
|
+
/* A custom account row keeps the Dropdown's disabled state without its row shape. */
|
|
403
|
+
.amenu a.is-disabled { /* muted-ink: state — unavailable account page */ color: var(--disabled-ink); cursor: not-allowed; pointer-events: none; }
|
|
404
|
+
/* The SVG takes the row's height; its React wrapper adds no line box. */
|
|
405
|
+
.amenu a > span[aria-hidden="true"] { display: contents; }
|
|
391
406
|
.amenu a svg { width: 19px; height: 19px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; opacity: 0.85; }
|
|
392
407
|
.amenu .asep { height: 1px; background: var(--border); margin: 5px 0; }
|
|
393
408
|
.amenu a.aout { color: var(--text); }
|
package/src/tokens/tokens.css
CHANGED
|
@@ -574,10 +574,7 @@
|
|
|
574
574
|
.ui-table-scroll,
|
|
575
575
|
.ui-table--sticky thead th,
|
|
576
576
|
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
|
|
577
|
-
.ui-table--hover:not(.ui-table--zebra) tbody tr:hover td,
|
|
578
577
|
.ui-table--zebra tbody tr:nth-child(even) td,
|
|
579
|
-
.ui-table--zebra tbody tr:hover td,
|
|
580
|
-
.ui-table--zebra.ui-table--hover tbody tr:hover td,
|
|
581
578
|
.ui-toast,
|
|
582
579
|
.ui-toast--soft,
|
|
583
580
|
.ui-toast--outline,
|
|
@@ -598,10 +595,14 @@
|
|
|
598
595
|
.ui-table-scroll,
|
|
599
596
|
.ui-table--sticky thead th,
|
|
600
597
|
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
|
|
601
|
-
.ui-table--
|
|
602
|
-
.
|
|
603
|
-
|
|
604
|
-
.ui-table--
|
|
598
|
+
.ui-table--zebra tbody tr:nth-child(even) td { --code-bg: var(--table-code-bg); }
|
|
599
|
+
/* A neutral hovered row gives an inline code chip the card surface. The step from
|
|
600
|
+
* --surface-2 clears 1.1:1 in both themes, even when the table follows a card. */
|
|
601
|
+
.ui-table--hover tbody tr:hover:not(.is-target),
|
|
602
|
+
.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th),
|
|
603
|
+
.ui-table-scroll > .ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
|
|
604
|
+
--code-bg: var(--surface);
|
|
605
|
+
}
|
|
605
606
|
.ui-card--accent,
|
|
606
607
|
.ui-card--live,
|
|
607
608
|
.ui-snippet--reveal { --code-bg: var(--surface); }
|