@uix-design/advanced
v0.3.0
Published
Optional advanced React workspaces, scheduling, editors, builders and media components for UIX Design.
Maintainers
Readme
@uix-design/advanced
Optional UIX React workspaces, scheduling, editors, builders and media components.
Prepared for public npm distribution. Requires the matching @uix-design/react
workspace release; publishing resolves the peer range to that release.
FilterBuilder, RuleBuilder, QueryBuilder, FormBuilder and MapSelector remain Beta and are
not ready for production projects.
It owns AICopilot, FileManager, ImageGallery, Spreadsheet, Calendar, Gantt and RichTextEditor, alongside the enterprise components previously grouped in Premium. It consumes public React primitives and tokens; React never depends on Advanced.
Panel migration
ChatSettingsPanel, NewTaskPanel, AppSettingsPanel and PremiumPanelsBoard have
been removed, together with their prop types and PremiumChatMode /
PremiumThemeMode. Compose settings and task forms with the existing React form,
Card and Grid primitives. UploadPanel, UpcomingPanel, MembersListPanel and
HotkeysPanel remain available independently.
import { DesignSystemProvider } from "@uix-design/react";
import { Calendar } from "@uix-design/advanced";
// Optional direct entry: @uix-design/advanced/calendar
// Styles and shared dependencies are included automatically.Each component entry imports its compiled stylesheet. The build preserves ESM modules and marks CSS as side effects so production consumers can discard unused components with their styles. Shared foundation styles are loaded once. No runtime style injection or browser-global access is required to load a component. Use a bundler/framework that processes CSS imports, including for server builds. Raw Node.js does not process CSS imports by itself.
The optional @uix-design/advanced/styles export loads all Advanced styles for
legacy integrations. Prefer automatic styles and avoid combining both mechanisms.
All themes, runtime accent, density and foundational controls come from React UI.
See MIGRATION.md for changed imports and release requirements.
Operational workspaces
QueryBuilder, RuleBuilder, FilterBuilder, FormBuilder and MapSelector are Beta and are not ready for production projects. Their component headers display a persistent Beta badge, including when embedded outside the documentation app.
Kanban, FormBuilder, PermissionMatrix, FilterBuilder, RuleBuilder, QueryBuilder and
inline ImageCropperEditor share Calendar's surface hierarchy: a panel-colored heading and body, with muted
toolbars and footers. Theme tokens preserve that hierarchy in dark mode. Busy
editor headings use labeled icon actions with tooltips, keeping their actions on
one row. They reuse React controls and include full-window mode by default;
allowFullscreen={false} hides it. fullscreenLabels and onFullscreenChange
configure its labels and state notifications.
FilterBuilder, RuleBuilder and QueryBuilder keep the editing area bounded and
switch between library, editor and properties in narrow containers. Their
metadata and technical results can be expanded on demand. Set
--uix-builder-height via style to override the default min(50rem, 70dvh).
FormBuilder keeps its existing panel and canvas controls and uses
--uix-form-builder-studio-height. PermissionMatrix preserves native table
layout and scrolls wide matrices inside its workspace.
Builder panel navigation uses underline tabs with keyboard support. FilterBuilder
has one scroll owner per panel; the canvas scrollbar sits on the panel edge and
logic connectors occupy a separate gutter. QueryBuilder keeps library tabs and search
fixed while its tables or saved queries scroll, with concise tab labels. PermissionMatrix uses aligned search,
resource and density controls. FormBuilder selects a field from its entire card;
preview controls stay inert until preview mode, with contextual editing actions.
Column reordering handles appear when layout guides (Grid) are enabled.
FormBuilder switches between an eye action for preview and a pencil action for editing.
Both modes retain their canvas in fullscreen. New fields do not inherit catalog
implementation notes as form help text. The catalog exposes one single-choice
control, complete telephone inputs, decimal amounts, native date/time inputs and
suggested text using option values. radio, signature and inputGroup remain
readable legacy schema types but are no longer offered for new fields; signature
remains a file attachment, not signature capture. The simulated CAPTCHA field is
removed from the catalog and flagged in old schemas. CAPTCHA verification requires
a host integration; the local preview cannot submit forms that require it.
The docs sidebar marks the four Beta builders and MapSelector, as well as their component headers.
ImageCropperEditor has a compact tool strip, an image canvas, and tabs for
adjustments, preview and output settings. Download/save actions stay in the footer.
Set --uix-cropper-height or --uix-cropper-panel-width to size the workspace.
showAdjustments, showPreview, showExportPanel, showToolbar and
showAspectRatios continue to control its features. Inline mode supports the same
fullscreen props as other workspaces; dialog/drawer/fullscreen variants retain
their own overlay header. Save is offered when onSave is supplied. The initial
crop fits the image, selection survives workspace resizing, and keeping the aspect
ratio synchronizes output height when the crop changes.
Persistence and execution remain host responsibilities. Save/publish actions and QueryBuilder’s export action appear when their callbacks
are supplied; local JSON exports remain available. Local schema validation does
not manufacture row counts, execution time or data coverage. Supply onPreview
(FilterBuilder) or onRunPreview (QueryBuilder) for actual results. Stale preview
responses cannot replace newer requests. RuleBuilder's local test simulates the
rule; it does not execute external actions. FormBuilder marks a draft published
only after onPublish resolves successfully.
Kanban defaults to a taller min(52rem, 85dvh) desktop workspace. Override
--uix-kanban-height and --uix-kanban-max-height via style to fit the host;
mobile layouts retain their natural height, and fullscreen uses the available window.
Kanban's currentOwner explicitly identifies the owner used by My deals;
without it, that preset is hidden. The unused maxViews quota was removed.
Kanban stage grouping and PermissionMatrix category grouping use a single pass;
FormBuilder reuses its filtered palette and builders share their heading,
navigation and styles without adding dependencies.
License
MIT. Copyright (c) 2026 José L. Alvarado Santamaría.
IdentityAssignmentManager
The workspace places a shared UIX Tree alongside a tabbed resource catalog. The
assigned tree groups resources by type and subsection; the effective-access tab
shows authorization relationships and decisions. Both tree views and the catalog
use the same contextual detail panel. Both trees
stay beside the catalog. Independent scrolling and a keyboard-accessible Splitter
keep the workspace within a bounded height. The tree starts at 390px. The shared
footer remains below all panels, including the inspector. Override
--uix-iam-workspace-height through style to change the working-area height. Below 46rem of component width, a
panel switch replaces the side-by-side layout, preserving the catalog search.
<IdentityAssignmentManager
allowFullscreen
fullscreenLabels={{ expand: "Expandir ventana", collapse: "Contraer ventana" }}
user={user}
resources={resources}
assignments={assignments}
categories={[
{ type: "tenant", label: "Tenants" },
{ type: "application", label: "Aplicaciones" },
{ type: "role", label: "Roles" }
]}
defaultCatalogType="role"
getResourceSection={(resource) => resource.scope ?? "Global"}
onAssignmentsChange={({ assignments: next }) => setAssignments(next)}
/>categoriescontrols labels and order in the catalog and assigned tree. Omitted resource types are appended, duplicate types use their first configuration, and empty catalog tabs remain stable after assignment. It is not a permission filter.catalogTabLimitdefaults to4and also supports3. Remaining categories appear as sections inside the last tab, named bycatalogOverflowLabel(defaultOtros accesos).getResourceSectionsupplies subsection labels for both panels. The default isscopeorGlobal. Supply a stable function for large catalogs.defaultCatalogTypeselects the initial category. Otherwise the first category with available resources is selected. Search matches all categories; tab counts reflect the current search. Switching tabs retains the query.- The effective-access filter uses checkboxes to combine allowed, conditional and denied decisions. Todo selects/clears all; partial selection is announced as mixed. Ancestors remain visible to preserve the path to matching nodes.
showAccessOverviewdefaults totrue. The effective tree derives from current assignments andparentIds, or uses a suppliedaccessTree. When supplying a server-generated tree, refresh it after a successful assignment change.allowFullscreendefaults tofalse, matching the shared React helper. It fills the browser window, restores focus on exit, supports Escape and nested overlays, and reports state throughonFullscreenChange.- Drag catalog resources into the assigned pane, including the effective-access view, or use the explicit + button. Selecting a catalog or assigned resource opens its information without mutating assignments. Assigned category/section selection shows a live summary. The inspector docks on wide workspaces and uses the shared modal Drawer on narrower layouts. Press Space to begin a keyboard drag, arrows to move, and Escape to cancel. Use × to remove one assignment or confirm Quitar todo to clear all. Tree actions remain visible inline.
readOnly, or controlledassignmentswithoutonAssignmentsChange, disables mutations while preserving searching, tree navigation and inspection. The host owns authorization and persistence; presentation groups never change scope.
Import IdentityResourceCategory for a typed category configuration. The manager
reuses React UI's Tree, Tabs, ButtonGroup, Splitter, Drawer, SearchField,
Button, IconButton, and useWorkspaceFullscreen without new dependencies.
Contextual AI copilot
Positive status uses the shared mint indicator tokens. proposal.validation renders a
plain label with a filled checkmark; set validationTone to warning, error, or
neutral for other outcomes. Text remains neutral for readability.
AICopilot is a provider-independent workspace for an objective, connected context,
an explicit action plan, sources, a preview and user-approved changes. It renders
application-provided data; it does not call a model, upload files or execute a plan itself.
import { AICopilot, AICopilotSchedule } from "@uix-design/advanced";
<AICopilot
status={status}
contexts={contexts}
objective={objective}
response={response}
steps={steps}
sources={sources}
proposal={{
id: revisionId,
title: "Tomorrow's schedule",
preview: <AICopilotSchedule items={proposedMeetings} />,
summary: "2 proposed changes",
applyLabel: "Apply 2 changes"
}}
onSubmit={generateProposal}
onAdjust={openProposalEditor}
onApply={applyApprovedRevision}
/>;statusis controlled:idle,generating,ready,applying,appliedorerror. Promise callbacks also lock the local controls while pending. Rejecting a callback presents a generic retryable error; failed requests retain the draft.onApplyreceives the exact proposal id, only through an explicit click on a ready proposal. Give each revision a unique id. Successful ids cannot be reapplied within that mounted instance. The consumer remains responsible for server authorization, persistence and idempotency.readOnlydisables application of changes.proposal.previewaccepts any React node: a table, document, diff, schedule or another exported component.validationis a display slot; setstatus="error"or provideerrorwhen validation should block application.value/onValueChangecontrol the composer;defaultValueinitializes local drafts. Enter sends, Shift+Enter inserts a line and IME composition is respected.- Optional
onAttach,onVoiceInput,onAddContext,onAdjustandheaderActionsenable application-specific controls. Unprovided actions are omitted. Cancellation callsonCancel; the consumer must abort its operation and updatestatus. sourcesopens through a keyboard-accessible disclosure. Step states expose pending, active, complete and error without relying solely on color.labelslocalizes all built-in text. Mobile stacks plan and preview; runtime accent, density, light/dark themes and reduced motion use the shared design system.AICopilotScheduleis a read-only preview for non-overlapping intervals, using minutes since midnight and a boundedstartHour/endHourrange. Its time geometry is proportional. UseCalendarwhen editing or resource scheduling is needed.
The documentation demo runs entirely locally and demonstrates generation, adjustment, explicit application, cancellation, sources, context, history, expansion and retries.
Calendar
Calendar, RichTextEditor and their public types are included in this package.
Styles are loaded automatically with Calendar.
The UI
library catalog includes working examples at /advanced/calendar.
import { Calendar, type CalendarEvent } from "@uix-design/advanced";
import { useState } from "react";
function TeamCalendar() {
const [events, setEvents] = useState<CalendarEvent[]>([]);
return <Calendar events={events} onEventsChange={setEvents} />;
}- The default date and Today use the current date. Day, week, month and agenda
share
date/onDateChangeandview/onViewChangecontrolled contracts. - Local ISO date/time strings use the device's local clock. Explicit ISO offsets
are converted to local time.
timezone,repeatandreminderare event metadata; the consuming application implements timezone conversion, recurring occurrences, notifications, persistence and server-side authorization. - Event IDs must be unique.
endis exclusive and must followstart; malformed events are excluded from the view. All-day and overnight events are supported. - Overlapping timed events use separate columns.
allowOverlap={false}rejects conflicting saves and moves. Pointer placement snaps toslotDuration. - Day and week cover all 24 hours by default, from 00:00 through 23:59. Overnight
events appear in each affected day; the current-time guide remains in view on
initial display.
minHourandmaxHourare inclusive visible-hour bounds (defaults:0and23); set them explicitly to restrict the schedule.hourHeightoptionally overrides the density's row height. Density inherits the theme unless explicitly set tocompact,comfortableorspacious. editable={false}permits inspection without mutation;disableddisables interactions. Saving validates the title and range without silently altering the entered times. Category and location changes update their related fields atomically.- With focus inside the calendar, T goes to today and C creates an event. Shortcuts ignore modified keys and text fields. Arrow keys navigate time slots; Enter opens the editor. Shared popovers and drawers handle focus and Escape.
- Day/week views start at the first column; resizing preserves manual horizontal scrolling. The month uses event counts that open the day view, and agenda provides a single-column list.
The current-time guide appears in day view as a local-time reference for any selected date, and in the current week in either five- or seven-day mode, even when today is a hidden weekend. It is an hour reference across the visible week, drawn above event cards without intercepting clicks or drags. Week views hide it outside the current week; all views respect configured hour bounds. The clock refreshes at minute boundaries and when returning to the tab or enabling the guide.
The toolbar uses a single UIX view selector: Day, Week · 5 days, Week · 7 days,
Month and Agenda. Five-day weeks show Monday–Friday; seven-day weeks honor
firstDayOfWeek and include weekends. The visible date label follows the displayed
days, and previous/next still move by a full week. showWeekends initializes and
synchronizes the week preference; selecting a week retains the public view="week"
contract. Labels can be customized with labels.view, labels.weekFiveDays and
labels.weekSevenDays. This preference affects week view only: Month always shows
complete seven-day rows, including weekends. Returning to week view retains the
selected five- or seven-day preference.
Resource scheduling
Use groupBy="resource" with resources to display people, rooms or services as
independent scheduling columns. Resource IDs must be unique, non-empty strings.
import { Calendar, type CalendarEvent, type CalendarResource } from "@uix-design/advanced";
const resources: CalendarResource[] = [
{
id: "camila",
name: "Dra. Camila Ramos",
type: "person",
subtitle: "Medicina general",
tags: [{ label: "Médica", tone: "info" }],
workingHours: [{ daysOfWeek: [1, 2, 3, 4, 5], startTime: "08:00", endTime: "18:00" }]
}
];
const appointment: CalendarEvent = {
id: "appointment-1",
resourceId: "camila",
title: "Elena Torres",
start: "2026-09-14T09:00",
end: "2026-09-14T09:30",
tags: [{ label: "Confirmada", tone: "success" }]
};
<Calendar
groupBy="resource"
resources={resources}
defaultEvents={[appointment]}
defaultView="day"
allowOverlap={false}
/>;- Day displays a column per resource. Week groups resource columns under each date, with synchronized horizontal scrolling and a shared time axis. Use the resource filter to focus the week on one person. Month retains complete seven-day weeks; month and agenda identify the resource on each event. Filters persist across views.
CalendarTaguses the public UIX Badge tones. Resource tags describe roles or capabilities; event tags describe application-defined states or services. They are metadata preserved when editing or moving an event. Applications update them througheventActionsor their controlledeventsstate.- A click in a column assigns that resource to the draft. Dragging between columns reassigns it while preserving duration and metadata. The editor separates resource assignment from location. Missing or unknown resources appear under Sin asignar.
- In resource mode,
allowOverlap={false}checks conflicts per resource, so different professionals can hold appointments at the same time. Global working hours and each resource's working hours both apply. AddresourceIdto a blocked interval to restrict only that resource; omit it for a shared closure. - Short appointments retain their actual duration; they never expand over another slot to make room for text. The tooltip and inspector provide full details when a card is too small. Resource mode leaves the existing date-based behavior intact.
The additional documentation demo at /advanced/calendar#calendar-resource-demo
uses fictitious appointments and can switch between medical and technical services.
Event cards and availability
Event cards share a borderless tinted surface in day, week, month and agenda.
event.icon accepts a decorative React element. event.attendees displays up to
three UIX avatars (using avatarUrl or name initials), followed by an overflow
count when space permits. Narrow overlapping cards prioritize a multiline title
and start time, reducing the avatar group to one person plus the remaining count and hiding
location and the end time before they collide
with the circular options button. Short cards reduce secondary content further.
Hover or keyboard focus shows the complete title, time range, location and people
in the shared UIX tooltip; Escape dismisses it. Clicking or tapping opens the event.
Select a date heading in week view to open that day with wider event columns.
Week columns retain a readable minimum width and scroll together with their headings.
Timed cards use equal top/bottom and left/right gaps without extending beyond their
actual interval; very short intervals reduce the vertical gap proportionally.
Each sufficiently tall card has a keyboard-accessible options menu, with Open event
and optional eventActions (id, label, icon, disabled, onSelect(event)).
Custom actions are consumer-owned; disable actions that mutate data in read-only
contexts. Toolbar icon-only buttons are circular.
import { Calendar, type CalendarEvent } from "@uix-design/advanced";
import { MessagesSquare, CalendarX2 } from "lucide-react";
import { useState } from "react";
function AppointmentCalendar() {
const [events, setEvents] = useState<CalendarEvent[]>([
{
id: "review",
title: "Team review",
icon: <MessagesSquare />,
start: "2026-09-10T10:00",
end: "2026-09-10T11:30",
attendees: [{ id: "ana", name: "Ana Torres" }]
}
]);
return (
<Calendar
defaultDate="2026-09-10"
events={events}
onEventsChange={setEvents}
workingHours={[
{
daysOfWeek: [1, 2, 3, 4, 5],
startTime: "08:00",
endTime: "18:00"
}
]}
blockedTimes={[
{
id: "meal",
title: "Lunch break",
reason: "meal",
start: "2026-09-10T12:00",
end: "2026-09-10T13:00"
}
]}
eventActions={[
{
id: "cancel",
label: "Cancel event",
icon: <CalendarX2 />,
onSelect: (selected) =>
setEvents((current) =>
current.map((event) =>
event.id === selected.id ? { ...event, status: "cancelled" } : event
)
)
}
]}
/>
);
}- Omit
workingHoursfor unrestricted 24-hour scheduling. An empty array closes every hour. Weekly rules use local weekdays (0= Sunday) andHH:mmbounds;endTimealso accepts24:00. A shift ending earlier than it starts crosses midnight (e.g. Wednesday22:00–06:00continues into Thursday). Overlapping shifts are merged; invalid rules do not open availability. blockedTimescontains dated exceptions, independent of calendar filters:id,title,start, exclusiveend, optionalreason(break,meal,unavailable) andicon. Invalid ranges are ignored. Supply dated occurrences for recurring breaks. Day and week display these ranges as striped bands.- Creation, saving and dragging reject timed events that intersect a block or
fall outside working hours, including partial intersections and overnight
ranges. Blocked areas show a not-allowed cursor and ignore clicks and drops
without inserting messages or shifting the grid. The editor reports invalid
saves inside its form. Adjacent intervals are allowed. New event finds the
first available slot in the selected day's visible range. New events default to
one hour, capped
at the next blocked period or end of the working shift: a free 12:30–13:00 gap
creates a 30-minute draft. Existing event durations are preserved when dragging.
Existing events remain visible when availability changes. Untimed
allDayreminders are exempt from hourly restrictions. - These are UI scheduling constraints; validate availability and permissions again in the application's persistence layer to handle concurrent changes.
Rich text editor
RichTextEditor provides a compact formatting toolbar, paragraph and heading
styles, lists, quotes, editable links, images, dividers and undo/redo. Format
reveals fonts, exact text sizes, alignment, list indentation, superscript/subscript,
text colors and highlights. Styles use UIX theme, accent and density tokens; compact
control groups share separators and scroll horizontally on mobile.
import { useState } from "react";
import { RichTextEditor } from "@uix-design/advanced";
function ProjectBrief() {
const [html, setHtml] = useState("<h2>Project brief</h2><p>Start with the goal.</p>");
return (
<RichTextEditor
label="Project brief"
description="Document the scope and next steps."
value={html}
onChange={setHtml}
/>
);
}- Use
value/onChangefor controlled HTML ordefaultValuefor uncontrolled editing. The editor now starts empty when neither is supplied; it no longer inserts sample content.onChangeemits normalized HTML only when it changes. Controlled echoes preserve the active selection and native editing history. label,descriptionanderrorMessageassociate visible guidance with the textbox.editorAriaLabelremains available for compositions with an external visible label.readOnlypermits reading and selection;disabledalso removes the textbox from the tab order. Both disable formatting and paste/drop edits.minHeightaccepts CSS lengths or numeric pixels.showStatusBar={false}hides the writing mode and whitespace-delimited word/character counts. Counts do not imply that content has been saved; persistence belongs to the consumer.- Tab / Shift+Tab move through all enabled controls in document order. Formatting preserves the text selection and keeps focus on the active toolbar control. Alt+F10 moves from the editor to the toolbar. Left/right arrows and Home/End also navigate its controls; up/down operate the paragraph selector. Escape returns to writing, or closes advanced formatting/link entry. Ctrl/⌘+K opens link entry; native bold, italic, underline and history shortcuts remain available.
- Insert image accepts an HTTP(S) URL and requires descriptive alternative text.
Images fit the writing surface and load lazily. Local file upload/storage is
application-owned; this control inserts already-hosted images. Unsafe image URLs,
event handlers,
srcsetand arbitrary image styles are removed on import/paste. - Link insertion separates Link text from Link address: a short label such as “Guide” can point to a long URL. Selected text prefills the label; leaving the label empty displays the address. Place the caret inside an existing link and use Ctrl/⌘+K or the link icon to edit its label/address or remove the link while keeping its text. Updating only the address preserves text formatting. Insert divider creates a horizontal rule; indentation controls apply to list items. New edits use the same native undo/redo history as text formatting.
- Incoming HTML and pasted/dropped HTML are normalized with an allowlist before
insertion. Nested content, legacy font markup and unsafe link protocols are
handled at the same boundary. Only HTTP(S),
mailto:andtel:links are accepted. Treat stored HTML as untrusted at other rendering/server boundaries and apply the consuming application's sanitization policy there as well. - The native
contenteditable/execCommandbridge is isolated in the editor internals to retain browser undo history. Browser editing behavior is not a structured document model or a collaborative editing protocol. SSR renders the accessible shell; HTML content is inserted and sanitized after client mount. - Existing
showComposerandshowQuickReactionsremain optional. Recipients are local sample state; these controls do not send messages or implement delivery.
Image Gallery
ImageGallery is the React image viewer for collections of photographs or attachments.
Immersive presentation keeps the image inside the inner rounded contour and uses
opaque heading/footer surfaces so image colors never tint the outer corners.
Navigation controls may independently use the frosted glass appearance.
It includes lateral previous/next controls, optional thumbnails, top-aligned title,
description and metadata, and loading/error/empty states. The default framed viewer
shows complete images without cropping.
import { IconButton } from "@uix-design/react";
import { ImageGallery } from "@uix-design/advanced";
import { Download } from "lucide-react";
<ImageGallery
items={[{ id: "lake", src: "/lake.png", alt: "Lake between mountains", title: "Alpine lake" }]}
renderActions={(image) => (
<IconButton label="Download image" onClick={() => downloadImage(image.src)}>
<Download size={18} />
</IconButton>
)}
/>;presentation="immersive"fills the whole component with the image and overlays frosted acrylic metadata, actions and thumbnails over the active image. Chrome respects the provider glass opacity, with opaque fallbacks for reduced transparency, forced colors and browsers without backdrop-filter. It adapts to mobile widths and keeps arrows in the available image area. The defaultpresentation="framed"separates chrome.navigationAppearance="glass"applies frosted surfaces to previous/next arrows. The default is"default";"borderless"is also supported.imageFit="contain"displays the entire image;imageFit="cover"fills the area with proportional cropping. Defaults: contain for framed, cover for immersive.- Use
index/onIndexChangefor controlled navigation ordefaultIndexfor local state. loopdefaults to false; endpoints disable the corresponding arrow.showThumbnailsdefaults to true. The gallery never advances automatically.- Focus the gallery to use Left/Right, Home and End. Touch swipes navigate while vertical scrolling remains available; RTL reverses horizontal navigation.
renderActions(item, index)composes optional actions for the active image. Consumers own sharing, downloads and persistence.disabledlocks navigation; custom actions own their disabled state.- Override
labelsfor localization.--uix-image-gallery-heightcontrols the stable viewport height. Styling ships in the library stylesheet.
RichTextEditor and table surfaces share the Card contour and neutral toolbar/footer surfaces. Writing focus uses a local 3px accent rail at the start of the text area, while toolbar controls retain their own focus indicators. Sorted table headers expose a tinted direction indicator, and selected rows retain their selection background during hover.
Gantt
GanttChart is a virtualized, interactive calendar-day schedule. It uses the shared
Button, IconButton, SearchField, Select, Field, Input and right Drawer. Import GanttTask, GanttDependency, GanttTaskChange and
GanttChartHandle for typed integration.
Built-in Add task, Dependencies, and Delete task actions are available for
uncontrolled schedules or when onScheduleChange handles the controlled schedule.
Select a task, open Dependencies, choose a predecessor, add the connection, then save.
Finish → Start is the default; other anchor relationships and integer calendar-day
lag are available under Relationship and delay. Cancel discards the draft. Duplicate
links, self-links and cycles are rejected. Date conflicts remain warnings; UIX never
silently reschedules tasks.
Hover or select an editable task to reveal its external Start/Finish connection
points. Drag a point onto another task's point, or activate the two points in
sequence with click/tap or Enter/Space. Finish → Start creates FS; the other endpoint
combinations create SS, FF or SF. Escape, pointer cancellation and releasing outside
a point discard a drag. Bar edges still resize dates; the center still moves the
task. Connection points sit above the first/last elbows of the softly rounded
orthogonal lines. Reuse the same point to branch to multiple successors; existing
links remain intact. The preview highlights invalid targets and validates again before one atomic
onScheduleChange transaction. allowDependencyCreation={false} hides the points
while retaining the Dependencies drawer. Read-only/locked tasks and summary groups
do not offer connection points. No new dependency or idle animation loop is added;
hover validation uses a cached graph traversal and only the preview path updates
on animation frames. The timeline scrolls near its edges during a drag.
Use defaultTasks and defaultDependencies for local state. For controlled structural
editing, pass both arrays and onScheduleChange and save the returned GanttSchedule
as one transaction. Its GanttScheduleChange.reason identifies create, delete,
dependencies or an existing task edit reason. Deletion requires confirmation and
removes descendants and all incident connectors; groups containing locked tasks are
protected. onBeforeScheduleChange can synchronously reject any transaction. Existing
onTasksChange and onBeforeTaskChange remain supported for ordinary task edits;
applications should use one persistence callback to avoid duplicate writes.
import { GanttChart, type GanttTask } from "@uix-design/advanced";
const [tasks, setTasks] = useState<GanttTask[]>([
{ id: "design", label: "Design", start: "2026-10-01", end: "2026-10-09", progress: 60 },
{ id: "build", label: "Build", start: "2026-10-12", end: "2026-10-23" }
]);
<GanttChart
tasks={tasks}
dependencies={[{ id: "handoff", sourceId: "design", targetId: "build", type: "FS" }]}
onTasksChange={(next, change) => {
setTasks(next);
// Save change.task to your backend as a single transaction.
}}
defaultZoom="week"
height={520}
/>;- Data: unique task IDs, inclusive
YYYY-MM-DDdates, optionalparentId,type(task,summary,milestone),progress(0–100),assignee,status,baseline,color,disabled,metadata. Milestones have equal start/end dates. - State:
tasks+onTasksChangeordefaultTasks; controlled/uncontrolled collapse and zoom;selectedTaskId+onTaskSelect;onBeforeTaskChangecan reject a transaction.readOnlyprevents pointer, keyboard and form edits. - Interaction: one click selects. The selected editable row shows a pencil to
the right of its progress; its tooltip and accessible name identify the task.
Space is reserved in editable rows so selection does not shift the task text.
Only the selected row mounts the action, including on touch screens. Read-only,
disabled and summary tasks have no edit action; loading/errors expose no rows.
There is no additional selection strip or toolbar edit action. Double-click or
Enter still opens the right drawer. Tab reaches the resize divider and the selected row pencil.
Escape or Cancel discards the draft and returns focus to the initiating control
or schedule. Saving commits one transaction. The drawer fills narrow screens
and keeps its actions visible while fields scroll. Drag tasks to move, edges to
resize. Changes preview locally and commit once on pointer release;
Escape/pointer cancellation discards the draft. Arrow keys, Home/End and Page
Up/Down navigate. Shift + left/right moves an editable task by one day. The form
is the non-drag alternative for start/end/progress edits. Editing remains available
with custom toolbars or
showToolbar={false}. - Dependencies: FS, SS, FF and SF with calendar-day
lag. FS starts at least the day after the source finish plus lag. Violations use dashed warning lines and text; cycles, invalid dates and missing references are reported bybuildGanttModel(tasks, dependencies).issues. Selection emphasizes incident links. - Scale: virtual rows, virtual date ticks, indexed incident dependencies, iterative hierarchy traversal. The docs include a 20,000-task example. This is bounded DOM rendering, not an unlimited-data guarantee; profile representative schedules, particularly dense dependency graphs, on your target devices.
- Calendar header: month/year groups sit above readable day cells (48 px) or
explicit inclusive week ranges. Weeks start on Monday by default; set
weekStartsOn={0}for Sunday (0–6 supported).localeformats labels without changing week boundaries. Month boundaries remain aligned to actual dates, including weeks spanning two months. Group labels remain visible while scrolling. Fit project switches to coarser calendar labels when needed, preserving date positions instead of squeezing daily text. Months group under years; very long fitted schedules use years under decades. - Presentation: theme/accent/density tokens,
height,rowHeight,taskColumnWidth,overscan,dateRange,today,locale,labels,showBaseline,showWeekends,showDependencies,showToolbar,loading,error,renderTaskLabel,renderTaskDetails,taskStyle. - Task column: drag the divider in the Tasks header or focus it and use left/right
arrows (16 px), Shift + arrows (160 px), Home/End for its limits. A guide follows
the pointer; the diagram resizes once on release. Escape cancels. Limits adapt to
the workspace and leave room for the timeline.
defaultTaskColumnWidthsets an uncontrolled initial width.taskColumnWidth+onTaskColumnWidthChangecontrols it; a width without a callback is fixed.resizableTaskColumn={false}hides the handle.labels.resizeTaskslocalizes its accessible name. This layout control remains available in read-only schedules; it never modifies task data. - Imperative navigation:
ref.scrollToTask(id)reveals an already expanded row;ref.scrollToDate(date)navigates the horizontal timeline.
Summary dates, calendars with holidays, automatic scheduling, critical-path calculation, persistence, permissions and multi-user reconciliation belong to the consuming application's model/service. UIX does not move related tasks silently. Dates use UTC calendar-day arithmetic, avoiding DST duration drift.
Implementation references: DHTMLX rendering performance, DHTMLX time scales, DHTMLX keyboard navigation.
The workspace accepts heading, description, actions and status. Use slots
to replace toolbar, buttons or task editor with stable component identities.
Banner and media variants
Banner, Card variant="media" and Carousel variant="media" compose image-led
catalogs, learning libraries and featured content using the same React UI tokens.
The streaming template uses this API; catalog, playback and persistence stay in
consumer code. Existing Card and Carousel calls continue to work unchanged.
import { Banner, Card, Carousel } from "@uix-design/react";
<Banner
title="Explore the collection"
imageSrc="/cover.webp"
contentAlign="start"
contentPosition="end"
minHeight="28rem"
imagePosition="60% center"
overlay="gradient"
headingLevel={1}
/>;
<Carousel
variant="media"
title="Recommended"
itemWidth="clamp(12rem, 25%, 18rem)"
gap="1rem"
scrollStep="item"
controlsPosition="header"
nextLabel="Next items"
>
<Card
variant="media"
title="Ocean"
imageSrc="/ocean.webp"
format="poster"
activateLabel="Play Ocean"
onActivate={() => openPlayer("ocean")}
metadata="Documentary"
progress={42}
progressLabel="Watched"
/>
</Carousel>;- Banner requires
titleandimageSrc. Composeeyebrow,metadata,description,actions; setheadingLevel(1–6).contentAlignandcontentPositionaccept start/center/end.minHeight,contentMaxWidth,contentPaddingandradiusaccept CSS lengths or pixel numbers.overlayis gradient (default), solid or none;overlayOpacityis clamped to 0–1. Keep text contrast sufficient when reducing or removing the scrim. - Card media requires
title,imageSrc,onActivate.formatsupports poster (2:3), landscape (16:9), square (1:1);aspectRatiooverrides it.activationIconreplaces Play, or null hides the icon.hoverEffectis glass (default) or none.contentPadding,actionInset,radius,metadata,actions,progress,progressLabel,disabledandactivateLabelconfigure composition. Secondary actions are outside the primary button and must be disabled separately when appropriate. - Both image surfaces accept
imageAlt(decorative by default),imagePosition,imageFit,imageSrcSet,imageSizes,imageLoadingandsurfaceTheme(dark/light, dark by default). Banner loads eagerly; cards load lazily. - Carousel media accepts
title,children,description,actions,itemWidth,gap,headingLevel(2 by default),showControls,controlsPosition(header/footer),scrollStep(page/item),snap(proximity/mandatory/none),previousLabel,nextLabel. Native scrolling supports touch, trackpads, focus navigation and RTL without cloned children. Use stable child keys. Controls disable at the boundaries and respect reduced motion. The gap above the scrollbar matches the gap between cards. Forslides, autoplay, controlledindex, transitions or thumbnails, use the default Carousel presentation (variant="slides").
CardProps and CarouselProps are discriminated unions. Exported types
CardDefaultProps, CardMediaProps, CarouselSlidesProps, CarouselMediaProps
and BannerProps describe each presentation without mixing incompatible options.
CSS custom properties use --uix-banner-*, --uix-card-media-*, and
--uix-carousel-media-*; prefer typed props for routine customization.
MediaHero, MediaCard and MediaRail remain deprecated compatibility aliases
for Banner and the two media variants. They contain no separate styling or
interaction implementations. New examples and templates use the canonical API.
Notification center
AppHeader opens NotificationCenter from its notification bell. Pass
notifications={{ items, onItemRead, onItemArchive, onItemRestore, onMarkAllAsRead }}
and update your application-owned items in those callbacks. The bell derives its
unread count from the supplied items; notificationCount overrides it for a
paginated server total. notificationLabel localizes the trigger.
The panel supports inbox (all non-archived items), general (non-archived items
with category: "general"), unread, read, and archived tabs. Configure tabs,
activeTab/defaultTab, onTabChange, and optional per-tab count overrides.
status takes precedence over the legacy unread flag. All labels, empty/loading
messages, header/footer content and error content are configurable.
Items accept avatars, an accessible avatarBadge presence label, time/dateTime,
metadata, body content, attachment links and actions (id, label, icon,
variant, disabled, busy, onSelect). Optional section groups the feed.
onActionSelect receives the action and item; persistence and request errors belong
to the consuming app. Use loading, error, and action busy while awaiting your
API. Reading is always explicit, never triggered by hover or opening the panel.
Without items, the panel is empty; opt into defaultNotificationCenterItems
explicitly for sample content. Pass notifications={false} to hide the bell.
Set an item's onView to show a magnifier IconButton. The callback can open a
detail drawer or navigate through the application's router; detailsLabel
provides its accessible name (defaults to "View details"). Summaries remain plain
text. Attachments and action buttons remain separate targets, and opening details
does not implicitly mark an item as read. Presence dots use --uix-success-indicator.
Rows highlight on hover and keyboard focus. Header, tabs and footer share the
system acrylic material with an opaque fallback for reduced transparency.
Empty states and unavailable data
EmptyState is exported from @uix-design/react. It renders content inside an
existing surface without adding a card, border, or background. Existing title,
description, icon, and actions compositions remain supported. The description
is optional and accepts structured content.
size:normal(default) orcompactfor lists and notification panels.align:center(default) orstart.headingLevel: 2–6 (default 3), matching the containing document hierarchy.tone:accent(default),neutral,success,warning, ordanger.- Icons are decorative; express their meaning in the visible text. Actions use
regular
Buttoncomponents and retain keyboard/focus behavior.
<EmptyState
icon={<SearchX size={24} />}
title="No matching projects"
description="Try a different name or clear your search."
actions={<Button onClick={clearSearch}>Clear search</Button>}
/>EmptyState does not infer application state or announce itself automatically.
Use the containing component's status region for dynamic updates. Do not treat a
loading request, missing permissions, or a failed connection as an empty dataset.
DataTableShell accepts error and unavailableState as string or structured
content. Either replaces the table, toolbar, and totals; errors use an alert region,
while unavailable states use a status region. Loading has priority; initial loading
shows only the loading feedback, while a refresh retains existing rows and hides
potentially stale totals. Use emptyState for a successfully loaded list with no
visible records. Search controls remain available for recovery from no results.
NotificationCenter.emptyState and .error accept structured EmptyState content
without an extra icon or text wrapper. Plain messages remain supported.
The same centered composition is used by Tree, ImageGallery, and Calendar's
Agenda view. Tree keeps search and its clear control available; override
emptyContent or search.emptyContent for localized or application-specific
content. ImageGallery.emptyState accepts a complete composition, including an
add-image action. labels.empty still changes only the default gallery message.
Calendar preserves editable day/week/month grids; an empty Agenda offers event
creation only when editing is allowed. Customize labels.noEvents,
labels.noEventsDescription, or replace the composition through emptyState.
Premium's Kanban and MediaManager also reuse EmptyState. Filtered-out content
offers a clear-filters action; a new media library offers its existing upload
flow. Both retain an emptyState override. Kanban messages are configurable via
labels.emptyTitle, emptyDescription, noResultsTitle, noResultsDescription,
and clearFilters. Loading remains distinct from empty content.
Timeline.emptyState replaces the default no-entries message. It does not invent
a create action for an automatically generated activity log. FormSequenceBoard
uses its existing labels.empty and only offers the first-form action when
onAddPanel is provided; populated boards retain their existing add control.
Gantt distinguishes no tasks from no search matches. emptyState can supply
application-owned create/import actions, while its default filtered state clears
the search. labels.noTasks, emptyDescription, and clearSearch customize the
new defaults; labels.empty remains the no-matches message. Loading and errors
retain separate rendering.
Advanced Search (SearchPalette) shows compact initial/no-results guidance;
clearing search and category returns focus to the search field. Its existing
emptyState overrides this composition. AI Copilot guides the first request in
its workspace while leaving the composer available; pending requests show progress
instead. Spreadsheet keeps its initially editable grid, and RichTextEditor keeps
its writing placeholder. Cards, ListGroup, and Carousel do not infer empty states.
Composable card content
Card.Row (also exported as CardRow) distributes tags, assignments, metadata and actions.
It wraps by default; align="start|center|end", justify="start|between|end" and wrap
control composition. Card.Meta (CardMeta) pairs a decorative icon with readable metadata.
Use descriptive text or aria-label for icon/count pairs. Use actual buttons or links for actions.
Compose these with the existing Badge appearance="pastel", Progress and AvatarStack;
Card does not own task state or assume a project-specific data model. Header, description,
actions and footer remain available through the existing Card props.
Concentric surface corners
Card (including variant="media"), Banner, CodeBlock, ImageGallery,
Spreadsheet, FormSequenceBoard, Calendar, GanttChart, RichTextEditor
and panel Tree accept nestedRadius
(default true). Their standalone radius is unchanged. radius sets an explicit
CSS length (numbers are pixels) and takes precedence over automatic nesting;
nestedRadius={false} retains the component's normal radius. These are also
exported as SurfaceRadiusProps.
A Card adjusts the first and last direct compatible surfaces in its vertical
body: top corners of the first child when there is no header, bottom corners of
the last child when there is no footer. Other corners keep the child's own
radius. Each adjusted radius subtracts the body padding and 1px border from the
parent's corresponding corner, clamped at zero. The default
24px radius with a 12px body inset produces an 11px child radius. bodyPadding="none"
subtracts only the border. Nested Cards resolve one level at a time. Density and
runtime token changes update the result entirely in CSS. A small render-time pass
over direct children (and transparent fragments) guards against raw text at either
boundary; it does not walk tree items or component descendants. Geometry adds no
DOM measurements, observers, listeners, effects or React cloning. A fixed-radius
Card can still supply its geometry to its own children.
<Card appearance="outlined">
<CodeBlock title="Source" code={source} language="tsx" />
</Card>A header interrupts only the top corners; a footer interrupts only the bottom.
With both present, the child keeps its own radius. Text or another element before
a surface interrupts its top adjustment; content after it interrupts its bottom
adjustment. CodeBlock also accepts this inset through Grid mode="flow",
unpadded rows and a single full-width column. A sole automatic CodeBlock at an
eligible Card edge uses the Card's existing inset without adding the column's
gutter. Other column padding is subtracted in CSS, including recursive flow
grids; noPadding subtracts nothing. CodeBlock applies an optical minimum of
half the parent corner radius minus its border (11px for a 24px Card), capped at
the block's own radius, so wider density insets do not flatten the curve. This is a visual refinement of strict
concentric geometry; explicit radii and nestedRadius={false} remain unchanged.
Only the first/last eligible path participates, so intervening text or rows interrupt the
corresponding edge. Layout grids, partial/responsive columns, offsets, padded rows,
custom inline styles and arbitrary wrappers remain geometry boundaries. Other
compatible surfaces still use direct Card composition. Controls, pills and avatars
keep their shapes.
Workspace scroll regions keep their existing sizes and behavior. Gallery images,
glass overlays and footer backgrounds follow the adjusted contour; editor toolbar
and status backgrounds do likewise. Only the workspace frame participates in the
parent Card's geometry. Form Sequence Board columns, calendar events, task bars,
cells, thumbnails and controls retain their own geometry.
<Card>
<Spreadsheet sheetName="Project budget" columns={columns} defaultRows={rows} />
</Card>
<Card>
<p>Write the next steps for the team.</p>
<RichTextEditor label="Project notes" />
<p>Changes stay in the project's history.</p>
</Card>Both examples adapt all frame corners to the available Card inset, including
through responsive flow columns. Keep a single example Card: workspaces supply
their own heading, toolbar and footer. Avoid another titled Card around them.
Images inside Banner/media Card follow their surface clipping; arbitrary img
elements are not resized or reinterpreted. Custom margins, transforms or
asymmetric insets require nestedRadius={false} or explicit radii. For nested
parent Cards, use a single length rather than percentage or multi-corner shorthand;
those shapes do not describe a shared circular center. Direct style.borderRadius
or custom geometry overrides are outside the automatic contract.
Spreadsheet structure editing
Click a text column heading to rename it inline, including newly inserted columns. Tab to the heading and press Enter, Space or F2 for keyboard access. Enter or blur saves the trimmed name; Escape cancels, and empty names preserve the previous label. Undo/redo includes label changes. Keys, cell values, formatting and formula addresses stay unchanged. Draft typing stays local to the heading; renaming preserves the normalized cells and formula evaluator instead of recalculating the sheet.
allowRenameColumns defaults to true, independently of allowAddColumns.
readOnly or allowRenameColumns={false} hides editing affordances and blocks
history steps that rename columns. Controlled columns require onColumnsChange;
renaming only calls that callback, so read-only controlled row data can be retained.
Rich React-node headings stay unchanged; only string, number and default headings
are editable. Translate renameColumn, columnNameInput and columnRenamed through
structureLabels.
Spreadsheet starts with no insertion button. Hover the upper/lower half of a row
index to choose the boundary before/after it; use the left/right half of a column
heading for columns. On touch screens, tap that region first. One accent + and
a guide preview the exact insertion boundary, including the start and end of the
sheet. Click the circle to insert. The existing gray header/index areas are used,
without adding left/top margins or permanent append buttons.
A single overlay owns the button independently of the table rows. Insertion keeps its DOM node, focus, position and scroll stable for repeated activation. The visible circle is 20px with a 32px desktop / 44px touch target. Hover changes only update the overlay; geometry is cached per header, with no polling or grid rerender on pointer movement. Scrolling dismisses an inactive preview; a focused control stays attached to the same boundary while visible.
Tab reaches the control. With it focused, arrow keys move between boundaries on the current axis, Home/End reveal the first/last boundary, Enter/Space insert and Escape returns focus to the grid. Column resize handles also reveal the column control on keyboard focus. Click a row number to select the row; Shift-click extends selection. Ctrl/Cmd + Shift + + inserts the selected number of rows above.
<Spreadsheet defaultColumns={columns} defaultRows={rows} allowAddRows allowAddColumns />Use defaultColumns / defaultRows for internal state. For a controlled schema,
pass columns with onColumnsChange; controlled data uses rows with
onRowsChange. Adding a column also reports updated rows with empty cells under
a stable new column key. Controlled values without their matching change callback
cannot be structurally edited.
allowAddRows={false} blocks appending, insertion, paste growth and redo operations
that would add rows. allowAddColumns={false} blocks new columns, including redo
growth. Both default to true; readOnly blocks all mutations. Existing-cell
editing remains available when only structure flags are disabled. Unavailable insertion controls are hidden. structureLabels accepts partial translated labels for
the controls, generated column names and live announcements.
Insertion preserves row IDs, protected cell metadata and formatting. Row and column references in formulas supported by the existing parser move with their referenced cells; ranges expand when insertion falls inside them. Unsupported syntax, including absolute references and external worksheets, is not rewritten. Undo and redo restore rows and column definitions together. Structure work runs on explicit mutations, without menus, continuous measurement or new dependencies. The single indicator changes only on header enter/leave or selection changes, without pointer-move handlers, layout measurements or observers.
File Manager
FileManager is a reusable file workspace: a folder tree, breadcrumbs, scoped search,
folder grid or compact list, multi-selection and metadata operations. Folder artwork is
lightweight SVG using theme tokens; it needs no images, thumbnails or extra dependencies.
import { FileManager, type FileManagerItem } from "@uix-design/advanced";
import { useState } from "react";
const [items, setItems] = useState<FileManagerItem[]>([
{ id: "projects", parentId: null, kind: "folder", name: "Projects" },
{
id: "guide",
parentId: "projects",
kind: "file",
name: "Guide.pdf",
size: 2048,
mimeType: "application/pdf",
modifiedAt: "2026-10-07"
}
]);
<FileManager
title="Team files"
items={items}
onItemsChange={(next, change) => {
setItems(next); // Update the controlled snapshot synchronously.
// Persist change.type and change.ids through your service.
}}
permissions={{ delete: false }}
allowFullscreen
/>;- Use globally unique, stable IDs. Every non-null
parentIdmust refer to a folder; supply an acyclic hierarchy. Renaming and moving preserve identities and contents. defaultItemssupports local state. ControlleditemswithoutonItemsChange, orreadOnly, hides mutations.permissionsindividually enables/disablescreate,rename,move,deleteandupload; these flags are UI policy, not server authorization.folderId/onFolderChangecontrol navigation;defaultFolderIdinitializes it. Search matches names in the current folder. Checkbox selection spans pages in that folder.- Create/rename reject blank, path-like, control-character and overlong names. Sibling names cannot collide, ignoring case and canonical Unicode differences. Move preserves nested selections and prevents cycles. Delete confirms and removes the entire subtree.
onItemsChange(next, { type, ids })is a synchronous metadata transaction, not a network request. Persist in the application, serialize server changes as needed and restore the previous snapshot on failure. Remote libraries must load all descendants before recursive deletion, or enforce deletion/validation on the server. Do not infer complete folder counts from partially loaded data. Reconcile concurrent changes with server versions.onOpenFile(file)andonDownload(file)connect your viewer and download service. WithoutonOpenFile, opening a file shows details;renderPreview(file)can add a preview. There is no implicit URL navigation, remote fetch, content parsing or download.onUpload(file, { folderId, signal, onProgress })returns a promise of file metadata (id,kind: "file",name, optionalsize,mimeType,modifiedAt). Only confirmed uploads enter the original destination. ReuseuploadOptionsfor FileUpload limits, validation, concurrency and localized labels. Closing the upload dialog aborts pending local requests; already completed files remain. Honor the signal and use idempotent upload requests to avoid duplicate remote files on retry or a destination conflict.showSidebardefaults to true and enables both the tree and its quick toggle beside the breadcrumbs. Users can hide it without losing their folder, search, selection or view. The desktop preference survives layout changes while mounted. In narrow containers, navigation opens temporarily and closes after choosing a folder or pressing Escape; focus returns to the trigger when dismissed.showSidebar={false}removes both the tree and toggle. The sharedButtonGroupview selector supports arrow/Home/End focus navigation and Enter/Space activation.- Navigation composes the public
Treewithappearance="plain", its own folder search, connectors, keyboard model and selection indicator. The root is a tree item, not a separately styled navigation button. File Manager's upload dialog usesFileUploadwithappearance="plain"so the Dialog owns the frame and heading. pageSizedefaults to 24 and is capped at 100. The tree is bounded at 200 folders; all items remain reachable through paginated main navigation. The model indexes metadata and defers search, without reading file bodies or creating previews.labels,locale,loading,error,onRetry,allowFullscreen,fullscreenLabels,radiusandnestedRadiuscover localized status, themes and existing UIX panel geometry. Native controls, the existing Tree keyboard model and shared dialogs provide keyboard access.
The React UI documentation includes a working Card example, localized labels, configuration
switches and a transport integration sample at /advanced/file-manager.
Composing a workspace with full-window support
useWorkspaceFullscreen<HTMLElement>(options, accessibleName) is exported for
composite workspaces in consumer packages. Pass the shared FullscreenProps;
attach the returned ref, merge style on the root, and set
data-uix-fullscreen={active || undefined}. Render action in your header.
Use uix-workspace-heading, uix-workspace-title and
uix-workspace-description for shared heading insets, typography and action sizes.
The consumer owns its full-height content layout; the helper owns top-layer
placement, background inertness, Escape, body scroll locking and focus restoration.
Tree's actionsPresentation defaults to auto (a menu in narrow trees). Choose
inline to keep separate row controls even within a narrow desktop pane, or
menu to always group them. Pair inline presentation with each item's existing
actionsVisibility="always" when actions must remain visible without hovering.
Shared workspace headings with subtitles use their natural title line height,
retaining the standard 12px inset and 32px desktop / 44px touch controls.
uix-workspace-mark provides the reusable accent icon tile.
Form sequence board
FormSequenceBoard shares the workspace surface radius, panel colors and 12px
header/footer insets used by Cards and the data workspaces. Its board footer shows
the form count and completion totals outside the scrolling track. Pass footer
for additional information or actions; each panel retains its own separate footer.
Column headings keep
the circular collapse action on the first row; footer actions use the shared
outline Button, respecting density and touch targets. Status badges and progress
remain semantic. Mobile layouts stack the forms while desktop keeps horizontal
navigation and independently scrollable form bodies. Existing panel, theme and
collapse APIs are unchanged. Ordinary wheel gestures use native browser scrolling;
Shift+wheel remains an explicit horizontal shortcut without consuming gestures at the board boundary.
Panel bodies scroll first when they have room; at either boundary, or without
vertical overflow, scrolling continues in the surrounding page. Textareas inside
panels also participate in this chain.
The same page-scroll behavior applies to Calendar time grids, Tree, PermissionMatrix and inline FilterMenu. Floating FilterMenu panels and modal boundaries intentionally contain scrolling.
Loading State Kit
LoadingStateKit is a lightweight composition wrapper for scoped accent color.
The kit supplies independent feedback components, not a framed application workspace.
Import from @uix-design/advanced/loading-state-kit; styles load automatically.
Use LoadingState to switch between loading, error, empty, and ready content, in that
priority order. Provide meaningful fallback actions such as retry or load sample data.
Skeletons are decorative: wrap a skeleton-only loading fallback in one labelled status
region. LoadingOverlay keeps children mounted; blocking disables both pointer and
keyboard interaction with the covered content via inert. Nonblocking overlays keep
that content interactive. A page overlay is a loading surface, not a modal dialog.
LoadingOverlay and its styles are owned by @uix-design/react. The Advanced export
is a re-export of that same implementation; new code should import it from React UI.
ProgressBar uses indeterminate feedback when its value is missing or non-finite;
known values are bounded by a valid min/max range. Motion respects reduced-motion
preferences. UploadProgress reports completed uploads at 100%, and only exposes
cancel/retry when the corresponding callback is provided. Documentation presents
independent examples of the indicators, skeletons, overlays and contextual states.
All fram
