Skip to content

0.0.2-alpha

Latest

Choose a tag to compare

@ReneSchwarzer ReneSchwarzer released this 31 Oct 08:48
· 2 commits to main since this release
5969440

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 StateCtrl base and the keyed Renderer reconciler, plus a binding control contract for state, changes, validation, saving and lifecycle.
  • Accessibility pass across all controls: label bindings, aria-labelledby for form controls that cannot take a <label>, autofill attributes, and contrast fixes.

New Features

Layout and Containers

  • ControlBox puts a frame around related content, with a primary, secondary and preferences section (SectionBoxPrimary, SectionBoxSecondary, SectionBoxPreferences).
  • ControlSection is a flat, collapsible section with a label row, without the frame of a card.
  • ControlGroup lays out related items as fields of one surface, separated by hairlines.
  • ControlAccordion / ControlAccordionItem are built on native <details> elements and need no script.
  • ControlCard has a header and footer that each take an icon and their own background and text colors.
  • ControlOffcanvas is a drawer that slides in from an edge of the viewport.
  • ControlMasterDetail puts a list and a detail region side by side with a splitter. ActionMasterDetail and ActionMasterDetailToggle control it.
  • ActionSplitFit resizes the side pane of a split control to fit its content. The split control also got a responsive app-shell layout.
  • ControlButtonGroup, ControlPopover, ControlTooltip and ControlSpinner replace 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, SpreadsheetAddress and SpreadsheetDate let applications build and read workbooks without handling JSON.
  • ControlSchedule is a calendar for appointments, events and tasks, with agenda, week and month views and holidays (ControlScheduleItem, ControlScheduleHoliday).
  • ControlSla is a service level agreement widget: status, budget meter, time left, periodic cycles, and pause/resume/settle actions. SlaEvaluator computes the status on the server. The client counts down and moves between states.
  • ControlHeatMap shows a grid of numbers as color-graded cells.
  • ControlTrafficLight is a read-only red/yellow/green status display.
  • ControlBarcode supports Code 128, Code 39, EAN-13, EAN-8 and QR codes, with configurable QR error correction.
  • ControlStat is a KPI tile with a value, a trend-colored delta and an optional icon.
  • ControlSteps, ControlTimeline, ControlDescriptionList, ControlAvatarGroup, ControlEmptyState and ControlSkeleton add step indicators, activity feeds, key/value lists, stacked avatars, empty-state placeholders and loading skeletons.
  • ControlDnf shows filters in disjunctive normal form, such as (A AND B) OR C.
  • ControlCountry, ControlPhone and ControlEmail display these values. Country flags are optional.
  • ControlContent is 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 (with ControlVideoTrack) and ControlAudio use the browser's built-in player and need no script. ControlPlayer is their common base and ControlPlayerSource adds sources.
  • ControlPdfViewer embeds 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, ControlFormItemInputDnf and ControlFormItemInputSpreadsheet (posts the workbook as JSON and reads it back through GetWorkbook).
  • Formatted text inputs based on ControlFormItemInputFormatted: ControlFormItemInputEmail, ControlFormItemInputDomain (DOMAIN\user or user@domain.tld), ControlFormItemInputFqdn, ControlFormItemInputIp (IPv4/IPv6), ControlFormItemInputPhone and ControlFormItemInputCountry. 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. CountryCatalog and 249 country flags support the country input.
  • IControlFormItemInput controls share a standard contract for value, disabled, required, validation and dirty state.
  • SvgContent accepts an uploaded SVG only if it contains no scripts, event handlers, script addresses, embedded HTML or nested documents. BindUpload / IBindUpload connect uploads to bindings.

Tables, Kanban, Quickfilter and Dashboard

  • Table: client-side search (TableCtrl.search(term)). ControlTable takes a Bind, so a ControlSearch can be attached with a BindSearch. Ordering, editing and sorting have been improved.
  • New table templates: ControlTableTemplateBarcode, …Country, …Dnf, …Email, …Html, …Markdown, …Phone and …TrafficLight. ControlTableCellMarkup shows formatted text but sorts and filters by plain text. TypeHorizontalAlignmentTable sets 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, …DropdownItem and …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 with ConvertToMarkdown and ConvertToPdf.
  • A null editor value is read as an empty document and no longer rejects the form.

Collaborative Editing

  • webexpress.webui.Ot is 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 WebPdf namespace: PdfDocument and its block and inline element model, PdfRendererMarkdown (ConvertMarkdownToPdf) and PdfRendererHtml. 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 IPdfPlugin with a NameAttribute is registered automatically when its plugin loads (PdfPluginManager). Outside a server it is registered through PdfPluginRegistry.Register.
  • Plugin elements in Markdown: IMarkdownPlugin, MarkdownPluginManager and MarkdownPluginRegistry do the same for HTML output.
  • MarkdownRendererHtmlToMarkdown converts HTML back to Markdown through the Markdown AST.

Sign-in and Session

  • ControlModalLogin shows 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.js renews 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

  • ControlCookieBanner shows cookie notices or consent choices that the application configures (TypeCookieBannerMode.Notice / Consent, CookieBannerCategory). It does not load any providers. CookieBannerDecision gives application code the visitor's validated choice for the current request. See cookie.banner.md.

Notifications

  • INotification.Link holds the address a notification refers to. AddNotification takes a link argument.
  • INotificationManager.DispatchNotification passes the application and session context to transports such as the message queue.
  • Notifications work in a cluster: NotificationRecord is the serializable form, and SessionPropertyNotificationConverter stores session notifications.
  • INotification.IsExpired(DateTime utcNow) checks expiry in UTC.

Theming, Persistence and Internationalization

  • A unified color scheme for all controls. ContrastColor picks 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 localStorage through webexpress.webui.LocalStorage instead of cookies.
  • Dark mode can follow a choice stored on the server: if the root element has data-wx-theme-service, the rendered data-wx-theme is used and the local copy is not written.
  • Client texts follow the page language from the lang attribute 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, …Sla and …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 StateCtrl and the keyed Renderer, 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 turn javascript:, data: or vbscript: addresses into links. XSS handling in ControlText and PdfRendererHtml was 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. SpreadsheetWorkbook keeps 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-bind of a <template> as an unregistered binding. Card rendering, state persistence, tab renaming, dashboard widgets and internal links/images were reworked or fixed. MarkdownParser handles 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.css and the Font Awesome web fonts are no longer shipped or included. Markup that relies on Bootstrap classes or fa-* icon classes is no longer styled.
  • Chart.js removed. chart.js is no longer included. Charts are drawn by the WebExpress chart engine.
  • Icon API. Icon no longer has a theme or a constructor that takes a theme. Subclasses now implement Symbol, and Class returns wx-icon-light wx-icon-light-<symbol>. Removed or renamed icon classes: IconChildCombatant, IconCommentAlt and IconTrashAlt (removed), IconPaperclip → IconPaperClip, IconRSS → IconRss.
  • Panel controls renamed (the Panel prefix 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 → ControlTool
    • IControlPanelDismissible → IControlDismissible, IControlPanelSplit → IControlSplit
    • FragmentControlPanelDismissible → FragmentControlDismissible, FragmentControlPanelFlex → FragmentControlFlex, FragmentControlPanelTool → FragmentControlTool, IFragmentControlPanelDismissible → IFragmentControlDismissible
    • SectionPanelDismissibleBody → SectionDismissible
    • ControlPanelCard was removed. Use ControlCard instead.
    • FragmentControlPanelDismissibleBody and IFragmentControlPanelDismissibleBody were removed.
  • Expandable removed. webexpress.webui.expandable.js / .css and their documentation were removed. Use ControlAccordion instead.
  • Removed client scripts: webexpress.webui.message.queue.js and webexpress.webui.modal.confirm.delete.js.
  • Notification API:
    • INotification.Scops was removed, and INotification.Link was added.
    • AddNotification(…) takes string link instead of IEnumerable<IScope> scops.
    • The session overloads take IRequest instead of Request.
    • RemoveNotifications(IApplicationContext, Request) → RemoveNotifications(IRequest), which now clears only the session.
    • RemoveNotifications(Guid) → RemoveNotifications(Guid id, Session session = null).
    • The event DispatchNotification was added to INotificationManager.
  • Changed behavior:
    • UI state is now stored in localStorage instead 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.translate returns a key that has no module unchanged.
  • Dependency: Requires WebExpress.WebCore 2.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 .nupkg and also saved next to the package as <packageid>.spdx.json (with a .sha256 file). Visual Studio builds hand the SBOM generation to dotnet msbuild.
  • The solution moved from WebExpress.WebUI.sln to WebExpress.WebUI.slnx.
  • dotnet test runs on Microsoft.Testing.Platform, enabled through a new global.json. The obsolete TestingPlatformDotnetTestSupport property was removed.
  • Test project: xunit.v3 3.2.2 → 4.0.2, Microsoft.NET.Test.Sdk removed, server garbage collection enabled, and DebugLocal builds against the local WebCore sources.
  • New JavaScript test suite: 176 *.test.mjs files run under Node through UnitTestJavaScript, 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, steps and traffic-light.
  • New docs/icons.md (icon set and how to add icons) and docs/structured-content-extensions.md.
  • docs/js/panel.dismissible.md was renamed to docs/js/dismissible.md, and docs/js/expandable.md was removed.
  • Updated: chart.md (native engine), editor.md and graph.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.