@danxbot/ui 14.4.0 → 15.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ import { type ReactNode, type Ref } from "react";
2
+ export type ImageUploadFieldShape = "circle" | "square";
3
+ export type ImageUploadFieldSize = "sm" | "md" | "lg" | "xl";
4
+ export interface ImageUploadFieldProps {
5
+ /** The current image URL. `undefined`/`null` means nothing is set yet. */
6
+ value?: string | null;
7
+ /**
8
+ * Fired once a pick resolves — either a successful upload (the URL
9
+ * `onUpload` returned) or a remove (`null`). This is the only way `value`
10
+ * ever changes; the component holds no persistent state of its own.
11
+ */
12
+ onChange?: (url: string | null) => void;
13
+ /** Uploads the picked file and resolves with its stored URL. Rejecting
14
+ * surfaces the rejection's `message` (or the rejection itself, stringified)
15
+ * as this field's error. */
16
+ onUpload: (file: File) => Promise<string>;
17
+ shape?: ImageUploadFieldShape;
18
+ size?: ImageUploadFieldSize;
19
+ /** Hides the remove control even when a value is set — for a slot that must
20
+ * always hold *something* (e.g. a required team logo with a seeded
21
+ * default). Default `true`. */
22
+ removable?: boolean;
23
+ accept?: string;
24
+ /** Bytes. Forwarded to `FileUpload`'s own limit + rejection message. */
25
+ maxSize?: number;
26
+ disabled?: boolean;
27
+ /** Rendered above the preview. */
28
+ label?: ReactNode;
29
+ /** Rendered under the preview, when there is no error to show instead. */
30
+ description?: ReactNode;
31
+ /** Accessible name for the replace/pick control — required since the
32
+ * control the preview state renders is icon-only. */
33
+ uploadLabel?: string;
34
+ removeLabel?: string;
35
+ className?: string;
36
+ ref?: Ref<HTMLDivElement>;
37
+ }
38
+ export declare function ImageUploadField({ value, onChange, onUpload, shape, size, removable, accept, maxSize, disabled, label, description, uploadLabel, removeLabel, className, ref, }: ImageUploadFieldProps): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { type InputProps } from "./Input";
2
+ export interface PasswordInputProps extends Omit<InputProps, "type" | "trailing"> {
3
+ /** Hides the show/hide toggle entirely — for a field where the operator
4
+ * should never be able to reveal what they typed (rare; default `true`). */
5
+ revealable?: boolean;
6
+ }
7
+ export declare function PasswordInput({ revealable, autoComplete, ...props }: PasswordInputProps): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import type { Ref } from "react";
2
+ export interface PasswordRequirementRule {
3
+ label: string;
4
+ met: boolean;
5
+ }
6
+ export interface PasswordRequirementsProps {
7
+ rules: PasswordRequirementRule[];
8
+ className?: string;
9
+ ref?: Ref<HTMLUListElement>;
10
+ }
11
+ export declare function PasswordRequirements({ rules, className, ref }: PasswordRequirementsProps): import("react").JSX.Element | null;
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from "react";
2
+ export interface ApiToken {
3
+ id: number;
4
+ name: string;
5
+ /** ISO instant. */
6
+ createdAt: string;
7
+ /** ISO instant, or `null`/omitted if it has never been used. */
8
+ lastUsedAt?: string | null;
9
+ /** ISO instant, or `null`/omitted for a token with no expiry. */
10
+ expiresAt?: string | null;
11
+ }
12
+ export interface ApiTokensPanelProps {
13
+ tokens: ApiToken[];
14
+ onCreate: (input: {
15
+ name: string;
16
+ expiresInDays?: number | null;
17
+ }) => Promise<{
18
+ token: string;
19
+ }>;
20
+ onRevoke: (id: number) => Promise<void>;
21
+ /** The id of a token currently mid-revoke. Disables just that row. */
22
+ busyId?: number | null;
23
+ emptyState?: ReactNode;
24
+ className?: string;
25
+ }
26
+ export declare function ApiTokensPanel({ tokens, onCreate, onRevoke, busyId, emptyState, className }: ApiTokensPanelProps): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { type PasswordRequirementRule } from "../PasswordRequirements";
2
+ export interface ChangePasswordFormProps {
3
+ /** Pure — recomputed against the current draft of the new password on every
4
+ * render. See the module header for why this is a function rather than a
5
+ * precomputed `rules[]`. */
6
+ passwordRules: (nextPassword: string) => PasswordRequirementRule[];
7
+ onSubmit: (current: string, next: string) => Promise<void>;
8
+ submitLabel?: string;
9
+ className?: string;
10
+ }
11
+ export declare function ChangePasswordForm({ passwordRules, onSubmit, submitLabel, className, }: ChangePasswordFormProps): import("react").JSX.Element;
@@ -0,0 +1,25 @@
1
+ export interface ProfileFormAccount {
2
+ name: string;
3
+ /** Omit entirely for a consumer whose account model has no separate
4
+ * username concept — the field simply does not render (see `types.ts`'s
5
+ * own `User.username` doc for the same optional-field convention). */
6
+ username?: string;
7
+ email: string;
8
+ avatarUrl?: string | null;
9
+ }
10
+ export interface ProfileFormSaveInput {
11
+ name: string;
12
+ username?: string;
13
+ email: string;
14
+ }
15
+ export interface ProfileFormProps {
16
+ account: ProfileFormAccount;
17
+ onSave: (input: ProfileFormSaveInput) => Promise<void>;
18
+ onUploadAvatar: (file: File) => Promise<string>;
19
+ /** Fired the moment a new avatar finishes uploading (or is removed) — see
20
+ * the module header for why the avatar has no separate Save step. */
21
+ onAvatarChange?: (avatarUrl: string | null) => void;
22
+ saveLabel?: string;
23
+ className?: string;
24
+ }
25
+ export declare function ProfileForm({ account, onSave, onUploadAvatar, onAvatarChange, saveLabel, className, }: ProfileFormProps): import("react").JSX.Element;
@@ -1 +1,11 @@
1
- export declare function ProfilePage(): import("react").JSX.Element;
1
+ import { type ProfileFormAccount, type ProfileFormSaveInput } from "./ProfileForm";
2
+ export interface ProfilePageProps {
3
+ /** The identity fields to edit. Omit to keep the original read-only (but
4
+ * still locally-editable) `actualUser` display. */
5
+ account?: ProfileFormAccount;
6
+ onSave?: (input: ProfileFormSaveInput) => Promise<void>;
7
+ onUploadAvatar?: (file: File) => Promise<string>;
8
+ onAvatarChange?: (avatarUrl: string | null) => void;
9
+ className?: string;
10
+ }
11
+ export declare function ProfilePage({ account, onSave, onUploadAvatar, onAvatarChange, className }: ProfilePageProps): import("react").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import type { Role } from "./types";
2
+ export interface RoleEditorDialogSubmitInput {
3
+ label: string;
4
+ description: string;
5
+ /** Only ever sent from CREATE mode — see this file's own header. `undefined` when no clone-from role was picked. */
6
+ cloneFromRoleId?: string;
7
+ }
8
+ export interface RoleEditorDialogProps {
9
+ mode: "create" | "edit";
10
+ open: boolean;
11
+ onOpenChange: (open: boolean) => void;
12
+ /**
13
+ * CREATE mode only — the roles offered as "clone permissions from" (a
14
+ * consumer typically hands every role the matrix already shows, owner
15
+ * included: cloning owner's COMPUTED set is a legitimate way to seed a
16
+ * near-owner role). Omitted or empty simply hides the field — a consumer
17
+ * with nothing to clone from does not owe this dialog an empty array.
18
+ */
19
+ cloneFromRoles?: Role[];
20
+ /** EDIT mode — the role's current values, so the fields open pre-filled rather than blank. */
21
+ initialLabel?: string;
22
+ initialDescription?: string;
23
+ /** Disables the form and shows a busy submit button while a save is in flight. */
24
+ loading?: boolean;
25
+ onSubmit: (input: RoleEditorDialogSubmitInput) => void;
26
+ className?: string;
27
+ }
28
+ export declare function RoleEditorDialog({ mode, open, onOpenChange, cloneFromRoles, initialLabel, initialDescription, loading, onSubmit, className, }: RoleEditorDialogProps): import("react").JSX.Element;
@@ -2,5 +2,20 @@ import type { Permission, Role } from "./types";
2
2
  export interface RolePermissionMatrixProps {
3
3
  roles: Role[];
4
4
  permissions: Permission[];
5
+ /**
6
+ * DX-3414 — turns each cell into a toggle. Defaults to `false` (the
7
+ * original read-only matrix, unchanged pixel-for-pixel and test-for-test).
8
+ * A `role.locked` column stays READ-ONLY even when `editable` — see
9
+ * `Role.locked`'s own doc comment (`types.ts`): a consumer's rules forbid
10
+ * touching that role at all, and the matrix has no business knowing why.
11
+ */
12
+ editable?: boolean;
13
+ /**
14
+ * Fired when an editable, unlocked cell is toggled. `granted` is the NEW
15
+ * value the caller should persist — the matrix holds no state of its own
16
+ * (PLN-13 R-3: presentational, no fetch); a consumer wires this to its own
17
+ * mutation and re-renders with the updated `roles` once it lands.
18
+ */
19
+ onChange?: (roleId: string, permissionKey: string, granted: boolean) => void;
5
20
  }
6
- export declare function RolePermissionMatrix({ roles, permissions }: RolePermissionMatrixProps): import("react").JSX.Element;
21
+ export declare function RolePermissionMatrix({ roles, permissions, editable, onChange, }: RolePermissionMatrixProps): import("react").JSX.Element;
@@ -1 +1,22 @@
1
- export declare function RolesPermissionsPage(): import("react").JSX.Element;
1
+ import { type RoleEditorDialogSubmitInput } from "./RoleEditorDialog";
2
+ import type { Permission, Role } from "./types";
3
+ export interface RolesPermissionsPageProps {
4
+ roles: Role[];
5
+ permissions: Permission[];
6
+ /** Gates the "New role" button, the manage-roles list, and the matrix's own `editable`. Defaults to `false` — read-only, pixel-identical to the page before this card. */
7
+ editable?: boolean;
8
+ /** Fired when an editable, unlocked matrix cell is toggled. Required to make the matrix respond; omit alongside `editable={false}`. */
9
+ onChangePermission?: (roleId: string, permissionKey: string, granted: boolean) => void;
10
+ onCreateRole?: (input: RoleEditorDialogSubmitInput) => void;
11
+ onRenameRole?: (roleId: string, input: {
12
+ label: string;
13
+ description: string;
14
+ }) => void;
15
+ onDeleteRole?: (roleId: string) => void;
16
+ /** Restores a SYSTEM role's seeded permission set — offered only for a role with `role.system` true (never `locked`; see `Role.locked`'s own doc comment for why owner never reaches this list at all). */
17
+ onResetRole?: (roleId: string) => void;
18
+ /** The id of a role currently mid-mutation. Disables just that row's controls, not the whole page. */
19
+ busyRoleId?: string | null;
20
+ className?: string;
21
+ }
22
+ export declare function RolesPermissionsPage({ roles, permissions, editable, onChangePermission, onCreateRole, onRenameRole, onDeleteRole, onResetRole, busyRoleId, className, }: RolesPermissionsPageProps): import("react").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from "react";
2
+ export interface Session {
3
+ id: number;
4
+ /** A human label for the session — "Chrome on macOS", "iPhone app", whatever
5
+ * the consumer's own backend derives from the user agent. */
6
+ name: string;
7
+ /** ISO instant. */
8
+ createdAt: string;
9
+ /** ISO instant. */
10
+ lastUsedAt: string;
11
+ /** ISO instant, or `null`/omitted for a session with no expiry. */
12
+ expiresAt?: string | null;
13
+ userAgent?: string;
14
+ ip?: string;
15
+ /** True for exactly one row — the session this UI is currently running in. */
16
+ current: boolean;
17
+ }
18
+ export interface SessionsListProps {
19
+ sessions: Session[];
20
+ onRevoke: (id: number) => Promise<void>;
21
+ /** The id of a session currently mid-revoke. Disables just that row. */
22
+ busyId?: number | null;
23
+ emptyState?: ReactNode;
24
+ className?: string;
25
+ }
26
+ export declare function SessionsList({ sessions, onRevoke, busyId, emptyState, className }: SessionsListProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined>;
@@ -5,6 +5,11 @@ export * from "./AccountMenu";
5
5
  export * from "./TeamSwitcher";
6
6
  export * from "./DevToolsPopover";
7
7
  export * from "./RolePermissionMatrix";
8
+ export * from "./RoleEditorDialog";
9
+ export * from "./ProfileForm";
8
10
  export * from "./ProfilePage";
9
11
  export * from "./RolesPermissionsPage";
10
12
  export * from "./MembersPanel";
13
+ export * from "./ChangePasswordForm";
14
+ export * from "./SessionsList";
15
+ export * from "./ApiTokensPanel";
@@ -28,6 +28,8 @@ export { InlineMarkdownEdit, type InlineMarkdownEditProps } from "./components/I
28
28
  export type { EditActivation } from "./components/edit/activation";
29
29
  export type { EditCommit, EditOutcome, EditRefusal } from "./components/edit/outcome";
30
30
  export { SecretField, type SecretFieldProps, type SecretValue } from "./components/SecretField";
31
+ export { PasswordInput, type PasswordInputProps } from "./components/PasswordInput";
32
+ export { PasswordRequirements, type PasswordRequirementsProps, type PasswordRequirementRule, } from "./components/PasswordRequirements";
31
33
  export { SettingRow, SettingGroup, type SettingRowProps, type SettingGroupProps, type SettingRowControlRenderProps, } from "./components/SettingRow";
32
34
  export { DescriptionList, DescriptionListItem, type DescriptionListProps, type DescriptionListItemProps, type DescriptionListEntry, } from "./components/DescriptionList";
33
35
  export { ConnectionCard, type ConnectionCardProps, type ConnectionHealth, } from "./components/ConnectionCard";
@@ -40,6 +42,7 @@ export { Menu, MenuItem, MenuGroup, MenuRadioGroup, MenuRadioItem, MenuSeparator
40
42
  export { ThemeMenu, type ThemeMenuProps } from "./components/ThemeMenu";
41
43
  export { AppShell, type AppShellProps, type NavItem, type NavSection, } from "./components/AppShell";
42
44
  export { FileUpload, type FileUploadProps, type UploadFile } from "./components/FileUpload";
45
+ export { ImageUploadField, type ImageUploadFieldProps, type ImageUploadFieldShape, type ImageUploadFieldSize, } from "./components/ImageUploadField";
43
46
  export { DatePicker, type DatePickerProps, type DateRange } from "./components/DatePicker";
44
47
  export { DateCalendar, type DateCalendarProps } from "./components/DateCalendar";
45
48
  export { DateField, DateTimeField, type DateFieldProps, type DateTimeFieldProps, } from "./components/DateField";
@@ -124,7 +127,7 @@ export { cellLabel, eventLabel, formatDateRange, longDate, monthTitle, timeOfDay
124
127
  export { initialFocusDay, isInMonth, nextDayForKey, useGridNavigation, type GridNavigation, type GridNavigationOptions, } from "./components/calendar/use-grid-navigation";
125
128
  export { AmbiguousTimeError, addDays, addDuration, addMonths, atMidnight, atTime, comparePlainDate, dayFraction, dayLengthMs, dayOfWeek, daysBetween, daysInMonth, endOfMonth, hoursInDay, instantAtFraction, instantToPlainDate, instantToPlainDateTime, isSameDate, isoDateString, isoDateTimeString, monthGridDays, nextDay, offsetAt, parsePlainDate, plainDateTimeToInstant, relativeAge, startOfDay, startOfMonth, startOfWeek, weekDays, type CalendarDuration, type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone, } from "./lib/time";
126
129
  export { allDayBandSegment, dayKey, daySlots, isAllDay, packBand, packLanes, snapFractionToInstant, timeSegments, timedBandSegment, type AllDayEvent, type BandInput, type BandOptions, type BandPlacement, type BandResult, type BandSegment, type CalendarEvent, type CalendarEventId, type CalendarView, type DaySlot, type DragKind, type EventDraft, type EventPalette, type LaneInput, type LaneOptions, type LanePlacement, type PaletteEntry, type TimeSegment, type TimedEvent, type VisibleRange, } from "./lib/calendar";
127
- export { RBACProvider, useRBAC, Can, useHasPermission, AccountMenu, TeamSwitcher, DevToolsPopover, RolePermissionMatrix, ProfilePage, RolesPermissionsPage, MembersPanel, type RBACProviderProps, type RBACHookResult, type CanProps, type AccountMenuProps, type TeamSwitcherProps, type DevToolsPopoverProps, type RolePermissionMatrixProps, type MembersPanelProps, type MembersPanelMember, type Permission, type Role, type User, type Team, type TeamMembership, } from "./components/rbac";
130
+ export { RBACProvider, useRBAC, Can, useHasPermission, AccountMenu, TeamSwitcher, DevToolsPopover, RolePermissionMatrix, RoleEditorDialog, ProfileForm, ProfilePage, RolesPermissionsPage, MembersPanel, ChangePasswordForm, SessionsList, ApiTokensPanel, type RBACProviderProps, type RBACHookResult, type CanProps, type AccountMenuProps, type TeamSwitcherProps, type DevToolsPopoverProps, type RolePermissionMatrixProps, type RoleEditorDialogProps, type RoleEditorDialogSubmitInput, type ProfileFormProps, type ProfileFormAccount, type ProfileFormSaveInput, type ProfilePageProps, type RolesPermissionsPageProps, type MembersPanelProps, type MembersPanelMember, type ChangePasswordFormProps, type SessionsListProps, type Session, type ApiTokensPanelProps, type ApiToken, type Permission, type Role, type User, type Team, type TeamMembership, } from "./components/rbac";
128
131
  export { UseCaseCard, RoadmapItemCard, RoadmapSwimlaneBoard, UseCaseLedgerPage, RoadmapPage, PhaseManager, TrackManager, deriveRoadmapItemStatus, isFullyBuilt, isUnbuilt, trackIds, trackProgress, toneForIndex, CATEGORY_TONES, type Domain, type Phase, type Track, type RoadmapItem, type RoadmapItemStatus, type UseCase, type UseCaseStatus, type UseCaseDecision, type UseCaseCardProps, type RoadmapItemCardProps, type RoadmapSwimlaneBoardProps, type UseCaseLedgerPageProps, type RoadmapPageProps, type PhaseManagerProps, type TrackManagerProps, } from "./components/roadmap";
129
132
  export { ProvenanceDisclosure, ProvenanceDetail, ProvenanceBadge, ConfidenceReadout, ConfidenceMeter, ConfidenceBar, provenanceStateLabel, confidenceBand, confidenceScore, scoredConfidence, ratedConfidence, type ProvenanceRecord, type ProvenanceState, type ProvenanceSource, type ProvenanceCheck, type ProvenanceCall, type ProvenanceSignoff, type ConfidenceBand, type ConfidenceScore, type ProvenanceConfidence, type ConfidenceReadoutProps, type ConfidenceBarProps, type ConfidenceBarSize, type ProvenanceDisclosureProps, type ProvenanceDetailProps, type ProvenanceDetailTitleAs, type ProvenanceTriggerBadge, type ProvenanceBadgeProps, type ProvenanceBadgeAppearance, type ConfidenceMeterProps, } from "./components/provenance";
130
133
  export { confidenceLevel, CONFIDENCE_LEVEL_LABELS, type ConfidenceLevel } from "./lib/confidence";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "14.4.0",
3
+ "version": "15.1.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",