@webority/ui-elements
v0.9.14
Published
Webority framework-agnostic UI custom elements (<wui-*>) — the single implementation of the interactive components, styled by @webority/theme. Used natively in Razor and wrapped by @webority/ui-react.
Downloads
9,012
Readme
@webority/ui-elements
Webority's internal <wui-*> custom elements — the shared behaviour behind the select,
autocomplete, multiselect, phone and date-picker controls, so both the React and Razor
component libraries run one implementation.
Published publicly so npm install needs no private registry. Built for Webority
products; no support commitment outside them.
You do not use these directly: write <AppSelect> (@webority/ui-react) or
<app-select> (Webority.Ui.Razor), which wrap them.
Use
npm install --save-exact @webority/ui-elements--save-exact is deliberate — pin @webority/* exactly, never ^. See
@webority/ui-react's README for why.
import '@webority/ui-elements'; // registers the custom elementsComponent catalogue: https://ui-react.webority.dev
Authoring a <wui-*> element
Rules learned from defects, not from style preference.
Every public accessor needs a setter, not just a getter. React sets a property on a
custom element whenever one exists on the instance, and only falls back to an attribute when
it does not. A getter-only accessor therefore throws
Cannot set property x of #<ce> which has only a getter the moment React renders
<wui-thing x={1} /> — and because that happens during render it takes the whole page down,
not just the field. Write the setter through to the attribute:
get length() { return Number(this.getAttribute('length') ?? 6); }
set length(v) { this.setAttribute('length', String(v)); }Enforced by pnpm check:parity, which fails on a public getter with no setter.
The accessible name has to land on the real control, not the host. aria-label on the
custom element names the element, which is not what a screen reader reads and not what axe
checks. Copy it onto the <input>/<button> inside during render.
Never position a floating panel by hand. Use anchorOverlay(trigger, panel) — it flips
above the trigger when there is no room below and clamps horizontally. Four elements each had
their own copy of top = rect.bottom + 4; every one of them ran off the bottom of the screen,
and a position: fixed panel below the fold cannot be scrolled to.
