Repository: outsystems-ui Runtime Environment: User Browser (library loaded by OutSystems applications) Last Updated: 2026-08-19
OutSystems UI is a client-side library that provides the TypeScript behaviors and CSS for 70+ UI patterns (Accordion, Carousel, DatePicker, Dropdown, Tabs, Sidebar, …) used by OutSystems Reactive Web and Native Mobile applications. It has no server component: the build produces one JavaScript bundle and one CSS bundle per platform target (O11, ODC), which the OutSystems runtime loads into the end user's browser and drives through the OutSystems.OSUI.* public API.
graph TB
ThisRepo["outsystems-ui<br/>Runs on: User Browser<br/>(AMD bundle loaded by host app)"]
HostApp["OutSystems App Runtime<br/>(Reactive Web / Mobile)<br/>EXTERNAL"]
Splide["Splide global window.Splide<br/>EXTERNAL"]
Flatpickr["Flatpickr global window.flatpickr<br/>EXTERNAL"]
NoUISlider["noUiSlider global window.noUiSlider<br/>EXTERNAL"]
VirtualSelect["VirtualSelect global window.VirtualSelect<br/>EXTERNAL"]
FloatingUI["Floating UI global window.FloatingUIDOM<br/>EXTERNAL"]
DOM["Browser DOM / Web APIs<br/>EXTERNAL"]
Registry["NPM Registry + OutSystems Forge<br/>EXTERNAL"]
HostApp -->|"Calls OutSystems.OSUI.* APIs<br/>Synchronous (in-process JS)"| ThisRepo
ThisRepo -.->|"Platform event callbacks<br/>Asynchronous"| HostApp
ThisRepo -->|"Provider JS API on window<br/>Synchronous"| Splide
ThisRepo -->|"Provider JS API on window<br/>Synchronous"| Flatpickr
ThisRepo -->|"Provider JS API on window<br/>Synchronous"| NoUISlider
ThisRepo -->|"Provider JS API on window<br/>Synchronous"| VirtualSelect
ThisRepo -->|"computePosition / autoUpdate<br/>Synchronous"| FloatingUI
ThisRepo -->|"DOM queries, listeners, observers<br/>Synchronous"| DOM
ThisRepo -.->|"Release publication of bundles<br/>Asynchronous (CI)"| Registry
classDef thisRepo fill:#80cbc4,stroke:#00796b,stroke-width:3px,color:#000
classDef external fill:#ef9a9a,stroke:#d32f2f,stroke-width:2px,stroke-dasharray: 5 5,color:#000
class ThisRepo thisRepo
class HostApp,Splide,Flatpickr,NoUISlider,VirtualSelect,FloatingUI,DOM,Registry external
Provider libraries are not bundled. They are declared as browser globals in src/scripts/Global.d.ts (types only) and consumed at runtime via window.*; the host OutSystems application is responsible for loading the script. The version each provider is written against is declared in code as ProviderInfo.Version; package.json devDependencies exist only to supply typings and SCSS sources.
| External Service | Communication Type | Purpose |
|---|---|---|
| OutSystems App Runtime | Sync (in-process JS calls) | Creates/configures/disposes patterns; receives callbacks for pattern events |
| Browser DOM / Web APIs | Sync (DOM API) | Rendering, listeners, MutationObserver/IntersectionObserver, gestures |
Splide 4.1.3 |
Sync (JS API on window) |
Carousel / Gallery slider provider |
Flatpickr 4.6.13 |
Sync (JS API on window) |
DatePicker, MonthPicker and TimePicker provider (incl. full calendar position set) |
noUiSlider 15.8.1 |
Sync (JS API on window) |
RangeSlider provider (single and interval modes) |
VirtualSelect 1.4.0 |
Sync (JS API on window) |
Dropdown provider (search and tags variants) |
Floating UI DOM 1.8.0 |
Sync (JS API on window) |
Positioning engine behind the Balloon feature (Dropdown, Tooltip, OverflowMenu, …) |
| OutSystems Service Studio | Sync (design-time import) | Developers consume patterns from the imported component |
| NPM Registry / OutSystems Forge | Async (release publication) | Distribution of versioned bundles (gulp/Tasks/PrepareToDeployNpm.js) |
To re-check declared provider versions: grep -rn "Version = " src/scripts/Providers --include=*.ts.
The build (Gulp, see gulp/README.md) emits one AMD bundle plus one CSS bundle per platform target:
dist/O11.OutSystemsUI.js/.css— OutSystems 11dist/ODC.OutSystemsUI.js/.css— OutSystems Developer Cloud.d.tsdeclarations in production mode;dev.<target>.*names with sourcemaps in development mode
There is no code splitting and no tree-shaking: the whole framework ships as one file, which keeps consumption in OutSystems apps a single script reference. Bundle content is trimmed at build time per platform (see T5), not at runtime. Commands live in CLAUDE.md; setup and workflow in CONTRIBUTING.md.
src/scripts/OSFramework/OSUI/ Internal framework: Pattern/, Feature/, Behaviors/, Event/, Helper/, Interface/, Utils/
src/scripts/OutSystems/OSUI/ Public API surface: Patterns/*API.ts, Utils/, GetVersion.ts, ErrorCodes.ts
src/scripts/Providers/OSUI/ Third-party wrappers: Carousel/Splide, Datepicker|Monthpicker|Timepicker/Flatpickr,
Dropdown/VirtualSelect, RangeSlider/NoUISlider, Utils/FloatingUI
Dependency direction is OutSystems → OSFramework → Providers, and the last hop is confined to factory functions (T1, T5).
Third-party libraries are wrapped by classes under src/scripts/Providers/OSUI/ that extend framework abstractions, and are accessed exclusively through browser globals rather than module imports. No pattern, behavior or public API may call a provider library directly. This keeps a provider upgrade (Splide major bump, new Flatpickr option set) a change inside one directory, and keeps the library loadable even when the host app defers provider scripts.
Evidence:
src/scripts/OSFramework/OSUI/Pattern/AbstractProviderPattern.ts(inAbstractProviderPattern) — provider lifecycle (prepareConfigs, provider instance creation/destruction) defined once for all provider-based patternssrc/scripts/Providers/OSUI/Carousel/Splide/Splide.ts,src/scripts/Providers/OSUI/Datepicker/Flatpickr/AbstractFlatpickr.ts,src/scripts/Providers/OSUI/Utils/FloatingUI/FloatingUI.ts— libraries invoked aswindow.Splide,window.flatpickr,window.FloatingUIDOMsrc/scripts/Global.d.ts— provider types declared onWindow, so no provider code is emitted into the bundlesrc/scripts/OSFramework/OSUI/Event/ProviderEvents/— provider event subscriptions normalized behind a framework managersrc/scripts/Providers/OSUI/SharedProviderResources/Flatpickr/Enum.ts(inPosition,ProviderInfo) — provider-specific option vocabulary and pinned version live in the provider layer
OutSystems.OSUI.* is the only surface OutSystems applications may call. It must not reference Providers.* types, and must return framework interfaces (never concrete provider classes). Runtime operations (property changes, method calls) must return a serialized success/error envelope instead of letting exceptions escape into platform logic; only Create fails loudly, since a duplicate registration is a programming error. This lets OSFramework be refactored freely, and lets the platform surface errors as data with stable error codes.
Evidence:
src/scripts/OutSystems/— no references toProviders.anywhere in the layer (grep -rl "Providers\." src/scripts/OutSystemsreturns nothing)src/scripts/OutSystems/OSUI/Utils/CreateApiResponse.ts(inCreateApiResponse) — wraps every callback in try/catch and returns a JSON{ code, isSuccess, message, value? }stringsrc/scripts/OutSystems/OSUI/Patterns/AccordionAPI.ts(inChangeProperty,CollapseAllItems) — every exported function delegates throughCreateApiResponsewith an entry fromOutSystems.OSUI.ErrorCodessrc/scripts/OutSystems/OSUI/Patterns/CarouselAPI.ts(inCreate) — returnsOSFramework.OSUI.Patterns.Carousel.ICarousel, never the Splide wrapper type
Each *API.ts owns a Map from pattern ID to instance; the platform holds strings, not JavaScript object references. Lookups go through Helper.MapOperation, which resolves both uniqueId and widgetId and always returns the newest instance for a reused widget ID. Without this, page lifecycle churn in OutSystems (conditional rendering, navigation) would leave stale references and leaked DOM listeners.
Evidence:
src/scripts/OutSystems/OSUI/Patterns/AccordionAPI.ts(_accordionMap,Create,Dispose) — duplicate IDs rejected on create, entry removed on disposesrc/scripts/OSFramework/OSUI/Helper/MapOperation.ts(inFindInMap) — uniqueId/widgetId resolution and "not found" error contractsrc/scripts/OSFramework/OSUI/Pattern/AbstractPattern.ts(inuniqueId,widgetId,equalsToID) — identity kept separate from the DOM element
AbstractPattern declares setHtmlElements/unsetHtmlElements, setCallbacks/unsetCallbacks and setA11YProperties as abstract, so accessibility wiring and teardown are non-optional rather than per-pattern discretion. Teardown must tolerate a DOM that the platform already removed — patterns own their listeners and attributes, so an unguarded dispose breaks page navigation.
Evidence:
src/scripts/OSFramework/OSUI/Pattern/AbstractPattern.ts— abstractsetA11YProperties,setCallbacks,setHtmlElements,unsetCallbacks,unsetHtmlElements;build/dispose/finishBuildorchestrationsrc/scripts/OSFramework/OSUI/Pattern/SectionIndexItem/SectionIndexItem.ts(indispose,_unsetTargetAttributes) — validates target elements still exist before unsetting attributessrc/scripts/OSFramework/OSUI/Pattern/AbstractParent.ts,AbstractChild.ts— children notify parents on removal so composite patterns (Accordion, Tabs, SectionIndex, Wizard) stay consistentsrc/scripts/OSFramework/OSUI/Behaviors/FocusTrap.ts,FocusManager.ts— shared A11Y behaviors reused instead of reimplemented per pattern
Files that only make sense on one platform are excluded from the TypeScript program per target, and platform-dependent literals are injected as post-compile placeholders. Both bundles therefore contain only code that can run, and patterns never carry if (platform === …) branches for excluded features.
Evidence:
gulp/ProjectSpecs/DefaultSpecs.js—excludeFromTsTranspile.O11removesOutSystems/OSUI/Utils/IconLibrary.tsandUtils/PreviewInDevices/**;iconPlaceholderClassdiffers per targetgulp/Tasks/TsTranspile.js(inupdateTsConfigFile,tsTranspileBasedOnPlatform) — rewrites theexcludeblock, compiles with--outFileper target, then restorestsconfig.jsongulp/Tasks/TsTranspile.js(inupdateFwkAndPlatformInfo) — replaces the<->platformType<->placeholder consumed byOSFramework.OSUI.Constants
Patterns with more than one implementation or mode are constructed by factory functions that return interfaces. Factories are the only place in OSFramework allowed to name a Providers.* class, and a second-level factory in the provider layer selects the mode. Adding a provider or mode is therefore additive: API code and pattern consumers stay untouched.
Evidence:
src/scripts/OSFramework/OSUI/Pattern/Carousel/CarouselFactory.ts(inNewCarousel) — returnsICarousel, instantiatesProviders.OSUI.Carousel.Splide.OSUISplide, throws for unknown providerssrc/scripts/OSFramework/OSUI/Pattern/DatePicker/DatePickerFactory.ts→src/scripts/Providers/OSUI/Datepicker/Flatpickr/FlatpickrFactory.ts— two-level selection (provider, then SingleDate/RangeDate)src/scripts/OSFramework/OSUI/Pattern/Dropdown/DropdownFactory.ts,RangeSlider/RangeSliderFactory.ts,Progress/ProgressFactory.ts— same shape for VirtualSelect variants, noUiSlider modes and Progress types (Bar/Circle)src/scripts/OSFramework/OSUI/Utils/FloatingPosition/FloatingPositionFactory.ts— the Balloon feature obtains a positioner through a factory rather than newing upProviders.OSUI.Utils.FloatingUI
- Features vs. patterns:
OSFramework/OSUI/Feature/Balloon/is a composable capability (floating panel + positioning + focus handling) reused by Dropdown, Tooltip, OverflowMenu and pickers, rather than a pattern with its own public API. - Configuration flow: the platform passes a JSON string;
*API.Createparses it and hands it to a*Configclass extendingAbstractConfiguration(AbstractProviderConfigurationfor provider patterns), which validates values and, for providers, maps them to provider options. - Event systems:
Event/DOMEvents(shared body-click, window-resize, scroll listeners plus RTL/language observers),Event/GestureEvents(swipe/drag),Event/ProviderEvents(provider event bridging). Patterns subscribe to the shared managers instead of attaching their own global listeners. - Quality assurance: E2E, visual-regression and cross-browser coverage live in the separate outsystems-ui-tests repository; this repository ships no test runner.
src/scripts/osui.ts keeps a thin shim that forwards legacy osui.* calls to OutSystems.OSUI.* and logs a deprecation warning. New code must not add entries to it.
Expires when: all supported OutSystems platform versions call
OutSystems.OSUI.*directly andsrc/scripts/osui.tsis deleted.