Neo Design System requires the TrueShade component. It backs light/dark persistence and the library cannot function without it. Install it first.
That is the whole setup. There is no OnApplicationReady hook to wire, no body class and no data attribute to set by hand. AppShell handles all of it.
AppShell is the outermost wrapper. It takes no input parameters and self-initialises: its OnReady places the TrueShade block and starts the shell for you.
Do not call InitShell yourself when using AppShell. It is already called on ready with the aside expanded.
ShellHeader placeholders: Portfolio, PortfolioOverlay, ExpandToggle, Buttons, AdditionalBlocks, Avatar, LoginOverlay.
ShellAside placeholders: Primary, Secondary, HeaderIcon, HeaderIconLeft, HeaderTitle, HeaderIconRight. Input: SecondaryOpen (Boolean, default True).
Layout_Neo placeholders: Header, TopInfo, Content. Inputs: ScrollType (Text, default "page"), LayoutType (Text), ReserveSidePanelSpace (Boolean).
Layout_Login is the whole login composition in one block: a centred form column with theme-aware corner artwork, spaced and typed for you in light and dark. Use it on a public screen instead of AppShell, not inside it.
It takes no input parameters and gives you four placeholders:
The form is yours, so the block imposes nothing on your authentication. Like AppShell, it places TrueShade itself, so the theme works on a login screen without any extra setup.
The same block carries the screens either side of sign-in. Reset password is Layout_Login with fewer rows and needs nothing extra. Sign up and verify email have a few classes of their own, below.
Password reveal. Add a container with pds-login-password-eye inside a field column marked pds-login-password-field and the icon is positioned, sized and themed. The toggle behaviour is yours to wire: the library ships the styling, not the logic. A few lines in the screen's OnReady that flip the input's type between password and text is all it takes.
Password requirements. For the verify-email step, password-analysis-title and password-analysis-requirements, with password-analysis-requirements-item on each line — a marker and a label, on a 4px rhythm. Put the list inside a field marked verify-password-field and it unrolls on :focus-within over 0.4s, so the rules appear while the field is being filled and fold away afterwards. Which requirements are met, and when, is your logic.
Consent row. verify-consent-row sets the checkbox-and-label rhythm: 12px type, an 8px gap, and the label free to wrap without dragging the checkbox out of line.
Error states. Add not-valid to a field for the invalid border. It survives hover and focus rather than losing the error colour to the interaction state.
Build the sidebar inside ShellAside's Primary placeholder.
Use AsideItem for a navigation entry. Inputs: Label, IsActive, Level, IsOpen, HasChildren, HasIcon, ParentId, Section. It raises OnClick. Level 0 is a section header with an optional expand arrow; level 1 is a leaf link.
Use AsideSection for a collapsible group. It wraps an AsideItem header plus an animated grid that shows and hides its children. Inputs: Label, SectionId, IsOpen, IsActive, HasIcon, Section.
To control the sidebar from your own code, call ToggleAside. ShellAside adds the is-aside-expanded class to the body automatically.
Neo Design System ships light and dark. TrueShade persists the user's choice and applies it as a data-theme attribute on the root element.
AppShell and Layout_Login both expose an OnThemeChange event with two Text outputs: Raw (what the user selected, which may be "system-default") and Effective (what is actually rendered). Handle it when a component needs to react to a theme change, recolouring a chart for instance.
InitTheme exists only for backwards compatibility and does nothing once the theme system is initialised. Use AppShell instead.
Most of Neo's surface is CSS classes applied to standard OutSystems widgets, not blocks. Apply these to get Neo styling:
A dialog is CSS rather than a block, so build it from standard widgets and apply these classes:
As with the password reveal, the library ships the styling. Opening, closing and what the buttons do are yours.
Beyond the shell, Neo Design System ships:
Neo Design System defines 612 design tokens covering colour, typography, spacing and sizing, elevation, motion and layout, with 295 dark-mode overrides.
Reference them from your own CSS with var(--token-name) rather than hardcoding values. Anything built on the tokens stays correct in both light and dark, and follows the design language when it moves. Tokens are the intended extension point: if a component you need does not ship as a block, build it against the tokens and it will match everything else.
The login layout adds four of its own that you can override the same way: --login-text-primary, --login-text-secondary, --login-label, --login-link-hover.
NeoDesignSystem
TrueShade
NeoBase
OnApplicationReady
AppShell
OnReady
Header
Aside
Content
ShellHeader
ShellAside
Layout_Neo
InitShell
Portfolio
PortfolioOverlay
ExpandToggle
Buttons
AdditionalBlocks
Avatar
LoginOverlay
Primary
Secondary
HeaderIcon
HeaderIconLeft
HeaderTitle
HeaderIconRight
SecondaryOpen
TopInfo
ScrollType
LayoutType
ReserveSidePanelSpace
Layout_Login
Logo
Title
Footer
pds-login-password-eye
pds-login-password-field
type
password
text
AsideItem
Label
IsActive
Level
IsOpen
HasChildren
HasIcon
ParentId
Section
OnClick
AsideSection
SectionId
ToggleAside
is-aside-expanded
data-theme
SetTheme(Theme)
GetTheme()
ToggleTheme()
UseSystemTheme()
OnThemeChange
Raw
Effective
InitTheme
btn
btn btn-primary
btn btn-destructive
btn btn-ghost
form-control
not-valid
dropdown
data-dropdown
dropdown-small
dropdown-large
dropdown-ghost
dropdown-btn
table
table-header
table-row
Initials
Color
Format
Size
Variant
DropdownEmpty
PopoverWidth
ExtendedClass
TriggerLabel
Trigger
DropdownItem
var(--token-name)
The login layout adds five of its own that you can override the same way: --login-text-primary, --login-text-secondary, --login-label, --login-input-border, --login-link-hover.
--login-text-primary
--login-text-secondary
--login-label
--login-input-border
--login-link-hover
BEFORE YOU START
Neo requires the TrueShade component — it backs light/dark persistence and the library cannot function without it. Install it first.
Neo is built for desktop. Below 1040px the layout enforces horizontal scrolling.
INSTALLATION
1. Install TrueShade from Forge.
2. Install Neo Design System.
3. In your application, add NeoDesignSystem and TrueShade as dependencies.
4. Set NeoBase as your application's theme.
That is the whole setup. There is no OnApplicationReady hook to wire, no body class and no data attribute to set by hand — AppShell handles all of it.
BUILDING YOUR FIRST SCREEN
1. Place AppShell on your screen. It gives you three placeholders: Header, Aside and Content.
2. Put ShellHeader in the Header placeholder.
3. Put ShellAside in the Aside placeholder.
4. Put Layout_Neo in the Content placeholder.
5. Build your page inside Layout_Neo's Content placeholder.
Do not call InitShell yourself when using AppShell — it is already called on ready with the aside expanded.
SIDEBAR NAVIGATION
THEME SWITCHING
- SetTheme(Theme) — apply "light", "dark" or "system-default".
- GetTheme() — returns the scheme actually in effect. "system-default" is resolved to the real operating system preference, so you always get "light" or "dark" back.
- ToggleTheme() — switch between light and dark.
- UseSystemTheme() — follow the operating system preference.
AppShell exposes an OnThemeChange event with two Text outputs: Raw (what the user selected, which may be "system-default") and Effective (what is actually rendered). Handle it when a component needs to react to a theme change — recolouring a chart, for instance.
STYLING STANDARD WIDGETS
- Button: btn. Variants: btn btn-primary, btn btn-destructive, btn btn-ghost.
- Input: form-control. Add not-valid for the validation error state.
- Dropdown or Select: dropdown, on an element carrying the data-dropdown attribute. Variants: dropdown-small, dropdown-large, dropdown-ghost, dropdown-btn.
- Table: table on the table, table-header on the header row, table-row on data rows.
READY-MADE BLOCKS
- Avatar — user initials in a coloured circle or square. Inputs: Initials (mandatory), Color, Format, Size, Label.
- Badge — status badge with semantic colour variants. Inputs: Label (mandatory), Variant (default "neutral").
- SearchInput — a search-styled input.
- Pagination — page navigation, with keyboard and screen-reader support.
- DropdownEmpty and DropdownItem — a floating menu panel and its rows. Keyboard and screen-reader accessible, dismisses on click-outside and on Escape, and positions itself to stay inside the viewport. DropdownEmpty inputs: IsOpen, PopoverWidth, ExtendedClass, TriggerLabel, with Trigger and Content placeholders. DropdownItem input: Title (mandatory).
- Skeleton, SkeletonBox and SkeletonTable — loading placeholders.
- Section — a content section wrapper.
- Icon and IconSprite — see Icons above.
USING DESIGN TOKENS
Neo Design System defines 612 design tokens covering colour, typography, spacing and sizing, elevation, motion and layout, with 277 dark-mode overrides.
GOOD TO KNOW
- There are no blocks for checkbox, radio, textarea, date picker, modal or tabs. Use standard widgets with the CSS classes above.
- No right-to-left support.
- Explicit keyboard and ARIA handling is implemented in DropdownEmpty and Pagination. Verify other blocks against your own accessibility requirements.
- This is an early alpha.