@nan0web/ui 1.3.0 โ 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/package.json +23 -12
- package/src/ArchitectureMap/ArchitectureMap.js +111 -0
- package/src/ArchitectureMap/index.js +1 -0
- package/src/InterfaceTemplate/InterfaceTemplate.js +95 -0
- package/src/InterfaceTemplate/index.js +1 -0
- package/src/README.md.js +76 -0
- package/types/ArchitectureMap/ArchitectureMap.d.ts +70 -0
- package/types/ArchitectureMap/index.d.ts +1 -0
- package/types/InterfaceTemplate/InterfaceTemplate.d.ts +67 -0
- package/types/InterfaceTemplate/index.d.ts +1 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @nan0web/ui
|
|
2
2
|
|
|
3
|
+
๐ด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ [English](./README.md) | ๐บ๐ฆ [ะฃะบัะฐัะฝััะบะพั](./docs/uk/README.md)
|
|
4
|
+
|
|
3
5
|
<!-- %PACKAGE_STATUS% -->
|
|
4
6
|
|
|
5
7
|
A lightweight, agnostic UI framework designed with the **nan0web philosophy**
|
|
@@ -172,6 +174,64 @@ import { Welcome } from '@nan0web/ui'
|
|
|
172
174
|
const output = Welcome({ user: { name: 'Test' } })
|
|
173
175
|
console.info(output) // โ Welcome Test!
|
|
174
176
|
```
|
|
177
|
+
### Master IDE (Component Sandbox)
|
|
178
|
+
|
|
179
|
+
The Master IDE (OlmuiInspector) provides a unified environment for testing and documenting
|
|
180
|
+
web components across platforms. It supports:
|
|
181
|
+
|
|
182
|
+
- **NaN0 Spec** โ a concise YAML-based shorthand for declaring component variations.
|
|
183
|
+
- **OlmuiInspector** โ unified UI for exploring component models and props.
|
|
184
|
+
- **Live Preview** โ real-time rendering of component states.
|
|
185
|
+
- **i18n UI** โ fully localized interface (UK/EN) for global developers.
|
|
186
|
+
- **Theme Editor** โ Bootstrap-like CSS variable system with live preview.
|
|
187
|
+
|
|
188
|
+
It follows the **Olmui** core pattern: *One Logic โ Many UI* (same manifest powers both CLI and Web).
|
|
189
|
+
|
|
190
|
+
#### Theme Editor (CSS Variables)
|
|
191
|
+
|
|
192
|
+
Professional-grade theming with live preview. Supports:
|
|
193
|
+
|
|
194
|
+
- **Palette**: primary, secondary, success, warning, danger, info
|
|
195
|
+
- **Geometry**: border-radius (sm/md/lg/pill/circle), spacing (sm/md/lg)
|
|
196
|
+
- **Type-safe inputs**: `type="color"` for colors, number inputs for dimensions
|
|
197
|
+
|
|
198
|
+
#### Component Rendering Architecture
|
|
199
|
+
|
|
200
|
+
The IDE handles data transformation between YAML models and web components:
|
|
201
|
+
|
|
202
|
+
- **Table**: `rows[][] + columns[]` โ `data[]` (array of objects)
|
|
203
|
+
- **Tree**: `data` โ `items` mapping with 4-level taxonomy
|
|
204
|
+
- **Markdown**: Raw markdown โ HTML via `_md2html()` converter
|
|
205
|
+
- **ProgressBar**: Tag alias (`ui-progress-bar` โ `ui-progress`), variant colors
|
|
206
|
+
- **LangSelect**: `string[]` โ `{code,title}[]` conversion
|
|
207
|
+
- **Hyphenated props**: Auto `camelCase` conversion (`show-label` โ `showLabel`)
|
|
208
|
+
|
|
209
|
+
#### NaN0 Spec (YAML)
|
|
210
|
+
|
|
211
|
+
Concise format for defining variations:
|
|
212
|
+
|
|
213
|
+
How to define a component variation using NaN0 Spec?
|
|
214
|
+
```yaml
|
|
215
|
+
- Button: Primary
|
|
216
|
+
$variant: brand
|
|
217
|
+
$outline: true
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### Documentation Site
|
|
221
|
+
|
|
222
|
+
The IDE includes an auto-generated documentation site.
|
|
223
|
+
HTML pages are generated from `ide.html` template via `generate-pages.js`:
|
|
224
|
+
|
|
225
|
+
- Per-language pages (`/uk/Data/Table.html`, `/en/Feedback/Alert.html`)
|
|
226
|
+
- SEO-optimized with `<title>` and `<meta>` per component
|
|
227
|
+
- Category-based URL routing (`/Data/`, `/Feedback/`, `/Forms/`, `/Actions/`, `/System/`)
|
|
228
|
+
- i18n navbar with `data-i18n` attributes
|
|
229
|
+
|
|
230
|
+
How to run the documentation site?
|
|
231
|
+
```bash
|
|
232
|
+
npm run docs:dev
|
|
233
|
+
```
|
|
234
|
+
|
|
175
235
|
## Playground Demos
|
|
176
236
|
|
|
177
237
|
The library includes rich playground demos:
|
|
@@ -205,6 +265,10 @@ Explore:
|
|
|
205
265
|
- [App](./src/App/)
|
|
206
266
|
- [Models](./src/Model/)
|
|
207
267
|
|
|
268
|
+
## Project Architecture & Specs
|
|
269
|
+
|
|
270
|
+
How the universal block spec is designed? - [check Universal Blocks Spec (`project.md`)](./project.md)
|
|
271
|
+
|
|
208
272
|
## Contributing
|
|
209
273
|
|
|
210
274
|
How to contribute? - [check here](./CONTRIBUTING.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nan0web/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "NaNโขWeb UI. One application logic (algorithm) and many UI.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -18,17 +18,22 @@
|
|
|
18
18
|
"test:coverage": "node --experimental-test-coverage --test-coverage-include=\"src/**/*.js\" --test-coverage-exclude=\"src/**/*.test.js\" --test \"src/**/*.test.js\"",
|
|
19
19
|
"test:coverage:collect": "nan0test coverage",
|
|
20
20
|
"test:docs": "node --test src/README.md.js",
|
|
21
|
+
"release:spec": "node --test \"releases/**/*.spec.js\"",
|
|
21
22
|
"test:release": "node --test \"releases/**/*.test.js\"",
|
|
22
23
|
"test:status": "nan0test status --hide-name",
|
|
23
24
|
"test:play": "node --test --test-timeout=3333 \"play/**/*.test.js\"",
|
|
24
|
-
"test:
|
|
25
|
+
"test:e2e": "playwright test --ignore-snapshots e2e/components.spec.js e2e/debug-label.spec.js",
|
|
26
|
+
"test:e2e:slow": "E2E_SLOW=1 playwright test e2e/visual.spec.js",
|
|
27
|
+
"test:all": "npm run test && npm run test:docs && npm run test:play && npm run test:e2e && npm run build && npm run knip",
|
|
25
28
|
"knip": "knip --production",
|
|
26
29
|
"precommit": "npm test",
|
|
27
30
|
"prepush": "npm test",
|
|
28
31
|
"prepare": "husky",
|
|
29
32
|
"release": "nan0release publish",
|
|
30
33
|
"clean": "rm -rf .cache/ && rm -rf dist/",
|
|
31
|
-
"clean:modules": "rm -rf node_modules"
|
|
34
|
+
"clean:modules": "rm -rf node_modules",
|
|
35
|
+
"docs:dev": "node docs/site/scripts/generate-pages.js && vite docs/site",
|
|
36
|
+
"docs:build": "node docs/site/scripts/generate-pages.js && vite build docs/site"
|
|
32
37
|
},
|
|
33
38
|
"exports": {
|
|
34
39
|
".": {
|
|
@@ -55,21 +60,27 @@
|
|
|
55
60
|
"license": "ISC",
|
|
56
61
|
"packageManager": "pnpm@10.11.0",
|
|
57
62
|
"devDependencies": {
|
|
58
|
-
"@nan0web/event": "
|
|
59
|
-
"@nan0web/i18n": "
|
|
60
|
-
"@nan0web/release": "
|
|
61
|
-
"@nan0web/test": "
|
|
62
|
-
"@nan0web/ui-cli": "
|
|
63
|
+
"@nan0web/event": "*",
|
|
64
|
+
"@nan0web/i18n": "*",
|
|
65
|
+
"@nan0web/release": "*",
|
|
66
|
+
"@nan0web/test": "*",
|
|
67
|
+
"@nan0web/ui-cli": "*",
|
|
68
|
+
"@nan0web/ui-lit": "workspace:*",
|
|
69
|
+
"@playwright/test": "^1.58.2",
|
|
70
|
+
"@rollup/plugin-yaml": "^4.1.2",
|
|
63
71
|
"@vitest/coverage-v8": "^3.2.4",
|
|
64
72
|
"husky": "^9.1.7",
|
|
73
|
+
"js-yaml": "^4.1.1",
|
|
65
74
|
"knip": "^5.83.1",
|
|
75
|
+
"lit": "^3.3.2",
|
|
76
|
+
"vite": "^6.0.0",
|
|
66
77
|
"vitest": "^3.2.4"
|
|
67
78
|
},
|
|
68
79
|
"dependencies": {
|
|
69
|
-
"@nan0web/co": "
|
|
70
|
-
"@nan0web/event": "
|
|
71
|
-
"@nan0web/log": "
|
|
72
|
-
"@nan0web/types": "
|
|
80
|
+
"@nan0web/co": "*",
|
|
81
|
+
"@nan0web/event": "*",
|
|
82
|
+
"@nan0web/log": "*",
|
|
83
|
+
"@nan0web/types": "*",
|
|
73
84
|
"string-width": "^7.2.0"
|
|
74
85
|
}
|
|
75
86
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArchitectureMap โ a cross-package component readiness registry.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which UI components are implemented in which packages
|
|
5
|
+
* (ui-lit, ui-cli, ui-react-bootstrap, etc.) and provides
|
|
6
|
+
* a programmatic readiness matrix.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const map = new ArchitectureMap()
|
|
10
|
+
* map.register('ui-lit', ['Button', 'Input', 'Select'])
|
|
11
|
+
* map.register('ui-cli', ['Button', 'Input'])
|
|
12
|
+
* map.getMatrix()
|
|
13
|
+
* // โ { Button: { 'ui-lit': true, 'ui-cli': true },
|
|
14
|
+
* // Input: { 'ui-lit': true, 'ui-cli': true },
|
|
15
|
+
* // Select: { 'ui-lit': true, 'ui-cli': false } }
|
|
16
|
+
* map.getReadiness('Button') // โ true (in all packages)
|
|
17
|
+
* map.getReadiness('Select') // โ false (missing from ui-cli)
|
|
18
|
+
*/
|
|
19
|
+
export default class ArchitectureMap {
|
|
20
|
+
/** @type {Map<string, Set<string>>} packageName โ Set of component names */
|
|
21
|
+
#packages = new Map()
|
|
22
|
+
|
|
23
|
+
/** @type {Set<string>} all known component names */
|
|
24
|
+
#components = new Set()
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Register a package and its exported components.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} packageName โ e.g. 'ui-lit', 'ui-cli', 'ui-react-bootstrap'
|
|
30
|
+
* @param {string[]} componentsList โ e.g. ['Button', 'Input', 'Select']
|
|
31
|
+
*/
|
|
32
|
+
register(packageName, componentsList = []) {
|
|
33
|
+
this.#packages.set(packageName, new Set(componentsList))
|
|
34
|
+
for (const name of componentsList) {
|
|
35
|
+
this.#components.add(name)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the list of all registered package names.
|
|
41
|
+
*
|
|
42
|
+
* @returns {string[]}
|
|
43
|
+
*/
|
|
44
|
+
getPackages() {
|
|
45
|
+
return [...this.#packages.keys()]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get all known component names (union of all packages).
|
|
50
|
+
*
|
|
51
|
+
* @returns {string[]}
|
|
52
|
+
*/
|
|
53
|
+
getComponents() {
|
|
54
|
+
return [...this.#components].sort()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Build a readiness matrix: { componentName โ { packageName โ boolean } }.
|
|
59
|
+
*
|
|
60
|
+
* Every known component gets an entry for every registered package.
|
|
61
|
+
*
|
|
62
|
+
* @returns {Object<string, Object<string, boolean>>}
|
|
63
|
+
*/
|
|
64
|
+
getMatrix() {
|
|
65
|
+
const packages = this.getPackages()
|
|
66
|
+
/** @type {Object<string, Object<string, boolean>>} */
|
|
67
|
+
const matrix = {}
|
|
68
|
+
|
|
69
|
+
for (const comp of this.#components) {
|
|
70
|
+
matrix[comp] = {}
|
|
71
|
+
for (const pkg of packages) {
|
|
72
|
+
matrix[comp][pkg] = this.#packages.get(pkg)?.has(comp) ?? false
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return matrix
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check if a component is implemented in ALL registered packages.
|
|
81
|
+
*
|
|
82
|
+
* @param {string} componentName
|
|
83
|
+
* @returns {boolean}
|
|
84
|
+
*/
|
|
85
|
+
getReadiness(componentName) {
|
|
86
|
+
if (this.#packages.size === 0) return false
|
|
87
|
+
for (const components of this.#packages.values()) {
|
|
88
|
+
if (!components.has(componentName)) return false
|
|
89
|
+
}
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get a summary: { total, ready, notReady, readyPercent }.
|
|
95
|
+
*
|
|
96
|
+
* @returns {{ total: number, ready: number, notReady: number, readyPercent: number }}
|
|
97
|
+
*/
|
|
98
|
+
getSummary() {
|
|
99
|
+
const components = this.getComponents()
|
|
100
|
+
const total = components.length
|
|
101
|
+
const ready = components.filter((c) => this.getReadiness(c)).length
|
|
102
|
+
return {
|
|
103
|
+
total,
|
|
104
|
+
ready,
|
|
105
|
+
notReady: total - ready,
|
|
106
|
+
readyPercent: total > 0 ? Math.round((ready / total) * 100) : 0,
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { ArchitectureMap }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, ArchitectureMap } from './ArchitectureMap.js'
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InterfaceTemplate โ base class for defining new UI interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Establishes the inheritance pattern for the "One Logic, Many UI" architecture.
|
|
5
|
+
* Each UI interface (CLI, Web, Mobile, Chat, Audio) extends this template
|
|
6
|
+
* and overrides the required methods.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* class CliInterface extends InterfaceTemplate {
|
|
10
|
+
* render(data) { return formatForTerminal(data) }
|
|
11
|
+
* async ask(prompt) { return readlinePrompt(prompt) }
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* @abstract
|
|
15
|
+
*/
|
|
16
|
+
export default class InterfaceTemplate {
|
|
17
|
+
/**
|
|
18
|
+
* List of methods that MUST be overridden by concrete implementations.
|
|
19
|
+
* Used for documentation and runtime validation.
|
|
20
|
+
*
|
|
21
|
+
* @type {string[]}
|
|
22
|
+
*/
|
|
23
|
+
static requiredMethods = ['render', 'ask']
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The name of this interface (e.g. 'cli', 'web', 'mobile').
|
|
27
|
+
* Override in subclass.
|
|
28
|
+
*
|
|
29
|
+
* @type {string}
|
|
30
|
+
*/
|
|
31
|
+
name = 'base'
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Render data to the user through the interface.
|
|
35
|
+
* Must be overridden by each concrete implementation.
|
|
36
|
+
*
|
|
37
|
+
* @param {any} [data] - data to render
|
|
38
|
+
* @returns {any} rendered output (string for CLI, DOM for web, etc.)
|
|
39
|
+
* @throws {Error} if not overridden
|
|
40
|
+
*/
|
|
41
|
+
render(data) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`InterfaceTemplate.render() must be overridden by ${this.name || 'subclass'}. ` +
|
|
44
|
+
'This is the primary output method for the interface.',
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Request input from the user through the interface.
|
|
50
|
+
* Must be overridden by each concrete implementation.
|
|
51
|
+
*
|
|
52
|
+
* @param {string} prompt - question or label for the input
|
|
53
|
+
* @param {object} [options] - options (type, choices, default, etc.)
|
|
54
|
+
* @returns {Promise<any>} user's response
|
|
55
|
+
* @throws {Error} if not overridden
|
|
56
|
+
*/
|
|
57
|
+
async ask(prompt, options = {}) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`InterfaceTemplate.ask() must be overridden by ${this.name || 'subclass'}. ` +
|
|
60
|
+
'This is the primary input method for the interface.',
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Validate that all required methods have been overridden.
|
|
66
|
+
* Call this in the subclass constructor to get early feedback.
|
|
67
|
+
*
|
|
68
|
+
* @returns {string[]} list of missing method overrides (empty = valid)
|
|
69
|
+
*/
|
|
70
|
+
validate() {
|
|
71
|
+
const missing = []
|
|
72
|
+
for (const method of InterfaceTemplate.requiredMethods) {
|
|
73
|
+
if (this[method] === InterfaceTemplate.prototype[method]) {
|
|
74
|
+
missing.push(method)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return missing
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get interface capabilities info.
|
|
82
|
+
*
|
|
83
|
+
* @returns {{ name: string, requiredMethods: string[], isComplete: boolean }}
|
|
84
|
+
*/
|
|
85
|
+
info() {
|
|
86
|
+
const missing = this.validate()
|
|
87
|
+
return {
|
|
88
|
+
name: this.name,
|
|
89
|
+
requiredMethods: [...InterfaceTemplate.requiredMethods],
|
|
90
|
+
isComplete: missing.length === 0,
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { InterfaceTemplate }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, InterfaceTemplate } from './InterfaceTemplate.js'
|
package/src/README.md.js
CHANGED
|
@@ -30,6 +30,8 @@ function testRender() {
|
|
|
30
30
|
* @docs
|
|
31
31
|
* # @nan0web/ui
|
|
32
32
|
*
|
|
33
|
+
* ๐ด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ [English](./README.md) | ๐บ๐ฆ [ะฃะบัะฐัะฝััะบะพั](./docs/uk/README.md)
|
|
34
|
+
*
|
|
33
35
|
* <!-- %PACKAGE_STATUS% -->
|
|
34
36
|
*
|
|
35
37
|
* A lightweight, agnostic UI framework designed with the **nan0web philosophy**
|
|
@@ -276,6 +278,76 @@ function testRender() {
|
|
|
276
278
|
])
|
|
277
279
|
})
|
|
278
280
|
|
|
281
|
+
/**
|
|
282
|
+
* @docs
|
|
283
|
+
* ### Master IDE (Component Sandbox)
|
|
284
|
+
*
|
|
285
|
+
* The Master IDE (OlmuiInspector) provides a unified environment for testing and documenting
|
|
286
|
+
* web components across platforms. It supports:
|
|
287
|
+
*
|
|
288
|
+
* - **NaN0 Spec** โ a concise YAML-based shorthand for declaring component variations.
|
|
289
|
+
* - **OlmuiInspector** โ unified UI for exploring component models and props.
|
|
290
|
+
* - **Live Preview** โ real-time rendering of component states.
|
|
291
|
+
* - **i18n UI** โ fully localized interface (UK/EN) for global developers.
|
|
292
|
+
* - **Theme Editor** โ Bootstrap-like CSS variable system with live preview.
|
|
293
|
+
*
|
|
294
|
+
* It follows the **Olmui** core pattern: *One Logic โ Many UI* (same manifest powers both CLI and Web).
|
|
295
|
+
*
|
|
296
|
+
* #### Theme Editor (CSS Variables)
|
|
297
|
+
*
|
|
298
|
+
* Professional-grade theming with live preview. Supports:
|
|
299
|
+
*
|
|
300
|
+
* - **Palette**: primary, secondary, success, warning, danger, info
|
|
301
|
+
* - **Geometry**: border-radius (sm/md/lg/pill/circle), spacing (sm/md/lg)
|
|
302
|
+
* - **Type-safe inputs**: `type="color"` for colors, number inputs for dimensions
|
|
303
|
+
*
|
|
304
|
+
* #### Component Rendering Architecture
|
|
305
|
+
*
|
|
306
|
+
* The IDE handles data transformation between YAML models and web components:
|
|
307
|
+
*
|
|
308
|
+
* - **Table**: `rows[][] + columns[]` โ `data[]` (array of objects)
|
|
309
|
+
* - **Tree**: `data` โ `items` mapping with 4-level taxonomy
|
|
310
|
+
* - **Markdown**: Raw markdown โ HTML via `_md2html()` converter
|
|
311
|
+
* - **ProgressBar**: Tag alias (`ui-progress-bar` โ `ui-progress`), variant colors
|
|
312
|
+
* - **LangSelect**: `string[]` โ `{code,title}[]` conversion
|
|
313
|
+
* - **Hyphenated props**: Auto `camelCase` conversion (`show-label` โ `showLabel`)
|
|
314
|
+
*
|
|
315
|
+
* #### NaN0 Spec (YAML)
|
|
316
|
+
*
|
|
317
|
+
* Concise format for defining variations:
|
|
318
|
+
*/
|
|
319
|
+
it('How to define a component variation using NaN0 Spec?', () => {
|
|
320
|
+
/**
|
|
321
|
+
* ```yaml
|
|
322
|
+
* - Button: Primary
|
|
323
|
+
* $variant: brand
|
|
324
|
+
* $outline: true
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
assert.ok(pkg.name === '@nan0web/ui')
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @docs
|
|
332
|
+
* #### Documentation Site
|
|
333
|
+
*
|
|
334
|
+
* The IDE includes an auto-generated documentation site.
|
|
335
|
+
* HTML pages are generated from `ide.html` template via `generate-pages.js`:
|
|
336
|
+
*
|
|
337
|
+
* - Per-language pages (`/uk/Data/Table.html`, `/en/Feedback/Alert.html`)
|
|
338
|
+
* - SEO-optimized with `<title>` and `<meta>` per component
|
|
339
|
+
* - Category-based URL routing (`/Data/`, `/Feedback/`, `/Forms/`, `/Actions/`, `/System/`)
|
|
340
|
+
* - i18n navbar with `data-i18n` attributes
|
|
341
|
+
*/
|
|
342
|
+
it('How to run the documentation site?', () => {
|
|
343
|
+
/**
|
|
344
|
+
* ```bash
|
|
345
|
+
* npm run docs:dev
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
assert.ok(pkg.scripts?.['docs:dev'])
|
|
349
|
+
})
|
|
350
|
+
|
|
279
351
|
/**
|
|
280
352
|
* @docs
|
|
281
353
|
* ## Playground Demos
|
|
@@ -320,6 +392,10 @@ function testRender() {
|
|
|
320
392
|
* - [App](./src/App/)
|
|
321
393
|
* - [Models](./src/Model/)
|
|
322
394
|
*
|
|
395
|
+
* ## Project Architecture & Specs
|
|
396
|
+
*
|
|
397
|
+
* How the universal block spec is designed? - [check Universal Blocks Spec (`project.md`)](./project.md)
|
|
398
|
+
*
|
|
323
399
|
* ## Contributing
|
|
324
400
|
*/
|
|
325
401
|
it('How to contribute? - [check here](./CONTRIBUTING.md)', async () => {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArchitectureMap โ a cross-package component readiness registry.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which UI components are implemented in which packages
|
|
5
|
+
* (ui-lit, ui-cli, ui-react-bootstrap, etc.) and provides
|
|
6
|
+
* a programmatic readiness matrix.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const map = new ArchitectureMap()
|
|
10
|
+
* map.register('ui-lit', ['Button', 'Input', 'Select'])
|
|
11
|
+
* map.register('ui-cli', ['Button', 'Input'])
|
|
12
|
+
* map.getMatrix()
|
|
13
|
+
* // โ { Button: { 'ui-lit': true, 'ui-cli': true },
|
|
14
|
+
* // Input: { 'ui-lit': true, 'ui-cli': true },
|
|
15
|
+
* // Select: { 'ui-lit': true, 'ui-cli': false } }
|
|
16
|
+
* map.getReadiness('Button') // โ true (in all packages)
|
|
17
|
+
* map.getReadiness('Select') // โ false (missing from ui-cli)
|
|
18
|
+
*/
|
|
19
|
+
export default class ArchitectureMap {
|
|
20
|
+
/**
|
|
21
|
+
* Register a package and its exported components.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} packageName โ e.g. 'ui-lit', 'ui-cli', 'ui-react-bootstrap'
|
|
24
|
+
* @param {string[]} componentsList โ e.g. ['Button', 'Input', 'Select']
|
|
25
|
+
*/
|
|
26
|
+
register(packageName: string, componentsList?: string[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get the list of all registered package names.
|
|
29
|
+
*
|
|
30
|
+
* @returns {string[]}
|
|
31
|
+
*/
|
|
32
|
+
getPackages(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Get all known component names (union of all packages).
|
|
35
|
+
*
|
|
36
|
+
* @returns {string[]}
|
|
37
|
+
*/
|
|
38
|
+
getComponents(): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Build a readiness matrix: { componentName โ { packageName โ boolean } }.
|
|
41
|
+
*
|
|
42
|
+
* Every known component gets an entry for every registered package.
|
|
43
|
+
*
|
|
44
|
+
* @returns {Object<string, Object<string, boolean>>}
|
|
45
|
+
*/
|
|
46
|
+
getMatrix(): {
|
|
47
|
+
[x: string]: {
|
|
48
|
+
[x: string]: boolean;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Check if a component is implemented in ALL registered packages.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} componentName
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
getReadiness(componentName: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Get a summary: { total, ready, notReady, readyPercent }.
|
|
60
|
+
*
|
|
61
|
+
* @returns {{ total: number, ready: number, notReady: number, readyPercent: number }}
|
|
62
|
+
*/
|
|
63
|
+
getSummary(): {
|
|
64
|
+
total: number;
|
|
65
|
+
ready: number;
|
|
66
|
+
notReady: number;
|
|
67
|
+
readyPercent: number;
|
|
68
|
+
};
|
|
69
|
+
#private;
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, ArchitectureMap } from "./ArchitectureMap.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InterfaceTemplate โ base class for defining new UI interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Establishes the inheritance pattern for the "One Logic, Many UI" architecture.
|
|
5
|
+
* Each UI interface (CLI, Web, Mobile, Chat, Audio) extends this template
|
|
6
|
+
* and overrides the required methods.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* class CliInterface extends InterfaceTemplate {
|
|
10
|
+
* render(data) { return formatForTerminal(data) }
|
|
11
|
+
* async ask(prompt) { return readlinePrompt(prompt) }
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* @abstract
|
|
15
|
+
*/
|
|
16
|
+
export default class InterfaceTemplate {
|
|
17
|
+
/**
|
|
18
|
+
* List of methods that MUST be overridden by concrete implementations.
|
|
19
|
+
* Used for documentation and runtime validation.
|
|
20
|
+
*
|
|
21
|
+
* @type {string[]}
|
|
22
|
+
*/
|
|
23
|
+
static requiredMethods: string[];
|
|
24
|
+
/**
|
|
25
|
+
* The name of this interface (e.g. 'cli', 'web', 'mobile').
|
|
26
|
+
* Override in subclass.
|
|
27
|
+
*
|
|
28
|
+
* @type {string}
|
|
29
|
+
*/
|
|
30
|
+
name: string;
|
|
31
|
+
/**
|
|
32
|
+
* Render data to the user through the interface.
|
|
33
|
+
* Must be overridden by each concrete implementation.
|
|
34
|
+
*
|
|
35
|
+
* @param {any} [data] - data to render
|
|
36
|
+
* @returns {any} rendered output (string for CLI, DOM for web, etc.)
|
|
37
|
+
* @throws {Error} if not overridden
|
|
38
|
+
*/
|
|
39
|
+
render(data?: any): any;
|
|
40
|
+
/**
|
|
41
|
+
* Request input from the user through the interface.
|
|
42
|
+
* Must be overridden by each concrete implementation.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} prompt - question or label for the input
|
|
45
|
+
* @param {object} [options] - options (type, choices, default, etc.)
|
|
46
|
+
* @returns {Promise<any>} user's response
|
|
47
|
+
* @throws {Error} if not overridden
|
|
48
|
+
*/
|
|
49
|
+
ask(prompt: string, options?: object): Promise<any>;
|
|
50
|
+
/**
|
|
51
|
+
* Validate that all required methods have been overridden.
|
|
52
|
+
* Call this in the subclass constructor to get early feedback.
|
|
53
|
+
*
|
|
54
|
+
* @returns {string[]} list of missing method overrides (empty = valid)
|
|
55
|
+
*/
|
|
56
|
+
validate(): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Get interface capabilities info.
|
|
59
|
+
*
|
|
60
|
+
* @returns {{ name: string, requiredMethods: string[], isComplete: boolean }}
|
|
61
|
+
*/
|
|
62
|
+
info(): {
|
|
63
|
+
name: string;
|
|
64
|
+
requiredMethods: string[];
|
|
65
|
+
isComplete: boolean;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, InterfaceTemplate } from "./InterfaceTemplate.js";
|