@nan0web/ui 1.12.1 → 1.12.3

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.
Files changed (37) hide show
  1. package/README.md +18 -345
  2. package/package.json +13 -8
  3. package/src/Model/index.js +2 -2
  4. package/src/core/GeneratorRunner.js +8 -0
  5. package/src/core/resolvePositionalArgs.js +51 -0
  6. package/src/domain/Content.js +5 -5
  7. package/src/domain/Document.js +1 -1
  8. package/src/domain/HeroModel.js +1 -1
  9. package/src/domain/ModelAsApp.js +310 -20
  10. package/src/domain/ModelAsApp.story.js +117 -0
  11. package/src/domain/app/GalleryCommand.js +9 -8
  12. package/src/domain/app/{GalleryRenderIntent.js → GalleryRenderCommand.js} +20 -20
  13. package/src/domain/app/SnapshotAuditor.js +81 -85
  14. package/src/domain/app/SnapshotRunner.js +1 -1
  15. package/src/domain/app/UIApp.js +12 -21
  16. package/src/index.js +4 -2
  17. package/src/inspect.js +1 -0
  18. package/src/testing/SnapshotRunner.js +2 -1
  19. package/src/testing/SpecRunner.js +37 -0
  20. package/types/Model/index.d.ts +2 -2
  21. package/types/core/resolvePositionalArgs.d.ts +24 -0
  22. package/types/docs/README.md.d.ts +1 -0
  23. package/types/domain/Content.d.ts +2 -2
  24. package/types/domain/Document.d.ts +2 -2
  25. package/types/domain/HeroModel.d.ts +2 -2
  26. package/types/domain/ModelAsApp.d.ts +49 -5
  27. package/types/domain/ModelAsApp.story.d.ts +1 -0
  28. package/types/domain/app/GalleryCommand.d.ts +6 -37
  29. package/types/domain/app/GalleryRenderCommand.d.ts +27 -0
  30. package/types/domain/app/SnapshotAuditor.d.ts +33 -23
  31. package/types/domain/app/SnapshotRunner.d.ts +2 -2
  32. package/types/domain/app/UIApp.d.ts +14 -11
  33. package/types/index.d.ts +4 -2
  34. package/types/inspect.d.ts +1 -0
  35. package/types/testing/SpecRunner.d.ts +22 -0
  36. package/types/testing/verifySnapshot.d.ts +1 -1
  37. package/types/domain/app/GalleryRenderIntent.d.ts +0 -31
package/README.md CHANGED
@@ -1,363 +1,36 @@
1
1
  # @nan0web/ui
2
2
 
3
- 🏴󠁧󠁢󠁥󠁮󠁧󠁿 [English](./README.md) | 🇺🇦 [Українською](./docs/uk/README.md)
3
+ Легкий, агностичний UI-фреймворк, розроблений за філософією **nan0web** — одна логіка додатка, багато UI-реалізацій (One Logic Many UI).
4
4
 
5
- <!-- %PACKAGE_STATUS% -->
5
+ ## Documentation / Документація
6
6
 
7
- A lightweight, agnostic UI framework designed with the **nan0web philosophy**
8
- — one application logic, many UI implementations.
7
+ Оберіть мову документації:
9
8
 
10
- This library provides core classes and utilities for building structured user interfaces.
11
- It supports:
9
+ - 🏴󠁧󠁢󠁥󠁮󠁧󠁿 [**English Documentation**](./docs/en/README.md)
10
+ - 🇺🇦 [**Українська документація**](./docs/uk/README.md)
12
11
 
13
- - Messaging (Input/Output)
14
- - Forms with validation
15
- - Progress tracking
16
- - Component rendering
17
- - View management with Frame rendering
18
- - App structure with core and user apps
12
+ ---
19
13
 
20
- Built to work in sync or async, terminal-based or web-based apps,
21
- focusing on type safety, minimalism, and pure JavaScript design.
14
+ ## Quick Start / Швидкий старт
22
15
 
23
- ## Installation
24
-
25
- How to install with npm?
26
16
  ```bash
27
17
  npm install @nan0web/ui
28
18
  ```
29
19
 
30
- How to install with pnpm?
31
- ```bash
32
- pnpm add @nan0web/ui
33
- ```
34
-
35
- How to install with yarn?
36
- ```bash
37
- yarn add @nan0web/ui
38
- ```
39
-
40
- ## Concepts & Architecture
41
-
42
- ### Message Flow
43
-
44
- UI communication is built around messages:
45
-
46
- - **`UiMessage`** – abstract message base class
47
- - **`OutputMessage`** – system output (content, error, priority)
48
-
49
- Messages are simple, serializable data containers. They help build
50
- decoupled communication systems between UI components.
51
-
52
- How to create input and output messages?
53
20
  ```js
54
- import { InputMessage, OutputMessage } from '@nan0web/ui'
55
- const input = UiMessage.from({ body: 'Hello User' })
56
- const output = OutputMessage.from({ content: ['Welcome to @nan0web/ui'] })
57
- console.info(input) // ← Message { body: "Hello User", head: {}, id: "....", type: "" }
58
- console.info(String(output)) // ← Welcome to @nan0web/ui
59
- ```
60
- ### Forms
61
-
62
- `UiForm` supports field definitions, data management, and schema validation.
63
- Every form includes a title, fields, and current state.
64
-
65
- Field types include:
21
+ import { Models } from '@nan0web/ui'
22
+ const { HeaderModel } = Models
66
23
 
67
- - `text`
68
- - `email`
69
- - `number`
70
- - `select`
71
- - `checkbox`
72
- - `textarea`
73
-
74
- How to define and validate a UiForm?
75
- ```js
76
- import { UiForm } from '@nan0web/ui'
77
- const form = new UiForm({
78
- title: 'Contact Form',
79
- fields: [
80
- FormInput.from({ name: 'email', label: 'Email Address', type: 'email', required: true }),
81
- FormInput.from({
82
- name: 'message',
83
- label: 'Your Message',
84
- type: 'textarea',
85
- required: true,
86
- }),
87
- ],
88
- state: {
89
- email: 'invalid-email',
90
- message: 'Hello!',
91
- },
92
- })
93
- const { isValid, errors } = form.validate()
94
- console.info(Object.keys(errors).length) // ← 1
95
- console.info(errors.email) // ← Invalid email format
24
+ const header = new HeaderModel({ title: 'My App' })
25
+ console.log(header.title)
96
26
  ```
97
- ### Components
98
-
99
- Components render data as frame-ready output.
100
-
101
- - `Welcome` – greets user by name
102
- - `Process` – shows progress bar and time
103
-
104
- How to render the Welcome component?
105
- ```js
106
- import { Welcome } from '@nan0web/ui'
107
- const frame = Welcome({ user: { name: 'Alice' } })
108
- const firstLine = frame[0].join('')
109
- console.info(firstLine) // ← Welcome Alice!
110
- ```
111
- ### View Manager
112
-
113
- `View` combines components and renders frames.
114
-
115
- Every view has:
116
-
117
- - Locale – formatted text, numbers, currency
118
- - StdIn / StdOut – input/output streams
119
- - Frame – output buffer with visual properties
120
-
121
- How to render frame with View?
122
- ```js
123
- import { View } from '@nan0web/ui'
124
- const view = new View()
125
- view.render(1)(['Hello, world'])
126
- console.info(String(view.frame)) // ← "\rHello, world"
127
- ```
128
- ### Frame Rendering
129
-
130
- `Frame` manages visual rendering with width and height limits.
131
- Useful for fixed-size terminals or UI blocks.
132
-
133
- Render methods:
134
-
135
- - `APPEND` – adds content after previous frame
136
- - `REPLACE` – erases and replaces full frame area
137
- - `VISIBLE` – renders only visible part of frame
138
-
139
- How to create a Frame with fixed size?
140
- ```js
141
- import { Frame } from '@nan0web/ui'
142
- const frame = new Frame({
143
- value: [['Frame content']],
144
- width: 20,
145
- height: 5,
146
- renderMethod: Frame.RenderMethod.APPEND,
147
- })
148
- const rendered = frame.render()
149
- console.info(rendered.includes('Frame content')) // ← true
150
- ```
151
- ### Domain Models (v1.9.0)
152
-
153
- v1.9.0 introduces a comprehensive set of domain models for layout and components.
154
- These models follow the **Model-as-Schema** pattern.
155
-
156
- #### Layout Models
157
- - `HeaderModel` — title, logo, navigation actions
158
- - `FooterModel` — copyright, version, social links
159
- - `HeroModel` — prominent call-to-action
160
-
161
- #### HTML5 Base Elements
162
- Fully typed zero-cost support for standard tags: `div`, `span`, `p`, `h1`-`h6`, `a`, `ul`, `table`, etc., plus SVG basics (`svg`, `path`, `rect`). Data must be standard `camelCase`.
163
-
164
- #### Component Models
165
- - `PricingModel` / `PricingSection` — plans with features and prices
166
- - `FeatureGrid` — grid of feature highlights
167
- - `ProfileDropdown` — user avatar and settings menu
168
- - `CommentModel` & `TestimonialModel` — social proof
169
- - `StatsModel` — data visualizations
170
- - `TimelineModel` — event history
171
-
172
- How to use the new Header and Hero models?
173
- ```js
174
- import { Model } from '@nan0web/ui'
175
- const { HeaderModel, HeroModel } = Model
176
- const header = new HeaderModel({
177
- title: 'NaN•Web',
178
- logo: '/logo.svg',
179
- actions: [{ title: 'Docs', href: '/docs' }],
180
- })
181
- const hero = new HeroModel({
182
- title: 'One Logic — Many UI',
183
- actions: [{ title: 'Get Started', href: '/start' }],
184
- })
185
- console.info(header.title) // ← NaN•Web
186
- console.info(hero.actions[0].title) // ← Get Started
187
- ```
188
- ### Intent Generators (v1.11.0)
189
-
190
- From v1.11.0, Intent creators are standard named functions generating
191
- strict interactions (ask, progress, show, render, result).
192
-
193
- - `ask(field, schema)` — requests input from the environment.
194
- - `progress(message)` — updates a visual loader.
195
- - `show(message, level, data)` — displays a notification (replaces deprecated `log`).
196
- - `render(component, props)` — renders a specific component view.
197
- - `result(data)` — ends the model execution cleanly.
198
-
199
- How to use Intent generators? (v1.11.0)
200
- ```js
201
- import { ask, show, result } from '@nan0web/ui'
202
- const nameIntent = ask('name', { help: 'Your name' })
203
- const msgIntent = show('Processing...', 'info')
204
- const endIntent = result({ ok: true })
205
- ```
206
- ### Testing UI (v1.11.0 Deterministic Testing)
207
-
208
- Core unit-tested to ensure stability in different environments.
209
- With **v1.11.0**, the architecture formally introduces `ScenarioTest` for zero-I/O deterministic testing.
210
-
211
- By lifting the asynchronous logic and providing an explicit scenario array, models are evaluated instantly without waiting on user prompt delays.
212
-
213
- How to test Model pipelines deterministically?
214
- ```js
215
- import { ModelAsApp, ask, result, show } from '@nan0web/ui'
216
- import { ScenarioTest } from '@nan0web/ui/test/ScenarioTest.js'
217
- const { ModelAsApp, ask, result, show } = await import('./index.js')
218
- const { ScenarioTest } = await import('./test/ScenarioTest.js')
219
- class ShoppingCartApp extends ModelAsApp {
220
- *run() {
221
- const product = yield ask('product', { help: 'Select product' })
222
- if (product?.value === 'laptop') {
223
- yield show('Good choice!', 'ok')
224
- }
225
- const confirm = yield ask('confirm', { help: 'Confirm purchase?' })
226
- return result({ product: product?.value, confirm: confirm?.value })
227
- }
228
- }
229
- const res = await ScenarioTest.run(ShoppingCartApp, [
230
- { field: 'product', value: 'laptop' },
231
- { field: 'confirm', value: true }
232
- ])
233
- ```
234
- You can also verify exceptions and validation rules by observing the final error in ScenarioTest.
235
-
236
- How to test validation errors with ScenarioTest?
237
- ```js
238
- import { ModelAsApp, ask, result } from '@nan0web/ui'
239
- import { ScenarioTest } from '@nan0web/ui/test/ScenarioTest.js'
240
- const { ModelAsApp, ask, result } = await import('./index.js')
241
- const { ScenarioTest } = await import('./test/ScenarioTest.js')
242
- class ValidatedApp extends ModelAsApp {
243
- *run() {
244
- const code = yield ask('code', { help: 'Enter code', required: true })
245
- if (!code?.value) throw new Error('Code is mandatory')
246
- return result({ code: code?.value })
247
- }
248
- }
249
- const res = await ScenarioTest.run(ValidatedApp, [
250
- { field: 'code', value: '' } // Simulating empty response
251
- ])
252
- ```
253
- All components, adapters, and models are designed to be testable
254
- with minimal setup.
255
-
256
- How to test visual UI components with assertions?
257
- ```js
258
- import { Welcome } from '@nan0web/ui'
259
- const output = Welcome({ user: { name: 'Test' } })
260
- console.info(output) // ← Welcome Test!
261
- ```
262
- ### Master IDE (Component Sandbox)
263
-
264
- The Master IDE (OlmuiInspector) provides a unified environment for testing and documenting
265
- web components across platforms. It supports:
266
-
267
- - **NaN0 Spec** — a concise YAML-based shorthand for declaring component variations.
268
- - **OlmuiInspector** — unified UI for exploring component models and props.
269
- - **Live Preview** — real-time rendering of component states.
270
- - **i18n UI** — fully localized interface (UK/EN) for global developers.
271
- - **Theme Editor** — Bootstrap-like CSS variable system with live preview.
272
-
273
- It follows the **Olmui** core pattern: *One Logic — Many UI* (same manifest powers both CLI and Web).
274
-
275
- #### Theme Editor (CSS Variables)
276
-
277
- Professional-grade theming with live preview. Supports:
278
-
279
- - **Palette**: primary, secondary, success, warning, danger, info
280
- - **Geometry**: border-radius (sm/md/lg/pill/circle), spacing (sm/md/lg)
281
- - **Type-safe inputs**: `type="color"` for colors, number inputs for dimensions
282
-
283
- #### Component Rendering Architecture
284
-
285
- The IDE handles data transformation between YAML models and web components:
286
-
287
- - **Table**: `rows[][] + columns[]` → `data[]` (array of objects)
288
- - **Tree**: `data` → `items` mapping with 4-level taxonomy
289
- - **Markdown**: Raw markdown → HTML via `_md2html()` converter
290
- - **ProgressBar**: Tag alias (`ui-progress-bar` → `ui-progress`), variant colors
291
- - **LangSelect**: `string[]` → `{code,title}[]` conversion
292
- - **Hyphenated props**: Auto `camelCase` conversion (`show-label` → `showLabel`)
293
-
294
- #### NaN0 Spec (YAML)
295
-
296
- Concise format for defining variations:
297
-
298
- How to define a component variation using NaN0 Spec?
299
- ```yaml
300
- - Button: Primary
301
- $variant: brand
302
- $outline: true
303
- ```
304
-
305
- #### Documentation Site
306
-
307
- The IDE includes an auto-generated documentation site.
308
- HTML pages are generated from `ide.html` template via `generate-pages.js`:
309
-
310
- - Per-language pages (`/uk/Data/Table.html`, `/en/Feedback/Alert.html`)
311
- - SEO-optimized with `<title>` and `<meta>` per component
312
- - Category-based URL routing (`/Data/`, `/Feedback/`, `/Forms/`, `/Actions/`, `/System/`)
313
- - i18n navbar with `data-i18n` attributes
314
-
315
- How to run the documentation site?
316
- ```bash
317
- npm run docs:dev
318
- ```
319
-
320
- ## Playground Demos
321
-
322
- The library includes rich playground demos:
323
-
324
- - [Registration Form](./play/registration.form.js)
325
- - [Currency Exchange](./play/currency.exchange.js)
326
- - [Mobile Top-up](./play/topup.telephone.js)
327
- - [Language Selector](./play/language.form.js)
328
-
329
- Run to explore live functionality:
330
-
331
- How to run the playground?
332
- ```bash
333
- # Clone repository and run playground
334
- git clone https://github.com/nan0web/ui.git
335
- cd ui
336
- npm install
337
- npm run play
338
- ```
339
-
340
- ## API Documentation
341
-
342
- Detailed API docs are available in each class JSDoc.
343
- Explore:
344
-
345
- - [Messages](./src/core/Message/)
346
- - [Forms](./src/core/Form/)
347
- - [Stream](./src/core/Stream.js)
348
- - [Components](./src/Component/)
349
- - [View](./src/View/)
350
- - [App](./src/App/)
351
- - [Models](./src/Model/)
352
-
353
- ## Project Architecture & Specs
354
-
355
- How the universal block spec is designed? - [check Universal Blocks Spec (`project.md`)](./project.md)
356
-
357
- ## Contributing
358
27
 
359
- How to contribute? - [check here](./CONTRIBUTING.md)
28
+ ## Resources / Ресурси
360
29
 
361
- ## License
30
+ - 🏴󠁧󠁢󠁥󠁮󠁧󠁿 [Project Architecture (`project.md`)](./docs/en/project.md)
31
+ - 🇺🇦 [Архітектура проєкту (`project.md`)](./docs/uk/project.md)
32
+ - [Contributing](./CONTRIBUTING.md)
33
+ - [License (ISC)](./LICENSE)
362
34
 
363
- How to license ISC? - [check here](./LICENSE)
35
+ ---
36
+ © 2026 nan0web
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nan0web/ui",
3
- "version": "1.12.1",
3
+ "version": "1.12.3",
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",
@@ -8,7 +8,7 @@
8
8
  "files": [
9
9
  "src/**/*.js",
10
10
  "!src/**/*.test.js",
11
- "!src/README.md.js",
11
+ "!src/docs/**/*.md.js",
12
12
  "types/**/*.d.ts"
13
13
  ],
14
14
  "exports": {
@@ -32,6 +32,10 @@
32
32
  "import": "./src/domain/index.js",
33
33
  "types": "./types/domain/index.d.ts"
34
34
  },
35
+ "./models": {
36
+ "import": "./src/Model/index.js",
37
+ "types": "./types/Model/index.d.ts"
38
+ },
35
39
  "./inspect": {
36
40
  "import": "./src/inspect.js",
37
41
  "types": "./types/inspect.d.ts"
@@ -67,6 +71,7 @@
67
71
  "devDependencies": {
68
72
  "@playwright/test": "^1.58.2",
69
73
  "@rollup/plugin-yaml": "^4.1.2",
74
+ "@types/node": "^25.6.0",
70
75
  "@vitest/coverage-v8": "^3.2.4",
71
76
  "husky": "^9.1.7",
72
77
  "js-yaml": "^4.1.1",
@@ -79,18 +84,18 @@
79
84
  "@nan0web/i18n": "1.5.0",
80
85
  "@nan0web/icons": "1.1.0",
81
86
  "@nan0web/inspect": "1.0.0",
82
- "@nan0web/ui-cli": "2.13.1",
83
- "@nan0web/nan0web.app": "0.1.0",
84
- "@nan0web/ui-lit": "1.1.0",
85
87
  "@nan0web/test": "1.1.4",
86
- "@nan0web/release": "1.0.3"
88
+ "@nan0web/ui-cli": "2.14.0",
89
+ "@nan0web/release": "1.0.3",
90
+ "@nan0web/nan0web.app": "0.1.0",
91
+ "@nan0web/ui-lit": "1.1.0"
87
92
  },
88
93
  "dependencies": {
89
94
  "string-width": "^7.2.0",
90
95
  "@nan0web/co": "2.0.1",
91
96
  "@nan0web/core": "1.1.3",
92
97
  "@nan0web/log": "1.1.1",
93
- "@nan0web/types": "1.7.3"
98
+ "@nan0web/types": "1.7.6"
94
99
  },
95
100
  "scripts": {
96
101
  "prebuild": "rm -rf types/",
@@ -101,7 +106,7 @@
101
106
  "test:nan0test": "node --test --test-timeout=3333 \"src/**/*.test.js\" | nan0test parse --fail",
102
107
  "test:coverage": "node --experimental-test-coverage --test-coverage-include=\"src/**/*.js\" --test-coverage-exclude=\"src/**/*.test.js\" --test \"src/**/*.test.js\"",
103
108
  "test:coverage:collect": "nan0test coverage",
104
- "test:docs": "node --test src/README.md.js",
109
+ "test:docs": "node --test --test-timeout=3333 'src/docs/**/*.md.js'",
105
110
  "release:spec": "node --test \"src/test/releases/**/*.test.js\"",
106
111
  "test:release": "node --test \"src/test/releases/**/*.test.js\"",
107
112
  "test:status": "nan0test status --hide-name",
@@ -58,7 +58,7 @@ export {
58
58
  ProfileDropdownModel,
59
59
  }
60
60
 
61
- const Model = {
61
+ const Models = {
62
62
  User,
63
63
  HeaderModel,
64
64
  FooterModel,
@@ -88,4 +88,4 @@ const Model = {
88
88
  ProfileDropdownModel,
89
89
  }
90
90
 
91
- export default Model
91
+ export default Models
@@ -276,6 +276,14 @@ export async function runGenerator(generator, handlers, options = {}) {
276
276
  break
277
277
  }
278
278
 
279
+ case 'result': {
280
+ if (handlers.result) {
281
+ await handlers.result(intent)
282
+ }
283
+ nextVal = undefined
284
+ break
285
+ }
286
+
279
287
  default:
280
288
  throw IntentErrorModel.error('unhandled_intent', { type: /** @type {any} */ (intent).type })
281
289
  }
@@ -0,0 +1,51 @@
1
+ import { Model, getMetadata } from '@nan0web/types'
2
+
3
+ /**
4
+ * Resolves positional CLI arguments into named model fields.
5
+ *
6
+ * Scans a Model class for `static` field descriptors with `positional: true`.
7
+ * The order of positional fields follows the declaration order of static properties
8
+ * (guaranteed by JavaScript spec for non-integer keys).
9
+ *
10
+ * @example
11
+ * class MyModel {
12
+ * static source = { help: 'Source path', default: '.', positional: true }
13
+ * static target = { help: 'Target path', default: 'out', positional: true }
14
+ * static quiet = { help: 'Quiet mode', default: false, type: 'boolean' }
15
+ * }
16
+ *
17
+ * const data = resolvePositionalArgs(MyModel, ['src/', 'dist/'])
18
+ * // → { source: 'src/', target: 'dist/' }
19
+ *
20
+ * @param {typeof Model} ModelClass - The Model class with static field descriptors.
21
+ * @param {string[]} args - Positional arguments from the CLI (e.g., process.argv positionals).
22
+ * @param {Object} [existing={}] - Existing named options (take priority over positionals).
23
+ * @returns {Object} Merged data object with positional args resolved to named fields.
24
+ */
25
+ export function resolvePositionalArgs(ModelClass, args = [], existing = {}) {
26
+ if (!args || !args.length) return { ...existing }
27
+
28
+ const metadata = getMetadata(ModelClass)
29
+ const positionalFields = []
30
+ for (const [key, descriptor] of Object.entries(metadata)) {
31
+ if (descriptor && typeof descriptor === 'object' && descriptor.positional === true) {
32
+ positionalFields.push(key)
33
+ }
34
+ }
35
+
36
+ const result = { ...existing }
37
+ for (let i = 0; i < positionalFields.length && i < args.length; i++) {
38
+ const field = positionalFields[i]
39
+ // Named options take priority over positionals
40
+ if (result[field] === undefined || result[field] === null) {
41
+ result[field] = args[i]
42
+ }
43
+ }
44
+
45
+ // Preserve remaining positional arguments for subcommands
46
+ if (args.length > positionalFields.length) {
47
+ result._positionals = args.slice(positionalFields.length)
48
+ }
49
+
50
+ return result
51
+ }
@@ -1,6 +1,6 @@
1
1
  import { Model } from '@nan0web/types'
2
2
 
3
- /**
3
+ /**
4
4
  * @typedef {Object} HTML5Elements
5
5
  * @property {string|ContentData[]} [a]
6
6
  * @property {string|ContentData[]} [abbr]
@@ -126,7 +126,7 @@ import { Model } from '@nan0web/types'
126
126
  * @property {string|ContentData[]} [text]
127
127
  */
128
128
 
129
- /**
129
+ /**
130
130
  * @typedef {Object} CoreUIElements
131
131
  * @property {import('./components/AccordionModel.js').AccordionModel} [accordion]
132
132
  * @property {import('./components/AutocompleteModel.js').AutocompleteModel} [autocomplete]
@@ -162,8 +162,8 @@ import { Model } from '@nan0web/types'
162
162
  * @property {ContentData[]} [sortable] - Інтерактивний Drag-n-Drop контейнер
163
163
  */
164
164
 
165
- /**
166
- * @typedef {Partial<Content & HTML5Elements & CoreUIElements> & Record<string, any>} ContentData
165
+ /**
166
+ * @typedef {Partial<Content & HTML5Elements & CoreUIElements> & Record<string, any>} ContentData
167
167
  */
168
168
 
169
169
  export class Content extends Model {
@@ -172,7 +172,7 @@ export class Content extends Model {
172
172
 
173
173
  /**
174
174
  * @param {ContentData | string} [data={}]
175
- * @param {import('@nan0web/types').ModelOptions} [options={}]
175
+ * @param {Partial<import('@nan0web/types').ModelOptions>} [options={}]
176
176
  */
177
177
  constructor(data = {}, options = {}) {
178
178
  if ('string' === typeof data) {
@@ -12,7 +12,7 @@ export class Document extends Model {
12
12
  /**
13
13
  *
14
14
  * @param {Partial<Document>} [data]
15
- * @param {import('@nan0web/types').ModelOptions} [options]
15
+ * @param {Partial<import('@nan0web/types').ModelOptions>} [options]
16
16
  */
17
17
  constructor(data = {}, options = {}) {
18
18
  super(data, options)
@@ -37,7 +37,7 @@ export class HeroModel extends Model {
37
37
 
38
38
  /**
39
39
  * @param {Partial<HeroModel | Record<string, any>>} [data={}]
40
- * @param {import('@nan0web/types').ModelOptions} [options={}]
40
+ * @param {Partial<import('@nan0web/types').ModelOptions>} [options={}]
41
41
  */
42
42
  constructor(data = {}, options = {}) {
43
43
  super(data, options)