Repository navigation
WebExpress.WebUI 2.0.0-alpha
Release date: 2026-10-31
Target framework: .NET 10 (net10.0)
Blog: WebExpress 2.0.0-alpha – Halloween update
WebExpress.WebUI 2.0.0-alpha is a major release. The library no longer bundles Bootstrap, Popper.js, Chart.js or Font Awesome. It ships its own stylesheets, its own SVG icon set and its own chart engine instead. The release also adds many new controls (spreadsheet, schedule, SLA, master-detail, cookie banner, media players and more), a server-side PDF renderer, real-time collaborative editing, and a shared contract that all client controls follow.
Highlights
- No third-party front-end frameworks. Bootstrap 5.3.8, Popper.js 2.11.8, Chart.js 4.5.0 and Font Awesome Free 7.1.0 have been removed. Layout, popovers, tooltips, modals and charts now run on WebExpress code.
- Own icon set. Icons are stroke drawings on a 21×21 grid, applied as CSS masks so they take the text color and font size. 240 new icon classes and about 1,370 SVG drawings were added.
- New controls, including a spreadsheet, schedule, SLA widget, master-detail view, heat map, traffic light, barcode, video/audio player, PDF viewer, cookie consent banner and login modal.
- Server-side PDF generation from Markdown and from stored editor content, with no browser or third-party library.
- Real-time collaborative editing based on operational transformation, for the WYSIWYG editor, the graph editor and the spreadsheet.
- State-driven client controls. The new
StateCtrlbase and the keyedRendererreconciler, plus a binding control contract for state, changes, validation, saving and lifecycle. - Accessibility pass across all controls: label bindings,
aria-labelledbyfor form controls that cannot take a<label>, autofill attributes, and contrast fixes.
New Features
Layout and Containers
ControlBoxputs a frame around related content, with a primary, secondary and preferences section (SectionBoxPrimary,SectionBoxSecondary,SectionBoxPreferences).ControlSectionis a flat, collapsible section with a label row, without the frame of a card.ControlGrouplays out related items as fields of one surface, separated by hairlines.ControlAccordion/ControlAccordionItemare built on native<details>elements and need no script.ControlCardhas a header and footer that each take an icon and their own background and text colors.ControlOffcanvasis a drawer that slides in from an edge of the viewport.ControlMasterDetailputs a list and a detail region side by side with a splitter.ActionMasterDetailandActionMasterDetailTogglecontrol it.ActionSplitFitresizes the side pane of a split control to fit its content. The split control also got a responsive app-shell layout.ControlButtonGroup,ControlPopover,ControlTooltipandControlSpinnerreplace their Bootstrap-based versions.
Data Display
ControlSpreadsheet: workbooks with several sheets, formulas, number and date formats, cell formatting, clipboard support for common spreadsheet formats, find, undo/redo and real-time collaboration. On the server,SpreadsheetWorkbook,SpreadsheetSheet,SpreadsheetCell,SpreadsheetStyle,SpreadsheetAddressandSpreadsheetDatelet applications build and read workbooks without handling JSON.ControlScheduleis a calendar for appointments, events and tasks, with agenda, week and month views and holidays (ControlScheduleItem,ControlScheduleHoliday).ControlSlais a service level agreement widget: status, budget meter, time left, periodic cycles, and pause/resume/settle actions.SlaEvaluatorcomputes the status on the server. The client counts down and moves between states.ControlHeatMapshows a grid of numbers as color-graded cells.ControlTrafficLightis a read-only red/yellow/green status display.ControlBarcodesupports Code 128, Code 39, EAN-13, EAN-8 and QR codes, with configurable QR error correction.ControlStatis a KPI tile with a value, a trend-colored delta and an optional icon.ControlSteps,ControlTimeline,ControlDescriptionList,ControlAvatarGroup,ControlEmptyStateandControlSkeletonadd step indicators, activity feeds, key/value lists, stacked avatars, empty-state placeholders and loading skeletons.ControlDnfshows filters in disjunctive normal form, such as(A AND B) OR C.ControlCountry,ControlPhoneandControlEmaildisplay these values. Country flags are optional.ControlContentis the reading view for stored rich text (WYSIWYG) or Markdown. It removes the editor's working markup and cleans raw markup before showing it.
Charts
- A native WebExpress chart engine replaces Chart.js. It supports bar and line datasets per series (
TypeDatasetChart), straight, Bézier and monotone curves (TypeCurveChart), and linear or moving-average trend lines (TypeTrendlineChart). - Axes with fixed bounds clip the series instead of clamping values. Polar area charts draw every visible dataset. Stacked filled areas rest on the series beneath them. Legend toggles keep keyboard focus.
Media and Documents
ControlVideo(withControlVideoTrack) andControlAudiouse the browser's built-in player and need no script.ControlPlayeris their common base andControlPlayerSourceadds sources.ControlPdfViewerembeds a PDF with an<object>element. Browsers without an inline viewer show a link instead.
Form Inputs
- New inputs:
ControlFormItemInputChoice(segmented buttons),ControlFormItemInputSlider(two-handle range),ControlFormItemInputEstimate(estimate scale as chips),ControlFormItemInputTrafficLight,ControlFormItemInputBarcode,ControlFormItemInputDnfandControlFormItemInputSpreadsheet(posts the workbook as JSON and reads it back throughGetWorkbook). - Formatted text inputs based on
ControlFormItemInputFormatted:ControlFormItemInputEmail,ControlFormItemInputDomain(DOMAIN\useroruser@domain.tld),ControlFormItemInputFqdn,ControlFormItemInputIp(IPv4/IPv6),ControlFormItemInputPhoneandControlFormItemInputCountry. The server normalizes the posted value and rejects text that is not valid (EmailAddress,DomainLogon,HostName,IpAddress). - Phone input and display use per-country numbering plans (
PhoneCatalog) and tell apart countries that share a calling code, such as Canada and the Bahamas under +1.CountryCatalogand 249 country flags support the country input. IControlFormItemInputcontrols share a standard contract for value, disabled, required, validation and dirty state.SvgContentaccepts an uploaded SVG only if it contains no scripts, event handlers, script addresses, embedded HTML or nested documents.BindUpload/IBindUploadconnect uploads to bindings.
Tables, Kanban, Quickfilter and Dashboard
- Table: client-side search (
TableCtrl.search(term)).ControlTabletakes aBind, so aControlSearchcan be attached with aBindSearch. Ordering, editing and sorting have been improved. - New table templates:
ControlTableTemplateBarcode,…Country,…Dnf,…Email,…Html,…Markdown,…Phoneand…TrafficLight.ControlTableCellMarkupshows formatted text but sorts and filters by plain text.TypeHorizontalAlignmentTablesets column alignment. - Kanban: columns can have configurable statuses with a color, and the status is shown on cards. A status can be picked when dropping a card. Columns can be resized by dragging (replaces the old size menu). A column can refuse a drop. Cards can have footer chips (
ControlKanbanCardChip). - Quickfilter: new item types
ControlQuickfilterItemAdd,…Avatar,…Dropdown,…DropdownItemand…MultiSelect. - Dashboard and kanban got settings dialogs. Dashboard widget rendering, lifecycle and persistence were reworked.
- Drop targets now look the same in all controls: a line for "insert between", a tinted dashed area for "insert into", and a red area for a refused drop. Colors come from the
--wx-drop-*tokens and have dark-mode variants.
WYSIWYG Editor and Content
- The editor uses a state-driven model/view architecture (
webexpress.webui.editor.model.js,webexpress.webui.editor.view.js). - New add-ons: box, code and document. Notes and comments are new, and notes also appear in
ControlContent. - Section and table handling have been improved, and the headline can optionally be edited.
- Slash commands, add-on categories and other editor texts are now translated.
EditorContent(server side) applies the same cleanup rules as the client. It converts stored editor values withConvertToMarkdownandConvertToPdf.- A
nulleditor value is read as an empty document and no longer rejects the form.
Collaborative Editing
webexpress.webui.Otis a DOM-free operational transformation core, used by the WYSIWYG editor, the graph editor and the spreadsheet for real-time editing with several users. See ot.md.
Markdown and PDF
- New
WebPdfnamespace:PdfDocumentand its block and inline element model,PdfRendererMarkdown(ConvertMarkdownToPdf) andPdfRendererHtml. PDF files are created entirely in-process. Page size, margins and font can be set up to the moment the document is written. - Plugin elements in PDFs: an
IPdfPluginwith aNameAttributeis registered automatically when its plugin loads (PdfPluginManager). Outside a server it is registered throughPdfPluginRegistry.Register. - Plugin elements in Markdown:
IMarkdownPlugin,MarkdownPluginManagerandMarkdownPluginRegistrydo the same for HTML output. MarkdownRendererHtmlToMarkdownconverts HTML back to Markdown through the Markdown AST.
Sign-in and Session
ControlModalLoginshows the login form in a modal dialog.- The login controls have a "Stay signed in" switch (on by default) and buttons for configured OpenID Connect providers. A translated message appears when an external sign-in fails.
webexpress.webui.session.jsrenews the short-lived access credential before it expires, when a tab wakes up, and after a server restart. Tabs coordinate through a Web Lock so a single-use refresh credential is redeemed only once. If the server is unreachable, it retries every 30 seconds.
Privacy and Consent
ControlCookieBannershows cookie notices or consent choices that the application configures (TypeCookieBannerMode.Notice/Consent,CookieBannerCategory). It does not load any providers.CookieBannerDecisiongives application code the visitor's validated choice for the current request. See cookie.banner.md.
Notifications
INotification.Linkholds the address a notification refers to.AddNotificationtakes alinkargument.INotificationManager.DispatchNotificationpasses the application and session context to transports such as the message queue.- Notifications work in a cluster:
NotificationRecordis the serializable form, andSessionPropertyNotificationConverterstores session notifications. INotification.IsExpired(DateTime utcNow)checks expiry in UTC.
Theming, Persistence and Internationalization
- A unified color scheme for all controls.
ContrastColorpicks black or white text by WCAG contrast for fill colors set by the author. - UI state (active tab, column widths, split sizes, view mode, etc.) is saved in
localStoragethroughwebexpress.webui.LocalStorageinstead of cookies. - Dark mode can follow a choice stored on the server: if the root element has
data-wx-theme-service, the rendereddata-wx-themeis used and the local copy is not written. - Client texts follow the page language from the
langattribute on<html>and fall back to the browser language only when it is missing.
Fragments
- New fragment classes for many controls, e.g.
FragmentControlAccordion,…Barcode,…Box,…Carousel,…Chart,…Code,…CookieBanner,…EmptyState,…HeatMap,…Html,…MasterDetail,…Search,…Section,…Skeleton,…Slaand…Stat. - Fragment controls decide whether to render through
FragmentContext.Check(request).
Performance
- Loading a spreadsheet workbook skips the full comparison with the current one when sheet count, IDs, names or dimensions already differ. Before, this comparison cost more than loading a 300,000-row workbook.
- All client controls render through
StateCtrland the keyedRenderer, which applies the smallest set of DOM changes. Several state changes in one turn render once.
Bug Fixes
- Security: The reading view parses raw stored values inertly and cleans them before inserting them, so framed documents, embedded plug-ins and script addresses are removed. The cleanup rules are now shared in
EditorHtml.clean. Markdown table cells no longer turnjavascript:,data:orvbscript:addresses into links. XSS handling inControlTextandPdfRendererHtmlwas corrected. - Forms: A form rendered several times in one request processes a submission only once. Selection and cascading inputs now read the submitted value under the field name instead of the ID, which also fixes the required check. The color input submits its value.
- Notifications: A dismissed session notification is actually removed and does not come back on the next page or reconnect. Session notifications are thread-safe. Dismissing over a socket uses the current session state.
RemoveNotifications(request)no longer clears other users' global notifications. - Spreadsheet: Formula results are copied, sheet references and named ranges are kept when cells move, and out-of-bounds writes are rejected.
SpreadsheetWorkbookkeeps hidden rows, columns and sheets. - Date inputs: Date and date-range calendars open on the current month when empty, and moving forward from the 31st no longer skips a month.
- Cookie banner: A withdrawal that cannot be stored removes the earlier consent. A tab showing an older policy version no longer deletes the newer version's cookie.
- Rendering: Table cell panels keep their layout classes. Light and dark badges have a visible edge. Schedule entries with a link keep their text color. The avatar widget no longer requests the URL
undefined. Dark-mode text colors no longer stay stuck. WYSIWYG editor dark mode, icon visibility and colors were fixed. - Graph and workflow: Rendering, edge alignment, workflow reload and autosave serialization were fixed.
- Other: The controller registry no longer treats the
data-wx-bindof a<template>as an unregistered binding. Card rendering, state persistence, tab renaming, dashboard widgets and internal links/images were reworked or fixed.MarkdownParserhandles alignment correctly and no longer adds extra table columns. Contrast was raised to at least 4.5:1 for code tokens, the calendar week column and the DNF add button.
Breaking Changes
- Bootstrap, Popper.js and Font Awesome removed.
bootstrap.min.css,bootstrap.min.js,popper.min.js,fontawesome.min.css,solid.cssand the Font Awesome web fonts are no longer shipped or included. Markup that relies on Bootstrap classes orfa-*icon classes is no longer styled. - Chart.js removed.
chart.jsis no longer included. Charts are drawn by the WebExpress chart engine. - Icon API.
Iconno longer has a theme or a constructor that takes a theme. Subclasses now implementSymbol, andClassreturnswx-icon-light wx-icon-light-<symbol>. Removed or renamed icon classes:IconChildCombatant,IconCommentAltandIconTrashAlt(removed),IconPaperclip→IconPaperClip,IconRSS→IconRss. - Panel controls renamed (the
Panelprefix was dropped):ControlPanelCallout→ControlCallout,ControlPanelCenter→ControlCenter,ControlPanelDismissible→ControlDismissible,ControlPanelFlex→ControlFlex,ControlPanelFooter→ControlFooter,ControlPanelGrid→ControlGrid,ControlPanelHeader→ControlHeader,ControlPanelMain→ControlMain,ControlPanelMedia→ControlMedia,ControlPanelNavbar→ControlNavbar,ControlPanelOverflow→ControlOverflow,ControlPanelSplit→ControlSplit,ControlPanelToast→ControlToast,ControlPanelTool→ControlToolIControlPanelDismissible→IControlDismissible,IControlPanelSplit→IControlSplitFragmentControlPanelDismissible→FragmentControlDismissible,FragmentControlPanelFlex→FragmentControlFlex,FragmentControlPanelTool→FragmentControlTool,IFragmentControlPanelDismissible→IFragmentControlDismissibleSectionPanelDismissibleBody→SectionDismissibleControlPanelCardwas removed. UseControlCardinstead.FragmentControlPanelDismissibleBodyandIFragmentControlPanelDismissibleBodywere removed.
- Expandable removed.
webexpress.webui.expandable.js/.cssand their documentation were removed. UseControlAccordioninstead. - Removed client scripts:
webexpress.webui.message.queue.jsandwebexpress.webui.modal.confirm.delete.js. - Notification API:
INotification.Scopswas removed, andINotification.Linkwas added.AddNotification(…)takesstring linkinstead ofIEnumerable<IScope> scops.- The session overloads take
IRequestinstead ofRequest. RemoveNotifications(IApplicationContext, Request)→RemoveNotifications(IRequest), which now clears only the session.RemoveNotifications(Guid)→RemoveNotifications(Guid id, Session session = null).- The event
DispatchNotificationwas added toINotificationManager.
- Changed behavior:
- UI state is now stored in
localStorageinstead of cookies, so view state saved earlier in cookies is not carried over. - Client texts use the page language instead of the browser language.
I18N.translatereturns a key that has no module unchanged.
- UI state is now stored in
- Dependency: Requires
WebExpress.WebCore2.0.0-alpha.
Dependencies
| Package / component | Change | Version | Licence |
|---|---|---|---|
WebExpress.WebCore (NuGet) |
updated | 0.0.11-alpha → 2.0.0-alpha | MIT |
Microsoft.Sbom.Targets (NuGet, build only, PrivateAssets="all") |
added | 4.1.13 | MIT |
flag-icons (country flags, Assets/flags) |
added | 7.2.3 | MIT |
libphonenumber-js (numbering plan data in PhoneCatalog) |
added (data only) | – | MIT |
| Bootstrap (CSS and JS) | removed | 5.3.8 | MIT |
Popper.js (@popperjs/core) |
removed | 2.11.8 | MIT |
| Chart.js | removed | 4.5.0 | MIT |
| Font Awesome Free (CSS, web fonts) | removed | 7.1.0 | Icons CC BY 4.0, fonts SIL OFL 1.1, code MIT |
A new THIRD-PARTY-NOTICES.md lists the direct dependencies and includes the original licence texts.
Build and Tests
- Release builds generate an SPDX SBOM. It is embedded in the
.nupkgand also saved next to the package as<packageid>.spdx.json(with a.sha256file). Visual Studio builds hand the SBOM generation todotnet msbuild. - The solution moved from
WebExpress.WebUI.slntoWebExpress.WebUI.slnx. dotnet testruns on Microsoft.Testing.Platform, enabled through a newglobal.json. The obsoleteTestingPlatformDotnetTestSupportproperty was removed.- Test project:
xunit.v33.2.2 → 4.0.2,Microsoft.NET.Test.Sdkremoved, server garbage collection enabled, andDebugLocalbuilds against the local WebCore sources. - New JavaScript test suite: 176
*.test.mjsfiles run under Node throughUnitTestJavaScript, with up to one Node process per processor. - C# tests now run in parallel. Each test has its own component hub, and only the Markdown and PDF plugin tests run serially. The number of C# unit test files grew from 178 to 261.
- The large-workbook and Node-runner tests use limits that do not depend on machine load.
- Sample test data uses neutral names.
- The documentation workflow now references the correct solution and Node version.
Documentation
- New pages under
docs/js:barcode,box,card,choice,content,contract,cookie.banner,country,dnf,domain,email,estimate,formatted-input,group,heatmap,kanban,login,master-detail,ot,pdf-viewer,phone,player,schedule,section,sla,slider,spreadsheet,state,stepsandtraffic-light. - New
docs/icons.md(icon set and how to add icons) anddocs/structured-content-extensions.md. docs/js/panel.dismissible.mdwas renamed todocs/js/dismissible.md, anddocs/js/expandable.mdwas removed.- Updated:
chart.md(native engine),editor.mdandgraph.md(collaboration),md-guide.md(PDF and Markdown plugins),webexpress.webui.md(local storage),wql.md, plus many control pages. README.md: new project description, corrected guide links, and an AI transparency notice.