Package Exports
- @nan0web/ui-core
- @nan0web/ui-core/models/Document
- @nan0web/ui-core/models/Navigation
- @nan0web/ui-core/models/Navigation.test
Readme
@nan0web/ui-core
| Status | Documentation | Test coverage | Features | Npm version |
|---|---|---|---|---|
🟢 99.3% |
🧪 English 🏴 Українською 🇺🇦 |
🟢 97.9% |
✅ d.ts 📜 system.md 🕹️ playground | — |
A library for creating framework-agnostic UI elements. Allows describing interfaces as simple objects.
Description
The @nan0web/ui-core package provides a minimal yet powerful foundation for
framework-agnostic UI elements. It is designed to enable developers to describe
UI components as declarative objects. Core classes and utilities:
Element— the main class for representing UI elements.processI18n— utility for translating and substituting variables in content.tokens— design system tokens for consistent UI styling.Theme— base class for creating and organizing UI themes.getUserTheme— function to select or create a custom theme.
These are perfect for building design systems, themeable UI frameworks, and reusable component libraries.
Installation
How to install with npm?
npm install @nan0web/ui-coreHow to install with pnpm?
pnpm add @nan0web/ui-coreHow to install with yarn?
yarn add @nan0web/ui-coreUsage
Basic Element Creation
Elements can be created with a component type, content, and props.
How to create a basic Element instance from object?
import Element from '@nan0web/ui-core'
const element = new Element({
Button: ["Click me"],
$variant: "primary"
})
console.info(element.type) // "Button"
console.info(element.content) // ["Click me"]
console.info(element.props) // { variant: "primary" }Nested Elements
Elements can include child elements as arrays.
How to create nested Elements and check hasChildren()?
import Element from '@nan0web/ui-core'
const element = new Element({
div: [
{ span: "Hello World" },
{ Button: ["Submit"] }
],
$style: "color: blue; margin: 10px"
})
console.info(element.hasChildren()) // true
console.info(element.getChildElements().length) // 2
Aria Attributes
Element handles $aria* props and converts them to aria-* attributes.
How to parse aria attributes like $ariaLabel?
import Element from '@nan0web/ui-core'
const element = new Element({
button: "Close",
$ariaLabel: "Close dialog"
})
console.info(element.props) // { "aria-label": "Close dialog" }Event Handlers
Element recognizes $on* props as event handlers.
How to parse event handlers like $onClick and $onKeyDown?
import Element from '@nan0web/ui-core'
const handleClick = () => console.log("Clicked")
const element = new Element({
button: "Click me",
$onClick: handleClick,
$onKeyDown: () => {}
})
console.info(typeof element.props.onClick)
console.info(typeof element.props.onKeyDown)i18n
Elements support translations and variable substitution via processI18n.
How to process translations with processI18n and $t?
import { processI18n } from '@nan0web/ui-core'
const input = { $t: "greetings.hello" }
const t = (key) => key === "greetings.hello" ? "Привіт!" : key
const result = processI18n(input, t)
console.info(result) // "Привіт!"How to substitute variables in text content with processI18n?
import { processI18n } from '@nan0web/ui-core'
const text = "User: {{name}}, Age: {{age}}"
const data = { name: "Іван", age: "30" }
const result = processI18n(text, null, data)
console.info(result) // "User: Іван, Age: 30"Playground: Try Before You Commit
There is a CLI sandbox to experiment safely:
git clone https://github.com/nan0web/ui-core.git
cd ui-core
npm install
npm run playAPI Reference
Element Class
flowchart TD
A[Structure] -->|UI-Block| B(Element)
C[Styling] -->|Tokens + Theme| B
D[Localization] -->|processI18n| B
B --> E[Render в React/Vue/etc]
style A fill:#eef,stroke:#333,color:#000
style C fill:#efe,stroke:#333,color:#000
style D fill:#fee,stroke:#333,color:#000
style B fill:#cfc,stroke:#333,color:#000
style E fill:#ffcc00,stroke:#333,color:#000Properties
type– the component type or HTML tag (e.g. "Button", "div").content– the element content (text, array, or nested elements).props– the extracted props with expanded $-keys.
Methods
hasChildren()– returns true if element contains nested elements.hasText()– returns true if content includes text.getChildElements()– returns an array of child Element instances.static from(input)– creates or returns existing Element.
Static Properties
PROP_ALIASES– map of custom key aliases (e.g.,$classforclassName).
Static Methods
parseProp()– transforms a $-prop into standard form.parseInlineStyle()– turns CSS string into style object.extractProps()– pulls all $-prefixed props.extractTags()– pulls non-prefixed keys as [type, content].
flowchart TD
I["Input: { Button, $props, content }"] --> J["Element.from(input)"]
J --> K[extractProps + extractTags]
K --> L[parseProp: $onClick → onClick]
K --> M[parseInlineStyle: 'color:red']
K --> N[PROP_ALIASES: $variant → variant]
N --> O[Element Instance]
O --> P[hasChildren?]
O --> Q[hasText?]
O --> R["getChildElements()"]
style I fill:#eef,stroke:#333,color:#000
style O fill:#cfc,stroke:#333,color:#000
style K fill:#def,stroke:#333,color:#000How to create Element with complex content?
import Element from '@nan0web/ui-core'
const element = new Element({
div: [
"Text content",
{ span: "Nested element" }
],
$className: "container",
$onClick: () => {}
})
console.info(element.type) // "div"
console.info(element.hasText()) // true
console.info(element.hasChildren()) // trueprocessI18n Utility
Parameters
input– content to translate or substitute.t– optional translation function.data– optional variable substitution object.
Returns
- processed content (string, array, or unchanged type).
How to use processI18n with arrays?
import { processI18n } from '@nan0web/ui-core'
const content = [
"Name: {{name}}",
{ $t: "welcome" },
[{ $t: "nested" }]
]
const t = (key) => key === "welcome" ? "Welcome" : "Nested"
const data = { name: "John" }
const result = processI18n(content, t, data)
console.info(result) // ["Name: John", "Welcome", ["Nested"]]Themes
Themes are built using atoms, molecules, and organisms.
flowchart TD
T[tokens.js] --> U["space, color, radius, shadow"]
U --> V[Theme]
V --> W[atoms: Button, Input]
V --> X[molecules: Card]
V --> Y[organisms: Modal]
V --> Z[CustomTheme]
V --> AA[DarkLightTheme]
V --> AB[NightTheme]
Z --> AC["getUserTheme(config)"]
AA --> AD["getActiveTheme() → prefers-color-scheme"]
style T fill:#efe,stroke:#333,color:#000
style V fill:#cfc,stroke:#333,color:#000
style Z fill:#ddf,stroke:#333,color:#000
style AA fill:#ddf,stroke:#333,color:#000How to access theme tokens?
import { tokens } from '@nan0web/ui-core'
console.info(tokens.color.primary) // "var(--color-primary)"
console.info(tokens.font.size.base) // "1rem"Custom Themes
Create a custom theme using getUserTheme.
How to create a custom theme using getUserTheme?
import { getUserTheme } from '@nan0web/ui-core'
const theme = getUserTheme({
atoms: { Button: { background: "red" } },
color: { background: "#fff" }
})
console.info(theme.atoms.Button.background) // "red"DarkLightTheme
Automatically switches between dark/light themes.
How to check active theme in DarkLightTheme?
import { DarkLightTheme } from '@nan0web/ui-core'
DarkLightTheme.current = "light"
const theme = DarkLightTheme.getActiveTheme()
console.info(theme) // { background: "#fff", text: "#000" }
Java•Script
Uses d.ts files for autocompletion
Contributing
How to contribute? - check here
License
How to license ISC? - check here